ORBSLAM2系统学习(二)

2023-05-16

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、ORBSLAM2简介

二、系统综述

系统框架

追踪线程Tracking

 局部建图线程local mapping

回环检测loop closing

三、多线程运转


前言

理解掌握ORBSLAM2系统整体框架

熟悉此系统ros运行节点线程


一、ORBSLAM2简介

  ORB_SLAM2是首个支持单目、双目和RGB-D相机的完整开源SLAM方案,能够实现地图重用,回环检测和重新定位的功能。能够实时计算相机的位姿,并生成场景的稀疏三维重建地图,使用特征点法的巅峰之作,定位精度非常高。

二、系统综述

系统框架

系统主要有三个线程组成:跟踪、Local Mapping(又称小图)、Loop Closing(又称大图) 

追踪线程Tracking

         这一部分主要工作是从图像中提取ORB特征,根据上一帧进行姿态估计,或者进行通过全局重定位初始化位姿,然后跟踪已经重建的局部地图,优化位姿,再根据一些规则确定新的关键帧。充当视觉里程计的功能。

        具体流程:

        1)图像灰度化处理。
        2)构建当前帧(提取每幅图像的特征点,并分配到网格中,这会极大的方便某一领域内的特征点的查找与匹配)。
        3)单目相机初始化操作:通过特征点匹配,使用RANSAC+DLC计算H矩阵,并根据对称转移误差计算H的评分。使用RANSAC+八点法计算E 矩阵,并根据极线约束估计F评分。选择H/E后通过SVD分解获得最优的R/t。随后进行三角化测距,全局BA优化,优化初始地图的相机位姿和路标点坐标。
        4)估计相机位姿并进行优化(位姿图优化)。追踪相机位姿的方法(主要的不同在于获得当前帧位姿的方式)包括:(1)恒速运动模型:根据前两帧的位姿变换估计当前帧的位姿,在领域内搜索特征点,随后进行位姿优化。(2)参考关键帧模型:以上一帧的位姿为当前位姿,搜索当前帧的参考关键帧(共视点最多的关键帧),使用词袋加速算法进行特征点匹配,随后优化位姿。 (3)重定位模型:使用词袋加速算法获得当前帧的候选关键帧,使用EPNP估计当前帧位姿,进行BA优化。

        5)追踪局部地图:将局部地图中的路标点投影到当前帧中,在当前帧中搜索与之匹配的特征点(每个路标点会有一个描述子),随后优化局部地图中的关键帧的位姿。
        6)判断关键帧。
 

 局部建图线程local mapping

        这一部分主要完成局部地图构建。包括对关键帧的插入,验证最近生成的地图点并进行筛选,然后生成新的地图点,使用Local BA,最后再对插入的关键帧进行筛选,去除多余的关键帧。

        具体流程:

        1)插入关键帧:将关键帧插入到局部地图中。在这个过程中会进行一下操作:(1)计算当前关键帧的词袋,并更新关键帧数据库。(2)更新共视图(更新当前帧和与其有共视关系的关键帧间的权重)。
        2)剔除错误的路标点:(1)路标点和关键帧中的特征点匹配,如果匹配成功的关键帧过少,则认为这个路标点是错误的。(2)路标点被3个以下的关键帧观测到。
        3)建立新的路标点:寻找与当前帧共视程度最高的候选关键帧,使用词袋加速算法+极限约束寻找特征点匹配。使用三角化测距形成新的路标点。在这个过程中,可能存在特征点1本来与路标点1存在联系,三角化之后,特征点1与路标点2建立了联系。这个时候需要进行路标点的融合。
        4)局部BA优化:优化局部地图中的关键帧位姿和路标点坐标。这里的关键帧指的是与当前帧的共视程度超过一定阈值的关键帧。对于小于阈值的共视关键帧,这提供约束,不会对其位姿进行优化。
        5)删除冗余关键帧:如果一个关键帧的90%以上的路标点可以被3个以上的关键帧观测到,就会被删除。

回环检测loop closing

        这一部分主要分为两个过程,分别是闭环探测和闭环校正。闭环检测先使用WOB进行探测,然后通过Sim3算法计算相似变换。闭环校正,主要是闭环融合和Essential Graph的图优化
在局部建图线程中,处理完一个关键帧后会将其抛入回环检测线程中。

        具体流程:

        1)检测候选回环关键帧:与当前帧的共视路标点超过15个,且词袋相似度大于一个阈值的关键帧视为候选回环关键帧。
        2)计算Sim3变换:由于单目相机存在尺度漂移现象,因此需要计算当前关键帧相对于回环关键帧以及世界坐标系的Sim3变换。
        3)回环融合:根据当前帧相对于世界坐标的Sim3变换,优化当前帧的共视关键帧的位姿(这样就会减少误差传递过程,使得位姿估计准确)。
        4)本质图优化:对本质图中的关键帧的位姿进行优化。
        5)在回环检测之后还会有一个全局BA优化线程,对所有关键帧的位姿以及路标点的坐标进行优化。
        更多内容参考ORB_SLAM2概述_嚣张的叉烧包的博客-CSDN博客_orb-slam2

