OpenCV模板匹配matchTemplate详解:原理、算法与代码实现

小岛来信
小岛来信
发布时间:2026-10-13 | 4人浏览过
原创

本文深入解析OpenCV中模板匹配函数matchTemplate的工作原理,详细对比TM_SQDIFF、TM_CCORR及TM_CCOEFF等六种匹配算法的适用场景与数值含义,并结合Python代码演示如何获取最佳匹配位置及绘制结果,帮助开发者掌握图像局部特征识别的核心技术。

模板匹配的应用场景存在一定局限性,其成功匹配高度依赖于特定的环境条件,受多种因素影响,因此该方法的适应性相对有限。

模板匹配原理与局限性

模板匹配属于最基础的模式识别方法,旨在确定特定对象图案在图像中的具体位置,从而实现对象识别。作为图像处理中最基本且常用的匹配手段,它存在明显的局限性:仅支持平行移动匹配,若目标图像发生旋转或尺寸缩放,该算法将失效。

模板匹配的核心任务是在整幅图像中搜索并定位与给定子图像相匹配的区域。

其工作原理是在待检测图像上,按照从左到右、从上向下的顺序,逐区域计算模板图像与重叠子图像的匹配度。匹配程度越高,表明两者相似的可能性越大。

以下是具体的代码实现部分。


import cv2 as cv
import numpy as np

def template_demo():
  tpl = cv.imread("./temp.png")
  target = cv.imread("./1.png")
  cv.imshow("template image",tpl)
  cv.imshow("target image",target)
  methods = [cv.TM_SQDIFF_NORMED,cv.TM_CCORR_NORMED,cv.TM_CCOEFF_NORMED]  #各种匹配算法
  th,tw = tpl.shape[:2]  #获取模板图像的高宽
  for md in methods:
    result = cv.matchTemplate(target,tpl,md)
    # result是我们各种算法下匹配后的图像
    # cv.imshow("%s"%md,result)
    #获取的是每种公式中计算出来的值,每个像素点都对应一个值
    min_val,max_val,min_loc,max_loc = cv.minMaxLoc(result)
    if md == cv.TM_SQDIFF_NORMED:
      tl = min_loc  #tl是左上角点
    else:
      tl = max_loc
    br = (tl[0]+tw,tl[1]+th)  #右下点
    cv.rectangle(target,tl,br,(0,0,255),2)  #画矩形
    cv.imshow("match-%s"%md,target)


src = cv.imread("./1.png") #读取图片
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)  #创建GUI窗口,形式为自适应
cv.imshow("input image",src)  #通过名字将图像和窗口联系
template_demo()
cv.waitKey(0)  #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作
cv.destroyAllWindows() #销毁所有窗口

补充说明如下内容。

常见模板匹配算法详解

1. 常见的几种模板匹配算法对比

① TM_SQDIFF为平方差匹配,TM_SQDIFF_NORMED为标准平方差匹配。该方法通过计算平方差进行匹配,最优匹配值为0;匹配效果越差,对应的匹配值越大。

② TM_CCORR为相关性匹配,TM_CCORR_NORMED为标准相关性匹配。该方法采用模板与图像间的乘法操作,数值越大表示匹配程度越高,0表示匹配效果最差。

③ TM_CCOEFF为相关性系数匹配,TM_CCOEFF_NORMED为标准相关性系数匹配。该方法将模板对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示糟糕匹配,0表示无相关性(即随机序列)。

总结而言,随着测量方式从简单的平方差向更复杂的相关系数演进,匹配精度逐渐提高,但相应的计算代价也随之增加。

对于相关性指标,数值越接近1表示匹配效果越好。

对于平方差指标,数值越小表示匹配效果越好。因此,TM_SQDIFF在使用逻辑上与其他算法存在区别。

核心函数matchTemplate与minMaxLoc使用指南

2. 核心函数解析:result = cv.matchTemplate(target, tpl, md)

OpenCV中的目标匹配函数为matchTemplate,其函数原型为:matchTemplate(image, templ, method[, result[, mask]]) -> result。其中,image参数代表待搜索的源图像,数据类型必须为8位整数或32位浮点;templ参数代表模板图像,其尺寸不得大于源图像,且数据类型需与源图像一致;method参数指定计算匹配程度的算法类型;result参数输出匹配结果图像,必须为单通道32位浮点格式。若源图像尺寸为W x H,模板尺寸为w x h,则结果图像result的尺寸为(W-w+1)x(H-h+1)。

其中,result变量存储了模板图像在源图像中匹配区域的位置信息。

3. 获取极值位置:min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)

OpenCV提供的minMaxLoc函数用于在给定矩阵中寻找最大值和最小值及其位置,该函数不适用于多通道数组。若需在所有通道中查找极值,需先将数组重新解释为单通道。函数原型为:minMaxLoc(src[, mask]) -> minVal, maxVal, minLoc, maxLoc。src参数为输入的单通道图像;mask为可选的掩码,用于选择子数组;minVal和maxVal分别返回最小值和最大值(若不需要可设为NULL);minLoc和maxLoc分别返回最小值和最大值的指针(在2D情况下,若不需要可设为NULL)。

结合上述每种匹配算法,我们可以观察其返回的具体数值。


result = cv.matchTemplate(target,tpl,md)
    #获取的是每种公式中计算出来的值,每个像素点都对应一个值
    min_val,max_val,min_loc,max_loc = cv.minMaxLoc(result)
    print("--------------%s--------------"%md)
    print("min_val",min_val)
    print("max_val",max_val)
    print("min_loc",min_loc)
    print("max_loc",max_loc)
    print("--------------%s--------------" % md)

--------------1--------------  #TM_SQDIFF_NORMED标准平方差匹配
min_val 0.0  #标准差是越小为0代表匹配上了
max_val 0.22279763221740723
min_loc (108, 248)
max_loc (3, 480)
--------------1--------------
--------------3--------------  #TM_CCORR_NORMED标准相关性匹配
min_val 0.9228140115737915
max_val 1.0  #相关性是越接近1代表匹配上了
min_loc (9, 378)
max_loc (108, 248)
--------------3--------------
--------------5--------------  #TM_CCOEFF_NORMED标准相关性系数匹配
min_val -0.10706906020641327
max_val 1.0  #相关性越接近1越好
min_loc (186, 248)
max_loc (108, 248)
--------------5--------------

通过查看min_loc和max_loc的关系,可以确定最佳匹配点。


cv.line(target,min_loc,max_loc,(0,255,255),2)

以上内容为本文的全部介绍,希望对读者的学习有所帮助,也欢迎大家继续支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表