zoukankan      html  css  js  c++  java
  • 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匹配,如果匹配的关键点数很少我们就抛弃这个候选的关键帧,否则我们就可以构造这个关键帧的pnp求解器 了。第三步:使用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里面每个关键帧的父亲(最小生成树)。

  • 相关阅读:
    Android自定义控件之仿美团下拉刷新
    Android性能优化之Bitmap的内存优化
    基于openfire+smack即时通讯instant message开发
    Android各组件/控件间通信利器之EventBus
    android的task任务栈
    Activity的启动模式
    Android 自定义View (一)
    Android之Handler用法总结
    Android中轻松使用线程
    Android 中Activity,Window和View之间的关系
  • 原文地址:https://www.cnblogs.com/panda1/p/7001118.html
Copyright © 2011-2022 走看看