Opencv 模板匹配 Template Matching

Opencv 模板匹配 Template Matching

模板匹配不同于直方图中的反向投影,它将模板图片在感兴趣图片中滑动,并用相应匹配方法度量相似性。

void cv::matchTemplate(
	cv::InputArray image, // Input image to be searched, 8U or 32F, size W-by-H
	cv::InputArray templ, // Template to use, same type as 'image', size w-by-h
	cv::OutputArray result, // Result image, type 32F, size (W-w+1)-by(H-h+1)
	int method // Comparison method to use
);

匹配方法

  1. Square Difference Matching Method (cv::TM_SQDIFF),最佳匹配为 0,越不匹配越大
  2. Normalized Square Difference Matching Method (cv::TM_SQDIFF_NORMED),最佳匹配为 0,越不匹配越大
  3. Correlation Matching Methods (cv::TM_CCORR),最不匹配为 0,越大越匹配
  4. Normalized Cross-Correlation Matching Method (cv::TM_CCORR_NORMED),最不匹配为 0,越大越匹配
  5. Correlation Coefficient Matching Methods (cv::TM_CCOEFF),最匹配为 1,最不匹配为 -1,无关为 0
  6. Normalized Correlation Coefficient Matching Method (cv::TM_CCOEFF_NORMED),匹配为正数,不匹配为负数

其中直接平方差值的最快,取相关系数的最慢,不过速度快效果也差。应该通过比较选择一个最合适的。 

enum TemplateMatchModes {
    TM_SQDIFF        = 0, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2\f]
    TM_SQDIFF_NORMED = 1, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
    TM_CCORR         = 2, //!< \f[R(x,y)= \sum _{x',y'} (T(x',y')  \cdot I(x+x',y+y'))\f]
    TM_CCORR_NORMED  = 3, //!< \f[R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}\f]
    TM_CCOEFF        = 4, //!< \f[R(x,y)= \sum _{x',y'} (T'(x',y')  \cdot I'(x+x',y+y'))\f]
                          //!< where
                          //!< \f[\begin{array}{l} T'(x',y')=T(x',y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}\f]
    TM_CCOEFF_NORMED = 5  //!< \f[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }\f]
};

Opencv 范例程序 

// Example 13-3. Template matching

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;

void help( char** argv ){
  cout << "\n"
  <<"\nExample 13-3: using matchTemplate(). The call is:\n"
  <<"\n"
  <<argv[0] <<" <template> <image_to_be_searched?\n"
  << "\nExample:\n" << argv[0] << "../BlueCup.jpg ../adrian.jpg"
  <<"\n"
  <<" This routine will search using all methods:\n"
  <<" cv::TM_SQDIFF 0\n"
  <<" cv::TM_SQDIFF_NORMED 1\n"
  <<" cv::TM_CCORR 2\n"
  <<" cv::TM_CCORR_NORMED 3\n"
  <<" cv::TM_CCOEFF 4\n"
  <<" cv::TM_CCOEFF_NORMED 5\n"
  <<"\n" << endl;
}

// Display the results of the matches
//
int main( int argc, char** argv ) {

  if( argc != 3) {
    help( argv );
    return -1;
  }

  cv::Mat src, templ, ftmp[6];   // ftmp is what to display on

  // Read in the template to be used for matching:
  //
  if((templ=cv::imread(argv[1], 1)).empty()) {
    cout << "Error on reading template " << argv[1] << endl;
    help( argv );return -1;
  }

  // Read in the source image to be searched:
  //
  if((src=cv::imread(argv[2], 1)).empty()) {
    cout << "Error on reading src image " << argv[2] << endl;
    help( argv );return -1;
  }

  // Do the matching of the template with the image
  for(int i=0; i<6; ++i){
    cv::matchTemplate( src, templ, ftmp[i], i);
    cv::normalize(ftmp[i],ftmp[i],1,0,cv::NORM_MINMAX);
  }

  // Display
  //
  cv::imshow( "Template", templ );
  cv::imshow( "Image", src );
  cv::imshow("SQDIFF", ftmp[0] );
  cv::imshow("SQDIFF_NORMED", ftmp[1] );
  cv::imshow("CCORR", ftmp[2] );
  cv::imshow("CCORR_NORMED", ftmp[3] );
  cv::imshow("CCOEFF", ftmp[4] );
  cv::imshow("CCOEFF_NORMED", ftmp[5] );

  // Let user view results:
  //
  cv::waitKey(0);
}

猜你喜欢

转载自blog.csdn.net/a40850273/article/details/83000078