ORBSLAM3 运行流程 以rgbd_tum.cc函数为例进行分析

一、运行

使用的是D435i相机自己录制的数据。

运行命令:

./Examples/RGB-D/rgbd_tum  '/opt/vslam/ORB_SLAM3_detailed_comments-dense_map_new/Vocabulary/ORBvoc.txt' '/opt/vslam/ORB_SLAM3_detailed_comments-dense_map_new/Examples/RGB-D/TUM1.yaml'   /opt/vslam/data/115/bag_tum '/opt/vslam/data/115/ass.txt' 

 简单解释一下,第一部分是可执行文件,第二部分是ORB词袋,第三部分是配置文件(在这里更改自己相机的参数),第四部分是数据文件存放所在的文件夹,第五部分是RGB和深度图像的时间戳文件。

二、rgbd_tum.cc文件

首先查看可执行文件链接位置

可以看到是位置是在 /Examples/RGB-D/rgbd_tum.cc,查看rgbd_tum.cc文件。

1、主函数初始化部分

int main(int argc, char **argv)
{
    //检查是否输入是5部分
    if(argc != 5)
    {
        cerr << endl << "Usage: ./rgbd_tum path_to_vocabulary path_to_settings path_to_sequence path_to_association" << endl;
        return 1;
    }
    
    // Retrieve paths to images
    vector<string> vstrImageFilenamesRGB;
    vector<string> vstrImageFilenamesD;
    vector<double> vTimestamps;
    //加载图像文件名和时间戳的关联文件
    string strAssociationFilename = string(argv[4]);
    LoadImages(strAssociationFilename, vstrImageFilenamesRGB, vstrImageFilenamesD, vTimestamps);

    //...
    return 0;
}

开始检查输入是否是5个参数,然后初始化几个容器和变量。

// Retrieve paths to images
vector<string> vstrImageFilenamesRGB;
vector<string> vstrImageFilenamesD;
vector<double> vTimestamps;
//加载图像文件名和时间戳的关联文件
string strAssociationFilename = string(argv[4]);

我们看一下这个我输入第五个参数ass.txt的具体内容

时间戳  文件夹名/图像命名    时间戳  文件夹名/图像命名

文件结构如下

然后进入LoadImages()函数。

2、LoadImages()函数

void LoadImages(const string &strAssociationFilename, vector<string> &vstrImageFilenamesRGB,
                vector<string> &vstrImageFilenamesD, vector<double> &vTimestamps)
{
    ifstream fAssociation;
    fAssociation.open(strAssociationFilename.c_str());
    while(!fAssociation.eof())
    {
        string s;
        getline(fAssociation,s);
        if(!s.empty())
        {
            stringstream ss;
            ss << s;
            double t;
            string sRGB, sD;
            ss >> t;
            vTimestamps.push_back(t);
            ss >> sRGB;
            vstrImageFilenamesRGB.push_back(sRGB);
            ss >> t;
            ss >> sD;
            vstrImageFilenamesD.push_back(sD);

        }
    }
}

LoadImages 函数接受四个参数: 

  1. strAssociationFilename: 一个字符串,表示包含图像文件名和时间戳的关联文件的路径。
  2. vstrImageFilenamesRGB: 一个字符串向量的引用,用于存储RGB图像的文件名。
  3. vstrImageFilenamesD: 一个字符串向量的引用,用于存储深度图像或其他类型图像的文件名。
  4. vTimestamps: 一个双精度浮点数向量的引用,用于存储图像对应的时间戳。

函数逻辑 

  1. 打开文件: 使用ifstream打开提供的关联文件strAssociationFilename

  2. 读取文件直到结束:

    • 通过while(!fAssociation.eof())循环,函数会一直读取文件直到到达文件末尾。
  3. 处理每一行:

    • 在循环内部,使用getline(fAssociation,s)读取文件的每一行到字符串s中。
    • 检查字符串s是否为空。如果不为空,则处理该行。
  4. 解析行:

    • 使用stringstream从字符串s中解析数据。
    • 首先读取一个时间戳t,并将其添加到vTimestamps向量中。
    • 然后读取一个字符串sRGB,表示RGB图像的文件名,并将其添加到vstrImageFilenamesRGB向量中。
    • 再次读取一个时间戳t,但是没有赋值操作,属于应付数据格式的无效操作
    • 最后,读取另一个字符串sD,表示深度图像或其他类型图像的文件名,并将其添加到vstrImageFilenamesD向量中。

 然后简单看一下主函数中后续的处理,nImages是彩色图像数量。

