使用Python删除或防止OpenCV中的重复模板匹配

时间:2014-02-17 12:43:41

标签: python opencv

我有一张地图,地图上有许多相似的符号(树)。一世 我正在使用opencv来查找所有符号的X,Y坐标。

它运作良好,但我得到了大量的重复结果。如果我增加过滤器阈值,则会丢失许多符号,从而减少重复次数。我已经尝试编写一些代码来过滤掉基于邻近度的结果,但我没有太多运气。有没有人对我在这里尝试的内容有任何见解?

img_rgb = cv2.imread('images/map.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('images/tree.jpg',0)
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)

threshold = 0.35
matches = np.where( res >= threshold)

tree_count = 0
for pt in matches:
    tree_count += 1
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (255,0,0), 1)

cv2.imwrite('found_map.jpg',img_rgb)
print "Done " + map

2 个答案:

答案 0 :(得分:2)

您可以跟踪已经检测到树木的图像区域(使用遮罩)。然后,仅当例如尚未标记每个比赛的中心时,才增加树计数器。

代码:

img_rgb = cv2.imread('trees.png')
template = cv2.imread('apple_tree.png')
h, w = template.shape[:2]

res = cv2.matchTemplate(img_rgb, template, cv2.TM_CCOEFF_NORMED)

threshold = 0.95
loc = np.where( res >= threshold)

tree_count = 0
mask = np.zeros(img_rgb.shape[:2], np.uint8)
for pt in zip(*loc[::-1]):
    if mask[pt[1] + h/2, pt[0] + w/2] != 255:
        mask[pt[1]:pt[1]+h, pt[0]:pt[0]+w] = 255
        tree_count += 1
        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,255,0), 1)

cv2.imwrite('found_map.jpg',img_rgb)
print("Found {} trees in total!".format(tree_count))

之前(不删除重复项): enter image description here

enter image description here

之后(使用蒙版删除重复项): enter image description here enter image description here

您会在底部图像中注意到绿色的细线,表明我们检测到3棵苹果树,而不是13棵!

答案 1 :(得分:0)

我可以想到两个选择。

  1. 执行结果图像的形态erosion,直到您只有点数。许多模块都具有此功能。例如opencv和skimage。

  2. 使用结果图像,您可以尝试计算轮廓并提取每个轮廓的内部。

  3. 如果没有一些样本数据,很难说什么是最佳选择。不同的数据通常需要不同的方法