首页 > 代码库 > ORB-SLAM2学习5 Tracking.h

ORB-SLAM2学习5 Tracking.h

一、直接上图,清楚明了。(来自论文)

技术分享

  我们注意到TRACKING线程,很清楚明白的告诉了我们是如何跟踪的,第一,提取ORB特征;第二,进行地图初始化(如果没初始化的话)。第三,初始位置估计(这里用3种模型代码在这里经过了很多判断来选择这三种模型的其中一种)得到是一个很粗略的初始位姿;第四,跟踪局部地图:为了优化上一步得到的初始位姿态。第五,决定是不是插入关键帧。

 

解释跟踪里面使用的三种模型,这三种模型都是用来得到当前帧的位姿T的,我们根据需要选择一种。

1.TrackWithMotionModel()

  这个就是论文里面提到的恒速运动模型(const velocity motion),意识相当于是:我们根据上一帧的跟踪结果得到一个运动的速度,我们能够像我们知道的恒速运动那样用类似”速度乘以时间“这一公式来估算当前帧的位姿。

2.TrackReferenceKeyFrame()

  这个很好理解,就是根据两帧之间的约束关系来求解位估算位姿。

3. Relocalization()

  当我们跟丢了的时候(我用RGBD相机测试代码的时候只要稍微运动快一点就会跟丢.....),我们用所谓的“重定位”来找回当前帧的位姿,重定位其实跟找闭环相似,都是在database里面找到与当前帧最相似的那一帧。

三种模型的函数如下:

bool Tracking::TrackWithMotionModel()

三种跟踪模型的一种:就是根据估计的速度来“预测当前帧的位姿”。

    bool TrackReferenceKeyFrame();

三个跟踪模型中的一种。会改变当前帧的位姿。

bool Tracking::Relocalization()

  三 个跟踪模型的一种。用于跟丢的时候,我们重新定位。知道当前帧的位姿。具体步骤:第一在关键帧的database里面寻找候选的关键帧们。第二:将第一步 得到的候选关键帧们一个个的与当前帧进行BoW匹配,如果匹配的关键点数很少我们就抛弃这个候选的关键帧,否则我们就可以构造这个关键帧的pno求解器 了。第三步:使用pnp算法算出候选的关键帧们与当前帧的位姿。然后进行优化,如果优化的结果不够好,我们就继续找,直到找到合适的关键帧为止 (nGood>50)。

三、mbOnlyTracking 的解释  

  做SLAM我们知道,我们要优化我们估计的位姿,和空间三维点的位置。ORB使用并行线程的策略,在跟踪的时候也有在建图。我们可以想象我们要优化的地图点的时候,地图点会不断地收敛到一个范围,这时候我们就可以认为地图点稳定了,没有必要继续优化了,我们只需要估计优化位姿,这就是mbOnlyTracking。当然反之就是既要建图又要估计位姿的情况。

四、其他各个函数学习。

 Tracking(System* pSys, ORBVocabulary* pVoc, FrameDrawer* pFrameDrawer, MapDrawer* pMapDrawer, Map* pMap,
             KeyFrameDatabase* pKFDB, const string &strSettingPath, const int sensor);

 

构造函数,传入各种参数,比如相机内参,畸变系数,金字塔层树,特征点个数......

 

// Preprocess the input and call Track(). Extract features and performs stereo matching.
    cv::Mat GrabImageStereo(const cv::Mat &imRectLeft,const cv::Mat &imRectRight, const double &timestamp);
    cv::Mat GrabImageRGBD(const cv::Mat &imRGB,const cv::Mat &imD, const double &timestamp);
    cv::Mat GrabImageMonocular(const cv::Mat &im, const double &timestamp);

 

这几个函数功能一样,用于不同的传感器。这个函数才是真正的跟踪函数。需要注意的是,当前帧在构造的时候,其所有的特征点、描述子都已经被计算出来了。跟踪完了的结果就是返回估计的当前帧位姿

 

   void Track();

这个函数是,我们用于跟踪的最主要的函数,其具体解释看上面的第一部分。

    // Map initialization for stereo and RGB-D
    void StereoInitialization();

双目的初始化。当前帧变成关键帧放到地图里面,得到关键点的3D坐标,并且将当前帧的关键点全部变成了地图点。

   // Map initialization for monocular
    void MonocularInitialization();

这里首先设置参考帧,new Initializer(mCurrentFrame,1.0,200); 之后还有苛刻的要求来决定是不是要初始化。然后才使用函数Initialize(mCurrentFrame, mvIniMatches, Rcw, tcw, mvIniP3D, vbTriangulated)真正的初始化。但这个函数的得到只是Rcw, tcw, mvIniP3D, vbTriangulated 后面两个是3D点坐标,和关键点是不是三角化了。  最后调用的函数CreateInitialMapMonocular();创建初始化的地图的。

void Tracking::CreateInitialMapMonocular()

  这个函数创建了初始化的单目地图,主要是就是创建了两个关键帧,并将这个两个关键帧匹配好的点作为地图点。然后进行一次全局的BA优化下。

 bool NeedNewKeyFrame();
  void CreateNewKeyFrame();
//将地图点的点投影到当前帧进行更多的匹配。 void Tracking::SearchLocalPoints()

  这里代码参考论文,论文提到关键帧在这里可以尽快的插入,因为在局部建图会去除多余的关键帧。尽快插入关键帧的好处就是增加鲁棒性,特别是在相机旋转的时候。

创建新的关键帧,就是把当前帧当做关帧,创造地图点,其他受牵连变量改变下就行了。

//就是将局部关键帧们里面的合适的局部关键点放到mvpLocalMapPoints容器里面,做为局部地图点
void
Tracking::UpdateLocalPoints()
void Tracking::UpdateLocalKeyFrames()

跟新局部关键帧,改变的是mvpLocalKeyFrames.将4中类型的关键帧放到mvpLocalKeyFrames里面,第一种:与当前帧有共视点的关键帧们kf1;第二种:与mvpLocalKeyFrames里面的关键帧有很多公视关系的关键帧们;第三种:mvpLocalKeyFrames里面每个关键帧的孩子们(最小生成树);第四种:mvpLocalKeyFrames里面每个关键帧的父亲(最小生成树)。

 

ORB-SLAM2学习5 Tracking.h