ORB-SLAM2 代码(+理论)解析(一):进入mono_euroc 主函数

 目录

一、ORB-SLAM2 程序运行步骤

二、ORB-SLAM2 系统框架

三、开始代码

学习程序1:    void LoadImages( )

学习程序2:    ORB_SLAM2::System SLAM( )



 

一、ORB-SLAM2 程序运行步骤

https://blog.csdn.net/hltt3838/article/details/113962104

 

二、ORB-SLAM2 系统框架

要了解一个系统的代码实现,总是要先从熟悉系统的框架开始,ORB-SLAM2的系统框架如下图所示:

 我们可以看到 TRACKING线程 中做了提取ORB特征、初始位姿估计等操作,那么这个线程应该属于SLAM中的“前端VO”;LOCAL MAPPING线程 里有Local BA,我们可以知道这个线程属于后端,主要做后端优化和建图工作;LOOP CLOSING线程从字面意思就能判断出是做回环检测的,分为回环检测和回环矫正。再需要知道的就是TRACKING线程接收了一帧一帧的图片后开始工作的,而LOCAL MAPPING线程接收的KeyFrame来自TRACKING线程“加工提炼”之后,LOOP CLOSING线程也是接收LOCAL MAPPING线程“进一步加工提炼”后的 KeyFrame 来进行工作。

注意:LOCAL MAPPING线程  开始就是对 关键帧 进行操作了 !

遗留问题: PLACE RECOGNITION和MAP 是什么? 后面进行解读
 

 

三、开始代码

mono_euroc.cc文件主要的函数如下

cd orb_slam/src/ORB_SLAM2     // 我的程序放在orb_slam/src/ORB_SLAM2里面

运行程序输入:

./Examples/Monocular/mono_euroc  Vocabulary/ORBvoc.txt  Examples/Monocular/EuRoC.yaml  /home/hltt3838/EuRoC_data/MH_01_easy/mav0/cam0/data  Examples/Monocular/EuRoC_TimeStamps/MH01.txt 

int main(int argc, char **argv)
{
    // step 0 检查输入参数个数是否足够
    if(argc != 5)
    {
        cerr << endl << "Usage: ./mono_tum path_to_vocabulary path_to_settings path_to_image_folder path_to_times_file" << endl;
        return 1;
    }

    // step 1 加载图像
    vector<string> vstrImageFilenames;      // 图像序列的文件名字符串序列
    vector<double> vTimestamps;             // 时间戳
    
    LoadImages(string(argv[3]),             // 3-保存图像的路径
               string(argv[4]),             // 4-保存图像时间的路径
               vstrImageFilenames,          // 读取到的图像名称数组
               vTimestamps);                // 时间戳数组
    
    
    // 当前图像序列中的图像数目
    int nImages = vstrImageFilenames.size();

    if(nImages<=0)
    {
        cerr << "ERROR: Failed to load images" << endl;
        return 1;
    }

    
    // step 2 加载SLAM系统
    ORB_SLAM2::System SLAM(
        argv[1],                            // 1-词典文件路径
        argv[2],                            // 2-相机参数文件路径
        ORB_SLAM2::System::MONOCULAR,       // 单目模式
        true);                              // 启用可视化查看器

    
    // step 3 运行前准备,Vector for tracking time statistics
    vector<float> vTimesTrack;  // 统计追踪一帧耗时 (仅Tracker线程)
    vTimesTrack.resize(nImages);

    cout << endl << "-------" << endl;
    cout << "Start processing sequence ..." << endl;
    cout << "Images in the sequence: " << nImages << endl << endl;

    
    // step 4 ,主循环,依次追踪序列中的每一张图像
    cv::Mat im;
    for(int ni=0; ni<nImages; ni++)
    {
        // step 4.1 读根据前面获得的图像文件名读取图像,读取过程中不改变图像的格式 
        im = cv::imread(vstrImageFilenames[ni],CV_LOAD_IMAGE_UNCHANGED);
        double tframe = vTimestamps[ni];

        // step 4.2 图像的合法性检查
        if(im.empty())
        {
            cerr << endl << "Failed to load image at: "
                 <<  vstrImageFilenames[ni] << endl;
            return 1;
        }

        // step 4.3 开始计时
#ifdef COMPILEDWITHC11
        std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
#else
        std::chrono::monotonic_clock::time_point t1 = std::chrono::monotonic_clock::now();
#endif

        // step 4.4 追踪当前图像;输入:图像+时间
        SLAM.TrackMonocular(im,tframe);

        // step 4.5 追踪完成,停止当前帧的图像计时, 并计算追踪耗时

#ifdef COMPILEDWITHC11
        std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
#else
        std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
#endif

        double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();

        vTimesTrack[ni]=ttrack;  
        

        // step 4.6 根据图像时间戳中记录的两张图像之间的时间和现在追踪当前图像所耗费的时间,继续等待指定的时间以使得下一张图像能够 按照时间戳被送入到SLAM系统中进行跟踪
        
        double T=0;//两张图像的时间间隔,注意转换一下单位
        if(ni<nImages-1)
            T = vTimestamps[ni+1]-tframe;
        else if(ni>0)
            T = tframe-vTimestamps[ni-1];

        if(ttrack<T)
            usleep((T-ttrack)*1e6);
    }

    // step 5 如果所有的图像都预测完了,那么终止当前的SLAM系统
    SLAM.Shutdown();


    // step 6 计算平均耗时
    sort(vTimesTrack.begin(),vTimesTrack.end()); // 排序,从小到大
    float totaltime = 0;
    for(int ni=0; ni<nImages; ni++)
    {
        totaltime+=vTimesTrack[ni];
    }
    cout << "-------" << endl << endl;
    cout << "median tracking time: " << vTimesTrack[nImages/2] << endl;
    cout << "mean tracking time: " << totaltime/nImages << endl;

 
    // step 7 保存TUM格式的相机轨迹
    // 估计是单目时有尺度漂移, 而LGA GBA都只能优化关键帧使尺度漂移最小, 普通帧所产生的轨迹漂移这里无能为力, 我猜作者这样就只保存了关键帧的位姿,从而避免普通帧带有尺度漂移的位姿对最终误差计算的影响
    SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");

    return 0;
}

 

