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:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

你可能感兴趣的:(学习笔记)