如果每加载到彩色图像或者彩色图像和深度图像数量不一致,直接报错,返回

int nImages = vstrImageFilenamesRGB.size();
    if(vstrImageFilenamesRGB.empty())
    {
        cerr << endl << "No images found in provided path." << endl;
        return 1;
    }
    else if(vstrImageFilenamesD.size()!=vstrImageFilenamesRGB.size())
    {
        cerr << endl << "Different number of images for rgb and depth." << endl;
        return 1;
    }

    

 3、主函数线程开启部分

ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::RGBD,true);
float imageScale = SLAM.GetImageScale();

//初始化追踪所用时间存储容器
// Vector for tracking time statistics
    vector<float> vTimesTrack;
    vTimesTrack.resize(nImages);
//输出一些显示,这里能看到一共读了多少图片
cout << endl << "-------" << endl;
cout << "Start processing sequence ..." << endl;
cout << "Images in the sequence: " << nImages << endl << endl;

新建System类 SLAM,各个线程的初始化,一切的开始 ,这个太多了,下一篇开肝。

链接:

ORBSLAM3 运行流程 ORB_SLAM3::System SLAM()函数-CSDN博客文章浏览阅读164次,点赞5次,收藏4次。【代码】ORBSLAM3 运行流程 ORB_SLAM3::System SLAM()函数。https://blog.csdn.net/weixin_44760904/article/details/135852602?spm=1001.2014.3001.5502文章浏览阅读164次,点赞5次,收藏4次。【代码】ORBSLAM3 运行流程 ORB_SLAM3::System SLAM()函数。https://blog.csdn.net/weixin_44760904/article/details/135852602?spm=1001.2014.3001.5502文章浏览阅读164次,点赞5次,收藏4次。【代码】ORBSLAM3 运行流程 ORB_SLAM3::System SLAM()函数。https://blog.csdn.net/weixin_44760904/article/details/135852602?spm=1001.2014.3001.5502文章浏览阅读164次,点赞5次,收藏4次。【代码】ORBSLAM3 运行流程 ORB_SLAM3::System SLAM()函数。https://blog.csdn.net/weixin_44760904/article/details/135852602?spm=1001.2014.3001.5502

imageScale是管理图像缩放的一个函数,经过几次跳转,源代码里是1.0

 System类成员函数:GetImageScale()

float System::GetImageScale()
{
    return mpTracker->GetImageScale();
}

Tracking类的成员函数GetImageScale()

float Tracking::GetImageScale()
{
    return mImageScale;
}

 在Tracking.cc里不同函数mImageScale的几次赋值都是1.0f,为了设置的处理大分辨率图像时使用。

4、主要循环

// Main loop
    cv::Mat imRGB, imD;
    for(int ni=0; ni<nImages; ni++)
    {
        // Read image and depthmap from file
        imRGB = cv::imread(string(argv[3])+"/"+vstrImageFilenamesRGB[ni],cv::IMREAD_UNCHANGED); //,cv::IMREAD_UNCHANGED);
        imD = cv::imread(string(argv[3])+"/"+vstrImageFilenamesD[ni],cv::IMREAD_UNCHANGED); //,cv::IMREAD_UNCHANGED);
        double tframe = vTimestamps[ni];

        if(imRGB.empty())
        {
            cerr << endl << "Failed to load image at: "
                 << string(argv[3]) << "/" << vstrImageFilenamesRGB[ni] << endl;
            return 1;
        }

        if(imageScale != 1.f)
        {
            int width = imRGB.cols * imageScale;
            int height = imRGB.rows * imageScale;
            cv::resize(imRGB, imRGB, cv::Size(width, height));
            cv::resize(imD, imD, cv::Size(width, height));
        }

#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

        // Pass the image to the SLAM system
        SLAM.TrackRGBD(imRGB,imD,tframe);
#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;

        // Wait to load the next frame
        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);

