I'm trying to code a python script that uses the cv2 library to template match an image. I have figured out how to detect one instance of the template in the image, taking into account if the template has a different scale, but i can't seem to figure out how to find multiple instances of a template in an image taking into account the scale as well.
I tried finding the first match, blocking it, then running the scan again, but the second scan can't find the template correctly.image with bounding boxes image to find
Does anyone know what can I do for it to detect both instances?
Here is the code im running:
import numpy as np
import imutils
import glob
import cv2
from imutils.object_detection import non_max_suppression
imagen_a_detectar = r"C:\Users\OMEN\OneDrive\Documentos\TEC\PROYECTO RESIDEO\REPO\SCRUMsinCUM\software\Deteccion Iconos\flecha50.jpg"
imagen_a_comparar = r"C:\Users\OMEN\OneDrive\Documentos\TEC\PROYECTO RESIDEO\REPO\SCRUMsinCUM\software\Deteccion Iconos\HomeAuto3.png"
template = cv2.imread(imagen_a_detectar)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
template = cv2.Canny(template, 50, 200)
(tH, tW) = template.shape[:2]
for imagePath in glob.glob(imagen_a_comparar):
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
found = None
threshold = 0.9
for scale in np.linspace(0.2, 1.0, 20)[::-1]:
scalem = scale
resized = imutils.resize(gray, width = int(gray.shape[1] * scale))
r = gray.shape[1] / float(resized.shape[1])
if resized.shape[0] < tH or resized.shape[1] < tW:
break
edged = cv2.Canny(resized, 50, 200)
result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
if found is None or max_val > found[0]:
found = (max_val, max_loc, r)
(_, max_loc, r) = found
(startX, startY) = (int(max_loc[0] * r), int(max_loc[1] * r))
(endX, endY) = (int((max_loc[0] + tW) * r), int((max_loc[1] + tH) * r))
m1 = cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), -1)
gray2 = cv2.cvtColor(m1, cv2.COLOR_BGR2GRAY)
resized2 = imutils.resize(gray2, width = int(gray.shape[1] * scalem))
r2 = gray.shape[1] / float(resized.shape[1])
edged2 = cv2.Canny(resized2, 50, 200)
result2 = cv2.matchTemplate(edged2, template, cv2.TM_CCOEFF_NORMED)
min_val2, max_val2, min_loc2, max_loc2 = cv2.minMaxLoc(result2)
found2 = (max_val2, max_loc2, r2)
(_, max_loc2, r2) = found2
(startX2, startY2) = (int(max_loc2[0] * r2), int(max_loc2[1] * r2))
(endX2, endY2) = (int((max_loc2[0] + tW) * r2), int((max_loc2[1] + tH) * r2))
m2 = cv2.rectangle(m1, (startX2, startY2), (endX2, endY2), (0, 0, 255), -1)
cv2.imshow("Image", m2)
cv2.waitKey(0)
print(str(endX) + ' ' +str(endY)+ ' ' +str(r))