Halcon 实战:如何为 XLD 模板添加极性信息以提升匹配精度?
在使用 Halcon 进行模板匹配时,我们通常有两种方式创建模板:
- 基于图像灰度(
CreateScaledShapeModel
) - 基于轮廓 XLD(
CreateScaledShapeModelXld
)
前者可自动提取边缘极性信息(即边缘是"由暗到亮"还是"由亮到暗"),而后者则因轮廓缺乏原始图像灰度数据,默认不含极性信息。
然而,在实际应用中,我们常常基于手动绘制或处理后的轮廓 XLD
创建模板,此时如果继续忽略极性,会在复杂背景下降低匹配精度,甚至出现误匹配。
本文将介绍一种 先创建无极性的轮廓模型,再通过实际图像自动注入极性信息 的技巧。
1️⃣ 问题背景:XLD 模板不支持 use_polarity?
我们在使用如下方式创建模板时,若将 polarity
设置为 "use_polarity"
,就会报错:
csharp
HOperatorSet.CreateScaledShapeModelXld(
contours,
"auto",
angleStartRad,
angleRangeRad,
angleStepRad,
minScale,
maxScale,
"auto",
"auto",
"use_polarity", // ⚠ 报错
contrast,
out modelID);
这是因为 XLD
轮廓本身不携带灰度信息,Halcon 无法判断边缘方向(极性),从而无法创建包含极性的模型。
2️⃣ 正确方式:先使用 ignore_local_polarity 创建
正确做法是先忽略极性创建模型:
csharp
HOperatorSet.CreateScaledShapeModelXld(
contours,
"auto",
angleStartRad,
angleRangeRad,
angleStepRad,
minScale,
maxScale,
"auto",
"auto",
"ignore_local_polarity", // ✅ 安全模式
contrast,
out modelID);
此时创建的模板没有极性,但可以匹配。
3️⃣ 高级技巧:后处理注入极性信息
Halcon 提供了一个鲜为人知的运算符 set_shape_model_metric
,允许我们在首次匹配后,使用真实图像为模板注入极性信息。
✅ 完整流程如下:
① 匹配一次获取模板位姿
csharp
HOperatorSet.FindScaledShapeModel(
image,
modelID,
angleStart, angleRange,
minScale, maxScale,
0.8, 1, 0.5,
"least_squares", 0, 0.9,
out rowMatch, out colMatch,
out angleMatch, out scaleMatch, out score);
② 创建仿射变换矩阵
csharp
HOperatorSet.VectorAngleToRigid(
0, 0, 0, // 模板参考点是 (0,0)
rowMatch[0], colMatch[0], angleMatch[0],
out homMat2D);
③ 为模型设置极性
csharp
HOperatorSet.SetShapeModelMetric(
image,
modelID,
homMat2D,
"use_polarity"); // 🎯 注入极性信息
此操作将遍历模板轮廓,并结合实际图像的灰度变化自动设置每条边的极性。
4️⃣ 后续使用:可正常使用 use_polarity 匹配
一旦极性信息注入完成,后续匹配时可以正常使用极性,从而获得更高的准确率和抗干扰能力。
csharp
HOperatorSet.FindScaledShapeModel(
image,
modelID,
angleStart, angleRange,
minScale, maxScale,
0.8, 1, 0.5,
"least_squares", 0, 0.9,
out rowMatch, out colMatch,
out angleMatch, out scaleMatch, out score);
Halcon 会自动使用之前注入的极性信息进行匹配。
🧠 总结
步骤 | 操作 | 说明 |
---|---|---|
① | CreateScaledShapeModelXld(..., "ignore_local_polarity") |
创建无极性模型 |
② | FindScaledShapeModel(...) |
匹配一次获得位置 |
③ | VectorAngleToRigid(...) |
得到模板 → 匹配点的变换 |
④ | SetShapeModelMetric(..., "use_polarity") |
注入极性信息 |
这种方式弥补了 XLD
模板模型初始不支持极性的缺陷。
效果展示
没加极性的匹配效果:
加了极性的匹配效果:
可以看到加了极性之后,匹配精确度更好了。