分析:程序很容易看懂,主要是 读取图像信息,初始化系统,追踪图像等,其程序的思维导图如下图所示:

 

学习程序1:    void LoadImages( )

/**
 * @brief 获取图像文件的信息
 * @param[in]  strImagePath     图像文件存放路径
 * @param[in]  strPathTimes     时间戳文件的存放路径
 * @param[out] vstrImages       图像文件名数组
 * @param[out] vTimeStamps      时间戳数组
 */

// 从文件中加载图像序列中每一张图像的文件路径和时间戳
void LoadImages(const string &strImagePath, const string &strPathTimes,
                vector<string> &vstrImages, vector<double> &vTimeStamps)
{
    // 打开文件
    ifstream fTimes;
    fTimes.open(strPathTimes.c_str());
    vTimeStamps.reserve(5000);
    vstrImages.reserve(5000);
    
    // 遍历文件
    while(!fTimes.eof())
    {
        string s;
        getline(fTimes,s);
        
        // 只有在当前行不为空的时候执行
        if(!s.empty())
        {
            stringstream ss;
            ss << s;
            // 生成当前行所指出的RGB图像的文件名称
            vstrImages.push_back(strImagePath + "/" + ss.str() + ".png");
            double t;
            ss >> t;
            
            // 记录该图像的时间戳
            vTimeStamps.push_back(t/1e9);//转换单位:秒, 具体看 MH01.txt

        }
    }
}

理解:

程序写的很好,有很大的借鉴意义,但要注意自己采集数据的时候怎么根据自己的图像数据去读取图像的名称和对应的时间序列,上面的程序对应的图片名字如下,好好体会:

下面的程序是把 时间转换成单位:秒

 vTimeStamps.push_back(t/1e9);   //转换单位:秒, 具体看 MH01.txt

 

学习程序2:    ORB_SLAM2::System SLAM( )

 这个程序在  System.cc  程序里面, 具体的分析看连接:https://mp.csdn.net/editor/html/115089937

 

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
ORB-SLAM2是一种基于视觉的单目、双目和RGB-D SLAM系统,可以用于实现实时定位和地图构建。EuRoC数据集是一个常用的SLAM数据集,包含了基于激光雷达和相机的传感器采集的图像序列和位姿数据。在这里,我们将介绍如何使用ORB-SLAM2跑通EuRoC数据集,并对其结果进行结论分析。 具体步骤如下: 1. 下载EuRoC数据集,并解压缩到本地计算机中。 2. 下载ORB-SLAM2的代码,并按照说明进行编译和安装。 3. 修改ORB-SLAM2的参数配置文件,以便正确读取EuRoC数据集。配置文件位于Examples/Monocular目录下,其中有一个名为EuRoC.yaml的文件。主要修改以下参数: - Vocabulary文件路径:修改为ORB-SLAM2的词袋文件路径。 - Camera calibration文件路径:修改为EuRoC数据集中的相机标定文件路径。 - 数据集文件路径:修改为EuRoC数据集的文件路径。 4. 运行ORB-SLAM2,对数据集进行处理。运行以下命令: ``` cd Examples/Monocular ./mono_euroc PATH_TO_VOCABULARY PATH_TO_SETTINGS.yaml PATH_TO_SEQUENCE_FOLDER ``` 其中,PATH_TO_VOCABULARY是ORB-SLAM2的词袋文件路径,PATH_TO_SETTINGS.yaml是ORB-SLAM2的配置文件路径,PATH_TO_SEQUENCE_FOLDER是EuRoC数据集的文件夹路径。 5. 等待ORB-SLAM2完成数据集处理。处理完成后,ORB-SLAM2会输出定位结果、重建的3D地图等信息。我们可以对这些结果进行分析和评估。 结论分析: 在运行ORB-SLAM2的过程中,我们可以得到一些性能评估指标,例如定位精度、重建的地图质量等。通过这些指标,我们可以对ORB-SLAM2在EuRoC数据集上的表现进行评价和分析。 此外,我们还可以使用其他数据集来对ORB-SLAM2进行测试和评估,以验证其鲁棒性和泛化能力。同时,我们还可以对ORB-SLAM2的参数进行调整,以优化其性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

他人是一面镜子,保持谦虚的态度

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值