19.1模板匹配
模板匹配就是用模板圖(通常是一個小圖)在目標圖像(通常是一個比模板圖大的圖片)中不斷的滑動比較,通過某種比較方法來判斷是否匹配成功,找到模板圖所在的位置。
不會有邊緣填充。
類似于卷積,滑動比較,挨個比較象素。
返回結果大小是:目標圖大小-模板圖大小+1。
19.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
函數在完成圖像模板匹配后返回一個結果矩陣,這個矩陣的大小與原圖像相同。矩陣的每個元素表示原圖像中相應位置與模板圖像匹配的相似度。
匹配方法不同,返回矩陣的值的含義也會有所區別。以下是幾種常用的匹配方法及其返回值含義:
-
cv2.TM_SQDIFF
或cv2.TM_SQDIFF_NORMED
:返回值越接近0,表示匹配程度越好。最小值對應的最佳匹配位置。
-
cv2.TM_CCORR
或cv2.TM_CCORR_NORMED
:返回值越大,表示匹配程度越好。最大值對應的最佳匹配位置。
-
cv2.TM_CCOEFF
或cv2.TM_CCOEFF_NORMED
:返回值越大,表示匹配程度越好。最大值對應的最佳匹配位置。
19.2.1 平方差匹配
cv2.TM_SQDIFF
以模板圖與目標圖所對應的像素值使用平方差公式來計算,其結果越小,代表匹配程度越高,計算過程舉例如下。
注意:模板匹配過程皆不需要邊緣填充,直接從目標圖像的左上角開始計算。
19.2.2 歸一化平方差匹配
cv2.TM_SQDIFF_NORMED
與平方差匹配類似,只不過需要將值統一到0到1,計算結果越小,代表匹配程度越高,計算過程舉例如下。
19.2.3 相關匹配
cv2.TM_CCORR
使用對應像素的乘積進行匹配,乘積的結果越大其匹配程度越高,計算過程舉例如下。
19.2.4 歸一化相關匹配
cv2.TM_CCORR_NORMED
與相關匹配類似,只不過是將其值統一到0到1之間,值越大,代表匹配程度越高,計算過程舉例如下。
19.2.5 相關系數匹配
cv2.TM_CCOEFF
需要先計算模板與目標圖像的均值,然后通過每個像素與均值之間的差的乘積再求和來表示其匹配程度,1表示完美的匹配,-1表示最差的匹配,計算過程舉例如下。
19.2.6 歸一化相關系數匹配
cv2.TM_CCOEFF_NORMED
也是將相關系數匹配的結果統一到0到1之間,值越接近1代表匹配程度越高,計算過程舉例如下。
19.3 繪制輪廓
找的目標圖像中匹配程度最高的點,我們可以設定一個匹配閾值來篩選出多個匹配程度高的區域。
-
loc=np.where(array > 0.8) #loc包含array中所有大于0.8的元素索引的數組
np.where(condition) 是 NumPy 的一個函數,當條件為真時,返回滿足條件的元素的索引。
-
zip(*loc)
-
*loc
是解包操作,將loc
中的多個數組拆開,作為單獨的參數傳遞給zip
。 -
zip
將這些數組按元素一一配對,生成一個迭代器,每個元素是一個元組,表示一個坐標點。
-
x=list([[1,2,3,4,3],[23,4,2,4,2]]) print(list(zip(*x)))#[(1, 23), (2, 4), (3, 2), (4, 4), (3, 2)]
import cv2 as cv
import numpy as np#讀圖
img = cv.imread('images/huoyingrenzhe.jpg')
temp = cv.imread('images/zhipai.jpg')
#轉灰度
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
temp_gray = cv.cvtColor(temp, cv.COLOR_BGR2GRAY)
#模板匹配,拿到匹配結果,返回匹配程度矩陣
res = cv.matchTemplate(img_gray, temp_gray, cv.TM_CCOEFF_NORMED)
#設置閾值,使用np.where()獲取符合條件的坐標
threshold = 0.8
#得到[[y1,y2,y3...],[x1,x2,x3...]]
loc = np.where(res >= threshold)
h,w = temp.shape[:2]
#解包
for pt in zip(*loc[::-1]):cv.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
cv.imshow('img', img)
cv.waitKey(0)
cv.destroyAllWindows()
![]() | ![]() |
注意得到[[y1,y2,y3...],[x1,x2,x3...]]這樣的返回值,因為先返回行索引再返回列索引