openCV實現模板匹配
阿新 • • 發佈:2019-01-05
在影象目標識別技術的研究應用中,模板匹配技術是其中一個重要的研究方向,它具有演算法簡單、計算量小以及識別率高的特點。模板匹配的基本原理是通過相關函式的計算來找到它和被搜尋圖的座標位置。比如可以設模板 T ( n×m畫素點)疊放在搜尋圖S上平移,模板覆蓋下的那塊搜尋圖叫做子圖, i , j 為這塊子圖的左上角像點在S圖中的座標 , 叫參考點 , 1≤ i , j ≤n -m+ 1。比較T和Si , j的內容,若兩者一致 , 則 T 和 Si , j之差為零。
針對影象特徵不同 , 有多種匹配演算法 。例如 : 絕對差演算法,是一種簡化了的 求解相 似度的 方法 , 計算量 小 , 當目標影象變化不是很快的情況下 , 具有一 定的實用性 ; 不變矩策略主要應用於一些簡單圖形的識別 , 具有大小旋轉不變性 ,但對於有形狀變化的圖 像識別 不太適 合 ; 傅 立葉變 換或小波變換 , 將影象變換到變換域 , 與目標影象變換域特徵進行比較得到相似程度 , 其匹配 準確度 高 、 抗干擾能力強 , 但計算量大。基於各種匹配演算法的優點 , 它們已被應用於從簡單圖形 ( 背 景 、汽車、飛機等) 到複雜影象 (字元、指紋、人臉等)的識別、目標跟蹤等眾多領域 。
openCV的C++版提供了模板匹配的函式:
void matchTemplate(InputArray image, InputArray temp, OutputArray result, int method)
image –需要進行模板匹配的原影象(搜尋圖)。
templ –模板影象,不能夠比原影象小並且需要和原圖有相同的格式。
result – 匹配視窗,如果原圖(image)尺寸是W×H,模板(templ)是w×h,則匹配視窗(result)的尺寸是(W-w+1)×(H-h+1)
method – 指定使用何種匹配方法的引數
method對應的匹配方法:
當函式完成匹配後,使用
minMaxLoc()
函式就可以找到做為全域性最大(CV_TM_SQDIFF
)或最小(CV_TM_CCORR
)值的最佳匹配結果。 下面通過一個例子來實現模板匹配:
#define WN "模板匹配"
Mat srcImg, tempImg, resultImg;
int MatchMetod;
int MaxTrackbarNum = 5;
void Matching(int, void*);
void matchTemplateFunction(){
srcImg = imread("Tekkaman.jpg");
tempImg = imread("headTan.png");
createTrackbar("方法", WN, &MatchMetod, MaxTrackbarNum, Matching);
Matching(0, 0);
waitKey(0 );
}
void Matching(int, void*){
//給區域性變數初始化
Mat copyImg;
srcImg.copyTo(copyImg);
//初始化用於結果輸出的矩陣
int resultImgCols = srcImg.cols - tempImg.cols + 1;
int resultImgRows = srcImg.rows - tempImg.rows + 1;
resultImg.create(resultImgCols, resultImgRows, CV_32FC1);
//進行匹配和標準化
matchTemplate(copyImg, tempImg, resultImg, MatchMetod);
normalize(resultImg, resultImg, 0, 1, NORM_MINMAX, -1, Mat());
//通過函式minMaxLoc定位最匹配位置
double minValue, maxValue;
Point minLocation, maxLocation,matchLocation;
minMaxLoc(resultImg, &minValue, &maxValue, &minLocation, &maxLocation, Mat());
//對於方法SQDIFF和SQDIFF_NORMED,越小的數值有著更高的匹配結果,而其餘方法,陣列越大匹配效果越好
if (MatchMetod == CV_TM_SQDIFF || MatchMetod == CV_TM_SQDIFF_NORMED){
matchLocation = minLocation;
}
else{ matchLocation = maxLocation; }
//繪製出矩形,並顯示最終結果
rectangle(srcImg, matchLocation, Point(matchLocation.x + tempImg.cols, matchLocation.y + tempImg.rows)
,Scalar(0,0,255),2,8,0);
rectangle(resultImg, matchLocation, Point(matchLocation.x + tempImg.cols, matchLocation.y + tempImg.rows), Scalar(0, 0, 255), 2, 8, 0);
imshow(WN,srcImg);
//imshow("效果圖", resultImg);
}
int main(){
matchTemplateFunction();
return 0;
}
原圖:
模板圖:
匹配結果: