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



  • 相关阅读:
    更新自己知识的网站
    CRM IFD 部署在同一台服务器上遇到的错误
    Dynamics CRM 修改Excel 最大导出记录限制及 最大上传文件限制
    CRM 插件奇怪的报错
    单实例,当MongoDB单表数据文件太大导致写入速度变慢
    MongoDB分片实战
    SpringCloud使用feign时的复杂参数传递(转)
    99%的人都理解错了HTTP中GET与POST的区别(转)
    MySQL 数据导入 Unknown MySQL server host 'localhost'
    会员积分体系设计思路(转)
  • 原文地址:https://www.cnblogs.com/hsy1941/p/11206921.html
Copyright © 2020-2023  润新知