W Kenny
W Kenny

Reputation: 2069

How to read the result for matchTemplate (OpenCV2 in python)

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.

enter image description here

Upvotes: 1

Views: 2298

Answers (2)

W Kenny
W Kenny

Reputation: 2069

Thanks for @rayryeng's reply and a little bit more explain is that~

Result:

  • Position (0,0) is with 0.05779364 confident
  • Position (0,1) is with 0.03569747 confident

Picture size:

  • haystack_img = 27x16
  • needle_img = 7x7

Since the image is compared by every pixel so the X and Y position can be counted as

  • X:27-7+1) = 21
  • Y:(16-7+1) = 10

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

rayryeng
rayryeng

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

Related Questions