金字塔等级的解释:https://blog.csdn.net/weixin_44490080/article/details/94471157
https://blog.csdn.net/dcrmg/article/details/52561656
在搜索过程中使用的金字塔层数是由NumLevels决定的。如果NumLevels设置为0,则使用创建模板时如create_scaled_shape_model中指定的金字塔层数。
可选地,NumLevels可以包含第二个值,该值确定所找到的匹配项被跟踪到的最低金字塔级别。因此,NumLevels的值[4,2]意味着匹配从第四个金字塔层开始,并跟踪匹配到第二个最低的金字塔层(最低的金字塔层用值1表示)。这种机制可以用来减少匹配的运行时间。然而,需要注意的是,在这种模式下,提取的位姿参数的精度通常低于正常模式,
在正常模式下,匹配被跟踪到金字塔的最低层次。NumLevels设置一个值的时候意味着匹配从设置的层数开始一直匹配到最底层。
算子:gen_gauss_pyramid(Image : ImagePyramid : Mode, Scale : ) 生成高斯金字塔
算子gen_gauss_pyramid计算一个缩小图像的金字塔。下一幅图像的缩小比例由参数scale决定。例如,如果Scale的值为0.5,图像的边缘长度就会缩短50%。这完全等同于“正常”金字塔。
参数Mode决定了平均的方式。有关此参数的更详细描述,请参见affine_trans_image。在比例等于0.5的情况下,有额外的模式'min'和'max'可用。在这种情况下,选择四个相邻像素的最小值或最大值。
请注意,每一层将作为一个单独的图像返回,即作为一个标志性的对象,带有一个矩阵和它自己的域。可以使用select_obj或copy_obj分别选择单个或多个级别。
* This example demonstrates how to adapt parameters for images
* with a low contrast and high noise.
* Thereby, the most important influence is the lowest pyramid
* level (in the parameter NumLevels of find operators like
* find_scaled_shape_model).
*
* Higher pyramid levels do not contain as much noise, so that
* the model can be found more easily there. The noise on lower
* pyramid levels sometimes prevents the found match from
* being tracked correctly.
*
*//===================================================//*
ImgPath := 'crosses/'
read_image (Image, ImgPath + 'crosses_01')
dev_update_off ()
dev_close_window ()
dev_disp_workflow_text ()
stop ()
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, 640, 640, WindowHandle)
get_window_param (WindowHandle, 'flush', Flush)
set_window_param (WindowHandle, 'flush', 'false')
flush_buffer (WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_color ('lime green')
dev_set_line_width (3)
NumImages := 10
*//================================================================//*
*//================这一段展示自动金字塔参数的效果====================//*
*
* Generate a model contour for use in create_shape_model_xld,
* create_scaled_shape_model_xld or create_aniso_shape_model_xld.
* The quality of the model contour is crucial.
*加载图像对象
read_object (ModelContour, 'model_contour')
*从XLD中创建模板,此时的金字塔等级仅用于创建模板时使用一次
create_scaled_shape_model_xld (ModelContour, 'auto', rad(-50), rad(100), 'auto', 0.75, 1.25, 'auto', 'auto', 'ignore_local_polarity', 5, ModelID)
get_shape_model_contours (ModelContours, ModelID, 1)
*
* Run with wanted rotation and scaling parameters. Greediness is
* set to 0.0 for an exhaustive search. MinScore should be low
* enough to find the wanted number of matches.
disp_message_block1 (WindowHandle, WindowHandle2)
*启用在边缘区域的匹配
set_shape_model_param (ModelID, 'border_shape_models', 'true')
for Index := 1 to NumImages by 1
read_image (Image, ImgPath + 'crosses_' + Index$'02')
*将金字塔层数设置为0即使用模板的金字塔参数值来查找
find_scaled_shape_model (Image, ModelID, rad(-50), rad(100), 0.75, 1.25, 0.1, 5, 0.0, 'least_squares', 0, 0.0, Row, Column, Angle, Scale, Score)
*
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, Scale, Scale, 0)
Text := 'Default model parameters.'
dev_disp_text (Text, 'window', 'top', 'left', 'black', 'box', 'true')
Text := 'Image ' + Index + '/' + NumImages
dev_disp_text (Text, 'window', 'top', 'right', 'black', 'box', 'true')
flush_buffer (WindowHandle)
wait_seconds (1)
endfor
set_window_param (WindowHandle, 'flush', 'true')
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
*//===================================================================//*
*//============这一段展示3层金字塔上每层的图像和模板效果效果=============//*
*
* Check the model for plausibility, in particular the number
* of pyramid levels, MinContrast and shape of the model
* contours. Is the object still well defined and visible
* on the highest pyramid level (both in the image and the
* model contours)?
* Here, the highest pyramid level is plausible and does
* not need to be adapted (in the parameter NumLevels of
* find_scaled_shape_model).
disp_message_block2 (WindowHandle, WindowHandle2)
*切换成2号窗显示
dev_set_window (WindowHandle2)
read_image (Image, ImgPath + 'crosses_01')
*从原图像中生成多个金字塔层级的图像,ImagePyramid是数组
gen_gauss_pyramid (Image, ImagePyramid, 'weighted', 0.5)
*获取模板参数,可以读到模板的金字塔层数是3
get_shape_model_params (ModelID, NumLevels, AngleStart, AngleExtent, AngleStep, ScaleMin, ScaleMax, ScaleStep, Metric, MinContrast)
hom_mat2d_identity (HomMat2DIdentityVisContour)
*NumLevels是3就是有3层,
*这一段程序展示一个图像上的3层金字塔的图像和匹配出来的模板效果
for Level := 1 to NumLevels by 1
*显示每一层上的匹配模板图像
get_shape_model_contours (ModelContoursLevel, ModelID, Level)
*选出每一层上的整个图像
select_obj (ImagePyramid, ObjectSelected, Level)
*把轮廓移动到图像中间
get_image_size (ObjectSelected, Width, Height)
hom_mat2d_translate (HomMat2DIdentityVisContour, Height / 2, Width / 2, HomMat2DTranslateVisContour)
affine_trans_contour_xld (ModelContoursLevel, ContoursAffineTrans, HomMat2DTranslateVisContour)
dev_clear_window ()
dev_display (ObjectSelected)
dev_display (ContoursAffineTrans)
Text := 'Shape model contours and test image on Level ' + Level + '/' + NumLevels + '.'
dev_disp_text (Text, 'window', 'top', 'left', 'black', 'box', 'true')
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
endfor
*切换成1号窗显示
dev_set_window (WindowHandle)
set_window_param (WindowHandle, 'flush', 'false')
*//===================================================================//*
*//============这一段展示仅在第3层金字塔上的匹配准确度效果=============//*
*//===================================================================//*
*注意:实际匹配是仅用的高层金字塔第3层,从而定位出目标位置,但由于使用的固定的外部函数
* dev_display_shape_matching_results(),这个函数仅使窗口展示出来的图像
* 和模板轮廓的效果是使用的底层金字塔来展示,所以仅起到展示位置的作用
*
*NumLevels设置为[3,3]就是从上面第3层开始查找,最低查找到第3层,结果就是只查找第3层
*
* Adapting the lowest pyramid level is the most promising approach.
* Here, using only the topmost level yields the best result.
*disp_message_block3 (WindowHandle, WindowHandle2)
dev_set_window (WindowHandle)
for Index := 1 to NumImages by 1
read_image (Image, ImgPath + 'crosses_' + Index$'02')
find_scaled_shape_model (Image, ModelID, rad(-50), rad(100), 0.75, 1.25, 0.1, 5, 0.0, 'least_squares', [3,3], 0.0, Row, Column, Angle, Scale, Score)
*
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, Scale, Scale, 0)
Text := 'Default model parameters.'
Text[1] := 'Adapted lower pyramid level in search.'
dev_disp_text (Text, 'window', 'top', 'left', 'black', 'box', 'true')
Text := 'Image ' + Index + '/' + NumImages
dev_disp_text (Text, 'window', 'top', 'right', 'black', 'box', 'true')
flush_buffer (WindowHandle)
wait_seconds (1)
endfor
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
flush_buffer (WindowHandle)
stop ()
*//===================================================================//*
*
*//===这一段根据图像噪声重设模板最小对比度,并手动生成一个图像匹配一次===//*
*目的: ?
*
* In case that adapting the lowest pyramid level is not sufficient,
* we systematically try to improve the model before adapting the
* lowest pyramid level again.
* Try to get a rough guess for a better MinContrast.
*修改最小对比度
estimate_noise (Image, 'foerstner', 20, Sigma)
set_shape_model_param (ModelID, 'min_contrast', Sigma)
*
* Set metric into shape model. Here, an artificial image is used in order
* to avoid the influence of noise.
gen_image_const (Image1, 'byte', 512, 512)
paint_region (Image1, Image1, ImageResult1, 255, 'fill')
paint_xld (ModelContour, ImageResult1, Image, 0)
find_scaled_shape_model (Image, ModelID, rad(-50), rad(100), 0.75, 1.25, 0.1, 5, 0.0, 'least_squares', 0, 0.0, Row, Column, Angle, Scale, Score)
Index := 0
dev_display_shape_matching_results (ModelID, 'red', Row[Index], Column[Index], Angle[Index], Scale[Index], Scale[Index], 0)
*计算形状匹配结果的变换矩阵
get_hom_mat2d_from_matching_result (Row[Index], Column[Index], Angle[Index], Scale[Index], Scale[Index], HomMat2DTranslate)
affine_trans_contour_xld (ModelContours, ContoursAffinTrans, HomMat2DTranslate)
set_shape_model_metric (Image, ModelID, HomMat2DTranslate, 'use_polarity')
*
*//===================================================================//*
*//===这一段再次使用1,2,3层金字塔搜索,和前面一样,只是'min_contrast'参数做了变化===//
*
*Greediness参数影响搜索速度,设置越小速度越慢,设置越大速度会越快
*
* Run with wanted rotation and scaling parameters. Greediness is set
* to 0.0 for an exhaustive search. MinScore should be low enough to find
* the wanted number of matches.
disp_message_block4 (WindowHandle, WindowHandle2)
for Index := 1 to NumImages by 1
read_image (Image, ImgPath + 'crosses_' + Index$'02')
find_scaled_shape_model (Image, ModelID, rad(-50), rad(100), 0.75, 1.25, 0.1, 5, 0.0, 'least_squares', 3, 0.0, Row, Column, Angle, Scale, Score)
*
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, Scale, Scale, 0)
Text := 'Model with changed MinContrast and Metric.'
dev_disp_text (Text, 'window', 'top', 'left', 'black', 'box', 'true')
Text := 'Image ' + Index + '/' + NumImages
dev_disp_text (Text, 'window', 'top', 'right', 'black', 'box', 'true')
flush_buffer (WindowHandle)
wait_seconds (1)
endfor
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
flush_buffer (WindowHandle)
stop ()
* //===================================================================//*
*//=====================再次仅使用第3层金字塔搜索======================//
*
* Additionally adapt the lowest pyramid level. Here, using only the
* topmost level yields the best result.
disp_message_block5 (WindowHandle, WindowHandle2)
for Index := 1 to NumImages by 1
read_image (Image, ImgPath + 'crosses_' + Index$'02')
find_scaled_shape_model (Image, ModelID, rad(-50), rad(100), 0.75, 1.25, 0.1, 5, 0.0, 'least_squares', [3,3], 0.0, Row, Column, Angle, Scale, Score)
*
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, Scale, Scale, 0)
Text := 'Model with changed MinContrast and Metric.'
Text[1] := 'Adapted lower pyramid level in search.'
dev_disp_text (Text, 'window', 'top', 'left', 'black', 'box', 'true')
Text := 'Image ' + Index + '/' + NumImages
dev_disp_text (Text, 'window', 'top', 'right', 'black', 'box', 'true')
flush_buffer (WindowHandle)
wait_seconds (1)
endfor
dev_disp_text ('Press Run (F5) to continue', 'window', 'bottom', 'right', 'black', [], [])
stop ()
*//===================================================================//*
*//===================最终使用第3层金字塔搜索,并提高分数====================//
*
* Adapt MinScore to obtain the correct number of matches. Here, setting
* MinScore to a higher value helps to eliminate false positives.
disp_message_block6 (WindowHandle, WindowHandle2)
for Index := 1 to NumImages by 1
read_image (Image, ImgPath + 'crosses_' + Index$'02')
find_scaled_shape_model (Image, ModelID, rad(-50), rad(100), 0.75, 1.25, 0.5, 5, 0.0, 'least_squares', [3,3], 0.0, Row, Column, Angle, Scale, Score)
*
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, Scale, Scale, 0)
Text := 'Model with changed MinContrast and Metric.'
Text[1] := 'Adapted lower pyramid level and MinScore in search.'
dev_disp_text (Text, 'window', 'top', 'left', 'black', 'box', 'true')
Text := 'Image ' + Index + '/' + NumImages
dev_disp_text (Text, 'window', 'top', 'right', 'black', 'box', 'true')
flush_buffer (WindowHandle)
wait_seconds (1)
endfor
* Restore default window parameter for 'flush'.
set_window_param (WindowHandle, 'flush', Flush)
执行算子:gen_gauss_pyramid (Image, ImagePyramid, 'weighted', 0.5)
得到的结果ImagePyramid如下,可以查看总共10层金字塔的图像
下一幅图像的缩小比例由参数scale决定。例如,如果Scale的值为0.5,图像的边缘长度就会缩短50%
对于有较低的对比度较多噪音的图像上,更高的金字塔层不包含太多的噪音,所以模型可以更容易地找到那里。低金字塔层次上的噪声有时会阻止找到的匹配被正确跟踪。
1、在第一层金字塔(底层金字塔)上的图像和匹配效果
2、在第二层金字塔上的图像和匹配效果
3、在第三层金字塔上的图像和匹配效果