灰度圖像我有一個項目,我想定位圖像一堆箭頭看起來像這樣:ibb.co/dSCAYQ 與下面的模板:ibb.co/jpRUtQPython的OpenCV的matchTemplate與蒙
我在Python中使用cv2的模板匹配功能。我的算法是將模板旋轉360度並匹配每次旋轉。我得到以下結果:ibb.co/kDFB7k
正如你所看到的,它運作良好,除2米的箭都非常接近,使得另一支箭是在模板中的黑色區域。
我正在嘗試使用掩碼,但似乎cv2並未在所有應用程序中使用我的掩碼,即無論掩碼數組具有什麼值,匹配都是相同的。已經嘗試了兩天,但cv2的有限文檔沒有幫助。
這裏是我的代碼:
import numpy as np
import cv2
import os
from scipy import misc, ndimage
STRIPPED_DIR = #Image dir
TMPL_DIR = #Template dir
MATCH_THRESH = 0.9
MATCH_RES = 1 #specifies degree-interval at which to match
def make_templates():
base = misc.imread(os.path.join(TMPL_DIR,'base.jpg')) # The templ that I rotate to make 360 templates
for deg in range(360):
print('making template: ' + str(deg))
tmpl = ndimage.rotate(base, deg)
misc.imsave(os.path.join(TMPL_DIR, 'tmp' + str(deg) + '.jpg'), tmpl)
def make_masks():
for deg in range(360):
tmpl = cv2.imread(os.path.join(TMPL_DIR, 'tmp' + str(deg) + '.jpg'), 0)
ret2, mask = cv2.threshold(tmpl, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
cv2.imwrite(os.path.join(TMPL_DIR, 'mask' + str(deg) + '.jpg'), mask)
def match(img_name):
img_rgb = cv2.imread(os.path.join(STRIPPED_DIR, img_name))
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
for deg in range(0, 360, MATCH_RES):
tmpl = cv2.imread(os.path.join(TMPL_DIR, 'tmp' + str(deg) + '.jpg'), 0)
mask = cv2.imread(os.path.join(TMPL_DIR, 'mask' + str(deg) + '.jpg'), 0)
w, h = tmpl.shape[::-1]
res = cv2.matchTemplate(img_gray, tmpl, cv2.TM_CCORR_NORMED, mask=mask)
loc = np.where(res >= MATCH_THRESH)
for pt in zip(*loc[::-1]):
cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
cv2.imwrite('res.png',img_rgb)
有些事情,我認爲可能是錯的,但不知道如何解決:
- 通道的數量面膜/ TMPL/IMG應該有。我嘗試了一個彩色4通道PNG stackoverflow eg.的例子,但不知道它如何轉換爲灰度或3通道JPEG。
- 掩碼數組的值。例如應掩蓋像素是1還是255?
任何幫助,非常感謝。
UPDATE 我在我的代碼中修復了一個微不足道的錯誤; mask = mask必須用於matchTemplate()的參數中。這與使用255的掩碼值相結合產生了不同。但是,現在我得到了大量的假陽性,如下所示: http://ibb.co/esfTnk請注意,假陽性與真陽性相關性更強。 任何關於如何解決我的面具來解決這個問題的指針?現在我只是使用我的模板的黑白轉換。
嘗試使用包含'0'和'255'強度值的單個通道掩碼。 – ZdaR
@ZdaR我試過了,但不起作用。看起來即使使用零矩陣或255矩陣的掩碼也不會影響匹配。 – TonyZ
原來這是個伎倆,我犯了一個微不足道的錯誤。我需要在matchTemplate()中使用參數mask = mask。 雖然有進一步的複雜性。我已經更新了這個問題。謝謝 – TonyZ