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,用于选择子阵列的可选掩膜。



原文地址:https://www.cnblogs.com/hsy1941/p/11206921.html