原理 :利用相關匹配的算法(cv2.TM_COEFF_NORMED), 簡單講就是用此算法把模板計算出來,再計算出圖片的值,從圖片中查找出最相近的位置。
import cv2 import numpy as np import imutils def template_matching(image_full_path, tmpl_full_path, min_confidence=0.93, ): """ :param image_full_path: 輸入圖片路徑,在該圖片中查找模板圖像 :param tmpl_full_path: 模板圖片,在輸入圖片中查找此模板 :param min_confidence: 最小信心度,該方法返回大於此信心度的結果 :return: 返回result_dic ==> {信心度:(坐標Tuple)}, sorted(confidence_list,reverse=True)==>信心度降序排列列表 """ img = cv2.imread(image_full_path) # 讀取輸入圖片 gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉換為灰度圖,采用CV_BGR2GRAY,轉換公式Gray = 0.1140*B + 0.5870*G + 0.2989*R # template = cv2.imread(tmpl_full_path, cv2.IMREAD_GRAYSCALE) # 讀取模板圖片的灰度圖 template = cv2.imread(tmpl_full_path) # 為保證輸入圖片與模板一致性,兩張圖片用相同方法讀取灰度圖片 template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) # w, h = template.shape[::-1] # 獲取模板的寬和高(繪圖時使用,本函數內無意義) res = cv2.matchTemplate(gray_img, template, cv2.TM_CCOEFF_NORMED) # TM_CCOEFF_NORMED 標准相關匹配 loc = np.where(res >= min_confidence) # 在結果中篩選大於最小信心度的結果 result_dic = {} confidence_list = [] for pt in zip(*loc[::-1]): result_dic[res[pt[1]][pt[0]]] = pt confidence_list.append(res[pt[1]][pt[0]]) # cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 3) # 在目標位置繪制一個紅色矩形框,邊寬3px return result_dic, sorted(confidence_list, reverse=True) def diff_size_template_matching(image_full_path, tmpl_full_path, min_confidence=0.95, ): """ :param image_full_path: 輸入圖片路徑,在該圖片中查找模板圖像 :param tmpl_full_path: 模板圖片,在輸入圖片中查找此模板 :param min_confidence: 最小信心度,該方法返回大於此信心度的結果 :return: 返回result_dic ==> {信心度:(坐標Tuple)}, sorted(confidence_list,reverse=True)==>信心度降序排列列表 """ template = cv2.imread(tmpl_full_path) template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) # 獲得灰度模板 image = cv2.imread(image_full_path) gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 獲得灰度圖片 result_dic = {} confidence_list = [] for scale in np.linspace(0.2, 1.0, 100)[::-1]: # 1倍到0.2倍 分100級變化(級數越高,可能獲得的匹配精度越高,處理越慢) resized = imutils.resize(template, width=int(template.shape[1] * scale)) # 以scale 為倍數改變模板大小 # (w, h) = resized.shape[::-1] # 求改變后的模板寬高 result = cv2.matchTemplate(gray_img, resized, cv2.TM_CCOEFF_NORMED) # 每次改變都進行一次匹配 loc = np.where(result >= min_confidence) # 在結果中篩選大於最小信心度的結果 for pt in zip(*loc[::-1]): result_dic[result[pt[1]][pt[0]]] = pt confidence_list.append(result[pt[1]][pt[0]]) # cv2.rectangle(image, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 3) return result_dic, sorted(confidence_list, reverse=True) if __name__ == '__main__': pass