文章目錄
- 前言
- 1.導入庫
- 2.圖片預處理
- 3.輸出模板圖片的寬和高
- 4.模板匹配
- 5.獲取匹配結果中所有符合閾值的點的坐標
- 5.1 threshold = 0.9:
- 5.2 loc = np.where(res >= threshold):
- 6.遍歷所有匹配點
- 6.1 loc 的結構回顧
- 6.2 loc[::-1] 的作用
- 6.2.1 為什么需要反轉?
- 6.3 zip(*loc[::-1]) 的作用
- 7.畫出模板匹配矩形框
- 7.1 功能
- 7.2 參數詳解
- 7.3 關鍵細節
- 7.4 常見問題
- 8.運行結果
- 9. 總結
前言
上文《OpenCV 模板匹配方法詳解》我們詳細介紹了模板匹配這一方法,本文我們來介紹一下模板與多個對象匹配的方法。
其中有很多的函數需要我們來詳細介紹,接下來我們直接看代碼講解:
1.導入庫
import cv2
import numpy as np
- 導入opencv庫和numpy庫
2.圖片預處理
img_rgb = cv2.imread("image.jpg")
img_gray = cv2.cvtColor(img_rgb,cv2.COLOR_BGR2GRAY)
template = cv2.imread("tem.jpg",0)
- 導入圖片,并轉化為灰度圖
- 導入的圖片如下圖所示,左圖為匹配圖片,右圖為模板圖片
3.輸出模板圖片的寬和高
h,w = template.shape[:2]
- template.shape:假設 template 是一個 NumPy 數組(通常是圖像數據),.shape 屬性會返回數組的維度信息。
- 對于圖像:通常返回 (高度, 寬度, 通道數),如果是灰度圖則只有 (高度, 寬度)
- [:2]:切片操作,取前兩個元素
- 例如對于彩色圖像 (480, 640, 3),取前兩個值得到 (480, 640)
- h, w = …:元組解包
- 將前兩個值分別賦值給變量 h (height/高度) 和 w (width/寬度)
所以這行代碼的作用是:獲取模板圖像的高度和寬度,分別存入變量 h 和 w 中。
4.模板匹配
# 使用模板匹配方法 cv2.matchTemplate 進行模板匹配
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
功能:
- 模板匹配:在 img_gray(灰度圖像)中滑動 template(模板圖像),計算每個位置的 相似度,并返回一個 相似度矩陣 res。
- 匹配方法:cv2.TM_CCOEFF_NORMED 是 歸一化相關系數匹配,取值范圍 [-1, 1],越接近 1 表示匹配度越高。
返回值 res:
- res 是一個 二維浮點型數組,大小 = (img_h - template_h + 1, img_w - template_w +1)(因為模板不能超出原圖邊界)
- 每個 res[y, x] 表示模板在 (x, y) 處的匹配得分。
5.獲取匹配結果中所有符合閾值的點的坐標
# 設定匹配閾值
threshold = 0.9
# 獲取匹配結果中所有符合閾值的點的坐標
loc = np.where(res >= threshold) #(符合條件的行,符合條件的列)
5.1 threshold = 0.9:
功能:
- 設定一個 匹配閾值,只有 res 中 ≥ 0.9 的點才被認為是有效匹配。
調整建議:
- 閾值越高(如 0.95),匹配越嚴格,漏檢率可能增加。
- 閾值越低(如 0.8),匹配越寬松,但可能誤檢。
5.2 loc = np.where(res >= threshold):
功能:
- 查找所有匹配度 ≥ threshold 的坐標,返回它們的 行列索引。
- loc 是一個 元組,包含兩個數組:
-
loc[0]:所有匹配點的 Y 坐標(行索引)
-
loc[1]:所有匹配點的 X 坐標(列索引
示例
假設 res 如下:
res = [[0.1, 0.3, 0.7],[0.8, 0.95, 0.6], # (1,1) = 0.95 ≥ 0.9[0.4, 0.9, 0.2] # (2,1) = 0.9 ≥ 0.9
]
執行 loc = np.where(res >= 0.9) 后:
loc = (array([1, 2]), array([1, 1])) # 匹配點:(Y=1,X=1), (Y=2,X=1)
注意:loc 是一個元組,格式為 (y_coords, x_coords),所以先返回的是Y值,再返回的是X值!!!
6.遍歷所有匹配點
for pt in zip(*loc[::-1]):
這段代碼 for pt in zip(*loc[::-1]): 是 模板匹配后處理 的關鍵部分,用于遍歷所有匹配到的目標位置,并調整坐標順序以適應 OpenCV 的繪圖要求。下面詳細解析它的作用:
6.1 loc 的結構回顧
在之前的代碼中:
loc = np.where(res >= threshold)
- loc 是一個元組,格式為 (y_coords, x_coords),所以先返回的是Y值,再返回的是X值
6.2 loc[::-1] 的作用
loc[::-1] 的作用loc[::-1] 對元組進行 反向切片,將 (y_coords, x_coords) 變成 (x_coords, y_coords)。
例如:
loc = (array([1, 2]), array([3, 4]))
loc[::-1] = (array([3, 4]), array([1, 2]))
# 現在順序是 (x, y)
6.2.1 為什么需要反轉?
- OpenCV 的坐標系統使用 (x, y)(列在前,行在后),而 np.where() 返回的是 (y, x),因此需要交換順序。
6.3 zip(*loc[::-1]) 的作用
- *loc[::-1] 解包 元組,相當于
zip(array([3, 4]), array([1, 2]))
- zip() 將兩個數組按元素配對,生成可迭代的 (x, y) 坐標對
for pt in zip(*loc[::-1]):print(pt) # 輸出:(3, 1), (4, 2)
最終效果:
遍歷所有匹配點,每次循環的 pt 是一個 (x, y) 坐標元組,可以直接用于 OpenCV 繪圖函數(如 cv2.rectangle())。
7.畫出模板匹配矩形框
cv2.rectangle(img_rgb,pt,(pt[0] + w,pt[1] + h),(0,0,255),1)
這段代碼 cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 1) 是 OpenCV 中用于在圖像上繪制矩形的函數,具體含義如下:
7.1 功能
在圖像 img_rgb 上,以 pt 為左上角起點,繪制一個 寬度為 w、高度為 h 的紅色矩形框,邊框粗細為 1 像素。
7.2 參數詳解
參數 | 含義 | 示例 |
---|---|---|
img_rgb | 要繪制矩形的目標圖像(RGB 格式) | 從 cv2.imread()讀取的圖像 |
pt | 矩形的 左上角坐標 (x, y) | (50, 100) 表示從圖像的第 50 列、第 100 行開始 |
(pt[0] + w, pt[1] + h) | 矩形的 右下角坐標 | 如果 pt=(50,100),w=30,h=20,則右下角是 (80, 120) |
(0, 0, 255) | 矩形顏色(BGR 格式) | (0,0,255)表示純紅色 |
1 | 矩形邊框的粗細(像素) | 1 表示 1 像素寬,-1表示填充矩形 |
7.3 關鍵細節
-
坐標順序
- OpenCV 使用 (x, y) 坐標,其中:
- x 是水平方向(列索引,從左到右遞增)
- y 是垂直方向(行索引,從上到下遞增)
- OpenCV 使用 (x, y) 坐標,其中:
-
顏色格式
- (0, 0, 255) 是 BGR 格式(不是 RGB),所以這里表示紅色。
- 常見顏色示例:
- 紅色:(0, 0, 255)
- 綠色:(0, 255, 0)
- 藍色:(255, 0, 0)
-
矩形尺寸
- w 和 h通常是模板圖像的寬度和高度(通過 template.shape[:2] 獲取)。
- 如果 w 或 h 超出圖像邊界,OpenCV 會報錯。
7.4 常見問題
-
為什么矩形顏色不對?
- 檢查顏色是否是 BGR 格式,例如紅色應為 (0, 0, 255),而非 RGB 的 (255, 0, 0)。
-
如何調整矩形樣式?
- 修改參數:
- 邊框粗細:2 表示更粗的邊框,-1 表示填充矩形。
- 顏色:(255, 0, 0) 是藍色,(0, 255, 0) 是綠色。
- 修改參數:
8.運行結果
9. 總結
到這里本篇博客就結束啦,感謝大家的閱讀!最近一直在堅持每天寫博客,當作是一個敘說心得的地方,在這個過程中自己通過不斷的回顧之前所學習的內容,發現很多細節地方之前都沒有注意到,通過再一次的回顧,增添了很多收獲,這真的就是“溫故而知新”這句話現實化了。最后,希望大家能一直朝著自己理想的方向努力。越努力,越幸運!!!