Template Matching

Tonee Bayhon
3 min readFeb 1, 2021

--

First, let’s see our source image:

from skimage.io import imread, imshow
from skimage.color import rgb2gray
carrier = imread('aircraft_carrier.jpg')
carrier_gray = rgb2gray(carrier)
imshow(carrier_gray);

Then, we define our template. For this image we just choose one of the planes:

template = carrier_gray[648:744,775:838]
imshow(template);

Then using match_template to prepare for template matching

from skimage.feature import match_template
result = match_template(carrier_gray, template)
imshow(result, cmap='viridis');

Looking for our original template in the source photo:

import numpy as np
import matplotlib.pyplot as plt
x, y = np.unravel_index(np.argmax(result), result.shape)

imshow(carrier_gray)
template_width, template_height = template.shape
rect = plt.Rectangle((y, x), template_height, template_width, color='y',
fc='none')
plt.gca().add_patch(rect);

Let’s lower the threshold to accommodate more matches:

from skimage.feature import peak_local_max
imshow(carrier_gray)
template_width, template_height = template.shape
for x, y in peak_local_max(result, threshold_abs=0.8):
rect = plt.Rectangle((y, x), template_height, template_width, color='y',
fc='none')
plt.gca().add_patch(rect);

With a threshold of 0.8, we only got two matches from the source image. What happens if we lower our threshold further?

imshow(carrier_gray)
template_width, template_height = template.shape
for x, y in peak_local_max(result, threshold_abs=0.1):
rect = plt.Rectangle((y, x), template_height, template_width, color='y',
fc='none')
plt.gca().add_patch(rect);

It seems that with too low of a threshold, we obtain unnecessary matches in our source image. Intuitively, we can say that for only a few pixels, the algorithm would already consider the selected image as a match. But we want something more meaning from our image, so we find the middle ground for these thresholds:

imshow(carrier_gray)
template_width, template_height = template.shape
for x, y in peak_local_max(result, threshold_abs=0.4):
rect = plt.Rectangle((y, x), template_height, template_width, color='y',
fc='none')
plt.gca().add_patch(rect);

It seems that with even a low threshold of 0.4, we are not getting all the planes. We can assume that all the rest of the planes would just be random matches.

  1. So, will we still be able to detect the airplanes if you enlarge the template?

Template matching basically tries to locate which pixel order matches with the template to a certain degree. If we were to enlarge the template, it would disrupt this order. Simply put, as much as human vision doesn’t discriminate between scales when negligible, but the machine interprets in numbers thus this array of numbers must be followed as well.

2. How about if we flip the template image?

At the onset, we can see that the matches of the image are close to those of whose orientation is similar to its own. Thus, if we flip the template image, following the same argument as the previous question, we won’t get the same matches. Although, we we do have plane on an opposite orientation in our source image, we can definitely get some matches.

3. Finally, will we still be able to detect the airplanes if we change the contrast of the image?

I believe that at a certain threshold, because the image will match certain values from the template, it will still be able to detect the airplanes. Again, with the caveat of having a lower threshold for the same result vs. the original one.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Tonee Bayhon
Tonee Bayhon

Written by Tonee Bayhon

Am I doing this data science thing right?

No responses yet

Write a response