模板匹配

1. 模板匹配

模板匹配就是用模板图(通常是一个小图)在目标图像(通常是一个比模板图大的图片)中不断的滑动比较,通过某种比较方法来判断是否匹配成功。

在这里插入图片描述

2. 匹配方法

res=cv2.matchTemplate(image, templ, method)

  • image:原图像,这是一个灰度图像或彩色图像(在这种情况下,匹配将在每个通道上独立进行)。

  • templ:模板图像,也是灰度图像或与原图像相同通道数的彩色图像。

  • method:匹配方法,可以是以下之一:

    • cv2.TM_CCOEFF
    • cv2.TM_CCOEFF_NORMED
    • cv2.TM_CCORR
    • cv2.TM_CCORR_NORMED
    • cv2.TM_SQDIFF
    • cv2.TM_SQDIFF_NORMED
    • 这些方法决定了如何度量模板图像与原图像子窗口之间的相似度。
  • 返回值res

    函数在完成图像模板匹配后返回一个结果矩阵,这个矩阵的大小与原图像相同。矩阵的每个元素表示原图像中相应位置与模板图像匹配的相似度。

    匹配方法不同,返回矩阵的值的含义也会有所区别。以下是几种常用的匹配方法及其返回值含义:

    1. cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED

      返回值越接近0,表示匹配程度越好。最小值对应的最佳匹配位置。

    2. cv2.TM_CCORRcv2.TM_CCORR_NORMED

      返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

    3. cv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED

      返回值越大,表示匹配程度越好。最大值对应的最佳匹配位置。

    2.1 平方差匹配

    cv2.TM_SQDIFF

    以模板图与目标图所对应的像素值使用平方差公式来计算,其结果越小,代表匹配程度越高,计算过程举例如下。

    注意:模板匹配过程皆不需要边缘填充,直接从目标图像的左上角开始计算。
    在这里插入图片描述

2.2 归一化平方差匹配

cv2.TM_SQDIFF_NORMED

与平方差匹配类似,只不过需要将值统一到0到1,计算结果越小,代表匹配程度越高,计算过程举例如下。
在这里插入图片描述

2.3 相关匹配

cv2.TM_CCORR

使用对应像素的乘积进行匹配,乘积的结果越大其匹配程度越高,计算过程举例如下。

在这里插入图片描述

2.4 归一化相关匹配

cv2.TM_CCORR_NORMED

与相关匹配类似,只不过是将其值统一到0到1之间,值越大,代表匹配程度越高,计算过程举例如下。

在这里插入图片描述

2.5 相关系数匹配

cv2.TM_CCOEFF

需要先计算模板与目标图像的均值,然后通过每个像素与均值之间的差的乘积再求和来表示其匹配程度,1表示完美的匹配,-1表示最差的匹配,计算过程举例如下。
在这里插入图片描述

2.6 归一化相关系数匹配

cv2.TM_CCOEFF_NORMED

也是将相关系数匹配的结果统一到0到1之间,值越接近1代表匹配程度越高,计算过程举例如下。
在这里插入图片描述

3. 绘制轮廓

找的目标图像中匹配程度最高的点,我们可以设定一个匹配阈值来筛选出多个匹配程度高的区域。

loc=np.where(array > 0.8) #loc包含array中所有大于0.8的元素索引的数组

示例代码:

import cv2
import numpy as np
image_np=cv2.imread("../src/picture.png")
# cv2.imshow("image",image_np)
template=cv2.imread("../src/muban.png")
#灰度化
image_np_gray=cv2.cvtColor(image_np,cv2.COLOR_BGR2GRAY)
template_gray=cv2.cvtColor(template,cv2.COLOR_BGR2GRAY)

#获取模板图的宽和高:
h,w=template.shape[:2]

#模板匹配:
res=cv2.matchTemplate(image_np_gray,template_gray,cv2.TM_CCOEFF_NORMED)

#对返回结果进行处理:
threshold=0.57
#对数组里的数据进行判断,如果满足,则返回其对应坐标

location=np.where(res>threshold)
# print(location[::-1])
# for i in zip(*location[::-1]):
#     print(i)

#对得到点的坐标进行反转处理,并在原图中框出来
for left_top in zip(*location[::-1]):
    right_bottom=(left_top[0]+w,left_top[1]+h)
    cv2.rectangle(image_np,left_top,right_bottom,(0,0,255))

#显示模板匹配的结果:
cv2.imshow("image_np",image_np)
cv2.waitKey(0)

在这里插入图片描述

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