You'll want to avoid using cv2.minMaxLoc(result) as this finds the single best result. What we want are multiple good results that are above a threshold.
Using non-maximum suppression is one way to find multiple matches within an image.
import cv2
from imutils.object_detection import non_max_suppression # pip install imutils
# Load the image and template
image = cv2.imread(img_path, cv2.IMREAD_COLOR)
template = cv2.imread(template_path, cv2.IMREAD_COLOR)
# Perform template matching
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
# Filter results to only good ones
threshold = 0.90 # Larger values have less, but better matches.
(yCoords, xCoords) = np.where(result >= threshold)
# Perform non-maximum suppression.
template_h, template_w = template.shape[:2]
rects = []
for (x, y) in zip(xCoords, yCoords):
rects.append((x, y, x + template_w, y + template_h))
pick = non_max_suppression(np.array(rects))
# Optional: Visualize the results
for (startX, startY, endX, endY) in pick:
cv2.rectangle(image, (startX, startY), (endX, endY),(0, 255, 0), 2)
cv2.imshow('Results', image)
Explanation:
We do non-max suppression because there will be a lot of 'good' results around each match in the original image (e.g. shifting the template by 1 pixel often gives a good result, so you'd get a whole bunch of overlapping bounding boxes around each instance of the object in the original image). Non-max suppression will filter to one good match per image region.
Note that this non-max suppression doesn't use the scores directly so this answer mentioned above may be better suited when using matchTemplate.