ORB SLAM2源码解读

ORBSLAM2系统流程所有细节


ORB SLAM2源码解读(一):系统流程

[为何要加载orb vocabulary?他的作用是啥?](https://www.zhihu.com/question/49153462/answer/114807054)
[ORB-SLAM3知识点():词袋模型BoW](https://zhuanlan.zhihu.com/p/354616831)
[ORB_SLAM2中的回环检测](https://zhehangt.github.io/2018/04/11/SLAM/ORBSLAM/ORBSLAM2LoopClosing/)

ORB SLAM2源码解读(二):MapPoint类

一个地图点会被多个关键帧观测到,多个关键帧之间通过共同观测到地图点而发生的关系叫共视关系,在orb-slam中,就是通过MapPoint类来维护共视关系的。在进行局部BA优化时,只优化具有共视关系的这些关键帧,其他关键帧的位姿不参与优化。

Replace:该函数的作用是将当前地图点(this),替换成pMp,这主要是因为在使用闭环时,完成闭环优化以后,需要调整地图点和关键帧,建立新的关系。
ComputeDistinctiveDescriptors:描述子之间的两两距离,对所有距离取平均,最后找离这个中值距离最近的描述子。
PredictScale:该函数的作用是预测特征点在金字塔哪一层可以找到。

ORB SLAM2源码解读(三):Frame类

ComputeStereoMatches:从双目中恢复深度
其作用是为左图的每一个特征点在右图中找到匹配点,根据基线(有冗余范围)上描述子距离找到匹配,再进行SAD精确定位,最后对所有SAD的值进行排序, 剔除SAD值较大的匹配对,然后利用抛物线拟合得到亚像素精度的匹配,匹配成功后会更新 mvuRight 和 mvDepth。

SAD算法:https://blog.csdn.net/lwx309025167/article/details/78387879

ORB SLAM2源码解读(四):KeyFrame类

https://blog.csdn.net/weixin_39373577/article/details/85226187
KeyFrame为关键帧,关键帧之所以存在是因为优化需要,所以KeyFrame的几乎所有内容都是位优化服务的。该类中的函数较多,我们需要归类梳理一下,明白其功能原理,才能真正弄懂它的内容。

图优化需要构建节点和变,节点很好理解,就是关键帧的位姿,所以需要有读写位姿的功能,边分为两种,第一种边是和MapPoint之间的,所以需要有管理和MapPoint之间关系的函数,第二种边是和其他关键帧之间的,他们之间需要通过MapPoint产生联系,两帧能够共同观测到一定数量的MapPoint时则可以在他俩之间建立边,这种关系叫共视,所以需要有管理共视关系的函数,这种通过共视关系构建的优化模型叫做Covisibility Graph。
但是,当需要优化较大范围的数据时,就会需要很大的计算量,因此需要简化,而ORB SLAM2中的Essential Graph就是Covisibility Graph的一种简化版,它通过“生成树(Spanning tree)”来管理各关键帧之间的关系,每个帧都有一个父节点和子节点,节点为其他关键帧,在构建优化模型时,只有具有父子关系的关键帧之间才建立边,换言之,Essential Graph就是Covisibility Graph的子集,这样就大大减少了边的数量,从而起到减小计算量的作用,因此,该类还需要有管理“生成树(Spanning tree)”的函数。

为了更清晰地了解Covisibility Graph 和 Essential Graph之间的区别,我们可以利用下面几张图再详细解释一下

ORB SLAM2源码解读_第1张图片

图(a)没什么好说的
图(b)中Covisibility graph是用来描述不同关键帧可以看到多少相同的地图点:每个关键帧是一个节点,如果两个关键帧之间的共视地图点数量大于15,则这两个节点之间建立边,边的权重是共视地图点的数量
图©中Spanning tree就是生成树,保留了所有的节点(或者说关键帧),但给各个关键帧找了父节点和子节点,每帧只跟各自的父节点和子节点相连,与其他关键帧不连接,此即为spanning tree
图(d)中即是essential graph,是根据spanning tree建立的图模型,它是是简版的covisibility graph。

Covisibility Graph: 具有一定共视点的关键帧的连接
Essential Graph: 是根据spanning tree建立的图模型,它是是简版的covisibility graph,通过GetCovisiblesByWeight构建
Spanning Tree: 共视程度最高的那个关键帧的连接

ORB SLAM2源码解读(五):KeyFrame DataBase类
参考1:ORB-SLAM3知识点(一):词袋模型BoW
参考2:ORB_SLAM2中的回环检测

该类的主要作用就是利用词袋数据,在已有的关键帧中查找和当前帧最接近的帧。
这个功能有两个作用:
一是重定位时候,通过检测当前帧和哪个关键帧最接近,来确定相机当前的位置和姿态,对应的检测函数是DetectRelocalizationCandidates。
二是在闭环检测时,通过检测来确定当前关键帧需要和哪些关键帧建立闭环修正的边,对应的检测函数是DetectLoopCandidates。
二者的区别不大,唯一的区别是闭环检测时不需要遍历和自己在闭环检测之前就已经有共视关系的关键帧。

闭环检测的主要步骤如下:
1)找出与当前帧pKF有公共单词的所有关键帧pKFi,不包括与当前帧相连的关键帧。
2)统计所有闭环候选帧中与pKF具有共同单词最多的单词数,只考虑共有单词数大于0.8*maxCommonWords以及匹配得分大于给定的minScore的关键帧,存入lScoreAndMatch。
3)对于第二步中筛选出来的pKFi,每一个都要抽取出自身的共视(共享地图点最多的前10帧)关键帧分为一组,计算该组整体得分(与pKF比较的),记为bestAccScore。所有组得分大于0.75*bestAccScore的,均当作闭环候选帧。

