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,用於選擇子陣列的可選掩膜。