-
什么是模板匹配
- 模板匹配和卷積原理很像,模板在原圖像上從原點開始滑動,計算模板與(圖像被模板覆蓋的地方)的差別程度,這個差別程度的計算方法在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,越相關。
- TM_SQDIFF(平方差匹配):這類方法利用平方差來進行匹配,最好匹配為0.匹配越差,匹配值越大.
-
六種方法對比
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()
-
- 六種方法中,最后三種,帶歸一化的效果最好,優先選擇