Reputation: 3757
I am running the example code for opencv's matchTemplate function. I would like to know how "good" the match is and eliminate the data if the match quality is below a threshold.
/// Do the Matching and Normalize
matchTemplate( img, templ, 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;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
cout << "minVal" << minVal << "maxVal" << maxVal << endl;
I am printing out minVal
and maxVal
for matches running with different templ
and img
they all come out to 0 and 1. How do I fix this so that they give me different values for match quality?
full example code I ran from opencv.org
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
/// Global Variables
Mat img; Mat templ; Mat result;
char* image_window = "Source Image";
char* result_window = "Result window";
int match_method;
int max_Trackbar = 5;
/// Function Headers
void MatchingMethod( int, void* );
/** @function main */
int main( int argc, char** argv )
{
/// Load image and template
img = imread( argv[1], 1 );
templ = imread( argv[2], 1 );
/// Create windows
namedWindow( image_window, CV_WINDOW_AUTOSIZE );
namedWindow( result_window, CV_WINDOW_AUTOSIZE );
/// Create Trackbar
char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );
MatchingMethod( 0, 0 );
waitKey(0);
return 0;
}
/**
* @function MatchingMethod
* @brief Trackbar callback
*/
void MatchingMethod( int, void* )
{
/// Source image to display
Mat img_display;
img.copyTo( img_display );
/// Create the result matrix
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create( result_rows, result_cols, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( img, templ, 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;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
//^^^^^^^^^^^^^^^^^^ ONLY GETTING 0 AND 1 HERE ^^^^^^^^^^^^^^^^^^^^^
/// 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; }
else
{ matchLoc = maxLoc; }
/// Show me what you got
rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
imshow( image_window, img_display );
imshow( result_window, result );
return;
}
Upvotes: 0
Views: 2157
Reputation: 5846
Simple idea: remove the normalize
call. It compresses the template match result into 0..1. See if maxVal
gives you something meaningful if you don't normalize.
What you see is entirely expected.
After normalize(result, result, 0, 1, NORM_MINMAX, ...)
the result
matrix will have all values scaled (linearly) and shifted to fit the range 0..1
.
See: normalize doc
And:
What does cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
minMaxLoc
returns the values and locations of the min/max extrema.
Therefore after that normalize
, you'll always get minVal == 0
, maxVal == 1
. See: minMaxLoc doc
The interesting part of the minMaxLoc
output here are the locations in minLoc
and maxLoc
. They will be the Point
where the min and max are found.
If matchTemplate
works well, you will see lots of low values and just one or a few peaks where the template matches well. maxLoc
will have the coordinates of the top peak. The remaining values set by minMaxLoc
tell you essentially nothing and you can ignore them. (As you can see in the sample code, some match methods will yield results that should interpreted the other way: low is good match, high is bad match -- in that case you should look at minLoc
).
Upvotes: 2