文章目录
- 1. 引言
- 2. 什么是模板匹配
- 3. Halcon 模板匹配的分类
- 4. 基于形状的模板匹配
- 5. 核心算子详解
- 5.1 create_shape_model 算子
- 5.2 find_shape_model 算子
- 5.3 dev_display_shape_matching_results 算子
- 5.4. 模板匹配角度的物理含义(非常关键)
- 6. 实战案例:物品位置的定位
- 6.1 代码实现
- 6.2 运行结果
- 6.3 Row, Column, Angle含义
- 7. 匹配不到目标的原因
- 8. 总结
1. 引言
模板匹配(Template Matching)是机器视觉中最经典、最基础的目标定位方法之一。它的核心思想非常简单:在一幅待检测图像中,寻找与预先给定的模板图像最相似的位置。Halcon 作为工业级机器视觉库,提供了多种模板匹配算子,能够应对不同场景下的定位需求。
本讲将系统讲解 Halcon 模板匹配的原理、分类、关键算子以及实战应用,帮助读者从零掌握模板匹配技术。
2. 什么是模板匹配
提前在模板图像中提取目标工件特征,在待测图像中搜索,找到目标,输出目标的位置、旋转角度(通用模板还输出缩放)。
核心用途:工件摆放位置不固定 → 模板匹配获取位姿 →align_metrology_model整体移动计量模型,完成卡尺测量。
3. Halcon 模板匹配的分类
Halcon 根据应用场景的不同,提供了多种模板匹配方法,主要分为以下四类:
| 模板类型 | 核心能力 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 灰度模板 create_template | 平移 | 简单 | 光照稍微变化直接失效,不能旋转 | 几乎淘汰,仅用来入门理解 |
| 形状模板 create_shape_model | 平移 + 旋转,不支持缩放 | 速度快,抗光照强,精度高 | 不能处理图像缩放 | 90%2D 工业定位首选(支架、菱形零件) |
| 通用形状模板 create_generic_shape_model | 平移 + 旋转 + 缩放 | 支持尺寸变化 | 速度慢一点 | 工件成像大小存在波动;可直接对接 Metrology |
| 局部形变模板 create_local_deformable_model | 平移 + 旋转 + 轻微形变 | 容忍工件轮廓微小变形 | 参数难调,速度慢 | 塑胶件、冲压 |
以上四种模板匹配方法形状模板在工业领域应用最多,速度快、抗光照能力强,精度高,接下来重点介绍形状模板匹配。
4. 基于形状的模板匹配
底层原理:形状模板提取边缘轮廓做匹配,不依赖灰度,所以光照变化鲁棒。
基于形状模板匹配实现流程:
read_image读取模板图片- (可选)
reduce_domain裁剪 ROI,只保留工件区域,去掉背景干扰 create_shape_model创建形状模板,生成 ModelID 模板句柄read_image读取待检测图像- (可选)
reduce_domain设置搜索 ROI,缩小搜索范围,提速 find_shape_model在图里查找模板,输出 Row,Column,Phi,Score- 判断 Score,过滤匹配失败的情况
dev_display_shape_matching_results可视化匹配结果- 【你的项目】
align_metrology_model,用模板位姿对齐计量模型 apply_metrology_model执行计量测量clear_shape_model释放模板内存(工程必写,防止内存泄漏)
5. 核心算子详解
5.1 create_shape_model 算子
create_shape_model(Template::NumLevels, AngleStart, AngleExtent, AngleStep, Optimization, Metric, Contrast, MinContrast:ModelID)作用:从模板图像提取边缘轮廓,创建形状模板,用于find_shape_model匹配;仅支持平移 + 旋转,原生不支持缩放。
输入参数
- Template(输入图像)
模板图像,用来生成模板的原图。
✅建议:提前用
reduce_domain裁剪 ROI,只保留工件,剔除多余背景,减少干扰。
- NumLevels:金字塔层数
可选:'auto'/ 整数。
- 金字塔:多分辨率图像,高层图像分辨率低、匹配速度快;层数太高,小特征丢失,容易匹配失败。
'auto':Halcon 自动选择,项目最常用。
面试一句话:金字塔用来加速匹配,由粗到细搜索。
- AngleStart:起始旋转角度(单位:弧度)
允许匹配的最小旋转角度。
例:工件最多逆时针转 10°,顺时针转 10° →AngleStart = -rad(10) - AngleExtent:角度范围(弧度)
允许旋转的总角度跨度。
示例:AngleStart=-rad(10), AngleExtent=rad(20),总范围 -10° ~ +10°
⚠注意:不是终止角度!终止角度 = AngleStart + AngleExtent
- AngleStep:角度步长(弧度)
模板在创建时,每隔多少角度预存轮廓。
'auto'自动计算(推荐)- 角度范围越大,步长建议略大;步长越小,模板内存越大,匹配越慢。
- Optimization:模板优化选项
'auto':自动(推荐)'none':不优化,保留全部轮廓点,精度高,模板占用内存大'point_reduction_high':大量减少轮廓点,速度更快,适合大工件
- Metric:匹配度量规则(面试高频)
'use_polarity'【默认】:边缘明暗极性必须一致。亮→暗的边缘,待测图也必须是亮→暗;明暗翻转直接匹配失败。'ignore_polarity':忽略极性。亮边变暗边,依旧可以匹配;适合背光翻转、正反面工件。
- Contrast:对比度阈值
提取模板轮廓时,边缘必须达到这个对比度才会被当成特征。
可以传两个值[MinC,MaxC],抑制弱边缘,保留强边缘。
数值太小,噪声会变成轮廓;数值太大,丢失细小特征。常用 20~40。
- MinContrast:待测图像最小对比度阈值
在待检测图像中,低于这个对比度的边缘直接忽略。
用来过滤待测图噪声,一般取值 5~15。
输出参数
ModelID:模板句柄,整数。后续find_shape_model、clear_shape_model都靠这个句柄操作模板。
5.2 find_shape_model 算子
find_shape_model(Image::ModelID, AngleStart, AngleExtent, MinScore, NumMatches, MaxOverlap, SubPixel, NumLevels, Greediness:Row, Column, Angle, Score)作用:在待测图像中搜索已经创建好的形状模板,输出目标工件的位置、旋转角度、匹配得分。搭配create_shape_model成对使用。
输入参数
- Image:待检测的输入图像。
- ModelID:模板句柄,
create_shape_model输出得到。用来指定要搜索哪个模板。 - AngleStart:搜索的起始旋转角度(弧度)。
和创建模板时的角度范围保持一致,代表搜索区间最小角度。 - AngleExtent:搜索角度总跨度(弧度)。
注意:不是结束角度。结束角度 = AngleStart + AngleExtent。
例:AngleStart=-rad(10), AngleExtent=rad(20),搜索范围 -10° ~ +10°
MinScore:最低匹配得分,取值 0~1。
只有匹配得分≥MinScore,才会被判定为找到目标。- 工业常用:
0.7 ~ 0.85 - 设置太高:容易漏检;太低容易检出伪目标、噪声。
- 工业常用:
NumMatches:最多查找多少个匹配目标。
- 单工件场景填
1;多工件根据实际数量填写。
- 单工件场景填
MaxOverlap:多个目标之间允许的最大重叠度,0~1。
当多个匹配框重叠面积超过该比例,会舍弃得分低的目标。0:完全不允许重叠1:允许完全重叠
单目标场景一般写0.5即可。
SubPixel:亚像素定位选项(精密测量重点,面试高频)
'none':不开启亚像素,像素级定位,精度低'interpolation':插值亚像素,精度一般'least_squares':最小二乘拟合,精度最高,你的 Metrology 尺寸测量必须选这个
NumLevels:搜索使用的金字塔层数。
不要随便改,一般固定写 0。- 填
0:使用创建模板时全部金字塔层(绝大多数工程默认写法) - 填数字 n:只使用前 n 层金字塔做搜索
- 填
Greediness:贪婪系数,取值 0~1。
控制搜索策略,速度和漏检的权衡- 数值越大,搜索越快;更容易漏掉目标
- 数值越小,搜索越慢,漏检概率低,鲁棒性更强
- 工程常用
0.7 ~ 0.9
输出参数
- Row, Column:模板参考点在图像上的亚像素坐标(行、列)
注意:不是工件中心点!是创建模板时模板的参考原点。
- Angle:目标工件相对于模板的旋转角度,单位弧度。
- Score:本次匹配的得分 (0~1)。越接近 1,轮廓匹配程度越高。
✅业务代码必须判断 Score,低于 MinScore 代表匹配失败,不能拿去给
align_metrology_model。
5.3 dev_display_shape_matching_results 算子
dev_display_shape_matching_results(::ModelID, Color, Row, Column, Angle, ScaleR, ScaleC, Model:)作用:可视化形状模板匹配结果,在图像窗口画出模板轮廓框,直观看到模板匹配到工件的位置与旋转角度,仅用于调试显示,不参与计算。
✅注意:shape_model(create_shape_model)不支持缩放,所以 ScaleR、ScaleC 固定填 1;
✅generic_shape_model才会有缩放,ScaleR/ScaleC 为匹配得到的缩放系数。
输入参数
- ModelID:模板句柄(
create_shape_model/create_generic_shape_model生成) - Color:绘制轮廓的颜色,字符串
'red'红色、'green'绿色、'blue'蓝色,也可以用'white'/'yellow'
- Row:模板参考点 Y 坐标(find_shape_model 输出)
- Column:模板参考点 X 坐标(find_shape_model 输出)
- Angle:工件旋转角度,单位弧度(find_shape_model 输出)
- ScaleR:行方向缩放系数
- shape_model(无缩放能力):固定写 1
- generic_shape_model:填入 find_generic_shape_model 输出的 Scale
- ScaleC:列方向缩放系数
- shape_model:固定写 1
- generic_shape_model:填入 find_generic_shape_model 输出的 Scale
- Model:ModelID 元组的索引
Default Value: 0
5.4. 模板匹配角度的物理含义(非常关键)
模板默认姿态:模板图片里工件的方向 = 0 弧度 (0°)
- 工件逆时针旋转 → 角度正数
- 工件顺时针旋转 → 角度负数
例:匹配结果 Phi=rad (10),代表待测图工件相对于模板,逆时针转了 10 度。
6. 实战案例:物品位置的定位
下面通过一个完整的实战案例,演示如何使用模板匹配实现定位。
6.1 代码实现
* Shape Model 形状模板匹配 Demo * 使用图片:metal-parts/metal-parts-01.png 金属零件,特征清晰,匹配稳定 dev_close_window()dev_update_off()*1. 读取模板原图,截取单个零件ROI制作模板 read_image(TemplateImg,'metal-parts/metal-parts-01.png')get_image_size(TemplateImg, W, H)dev_open_window_fit_image(TemplateImg,0,0, -1, -1, WinHandle)* ROI框选第一个金属零件,剔除背景干扰 gen_rectangle1(ROI,150,250,320,480)reduce_domain(TemplateImg, ROI, TemplateROI)dev_display(TemplateROI)* 创建形状模板,允许±130°旋转 create_shape_model(TemplateROI,'auto', -rad(130), rad(260),'auto','auto','use_polarity','auto','auto', ModelID)*2. 读取待测图片,同数据集,零件平移+轻微旋转 read_image(Image,'metal-parts/metal-parts-02.png')dev_display(Image)*3. 模板搜索 find_shape_model(Image, ModelID, -rad(130), rad(260),0.7,2,0.5,'least_squares',0,0.8, Row, Column, Phi, Score)*4. 判断+可视化结果if(Score>0.7)disp_message(WinHandle,'匹配成功','window',10,10,'green','true')dev_display_shape_matching_results(ModelID,'red', Row, Column, Phi,1,1,0)disp_message(WinHandle,'Row:'+Row$'6.2f'+' Col:'+Column$'6.2f'+' Angle:'+deg(Phi)$'5.2f'+'° Score:'+Score$'0.3f','window',40,10,'blue','true')elsedisp_message(WinHandle,'匹配失败','window',10,10,'red','true')endif *释放资源 clear_shape_model(ModelID)6.2 运行结果
从以上结果可以看到成功匹配到两个目标。
6.3 Row, Column, Angle含义
值得注意的知识点:
以上返回的Row, Column是模板原点(模板的参考中心点)在输入图像 Image 里的亚像素坐标。
- 模板原点是哪里?
创建模板create_shape_model时,模板 ROI 的几何中心就是模板原点。
你用
reduce_domain截取一块 ROI 做模板,这块 ROI 的中心,就是模板参考点。不是零件的几何中心,是模板 ROI 区域的中心!
举例子:
gen_rectangle1 (ROI, 60,70,230,240) reduce_domain (TemplateImg, ROI, TemplateROI)这个矩形 ROI:
左上角 (60,70),右下角 (230,240)
模板原点:
Row₀ = (60+230)/2
Col₀ = (70+240)/2
匹配成功后输出的Row,Column,就是这个中心点在待测图上对应的位置。
- 配套 Angle 含义
Angle:待测图像上模板实例,相对原始模板旋转的弧度。
逆时针为正,顺时针为负
7. 匹配不到目标的原因
find_shape_model算子中NumMatches参数设置的是1;
解决:把 NumMatches 改成大于 1;
匹配得分 Score 不足
第二个零件的匹配得分 <MinScore (0.7) → 直接被过滤,判定不是目标
解决:适当调低 MinScore,比如 0.6零件重叠,MaxOverlap 阈值过滤掉第二个
MaxOverlap=0.5:如果两个零件匹配框重叠超过 50%,只保留高分的那个。
两个零件挨很近:可以调高 MaxOverlap,例如 0.8第二个零件旋转角度超出模板搜索角度范围
模板只允许 ±10°,第二个零件旋转了 15°,超出 AngleExtent 范围,搜不到。
解决:扩大AngleStart、AngleExtent第二个零件成像对比度差 / 部分遮挡
轮廓特征弱,匹配得分低。
8. 总结
本讲详细介绍了 Halcon 模板匹配的原理、分类和实战应用:
- 模板匹配原理:通过相似度搜索定位目标;
- 四大分类:灰度、形状、相关、描述符匹配;
- 核心算子:
create_shape_model和find_shape_model; - 优化策略:金字塔搜索、参数调优、多模板匹配;
- 实战案例:器件定位完整流程。
模板匹配是机器视觉定位的基础,掌握好这一技术,将为后续学习目标检测、缺陷检测等高级技术打下坚实基础。建议读者多动手实践,通过调整不同参数来深入理解各参数对匹配结果的影响。