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

原创文章 58 获赞 118 访问量 7416

猜你喜欢

转载自blog.csdn.net/weixin_45224869/article/details/105717490