模板匹配相关概念与几种不常用的模板匹配(学都学了,了解一下)

一、模板匹配相关概念

(一)什么是模板匹配?

  • 模板匹配指的是通过模板图像与测试图像之间的比较,找到测试图像上与模板图像相似的部分,这是通过计算模板图像与测试图像中目标的相似度来实现的,可以快速地在测试图像中定位出预定义的目标

  • 是图像处理中最基本、最常用的匹配方法

(二)匹配主要思路

  • 为感兴趣的对象创建模型:使用具用代表性图像来创模板匹配模型句柄

  • 在搜索图像中查找模型在图像中搜索先前创建的模型的实例及其位置,搜索它们的角度及行列坐标

(三)匹配结果

  • 通过模板匹配可以得到目标的相似度,旋转角度,行列坐标,缩放大小等

(四)需要处理的问题

  • 针对不同的图像特征和检测环境,有多种模板匹配算法

  • 如何选择合适的模板匹配算法,取决于具体的图像数据和匹配任务

  • 只有理解这些算法的原理和适用场景后,才能根据项目的需要选择合适的算法

(五)模板匹配的分类

  • HALCON模板匹配包含:基于点、基于灰度值、基于描述性、基于相关性、基于形状、基于组件、局部可变形、可变形的

  • 常用的方式是基于相关性和基于形状

二、基于灰度值的模板匹配(Gray-Value-Based,不怎么用的)

  • 基于灰度值的模板匹配是最经典的模板匹配算法,也是最早提出来的模板匹配算法

(一)根本思想

  • 计算模板图像与检测图像之间的像素灰度差值的绝对值总和(SAD方法)或者平方差总和(SSD方法)

(二)原理

(三)使用条件

  • 首先选择一块ROI(感兴趣区域)作为模板图像,生成基于灰度值的模板

  • 然后将检测图像与模板图像进行粗匹配,在检测图像与模板图像中任选一点,采取隔点搜索的方式计算二者灰度的相似性,这样粗匹配一遍得到粗相关点

  • 接下来进行精匹配,将得到的粗相关点作为中心点,用最小二乘法寻找二者之间的最优匹配点

  • 该方法是利用模板图像的所有灰度值进行匹配,但在光照发生变化的情况下灰度值会产生强烈的变化

  • 因此该方法不能适应光照发生变化的情况,也不能用于多通道图像的匹配

  • 适用于目标图像光照比较稳定的情况,多数情况下还是优先考虑基于相关性的匹配和基于形状的匹配。只有针对极少数的简单图像,才会考虑基于灰度值的匹配

(四)灰度匹配算子

/*
1.创建模板:create_template()
2.搜索模板和图像的最佳匹配:best_match()
3.释放模板:clear_template()
*/

(五)实例

// 清空窗口,然后读取图像,转换为灰度图。关闭当前图像窗口并打开一个固定纵横比的窗口用来显示窗口
dev_clear_window ()
read_image(Image, '灰度.png')
rgb1_to_gray(Image, GrayImage)
dev_close_window()
dev_open_window_fit_image(GrayImage, 0, 0, -1, -1, WindowHandle)
dev_display(GrayImage)

// 画ROI区域(单个圆点),用于创建模板
draw_circle(WindowHandle, Row1, Column1, Radius1)
gen_circle(ROI_0, Row1, Column1, Radius1)
reduce_domain(GrayImage, ROI_0, ImageReduced)
create_template(ImageReduced, 255, 4, 'sort', 'original', TemplateID)
    
// 二值化后进行连通域操作,多条件筛选想要的区域
threshold(GrayImage, Region, 128, 255)
connection(Region, ConnectedRegions)
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 1000, 50000)
// 为选中的区域增加灰度值,这里增加的是灰度图
add_channels(SelectedRegions, GrayImage, GrayRegions)

// 搜索模板和图像的最佳匹配。
best_match(GrayRegions, TemplateID, 40, 'false', Row, Column, Error1)
// 生成特定长度的元组并初始化其元素,将所有的圆半径设为20
// 要生成元组长度,常量,用于初始化元组元素。新生成的元组中每个元素的数据类型和值由输入参数Const决定,该参数可能只包含单个元素。Newtuple中的所有元素都具有与Const中单个元素相同的数据类型和值。
tuple_gen_const(|Row|, 20, Radius)
dev_set_line_width (3)
// 创建与圆或圆弧对应的XLD轮廓
gen_circle_contour_xld(Circles, Row, Column, Radius, 0, 6.28318, 'positive', 1)
dev_display(GrayImage)
dev_display(Circles)

