【OpenCV Python】核心操作--模板匹配
2.多物件匹配
有時候,如果你要匹配的模板,在圖形中多次出現,那麼就需要多物件匹配。
多物件匹配的原理很簡單,因為opencv裡的模板匹配,是將圖形裡的每一處和模板進行對比,所以同一個模板下,多物件匹配情況下,結果矩陣裡會有好幾個值,和最大(小)值接近,如果我們設定一個閾值,在這個閾值以上(以下)的值都提取出來,再分別得到他們的座標,理論上只要這個閾值設定的恰當,就可以將多物件都匹配出來。
在使用多物件匹配時,先介紹幾個方便處理這個過程的函式:
np.nonzero()
這個函式的輸入是一個多維陣列,其作用是將所有非0值的索引放入一個多維數組裡作為結果輸出,如果輸入是1維,結果應該也是1維,2維的結果應該也是
例如:
A=[[0,1,1],[0,0,0],[1,0,0]]
result = np.nonzero(A)
print result
我們可以看出A這個數組裡,非0的數值分別是第0個小陣列的第1個,第0個小陣列第2個,第2個小陣列第0個。所以結果放在兩個數組裡[0.0.2],[1.2.0]
np.where[condition, x, y]
對於這個函式,conditon,x,y都是同維度的陣列,其結果也是個同維度的陣列,它的作用是這樣的,condition裡的第(i,j)裡的數看作一個bool型別的數,如果是true,將x裡對應的(i,j)數值放入結果的(i,j)位置,如果是false就將y裡對應的(i,j
這個函式還有一種情況,如果輸入只有conditon一個引數,則是輸出np.nonzero(condition)
如果將一個numpy的array與一個數做比較,則是將array裡每一個數值分別與這個數做對比,將結果放入每一個數對應的位置
例如:
A=np.array([[0,1,1],[0,0,0],[1,0,0]])
result=A>=1
print result
螢幕剪輯的捕獲時間: 2018/4/17 22:39
Zip()
zip函式的輸入是不定量個list或者tuple,如A,B,C,這個函式將輸入的list或者tuple的第i位
(0<i<len(list))位取出,組成(A
例如:
A = [0,1,2]
B = [1,4,5]
C = [7,0,0]
print zip(A,B,C)
螢幕剪輯的捕獲時間: 2018/4/17 22:56
值得注意的是,zip的輸入是不定函式,其數量是不定的,所以使用zip(*arg),將所有引數放入一個list裡,作為輸入,也是可以的,所以上面的程式碼也可以這樣寫:
D = [[0,1,2], [1,4,5],[7,0,0]]
print zip(*D)
其輸出和上面一樣。
講了這麼多,我們來看看多物件匹配具體怎麼完成,程式碼如下:
img = cv2.imread("Mine.png", 1)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.imread("temp.png", 0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
locs = np.where(res >=0.985)
for loc in zip(*locs[::-1]):
img =cv2.rectangle(img, loc, (loc[0] + w, loc[1] + h), (0, 0, 255), 3)
螢幕剪輯的捕獲時間: 2018/4/17 23:01
以上程式碼中,黑色部分和之前單個匹配一樣,對於紅色部分。
0.985是我們設定的閾值,res>=0.958的作用是將結果array裡符合條件的數值換成True,反之換成False。
np.where的作用是將true的索引輸出到loc變數
loc[::-1]將輸出的索引變換成x,y座標,因為索引和x,y座標是正好相反的,所以要對換下位置。
然後再迴圈座標,分別畫出紅色邊界。