opencv C++模板匹配的簡單實現

一 簡單實現

#include <opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;

int main()
{
	Mat img = imread("52.jpg");
	Mat templ = imread("templ.jpg");
	Mat result;
	matchTemplate(img,templ,result,TM_CCOEFF_NORMED);//原圖,模板,匹配方法
	
	double maxVal, minVal;
	Point maxLoc, minLoc;
	//尋找最大值,最小值
	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
	//繪制矩形,矩形的左上角是最大值的位置,右下角是在最大值上加上模板的行寬和和列高
	rectangle(img,Point(maxLoc.x,maxLoc.y),Point(maxLoc.x+templ.cols,maxLoc.y+templ.rows),Scalar(0,0,255),2);//顏色紅色,粗度2
	imshow("原圖", img);
	imshow("模板",templ);
	imshow("result",result);
	waitKey(0);
	return 0;
}

結果如下,分別是模板圖,原圖(找到瞭與模板匹配的部分,並矩形框標記,結果圖,暫時覺得有點問題的 )

二 函數及原理講解

1 matchTemplate()參數詳解

matchTemplate( InputArray image, InputArray templ,OutputArray result, int method );

image:待匹配的源圖像
templ:模板圖像
result:保存結果的矩陣,我們可以通過minMaxLoc() 確定結果矩陣的最大值和最小值的位置.

method :模板匹配的算法
有以下六種:
  enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };

TM_SQDIFF,TM_SQDIFF_NORMED匹配數值越低表示匹配效果越好,其它四種反之。
TM_SQDIFF_NORMED,TM_CCORR_NORMED,TM_CCOEFF_NORMED是標準化的匹配,得到的最大值,最小值范圍在0~1之間,其它則需要自己對結果矩陣歸一化。
不同的方法會得到差異很大的結果,可以通過測試選擇最合適的方法。

cv::TM_SQDIFF 判斷 minVal 越小,效果越好
計算模板與目標圖像的方差,由於是像素值差值的平方的和,所以值越小匹配程度越高;

cv::TM_SQDIFF_NORMED 判斷 minVal 越接近0,效果越好
范化的cv::TM_SQDIFF,取值為0-1之間,完美匹配返回值為0;

cv::TM_CCORR 判斷 maxVal 越大,效果越好
使用dot product計算匹配度,越高匹配度就好;

cv::TM_CCORR_NORMED 判斷 maxVal 越接近1,效果越好
范化的cv::TM_CCORR,0-1之間,我用的這個;

cv::TM_CCOEFF 判斷 maxVal 越大,效果越好
采用模板與目標圖像像素與各自圖像的平均值計算dot product,正值越大匹配度越高,負值越大圖像的區別越大,但如果圖像沒有明顯的特征(即圖像中的像素值與平均值接近)則返回值越接近0;

cv::TM_CCOEFF_NORMED 判斷 maxVal 越接近1,效果越好
范化的cv::TM_CCOEFF,-1 ~ 1之間。

2 minMaxLoc()函數

查找全局最小和最大稀疏數組元素並返回其值及其位置

void minMaxLoc(const SparseMat& a, double* minVal,double* maxVal, int* minIdx=0, int* maxIdx=0);

a: 匹配結果矩陣
&minVal 和 &maxVal: 在矩陣 result 中存儲的最小值和最大值
&minLoc 和 &maxLoc: 在結果矩陣中最小值和最大值的坐標.

到此這篇關於opencv C++模板匹配的文章就介紹到這瞭,更多相關opencv 模板匹配內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: