一、學習目標
- 了解圖片內容定位方法matchTemplate使用
- 了解minMaxLoc方法使用
上一篇《[python opencv 計算機視覺零基礎到實戰] 十、圖片效果毛玻璃》
如有錯誤歡迎指出~
二、了解從一張圖片中找到指定內容的方法
2.1 使用matchTemplate函數對圖片中的指定內容進行查找
有小伙伴可能用過一些輔助軟件,幫助我們從一些游戲中找到固定像素,并且去對該像素位置進行點擊,隨后解放雙手。今天這一節所講解的就是與這個功能相關的內容,對圖像中的指定圖形元素進行查找,并且選中該元素。
我們所使用的方法是matchTemplate。matchTemplate主要是一種匹配方法,通過判斷物體在一張圖片中的什么位置,從而進行定位,如下圖所示:
matchTemplate將會在對像素點進行匹配,匹配相似度越大,則確定該位置為目標。這個方法有一定局限性,在原圖中若目標圖片發生了旋轉等變化,那么將會查找失敗。
matchTemplate有幾種匹配算法,分別是TM_SQDIFF平方差匹配、TM_CCORR相關性匹配以及TM_CCOEFF相關性系數匹配。TM_SQDIFF平方差匹配是平方差匹配,最佳匹配值為0,若不佳則匹配值會越大;TM_CCORR是由原圖和目標圖像做乘法,值越高匹配越佳,反之越差,0為最差;TM_CCOEFF是將模版對其均值相對值與圖像對其均值相關值進行匹配,最佳匹配為1,0表示完全匹配不到,-1則表示有匹配,但是精確度不高。以上內容了解即可,對于初學者來說就知道就行,不理解也不妨礙我們現階段使用該API進行開發。
matchTemplate函數原型為:
matchTemplate(img, tpl, method[, result[, mask]])
matchTemplate中參數img為目標圖像,tpl為原圖,method是所使用的匹配算法,result是匹配結果圖像。
我們首先引入所需庫:
import cv2
import numpy as nptarget = cv2.imread(r'C:\Users\mx\Desktop\1.jpg')
tpl = cv2.imread(r'C:\Users\mx\Desktop\1target.png')
以上代碼中引入了目標圖片target與原圖tpl。隨后我們使用TM_SQDIFF_NORMED匹配方法對圖像進行匹配。
接下來獲取目標圖片的寬高:
th, tw = tpl.shape[:2]
目標圖片如下:
隨后傳入參數至matchTemplate方法中:
result = cv2.matchTemplate(target, tpl, cv2.TM_SQDIFF_NORMED)
接下來我們需要使用一個方法minMaxLoc。minMaxLoc方法是在一個矩陣中尋找最大值和最小值,并且得到最大值最小值的索引。若有一個矩陣為[[1,2,3,4],[5,11,7,8]],名為a,傳入到 方法后,代碼如下:
min_val,max_val,min_loc,max_loc=cv2.minMaxLoc(a)
print(min_val,max_val,min_loc,max_loc)
最終結果將是:
1.0 11.0 (0, 0) (1, 1)
我們接下來使用minMaxLoc獲取matchTemplate算出來的計算結果,由于我們使用的方法是TM_SQDIFF_NORMED,那么將獲取最低值進行目標獲取。代碼如下:
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
tl = min_loc
接下來我們使用rectangle對所需要的部分進行繪圖。rectangle接收五個參數,分別是image圖片、start_point起始坐標、end_point結束坐標、color顏色、thickness線條粗細。我們就常規使用前4個參數就ok了。
接下來我們使用最小的坐標加上目標圖片的寬高就可以知道繪制區域了:
br = (tl[0] + tw, tl[1] + th)
最終完整的代碼如下:
import cv2
import numpy as nptarget = cv2.imread(r'C:\Users\mx\Desktop\1.jpg')
tpl = cv2.imread(r'C:\Users\mx\Desktop\1target.png')
th, tw = tpl.shape[:2]result = cv2.matchTemplate(target, tpl, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
tl = min_loc
br = (tl[0] + tw, tl[1] + th)
cv2.rectangle(target, tl, br, [0, 255, 0])
cv2.imshow("target", target)cv2.waitKey(0)
cv2.destroyAllWindows()
結果如下:
2.2 深入了解matchTemplate函數
matchTemplate函數的查找方式我們可以通過matchTemplate函數所返回的結果進行查看,修改代碼如下:
import cv2
import numpy as nptarget = cv2.imread(r'C:\Users\mx\Desktop\1.jpg')
tpl = cv2.imread(r'C:\Users\mx\Desktop\1target.png')
methods = [cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF_NORMED]
th, tw = tpl.shape[:2]result = cv2.matchTemplate(target, tpl, cv2.TM_SQDIFF_NORMED)cv2.imshow("result", result)cv2.waitKey(0)
cv2.destroyAllWindows()
我們以上代碼直接顯示了result結果,由于為了演示效果,最理想狀態是扣選出來的圖片,所以我使用了原圖進行目標圖像的選取。
tpl=target[200:400,280:450]
并且使用了methods列表存儲了匹配方法TM_SQDIFF_NORMED、TM_CCORR_NORMED、TM_CCOEFF_NORMED。之后使用了遍歷依次使用這些方法對目標圖片進行匹配。但是由于不同的方法高地值表示不懂的匹配效果,在此使用了if語句判斷不同的方法取不同的高低值:
if md == cv2.TM_SQDIFF_NORMED:tl = min_locelse:tl = max_loc
修改了目標圖,為了有更好的對比,目標圖如下:
結果如下:
以上我展示了一種方法的結果圖,其它方法由于我選擇的目標圖有太多相似的區域,所以這張圖是一種較為理想的想過。可以看到在黃色箭頭選擇的區域有明顯的高亮位置,該位置則是我們進行目標匹配后的結果位置。其實在進行匹配時,這個過程就類似于是卷積。
該系列文章首發于ebaina
三、總結
- 目標匹配方法matchTemplate的使用方法
- 了解了matchTemplate方法有3中匹配方式,依次是TM_SQDIFF_NORMED、TM_CCORR_NORMED、TM_CCOEFF_NORMED
- 了解了不同匹配方法之間高低值有不同的依據結果