01 整体代码运行流程

文章目录

    • 01 整体代码运行流程
      • 1.1 运行官方 Demo
      • 1.2 变量命名规则
      • 1.3 多线程
      • 1.4 线程锁
      • 1.5 SLAM 主类 System

01 整体代码运行流程

1.1 运行官方 Demo

以 stereo_kitti 为例,执行

./stereo_kitti path_to_vocabulary path_to_settings path_to_sequence
  • ./stereo_kitti:可执行文件

  • path_to_vocabulary:字典路径

  • path_to_settings:配置文件路径,包含相机参数和 ORB 特征提取参数

  • path_to_sequence:数据集路径

主函数

int main(int argc, char **argv)
{
    if(argc != 4)
    {
        cerr << endl << "Usage: ./stereo_kitti path_to_vocabulary path_to_settings path_to_sequence" << endl;
        return 1;
    }

    // 载入左右目图片、时间戳
    vector<string> vstrImageLeft;
    vector<string> vstrImageRight;
    vector<double> vTimestamps;
    LoadImages(string(argv[3]), vstrImageLeft, vstrImageRight, vTimestamps);

    const int nImages = vstrImageLeft.size();

    // 创建 SLAM 对象
    ORB_SLAM2::System SLAM(argv[1],argv[2],ORB_SLAM2::System::STEREO,true);

    // 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;

    // Main loop
    cv::Mat imLeft, imRight;
    for(int ni=0; ni<nImages; ni++)
    {
        // Read left and right images from file
        imLeft = cv::imread(vstrImageLeft[ni],CV_LOAD_IMAGE_UNCHANGED);
        imRight = cv::imread(vstrImageRight[ni],CV_LOAD_IMAGE_UNCHANGED);
        double tframe = vTimestamps[ni];    // 记录对应的时间

        if(imLeft.empty())
        {
            cerr << endl << "Failed to load image at: "
                 << string(vstrImageLeft[ni]) << endl;
            return 1;
        }

        std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();

        // Pass the images to the SLAM system
        SLAM.TrackStereo(imLeft,imRight,tframe);        

        std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();

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

        vTimesTrack[ni]=ttrack;     // 记录下每次 track 耗时

        // 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)
			this_thread::sleep_for(std::chrono::microseconds((int)((T-ttrack)*1e6)));
    }

    // 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.SaveTrajectoryKITTI("CameraTrajectory.txt");

    return 0;
}

1.2 变量命名规则

  • m 开头的变量表示为某类的成员变量;

  • 变量名的第一、二个字母表示其数据类型:

    s 表示 std::set 类型

    v 表示 std::vector 类型

    l 表示 std::list 类型

    p 表示指针类型

    n 表示 int 类型

    b 表示 bool 类型

    KF 表示 KeyFrame 类型

1.3 多线程

在这里插入图片描述

包括 Tracking、LocalMapping、LoopClosing 三个线程。

当 Tracking 不产生关键帧时,LocalMapping、LoopClosing 线程基本处于空转状态;并且,Tracking 线程产生关键帧的频率和时机是不固定的,因此需要三个线程同时进行,LocalMapping 和 LoopClosing 不断循环查询 Tracking 是否产生了关键帧。

1.4 线程锁

unique_lock<mutex> lock(mMutexConnections); 即为加锁,锁的有效性仅限于大括号内,也就是说,到大括号外,锁就会自动释放。所以程序中的一些大括号并非可有可无,需要注意。

1.5 SLAM 主类 System

成员变量/函数访问控制备注
eSensor mSensorprivate传感器类型,可选 MONOCULAR、STEREO、RGBD
ORBVocabulary* mpVocabularyprivate字典,用来保存 ORB 描述子聚类结果
KeyFrameDatabase* mpKeyFrameDatabaseprivate关键帧数据库
Map* mpMapprivate地图
Tracking* mpTrackerprivate追踪器
LocalMapping* mpLocalMapperprivate局部建图、BA
LoopClosing* mpLoopCloserprivate回环检测
Viewer* mpViewerprivate查看器
FrameDrawer* mpFrameDrawerprivate帧绘制器
MapDrawer* mpMapDrawerprivate地图绘制器
std::thread* mptLocalMappingprivate局部建图线程
std::thread* mptLoopClosingprivate回环检测线程
std::thread* mptViewerprivate查看器线程
System(...)public构造函数:初始化 SLAM 系统,启动 建图、回环、查看器线程
cv::Mat TrackStereo(...)
cv::Mat TrackRGBD(...)
cv::Mat TrackMonocular(...)
public
public
public
追踪双目相机,返回相机位姿
追踪 RGBD 相机,返回相机位姿
追踪单目相机,返回相机位姿
void ActivateLocalizationMode()
void DeactivateLocalizationMode()
std::mutex mMutexMode
bool mbActivateLocalizationMode
bool mbDeactivateLocalizationMode
public
public
private
private
private
开启纯定位模式(关闭建图线程)
关闭纯定位模式
void Reset()
std::mutex mMutexReset
bool mbReset
public
private
private
系统复位
void Shutdown()public系统关闭
void SaveTrajectoryTUM
void SaveKeyFrameTrajectoryTUM()
void SaveTrajectoryKITTI()
public
public
public
以 TUM/KITTI 格式保存相机运动轨迹和关键帧位姿

