计算箭头的数量

Counting the number of arrows

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

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

模板:

    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。

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

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

可以在此 git repository. and it's explanation is available in this post 上找到该代码。

如果您未能关注,请在下方评论。