zoukankan      html  css  js  c++  java
  • ORB-SLAM2初步(源码逻辑分析)

    今天主要是梳理一下ORB-SLAM2源码的逻辑关系,GitHub和泡泡机器人上有很好的注释版本(吴博),大神请(轻)板砖。

    一、文件

    如图所示,Examples里面存放的分别是基于单目、双目、RGBD的实例程序,一般都是基于TUM等数据库,还有一个ROS版本的ORB-SLAM2,以及一个应用与AR的Demo程序;

     include文件夹存放的是头文件,ORB-SLAM2可以被当作一个库来使用,很多函数都可以直接调用;

    src文件夹存放的是和include对应的源文件,包括主要的Tracking、LocalMapping、LoopClosing等的实现过程都在这个文件夹下;

    Thirdparty存放的是用到的第三方库,Vocabulary存放的是回环检测中BoW用到的视觉词典;

    其它的主要是一些编译文件,作者不仅给出了CMakeLists.txt,还给出了build.sh,只要配置好了本地环境,运行一下build.sh就行了。

    二、运行过程

    作者将整个SLAM过程做成一个系统(System),因此只要在主函数中声明一个SLAM System就可以进入跟踪过程了,以mono_tum.cc为例:

    (1)LoadImages(strFile, vstrImageFilenames, vTimestamps);//作者首先从文件中读取了图像名称列表

    (2)ORB_SLAM2::System SLAM(argv[1],argv[2],ORB_SLAM2::System::MONOCULAR,true);//然后声明了一个SLAM系统,并设定是单目MONOCULAR

    (3)for(int ni=0; ni<nImages; ni++)//使用一个for循环依次读取图片并将图片输入到声明的SLAM系统中;

      {  

        im = cv::imread(string(argv[3])+"/"+vstrImageFilenames[ni],CV_LOAD_IMAGE_UNCHANGED);

        SLAM.TrackMonocular(im,tframe);//进入SLAM系统的接口

      }

    (4)SLAM.Shutdown();//图像读取完毕之后关闭SLAM系统;

    //主函数运行结束,后面另有保存轨迹的函数等;

    //从上面过程可以看出,SLAM系统的入口在TrackMonocular这个函数,SLAM的实现在System中;

    //以下过程就在System.cpp文件中

    //在System的构造函数中,作者在声明该SLAM系统时就启用了至少3个线程,分别计算跟踪、局部建图和回环检测,还有一个是可选的交互线程

    mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer,
      mpMap, mpKeyFrameDatabase, strSettingsFile, mSensor);//Tracking线程的初始化;

    mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper);//LocalMapping线程的初始化;

    mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser);//LoopClosing线程的初始化;

    mptViewer = new thread(&Viewer::Run, mpViewer);//Viewer线程的初始化;

    //构造函数中还有读取视觉词典等操作

    (3.1)cv::Mat System::TrackMonocular(const cv::Mat &im, const double &timestamp);//SLAM系统的入口

    (3.2)cv::Mat Tcw = mpTracker->GrabImageMonocular(im,timestamp);//跟踪线程的入口,因为调用该函数的对象为mpTracker;

    //下面就进入了Tracking.cpp文件

      (3.2.1)cv::Mat Tracking::GrabImageMonocular(const cv::Mat &im, const double &timestamp)//首先进入该函数体中,进行灰度图的转换;

      (3.2.3)Track();//然后在灰度图转换的函数体中完成函数的跳转,当前这个函数就是跟踪的主函数体;

        (3.2.3.1)if(mState==NOT_INITIALIZED)  //判断系统是否初始化,没有初始化就跳转到初始化函数,这是单目所独有的过程;

              {

                MonocularInitialization();//初始化的跳转函数,具体的初始化过程在Initializer.cc文件中

              }

        (3.2.3.2)if(mpInitializer->Initialize(mCurrentFrame, mvIniMatches, Rcw, tcw, mvIniP3D, vbTriangulated))//初始化的跳转在这个函数中,因为初始化有一些条件,因此需要做判断

      (3.2.1)return mCurrentFrame.mTcw.clone();//最终在灰度图转换的函数中完成跟踪过程,返回相机位姿矩阵;

     (3.1)return Tcw;//跳转,实现对相机位姿的跟踪

    三、总结

      代码的逻辑比较清晰,而且封闭性比较好,可以稍作修改作为库文件使用。

  • 相关阅读:
    CIA泄露资料分析(黑客工具&技术)—Windows篇
    包学会之浅入浅出Vue.js:结业篇
    包学会之浅入浅出Vue.js:升学篇
    包学会之浅入浅出Vue.js:开学篇
    Manacher算法详解
    CSP-S 2019 游记
    洛谷 P3373 【模板】线段树 2
    AHOI 2009 维护序列
    洛谷 P4017 最大食物链计数
    洛谷 SP14932 LCA
  • 原文地址:https://www.cnblogs.com/mafuqiang/p/6863558.html
Copyright © 2011-2022 走看看