一、整体功能概述
这个 Halcon 示例的核心目标是:创建一个支持「尺度不变」的形状匹配模板,并将该模板保存为文件(.shm 格式),供后续的形状匹配任务直接调用。
形状匹配是机器视觉中用于目标定位的核心技术,而「尺度不变」意味着该模板可以匹配到图像中 ** 放大或缩小(0.8~1.0 倍范围内)** 的同一目标,同时还支持一定角度旋转(-45°~45° 范围内)的目标匹配,不受目标尺寸小幅变化和旋转的影响。
整个流程遵循「图像获取→模板区域分割→形状模型创建→模型保存→资源释放」的机器视觉模板制作标准流程。
二、逐段代码详细解析
(一)前期环境初始化
hdevelop
dev_update_off ()
dev_close_window ()
dev_update_off ():关闭 Halcon 的图形窗口实时更新功能。- 作用:避免后续每一步图像处理操作都实时刷新窗口,减少资源消耗,提升程序运行速度,同时让最终的结果展示更整洁(只在需要时显示关键内容)。
dev_close_window ():关闭当前已存在的图形显示窗口(如果有)。- 作用:清空前期可能残留的窗口,为后续适配待处理图像尺寸创建新窗口做准备,避免窗口重叠或尺寸不匹配的问题。
(二)图像获取与窗口创建
hdevelop
read_image (Image, 'green-dot')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_display (Image)
read_image (Image, 'green-dot'):从 Halcon 内置图像库中读取名为「green-dot」的图像,存储到变量Image中(Image是 Halcon 的图像对象,包含图像的像素数据、尺寸、通道等信息)。dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle):创建一个适配Image图像尺寸的图形窗口。- 参数说明:
Image:待适配的图像对象,窗口尺寸会自动匹配该图像的宽高;0, 0:窗口在屏幕上的起始坐标(x=0,y=0,即屏幕左上角);-1, -1:窗口的宽和高(设为 - 1 时,表示自动适配图像尺寸,不手动指定);WindowHandle:输出窗口句柄,后续对窗口的操作(如显示文字、绘制图形)都需要通过该句柄指定目标窗口。
- 参数说明:
dev_display (Image):在创建好的窗口中显示图像Image,让用户直观看到原始待处理图像。
(三)显示设置与信息提示
hdevelop
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_color ('green')
dev_set_line_width (3)
Message := 'This example shows how to create a shape model'
Message[1] := 'for scale invariant matching and how to save'
Message[2] := 'it in a file.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
这部分是「可视化辅助设置」,目的是让窗口中的提示信息和图形标注更清晰,同时暂停程序等待用户确认,方便分步查看流程。
set_display_font:设置窗口中显示文字的字体样式,这里设置为 16 号、等宽字体、加粗、不加斜。dev_set_draw ('margin'):设置图形绘制模式为「轮廓模式」(仅绘制区域的边缘,不填充内部),后续显示模板区域时只展示轮廓,不遮挡原始图像。dev_set_color ('green'):设置绘制图形和文字的颜色为绿色。dev_set_line_width (3):设置绘制轮廓的线宽为 3 个像素,让轮廓更清晰易见。Message变量:定义多行提示信息,说明该示例的功能。disp_message:在窗口中指定位置显示提示文字,背景为黑色、不透明,提升可读性。disp_continue_message:显示「按任意键继续」的提示信息。stop ():暂停程序运行,等待用户按下任意键后继续执行后续代码(分步查看流程的关键函数,方便调试和理解每一步结果)。
(四)模板区域分割(核心步骤 1:提取目标区域)
这部分的核心目标是从原始图像中精准提取出需要制作形状模板的目标区域,排除背景干扰,为后续创建形状模型提供纯净的区域数据。
hdevelop
threshold (Image, Region, 0, 128)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10000, 20000)
fill_up (SelectedRegions, RegionFillUp)
dilation_circle (RegionFillUp, RegionDilation, 5.5)
dev_display (Image)
dev_display (RegionDilation)
disp_message (WindowHandle, 'Template region', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
逐句解析:
threshold (Image, Region, 0, 128):对原始图像进行全局阈值分割 。- 原理:将图像中像素灰度值在「0~128」范围内的像素划分为前景(目标区域),灰度值大于 128 的划分为背景,生成一个二值化区域
Region。 - 作用:初步分离目标和背景,是图像分割的基础方法。
- 原理:将图像中像素灰度值在「0~128」范围内的像素划分为前景(目标区域),灰度值大于 128 的划分为背景,生成一个二值化区域
connection (Region, ConnectedRegions):对二值化区域进行连通域分析 。- 原理:将
Region中相互连通(相邻像素组成的完整区域)的部分分割成独立的连通域,每个连通域对应一个独立的区域对象,存储在ConnectedRegions中。 - 作用:分离前景中的多个独立目标(避免多个目标粘连在一起),方便后续筛选出需要的目标区域。
- 原理:将
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10000, 20000):对连通域进行形状筛选 。- 原理:以「区域面积(area)」为筛选条件,选择面积在「10000~20000」像素范围内的连通域,存储到
SelectedRegions中。 - 作用:精准筛选出目标模板区域,排除面积过大或过小的噪声区域(如背景杂点、小目标残留)。
- 原理:以「区域面积(area)」为筛选条件,选择面积在「10000~20000」像素范围内的连通域,存储到
fill_up (SelectedRegions, RegionFillUp):对筛选后的区域进行孔洞填充 。- 原理:填充
SelectedRegions区域内部的孔洞(即区域内部不连通的背景像素区域),生成一个完整无孔洞的区域RegionFillUp。 - 作用:让模板区域更完整,避免孔洞对后续形状模型创建的干扰(形状模型依赖完整的区域轮廓)。
- 原理:填充
dilation_circle (RegionFillUp, RegionDilation, 5.5):对填充后的区域进行圆形结构元素膨胀操作 。- 原理:以半径为 5.5 的圆形作为结构元素,对
RegionFillUp的轮廓进行向外扩张,扩大区域范围,生成RegionDilation。 - 作用:轻微扩大模板区域,弥补阈值分割和筛选过程中可能丢失的目标边缘像素,让模板区域更贴合真实目标的边缘,提升后续匹配的鲁棒性。
- 原理:以半径为 5.5 的圆形作为结构元素,对
- 后续的
dev_display和stop():显示分割后的最终模板区域,提示用户查看,等待用户确认后继续。
(五)形状模型创建(核心步骤 2:生成尺度不变形状模板)
这部分是整个示例的核心,负责将分割好的模板区域转换为可用于匹配的「尺度不变形状模型」。
hdevelop
reduce_domain (Image, RegionDilation, ImageReduced)
inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, 40)
create_scaled_shape_model (ImageReduced, 5, rad(-45), rad(90), 0, 0.8, 1.0, 0, ['none','no_pregeneration'], 'ignore_global_polarity', 40, 10, ModelID)
dev_display (Image)
dev_display (ModelRegions)
disp_message (WindowHandle, 'Regions of the shape model', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
逐句解析:
reduce_domain (Image, RegionDilation, ImageReduced):缩小图像定义域 (也叫「区域裁剪」)。- 原理:将原始图像
Image的有效像素范围限制在RegionDilation区域内,区域外的像素被屏蔽(视为无效),生成裁剪后的图像ImageReduced。 - 作用:只保留目标模板区域对应的图像内容,排除背景干扰,减少后续形状模型创建的计算量,提升模型创建效率和精度。
- 原理:将原始图像
inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, 40):检查并预处理形状模型的输入图像 。- 原理:对裁剪后的图像
ImageReduced进行高斯平滑和边缘提取,生成用于创建形状模型的中间图像ModelImages和边缘区域ModelRegions。 - 参数说明:
1是高斯平滑系数(平滑程度),40是边缘提取的阈值(控制边缘的提取精度)。 - 作用:
- 预处理图像,去除噪声,强化目标边缘(形状模型的核心是边缘轮廓信息);
- 让用户可以查看最终用于创建模型的边缘区域,验证预处理效果,为后续
create_scaled_shape_model提供高质量输入。
- 原理:对裁剪后的图像
create_scaled_shape_model:创建尺度不变形状模型 (整个示例的核心函数,详细讲解见第三部分)。- 作用:基于预处理后的图像,生成支持旋转和尺度变化的形状模型,返回模型句柄
ModelID(后续保存、调用模型都需要该句柄)。
- 作用:基于预处理后的图像,生成支持旋转和尺度变化的形状模型,返回模型句柄
- 后续的
dev_display和stop():显示形状模型的核心边缘区域,提示用户查看模型的有效轮廓,等待用户确认。
(六)模型保存与资源释放
hdevelop
write_shape_model (ModelID, 'green-dot.shm')
Message := 'The shape model has been saved in the file'
Message[1] := '\'green-dot.shm\'.'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_end_of_program_message (WindowHandle, 'black', 'true')
clear_shape_model (ModelID)
write_shape_model (ModelID, 'green-dot.shm'):将创建好的形状模型保存为文件。- 作用:将内存中的形状模型(通过
ModelID标识)写入到本地文件「green-dot.shm」中,后续其他程序可以通过read_shape_model读取该文件,直接使用形状模型进行匹配,无需重新创建,提升后续匹配程序的运行效率。
- 作用:将内存中的形状模型(通过
disp_end_of_program_message:显示程序运行结束的提示信息。clear_shape_model (ModelID):释放形状模型占用的内存资源 。- 作用:Halcon 中的形状模型是占用内存较大的对象,程序运行结束后,必须手动释放模型句柄对应的内存资源,避免内存泄漏(尤其是在循环运行或大型程序中,这一步至关重要)。
三、核心函数详解:create_scaled_shape_model
该函数是创建「尺度不变形状模型」的核心,参数众多,决定了模型的匹配性能,下面对关键参数进行详细解读(按参数顺序):
hdevelop
create_scaled_shape_model (ImageReduced, 5, rad(-45), rad(90), 0, 0.8, 1.0, 0, ['none','no_pregeneration'], 'ignore_global_polarity', 40, 10, ModelID)
| 参数位置 | 参数值 | 含义与作用 |
|---|---|---|
| 1 | ImageReduced | 输入图像(裁剪后的目标区域图像,无背景干扰) |
| 2 | 5 | 模型金字塔层数(设为 5 表示创建 5 层金字塔模型)原理:金字塔层数越多,匹配速度越快,但匹配精度略有下降,反之则精度高、速度慢 |
| 3 | rad(-45) | 模型支持的最小旋转角度(弧度制),rad(-45)表示 - 45°(Halcon 中角度默认使用弧度制,rad()函数用于角度转弧度) |
| 4 | rad(90) | 旋转角度范围(从最小旋转角度开始,覆盖 90° 的范围,即支持 - 45°~+45° 的旋转目标匹配) |
| 5 | 0 | 旋转角度步长(设为 0 表示自动优化步长,提升匹配效率和精度) |
| 6 | 0.8 | 模型支持的最小缩放比例(即可以匹配到原始目标 0.8 倍大小的目标) |
| 7 | 1.0 | 模型支持的最大缩放比例(即可以匹配到原始目标 1.0 倍大小的目标)结合参数 6,实现「0.8~1.0 倍」的尺度不变匹配 |
| 8 | 0 | 缩放比例步长(设为 0 表示自动优化步长) |
| 9 | ['none','no_pregeneration'] | 模型创建选项(无额外预处理、不预生成所有旋转 / 尺度的模型,节省内存) |
| 10 | 'ignore_global_polarity' | 极性忽略选项(忽略图像全局明暗反转,即无论目标是亮背景暗还是暗背景亮,都能匹配到,提升鲁棒性) |
| 11 | 40 | 边缘提取阈值(与inspect_shape_model的阈值对应,控制模型边缘的提取精度) |
| 12 | 10 | 模型最小边缘长度(过滤短于 10 个像素的边缘,去除噪声干扰) |
| 13 | ModelID | 输出模型句柄(唯一标识创建的形状模型,用于后续保存、调用、释放) |
四、关键知识点总结
- 形状匹配模板制作流程:图像获取→预处理→区域分割→模型创建→模型保存→资源释放,这是 Halcon 形状匹配的标准流程,适用于大多数目标定位场景。
- 尺度不变的实现 :通过
create_scaled_shape_model的第 6、7 个参数(最小 / 最大缩放比例)实现,支持目标尺寸在指定范围内变化的匹配。 - 鲁棒性提升技巧:孔洞填充、膨胀操作、忽略全局极性、金字塔模型,这些步骤和参数都能提升模型在复杂场景下的匹配成功率。
- 资源管理 :
clear_shape_model是必须的步骤,用于释放模型内存,避免内存泄漏,尤其是在大型项目中需要重点关注。 - 分步调试的重要性 :示例中多次使用
stop()暂停程序,方便查看每一步的处理结果,这是 Halcon 程序调试的常用技巧,有助于快速定位问题。
补充说明
该示例只完成了「形状模型的创建与保存」,后续如果需要进行实际的匹配,还需要使用read_shape_model读取保存的.shm 文件,再通过find_scaled_shape_model函数在待匹配图像中查找目标,实现目标的定位。