OpenCV模版匹配中有6种方法,我们今天就来分别看下不同方法的效果。
cv2.matchTemplate()result = cv2.matchTemplate(image, templ, method, mask=None)
image:源图像(8位灰度或彩色)。
templ:模板图像,大小不能超过源图像。
method:匹配方法,决定了相似度如何计算。常用以下6种:
| 方法标识符 (OpenCV) | 公式逻辑 | 最佳值是 |
|---|---|---|
cv2.TM_SQDIFF |
平方差 | 最小值 |
cv2.TM_SQDIFF_NORMED |
归一化平方差 | 最小值(越接近0越好) |
cv2.TM_CCORR |
相关性 | 最大值 |
cv2.TM_CCORR_NORMED |
归一化相关性 | 最大值(越接近1越好) |
cv2.TM_CCOEFF |
相关系数 | 最大值 |
cv2.TM_CCOEFF_NORMED |
归一化相关系数 | 最大值(越接近1越好) |
归一化方法(后缀 _NORMED)对光照变化更鲁棒,推荐优先使用。
对于 _SQDIFF 系列,完全匹配时理论值为 0,因此要找最小值;其余方法找最大值。
我们就用实例代码来看看效果。
#6种匹配方式的对比
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('./images/lina.png', 0) #0表示灰度图
template = cv2.imread('./images/linat.png', 0)
#定义6种方法列表
methods = ['cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED',
'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED',
'cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED']
# w,h = template.shape[:2]
w,h = template.shape[1], template.shape[0]
print(w,h)
for method in methods:
img2 = img.copy()
#匹配
res =cv2.matchTemplate(img, template, eval(method))
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if method in ['cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']:
# 选择最小值
top_left = min_loc
else:
# 选择最大值
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(img2, top_left, bottom_right, (255, 0, 0), 2)
#画子图,画在一起
plt.subplot(121)
plt.imshow(res, cmap='gray')
plt.axis('off')
plt.subplot(122)
plt.imshow(img2, cmap='gray')
plt.axis('off')
plt.suptitle(f'{method} - Result')
plt.show()
实例效果图如下:

上面这些图中,img的图片如下:

模版图片如下:

6种方法中,有5种方法基本都可以正确匹配找到模版图片,只有cv2.TM_CCORR方法产生了偏差。

全部评论