计算箭头数

时间:2019-01-30 07:22:18

标签: python-3.x opencv3.0

我正在OpenCV中进行我的第一个项目。 我需要找到image]中的所有箭头,并将方向保存在列表中。

我使用模板匹配来找到所有箭头。这是可行的,因为所有箭头都彼此相似。我在每个箭头周围形成一个矩形框。但是,当我尝试计算这些矩形时,并没有得到我期望的结果。我不知道发生了什么。

模板:left_to_right_arrow            right_to_left_arrow

    image = cv2.imread('input.png')
    img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#Converted to grayscale

    ###read the templates
    right = cv2.imread('Images/arrow_right.png',0)
    wr, hr = right.shape[::-1]
    left=cv2.imread('Images/arrow_left.png',0)
    wl, hl = left.shape[::-1]
    slf=cv2.imread('Images/self_arrow.jpg',0)
    ws, hs = slf.shape[::-1]

    ###Template Matching
    res = cv2.matchTemplate(img_gray,right,cv2.TM_CCOEFF_NORMED)
    res1= cv2.matchTemplate(img_gray,left,cv2.TM_CCOEFF_NORMED)
    res2= cv2.matchTemplate(img_gray,slf,cv2.TM_CCOEFF_NORMED)

    ###To get multiple instances set a threshold
    threshold = 0.85
    loc = np.where(res >= threshold)
    pp = pprint.PrettyPrinter(indent=4)
    loc1=np.where(res1 >= threshold)
    loc2 = np.where( res2 >= threshold)

    count=0
    ###Draw rectangles around each instance in the image
    for pt in zip(*loc[::-1]):
        cv2.rectangle(image, pt, (pt[0] + wr, pt[1] + hr), (0,0,255), 1)
        pp.pprint(pt)
        count+=1
    print(count)
    for pt in zip(*loc1[::-1]):
        cv2.rectangle(image, pt, (pt[0] + wl, pt[1] + hl), (0,255,0), 1)
    for pt in zip(*loc2[::-1]):
        cv2.rectangle(image, pt, (pt[0] + ws, pt[1] + hs), (255,0,0), 1)
    ###Save the image
    cv2.imwrite('arrow_extracted.jpg',image)

根据上图的预期结果是2。 实际结果是63。 Arrows_extracted

1 个答案:

答案 0 :(得分:1)

实际上,您已经找到63个匹配的框,因为它们存在。原因是重叠的框,您可以看到绘制一条线的宽度并将其与边界框的宽度进行比较,以发现那里有多个框。现在我们可以解决这个问题了吗,简短的回答是的,一种方法是提高阈值,但是我不建议您这样做,因为您可能会错过一些箭头,因此我们可以使用cv2.minMaxLoc(),但是只能检测到一次。 tl;dr;我们能做的最好的就是称为非最大抑制的算法。

简而言之,它会提取所有框并比较它们是否重叠超过给定的阈值区域,然后抑制框重叠太多以至于它们可能会限制同一对象。

该代码可在此git repository上找到。其说明可在this post中找到。

如果您不遵循,请在下方评论。