【发布时间】:2017-11-25 04:16:58
【问题描述】:
我有一个项目,我想在如下所示的图像中找到一堆箭头:ibb.co/dSCAYQ 使用以下模板:ibb.co/jpRUtQ
我在 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)
有些事情我认为可能是错误的,但不知道如何解决:
- mask/tmpl/img 应具有的通道数。我尝试了一个带有彩色 4 通道 png stackoverflow eg. 的示例,但不确定它如何转换为灰度或 3 通道 jpeg。
- 掩码数组的值。例如屏蔽掉的像素应该是 1 还是 255?
非常感谢任何帮助。
更新 我修复了代码中的一个小错误;必须在 matchTemplate() 的参数中使用 mask=mask。这与使用 255 的掩码值相结合产生了差异。但是,现在我得到了大量的误报,如下所示: http://ibb.co/esfTnk 请注意,假阳性比真阳性的相关性更强。 有关如何修复我的面具以解决此问题的任何指示?现在我只是使用模板的黑白转换。
【问题讨论】:
-
尝试使用包含
0和255强度值的单通道掩码。 -
@ZdaR 我试过了,但没用。似乎即使使用零矩阵或 255 矩阵的掩码对匹配也没有影响。
-
原来这成功了,我犯了一个小错误。我需要在 matchTemplate() 中使用参数 mask=mask。不过还有更多的并发症。我已经更新了这个问题。谢谢