target
In this chapter, you will learn
- Find objects in images using template matching
- Function: cv2.matchTemplate(), cv2.minMaxLoc()
theory
Template matching is a method used to search and find the location of template image in large image. To this end, OpenCV implements a function cv2.matchTemplate().
It just slides the template image onto the input image (just like in 2D convolution), and then compares the puzzle of the template and the input image under the template image.
Several comparison methods are implemented in OpenCV. It returns a grayscale image, where each pixel represents the degree to which the pixel's neighborhood matches the template.
If the size of the input image is (WXH) and the size of the template image is (WXH), the size of the output image will be (W-w+1, H-h+1). Once you get the result, you can use the cv2.minMaxLoc() function to find out where the maximum / minimum value is. Take it as the upper left corner of the rectangle, and take (w, h) as the width and height of the rectangle, which is the area of the template.
be careful
If cv2.tm is used_ As a comparison method, sqdiff is the minimum value to provide the best match.
Template matching in OpenCV
As an example, you will search for Messi's face in his photos. Therefore, a template is created as follows:
All comparison methods will be tried so that you can see their results:
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('messi.png', 0) img2 = img.copy() template = cv2.imread('template.png', 0) w, h = template.shape[::-1] # All the 6 methods for comparison in a list methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED'] for meth in methods: img = img2.copy() method = eval(meth) # apply template matching res = cv2.matchTemplate(img, template, method) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # if the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]: top_left = min_loc else: top_left = max_loc bottom_right = (top_left[0]+w, top_left[1]+h) cv2.rectangle(img, top_left, bottom_right, 255, 2) plt.subplot(121),plt.imshow(res,cmap = 'gray') plt.title('Matching Result'), plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(img,cmap = 'gray') plt.title('Detected Point'), plt.xticks([]), plt.yticks([]) plt.suptitle(meth) plt.show()
View the following results:
-
cv2.TM_CCOEFF
-
cv2.TM_CCOEFF_NORMED
-
cv2.TM_CCORR
-
cv2.TM_CCORR_NORMED
-
cv2.TM_SQDIFF
-
cv2.TM_SQDIFF_NORMED
As you can see, using cv2.TM_CCORR series and cv2.tm_ SQDIFF_ The result of normalized is not ideal
Multi object template matching
In the previous section, we searched for Messi's face in the image, which appears only once in the image. Assuming you are searching for an object with multiple occurrences, cv2.minMaxLoc() does not provide all locations. In this case, thresholding is used. Therefore, in this example, we will use a screenshot of the famous game Mario and find a coin in it.
# Match multiple objects img_bgr = cv2.imread('mario.png') img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) # plt.imshow different from cv2.imshow img_copy = img_rgb.copy() img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread('mario_coin.png', 0) w, h = template.shape[::-1] res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) threshold = 0.8 loc = np.where(res >= threshold) for pt in zip(*loc[::-1]): cv2.rectangle(img_rgb, pt, (pt[0]+w, pt[1]+h), (0,0,255), 2) plt.subplot(121) plt.imshow(img_copy) plt.title('origin') plt.xticks([]) plt.yticks([]) plt.subplot(122) plt.imshow(img_rgb) plt.title('match res') plt.xticks([]) plt.yticks([]) plt.show()
result: