1. 程式人生 > >【OpenCV Python】核心操作--模板匹配

【OpenCV Python】核心操作--模板匹配

2.多物件匹配

有時候,如果你要匹配的模板,在圖形中多次出現,那麼就需要多物件匹配。

多物件匹配的原理很簡單,因為opencv裡的模板匹配,是將圖形裡的每一處和模板進行對比,所以同一個模板下,多物件匹配情況下,結果矩陣裡會有好幾個值,和最大(小)值接近,如果我們設定一個閾值,在這個閾值以上(以下)的值都提取出來,再分別得到他們的座標,理論上只要這個閾值設定的恰當,就可以將多物件都匹配出來。

在使用多物件匹配時,先介紹幾個方便處理這個過程的函式:

  np.nonzero()

這個函式的輸入是一個多維陣列,其作用是將所有非0值的索引放入一個多維數組裡作為結果輸出,如果輸入是1維,結果應該也是1維,2維的結果應該也是

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

)數值放入結果的(i,j)位置。

這個函式還有一種情況,如果輸入只有conditon一個引數,則是輸出np.nonzero(condition)

如果將一個numpyarray與一個數做比較,則是將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

i,Bi,Ci)再將這些tuple放入一個list裡輸出:

例如:

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座標是正好相反的,所以要對換下位置。

然後再迴圈座標,分別畫出紅色邊界。