OpenCV matchTemplate minVal maxVal仅返回0和1 [英] OpenCV matchTemplate minVal maxVal only return 0 and 1

查看:252
本文介绍了OpenCV matchTemplate minVal maxVal仅返回0和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;

对于正在使用不同的templimg运行的比赛,我正在打印出minValmaxVal,它们都显示为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 == 0maxVal == 1.请参阅: minMaxLoc文档

minMaxLoc输出中有趣的部分是minLocmaxLoc中的位置.它们将是找到最大值和最小值的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