OpenCv--模板匹配

模板匹配

模板匹配是一項在一幅圖像中尋找與另一幅模板圖像最匹配(相似)部分的技術.

實現:

  • 我們需要2幅圖像:

    1. 原圖像 (I): 在這幅圖像裏,我們希望找到一塊和模板匹配的區域
    2. 模板 (T): 將和原圖像比照的圖像塊

    我們的目標是檢測最匹配的區域:

    ../../../../../_images/Template_Matching_Template_Theory_Summary.jpg
  • 爲了確定匹配區域, 我們不得不滑動模板圖像和原圖像進行 比較 :

    ../../../../../_images/Template_Matching_Template_Theory_Sliding.jpg
  • 通過 滑動, 我們的意思是圖像塊一次移動一個像素 (從左往右,從上往下). 在每一個位置, 都進行一次度量計算來表明它是 “好” 或 “壞” 地與那個位置匹配 (或者說塊圖像和原圖像的特定區域有多麼相似).

  • 對於 T 覆蓋在 I 上的每個位置,你把度量值 保存 到 結果圖像矩陣 (R) 中. 在 R 中的每個位置 (x,y) 都包含匹配度量值:

    ../../../../../_images/Template_Matching_Template_Theory_Result.jpg

    上圖就是 TM_CCORR_NORMED 方法處理後的結果圖像 R . 最白的位置代表最高的匹配. 正如您所見, 紅色橢圓框住的位置很可能是結果圖像矩陣中的最大數值, 所以這個區域 (以這個點爲頂點,長寬和模板圖像一樣大小的矩陣) 被認爲是匹配的.

  • 實際上, 我們使用函數 minMaxLoc 來定位在矩陣 R 中的最大值點 (或者最小值, 根據函數輸入的匹配參數) .

opencv實現方法:

  • 使用OpenCV函數 matchTemplate 在模板塊和輸入圖像之間尋找匹配,獲得匹配結果圖像
  • 使用OpenCV函數 minMaxLoc 在給定的矩陣中尋找最大和最小值(包括它們的位置).

歸一化作用:

定義:標準化是將不同變化範圍的值映射到相同的固定範圍中,常見的是 [0,1],此時亦稱歸一化,也可以是[-1,1]範圍。

形式:

min_max標準化:

也稱爲離差標準化,是對原始數據的線性變換,使結果值映射到[0 - 1]之間。轉換函數如下:

clip_image002

2.Z-score標準化方法

這種方法給予原始數據的均值(mean)和標準差(standard deviation)進行數據的標準化。經過處理的數據符合標準正態分佈,即均值爲0,標準差爲1,轉化函數爲:

clip_image004

作用:

1.無量綱化
例如房子數量和收入,從業務層知道這兩者的重要性一樣,所以把它們全部歸一化,這是從業務層面上作的處理。

2.避免數值問題
不同的數據在不同列數據的數量級相差過大的話,計算起來大數的變化會掩蓋掉小數的變化。

3.一些模型求解的需要
例如梯度下降法,如果不歸一化,當學習率較大時,求解過程會呈之字形下降。學習率較小,則會產生直角形路線,不管怎麼樣,都不會是好路線。

4.時間序列
進行log分析時,會將原本絕對化的時間序列歸一化到某個基準時刻,形成相對時間序列,方便排查。

5.收斂速度
加快求解過程中參數的收斂速度。

例子:

假設有兩個變量,都是均勻分佈,x1範圍是[10000,20000],x2範圍是[1,2]。有很多處於同一直線上的點,我們稱這條直線爲L。如果現在我們要做一個分類的話,x2幾乎可以被忽略,x2很無辜的被幹掉了,僅僅因爲所謂量綱的問題。即便x2不被幹掉,現在繼續求解,來做梯度下降。 很顯然,如果某一步我們求得的下降方向不在直線L上,幾乎可以肯定肯定這步不會下降。這就會導致不收斂,或者收斂很慢。

模板匹配實例:

#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
Mat src1,src2, dst;
int value = 0;
int max_value = 5;
void demo(int, void*);
int main()
{
	src1 = imread("C:\\Users\\馬迎偉\\Desktop\\heibao.jpg");
	src2 = imread("C:\\Users\\馬迎偉\\Desktop\\heibao1.png");
	if (src1.empty())
	{
		printf("cannot load!!\n");
		system("pause");
		return -1;
	}
	namedWindow("src",CV_WINDOW_AUTOSIZE);
	namedWindow("output",CV_WINDOW_AUTOSIZE);
	createTrackbar("trackbar","output",&value,max_value,demo);
	demo(0, 0);
	//imshow("output", dst);
	waitKey(0);
	return 0;
}
void demo(int, void*)
{
	int dst_col = src1.cols - src2.cols + 1;
	int dst_row = src1.rows - src2.rows + 1;
	//dst必須規定是 這個尺寸和類型
	dst.create(Size(dst_col,dst_row),CV_32FC1);
	//模板匹配
	matchTemplate(src1,src2,dst,value,Mat());
	//歸一化
	normalize(dst,dst,0,1,NORM_MINMAX,-1,Mat());
	double minval, maxval;
	Point minloc, maxloc, loc;
	//找到模板匹配的最大值最小值和位置
	minMaxLoc(dst,&minval,&maxval,&minloc,&maxloc,Mat());
	if (value==CV_TM_SQDIFF||value==CV_TM_SQDIFF_NORMED)
	{
		loc = minloc;
	}
	else
	{
		loc = maxloc;
	}
	rectangle(dst,Rect(loc.x,loc.y,src2.cols,src2.rows),Scalar(0,0,255),2,LINE_AA);
	rectangle(src1,Rect(loc.x, loc.y, src2.cols, src2.rows), Scalar(255, 255, 255), 2, LINE_AA);
	imshow("output",dst);
	imshow("src", src1);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章