目录
特征点提取器的构造函数(主要函数)
问题一:图像金字塔每层如何分配特征点数量
问题二:ORB(Oriented FAST and Rotated BRIED)的特征点、特征描述子
(1)FAST特征点
(2)Oriented FAST(包含灰度质心圆的概念,改进之处)
(3)BRIEF描述子
(4)rBRIEF和steered BRIEF(改进之处)
问题三:构建图像金字塔
(1)图像金字塔
注意:图像金字塔进行扩充:
问题四:ORB构造函数仿函数、图像帧构造函数
(1)ORB构造函数仿函数
(2)ORB构造函数仿函数
问题五:特征点四叉树均匀化分配(改进之处)
主要参考链接
//特征点提取器的构造函数
ORBextractor::ORBextractor(int _nfeatures, //指定要提取的特征点数目
float _scaleFactor, //指定图像金字塔的缩放系数
int _nlevels, //指定图像金字塔的层数
int _iniThFAST, //指定初始的FAST特征点提取参数,可以提取出最明显的角点
int _minThFAST): //如果初始阈值没有检测到角点,降低到这个阈值提取出弱一点的角点
nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
iniThFAST(_iniThFAST), minThFAST(_minThFAST)//设置这些参数
详细中文源码解读:链接:https://pan.baidu.com/s/1LWfowy5wbUdXamEGE1STcA 提取码:t796
PS:该代码从“计算机视觉life”客服处免费获得,感觉确实挺详细的,就标明一下出处,侵权则删。
主要思路:求出图像金字塔每一层面积的总和,根据每一层面积所占的比例,分配的特征点数量。
参考链接:ORB-SLAM2源码特征点提取_机务猿的博客-CSDN博客_orbslam2特征提取
详细过程:
主要思路:比较中心点与周围16个点的灰度值大小。
参考链接:
[ORB-SLAM2] ORB-SLAM中的ORB特征(提取) - 知乎
常见图像特征点——FAST角点,ORB,SIFT_小伟db的博客-CSDN博客_fast角点
ORB-SLAM2中FAST改进的小细节:
改进一:特征计算的简化
我们一般取2、6、10、14这四个位置的点,如果有三个及以上和P不同,则认为它是一个特征点。
改进二:非最大值抑制
取一个领域,只保留其中响应大的点,目的是为了简化计算。
改进三:金字塔
FAST对亮度有鲁棒性,但没有尺度不变性,因为每次取的点的范围是一样的。
改进四:方向
FAST没有旋转不变性,于是计算一个邻域内灰度值的质心,然后将中心点和质心的连线得到x轴,服务于后续的rBRIEF。
使用Oriented FAST原因:BRIEF描述子的计算过程:在当前关键点P周围以一定模式选取N个点对,组合这N个点对的T操作的结果就为最终的描述子。当我们选取点对的时候,是以当前关键点为原点,以水平方向为X轴,以垂直方向为Y轴建立坐标系。当图片发生旋转时,坐标系不变,同样的取点模式取出来的点却不一样,计算得到的描述子也不一样,这是不符合我们要求的。因此我们需要重新建立坐标系,使新的坐标系可以跟随图片的旋转而旋转。这样我们以相同的取点模式取出来的点将具有一致性。(通俗易懂理解ORBSLAM2特征提取模块 - 简书)
主要思路:利用了灰度质心圆求出灰度的质心。指定中心点到质心的方向为特征点方向
参考链接:https://www.jianshu.com/p/9ee6b2145eaa【ORB-SLAM2源码梳理3】构造特征点图像金字塔,构造灰度质心圆(ORBextractor.cc)_Jay_z在造梦的博客-CSDN博客_灰度质心
详细过程:P为关键点。以半径R选择一块圆形区域,其中每个小格子代表一个像素。现在我们用大学物理微积分方法求圆形木板质心进行类比,木板上每个点的质量相当于像素值。我们即可求出密度不均匀木板的质心Q。计算公式如下。其中R在代码中为HALF_PATCH_SIZE=15,即选半径为15个像素值。
方法二:
当我们以PQ作为坐标轴时,在不同的旋转角度下,我们以同一取点模式取出来的点是一致的。这就解决了旋转一致性的问题。
主要思路:选在关键点为中心选一个区域,取N对点,比较每个点对大小,得到一个二进制码,即为相应的描述子
参考链接:[ORB-SLAM2] ORB-SLAM中的ORB特征(提取) - 知乎
详细过程:
使用rBRIEF和steered BRIEF原因:rBRIEF特征描述是在BRIEF特征描述的基础上加入旋转因子改进的。使用steeredBRIEF方法得到的特征描述子具有旋转不变性,但是却在另外一个性质上不如原始的BRIEF算法。是什么性质呢,是描述符的可区分性,或者说是相关性。这个性质对特征匹配的好坏影响非常大。描述子是特征点性质的描述。描述子表达了特征点不同于其他特征点的区别。我们计算的描述子要尽量的表达特征点的独特性。如果不同特征点的描述子的可区分性比较差,匹配时不容易找到对应的匹配点,引起误匹配。
参考链接:
传统特征点检测器的检测特征点和匹配流程_婉拒校花三次的博客-CSDN博客
ORB特征提取详解 BRUEF rBRIEF steered BRIEF_Jinxiaoyu886的博客-CSDN博客_rbrief 描述子 opencv
详细过程:
请直接参考以上链接,较为详细。
主要思路:相机成像“物近像大,物远像小”的原理。为了实现特征尺度不变性采用了图像金字塔,金字塔的缩放因子为1.2,。其思路就是对原始图形(第0层)依次进行1/1.2缩放比例进行降采样得到共计8张图片(包括原始图像),然后分别对得到的图像进行特征提取,并记录特征所在金字塔的第几层,这样得到一帧图像的特征点。
参考链接:ORB_SLAM2中特征提取之图像金字塔尺度不变性理解_RobotLife的博客-CSDN博客
通俗易懂理解ORBSLAM2特征提取模块 - 简书
详细过程:
现在假设在第二层中有一特征点F,为了避免缩放带来特征点F在纵向的移动,为简化叙述,选择的特征点F位于图像中心,如图2所示。根据相机成像“物近像大,物远像小”的原理,如图2所示为相机成像的示意图。假设图1中摄像机原始图像即金字塔第0层对应图2中成像视野I0 ,则图1中图像金字塔第2层图像可以相应对应于图2中成像视野I2 。由图三可知,金字塔第二层相当于原图(第0层)缩放了倍(边的尺度是缩放1.2,面积则缩放)。
使用了copyMakeBorder函数
,边界留白长度为第三四五六个参数,代码中为const int EDGE_THRESHOLD = 19;
copyMakeBorder(mvImagePyramid[level], //源图像
temp, //目标图像(此时其实就已经有大了一圈的尺寸了)
EDGE_THRESHOLD, EDGE_THRESHOLD, //top & bottom 需要扩展的border大小
EDGE_THRESHOLD, EDGE_THRESHOLD, //left & right 需要扩展的border大小
BORDER_REFLECT_101+BORDER_ISOLATED); //扩充方式,opencv给出的解释:
扩充方式主要以下三种:
主要思路:可以用于仿函数(一个可以实现函数功能的对象)
仿函数( functor)又称为函数对象( function object)是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载 operator()运算符
1.仿函数可有拥有自己的数据成员和成员变量,这意味着这意味着仿函数拥有状态。这在一般函数中是不可能的。
2.仿函数通常比一般函数有更好的速度
参考链接:ORB2单目读代码笔记3--ORB特征提取构造函数仿函数、图像帧构造函数、计算图像金字塔并进行扩充_不能再吃了OvO的博客-CSDN博客
详细过程:
首先出现在Frame类中,
Fram::ExtractORB作用:的提取图像的ORB特征点,提取的关键点存放在mvKeys,描述子存放在mDescriptors。
再从ExtractORB类中找到operator()
* @brief 用仿函数(重载括号运算符)方法来计算图像特征点
*
* @param[in] _image 输入原始图的图像
* @param[in] _mask 掩膜mask
* @param[in & out] _keypoints 存储特征点关键点的向量
* @param[in & out] _descriptors 存储特征点描述子的矩阵
*/
void ORBextractor::operator()( InputArray _image, InputArray _mask, vector& _keypoints,
OutputArray _descriptors)
{
使用仿函数的作用是对输入的图像提取特征点、计算描述子。
这个属于Fram类中的Frame::Frame函数,此处不详说,具体可以参考链接:
判断frame是否已创建_ORB SLAM2源码解读(三):Frame类_weixin_39747399的博客-CSDN博客
目的:ORB 特征提取方法有个问题,就是特征点往往集中在纹理丰富的区域,而缺乏特征的区域特征点数量会少很多,这会导致一部分特征点是没有用的,本来一个特征点就可以表达清楚一个小的区域,现在在这个区域附近提取了十个特征点,那么其他九个就是冗余的。除了冗余因素外,还有一个重要的影响就是会影响位姿的解算,特征点在空间中分布的层次越多,越均匀,那么特征匹配越能精确地表达出空间的几何关系。极端来说,比如所有特征点都集中在了一个点,那么我们是无法计算出相机的位姿的。也就是说,特征点分布太过集中,会影响 SLAM 的精度。(ORB-SLAM 解读(三) ORB特征点均匀化_Hali_Botebie的博客-CSDN博客_特征点均匀化)
主要思路:是将地理空间递归划分为不同层次的树结构。它将已知范围的空间等分成四个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割。四叉树的结构比较简单,并且当空间数据对象分布比较均匀时,具有比较高的空间数据插入和查询效率,因此四叉树是GIS中常用的空间索引之一。常规四叉树的结构如图所示,地理空间对象都存储在叶子节点上,中间节点以及根节点不存储地理空间对象。
参考链接:ORB2单目读代码笔记3--ORB特征提取构造函数仿函数、图像帧构造函数、计算图像金字塔并进行扩充_不能再吃了OvO的博客-CSDN博客VSLAM系列原创04讲 | 四叉树实现ORB特征点均匀化分布:原理+代码_计算机视觉life的博客-CSDN博客_特征点分布ORB2单目读代码笔记3--ORB特征提取构造函数仿函数、图像帧构造函数、计算图像金字塔并进行扩充_不能再吃了OvO的博客-CSDN博客
ORB2单目读代码笔记4--提取ORB特征点、四叉树实现均匀化分布_不能再吃了OvO的博客-CSDN博客_四叉树orb
通俗易懂理解ORBSLAM2特征提取模块 - 简书
四叉树空间索引原理及其实现_小哈龙的博客-CSDN博客_四叉树索引
详细过程:
ORB2单目读代码笔记4--提取ORB特征点、四叉树实现均匀化分布_不能再吃了OvO的博客-CSDN博客_四叉树orb
请直接参考以上链接,较为详细。
注意一:特征点均匀化策略一分为4都是一分为4到底吗,比如说1张图像,已经一分为4。在这个基础上,下一轮是否对这4个中的每一个都进行一分为四了?还是说到数目了就停止了。
解决一:不断地进行一分为4。=>快要达到目标数量的时候,那就sort排序一下=>从数量多的进行开始进行一分为4,同时每次判断是否满足目标数量。这样很符合一个人的思维。
ORB-SLAM2代码笔记(十):ORBextractor - 简书 (jianshu.com)通俗易懂理解ORBSLAM2特征提取模块 - 简书ORB_SLAM2 代码分析及介绍(视觉VO及重定位,Tracking)第一部分_右边是我女神的博客-CSDN博客_orbslam2代码详解
(一)ORB描述子提取 - 小C酱油兵 - 博客园 (cnblogs.com)
(2条消息) ORB-SLAM2源码特征点提取_机务猿的博客-CSDN博客_orbslam2特征提取
好文推荐: ORB-SLAM2代码详解02: 特征点提取器ORBextractor_ncepu_Chen的博客-CSDN博客_orbextractor