OpenCV模版匹配中6种方法对比

21人浏览 / 0人评论 / 添加收藏

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方法产生了偏差。

全部评论