这里就看到我输入的第四个参数是/opt/vslam/data/115/bag_tum,他在后面加上/和之前ass.txt文档的命名进行图片读取,如果imageScale != 1.f,则对图片进行缩放,然后进入TrackRGBD(imRGB,imD,tframe)函数,后续写,再下面是模仿现实时间方面的操作。

链接:

ORBSLAM3 运行流程 TrackRGBD()函数-CSDN博客文章浏览阅读14次。这个函数也是在rgbd_tum.cc里被调用的。这里起到主要作用的是调用。https://blog.csdn.net/weixin_44760904/article/details/135873957?spm=1001.2014.3001.5502文章浏览阅读14次。这个函数也是在rgbd_tum.cc里被调用的。这里起到主要作用的是调用。https://blog.csdn.net/weixin_44760904/article/details/135873957?spm=1001.2014.3001.5502文章浏览阅读14次。这个函数也是在rgbd_tum.cc里被调用的。这里起到主要作用的是调用。https://blog.csdn.net/weixin_44760904/article/details/135873957?spm=1001.2014.3001.5502文章浏览阅读14次。这个函数也是在rgbd_tum.cc里被调用的。这里起到主要作用的是调用。https://blog.csdn.net/weixin_44760904/article/details/135873957?spm=1001.2014.3001.5502

1、计算并记录处理一个图像帧所需的时间ttrack,这个时间被存储在 vTimesTrack容器中,对应于当前处理的图像帧的索引ni

2、计算下一帧与当前帧之间应有的时间间隔。vTimestamps 是一个包含每帧的时间戳的数组。如果不是最后一帧(ni < nImages - 1),它计算下一帧和当前帧的时间差;如果是最后一帧,它计算当前帧和前一帧的时间差。

3、如果处理时间ttrack小于应有的时间间隔T,代码将使程序休眠差额的时间,以保持时间同步。usleep 函数接受微秒作为参数,因此将时间差(秒)乘以 1e6 来转换

5、 系统终止

// Stop all threads
    SLAM.Shutdown();

    // Tracking time statistics
    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;

    // Save camera trajectory
    SLAM.SaveTrajectoryTUM("CameraTrajectory.txt");
    SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");   

    return 0;
  1. 停止所有线程SLAM.Shutdown();这行代码负责安全地停止SLAM系统中所有的运行线程。

  2. 追踪时间统计:这部分代码首先对存储每一帧追踪时间的向量vTimesTrack进行排序,然后计算总追踪时间,并输出中位数和平均追踪时间。

    • 排序:sort(vTimesTrack.begin(),vTimesTrack.end());将追踪时间从最短到最长排序。
    • 总时间计算:通过遍历vTimesTrack向量,累加每个元素(每帧的追踪时间),计算出总时间。
    • 中位数和平均时间输出:输出中位数追踪时间(vTimesTrack[nImages/2])和平均追踪时间(totaltime/nImages)。
  3. 保存相机轨迹:SLAM系统保存了两种轨迹文件。SaveTrajectoryTUM方法保存的是相机的整体轨迹,而SaveKeyFrameTrajectoryTUM方法保存的是关键帧轨迹。这些文件通常用于后续分析、调试或可视化。

    • SLAM.SaveTrajectoryTUM("CameraTrajectory.txt");保存相机的整体轨迹。
    • SLAM.SaveKeyFrameTrajectoryTUM("KeyFrameTrajectory.txt");保存关键帧的轨迹。
  4. 程序结束:最后,程序返回0,表示正常结束。

 我的电脑是处理器是11th Gen Intel® Core™ i7-11800H @ 2.30GHz × 16  显卡rtx3080,最后结束时的输出,可以看到跟踪基本0.015s每帧,极限能达到每秒60帧,加入yolo后平均每帧5-10ms处理时间算,再加上通讯时间,实时30帧基本没问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/357609.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

