在許多電腦視覺應用中,我們常常需要在一張大圖中尋找特定的小圖(模板)。
這種方法稱為 模板匹配(Template Matching),常用於 GUI 自動化測試、遊戲畫面偵測、零件定位等場景。
模板匹配是透過滑動視窗的方式,將模板圖片逐像素套用到大圖中,計算相似度分數。
OpenCV 提供 cv2.matchTemplate
來完成此操作。
常見的比對方法:
cv2.TM_CCOEFF
cv2.TM_CCOEFF_NORMED
cv2.TM_CCORR
cv2.TM_CCORR_NORMED
cv2.TM_SQDIFF
cv2.TM_SQDIFF_NORMED
📖 一般推薦使用 NORMED 版本,結果會在
[-1,1]
或[0,1]
範圍內,較好判斷。
假設我們有一張大圖 lake.jpg
,以及要尋找的模板小圖 boat.jpg
。
import cv2
# 讀取圖片
img = cv2.imread("lake.jpg")
template = cv2.imread("boat.jpg")
cv2.imshow("img", img)
cv2.imshow("template", template)
# 將以下程式碼放在所有顯示語句的最後面
cv2.waitKey()
cv2.destroyAllWindows()
只尋找一個最佳匹配位置,適合目標只出現一次的情境。
import numpy as np
# 轉灰階
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
w, h = template_gray.shape[::-1]
# 模板匹配
res = cv2.matchTemplate(img_gray, template_gray, cv2.TM_CCOEFF_NORMED)
# 取得最佳匹配位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# 取最大值的位置
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
# 繪製矩形
cv2.rectangle(img, top_left, bottom_right, (0, 255, 0), 2)
cv2.imshow("Template Matching", img)
若大圖中有多個相同模板,可設定相似度閾值,篩選所有大於該值的位置。
threshold = 0.5 # 相似度閾值,建議設在 0.7~0.9 之間,數值越高代表匹配要求越嚴格
loc = np.where(res >= threshold) # 找出所有相似度大於閾值的位置
for pt in zip(*loc[::-1]): # loc[::-1] 轉換為 (x, y) 座標
cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2) # 在每個匹配位置畫紅色框
cv2.imshow("Multiple Matches", img)
程式與參數說明:
threshold
:設定模板匹配的相似度門檻,數值越高只會顯示最接近的結果,太低可能會有誤判。我這裡故意將數值設定成較低的0.5,可以看到旁邊另個艘船就出現誤判而出現了。np.where(res >= threshold)
:回傳所有符合條件的座標點。cv2.rectangle()
:在每個找到的匹配位置畫出紅色矩形框,框的大小與模板一致。這時會發現同個物件被重複框選,為了解決重複框選的問題,我們將程式調整一下。
OpenCV 有提供 groupRectangles,可以把多個重疊的框合併成一個。
# 假設 res 已經算好,w, h 是模板大小
threshold = 0.5
loc = np.where(res >= threshold)
rects = [] # 暫存所有偵測到的框
for pt in zip(*loc[::-1]):
rects.append([pt[0], pt[1], w, h]) # (x, y, w, h)
# 用 groupRectangles 合併重疊的框
rects, weights = cv2.groupRectangles(rects, groupThreshold=1, eps=0.5)
# 畫框
for (x, y, w, h) in rects:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.imshow("Multiple Matches", img)
方法 | 優點 | 缺點 | 適用場景 |
---|---|---|---|
模板匹配 | 實作簡單、速度快 | 不支援縮放/旋轉 | 固定大小與方向目標 |
特徵點方法(ORB/SIFT) | 支援縮放、旋轉、變形 | 實作較複雜、速度較慢 | 目標有變形或多樣性 |
補充說明:
模板匹配是一種簡單直接的方法,適合固定大小與方向的目標。
若目標在影像中有縮放或旋轉差異,建議使用特徵點方法以提升辨識效果。