模板匹配

空扰寡人 提交于 2020-03-01 15:40:35
  • 什么是模板匹配

    • 模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在OpenCV里面有六种方法,然后将每次的计算结果放入一个矩阵里,作为结果输出。
    • 假设原图像是AxB 大小,而模板是axb 大小,则输出结果的矩阵就是(A-a+1)x(B-b+1)
    • cv2.matchTemplate(img, template, method) 模板匹配函数
    • min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 得到矩阵最大值和最小值,以及最大值和最小值的位置
  • 六种计算方法

    • TM_SQDIFF(平方差匹配):这类方法利用平方差来进行匹配,最好匹配为0.匹配越差,匹配值越大.
    • TM_CCORR(相关匹配):这类方法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果.
    • TM_CCOEFF(相关匹配):这类方法将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示糟糕的匹配,0表示没有任何相关性(随机序列).
      •     其中

    • TM_SQDIFF_NORMED(标准平方差匹配):计算归一化平方不同,计算出来的值越接近0,越相关。
    • TM_CCORR_NORMED(标准相关匹配):计算归一化相关性,计算出来的值越接近1,越相关。
    • TM_CCOEFF_NORMED(标准相关匹配):计算归一化相关系数,计算出来的值越接近1,越相关。
  • 六种方法对比

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt


# 要读取两个图片
img = cv.imread('lena.jpg', 0) # 0表示读取灰度图
template = cv.imread('face.jpg', 0)

methods = ['cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED', 'cv.TM_CCORR', 'cv.TM_CCORR_NORMED', 'cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED'] # 六种计算方法

for meth in methods:
    img2 = img.copy()
    method = eval(meth) # 得到的是计算方法的真值(0,1,2,3,4,5)
    res = cv.matchTemplate(img, template, method)
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
    
    # 如果是cv.TM_SQDIFF或者cv.TM_SQDIFF_NORMED,就取最小值,否则取最大值
    if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + template.shape[1], top_left[1] + template.shape[0])
    # 画矩形
    cv.rectangle(img2, top_left, bottom_right, 255, 2)
    
    plt.subplot(131), plt.imshow(res, cmap='gray')
    plt.xticks([]), plt.yticks([])
    plt.subplot(132), plt.imshow(img2, cmap='gray')
    plt.xticks([]), plt.yticks([])
    plt.subplot(133), plt.imshow(template, cmap='gray')
    plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)
    plt.show()

 

 

 

 

 

 

    •    六种方法中,最后三种,带归一化的效果最好,优先选择
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!