ORB SLAM2源码解读(六):Map类

Map类比较简单,主要功能就是增删关键帧和地图点,此处直接列出主要函数列表。

ORB SLAM2源码解读(七):Optimizer类

1)当前帧位姿计算:PoseOptimization

每个帧可见多个地图点, 可以建立多个边连接, 构成图进行优化. 只对这一帧的SE3位姿进行优化,不优化地图点坐标。

2)闭环检测时两帧之间相对位姿计算:OptimizeSim3

优化两帧之间的位姿变换, 因为两帧之间可以看到多个相同的地图点, 可以构成一个超定方程组, 可以最小化误差优化。优化帧间变化的SIM3位姿与地图的VertexSBAPointXYZ位姿

3)局部地图调整:LocalBundleAdjustment

在一个CovisbilityMap内进行优化. 在一定范围的keyframe中,可以看到同一块地图, 即是CovisbilityMap. 连接CovisbilityMap内的每一个MapPoint点与可见它的所有keyframe, 放在一起进行优化. 这个优化是双向的, 既优化地图点的VertexSBAPointXYZ位姿, 又优化frame的SE3位姿.

4)全局地图调整(简化版):OptimizeEssentialGraph

加入Loop Closure的考虑, Covisbility图中的keyframe相互连起来, Keyframe之间有前后相连, 于是不同的Covisbility图也可以联系起来. 这是一个大范围的优化, 主要是加入了Loop Closure约束. 优化的是Camera的SIM3位姿.

5)全局地图调整(完整版):GlobalBundleAdjustemnt

最大范围的优化, 优化所有Camera的SE3位姿与地图点的XYZ位姿.

ORB SLAM2源码解读(八):Initializer类

ORBSLAM2之单目初始化(2)
ORBSLAM2之单目初始化(4)

ORB SLAM2源码解读(九):Tracking类

Tracking线程4——Track函数中相机位姿估计

ORB SLAM2源码解读(十):LocalMapping类
ORB SLAM2源码解读(十一):LoopClosing类
ORB SLAM2源码解读(十二):Sim3Solver类

SIM3求解:https://note.youdao.com/ynoteshare/index.html?id=76a1d9452a3b6371464dd9b2745f5a2a&type=note&_time=1653397729283

ORBextractor:
【ORB-SLAM2源码梳理3】构造特征点图像金字塔,构造灰度质心圆
ORB-SLAM2代码笔记(十):ORBextractor
ORB_SLAM2 源码解析 ORB特征提取(二)
ORB特征点提取代码详解 四叉树均匀化

ORBmatcher类: 十一种特征匹配策略

你可能感兴趣的:(slam)