1. cv2.matchTemplate(src, template, method) # 用於進行模板匹配
參數說明: src目標圖像, template模板,method使用什么指標做模板的匹配度指標
2. min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ret) # 找出矩陣中最大值和最小值,即其對應的(x, y)的位置
參數說明:min_val, max_val, min_loc, max_loc 分別表示最小值,最大值,即對應的位置, ret輸入的矩陣
3. cv2.rectangle(img, (x, y), (x+w. y+h), (0, 0, 255), 2) 用於在圖像上畫出矩陣
參數說明:img表示圖片,(x, y)表示矩陣左上角的位置,(x+w, y+h)表示矩陣右下角的位置, (0, 0, 255)表示顏色,2表示線條
模板匹配:表示使用一個圖像的模板,在一副主圖上:從左到右,從上到下進行滑動,每次只滑動一個像素,最終結果的維度為(h - ht + 1, w - wt + 1),
h表示主圖的長,ht表示模板的長, w表示主圖的寬,wt表示模板的寬
對於結果的求法:這里使用幾個指標:
這是模板匹配中的6個指標
第一個指標,用於計算均分根誤差,均方根誤差越小,表示模板與主圖的部分匹配度越高
第二個指標,表示相關性, 即dot(x, y), 相關性越大說明,模板與主圖部分的匹配度越高
第三個指標, 表示相關性系數,即dot(x-x', y-y') x' 和 y’表示的是x的均值和y的均值,相關性系數越大,模板與主圖部分的匹配度越高
下面三個指標的歸一化表示, /sqrt(dot(∑x^2 + ∑y^2)) , 下面是數學公式
單個目標的模板匹配
代碼:
第一步:讀入目標圖片,讀入模板圖片,對目標圖片和模板圖片進行灰度化操作
第二步:使用cv2.matchtemplate(img, template, cv2.TM_CCOEFF_NORMED) 進行模板匹配,獲得大量的ret結果
第三步:使用min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ret) # 找出最大值數所在的位置
第四步:使用cv2.rectangle(original, max_loc, (max_loc[0] + w, max_loc[1] + h), (0, 0, 255), 2) 進行畫圖操作
第五步:我們對上述的方法進行循環,嘗試各種方法所得到的結果
import cv2 import numpy as np import matplotlib.pyplot as plt original = cv2.imread('lena.jpg') img = cv2.imread('lena.jpg', 0) template = cv2.imread('face.jpg', 0) h, w = template.shape[:2] methods = ['cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCOEFF', 'cv2.TM_SQDIFF_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED'] ret = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ret) draw_img = original.copy() ret = cv2.rectangle(draw_img, max_loc, (max_loc[0]+w, max_loc[1]+h), (0, 0, 255), 2) cv2.imshow('ret', ret) cv2.waitKey(0) cv2.destroyAllWindows()
for method in methods: draw_img = img.copy() op = eval(method) ret = cv2.matchTemplate(img, template, op) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ret) if method in ['cv2.TM_SQDIFF_NORMED', 'cv2.TM_SQDIFF']: loc = min_loc else: loc = max_loc rect = cv2.rectangle(draw_img, loc, (loc[0] + w, loc[1] + h), (0, 0, 255), 2) plt.subplot(121) plt.imshow(ret, cmap='gray') plt.title(method) plt.subplot(122) plt.imshow(rect, cmap='gray') plt.title(method) plt.show()
多目標匹配, 多目標匹配使用的是一個閾值,當大於這個閾值時,我們認為已經獲得一個目標的匹配值
而使用cv2.matchTemplate匹配出的ret實際是一些上述指標的數值
代碼:
第一步:讀入圖片,對目標圖片和模板進行灰度化
第二步:匹配模板,獲得ret
第三步:使用np.where(ret>0.8) 刪選合適的位置,這個位置是(0, 2)即0表示豎的,2表示橫着的
第四步:使用index[::-1]將位置進行調換,使用*index[::-1]使得矩陣發生拆分,使用zip進行兩兩組合
第五步:使用cv2.rectangle進行畫多個矩陣
第六步:使用cv2.imshow展示圖片
original = cv2.imread('mario.jpg') img = cv2.imread('mario.jpg', 0) template = cv2.imread('mario_coin.jpg', 0) h, w = template.shape[:2] ret = cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED) index = np.where(ret > 0.8) draw_img = original.copy() for i in zip(*index[::-1]): rect = cv2.rectangle(draw_img, i, (i[0]+w, i[1]+h), (0, 0, 255), 1) cv2.imshow('rect', np.hstack((original, rect))) cv2.waitKey(0) cv2.destroyAllWindows()