In my project I have to search shapes (two types) using two different templates in one image. There is, for each type, zero or one shape per image, leading to 4 possible outcomes (both shapes present; both shapes absent; 1 absent, 1 present and vice-versa). Shapes can overlap. I must be particularly careful to false positive detection (i.e. wrong template having highest match on other shape) for both shapes, that's much worse than a false negative. The templates consist of black (i.e. close to zero intensity) geometric shapes (crosses) and have a very high constrast with the background which is grey to white (contrast of 1:100 typically) which should help a lot. There is no change of perspective involved. Shapes may be rotated but only with small angles (< 1 deg), and their scaling is also expected to be quite close to be right in the first place.
Therefore I concluded that template matching matchTemplate
from openCV should be an efficient tool (leaving out possible minor problems due to rotation/scaling).
Based on the input of this post (Understanding and evaluating template matching methods) I thought that TM_SQDIFF_NORMED
or TM_CCOEFF_NORMED
methods would do a good job, in particular with TM_CCOEFF_NORMED
I expect to be less sensitive to illumination which do occur in my images.
After tests I realize that the best-match value (min for TM_SQDIFF_NORMED
, max for TM_CCOEFF_NORMED
) obtained in the result matrix after one template search using any of these two methods depends on the presence of the other shape in the image. I therefore thought of using the optional mask argument of template matching; limiting the search to the exact area of the shape in the template (which is only filled with zeros). However it is not available for none of these methods (only coded for methods TM_SQDIFF
and TM_CCORR_NORMED
).
That seems to lead to some unfortunate trade-off:
1/ Working with TM_SQDIFF
or TM_CCORR_NORMED
and a mask corresponding to each shape has the advantage of limiting the impact of one shape onto another but I understand that I will become more sensitive to difference in illumination;
or 2/ Continuing to work with TM_SQDIFF_NORMED
or TM_CCOEFF_NORMED
but I am not able to anticipate where it will lead since the score for each shape will always depend on the presence of the other shape.
Alternatively I could do my own function doing a template search using a TM_CCOEFF_NORMED
with masking possibility, but quite time-consuming and again I am not able to tell confidently that it's the way to go.
To pick the right threshold I plan to implement a ROC curve which will favor as low false positive rate as possible, even though it may come at the price of lower true positive rate (at least to start with), meaning a rather high threshold.
Generally I would like to ask for feedback before start coding anything else. It may even be that the matchTemplate
is not the best approach here. Thanks in advance.