计算箭头的数量
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 上找到该代码。
如果您未能关注,请在下方评论。
我正在使用 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 上找到该代码。
如果您未能关注,请在下方评论。