OpenCV matchTemplate minVal maxVal仅返回0和1 [英] OpenCV matchTemplate minVal maxVal only return 0 and 1
问题描述
我正在运行opencv的matchTemplate函数的示例代码.我想知道匹配的好"程度,如果匹配质量低于阈值,则消除数据.
/// 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;
对于正在使用不同的templ
和img
运行的比赛,我正在打印出minVal
和maxVal
,它们都显示为0和1.如何解决此问题,以便为比赛质量提供不同的值?
我从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;
}
简单的想法:删除normalize
调用.它将模板匹配结果压缩为0.1.1.看看maxVal
是否可以使您有意义,如果您不进行标准化.
详细说明
您所看到的完全是预期的.
在normalize(result, result, 0, 1, NORM_MINMAX, ...)
之后,result
矩阵将具有所有值(线性缩放)并移位以适合范围0..1
.
请参阅:规范化文档
和:
cv :: normalize(_src,dst ,0、255,NORM_MINMAX,CV_8UC1);
minMaxLoc
返回最小/最大极值的值和位置.
因此,在normalize
之后,您将始终得到minVal == 0
,maxVal == 1
.请参阅: minMaxLoc文档
minMaxLoc
输出中有趣的部分是minLoc
和maxLoc
中的位置.它们将是找到最大值和最小值的Point
.
如果matchTemplate
工作正常,您会看到很多低值,只有一个或几个峰与模板匹配良好. maxLoc
将具有最高峰的坐标. minMaxLoc
设置的其余值基本上不会告诉您任何内容,您可以忽略它们. (正如您在示例代码中看到的那样,某些匹配方法将产生应以另一种方式解释的结果:低是好匹配,高是差匹配-在这种情况下,您应该查看minLoc
.)
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;
}
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.
Detailed explanation
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
).
这篇关于OpenCV matchTemplate minVal maxVal仅返回0和1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!