OpenCV4學習筆記(48)——GFTT特徵點檢測算法

在之前的筆記《OpenCV學習筆記(32)》中整理記錄了在OpenCV中關於Harris角點檢測和shi-tomas角點檢測的一些內容,而由於角點對於一幅圖像而言是非常重要的特徵點,所以OpenCV在特徵點檢測模塊中又基於shi-tomas角點檢測算法集成了一個新的特徵檢測器,這也就是今天要記錄的GFTT特徵點檢測。

那麼什麼是GFTT特徵點呢?哈哈哈哈其實這個命名很隨意,還記得之前記錄的關於調用shi-tomas角點檢測算法的API叫做goodFeaturesToTrack(),這咋一看,可不就是縮寫嗎。。。。。。當然了到底是不是這麼命名的咱也不清楚,咱也沒得問,ԾㅂԾ, 。

說白了,(goodfeaturetotrack)GFTTDetector特徵點檢測算法就是基於shi - tomas角點檢測變化而來的一種特徵提取方法,相當於OpenCV中根據shi-tomas算法集成的一個檢測器接口。但是GFTT檢測器和單純的shi-tomas角點檢測還是有點區別的,主要是表現在輸出的對象類型上。通過goodFeaturesToTrack()得到的是圖像上的Point類型的角點,而通過GFTTDetector檢測到的則是圖像上的KeyPoint類型的關鍵點、也即是特徵點。所以如果是想對圖像特徵這方面進行操作的,就得使用GFTT特徵點檢測算法來進行提取特徵點。

我們可以通過GFTTDetector::create()來創建一個GFTT特徵點檢測器,其參數如下:
(1)參數maxCorners:檢測到的最大角點數量;
(2)參數qualityLevel:輸出角點的質量等級,取值範圍是 [ 0 , 1 ];如果某個候選點的角點響應值小於(qualityLeve * 最大角點響應值),則該點會被拋棄,相當於判定某候選點爲角點的閾值;
(3)參數minDistance:兩個角點間的最小距離,如果某兩個角點間的距離小於minDistance,則會被認爲是同一個角點;
(4)參數mask:如果有該掩膜,則只計算掩膜內的角點;
(5)參數blockSize:計算角點響應值的鄰域大小,默認值爲3;如果輸入圖像的分辨率比較大,可以選擇比較大的blockSize;
(6)參數useHarrisDector:布爾類型,如果爲true則使用Harris角點檢測;默認爲false,使用shi-tomas角點檢測算法;
(7)參數k:只在使用Harris角點檢測時才生效,也就是計算角點響應值時的係數k。

可以看到,創建GFTT特徵點檢測所需的參數其實和goodFeaturesToTrack()所需的參數是一樣的,具體的內容可以參閱我之前的筆記。

不過需要注意的是,GFTT特徵點檢測器和OpenCV中其他特徵點檢測器有一個很大的不同之處,那就是GFTT特徵點檢測器只支持提取特徵點,而不支持計算描述子。也就是說我們只能夠得到GFTT特徵點,也能夠對特徵點進行繪製或者轉化成爲普通的Point類型的角點進行下一步操作。但是這樣就很尷尬了,單純能檢測出特徵點卻沒有集成生成特徵描述子的接口,這就很不利於我們需要的對圖像特徵方面的一些操作了。

不過,有句古話說的好:上有政策、下有對策。既然GFTT特徵檢測器沒有集成相應的特徵描述子,那我們就借用一下OpenCV中其他特徵檢測器的描述子接口嘛。例如我們可以通過其他檢測方法(如ORB特徵算法)的特徵描述算法來計算GFTT特徵點的描述子,我們只需要多創建一個ORB特徵檢測器,然後調用它的生成描述子接口,並傳入我們先前得到的GFTT特徵點就可以了。

代碼演示如下:

	Mat tem_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\tem.jpg");
	Mat test_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\miao.jpg");
	resize(tem_image, tem_image, Size(120,160));
	resize(test_image, test_image, Size(480, 640));
	auto gftt = GFTTDetector::create(1000, 0.2, 1.0, 3, false, 0.04);
	vector<KeyPoint>keyPoints_tem, keyPoints_test;
	gftt->detect(tem_image, keyPoints_tem, Mat());
	gftt->detect(test_image, keyPoints_test, Mat());
	drawKeypoints(tem_image, keyPoints_tem, tem_image, Scalar::all(-1), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
	drawKeypoints(test_image, keyPoints_test, test_image, Scalar::all(-1), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
	imshow("tem_image", tem_image);
	imshow("test_image", test_image);

	auto orb = ORB::create();
	Mat descriptors_tem, descriptors_test;
	orb->compute(tem_image, keyPoints_tem, descriptors_tem);
	orb->compute(test_image, keyPoints_test, descriptors_test);

	auto matcher = DescriptorMatcher::create(DescriptorMatcher::MatcherType::BRUTEFORCE_HAMMING);
	vector<DMatch> matches;
	matcher->match(descriptors_tem, descriptors_test, matches, Mat());
	Mat result;
	drawMatches(tem_image, keyPoints_tem, test_image, keyPoints_test, matches, result, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
	imshow("result", result);

上述代碼中,正是藉助了ORB特徵算法的特徵描述算法,來生成GFTT特徵點的特徵描述子,並用於進一步的GFTT特徵點匹配,效果如下圖:
在這裏插入圖片描述
所以當我們需要使用GFTT特徵點來進行某些操作時,可以根據我們的需求去借用其他特徵檢測算法的特徵描述算法來生成不同的GFTT特徵描述子,以便我們的進一步操作。

本次筆記到此整理完畢~

PS:本人的註釋比較雜,既有自己的心得體會也有網上查閱資料時摘抄下的知識內容,所以如有雷同,純屬我向前輩學習的致敬,如果有前輩覺得我的筆記內容侵犯了您的知識產權,請和我聯繫,我會將涉及到的博文內容刪除,謝謝!

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