I have a map on which there is a number of similar symbols (trees) spread across the map. I I'm using opencv to find the X,Y coordinates of all the symbols.
It's working well but I am getting a huge number of duplicate results. If I increase the filter threshold the number of duplicates is reduced by lots of the symbols are missed. I've tried writing some code to filter out results based on proximity but I'm not having much luck. Does anyone have any insight into what I could try here?
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
You can keep track of the regions of the image where you already detected a tree (using a mask). Then you only increase the tree counter if, for example, the center of each match was not marked yet.
Code:
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))
Before (not removing duplicates):
After (removing duplicates with mask):
You can notice in the bottom image the thinner green lines illustrating that we detected 3 apple trees instead of 13!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With