模板匹配介紹
我們需要2幅圖像:
原圖像 (I):在這幅圖像里,我們希望找到一塊和模板匹配的區域
模板 (T):將和原圖像比照的圖像塊
-
模板匹配就是在整個圖像區域發現與給定子圖像匹配的小塊區域。
-
所以模板匹配首先需要一個模板圖像T(給定的子圖像)
-
另外需要一個待檢測的圖像-源圖像S
-
工作方法,在帶檢測圖像上,從左到右,從上向下計算模板圖像與重疊子圖像的匹配度,匹配程度越大,兩者相同的可能性越大。
模板匹配原理
我們的目標是檢測最匹配模板的原圖像的區域:
為了確定匹配模板區域, 我們不得不滑動模板圖像和原圖像進行比較 :
對于 模板(T) 覆蓋在 原圖像 (I) 上的每個位置,你把度量值保存 到 結果圖像矩陣 ( R ) 中. 在 R 中的每個位置 (x,y) 都包含匹配度量值:
上圖(右)就是TM_CCORR_NORMED方法處理后的結果圖像 R . 最白的位置代表最高的匹配. 正如您所見, 黑色框住的位置很可能是結果圖像矩陣中的最大數值, 所以這個區域 (以這個點為頂點,長寬和模板圖像一樣大小的矩陣) 被認為是匹配的.
實際上, 我們使用函數minMaxLoc來定位在矩陣 R 中的最大值點 (或者最小值, 根據函數輸入的匹配參數) .
voidminMaxLoc(InputArray src,double* minVal,double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())
-
src:輸入圖像。
-
minVal:在矩陣 src中存儲的最小值,可輸入NULL表示不需要。
-
maxVal :在矩陣 src中存儲的最大值,可輸入NULL表示不需要。
-
minLoc:在結果矩陣中最小值的坐標,可輸入NULL表示不需要,Point類型。
-
maxLoc:在結果矩陣中最大值的坐標,可輸入NULL表示不需要,Point類型。
-
mask:可選的掩模
模板匹配介紹 – 匹配算法介紹:
OpenCV中提供了六種常見的匹配算法如下:
-
計算平方不同 :計算出來的值越小,越相關TM_SQDIFF = 0
-
計算相關性:計算出來的值越大,越相關TM_CCORR = 2
-
計算相關系數:計算出來的值越大,越相關TM_CCOEFF = 4
-
計算歸一化平方不同 :計算出來的值越接近0,越相關TM_SQDIFF_NORMED = 1
-
計算歸一化相關性:計算出來的值越接近1,越相關TM_CCORR_NORMED = 3
-
計算歸一化相關系數:計算出來的值越接近1,越相關TM_CCOEFF_NORMED = 5
總結如下:
matchTemplate(
InputArray image,// 源圖像,必須是8-bit或者32-bit浮點數圖像
InputArray templ,// 模板圖像,類型與輸入圖像一致
OutputArray result,// 輸出結果,必須是單通道32位浮點數,假設源圖像WxH,模板圖像wxh, 則結果必須為W-w+1, H-h+1的大小。
intmethod,//使用的匹配方法
InputArray mask=noArray()//(optional)
)
#include
#include
usingnamespacestd;
usingnamespacecv;
// 定義一些全局變量, 例如原圖像(img), 模板圖像(templ) 和結果圖像(result) ,
// 還有匹配方法以及窗口名稱:
Mat img, templ, result;
char* image_window ="Source Image";
char* result_window ="Result window";
intmatch_method = TM_SQDIFF;
intmax_Trackbar =5;
voidMatchingMethod(int,void* );
intmain(intargc,char** argv )
{
// 1. 載入原圖像和模板塊
img = imread("E:/Experiment/OpenCV/Pictures/TargetSearch.jpg");
templ = imread("E:/Experiment/OpenCV/Pictures/Target.jpg");
imshow("模板圖像",templ);
// 創建窗口
namedWindow( image_window, CV_WINDOW_AUTOSIZE );
namedWindow( result_window, CV_WINDOW_AUTOSIZE );
// 2. 創建滑動條并輸入將被使用的匹配方法. 一旦滑動條發生改變,回調函數 MatchingMethod 就會被調用.
char* trackbar_label ="模板匹配方式";
createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );
MatchingMethod(0,0);
waitKey(0);
return0;
}
voidMatchingMethod(int,void* )
{
// 將被顯示的原圖像
Mat img_display;
img.copyTo( img_display );
// 創建輸出結果的矩陣
intresult_cols = img.cols - templ.cols +1;
intresult_rows = img.rows - templ.rows +1;
// 創建了一幅用來存放匹配結果的輸出圖像矩陣. 仔細看看輸出矩陣的大小(它包含了所有可能的匹配位置)
result.create( result_cols, result_rows, CV_32FC1 );
// 執行模板匹配操作,并對結果進行歸一化:
matchTemplate( img, templ, result, match_method );
normalize( result, result,0,1, NORM_MINMAX,-1, Mat() );
// 通過函數 minMaxLoc 定位最匹配的位置
doubleminVal, maxVal;
Point minLoc, maxLoc;
Point matchLoc;
//通過使用函數 minMaxLoc ,我們確定結果矩陣 R 的最大值和最小值的位置.
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );//尋找result中最大值,最小值,及它們所在的位置
// 對于方法 SQDIFF 和 SQDIFF_NORMED, 越小的數值代表更高的匹配結果. 而對于其他方法, 數值越大匹配越好
if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED ){
matchLoc = minLoc;
}else{
matchLoc = maxLoc;
}
// 繪制矩形
rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0),2,8,0);
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0),2,8,0);
imshow( image_window, img_display );
imshow( result_window, result );
return;
}
運行結果
審核編輯 :李倩
-
圖像
+關注
關注
2文章
1083瀏覽量
40418 -
模板
+關注
關注
0文章
108瀏覽量
20554 -
函數
+關注
關注
3文章
4307瀏覽量
62433
原文標題:?詳細剖析模板匹配
文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論