构造函数


// 依次传入数据集、配置文件、传感器类型、bUseViewer
System::System(const string &strVocFile, const string &strSettingsFile, const eSensor sensor,
               const bool bUseViewer):mSensor(sensor),mbReset(false),mbActivateLocalizationMode(false),
               mbDeactivateLocalizationMode(false)
{
    // Step1 初始化成员变量、
    // Step1.1 读取配置文件
    cv::FileStorage fsSettings(strSettingsFile.c_str(), cv::FileStorage::READ);
    
    // Step1.2 载入 ORB 字典
    mpVocabulary = new ORBVocabulary();
    
    // Step1.3 创建关键帧数据库
    mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);
    
    // Step1.4 创建地图
    mpMap = new Map();
    
    // Step1.5 绘图
    mpFrameDrawer = new FrameDrawer(mpMap);
    mpMapDrawer = new MapDrawer(mpMap, strSettingsFile);
    
    // Step2 三大线程
    // Step2.1 Tracking 线程,只需创建 Tracking 对象即可
    mpTracker = new Tracking(this, mpVocabulary, mpFrameDrawer, mpMapDrawer,
                             mpMap, mpKeyFrameDatabase, strSettingsFile, mSensor);
    
    // Step2.2 创建 Local Mapping 线程和 mpLocalMapper 
    mpLocalMapper = new LocalMapping(mpMap, mSensor==MONOCULAR);
    mptLocalMapping = new thread(&ORB_SLAM2::LocalMapping::Run,mpLocalMapper);
    
    // Step2.3 创建 LoopClosing 线程和 mpLoopCloser
    mpLoopCloser = new LoopClosing(mpMap, mpKeyFrameDatabase, mpVocabulary, mSensor!=MONOCULAR);
    mptLoopClosing = new thread(&ORB_SLAM2::LoopClosing::Run, mpLoopCloser);
    
    // 线程间通信
    mpTracker->SetLocalMapper(mpLocalMapper);
    mpTracker->SetLoopClosing(mpLoopCloser);

    mpLocalMapper->SetTracker(mpTracker);
    mpLocalMapper->SetLoopCloser(mpLoopCloser);

    mpLoopCloser->SetTracker(mpTracker);
    mpLoopCloser->SetLocalMapper(mpLocalMapper);
}

注意到,创建 Tracking 线程时,并没有 std::thread 成员变量,仅仅初始化了 Tracking 对象。这是因为,在逻辑上三个线程是并发的,互不包含;但实际编程中,我们将 Tracking 线程视为主线程,LocalMapping 和 LoopClosing 为子线程,Tracking 通过持有两个子线程的指针实现对其控制。

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

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

相关文章

大创项目推荐 深度学习 python opencv 实现人脸年龄性别识别

文章目录 0 前言1 项目课题介绍2 关键技术2.1 卷积神经网络2.2 卷积层2.3 池化层2.4 激活函数&#xff1a;2.5 全连接层 3 使用tensorflow中keras模块实现卷积神经网络4 Keras介绍4.1 Keras深度学习模型4.2 Keras中重要的预定义对象4.3 Keras的网络层构造 5 数据集处理训练5.1 …

W25Q64(模拟SPI)读写数据的简单应用

文章目录 一、W25Q64是什么&#xff1f;二、使用步骤1.硬件1.引脚说明2.硬件连接3.设备ID4.内部框架5.指令集指令集1指令集2 2.软件1.W25Q64引脚定义代码如下&#xff08;示例&#xff09;&#xff1a;2.W25Q64初始化代码如下&#xff08;示例&#xff09;&#xff1a;3.W25Q64…

在排序数组中查找元素的第一个和最后一个位置(Java详解)

一、题目描述 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。 示…

Android开发——组合函数、注解与连接Android设备

1、JetPack Compose、组合函数与注解和文本修改 1、JetPack Compose&#xff1a;Jetpack Compose 是由 Google 推出的用于构建 Android 用户界面的现代化工具包。它是一个声明式的 UI 工具包&#xff0c;用于简化 Android 应用程序的用户界面设计和开发。Jetpack Compose 采用…

02.Git常用基本操作

一、基本配置 &#xff08;1&#xff09;打开Git Bash &#xff08;2&#xff09;配置姓名和邮箱 git config --global user.name "Your Name" git config --global user.email "Your email" 因为Git是分布式版本控制工具&#xff0c;所以每个用户都需要…

02-分组查询group by和having的使用

分组查询 MySQL中默认是对整张表的数据进行操作即整张表为一组, 如果想对每一组的数据进行操作,这个时候我们需要使用分组查询 分组函数的执行顺序: 先根据where条件筛选数据,然后对查询到的数据进行分组,最后也可以采用having关键字过滤取得正确的数据 group by子句 在一条…