三、多线程运转

bool Initializer::Initialize(const Frame &CurrentFrame) {
 	// ...
    thread threadH(&Initializer::FindHomography, this, ref(vbMatchesInliersH), ref(SH), ref(H));
    thread threadF(&Initializer::FindFundamental, this, ref(vbMatchesInliersF), ref(SF), ref(F));
    // ...
}

        局部建图和回环检测线程都是靠Tracking线程产生的关键帧而运转的,在Tracking线程没有产生关键帧时, 局部建图和回环检测线程都是处于空转状态,直到Tracking线程产生关键帧时,LocalMapping、LoopClosing线程和Tracking线程一起运转,使运算速度加快。

// Tracking线程主函数
void Tracking::Track() {
	// 进行跟踪
    // ...
	
    // 若跟踪成功,根据条件判定是否产生关键帧
    if (NeedNewKeyFrame())
        // 产生关键帧并将关键帧传给LocalMapping线程
        KeyFrame *pKF = new KeyFrame(mCurrentFrame, mpMap, mpKeyFrameDB);
        mpLocalMapper->InsertKeyFrame(pKF);	
}
 
// LocalMapping线程主函数
void LocalMapping::Run() {
	// 死循环
    while (1) {
        // 判断是否接收到关键帧
        if (CheckNewKeyFrames()) {
            // 处理关键帧
            // ...
            
            // 将关键帧传给LoopClosing线程
            mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
        }
        
        // 线程暂停3毫秒,3毫秒结束后再从while(1)循环首部运行
        std::this_thread::sleep_for(std::chrono::milliseconds(3));
    }
}
 
// LoopClosing线程主函数
void LoopClosing::Run() {
    // 死循环
    while (1) {
        // 判断是否接收到关键帧
        if (CheckNewKeyFrames()) {
            // 处理关键帧
            // ...
        }
 
        // 查看是否有外部线程请求复位当前线程
        ResetIfRequested();
 
        // 线程暂停5毫秒,5毫秒结束后再从while(1)循环首部运行
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }
}

        当三个线程同时运转程序发生混乱的时候,需要给他们加锁。所谓加锁就是只有拿到锁的线程才可以正常运转,运转结束之后自动释放锁。如果一个线程要运转但是锁被其他线程占用着,那只能一直等到其他线程释放锁之后拿到锁才可以继续运行。

class KeyFrame {
protected:
	KeyFrame* mpParent;
    
public:
    void KeyFrame::ChangeParent(KeyFrame *pKF) {
        unique_lock<mutex> lockCon(mMutexConnections);		// 加锁
        mpParent = pKF;
        pKF->AddChild(this);
    }
 
