Home > front end >  Opencv matchTemplate couldn't find bush inside map
Opencv matchTemplate couldn't find bush inside map

Time:05-24

I want to find 2d images of bush inside a 2d map. According to their website I used this code

image = cv2.imread('images/Pallet_Town.png', cv2.IMREAD_UNCHANGED)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
template = cv2.imread('images/Bush (small).png', cv2.IMREAD_UNCHANGED)

template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2RGB)

print(image.shape)
w, h, _ = template.shape

result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(result >= threshold)
print(*loc[::-1])
for pt in zip(*loc[::-1]):
    cv2.rectangle(image, pt, (pt[0]   w, pt[1]   h), (0, 0, 255), 2)
cv2.imwrite('images/result.png', image)

The code doesn't work and is not able to find any bush. The result image has no rectangles. What else function should I use to find the bush inside the image (Be it an opencv function or any other package) or is it my code problem.

Using these images (Bush is under the map)

Map

Bush: Bush

CodePudding user response:

I have actually found the answer, As fmw42 suggested me in comments making a mask of the bush and hence using this code I got the answer. Later I also had to increase the threshold to 0.9. Alternatively reducing threshold to 0.24 also worked but for different images it would have different thresholds which I didn't want

image = cv2.imread('images/Pallet_Town.png', cv2.IMREAD_UNCHANGED)
template = cv2.imread('images/Bush (small).png', cv2.IMREAD_UNCHANGED)

bush = template[:, :, 0:3]
alpha = template[:, :, 3]
alpha = cv2.merge([alpha, alpha, alpha])
result = cv2.matchTemplate(image, bush, cv2.TM_CCORR_NORMED, mask=alpha)
w, h, _ = template.shape

threshold = 0.9
loc = np.where(result >= threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(image, pt, (pt[0]   w, pt[1]   h), (0, 0, 255), 2)
cv2.imwrite('images/result.png', image)

result.png

CodePudding user response:

Your template has a transparent background. But your matchTemplate is not using the mask from the transparency alpha channel. So you are matching with the background from whatever is under the transparency, which likely does not match the area around the bush well. In your template that background is black and your bushes have a white background. So either change the template background to white or use the mask from the alpha channel in the matchTemplate(). See the documentation for matchTemplate for the use of a mask image (last argument in the following) in Python/OpenCV:

result  =   cv.matchTemplate(   image, templ, method[, result[, mask]]  )

So take your template image (the bush):

enter image description here

and extract the alpha channel and keep only the BGR channels for the image:

mask = template[:,:,3]

enter image description here

template = template[:,:,0:3]

enter image description here

Do not convert to grayscale. matchTemplate can work with color images.

  • Related