医美诊疗前后要注意的八大诀窍

【记者许家源/综合报导】 随着年龄的增长&#xff0c;许多人都想保持年轻美丽&#xff0c;因此寻求医美诊疗的帮助。然而&#xff0c;进入医美诊所后&#xff0c;你可能会发现&#xff0c;想要打肉毒、除毛等&#xff0c;实际花费和广告中的金额相差甚远。为了避免上当受骗&am…

C# 使用WMI监听进程的启动和关闭

写在前面 Windows Management Instrumentation&#xff08;WMI&#xff09;是用于管理基于 Windows 操作系统的数据和操作的基础结构。具体的API可以查看 WMI编程手册。 WMIC 是WMI的命令行管理工具&#xff0c;使用 WMIC&#xff0c;不但可以管理本地计算机&#xff0c;还可…

Layui + Echarts 5.0

Layui 怎么整合最新版本的 Echarts 5.0&#xff0c;Echarts 4 升级到 5后&#xff0c;有了很大改变&#xff0c;新的配置项4是无法兼容的&#xff0c;所以想要使用新的功能&#xff0c;都需要升级&#xff01; 新建一个echarts.js文件 layui.define(function (exports) {// 这…

【教程】iOS如何抓取HTTP和HTTPS数据包经验分享

&#x1f4f1; 在日常的App开发和研发调研中&#xff0c;对各类App进行深入的研究分析时&#xff0c;我们需要借助专业的抓包应用来协助工作。本文将介绍如何使用iOS手机抓包工具来获取HTTP和HTTPS数据包&#xff0c;并推荐一款实用的抓包应用——克魔助手&#xff0c;希望能够…

Spring: 实体类转换工具总结

文章目录 一、MapStruct1、介绍2、原理3、使用4、问题处理&#xff08;1&#xff09;IDEA编译报错&#xff1a;NullPointerException 一、MapStruct 1、介绍 MapStruct是一个实体类属性映射工具&#xff0c;通过注解的方式实现将一个实体类的属性值映射到另外一个实体类中。在…

前缀和入门(c++语言)

在讲算法之前&#xff0c;我们先来思考一个问题&#xff1a;小明有n个编号为1~n的篮子&#xff0c;每个篮子里装有ai个苹果&#xff0c;求从 x至y 的篮子里的苹果数量之和。 如果没学过前缀和的同学&#xff0c;可能会打出这样的代码&#xff1a; 这种算法要得出一个区间之和&…

隐马尔可夫模型系列——(六)总结与展望

一、总结&#xff1a; 隐马尔可夫模型&#xff08;Hidden Markov Model&#xff0c;HMM&#xff09;是一种用于建模序列数据的统计模型&#xff0c;在语音识别、自然语言处理、金融领域等多个领域都有广泛的应用。其优势包括可以处理动态序列数据、具有一定的鲁棒性、可以灵活…

阿里云服务器2024年最新优惠价格表,轻量应用服务器61元起,云服务器99元起

阿里云服务器2024年最新优惠价格是多少&#xff1f;不同时期阿里云服务器的租用价格不同&#xff0c;进入2024年&#xff0c;阿里云服务器的优惠价格也有所变动&#xff0c;共享型云服务器2核2G最低还是只要99元1年&#xff0c;独享型云服务器2核4G只要199元1年&#xff0c;而轻…

复杂SQL治理实践 | 京东物流技术团队

一、前言 软件在持续的开发和维护过程中&#xff0c;会不断添加新功能和修复旧的缺陷&#xff0c;这往往伴随着代码的快速增长和复杂性的提升。若代码库没有得到良好的管理和重构&#xff0c;就可能积累大量的技术债务&#xff0c;包括不一致的设计、冗余代码、过时的库和框架…

探讨UI自动化测试几步骤

