我有一张地图,上面有许多类似的符号(树)分布在地图上。我正在使用 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
Run Code Online (Sandbox Code Playgroud)
Joã*_*cho 11
您可以跟踪已检测到树的图像区域(使用遮罩)。然后,例如,如果尚未标记每个匹配项的中心,则仅增加树计数器。
代码:
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] + int(round(h/2)), pt[0] + int(round(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))
Run Code Online (Sandbox Code Playgroud)
您可以在底部图像中注意到较细的绿线,说明我们检测到 3 棵苹果树,而不是 13 棵!
我可以想到两个选择。
对结果图像进行形态侵蚀,直到只剩下点。很多模块都有这个功能。例如 opencv 和 skimage。
使用结果图像,您可以尝试计算轮廓并提取每个轮廓的内部。
如果没有一些样本数据,很难说什么是最好的选择。不同的数据通常需要不同的方法。