Reputation: 3071
I'm trying to use the match_template method from the scikit-image library to check if a template exists inside an image and get its X and Y positions. I'm using the scikit-image template matching example.
My code looks like this:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import numpy as np
from skimage import io
from skimage.color import rgb2gray
from skimage.feature import match_template
def exists(image, template):
"""Perform a template match and returns the X and Y positions.
Args:
image (str): path to the full image.
template (str): path to the template image.
Returns:
If there is a match, return the X and Y positions.
If there is not match, return None.
"""
image = io.imread(image, as_gray=True)
template = io.imread(template, as_gray=True)
result = match_template(image, template, pad_input=True)
return np.unravel_index(np.argmax(result), result.shape)[::-1]
# unreachable
return None
It is performing the template match correctly when it exists in the image, but when the template doesn't exist it gives me wrong X and Y positions.
How can I check if the template doesn't exist and return None
in this case?
Upvotes: 0
Views: 1177
Reputation: 5738
I don't know enough about the output of match_template
to give you a definitive answer, but the critical thing is that the function always returns just the correlation image:
Returns
-------
output : array
Response image with correlation coefficients.
Therefore, to determine that you haven't found a template match, you have to determine that the max of output
is below some threshold. I don't know what a good threshold is. In general, I think it will vary depending on the size of your template and on how much noise/variation you want to allow. My suggestion is that you run match_template
on a few positive examples (containing the template, with varying amounts of noise) and a few negative ones (without), and plot the two distributions to choose a threshold. Then you can add:
def exists(image, template, threshold):
...
max_corr = np.max(result)
if max_corr > threshold:
return np.unravel_index(np.argmax(result), result.shape)[::-1]
else:
return None
Upvotes: 1