opencv-python 详解模板匹配matchTemplate
模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题。它是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。通俗来讲就是利用小图来找大图,可以看作是一种简陋的目标检测方法。它只是将模板图像滑动到输入图像上(就像在2D卷积中一样),然后在
作者:RayChiu_Labloy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
模板匹配是一种最原始、最基本的模式识别方法,研究某一特定对象物的图案位于图像的什么地方,进而识别对象物,这就是一个匹配问题。它是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。
通俗来讲就是利用小图来找大图,可以看作是一种简陋的目标检测方法。它只是将模板图像滑动到输入图像上(就像在2D卷积中一样),然后在模板图像下比较模板和输入图像的拼图。举例来说,对于以下两张图片(大图为原图,左上角小图为样章),使用cv.matchTemplate()函数进行匹配,再使用cv.minMaxLoc()函数获得全局极值的位置和数值大小。

先看第一个函数也是最重要的匹配方法:
result = cv.matchTemplate( image, templ, method[, result[, mask]] )
- image:原图
- templ:用于匹配的样章
- method:原图与样章匹配效果的判别标准,参考链接:TemplateMatchModes
- result:输出图片
- mask:template的遮罩
其中method 有如下几种:
CV_TM_SQDIFF:平方差匹配法;
CV_TM_SQDIFF_NORMED:归一化平方差匹配法;
CV_TM_CCORR:相关匹配法;
CV_TM_CCORR_NORMED:归一化相关匹配法;
CV_TM_CCOEFF:系数匹配法;
CV_TM_CCOEFF_NORMED:化相关系数匹配法
对应公式:

公式计算过程详解:
在这里先谈一下matchTemplate()的result,result是一个结果矩阵,假设待匹配图像为 I,宽高为(W,H),模板图像为 T,宽高为(w,h)。那么result的大小就为(W-w+1,H-h+1) 。
原因是因为,在匹配时,以模板大小的搜索框依次遍历整张图片时,每行需要遍历(W-w+1)次,每列需要遍历(H-h+1)。
以下列矩阵为例:

待匹配图像 I.Size(5,5),模板图像 T.Size(3,3)。以Size(3,3)的搜索框遍历图像I时,x方向需要遍历3次,y方向遍历3次。
多观察发现,归纳出result.Size(W-w+1,H-h+1)。
然后回到谈method,T 代表模板图像,I 代表待匹配图像。x ,y 代表当前搜索框在 I 矩阵中左上角元素的坐标。x' ,y' 代表T和搜索框框出来的 I 的矩阵的元素坐标。
如下图:以归一化相关系数匹配方法为例。此时搜索框左上角坐标(x,y)=(0,0)。

对此搜索框内的矩阵和模板矩阵进行数据比较。
第一步:减去均值。
第二步:求俩矩阵内积,以及两个矩阵内元素平方和的平方的乘积。

对公式研究发现:
方差匹配方法:完全匹配会得到1, 完全不匹配会得到0。
归一化方差匹配方法:完全匹配结果为0。
相关性匹配方法:完全匹配会得到很大值,不匹配会得到一个很小值或0。
归一化的互相关匹配方法:完全匹配会得到1, 完全不匹配会得到0。
相关系数匹配方法:完全匹配会得到一个很大值,完全不匹配会得到0,完全负相关会得到很大的负数。
(此处与书籍以及大部分分享的资料所认为不同,研究公式发现,只有归一化的相关系数才会有[-1,1]的值域)
归一化的相关系数匹配方法:完全匹配会得到1,完全负相关匹配会得到-1,完全不匹配会得到0。
再来看另一个函数:
minVal,maxVal,minLoc,maxLoc=cv.minMaxLoc(src [,mask])
函数功能:假设有一个矩阵a,现在需要求这个矩阵的最小值,最大值,并得到最大值,最小值的索引。咋一看感觉很复杂,但使用这个CV2.minMaxLoc()函数就可全部解决。函数返回的四个值就是上述所要得到的。
实验代码:
import cv2
import numpy as np
img = cv2.imread("E:/Users/raychiu/Desktop/simpsons.jpg")
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.imread("E:/Users/raychiu/Desktop/barts_face.jpg", cv2.IMREAD_GRAYSCALE)
cv2.imshow("template", template)
cv2.imshow("gray_img", gray_img)
w, h = template.shape[::-1]
result = cv2.matchTemplate(gray_img, template, cv2.TM_CCOEFF_NORMED)
minval, maxval, minloc, maxloc = cv2.minMaxLoc(result)
print(minval, maxval, minloc, maxloc)
loc = np.where(result >= 0.6)
# for pt in zip(*loc[::-1]):
# cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 3)
pt = maxloc
cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 255, 0), 3)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
参考:OpenCV-Python系列之模板匹配 - 哔哩哔哩
https://blog.csdn.net/qq_42791845/article/details/103700503
【如果对您有帮助,交个朋友给个一键三连吧,您的肯定是我博客高质量维护的动力!!!】
更多推荐



所有评论(0)