随着软件开发的不断发展&#xff0c;UI自动化测试变得越来越重要&#xff0c;它能够提高测试效率、降低人为错误&#xff0c;并确保软件交付的质量。本文将介绍UI自动化测试的一般步骤和一些最佳实践&#xff0c;以帮助开发团队更好地实施自动化测试。 需求分析和选择测试工具&…

RabbitMQ基本使用,docker安装RabbitMQ,SpringBoot整合RabbitMQ

1.拉取镜像 docker pull rabbitmq:3.9.15-management2.运行容器 docker run -d --hostname rabbit1 --name myrabbit1 -p 15672:15672 -p 5672:5672 -e RABBITMQ_ERLANG_COOKIErabbitcookie rabbitmq:3.9.15-management3.访问地址 安装ip加端口号 http://192.168.123.3:156…

通过Opencv进行角点检测

目录 引入 介绍 ①使用的主要函数介绍 ②实际例子解释 ③自相似性是什么? 引入 我们想要获取图片上的角点,就要用到我们的harris角点检测 介绍 ①使用的主要函数介绍 cv2.cornerHarris() img&#xff1a; 数据类型为 float32 的入图像 不是float32的数据要使用&#xff0…

扩展学习|一文明晰推荐系统应用开发核心技术发展

文献来源&#xff1a;Lu J, Wu D, Mao M, et al. Recommender system application developments: a survey[J]. Decision support systems, 2015, 74: 12-32. 主题&#xff1a;关于推荐系统应用开发的调查研究 关键词:推荐系统、电子服务个性化、电子商务、电子学习、电子政务 …

FastBee开源物联网平台2.0开源版发布啦!!!

一、项目介绍 物美智能(wumei-smart)更名为蜂信物联(FastBee)。 FastBee开源物联网平台&#xff0c;简单易用&#xff0c;更适合中小企业和个人学习使用。适用于智能家居、智慧办公、智慧社区、农业监测、水利监测、工业控制等。 系统后端采用Spring boot&#xff1b;前端采用…

手机壳也能散热了?

作为一个玩了6年的王者荣耀玩家&#xff0c;手机发热真的很影响游戏体验&#xff01;&#xff01;游戏掉帧&#xff0c;性能下降很恼人&#xff0c;试过好几个散热工具&#xff0c;实际效果都不太好&#xff5e; 自从入了Mate 60之后&#xff0c;看着这款微泵液冷壳毫无犹豫第…

【解决】Unity 工程无法正常打开而崩溃问题

开发平台&#xff1a;Unity 2022.3.17f1c1 一、问题描述 访问 Unity 工程等待 Open Projet&#xff08;busy for 时间&#xff09;&#xff0c;出现崩溃、闪退等情况&#xff0c;导致无法正常进入Unity编辑页面。 二、问题分析 笔者在 URP 渲染管线下处理 Obi Fluid 流体插件 D…

动手学深度学习(一)深度学习介绍1

目录 一、引言 1.日常生活中的机器学习&#xff1a; 2.机器学习中的关键组件&#xff1a; 2.1 数据&#xff1a; 2.2 模型&#xff1a; 2.3 目标函数&#xff1a; 2.4 优化算法&#xff1a; 3. 各种机器学习问题&#xff1a; 3.1 监督学习&#xff1a; 3.1.1 回归&…

Databend 开源周报第 130 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 支持 CREATE OR…

推荐一款Linux、数据库、Redis、MongoDB统一管理平台!

官方演示 状态查看 ssh 终端 文件操作 数据库操作 sql 编辑器 在线增删改查数据 Redis 操作 Mongo 操作 系统管理 账号管理 角色管理 资源管理 一.安装 1.下载安装包 cd /opt wget https://gitee.com/dromara/mayfly-go/releases/download/v1.7.1/mayfly-go-linux-amd64.zi…

Hana SQL+正则表达式

目录 一、Pre 前言 二、知识点拆解 1&#xff09;case when…then…else 2&#xff09;json_value 函数 拓展资料 3&#xff09;CAST 函数 拓展资料 4) ROUND 函数 5&#xff09;occurences_regexpr 函数 拓展资料 6&#xff09;正则表达式 拓展资料 三、整合分析…
最新文章