OpenCV 模板匹配函数matchTemplate详解


  void cv::matchTemplate( cv::InputArray image, // 待匹配图像W*H
        cv::InputArray templ, // 模板图像,和image类型相同, 大小 w*h
        cv::OutputArray result, // 匹配结果图像, 类型 32F, 大小 (W-w+1)*(H-h+1)
        int method // 用于比较的方法
    );

 

1.result数据的含义

       模板匹配函数cvMatchTemplate依次计算模板与待测图片的重叠区域的相似度,并将结果存入映射图像result当中,也就是说result图像中的每一个点的值代表了一次相似度比较结果。

 

      2.result的尺寸大小

       如图可知,模板在待测图像上每次在横向或是纵向上移动一个像素,并作一次比较计算,由此,横向比较W-w+1次,纵向比较H-h+1次,从而得到一个(W-w+1)×(H-h+1)维的结果矩阵,result即是用图像来表示这样的矩阵,因而图像result的大小为(W-w+1)×(H-h+1)。匹配结果图像与原图像之间的大小关系,他们之间差了一个模板大小。

       3.如何从result中获得最佳匹配区域

       使用函数cvMinMaxLoc(result,&min_val,&max_val,&min_loc,&max_loc,NULL);从result中提取最大值(相似度最高)以及最大值的位置(即在result中该最大值max_val的坐标位置max_loc,即模板滑行时左上角的坐标,类似于图中的坐标(x,y)。

       由此得到:rect=cvRect(max_loc.x,max_loc.y,tmp->width,tmp->height); rect表示最佳的匹配的矩形区域。

 1 #include "opencv2/highgui/highgui.hpp"
 2 #include "opencv2/imgproc/imgproc.hpp"
 3 #include <iostream>
 4 using namespace cv;  5 
 6 
 7 //-----------------------------------【宏定义部分】--------------------------------------------  8 // 描述:定义一些辅助宏  9 //------------------------------------------------------------------------------------------------ 
 10 #define WINDOW_NAME1 "【原始图片】"        //为窗口标题定义的宏 
 11 #define WINDOW_NAME2 "【匹配窗口】"        //为窗口标题定义的宏 
 12 
 13 //-----------------------------------【全局变量声明部分】------------------------------------  14 // 描述:全局变量的声明  15 //-----------------------------------------------------------------------------------------------
 16 Mat g_srcImage;  17 Mat g_templateImage;  18 Mat g_resultImage;  19 int g_nMatchMethod;  20 int g_nMaxTrackbarNum = 5;  21 
 22 //-----------------------------------【全局函数声明部分】--------------------------------------  23 // 描述:全局函数的声明  24 //-----------------------------------------------------------------------------------------------
 25 void on_Matching(int, void*);  26 static void ShowHelpText();  27 
 28 
 29 //-----------------------------------【main( )函数】--------------------------------------------  30 // 描述:控制台应用程序的入口函数,我们的程序从这里开始执行  31 //-----------------------------------------------------------------------------------------------
 32 int main()  33 {  34     
 35 
 36 
 37     //【1】载入原图像和模板块
 38     g_srcImage = imread("1.jpg", 1);  39     g_templateImage = imread("2.jpg", 1);  40 
 41     //【2】创建窗口
 42  namedWindow(WINDOW_NAME1, CV_WINDOW_AUTOSIZE);  43  namedWindow(WINDOW_NAME2, CV_WINDOW_AUTOSIZE);  44 
 45     //【3】创建滑动条并进行一次初始化
 46     createTrackbar("方法", WINDOW_NAME1, &g_nMatchMethod, g_nMaxTrackbarNum, on_Matching);  47     on_Matching(0, 0);  48 
 49     waitKey(0);  50     return 0;  51 
 52 }  53 
 54 //-----------------------------------【on_Matching( )函数】--------------------------------  55 // 描述:回调函数  56 //-------------------------------------------------------------------------------------------
 57 void on_Matching(int, void*)  58 {  59     //【1】给局部变量初始化
 60  Mat srcImage;  61  g_srcImage.copyTo(srcImage);  62 
 63     //【2】初始化用于结果输出的矩阵
 64     int resultImage_cols = g_srcImage.cols - g_templateImage.cols+1 ;  65     int resultImage_rows = g_srcImage.rows - g_templateImage.rows +1;  66  g_resultImage.create(resultImage_cols, resultImage_rows, CV_8UC3);  67 
 68     //【3】进行匹配和标准化→g_srcImage待匹配的源图像,g_templateImage模板图像  69     //g_resultImage保存结果的矩阵,我们可以通过minMaxLoc() 确定结果矩阵的最大值和最小值的位置.  70     //g_nMatchMethod模板匹配的算法
 71  matchTemplate(g_srcImage, g_templateImage, g_resultImage, g_nMatchMethod);  72     //normalize查找全局最小和最大稀疏数组元素并返回其值及其位置
 73     normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1);  74 
 75     //【4】通过函数 minMaxLoc 定位最匹配的位置
 76     double minValue;  77     double maxValue;  78  Point minLocation;  79  Point maxLocation;  80  Point matchLocation;  81     minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());  82 
 83     //【5】对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值有着更高的匹配结果. 而其余的方法, 数值越大匹配效果越好
 84     if (g_nMatchMethod == CV_TM_SQDIFF || g_nMatchMethod == CV_TM_SQDIFF_NORMED)  85  {  86         matchLocation = minLocation;  87  }  88     else
 89  {  90         matchLocation = maxLocation;  91  }  92 
 93     //【6】绘制出矩形,并显示最终结果
 94     rectangle(srcImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);  95     rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_templateImage.cols, matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);  96 
 97  imshow(WINDOW_NAME1, srcImage);  98  imshow(WINDOW_NAME2, g_resultImage);  99 
100 }
void minMaxLoc(const SparseMat& src, double* minVal, double* maxVal, int* minIdx=0, int* maxIdx=0);

参数1:InputArray类型的src,输入单通道数组(图像)。
参数2:double*类型的minVal,返回最小值的指针。若无须返回,此值置为NULL。
参数3:double*类型的maxVal,返回最大值的指针。若无须返回,此值置为NULL。
参数4:Point*类型的minLoc,返回最小位置的指针(二维情况下)。若无须返回,此值置为NULL。
参数5:Point*类型的maxLoc,返回最大位置的指针(二维情况下)。若无须返回,此值置为NULL。
参数6:InputArray类型的mask,用于选择子阵列的可选掩膜。




免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM