引用资料 https://www.codeproject.com/Articles/99457/Edge-Based-Template-Matching
著名机器视觉软件Halcon 的开发人员出版的一本书
中译本《机器视觉算法与应用》。
这本书里面没有代码,也没有公式验证,有少量必要的公式罗列。
侧重于工业上一些常用机器视觉算法的实现原理。
=========================================================
另外这里有C#与emgucv的算法实现:https://gitee.com/e1ki0lp/Edge-Based-Template-Matching
=========================================================
对于机器视觉来讲,视觉引导是很常见的应用,找到物体往往需要使用模版匹配。
工业上实操起来,我们需要的是鲁棒,稳定,准确,快速的算法。
基于灰度的算法是一个好的方向,基于特征点的算法可能并不适用。
这里主要介绍一种基于边缘的模版匹配算法。
下面只说笔者代码中的处理流程。
1.获取模版
①.找到感兴趣区域中的的边缘。OpenCV已经有了Canny函数,配合 FindContours 函数即可得到边缘点坐标值。
②.计算边缘点在的x,y方向的梯度值。OpenCV的 Sobel 函数。
③.根据②的数据计算边缘点的梯度强度和梯度角度。OpenCV的CartToPolar函数。
④.遍历边缘点,保存边缘点对应的x,y梯度,并将梯度强度归一化处理(1除以该点梯度强度,这样得到的值都是[0,1]区间内的值)
并将边缘点坐标转换为相对于中心的相对坐标(实际上我这里使用的是第一个边缘点坐标,并没有使用中心点,因为找中心也需要计算)
经过以上操作,我们便建立好了模版。
2,模版匹配
①.计算边缘点在x,y方向的梯度值。同 1.②。
②.根据①的数据计算边缘点的梯度强度和梯度角度。
③.这步是最重要的,通过 归一化交叉相关(NCC) 算法计算模版边缘梯度和目标图像边缘梯度的相关性。
而且该算法得到的值就是匹配相关性的得分,分值范围在[0,1],具体实现可以去看代码。其实就是拿着你的模版边缘在图像中平移,每移动一步计算一下边缘点对应的梯度强度相关性,这里引用链接中实现了一种优化,如果计算边缘点梯度相似性过程中得分过低,就可以跳过后续边缘点的计算,直接移动到下一个位置。
本文章中提供的C#算法和处理流程只是对检测结果的实现,追求代码的简化,但是效率是最差的,实际上中间实现和引用链接完全不同,因为Canny算法中已经包含了Sobel算法和计算梯度强度和梯度角度的过程以及遍历图像操作,所以获取模板操作的四个步骤完全可以合并到Canny函数中,但是EmguCV/OpenCV的Canny函数没有将这些中间变量暴露出来。引用链接中的实现是重写Canny算法,这样便能够使用Canny算法的中间变量。不需要再重复计算,经过一轮Canny算法即可建立模版数据
引用链接中还提及一些优化方法,比如对图像使用金字塔处理加快匹配速度,旋转建模使算法抗旋转。
拓展思维,我们可以发现梯度角度值没有使用,实际上也可以用于相似性检测,还能用于旋转角度的测量。
除了NCC算法,其它的一些基于灰度值的匹配算法也可照搬套用。
这里水平有限只提供一些思路,无法展开。
VisionPro的PatMax算法,Halcon的形状匹配算法都是基于边缘的模版匹配。
实际上搜Halcon作者的名字还是搜到一些相关资料的,摘录此处期待读者发挥:
Halcon机器视觉的一些效果演示 http://campar.in.tum.de/Main/AndreasHofhauser
网页最下面有几篇相关的实现论文可以下载。
Halcon的Carsten Steger博士的一些出版物 https://iuks.in.tum.de/members/steger/publications
其中有两篇是几种找相似模版算法的比较,网页搜 2D Object
因为这些人有Halcon这种成熟工业软件产品的关系,论文都很直白,原理+公式,只要看懂公式就能撸码实现。
当然具体的处理时间优化就属于边缘工作了,肯定不会在论文里,只能说按照论文撸出来的代码肯定能跑出基本效果。
参考性还是很高的。