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