匹配的概念是相当简单的:在一张训练的图像中,一个所谓的模板被呈现。系统从这个模板中获得一个模型,然后这个模型被用来在搜索图像中去定位和模板相似的对象。依据所用的方法,这种方法能够适应光照、遮挡、变化的尺寸、位置和旋转,有甚者是模板部分的相对移动。
匹配的优势是其具有易用性、很强的鲁棒性和灵活性。匹配不要求对期望对象任何类型的分割,通过一些匹配方法,这些对象可以被定位,即使它们被其他对象所覆盖。还有就是,匹配仅仅有少量的参数,甚至这些参数在大多数情况下是被自动决定的,对于那些终端用户在机器视觉上有很少技能的应用而言,这些优势都将显得更加有诱惑力。
对于匹配,HALCON提供了不同的方法,选择要依靠图像数据和需要解决的任务。
lCorrelation-based-matching是基于灰度值和标准化的互相关。这里,线性光照变化时可以被应付的。算子的使用类似基于形状匹配的算子,比起基于形状匹配的优势是其对于纹理也能够处理。另一方面,对象仅仅能够被旋转,但不能被缩放,且方法仅限对于灰度值图像。另外,此方法对遮挡,杂物和非线性光照变化敏感。
lShape-based-matching代表着机器视觉的最新技术。不是用灰度值,而是沿着轮廓的特征被提取并被用来模型的产生和匹配。这样的效果就是这种方法对光照和对象灰度值变化是保持不变的,它可处理缺少对象部分,杂物,噪声,虚焦和轻微变形的模型。还有,多个实例可以被找到,并且多个模型可以被同时应用。此方法运行对象被旋转和缩放,并也可以被应用到多通道图像上。
lComponent-based-matching可以被认为高级的基于形状匹配:提高之处在于对象可以被认为多个部分组成,且其可以相对于彼此移动(旋转和转化)。一个简单的例子就是一对镊子,逻辑上其被认为识一个对象,但是物理上它是由两个部分组成的。基于组件匹配的匹配允许在一个搜索步骤中处理这样的组合对象。优势是相比于将部分作为不同模型来处理,改良了执行时间和增强了鲁棒性。但是与基于形状匹配相反,它不能处理虚焦的图像或者轻微变形的模型。
lLocal-deformable-matching与基于形状匹配是类似的,但是大的变形可以被处理并被返回。特别地,除了位置和得分,匹配还可以返回一个搜索图像关键部分的矫正版本,一个描述变形的向量场,和并找到模型实例的变形轮廓。
lPerspectie-deformable-matching也与基于形状匹配类似,但这里更强的透视变形可以被处理,不仅2D位姿,而是2D映射转化矩阵被返回。另外,透视变形匹配的矫正版本也是可行的。这里,不仅2D映射转化矩阵,而是对象的3D位姿也被返回。
lDescriptor-based-matching具有与透视变形匹配相同的目的,例如对于非标定情况下获取2D映射转化矩阵,并且在标定情况下获得3D位姿。主要的不同是点,而不是轮廓,被用来去创建和寻找模型,这样,对于纹理性很强的对象它是特别适合的,但不适合低纹理性的对象。相比于透视变形匹配,对于更大搜索空间更快,但精度会降低。
l3D-matching由不同的用3D数据作为模板匹配的方法组成。需要注意的是如果你在3D空间中搜索平面对象或者对象部分时,透视变形匹配或者基于描述符匹配是更快和更方便去用的选项。
lPoint-based-matching具有结合两个覆盖图像的目的。首先在两张图像中提取关键点,这些点作为实际匹配过程的输入,匹配的结果是从一张图像到另一张图像的映射,允许转化,旋转,缩放和透视变形。这个映射一般被用来去结合两张图像未一个单独更大的图像。当然,一张图像可以被看作为一个模板,另一张图像作为被寻找对象实例。基于点匹配能够处理没有标定的透视变形,但是需要更多的执行时间,其主要来源于关键点的提取。
基本概念
匹配被划为为如下的部分:
搜索2D模型(正交视图)
基于相关性的匹配
对虚焦,轻微的形变和线性光照变化保持不变,对纹理对象表现很好,但对杂质,遮挡,非线性关照变化,尺度变化,或者多通道图像是不起作用的
基于形状的匹配
对杂质,遮挡,非线性光照变化,尺度变化,虚焦和轻微的形变保持不变,并可以作用在多通道图像上。可以同时应用到多个模型上,但是对一些纹理是比较困难的。
基于组件的匹配
对象的组件有相对的运动。对杂质,遮挡,非线性光照变化和尺度变化保持不变。可以同时被应用到多个模型中,但是对一些纹理是困难的,也不作用于虚焦和形变。
局部变形匹配
返回的也是模型实例的形变。对杂质,遮挡,非线性光照变化,尺度变化和局部形变保持不变。可作用于多通道图像。
搜索2D模型(正交或者透视视图)
透视变形匹配
对杂质,遮挡,非线性光照变化,尺度,虚焦和透视形变保持不变,可作用于多通道图像,但对一些纹理是困难的。
基于描述符的匹配
对杂质,遮挡,非线性光照变化,尺度和透视形变保持不变,但是没有纹理是不起作用的,尤其是奇异点,并且对于虚焦或者多通道图像也是不起作用的。
搜索3D模型
3D匹配
---
搜索相对应点去结合覆盖图像(没有标定的拼接)
基于点匹配
---
图像匹配的一般步骤:
获取图像
对于训练和匹配,首先一张图像应该被获取。
创建(训练)模型
为了创建一个匹配模型,首先一个在训练图像中覆盖模板的ROI必须被指定,只有图像那些真正重要且稳定的部分才能被用来去训练。训练算子的输入时被剪切的图像和控制参数。模型的句柄是训练的输出,然后模型会被用来做及时搜索或者被存储在文件中。
寻找模型
已经创建(或加载)了一个模型,其就可以被用来在图像中定位对象,每种方法都会提供特定的方法去执行这个任务。如果一个或者多个对象被找到,它们的位姿(位置,旋转和尺度)或者2D映射转化矩阵,连同它们的得分,一切被返回。这些值可以是已经期望的值或者作为下一步视觉处理的输入,例如定位感兴趣区域。
销毁模型
当你不再需要匹配模型的时候,你应该摧毁它。例如,对于基于形状的匹配,你可以用clear_shape_model去销毁它。
//
// File generated by HDevelop for HALCON/DOTNET (C#) Version 10.0
//
using HalconDotNet;
namespace VsHelper
{
void Match()
{
HTuple Width, Height, WindowHandle3, Row1, Column1, Row2, Column2, hv_ModelId,row,col,angle,score;
HObject GrayImage, roi1, ho_Image, ho_ModelRegion, ho_TemplateImage;
HOperatorSet.ReadImage(out ho_Image, @"E:\文件整理\halconImg\1.png");
HOperatorSet.GetImageSize(ho_Image, out Width, out Height);
HOperatorSet.OpenWindow(0, 0, 400, 400, 0, "", "", out WindowHandle3);
HDevWindowStack.Push(WindowHandle3);
//需要显示一下,窗口才会更新图片
if (HDevWindowStack.IsOpen())
HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
//设置窗口几何对象显示颜色,这个设置一直到下一个SetColor才会改变。
if (HDevWindowStack.IsOpen())
HOperatorSet.SetColor(HDevWindowStack.GetActive(), "red");
//定义区域的填充模式,有'fill', 'margin'前者是填充全部区域,后者是显示边缘,在显示边缘时可以用
if (HDevWindowStack.IsOpen())
HOperatorSet.SetDraw(HDevWindowStack.GetActive(), "margin");
//设置线宽
if (HDevWindowStack.IsOpen())
HOperatorSet.SetLineWidth(HDevWindowStack.GetActive(), 1);
//设置在窗口写字的位置
HOperatorSet.SetTposition(WindowHandle3, 24, 12);
HOperatorSet.WriteString(WindowHandle3, "请用鼠标画ROI");
//画不带方向的roi矩形框,2是带方向的
HOperatorSet.DrawRectangle1(WindowHandle3, out Row1, out Column1, out Row2, out Column2);
//生成矩形框
HOperatorSet.GenRectangle1(out ho_ModelRegion, Row1, Column1, Row2, Column2);
//用上面的矩形抠图,生成roi区域
HOperatorSet.ReduceDomain(ho_Image, ho_ModelRegion, out ho_TemplateImage);
//创建模板
HOperatorSet.CreateNccModel(ho_TemplateImage, "auto", new HTuple(0).TupleRad(), new HTuple(20).TupleRad(),
"auto", "use_polarity", out hv_ModelId);
HOperatorSet.FindNccModel(ho_TemplateImage, hv_ModelId, -0.39, 0.78, 0.8,
1, 0.5, "true", 0, out row, out col, out angle, out score);
ho_TemplateImage.Dispose();
HOperatorSet.ClearNccModel(hv_ModelId);
}
// Main procedure
private void action()
{
// Local iconic variables
HObject ho_Image, ho_ImageGray;
// Local control variables
HTuple hv_WindowHandle, hv_Width, hv_Height;
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_Image);
HOperatorSet.GenEmptyObj(out ho_ImageGray);
HOperatorSet.SetWindowAttr("background_color", "black");
HOperatorSet.OpenWindow(0, 0, 512, 512, 0, "", "", out hv_WindowHandle);
HDevWindowStack.Push(hv_WindowHandle);
ho_Image.Dispose();
HOperatorSet.ReadImage(out ho_Image, @"E:\文件整理\halconImg\1.png");
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_Image, HDevWindowStack.GetActive());
}
HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
ho_ImageGray.Dispose();
HOperatorSet.Rgb3ToGray(ho_Image, ho_Image, ho_Image, out ho_ImageGray);
if (HDevWindowStack.IsOpen())
{
HOperatorSet.DispObj(ho_ImageGray, HDevWindowStack.GetActive());
}
ho_Image.Dispose();
ho_ImageGray.Dispose();
}
}
}