ORB_SLAM2代码阅读(2)——Tracking线程
1. 说明
本文接着上一篇对于ORB-SLAM的系统介绍继续记录ORB-SLAM2的主线程tracking的相关内容。有很多细节部分还没有弄清楚,暂时先将整体思路捋顺。本文的内容最好参照着代码一起阅读,由于篇幅较长,并未在文中插入太多代码。在将整个ORB_SLAM2系统阅读完毕后,我在公开我注释的代码。
2. 简介
2.1 Tracking 流程
ORB-SLAM的tracking线程作为系统的主线程,也是SLAM前端视觉里程计的主要内容,实现的主要内容就是确定每一帧图像的位姿和确定关键帧。
由系统整体框架可知,tracking部分的主要内容有以下几个部分:
在阅读了代码之后,发现将tracking部分的主要内容划分为以下几个模块比较合适:
下文将对各个部分进行详述。
2.2 Tracking 线程的二三四
2.2.1 Tracking 线程的二种模式
Tracking线程由两种模式:1.纯追踪模式 2.同步定位与建图模式(默认模式)
- 纯追踪模式:不插入新的关键帧,不添加新的地图点,局部地图线程不工作,而且回环检测线程也不会工作,只会追踪地图中现有的地图点。
- 同步定位与建图模式:在追踪线程的同时有局部建图和回环检测
2.2.2 Tracking 线程的三种方法
Tracking线程中涉及三种位姿计算方法:运动模型跟踪、参考关键帧跟踪、重定位
- 运动模型跟踪:匹配方式使用上一帧特征点投影到当前帧的方式进行匹配,得到的匹配地图点作为图优化节点,然后根据上一帧的位姿和上一帧位姿的变换速度得到当前帧的初始位姿,用位姿图优化进行位姿优化得到当前帧位姿。
- 参考关键帧跟踪:匹配方式使用关键帧BOW向量与当前帧进行匹配,通过该匹配方式得到地图点得到的地图点作为图优化节点,然后将上一帧的位姿作为初始位姿,用位姿图优化进行位姿优化得到当前帧位姿。
- 重定位:匹配方式是将局部地图点(除去1、2已经匹配过的地图点剩下的局部地图点!!!)投影到到当前帧下进行匹配,得到的匹配地图点作为图优化节点,然后根据上面1、2得到帧位姿作为当前帧的初始位姿,用位姿图优化进行位姿优化得到当前帧位姿。
2.2.3 Tracking 线程的四种状态
Tracking线程有四种状态:1.NO_IMAGES_YET 2.NOT_INITIALIZED 3.OK 4.LOST
- NO_IMAGES_YET:表示当前没有图片。处于NO_IMAGES_YET,当新的一帧来临时,将线程状态改变为NOT_INITIALIZED。
- NOT_INITIALIZED:表示当前没有初始化追踪线程。处于NOT_INITIALIZED,则针对单目相机和双目相机/RGBD相机进行不同的初始化。
- OK:表示当前追踪线程完好。处于OK,经过初始化后追踪线程就转为OK状态,在没有丢帧或者是复位的情况下系统将一直处于OK状态。处于OK状态的系统就可以进行位姿估计,地图点追踪。
- LOST:表示当前追踪线程丢失——注意这里的线程状态都是指当前帧处理之前的状态。处于LOST状态,上一帧追踪失败,当前帧进行重定位。
2.3 Tracking 类的成员变量
Tracking 类中由很多成员变量。直接看代码会很难理解成员变量代表的意义,所以先简单介绍一下成员变量。
其中较为重要的变量有:
变量名 | 变量类型 | 说明 |
---|---|---|
mState | eTrackingState | 跟踪状态标志 |
mbOnlyTracking | bool | 跟踪模式标志 |
mCurrentFrame | Frame | 当前帧 |
mLastFrame | Frame | 上一帧 |
mpReferenceKF | KeyFrame* | 参考关键帧 |
mpLastKeyFrame | KeyFrame* | 上一关键帧 |
mvpLocalKeyFrames | std::vector<KeyFrame*> | 局部地图关键帧 |
mvpLocalMapPoints | std::vector<MapPoint*> | 局部地图的地图点 |
mpMap | Map* | 指代整个地图 |
mlRelativeFramePoses | list < cv::Mat> | 图像帧与其参考关键帧之间的变换关系链表(用于绘制轨迹) |
mlpReferences | list<KeyFrame*> | 每一帧的参考关键帧 (用于绘制轨迹) |
mlFrameTimes | list< double > | 每一帧的时间戳(用于绘制轨迹) |
其它变量在遇到的时候在做说明!
3. Tracking线程的各个功能模块
Tracking线程的入口是TrackStereo(),其中GrabImageStereo()返回位姿。GrabImageStereo()成员函数将输入图像转换为灰度图并构建当前帧,然后调用Track()函数。调用Track()函数表示进入了真正的跟踪流程。
进入跟踪流程后,下面开始介绍其中的各个功能模块。
3.1 初始化
这里的初始化指的是追踪过程的初始化环节,而不是Tracking类构造函数中的初始化内容。顺便说一下,构造函数中根据配置文件设置了相应的参数并声明了ORB特征点提取器。ORB特征提取的过程在构造当前帧的时候进行。
图像传输正常的情况下,追踪过程的第一步就是判断是否已经初始化。
判断部分相应代码为:
if