模板匹配,顧名思義,即在一副影像中尋找和另一幅影像最相似(匹配)的部分,前段時間做實驗
用到了模板匹配演算法,之前作的筆記先放到博客上.
1、用到的函式和引數解釋
1.1 Rect()函式
Mat Image = imread(“0.png”)
Mat templateimage = Image(Rect(x, y, n,m));
即我們先定位到坐標為(x,y)這個像素點,然后以這個點為起點,往右下劃出一個n列m行的區域
參考博客:https://blog.csdn.net/weixin_30954607/article/details/95317294
1.2 nameWindow()函式
namedWindow( image_window, CV_WINDOW_AUTOSIZE ); // 視窗名稱,視窗標識 CV_WINDOW_AUTOSIZE是自動調整視窗大小以適應圖片尺寸
namedWindow( result_window, CV_WINDOW_AUTOSIZE );
創建視窗,第一個引數是視窗名稱,第二個視窗是int型別的Flag可以填寫以下的值:
WINDOW_NORMAL //設定了這個值,用戶便可以改變視窗的大小(沒有限制)
WINDOW_AUTOSIZE //如果設定了這個值,視窗大小會自動調整以適應所顯示的影像,并且不能手動改變視窗大小
1.3 createTrackba()函式
createTrackbar(const string& trackbarname, const string& winname,
int* value, int count,
TrackbarCallback onChange = 0,
void* userdata = 0);
引數1. trackbarname:滑動空間的名稱;
引數2. winname:滑動空間用于依附的影像視窗的名稱;
引數3. value:初始化閾值;
引數4. count:滑動控制元件的刻度范圍;
引數5. TrackbarCallback是回呼函式.
1.4 matchTemplate()函式
matchTemplate( img, templ, result, match_method );
即模板匹配函式,引數含義分別為:待匹配影像,模版影像,輸出結果影像,匹配方法.
匹配方法就是采取何種計算方式來衡量模板影像和代匹配影像某部分的相似(匹配)程度.
opencv提供了6種方法:
平方差匹配法 CV_TM_SQDIFF
歸一化平方差匹配法 CV_TM_SQDIFF_NORMED
相關匹配法 CV_TM_CCORR
歸一化相關匹配法 CV_TM_CCORR_NORMED
系數匹配法 CV_TM_CCOEFF
化相關系數匹配法 CV_TMCCOEFF_NORMED
需要注意的是對于方法SQDIFF和SQDIFF_NORMED兩種方法來講,越小的值就有著更高的匹配結果,而其余的方法則是數值越大匹配效果越好.
參考博客:https://blog.csdn.net/keith_bb/article/details/70050080
1.5 normalize()歸一化函式
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
引數含義:輸入陣列,輸出陣列,normalize的最小值,normalize的最大值,歸一化型別,當type為負數的時候輸出的type和輸入的type相同.
歸一化函式是為了后面資料處理的方便,其次是保證程式運行時收斂加快.
1.6 minMaxLoc()函式
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
用于檢測矩陣中最大值和最小值的像素點位置.
2、實驗原理和代碼
2.1 原理
讓模板圖片在待匹配圖片上的一次次滑動(從左到右,從上到下一個像素為單位的移動),然后將兩張圖片的像素值進行比對,然后選擇相似度最高的部分進行標記,當遇到相似度更高的部分時更換標記部分,掃描完畢之后,將相似度最高的部分標記出來,作為圖片進行輸出.
2.2 實驗代碼
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace std;
using namespace cv;
Mat img; Mat templ; Mat result;
char* image_window = "Original Image"; //視窗名稱定義
char* result_window = "Result window"; //視窗名稱定義
int match_method;
int max_Trackbar = 5;
void MatchingMethod( int, void* )
{
Mat img_display;
img.copyTo( img_display ); //將img的內容copy到img_display
/// 創建輸出結果矩陣
int result_cols = img.cols - templ.cols + 1;//計算用于儲存匹配結果的輸出影像矩陣的大小
int result_rows = img.rows - templ.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 );//被創建矩陣的列數,行數,以CV_32FC1形式儲存
/// 進行匹配和標準化
matchTemplate( img, templ, result, match_method ); //待匹配影像,模版影像,輸出結果影像,匹配方法
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );//歸一化
/// 通過函式 minMaxLoc 定位最匹配的位置
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );//檢測矩陣中最大值和最小值的像素位置
/// 對于方法 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(0,0,255), 2, 8, 0 ); //用矩形框起來框出最佳匹配位置
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar(0,0,255), 2, 8, 0 );
imshow( image_window, img_display );//輸出最終的到的結果
imwrite("result.png",img_display); //將得到的結果寫到源代碼目錄下
imshow( result_window, result ); //輸出匹配結果矩陣
return;
}
/*主函式*/
int main( int argc, char** argv )
{
img = imread("./../1.png");//載入待匹配影像
templ = imread("./../2.png");//載入模版影像
/// 創建視窗
namedWindow( image_window, CV_WINDOW_AUTOSIZE ); //視窗名稱,視窗標識CV_WINDOW_AUTOSIZE是自動調整視窗大小以適應圖片尺寸
namedWindow( result_window, CV_WINDOW_AUTOSIZE );
/// 創建滑動條
createTrackbar("jackchen", image_window, &match_method, max_Trackbar, MatchingMethod );
MatchingMethod( 0, 0 );//初始化顯示
waitKey(0);
return 0;
}
3、匹配結果展示
待匹配影像:

模板影像:

匹配結果(拉動滑塊可以得到不同匹配方式的結果):

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289708.html
標籤:其他
上一篇:STM32H750獲取OV7670攝像頭影像及上位機解碼(一維碼&二維碼)
下一篇:普通話識別,mp3格式轉wav, 采樣率轉換48000轉16000,多通道轉單通道,運用百度API,短音頻,python