三、基于形变的模板匹配 

  • 基于形变的模板匹配也是一种基于形状的匹配方法。但是基于形变的模板匹配返回结果中不仅包括轻微形变的形状、形变的位置和参数,还有描述形变的参数,如旋转角度、缩放倍数等

  • 基于透视的形变可以返回一个二维投影变换矩阵。如果是在相机标定的情况下,通过相机参数,还可以计算出目标的三维位姿

(一)根本思想

  • 形变有基于目标局部的形变 local deformable matching(局部变形匹配)和由于透视关系而产生的形变(透视形变匹配)

(二)原理

(三)使用条件

  • 对于很多干扰因素不敏感,如光照变化、混乱无序、缩放变化等。其适用于多通道图像,对于纹理复杂的图像匹配则不太适用

(四)局部变形匹配算子

/*
1.创建模板:create_local_deformable_model()
2.寻找模板:find_local_deformable_model()
3.释放模板:clear_deformable_model()
*/

(五)实例(基于局部形变的匹配)

dev_close_window ()
*读取参考图像,这里读取的是单通道灰度图像	
*这里的参考图像是已经剪裁好的感兴趣区域图像,可以直接作为模板图像
read_image (ModelImage, 'data/creamlabel')
*设置显示窗口参数
dev_open_window_fit_image (ModelImage, 0, 0, -1, -1, WindowHandle)
*创建局部形变模板,返回局部形变模板句柄ModelID
create_local_deformable_model (ModelImage, 'auto', rad(-15), rad(30), 'auto', 1, 1, 'auto', 1, 1, 'auto', 'none', 'use_polarity', [40,60], 'auto', [], [], ModelID)
*获取局部形变模板的轮廓
get_deformable_model_contours (ModelContours, ModelID, 1)
*为了将模板轮廓可视化显示,需要将轮廓与图像实物对应起来
*因此出于可视化显示的目的,先获取模板图像的几何中心
area_center (ModelImage, Area, Row, Column)
*进行仿射变换
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_translate (HomMat2DIdentity, Row, Column, HomMat2DTranslate)
affine_trans_contour_xld (ModelContours, ContoursAffinTrans, HomMat2DTranslate)
*设置轮廓显示的线条参数,显示模板图像与轮廓
dev_set_line_width (2)
dev_display (ModelImage)
dev_display (ContoursAffinTrans)
stop ()
*读取测试图像,这里的图像中更包含模板图像,并且有一定的形变
read_image (DeformedImage, 'data/cream')
*显示用于测试的局部形变图像
dev_resize_window_fit_image (DeformedImage, 0, 0, -1, -1)
dev_display (DeformedImage)
*进行局部形变模板匹配
find_local_deformable_model (DeformedImage, ImageRectified, VectorField, DeformedContours, ModelID, rad(-14), rad(28), 0.9, 1, 0.9, 1, 0.78, 0, 0, 0, 0.7, ['image_rectified','vector_field','deformed_contours'], ['deformation_smoothness','expand_border','subpixel'], [18,0,0], Score, Row, Column)
*显示形变轮廓
dev_display (DeformedImage)
dev_set_line_width (2)
dev_set_color ('red')
dev_display (DeformedContours)
stop()
*匹配结束,释放模板资源
clear_deformable_model (ModelID)

四、基于描述符的模板匹配

(一)根本思想

  • 与基于透视形变的模板匹配类似,基于描述符的模板匹配能够在物体处于透视形变的状态下进行匹配,并且已标定和未标定的相机图像都适用

  • 与透视形变不同的是,它的模板不是根据边缘轮廓创建的,而是根据特征点创建的

(二)原理

  • 点的位置或相邻像素的灰度信息等都可以作为描述符

(三)使用条件

  • 有纹理的平面图形非常适用于这种方法,尤其是对于旋转倾斜等场景中的匹配可以得到非常理想的结果

  • 基于描述符的模板匹配只能用于有纹理的图像

(四)描述符匹配算子

 /*
 1.创建模板:create_calib_descriptor_model()
 2.寻找模板:find_calib_descriptor_model()
 3.释放模板:clear_descriptor_model()
 */

(五)实例

 dev_close_window ()
 *读取参考图像,这里的参考图像应只包含识别的关键区域,用于创建模板
 read_image (ImageLabel, 'D:/MVTec/HALCON-21.11-Progress/examples/images/brochure/brochure_01.jpg')
 *设置窗口参数用于显示图像
 get_image_size (ImageLabel, Width, Height)
 dev_open_window (0, 0, Width, Height, 'black', WindowHandle1)
 dev_set_draw ('margin')
 dev_display (ImageLabel)
 *设置用于存储特征点和感兴趣区域的变量
 NumPoints := []
 RowRoi := [10,10,Height - 10,Height - 10]
 ColRoi := [10,Width - 10,Width - 10,10]
 *将参考图像中的除边缘外的区域都设为感兴趣区域。因为参考图像已经近似于匹配的纹理样本
 gen_rectangle1 (Rectangle, 10, 10, Height - 10, Width - 10)
 *显示参考图像上选择的ROI区域
 dev_set_line_width (4)
 dev_display (Rectangle)
 stop ()
 *将感兴趣区域剪裁为模板图像
 reduce_domain (ImageLabel, Rectangle, ImageReduced)
 dev_clear_window ()
 dev_display (ImageLabel)
 *创建基于描述符的模板
 create_uncalib_descriptor_model (ImageReduced, 'harris_binomial', [], [], ['min_rot','max_rot','min_scale','max_scale'], [-90,90,0.2,1.1], 42, ModelID)
 *设置模型的原点,为了后面获取坐标作参照
 set_descriptor_model_origin (ModelID, -Height / 2, -Width / 2)
 *获取模型中特征点的位置
 get_descriptor_model_points (ModelID, 'model', 'all', Row_D, Col_D)
 *将模型中计算出的特征点存入NumPoints变量中
 NumPoints := [NumPoints,|Row_D|]
 ​
 *读取测试图像,这里读取的是单通道灰度图像,因此省略了通道转化的步骤
 read_image (ImageGray, 'D:/MVTec/HALCON-21.11-Progress/examples/images/brochure/brochure_05.jpg')
 dev_resize_window_fit_image (ImageGray, 0, 0, -1, -1)
 dev_display (ImageGray)
 *对描述符特征点进行匹配
 find_uncalib_descriptor_model (ImageGray, ModelID, 'threshold', 800, ['min_score_descr','guided_matching'], [0.003,'on'], 0.25, 1, 'num_points', HomMat2D, Score)
 *显示匹配结果,将特征点用不同的颜色绘制出来
 if ((|HomMat2D| > 0) and (Score > NumPoints[0] / 4))
     get_descriptor_model_points (ModelID, 'search', 0, Row, Col)
   *创建十字标识符
     gen_cross_contour_xld (Cross, Row, Col, 6, 0.785398)
     projective_trans_region (Rectangle, TransRegion, HomMat2D, 'bilinear')
     projective_trans_pixel (HomMat2D, RowRoi, ColRoi, RowTrans, ColTrans)
     angle_ll (RowTrans[2], ColTrans[2], RowTrans[1], ColTrans[1], RowTrans[1], ColTrans[1], RowTrans[0], ColTrans[0], Angle)
     Angle := deg(Angle)
     if (Angle > 70 and Angle < 110)
         area_center (TransRegion, Area, Row, Column)
         dev_set_color ('green')
         dev_set_line_width (4)
         dev_display (TransRegion)
         dev_set_colored (6)
         dev_display (Cross)                
    endif
 endif
 stop ()
 *匹配结束,释放模板资源
 clear_descriptor_model (ModelID)

五、优化匹配速度

  • 可从两个方面下手:缩小搜索空间和使用图像不采样

六、使用halcon匹配助手进行匹配

  • 选择匹配方法
  • 创建模板
  • 检测模板
  • 优化匹配速度

猜你喜欢

转载自blog.csdn.net/soaipipiop/article/details/127202515