OpenCV4學習筆記(47)——BRISK特徵提取描述算法

今天要整理記錄的是OpenCV中BRISK特徵提取描述算法的運用。

BRISK特徵提取描述算法全稱爲 Binary Robust Invariant Scalable Keypoints(二進制魯棒不變可擴展關鍵點)。BRISK算法也是SIFT算法的一種改進型,主要是針對於旋轉不變性、魯棒性、運算速度等方面做了優化,其大致流程如下:

(1)在提取特徵點階段與SIFT算法類似(可參閱《OpenCV4學習筆記(38)》,同樣是先構造多尺度圖像金字塔,再從每一層圖像組的多尺度空間中找到最大特徵點(非極大值抑制);

(2)再通過亞像素插值得到最大特徵點的精確座標位置,也即把最大特徵點從其它層的座標映射到金字塔最底層的座標位置,從而完成對最大特徵點的定位。

(3)在描述特徵點階段,使用特徵點鄰域同心圓採樣法,在每個特徵點的鄰域中選擇一個同心圓,在這個同心圓上均勻採樣,並對所有采樣點進行高斯模糊以消除重複採樣帶來的影響,並以採樣點中的短距離點對的灰度值比較結果,來構建二進制描述子(類似BRIEF特徵二進制描述算法,可參閱《OpenCV4學習筆記(39)》)。

(4)再以每個特徵點的方向特徵、也就是梯度來進行方向歸一化,強化了BRISK特徵描述子的旋轉不變性。

通過上述步驟即可得到BRISK特徵的二進制描述子,總的來說BRISK特徵算法是一種效果比較好的特徵算法,主要優點在於它的檢測速度,相比SIFT等特徵算法而言要明顯更快,可以用於實時處理中。

在OpenCV中同樣封裝好了BRISK算法的特徵檢測器,下面是調用BRISK算法的代碼演示:

	Mat tem_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\tem.jpg");
	Mat dected_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\miao.jpg");
	resize(tem_image, tem_image, Size(160,120));
	resize(dected_image, dected_image, Size(600, 800));

	auto brisk = BRISK::create();
	vector<KeyPoint> keyPoints_tem, keyPoints_dected;
	Mat descriptors_tem, descriptors_dected;
	brisk->detectAndCompute(tem_image, Mat(), keyPoints_tem, descriptors_tem, false);
	brisk->detectAndCompute(dected_image, Mat(), keyPoints_dected, descriptors_dected, false);

	auto matcher = DescriptorMatcher::create(DescriptorMatcher::MatcherType::BRUTEFORCE);
	vector<DMatch> matches;
	matcher->match(descriptors_tem, descriptors_dected, matches);

	float maxdist = matches[0].distance;
	for (int i = 0; i < matches.size(); i++)
	{
		if (maxdist < matches[i].distance)
		{
			maxdist = matches[i].distance;
		}
	}
	float thresh = 0.45;
	vector<DMatch> good_Matches;
	vector<Point2f> temPoints, dectedPoints;
	for (int j = 0; j < matches.size(); j++)
	{
		if (matches[j].distance < thresh * maxdist)
		{
			good_Matches.push_back(matches[j]);
			temPoints.push_back(keyPoints_tem[matches[j].queryIdx].pt);
			dectedPoints.push_back(keyPoints_dected[matches[j].trainIdx].pt);
		}
	}
	if (0 == good_Matches.size())
	{
	cout << "不存在最佳匹配特徵點" << endl;
	return 0;
	}

	Mat result;
	drawMatches(tem_image, keyPoints_tem, dected_image, keyPoints_dected, good_Matches, result, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
	imshow("result", result);

演示效果如下圖:
在這裏插入圖片描述
在運行BRISK算法和SIFT等算法對同一張圖像進行特徵點提取時,可以明顯的感受到二者的速度差距,可以說BRISK是一種高速的特徵點檢測和特徵描述子生成以及高速匹配的算法。

而且BRISK特徵提取描述算法在很大程度上還保留了旋轉不變性和尺度不變性,實現了較高檢測質量的同時仍然具有較快的運行速度,有效降低了計算成本,更適合用於實時特徵提取的工作中。

好的,今天的筆記整理到此結束,謝謝閱讀。

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

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