【STM32】STM32学习笔记-EXTI外部中断(11)

00. 目录 文章目录 00. 目录01. 中断系统02. 中断执行流程03. STM32中断04. NVIC基本结构05. NVIC优先级分组06. EXTI简介07. EXTI基本结构08. AFIO复用IO口09. EXTI框图10. 计数器模块11. 旋转编码器简介12. 附录 01. 中断系统 中断&#xff1a;在主程序运行过程中&#xff0…

easy贪吃蛇

之前承诺给出一个贪吃蛇项目。 1.EasyX库认知 有关EasyX库的相关信息&#xff0c;您可以看一下官方的文档&#xff1a;EasyX官方文档。 这里我做几点总结&#xff1a; EasyX库就和名字一样&#xff0c;可以让用户调用一些简单的函数来绘制图像和几何图形利用EasyX库可以制作…

ES6 面试题 | 15.精选 ES6 面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

知识付费平台选择指南:如何找到最适合你的学习平台?

在当今的知识付费市场中&#xff0c;用户面临的选择越来越多&#xff0c;如何从众多知识付费平台中正确选择属于自己的平台呢&#xff1f;下面&#xff0c;我们将为您介绍我有才知识付费平台相比同行的优势&#xff0c;帮助您做出明智的选择。 一、创新的技术架构&#xff0c;…

3.3【窗口】窗口的几何形状(二,窗口属性)

写在前面 应用程序使用窗口来显示内容。一些属性决定了窗口及其内容的大小和位置。其他属性决定了窗口内容的外观和解释。 了解窗口属性引用的两个坐标系非常重要。如果你知道你正在使用的坐标系,那么为你的窗口属性选择设置值会容易得多,并且会更有意义。 一,显示相关属…

【CMU 15-445】Lecture 11: Joins Algorithms 学习笔记

Joins Algorithms Nested Loop JoinNaive Nested Loop JoinBLock Nested Loop JoinIndex Nested Loop Join Sort-Merge JoinHash JoinBasic Hash JoinPartitioned Hash Join Conclusion 本节课主要介绍的是数据库系统中的一些Join算法 Nested Loop Join Naive Nested Loop Joi…

华媒舍:打造出色科普文章的10步路透社发稿手册

1.科普文章的编写是一项让科技知识更为浅显易懂重要工作。下面我们就详细介绍路透社的发稿手册&#xff0c;带来了好用的流程&#xff0c;协助作者从零开始创作出色的科普文章。 2.明确主题风格在创作科普文章以前&#xff0c;首先要明确要介绍的主题风格。选择一个有趣且适合…

verilog语法进阶,时钟原语

概述&#xff1a; 内容 1. 时钟缓冲 2. 输入时钟缓冲 3. ODDR2作为输出时钟缓冲 1. 输入时钟缓冲 BUFGP verilog c代码&#xff0c;clk作为触发器的边沿触发&#xff0c;会自动将clk综合成时钟信号。 module primitive1(input clk,input a,output reg y); always (posed…

【C++11特性篇】探究【右值引用(移动语义)】是如何大大提高效率?——对比【拷贝构造&左值引用】

前言 大家好吖&#xff0c;欢迎来到 YY 滴C11系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.【左值&左值引用】和【右值&a…

Leetcode 删除有序数组中的重复项

给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成 示例 1&#xff1a; 输入&…

超声波清洗机哪个好?怎么样挑选清洗力比较强超声波清洗机

大部分的年轻人&#xff0c;现在因为各种原因&#xff0c;戴眼镜的人群不再是局限于学生&#xff0c;很多打工族或者是老人也戴上了眼镜&#xff0c;近视眼或者是老花眼都有。戴眼镜的人群越来越多&#xff0c;会有很多人忽视眼镜清洗这个事情&#xff0c;眼镜长时间不清洗的话…

多层记忆增强外观-运动对齐框架用于视频异常检测 论文阅读

MULTI-LEVEL MEMORY-AUGMENTED APPEARANCE-MOTION CORRESPONDENCE FRAMEWORK FOR VIDEO ANOMALY DETECTION 论文阅读 摘要1.介绍2.方法2.1外观和运动对其建模2.2.记忆引导抑制模块2.3. Training Loss2.4. Anomaly Detection 3.实验与结果4.结论 论文标题&#xff1a;MULTI-LEVE…

云渲染技术下的虚拟现实:技术探索与革新思考

虚拟现实&#xff08;含增强现实、混合现实&#xff09;是新一代信息技术的重要前沿方向&#xff0c;是数字经济的重大前瞻领域&#xff0c;将深刻改变人类的生产生活方式&#xff0c;产业发展战略窗口期已然形成。但是虚拟现实想要深入改变影响我们的生活&#xff0c;以下技术…

PyQt6 QToolBar工具栏控件

锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计44条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话版…