    KeyFrame *KeyFrame::GetParent() {
        unique_lock<mutex> lockCon(mMutexConnections);		// 加锁
        return mpParent;
    }
}
 
 
void KeyFrame::EraseConnection(KeyFrame *pKF) {
    // 第一部分加锁
    {
        unique_lock<mutex> lock(mMutexConnections);
        if (mConnectedKeyFrameWeights.count(pKF)) {
            mConnectedKeyFrameWeights.erase(pKF);
            bUpdate = true;
        }
    }// 程序运行到这里就释放锁,后面的操作不需要抢到锁就能执行
	
    UpdateBestCovisibles();
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ORBSLAM2系统学习(二) 的相关文章

随机推荐

  • apt 和 apt-get 区别

    文章目录 1 apt 的由来2 apt 和 apt get 的区别3 应该使用 apt 还是 apt get xff1f 1 apt 的由来 Ubuntu Linux Mint和elementary OS 等发行版的 Linux 均是基于D
  • 你是我的眼:水哥王昱珩带你重新打量这世界

    水哥 王昱珩在 最强大脑 舞台上凭借着 微观辨水 一战成名 在节目中 xff0c 他以1秒四杯的速度从520杯同质同量同水源的水中 xff0c 迅速找出了之前被随机选中的那杯 xff0c 甚至看出了这杯水从被选中拿起观察再到放回原位 xff
  • 性能优化与内存优化

    性能优化 主要以这四个方向进行优化 xff1a 稳定流畅耗损apk 瘦身 稳定 避免内存溢出异常捕获反馈机制 流畅 卡顿的原因 xff1a 布局复杂动画过多View 的过度绘制UI 耗时操作频繁 GC 耗损 减少没必要的网络访问或合并相关网
  • (2)工作空间

    工作空间 特点创建工作空间编译添加环境变量 特点 1 工作空间的主要作用是存放工程文件和文件代码 xff08 存放工作空间和代码的一个文件夹 xff09 2 ROS的开发依赖于工作空间 3 编写源代码 编译都是在工作空间下完成的 4 一般工
  • 工程伦理 清华大学 MOOC 期末答案 2020冬

    前言 xff1a 答案是本人自己查阅 不保证其完全正确性 xff0c 仅供参考 点个赞再走呗 xff1a xff09 1 单选题 1分 以下不属于安全文化的核心的是 D A 人的安全知识 B 人的安全意识 C 人的安全技能 D 人的安全装备
  • HTML移动端的基本了解

    文章目录 前言 一 PC端与移动端的区别 PC端 xff1a 移动端 xff1a 二 视口 布局视口 视觉视口 理想视口 meta视口标签 三 二倍图 四 移动端开发选择 单独制作移动端页面 主流 响应式页面兼容移动端 其次 总结 前言 分
  • 树莓派4B(armv7l,arm32)buster部署英特尔第二代神经计算棒,示例:运行darknet-yolov4-tiny

    记录整个部署的步骤 英特尔第二代神经计算棒 xff08 Intel NCS2 xff09 的使用需要到OpenVINO官网下载安装某一个版本的软件 xff0c 目前是支持Windows Linux和树莓派的Raspbian OS 下面贴出来
  • 树莓派结合英特尔神经计算棒二代(NCS2)的openvino包部署人工智能应用

    利用树莓派和英特尔神经计算棒二代 xff08 NCS2 xff09 进行边缘端AI硬件平台部署三部曲 xff1a 二 xff09 树莓派4B和NCS2配置时cmake编译报错以及import error can t find moudle
  • 树莓派报错“Cannot currently show the desktop”的完美解决办法

    最近在利用树莓派部署神经网络的时候出现了一些大大小小的问题 xff0c 很多问题都可以在网上直接或间接地找到答案 xff0c 但有个别问题即使按照网上的高赞博客说的去做了仍然没用 笔者根据最近遇到的有关树莓派VNC win10远程桌面连接
  • Nvidia Jetson XAvier NX开发套件从装机到pytorch环境搭建YoloV5+DeepSort+TensorRT

    目录 1 刷机与装机1 1 准备VMware工作站和linux的unbuntu16 04虚拟机 xff1a 1 2 将SD上的系统移动至SSD1 3 SSH配置1 4 查看Jetpack版本1 5 启动风扇 2 深度学习环境配置2 1 py
  • Python+OpenCV+matplotlib+wxPython实现的图像处理程序

    Python 43 OpenCV 43 matplotlib 43 wxPython实现的图像处理程序 背景 xff1a 本学期多媒体技术原理与应用课程的实验部分代码结果截图结语 背景 xff1a 本学期多媒体技术原理与应用课程的实验 本学
  • 按量购买阿里云服务器、k8s集群

    基础配置 创建私有网络 注意这里的交换区必须和服务器的所选区相同 连接测试 ping a 172 31 0 141 172 31 0 143 172 31 0 142 ping一下私有网络 ping 172 32 0 141 设置弹性ip
  • 小米6渲染图曝光 边框惊艳 国产曲面旗舰要发黑色版

    昨天咱们刚刚说过 小米6会有陶瓷版本 并且估计会在四月发布 今天 网友的渲染图又来了 没上车的赶紧上车 别忘了底部打卡 最近 对于小米6的传言很众多 xff0c 但不管怎么说 xff0c 骁龙835处理器 IMX400传感器以及高屏占比等都
  • 时间戳对齐的简单算法(原创)

    实际融合算法过程中常常出现时间戳对不齐的情况 为了解决此问题 xff0c 用了两个队列来解决时间戳匹配问题 时间戳对齐算法实现原理如下下图为插入状态 如图所示共有两个队列 xff0c 有七个状态 xff0c 通过对于轮速递推结果的动态保存
  • java中equals和==的区别(简单介绍)

    java中equals和 61 61 的区别 简单介绍 equals方法是java lang Object类的方法 有两种用法说明 一 对于字符串变量来说 xff0c 使用 61 61 和 equals 方法比较字符串时 xff0c 其比较
  • 如何上传到GitHub的main分支而不是master分支

    由于在2020年10月01日后 xff0c 在 GitHub 上创建的仓库都默认命名为 main 而非原本的 master 所以 有人看了我的 https blog csdn net m0 46419510 article details
  • Python中的Pandas、Matplotlib库详解

    文章目录 Pandas数据分析库Pandas的基本数据结构访问数据算术运算和对齐数据整理 Matplotlib绘图库Matplotlib简介几种常见的图形多图绘制使用Pandas绘图 Pandas数据分析库 1 xff09 Pandas是目
  • 卡尔曼滤波模型及Matlab模型建立

    目录 一 卡尔曼滤波 1 概念解析 xff1a 2 卡尔曼滤波的最优估计模型 3 实例 小车匀加速直线运动 4 Matlab建模 二 扩展卡尔曼滤波 xff08 EKF Extended KAlman Filter xff09 1 非线性系
  • 智能车 PID 调试

    智能车 PID 调试 文章目录 智能车 PID 调试学习目的开环控制与闭环控制开环控制闭环控制小结 PID 概述简介PID 公式 xff1a 舵机 PID分析算法 电机 PID分析算法调试口决 注意事项 学习目的 使电机速度和舵机转向更精准
  • ORBSLAM2系统学习(二)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 目录 前言 一 ORBSLAM2简介 二 系统综述 系统框架 追踪线程Tracking 局部建图线程local mapping 回环检测l