ORB_SLAM 源码解析 1

ORB_SLAM 源码解析

跟踪线程 深度 双目初始化位姿 运动模型 关键帧模式 重定位 局部地图跟踪 关键帧

mpMap就是我们整个位姿与地图(可以想象成ORB-SLAM运行时的那个界面世界),

MapPoint和KeyFrame都被包含在这个mpMap中。

因此创建这三者对象(地图,地图点,关键帧)时,

三者之间的关系在构造函数中不能缺少。

另外,由于一个关键帧提取出的特征点对应一个地图点集,

因此需要记下每个地图点的在该帧中的编号;

同理,一个地图点会被多帧关键帧观测到,

也需要记下每个关键帧在该点中的编号。

地图点,还需要完成两个运算,第一个是在观测到该地图点的多个特征点中(对应多个关键帧),

挑选出区分度最高的描述子,作为这个地图点的描述子;

pNewMP->ComputeDistinctiveDescriptors();

第二个是更新该地图点平均观测方向与观测距离的范围,这些都是为了后面做描述子融合做准备。

pNewMP->UpdateNormalAndDepth();

跟踪

每一帧图像 Frame —> 提取ORB关键点特征 —–> 根据上一帧进行位置估计计算R t (或者通过全局重定位初始化位置)

——> 跟踪局部地图,优化位姿 ——-> 是否加入 关键帧

1. Tracking线程

帧 Frame

1】初始化

​ 单目初始化 MonocularInitialization()

​ 双目初始化 StereoInitialization

2】相机位姿跟踪P

​ 同时跟踪和定位 同时跟踪与定位,不插入关键帧,局部建图 不工作

​ 跟踪和定位分离 mbOnlyTracking(false)

​ 位姿跟踪 TrackWithMotionModel() TrackReferenceKeyFrame() 重定位 Relocalization()

a 运动模型(Tracking with motion model)跟踪

速率较快 假设物体处于匀速运动

​ 用 上一帧的位姿和速度来估计当前帧的位姿使用的函数为TrackWithMotionModel()。

​ 这里匹配是通过投影来与上一帧看到的地图点匹配,使用的是

​ matcher.SearchByProjection(Frame &CurrentFrame, const Frame &LastFrame, …)。

b 关键帧模式 TrackReferenceKeyFrame()

​ 当使用运动模式匹配到的特征点数较少时,就会选用关键帧模式。即尝试和最近一个关键帧去做匹配。

​ 为了快速匹配,本文利用了bag of words(BoW)来加速。

​ 首先,计算当前帧的BoW,并设定初始位姿为上一帧的位姿;

​ 其次,根据位姿和BoW词典来寻找特征匹配,使用函数matcher.SearchByBoW(KeyFrame pKF, Frame &F, …);

​ 匹配到的是参考关键帧中的地图点。

​ 最后,利用匹配的特征优化位姿。

c 通过全局重定位来初始化位姿估计 Relocalization()

​ 假如使用上面的方法,当前帧与最近邻关键帧的匹配也失败了,

​ 那么意味着需要重新定位才能继续跟踪。

​ 重定位的入口如下: bOK = Relocalization();

​ 此时,只有去和所有关键帧匹配,看能否找到合适的位置。

​ 首先,计算当前帧的BOW向量,在关键帧词典数据库中选取若干关键帧作为候选。

​ 使用函数如下:vector vpCandidateKFs = mpKeyFrameDB->DetectRelocalizationCandidates(&mCurrentFrame);

​ 其次,寻找有足够多的特征点匹配的关键帧;最后,利用RANSAC迭代,然后使用PnP算法求解位姿。这一部分也在Tracking::Relocalization() 里

3】局部地图跟踪

​ 更新局部地图 UpdateLocalMap() 更新关键帧和 更新地图点 UpdateLocalKeyFrames() UpdateLocalPoints

​ 搜索地图点 获得局部地图与当前帧的匹配

​ 优化位姿 最小化重投影误差 3D点-2D点对 si pi = K T Pi = K exp(f) Pi

4】是否生成关键帧

​ 加入的条件:

​ 很长时间没有插入关键帧

​ 局部地图空闲

​ 跟踪快要跟丢

​ 跟踪地图 的 MapPoints 地图点 比例比较少

5】生成关键帧

​ KeyFrame(mCurrentFrame, mpMap, mpKeyFrameDB)

​ 对于双目 或 RGBD摄像头构造一些 MapPoints,为MapPoints添加属性

进入LocalMapping线程

设置闭环检测帧 mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame); // ===

给咱来个🍰,啾咪