c++ - OpenCV 中具有公差的模板匹配

标签 c++ opencv image-processing computer-vision template-matching

我正在使用 OpenCV 和 C++。我想检查一个图像是否是另一个图像的一部分,并且已经找到了一个名为 matchTemplate 的函数,该函数正在运行。但是如果模板图像有点不同怎么办?是否有像 matchTemplate 这样的函数或方法来检查模板是否是源图像的一部分,但具有诸如 positionangle 之类的公差参数、尺寸甚至变形?还是我需要一种与模板匹配完全不同的方法?

到目前为止,这是我的代码,它在源图像中找到模板图像,但没有(或几乎没有)容差。

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>

using namespace cv;
using namespace std;

/// Global Variables
Mat img; Mat templ; Mat result;
const char* image_window = "Source Image";
const char* result_window = "Result window";

int match_method;
int max_Trackbar = 5;

/// Function Headers
void MatchingMethod( int, void* );

/**
* @function main
*/
int main( int, char** argv )
{
  /// Load image and template
  img = imread( "a1.jpg", 1 );
  templ = imread( "a2.jpg", 1 );

  /// Create windows
  namedWindow( image_window, WINDOW_AUTOSIZE );
  namedWindow( result_window, WINDOW_AUTOSIZE );

  /// Create Trackbar
  const 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_cols, result_rows, 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() );


  /// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
  if( match_method == TM_SQDIFF || match_method == 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;
}

我在代码中使用的图像:

source image a1.jpg template image a2.jpg

最佳答案

您已经确定了模板匹配的主要限制。它对图像的任何变形都非常脆弱。模板匹配的工作原理是在图像周围滑动一个模板大小的框,并检查模板与框内区域之间的相似性。它使用逐像素比较方法检查相似性,例如归一化互相关。如果你想允许不同的大小和旋转,你需要写一个循环来放大或缩小原始模板,或者旋转它。它变得非常低效。

如果你想允许变形,并且还可以在不同的比例和旋转下进行更有效的搜索,标准方法是 SURF。如果您的图像具有良好的分辨率(您的图像就是这样),它会非常有效且非常准确。您可以搜索教程并找到使用 SURF 查找对象的示例代码。基本上 SURF 识别模板和图像中的关键点(独特的图像区域)。然后,您在图像中找到与模板匹配的关键点数量最多的区域。 (如果您已经在这样做,并且这就是您所说的“特征匹配”的意思,那么我认为您走在正确的轨道上。)

关于c++ - OpenCV 中具有公差的模板匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21013218/

相关文章:

Java:使用AffineTransform缩放图像时出现线条

c++ - Oracle最新OCI版本

c++ - 从系统时间中添加或减去一小部分时间

c++ - 如何在opencv c++中有效清除 vector <Mat>

opencv - 如何在 “image”中模拟高斯噪声峰

python - 从图像中检测水平白线并使用 OpenCV Python 获取它们的坐标

linux - 是否可以从命令行对图像应用效果?

c++ - Eclipse 问题 - 编译期间不考虑 .c 和 .cpp 文件中定义的预处理

c++ - 我应该使用什么工具来创建我的构建机器?

opencv - 如何在 OpenCV 中使用夜视摄像头输入(帧)?