Sometimes, you'll want to figure out where or how many times a certain kind of object appears in an image. (Imagine, for instance, that you're dealing with a huge number of images that would be difficult for a single person to look through quickly). This is where template matching comes in. For example, if you're curious about how many times the white flower shows up in the image, you can start with a template, and then make a map of where the image of interest best matches the template. For our template image (which we refer to as "flowertemplate.jpg"), we are using one of the flowers from the image and assuming that it is similar enough to the other flowers in the image that computer software will identify the other flowers as a good match to the template image, without confusing other objects as flowers.
We do not necessarily have to use part of the original image as a template. You could just as easily select a flower from a different image. Sometimes people will simulate an image to use as a template based on their knowledge of what the object should look like.
Underneath the hood, the function is essentially figuring out where the array of numbers represented by the flower template best matches a sub-section of the array of numbers representing the image you're processing. This function returns a 2D array of numbers (which we call “match_intensity” in the code below) indicating how well a location in the image matches to the template. Higher numbers mean the match is better.
We can make a plot of this 2D array. We can see that the brightest spot in the map is near the center, which corresponds to the location of the flower that was originally used to make the template. But notice that we also get four other bright spots, corresponding to the other four similar flowers that are also in the image. We can locate these other four flowers using our old friends np.max() and np.where() to find the local maxima in the image (i.e., the pixels in the image that are brighter than anything nearby).
If we run the code:
y_bestmatch, x_bestmatch = np.where(np.max(match_intensity)==match_intensity)
then we’ll only get the location of the brightest spot at the center. To get the location of a different local maximum, we need to select only part of the array using array slicing:
y_match, x_match = np.where(np.max(match_intensity[:400, 1000:])==match_intensity[:400,1000:])
This line of code will help you find the location of the flower in the upper right corner of the intensity map. However, the value that you get for x_match will be 176, because the code only looks at the part of the array where the x-value is larger than 1000. So, to get back the value of x that corresponds to the original match_intensity plot, you need to add 1000 so that you get 1176.
1 import numpy as np
2 #import image processing package
3 from skimage import io
4 from skimage.feature import match_template
5 #import plotting package
6 import matplotlib.pyplot as plt
7 #read in image
8 imagefile = io.imread("Flowers.jpg", as_gray = True)
10 #read in template image
11 template = io.imread("flowertemplate.jpg", as_gray = True)
13 #calculate how well the template matches different locations in the image
14 match_intensity = match_template(imagefile, template)
16 f1 = plt.figure()
17 plt.imshow(match_intensity, cmap = 'gray')
20 #find out where the best match occurs
21 y_bestmatch, x_bestmatch = np.where(np.max(match_intensity)==match_intensity)
22 print("The best match occurs at an x value of %d and a y value of %d" % (x_bestmatch, y_bestmatch))
24 #find out where match occurs to flower in upper right corner:
25 y_match, x_match = np.where(np.max(match_intensity[:400, 1000:])==match_intensity[:400,1000:])
26 print("A match also occurs at an x value of %d and a y value of %d" % (x_match+1000,y_match))