Opencv模板匹配运用

来源:互联网 发布:什么事windows原版系统 编辑:程序博客网 时间:2024/05/18 03:56


1. 什么是模板匹配?

模板匹配是一种用于在源图像S中寻找定位给定目标图像T(即模板图像)的技术。其原理很简单,就是通过一些相似度准则来衡量两个图像块之间的相似度Similarity(S,T)。

2. 用途
模板匹配方法常用于一些平面图像处理中,例如印刷中的数字、工业零器件等小尺寸目标图像识别分类。


3. 方法

模板匹配中,源图像和模板图像可以是二值图像、灰度图像、彩色图像。


一般而言,模板匹配有两种使用场景:
1)如果源图像S与模板图像T大小(高和宽)一致,则直接使用相似度计算公式对这两个图像进行相似度计算。


2)如果源图像S的size大于模板图像T,则在S中匹配T时,需要滑动匹配窗口(即模板图像的大小),计算模板图像与该窗口对应的图像区域之间的相似度。对整张S图像滑动完后,得到多个匹配结果。这里,有两种方式获取匹配结果。一种是返回所有匹配结果中的最佳匹配结果(最小值或最大值,依相似度计算方式而定)。另一种,是设定一个阈值,大于或小于该阈值的匹配结果都认为是有效的匹配。


例如,如图1所示,想要在大图中定位到小图(小狗的头部),使用模板匹配时的滑动过程如图2所示:

../../../../../_images/Template_Matching_Template_Theory_Summary.jpg  图1

(来源:http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html#template-matching)


../../../../../_images/Template_Matching_Template_Theory_Sliding.jpg   图2

(来源:http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html#template-matching)



滑动完整张大图后,得到一张包含所有匹配结果的图,如图3所示。图3中的一个像素位置代表了一次模板匹配的结果。

../../../../../_images/Template_Matching_Template_Theory_Result.jpg 图3
(来源:http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html#template-matching)


4. 模板匹配中常用的相似度计算方法有:


1)Square difference matching method (method = CV_TM_SQDIFF) 平方差

R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2
2)Correlation matching methods (method = CV_TM_CCORR) 互相关

R(x,y)= \sum _{x',y'} (T(x',y')  \cdot I(x+x',y+y'))
3)Correlation coefficient matching methods (method = CV_TM_CCOEFF)  相关系数

R(x,y)= \sum _{x',y'} (T'(x',y')  \cdot I(x+x',y+y'))

\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}

4)上述三种方法的归一化形式(目的是为了减少光照的影响)

上述方法,OpenCV中都有实现。另外,除上述OpenCV实现了的方法外,还有一些相似度衡量方法,包括:

5)Sum of Absolute difference SAD 绝对差值

6)Match Pixel Count MPC 匹配成功点数



5. 模板匹配方法的优缺点:

优点:简单、直接

缺点:不具有旋转不变性、不具有尺度不变性



5. OpenCV中的模板匹配实例代码:

(代码来源:http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html#template-matching)


[cpp] view plaincopy
  1. #include "opencv2/highgui/highgui.hpp"  
  2. #include "opencv2/imgproc/imgproc.hpp"  
  3. #include <iostream>  
  4.   
  5. using namespace std;  
  6. using namespace cv;  
  7.   
  8. /// 全局变量  
  9. Mat img; Mat templ; Mat result;  
  10. char* image_window = "Source Image";  
  11. char* result_window = "Result window";  
  12.   
  13. int match_method;  
  14. int max_Trackbar = 5;  
  15.   
  16. /// 函数声明  
  17. void MatchingMethod( intvoid* );  
  18.   
  19.   
  20.   
  21. int main( int argc, char** argv )  
  22. {  
  23.     //  读图片  
  24.     img = imread( argv[1], 1 );  
  25.     templ = imread( argv[2], 1 );  
  26.       
  27.     //  创建图像显示窗口  
  28.     namedWindow( image_window, CV_WINDOW_AUTOSIZE );  
  29.     namedWindow( result_window, CV_WINDOW_AUTOSIZE );  
  30.   
  31.     //  创建混动条  
  32.     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";  
  33.     createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );  
  34.   
  35.     MatchingMethod( 0, 0 );  
  36.   
  37.     waitKey(0);  
  38.     return 0;  
  39. }  
  40.   
  41.   
  42.   
  43. // 模板匹配  
  44. void MatchingMethod( intvoid* )  
  45. {  
  46.     // 用于显示结果  
  47.     Mat img_display;  
  48.     img.copyTo( img_display );  
  49.   
  50.     // 用于存储匹配结果的矩阵  
  51.     int result_cols =  img.cols - templ.cols + 1;  
  52.     int result_rows = img.rows - templ.rows + 1;  
  53.     result.create( result_cols, result_rows, CV_32FC1 );  
  54.   
  55.     // 进行模板匹配  
  56.     matchTemplate( img, templ, result, match_method );  
  57.     // 归一化结果(方便显示结果)  
  58.     normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );  
  59.   
  60.     // 找到最佳匹配位置  
  61.     double minVal;   
  62.     double maxVal;   
  63.     Point minLoc;   
  64.     Point maxLoc;  
  65.     Point matchLoc;  
  66.   
  67.     minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );   // 寻找result中的最大和最小值,以及它们所处的像素位置  
  68.   
  69.     // 使用SQDIFF和SQDIFF_NORMED方法时:值越小代表越相似  
  70.     // 使用其他方法时:值越大代表越相似  
  71.     if( match_method  == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )  
  72.     {  
  73.         matchLoc = minLoc;   
  74.     }  
  75.     else  
  76.     {   
  77.         matchLoc = maxLoc;   
  78.     }  
  79.   
  80.     // 显示匹配结果  
  81.     rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );  
  82.     rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );  
  83.   
  84.     imshow( image_window, img_display );  
  85.     imshow( result_window, result );  
  86. }  




0 0
原创粉丝点击