L06: 图像处理插件:模板匹配 (Plugin.Match)
1. 引言
在前面的章节中,我们学习了如何创建一个基础的图像采集插件。本章我们将深入探讨一个更复杂的图像处理插件:Plugin.Match
。该插件将演示如何利用Halcon强大的模板匹配功能在输入图像中定位预定义的模板。
模板匹配是机器视觉中非常常用的技术,用于在图像中快速准确地找到一个或多个与已知模板相似的区域。理解其实现方式对于开发各种视觉检测、定位和识别应用至关重要。
我们将重点关注:
- 如何创建和管理Halcon的模板句柄 (ModelID)。
- 如何在插件中集成Halcon的形状匹配或灰度匹配算子。
- 如何处理匹配结果,例如位置、角度和得分。
- 如何在用户界面中配置匹配参数,如对比度、最小得分等。
- 如何将匹配结果(如定位的框和中心点)显示在图像上。
2. Plugin.Match 概述
Plugin.Match
插件的核心功能是接收一张输入图像,并根据用户预先创建或加载的模板,在该图像中搜索匹配的实例。插件的输出通常是匹配到的目标的位置坐标、旋转角度以及一个匹配得分。
2.1 插件功能需求
一个典型的模板匹配插件应具备以下功能:
- 模板管理:
- 创建模板:允许用户从当前显示的图像中选择一个区域 (ROI) 作为模板,并设置相关参数(如金字塔级别、角度范围、对比度等)来创建形状模板或灰度模板。
- 加载模板:允许用户从文件加载之前保存的模板句柄。
- 保存模板:允许用户将当前创建或加载的模板句柄保存到文件,以便后续使用。
- 显示模板图像:在UI上显示当前使用的模板图像。
- 匹配参数配置:
- 最小匹配得分:用户可以设置一个阈值,只有匹配得分高于此阈值的才被认为是有效匹配。
- 匹配数量:期望找到的目标数量。
- 贪婪度 (Greediness):控制匹配算法的搜索策略。
- 角度范围和步长(如果模板支持旋转)。
- 缩放范围和步长(如果模板支持缩放)。
- 执行匹配: 在输入图像上执行模板匹配操作。
- 结果输出与显示:
- 输出匹配到的每个实例的行坐标 (Row)、列坐标 (Column)、旋转角度 (Angle) 和匹配得分 (Score)。
- 在图像上绘制匹配结果,例如用矩形框出匹配区域,并标记中心点。
3. ModuleObj.cs
- 模板匹配逻辑
Plugin.Match
的 ModuleObj.cs
将负责处理所有与Halcon模板匹配相关的核心逻辑。
3.1 关键成员变量
// 示例:Plugin.Match/ModuleObj.cs (部分成员)
using HalconDotNet;
using VisionFramework.Core; // 假设的核心命名空间
public class MatchModule : ModuleObjBase
{
// --- 输入引脚 ---
[InputPin("输入图像", "待匹配的图像")]
public HObject InputImage { get; set; }
// --- 输出引脚 ---
[OutputPin("匹配结果Row", "匹配到的目标的中心行坐标数组")]
public HTuple ResultRow { get; private set; }
[OutputPin("匹配结果Col", "匹配到的目标的中心列坐标数组")]
public HTuple ResultCol { get; private set; }
[OutputPin("匹配结果Angle", "匹配到的目标的旋转角度数组")]
public HTuple ResultAngle { get; private set; }
[OutputPin("匹配结果Score", "匹配到的目标的得分数组")]
public HTuple ResultScore { get; private set; }
[OutputPin("匹配数量", "成功匹配到的目标数量")]
public int MatchCount { get; private set; }
// --- 模板相关参数 ---
public HObject TemplateImage { get; set; } // 用于UI显示的模板图像
public HTuple ModelID { get; set; } // Halcon模板句柄
public string ModelPath { get; set; } = ""; // 模板文件路径
// --- 匹配参数 (通常在UI中配置,并通过属性绑定到这里) ---
public double MinScore { get; set; } = 0.7;
public int NumMatches { get; set; } = 0; // 0表示查找所有
public double Greediness { get; set; } = 0.8;
public double AngleStart { get; set; } = -0.39; // 弧度,约-22.5度
public double AngleExtent { get; set; } = 0.78; // 弧度,约45度
public string Metric { get; set; } = "use_polarity"; // 匹配度量,例如 use_polarity, ignore_global_polarity
// ... 其他参数,如金字塔级别、对比度等
// 内部用于显示的结果
public HXLDCont MatchedContours { get; private set; } // 匹配到的轮廓
public MatchModule() : base()
{
ModuleName = "模板匹配";
ResultRow = new HTuple();
ResultCol = new HTuple();
ResultAngle = new HTuple();
ResultScore = new HTuple();
MatchedContours = new HXLDCont();
}
// ... 方法实现 ...
}
关键点:
- 输入/输出引脚: 定义了清晰的输入(
InputImage
)和输出(ResultRow
,ResultCol
,ResultAngle
,ResultScore
,MatchCount
)。 - 模板句柄
ModelID
: 这是核心,存储了Halcon创建的模板模型。 - 模板图像
TemplateImage
: 用于在UI上给用户一个视觉参考。 - 匹配参数: 如最小得分、匹配数量、贪婪度、角度范围等,这些参数将直接影响匹配算子的行为。
MatchedContours
: 用于存储匹配到的目标的轮廓,方便在图像上绘制。
3.2 核心方法实现
3.2.1 创建模板 (CreateModel
)
此方法通常由UI调用,当用户选择了一个ROI并点击“创建模板”时触发。
// 伪代码 - 创建形状模板
public bool CreateModelFromROI(HObject image, HObject roiRegion)
{
try
{
ModelID?.Dispose(); // 清理旧模板
TemplateImage?.Dispose();
HOperatorSet.ReduceDomain(image, roiRegion, out HObject imageReduced);
TemplateImage = imageReduced.Clone(); // 保存模板图像用于显示
// 示例:创建形状模板 (Shape-Based Matching)
HOperatorSet.CreateShapeModel(imageReduced,
"auto", // NumLevels (金字塔层数)
AngleStart, // AngleStar