# Source image having 2 or more part matched with a template image

Hello! I was surveying image matchTemplate algorithm and found out there is no explanation about what happens when there are 2 or more regions matched with template image on the source image. For example, I want to find a rectangle in the image which has two exactly same rectangles. Does Function "matchTemplate" return 2 or more outlined part on one Source image? Or 2 or more Source images with one outlined region each? Or just treat as exception?

I understood that finding image matched is related to Function "minMaxLoc", but, again, there is no explanation about what happens when there are 2 or more maximum values with different indexes on matrix. I have been so curious about this situation, but cannot infer what will happen on this special situation. If I understood the reference correctly, the code does not consider such condition. It only deals with situation that there are one maximum value and one minimum value.

I really want to execute by myself, but I cannot access development environment recently. And there is no way to understand why it happens like that. As a student who is not a skilled programmer, I'd appreciate some help on this problem. Thanks!

Jeff Lee

PS.I was reading information on http://www.stb-tester.com ,which is about Set Top Box Test Tool using matchTemplate algorithm, and end up here.

edit retag close merge delete

Sort by » oldest newest most voted

Looking at the matchTemplate documentation you can see that the result parameter contains a map of comparison results. This is actually a response of the input image to the filter (the template created) that will result in a mapping with local maxima. Look for the positions with the largest response (by thresholding the image). This will help you determine more than a single maxima or match, since exact the same images will have the same response.

More information on this problem can be found in the matchTemplate tutorial.

The tutorial mentions

In practice, we use the function minMaxLoc to locate the highest value (or lower, depending of the type of matching method) in the R matrix.

which actually means that they use that minMaxLoc to locate the maximum value, but if you threshold the image on your own threshold, you will basically find more local maxima.

more

Ah... It turns out I was understanding in a wrong way. I should have read the example code more precisely. So, if I understood well, "matchTemplate" returns the matrix R of comparison result and should use threshold() and minMaxLoc() after using "matchTemplate" function.
Thank you for explaining the method in easy sentences! I really appreciate your help!

( 2013-08-08 19:43:25 -0500 )edit

You are welcome. And yes like the example of @Mostafa Sataki show you, a combination of threshold() and the minMaxLoc() will get you the solution.

( 2013-08-09 02:11:48 -0500 )edit

In the first you have to use threshold() then use minMaxLoc.In each step you have to clear the current local maximum then find next local maximum.

Example:

object :

scene:

Result:

You have to change OpenCV example.

vector<Point> tempMatch(Mat object,Mat scene,int match_method,float peek_percent)
{
Mat img_display;
scene.copyTo( img_display );

/// Create the result matrix
int result_cols =  scene.cols - object.cols + 1;
int result_rows = scene.rows - object.rows + 1;

Mat result( result_cols, result_rows, CV_32FC1 );

/// Do the Matching and Normalize
matchTemplate( scene, object, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

/// Localizing the best match with minMaxLoc
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;

/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if( match_method  == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{
matchLoc = minLoc;
threshold(result,result,0.1,1,CV_THRESH_BINARY_INV);

}
else
{
matchLoc = maxLoc;
threshold(result,result,0.9,1,CV_THRESH_TOZERO);
}
vector<Point> res;
maxVal = 1.f;
while (maxVal > peek_percent)
{
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
if (maxVal > peek_percent)
{
rectangle(result,Point(maxLoc.x - object.cols/2,maxLoc.y - object.rows/2),Point(maxLoc.x + object.cols/2,maxLoc.y + object.rows/2),Scalar::all(0),-1);
res.push_back(maxLoc);
}

}

return res;
}
void drawMatch(Mat object,Mat scene,vector<Point> match_centers)
{
for(size_t i=0; i < match_centers.size();i++)
rectangle(scene,Point(match_centers[i].x ,match_centers[i].y ),Point(match_centers[i].x + object.cols,match_centers[i].y + object.rows),Scalar(0,255,0),2);
}

int main()
{
vector<Point> match_centers = tempMatch(object,scene,CV_TM_SQDIFF_NORMED,0.9);
drawMatch(object,scene,match_centers);
imshow("result",scene);
waitKey(0);
return 0;
}


There is another example here.

more

1

Thank you for your kindness suggesting such a specific example. The example helped me a lot in understanding how to use the "matchTemplate" function. Unfortunately, I was wondering about what "matchTemplate" returns in such situation. However, by reading the example, I was able to assume the result of calling "matchTemplate" in this case. Again, I really appreciate your help. Thanks!

( 2013-08-08 19:34:00 -0500 )edit

Official site

GitHub

Wiki

Documentation