4. 创建形状模板的完整流程
形状模板匹配是 HALCON 中最常用的定位手段之一,而 create_shape_model 是整条定位链路的起点。这个算子一次性决定了模板“长什么样”“在多大范围内搜索”“以多细的粒度搜索”,后续的 find_shape_model 只是在这个既定模型上做匹配。因此,理解每个参数的含义与相互制约关系,比记住调用顺序更重要。
先看算子的完整签名:
create_shape_model(
Template : : // 输入模板图像(通常为 reduce_domain 后的 ROI)
NumLevels : : // 金字塔层级,'auto' 或整数
AngleStart : : // 起始角度(弧度,逆时针为正)
AngleExtent : : // 角度范围(弧度)
AngleStep : : // 角度步长,'auto' 或数值
Optimization : : // 优化方式:'auto'/'none'/'point_reduction_low/medium/high'
Metric : : // 匹配度量:'use_polarity'/'ignore_global_polarity'/'ignore_local_polarity'
Contrast : : // 对比度阈值,'auto' 或 [low, high, min_size]
MinContrast : : // 最小对比度
ModelID : ) // 输出模型句柄
下面按“先定几何、再定精度、最后定鲁棒性”的顺序逐层展开。
一、金字塔层级 NumLevels:速度与稳定性的第一道权衡
金字塔层级决定了模板被降采样多少次。层级越高,顶层图像越小,搜索越快,但顶层能保留的细节越少,容易在低对比度或相似结构上误匹配;层级越低,细节越丰富,定位越稳,但耗时上升。经验上,NumLevels 应满足:顶层图像中模板的短边仍能保留约 10~15 个像素。例如模板 ROI 短边为 200 像素,取 4 层后顶层约 12 像素,基本可用;若短边只有 40 像素,取 4 层后仅剩 2~3 像素,模板会退化成模糊斑块。
实际工程中常用 'auto' 让 HALCON 自动选择,但自动值偏保守。若发现匹配速度慢,可手动加 1 层;若发现误匹配多、定位抖动大,则减 1 层。判断依据是:在 find_shape_model 返回的 Score 中,正确目标应稳定高于 0.7~0.8,而干扰区域明显偏低。
二、角度范围与步长:覆盖旋转与搜索密度的平衡
AngleStart 与 AngleExtent 共同定义搜索的旋转区间。HALCON 约定逆时针为正,角度单位为弧度。若目标可能正反 180° 出现,可设 AngleStart = -rad(180)、AngleExtent = rad(360);若仅小角度倾斜,如 ±5°,则设 AngleStart = -rad(5)、AngleExtent = rad(10)。范围越大,模型内部存储的角度采样越多,创建时间和内存都会上升。
AngleStep 是角度采样间隔。步长过大会漏掉真实角度,导致定位偏差;步长过小则模型膨胀、匹配变慢。一个实用的估算方法是:设模板最远点到旋转中心的距离为 R,允许的最大定位误差为 e,则步长应满足 AngleStep ≤ 2·arcsin(e / (2R))。例如 R = 150 像素、允许误差 1 像素,则步长约 0.0067 rad(约 0.38°)。工程上常取 'auto',再根据实测偏差微调。
三、对比度 Contrast 与 MinContrast:决定哪些边缘进入模型
Contrast 控制模板边缘的提取质量。当设为 'auto' 时,HALCON 会自动分析 ROI 内的灰度分布并选取阈值;当设为三元组 [low, high, min_size] 时,low 与 high 是滞后阈值的上下限,min_size 用于过滤小于该像素尺寸的孤立斑点。例如 [20, 40, 3] 表示:边缘强度低于 20 的忽略,高于 40 的确定为边缘,介于两者之间的仅当与强边缘相连时才保留,且小于 3 像素的斑点被剔除。
MinContrast 是匹配阶段的门槛,它规定候选区域中边缘对比度至少达到多少才参与评分。若模板本身对比度低,而 MinContrast 设得过高,会导致 Score 普遍偏低甚至找不到目标;反之设得过低,则背景噪声也可能被当成边缘,造成误匹配。通常建议 MinContrast 取 Contrast 下限的 1/2 到 2/3。
四、Optimization 与 Metric:模型精简与极性容忍
Optimization 决定是否对模型点做精简。'auto' 会在保证精度的前提下减少点数,加快匹配;'point_reduction_high' 精简最激进,适合纹理简单、边缘清晰的工件;'none' 保留全部点,适合弱边缘或需要极高精度的场合。Metric 则决定是否容忍极性反转:'use_polarity' 要求目标与模板明暗关系一致;'ignore_global_polarity' 允许整体明暗反转;'ignore_local_polarity' 允许局部反转,但会降低区分度,容易误匹配。
五、一个可复用的参数配置示例
假设检测对象为金属冲压件,ROI 短边约 180 像素,允许 ±8° 旋转,允许定位误差 1 像素,最远点距旋转中心约 120 像素。可按下述方式配置:
read_image (Image, 'stamping_01.png')
gen_rectangle1 (ROI, 220, 180, 400, 360)
reduce_domain (Image, ROI, Template)
* 角度步长估算:2*arcsin(1/(2*120)) ≈ 0.0083 rad
create_shape_model (Template, 'auto', -rad(8), rad(16), \
rad(0.4), 'auto', 'use_polarity', \
[25, 50, 4], 15, ModelID)
* 查看模型实际使用的金字塔层级
get_shape_model_params (ModelID, NumLevels, AngleStart, AngleExtent, \
AngleStep, ScaleMin, ScaleMax, Metric, MinContrast)
创建完成后,建议先用 get_shape_model_contours 把模型轮廓叠加回原图,确认边缘是否覆盖了真正有区分度的结构,而不是把背景纹理也纳入模型。随后用 find_shape_model 在若干张图上试跑,观察 Score 分布:正确目标应明显高于干扰区域,且同一目标在不同图像上的 Score 波动不宜过大。若波动明显,优先回头调整 Contrast 与 MinContrast,而不是盲目增加金字塔层级。
Score 与耗时变化。总结来看,create_shape_model 的调参逻辑可以归纳为:先用金字塔层级确定速度与稳定性的基调,再用角度范围与步长覆盖实际旋转工况,最后用对比度与最小尺寸把真正有区分度的边缘筛进模型。三者共同决定了后续 find_shape_model 能否稳定、准确地输出位姿。