【工程应用二】 多目标多角度的快速模板匹配算法(基于边缘梯度)

       基于NCC的多目标多角度快速模板匹配算法详见:http://www.javashuo.com/article/p-vqdbukfw-vk.htmlhtml

       乘着研究NCC的热情,顺便也研究了下基于边缘梯度的匹配。算法

       基于边缘梯度方面的匹配,最为出名的莫过于CodeProject上一篇多年前的印度小哥的文章,连接为:Edge Based Template Matching测试

       这篇文章的核心计算公式为:网站

                           (1)编码

 

       在国内的中文有关网站上却经常看到下述公式(分母第二项不一样),这明显是个错误的式子,也不知道哪位是原始创造者。spa

              

        这个核心计算式和基于NCC的看上去类似又有着不少不一样。注意式子中的大写字母G表示图像的梯度信息,这个是可正亦可负的。即计算式已经脱离原有的像素信息,而使用了梯度相关信息,经常使用的获取X和Y方向梯度的方式有:.net

            

    即Sobel边缘检测算子。code

         在印度小哥的文章里,采用了Canny检测来检测出边缘,而后只对模板图和搜索图中对应的边缘位置计算上述得分公式(以模板图中的边缘处为依据), 这样起到减小取样点,提升速度的做用。htm

         我实际测试这种方法若是直接对模板和搜索图作,不少状况下是能够的,可是仍是存在着一些问题,主要有:对象

         一、虽然Canny的使用减小了不少计算量,可是他彻底剔除了其余弱边缘处的信息,就好像把考试中那些不及格的学生都定型为差生同样,是不科学的。这些弱边缘在必定程度上也有着至关的信息量。

         二、Canny自己是有着不少参数来控制最终的效果的,不是一个固定的参数对每一副图像都能获取稳定的效果,所以,这就很难成为一个稳定的算法了。

         三、若是采用了金字塔等技术,在金字塔层数增长时,Canny所对应的边缘会愈来愈不稳定,这会影响最终的精度。

         因此,我以为不该该使用Canny获其余的相似技术实现这个过程,个人想法仍是对全图实现上述公式的计算。

         可是,这又会遇到几个问题。

         一、计算量飙升,这个能够经过金字塔的技术来解决。

         二、咱们仔细的观察公式(1),若是作一个全局的匹配计算,在计算过程当中,必然会遇到很多地方的X和Y方向的梯度都为0或者很小,并且这种像素占的比例还至关高,毕竟图像中真正属于边缘的地方不多。那么这样的一个事实就回到致使不少累加项的值为0或很小(X和Y梯度都为0时,式子的分母为0,程序须要作判断,但输出的结果必然也会是0),这样总体累加后再求平均数咱们将得到一个很小的得分(哪怕和模板图如出一辙的地方)。

        一种改进的方法就是把模板图的总体的幅值信息做为一个因子放入到上述计算公式的分母中,这样,模板图中梯度较小的位置,对总体的幅值贡献就小,从而不会对最后的得分形成影响。

        在实际的编码中,咱们还会遇到不少的其余方面的困难,列举一些以下:

       一、对于角度的检测,相似的,咱们也建立多个离散的模板,咱们须要旋转模板,而后计算模板的边缘梯度,可是,旋转自己产生了新的边缘,并且是强边缘,以下所示:

          

     若是把这边缘带入式中计算,很是明显不会获得可靠的结果,咱们须要把这个边缘剔除。

     二、不管采用何种边缘梯度检测算子,最小的都会涉及到3*3的局部范围,那么对于未旋转或者旋转后的模板图,都存在一个明显问题,最外一圈像素的梯度如何处理,若是使用重复边缘像素的方式,那么就会得到一个较小的梯度,可是实际在在搜索图中是不存在这个问题的,只要模板不在搜索图的边缘处。所以,若是这样处理,哪怕模板就是从搜索图中直接扣取出来的,依据(1)式计算出的结果也不会等于1,而是小于1。

  如何解决这个问题,我目前想到的也只有忽略最外圈的梯度值,即他们不参与类似性计算。这样就要求在作模板图时,须要能够在实际须要的模板的基础上,中心对称的长和宽每边各增长一个像素。可是,这样实际上仍是没有完美解决问题,由于当有金字塔存在时,这能够增长的1个像素通过下采样后已经没有一个像素了,仍是有点头大,暂时没有想到什么好办法。、

IM_Rotate(Template, Rotate, RTI.Mask, Angle, 1, Amount);            // 旋转图像,获取Mask值
IM_Edge_Erode_3X3(RTI.Mask, RTI.Mask);

  想到的另一个方法就是旋转时不是旋转图像而后再计算梯度,而是直接旋转X和Y方向的梯度,可是新的难处是梯度值是有正有负的,这种数据的旋转在使用双线性插值时,因为四个取样点的极性不一样,是否能直接处理呢,我感受好像有问题,好比四个数,2正2负,有可能插值后结果就为0了。

      目前,采用了一些很是规的手段,仍是基本有必定的成果了,一些不是特别状况的图,使用基于边缘梯度的方式也能获取到较为准确的结果,好比基于NCC那个几个测试图,也是能够的。

      进一步测试代表,这个算法相对于NCC,在某些状况下确实是有更靠谱的识别结果,并且是对强边缘的识别效果很不错。

           

          基于NCC的结果                                               基于边缘梯度的结果

       由上面的测试图也可看出,两种算法对于光照的影响都有必定的抵抗能力。

       再看一个比较有意思的图:

       

       这里的MaxOverlap设置为0.7,MinScore也设置为0.7.

       对于下面这种复杂的边缘重叠的对象也有必定的免疫力。

        

 

                                           基于NCC的结果                                                                基于边缘梯度的结果

     上述测试图,基于边缘的成功的锁定了20个待检测的目标,而基于NCC的则丢失了一个,固然这并非说基于NCC的就比基于边缘的差。

       本算法待进一步改进后可能会集成到国产视觉软件Malcon中,详情请看 中国的Malcon跟德国的Halcon的相比的优缺点 

       Malcon官方博客:https://www.cnblogs.com/Malcon

       或者点击:         https://blog.csdn.net/lindrs/article/details/114113280?spm=1001.2014.3001.5502

       目前可经过下面连接获取一个可视化的Demo:  https://files.cnblogs.com/files/Imageshop/TemplateMatching.rar

       一样声明,这个Demo自己是有Bug的(不影响测试使用),请不要将其直接应用到工业环境中,以避免形成没必要要的损失。

      若是您以为本博文对您有所帮助,也可慷慨解囊。

     

相关文章
相关标签/搜索