浅谈opencv库中的特征点提取与匹配(四)——ORB特征点提取详解
上篇博文中,小楼给大家介绍了SIFT特征点,这中特征点的优势固然明显,但随着带来的副作用也是巨大的.(老天爷从来都是公平的).那就是它巨大的计算量.目前来说,还没有那种cpu能够实时的计算SIFT特征点.
今天,介绍给大家一种相对来说更加完美的特征点–ORB特征.
ORB特征是近年来非常具有代表性的一种特征.它采用关键点和二进制描述子来对特征点进行判定与描述.下面为大家详细介绍ORB特征.
1. ORB特征由FAST关键点和BRIEF描述子构成,
其特征点的提取步骤分为FAST关键点的提取和BRIEF描述子的生成.
2.FAST关键点的提取:
FAST是一种角点,主要根据该点像素值与周围邻域像素点的像素值比较获得.主要检测灰度变化明显的地方.其提取步骤可以分为四部.
(1)读取检测点的灰度值I;
(2)设置一个阈值P(如I的120%);
(3)选取检测点的邻域像素;
(4)判断邻域像素点的灰度值是否大于阈值P,若连续n个邻域点的灰度值大于阈值,判定检测点为关键点 .BRIEF描述子:BRIEF描述子为一种二进制描述子,通过比较关键点与其邻域点像素值的大小.如邻域点像素值大于关键点像素值的话取0,否则取1.这样我们可以构建出一个128维的二进制向量来对关键点进行描述.就是因为ORB特征的描述子只需要比较大小,因此,它能保持很好的实时性.
接下来是ORB特征的提取实践,编写一个简单的小程序就可以实现这个功能.
运行环境:ubuntu16.04+opencv-3.1.0
//初始化
std::vector<KeyPoint> keypoints_1;
Mat descriptors_1;
//计时
clock_t time_stt=clock();
cout<<"< Extracting keypoints from images using ORB..."<<endl;
Ptr<FeatureDetector> detector = ORB::create();
detector->detect ( image,keypoints_1 );
Ptr<DescriptorExtractor> descriptor = ORB::create();
descriptor->compute ( image, keypoints_1, descriptors_1 );
cout<<"image has"<<keypoints_1.size()<<"points"<<endl;
cout<<"time use in ORB is"<<1000 * (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms" << endl;
//绘制并保存特征点
Mat out1;
namedWindow("提取结果",CV_WINDOW_NORMAL);
drawKeypoints( image, keypoints_1, out1, Scalar::all(-1), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("提取结果",out1);
imwrite("./orb.png",out1);
提取结果如下图所示:大家可以与上文的SIFT特征点进行对比,会发现提取时间大大减少了.这个时间也与电脑的性能有关,但是楼主用的是同一台老电脑.ORB特征的强大可见一斑!
全部代码留邮箱找楼主要,欢迎大家随时讨论!