Reputation: 2069
The following code is actually the result which of which I immediately print out:
result = cv.matchTemplate(haystack_img, needle_img, cv.TM_SQDIFF_NORMED
Picture size:
However, I don't really understand what that means.
Upvotes: 1
Views: 2298
Reputation: 2069
Thanks for @rayryeng's reply and a little bit more explain is that~
Result:
Picture size:
Since the image is compared by every pixel so the X and Y position can be counted as
X:0, 1, 2, 3, ... ,21 = the position in every list also equal to
len(result[0])
[
0.05779364
0.06816062
0.07974802
0.09858147
0.12885822
0.16065261
0.19880965
0.28301606
0.3753051
0.47798595
0.5469872
0.5558993
0.5515625
0.5280534
0.51457506
0.4536102
0.41659155
0.38783583
0.37042123
0.34466013
0.31110483
]
Y:0, 1, 2, 3, 4, 5 = the position in the list also equal to
len(result)
[
[0.05779364 0.06816062 ...]
[0.03569747 0.03553726 ...]
[0.06887697 0.07845661 ...]
[0.10796931 0.12338859 ...]
[0.15996848 0.18395858 ...]
[0.224204 0.2505653 ...]
[0.3423201 0.37836382 ...]
[0.38187546 0.38226286 ...]
[0.39126304 0.39931965 ...]
[0.39757547 0.4197682 ...]
]
Offical docs: https://docs.opencv.org/4.2.0/df/dfb/group__imgproc__object.html#ga586ebfb0a7fb604b35a23d85391329be
Upvotes: 0
Reputation: 104464
The output gives you a response image that will be of size 21 x 10 where the 7 x 7 needle_img
template is slide across the image left to right and top to bottom where each 7 x 7 window coincident with the template is extracted and a correlation is computed. Note the reduction in size for the output. It's smaller than the search image because the template is assumed to fit completely inside the image.
However, the metric you've chosen is a distance metric (cv2.TM_SQDIFF_NORMED
). For each element in this response image, it gives you the dissimilarity between the template and each window. The location that gives you the smallest value means that if you placed the template's top left corner at this location, this is where the template best matches the image.
Here is some code that will draw a bounding box where the template best matched in the haystack image:
result = cv2.matchTemplate(haystack_img, needle_img, cv.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = min_loc
w, h = (7, 7)
bottom_right = (top_left[0] + w, top_left[1] + h)
img_to_show = haystack_img.copy()
cv2.rectangle(img_to_show, top_left, bottom_right, 255, 2)
cv2.imshow("Result", img_to_show)
cv2.waitKey(0)
Run the template matching, then use cv2.minMaxLoc
to find the smallest and largest values as well as where they're located in the image. We want to use the location of the smallest value given the method you're using (distance). min_loc
will provide the column and row coordinates of the top left corner of where the template should best match. We create the bottom right coordinates based on the dimensions of the template, then create a new copy of the image and draw a white rectangle on that showing you were the template best matched then show the image at the end.
Upvotes: 4