orbslam2代码解读(3):localmapping局部建图线程

news2025/1/13 13:51:52

书接上回,介绍完了跟踪线程,已经得到了当前帧相机的位姿,并且当判断需要产生关键帧的时候,tracking线程把新创建的关键帧插入到mpLocalMapper这个线程的mlNewKeyFrames容器中。所以这时候局部线程就根据这个新的关键帧来进行局部建图的操作。

局部建图的主要程序

// 主循环
while(1)
{
    // Step 1 告诉Tracking,LocalMapping正处于繁忙状态,请不要给我发送关键帧打扰我
    // LocalMapping线程处理的关键帧都是Tracking线程发来的
    SetAcceptKeyFrames(false);
    // 等待处理的关键帧列表不为空
    if(CheckNewKeyFrames()){
        // Step 2 处理列表中的关键帧,包括计算BoW、更新观测、描述子、共视图,插入到地图等
        ProcessNewKeyFrame();
        // Step 3 根据地图点的观测情况剔除质量不好的地图点
        MapPointCulling();
        // Step 4 当前关键帧与相邻关键帧通过三角化产生新的地图点,使得跟踪更稳
        CreateNewMapPoints();
        // 已经处理完队列中的最后的一个关键帧
        if(!CheckNewKeyFrames()){
            //  Step 5 检查并融合当前关键帧与相邻关键帧帧(两级相邻)中重复的地图点
            SearchInNeighbors();
        }
        // 终止BA的标志
        mbAbortBA = false;
        // 已经处理完队列中的最后的一个关键帧,并且闭环检测没有请求停止LocalMapping
        if(!CheckNewKeyFrames() && !stopRequested())
        {
            // Step 6 当局部地图中的关键帧大于2个的时候进行局部地图的BA
            if(mpMap->KeyFramesInMap()>2)
      // 注意这里的第二个参数是按地址传递的,当这里的 mbAbortBA 状态发生变化时,能够及时执行/停止BA
           Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpMap);
            // Step 7 检测并剔除当前帧相邻的关键帧中冗余的关键帧
            // 冗余的判定:该关键帧的90%的地图点可以被其它关键帧观测到
            KeyFrameCulling();
        }
        // Step 8 将当前帧加入到闭环检测队列中
        // 注意这里的关键帧被设置成为了bad的情况,这个需要注意
        mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
    }

cvlife的注释版删掉一些冗余的解释后,主要就是这么一个流程,后续就逐个流程介绍。

step1,SetAcceptKeyFrames(false)

告诉Tracking,LocalMapping正处于繁忙状态,请不要给我发送关键帧打扰我。其实就是设置标志位让其他线程可以知道当前线程的信息(记得需要加互斥锁)。

step2,ProcessNewKeyFrame()

mlNewKeyFrames容器不为空(即有新的关键帧产生),就需要处理容器中的新关键帧。

  1. 计算新关键帧特征点的词袋向量。(老朋友了,在跟踪那一章对词袋解释的比较详细)
  2. 处理新关键帧中有效的地图点。①如果地图点不是来自当前帧的观测(比如来自局部地图点),为当前地图点添加观测(addobservation函数,主要可以通过这个函数知道地图点都被哪些关键帧观测到了,能够知道共视关系)。②更新地图点的平均观测方向(地图点与相机光心的夹角)和观测距离范围(观测距离的预测与金字塔层级有关,具体可以参考这篇博客:【ORB-SLAM2】MapPoint::PredictScale()小记)。③更新地图点的最佳描述子。
    在这里插入图片描述在这里插入图片描述
  3. 更新关键帧之间的连接关系。主要就是根据共视地图点数量对关键帧排序,更新新关键帧与其他关键帧的共视关系。
  4. 将新关键帧插入到全局地图中。

step3,MapPointCulling()

这个函数的主要作用就是提出质量不好的新增地图点。新增的地图点有两种:第一种是如果双目或者RGBD相机会在创建关键帧中新生成的地图点。第二种是后续三角化中产生的新地图点。
这个函数的过程如下:

  1. 根据相机类型设置不同的观测阈值。cnThObs
  2. 遍历新增的地图点,并且检查好坏。检测条件:①如果已经是坏点就直接不要。②跟踪到该地图点的帧数比应该见到该地图点的帧数比例小于25%(就是在跟踪过程中(mnFound/mnVisible) < 25%这个比例)。③从该点建立开始,到现在已经过了不小于2个关键帧,但是观测到该点的相机数却不超过阈值cnThObs,所以删除。④从建立该点开始,已经过了3个关键帧而没有被剔除,则认为是质量高的点,所以不删除。

step4,CreateNewMapPoints()

这个函数主要是通过当前关键帧与相邻关键帧通过三角化产生新的地图点,这个是单目非常重要的函数,因为就是需要通过这样三角化不断产生统一尺度的地图3d点,才能在后续跟踪过程直接通过pnp求解出统一个尺度下的连续位姿(虽然这个尺度在slam长时间运行时会有尺度漂移,但是可以通过回环检测加sim3匹配来优化)。
在这里插入图片描述
这个函数的过程如下:

  1. 在当前关键帧的共视关键帧中找到共视程度最高的前10/20个相邻关键帧。(就是根据共视地图点数量的顺序来提取)
  2. 遍历相邻关键帧,首先判断两个关键帧之间的baseline。在双目的情况下,如果这个baseline小于双目相机自身的基线,则不进行三角化,因为基线短的时候恢复的深度误差大。在单目情况下则是检查这个baseline与当前关键帧地图点的深度中值的比值,如果太小同样也不进行三角化。
  3. 如果上述情况都满足,后续根据两个关键帧的位姿计算它们之间的基础矩阵(跟初始化的时候是反过来,初始化的时候是先通过匹配点对求解一个线性方程组,得到基础矩阵)。
  4. 通过词袋模型对两个关键帧未匹配的特征点快速匹配,用极线约束抑制离群点(极线约束就是依靠基础矩阵将特征点进行投影,然后根据点到直线距离与卡方分布联合抑制离群点),并且生成新的匹配点对
    在这里插入图片描述
  5. 对每对匹配通过三角化生成3D点,和 Triangulate函数差不多。
  6. 如果三角化3d点成功,就构造MapPoint,并且添加地图点的各种属性(添加地图点的observation,计算最佳描述子,更新观测方向和深度等等),最终地图点加入mlpRecentAddedMapPoints容器中,并且需要通过MapPointCulling()来检测这个点的质量。

step5,SearchInNeighbors()

当已经处理完队列中的最后的一个关键帧,就会调用这个函数,检查并融合当前关键帧与相邻关键帧帧(两级相邻)中重复的地图点。注意一些命名规则:当前关键帧的邻接关键帧,称为一级相邻关键帧,也就是邻居,与一级相邻关键帧相邻的关键帧,称为二级相邻关键帧,也就是邻居的邻居。
在这里插入图片描述

这个函数的过程如下:

  1. 获得当前关键帧在共视图中权重排名前10/20的邻接关键帧(一级相邻关键帧)
  2. 获取二级相邻关键帧
  3. 将当前帧的地图点分别投影到两级相邻关键帧,寻找匹配点对应的地图点进行融合,称为正向投影融合。融合策略如下:①如果地图点能匹配关键帧的特征点,并且该点有对应的地图点,那么选择观测数目多的替换两个地图点。②如果地图点能匹配关键帧的特征点,并且该点没有对应的地图点,那么为该点添加该投影地图点
  4. 将两级相邻关键帧地图点分别投影到当前关键帧,寻找匹配点对应的地图点进行融合,称为反向投影融合。策略都是一样的,调用的同一个函数。
  5. 更新当前帧地图点的描述子、深度、平均观测方向等属性
  6. 更新当前帧与其它帧的共视连接关系

step6,Optimizer::LocalBundleAdjustment()

新的关键帧通过上面的函数都处理好了,后续就是进行局部BA,当全局地图的关键帧数量大于2就可以开始执行局部BA的优化。这里的优化就不是只优化当前关键帧的位姿了,而是将当前关键帧局部的关键帧及其地图点加到图中进行优化。
这个函数的过程如下:

  1. 将当前帧和当前帧的共视帧加入局部关键帧的容器中(其实就是当前帧与当前帧的一级相连关键帧)。
  2. 遍历局部关键帧,将这些关键帧的地图点加入到局部地图点的容器
  3. 得到能够观测到局部地图点,但不属于局部关键帧的关键帧(二级相连),这些二级相连关键帧在局部BA优化时不优化(这些关键帧属于fixed keyframes)
  4. 通过g2o构造这个局部BA优化。注意的是局部关键帧的位姿和局部地图点的位置都是优化对象(不固定),而二级相连的关键帧负责提供约束(所以它们的位姿是固定的)。还需要注意的一点:这个局部BA会假设局部的尺度是一致的,所以优化的局部关键帧位姿都是SE3,与全局BA相反,因为全局BA优化的关键帧位姿都是Sim3(全局的范围更大,必须考虑尺度漂移)。
  5. 第一阶段优化后,找到误差不符合卡方分布的边,设置为外点,后续不进行优化。排除了外点后继续进行第二阶段的优化。在优化后重新计算误差,剔除连接误差比较大的关键帧和地图点(只是删除了它们之间的observation关系)。最终更新关键帧的位姿和地图点的位置及其属性(平均观测方向和深度)。

step7,KeyFrameCulling()

这个函数主要是提取当前关键帧在共视图中的关键帧,根据地图点在共视图中的冗余程度剔除该共视关键帧(冗余关键帧的判定:90%以上的地图点能被其他关键帧(至少3个)观测到)。函数的逻辑也比较简单,这里就不展开了。

step8

将当前关键帧加入到闭环检测的队列mlpLoopKeyFrameQueue中,这个的逻辑一般都是新产生了一个关键帧都会加入到这个队列中,如果这个关键帧是冗余的话会被设置为bad,回环的时候会检测bad标志,所以不用担心。

总结

这个localmapping局部建图线程还是比较简单的,就是处理关键帧,处理完毕就执行一个局部BA的优化。最后给回环线程留了一个队列,用于检测是否有回环。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三星系统因何而成?或许是因为吞噬了第四颗恒星

相比于其他的类似星体&#xff0c;这个特殊的三星系统拥有更大更紧密的星体。 三星 天文学家发现了前所未见的三星系统。相比于其他典型的三星系统&#xff0c;这一三星系统拥有更大的体积&#xff0c;并且排列也更加紧密&#xff0c;这也使得这一系统更加特别。科学家推测&am…

8、项目目录结构创建

项目目录结构创建 8.1 三层架构 在spring-boot 的web项目中大都是按照这个思路来的: controller层 —> service层(serviceImpl实现service接口)—> mapper层—> mapper.xml文件 创建目录 commen:存放公共代码的 config:存放配置代码的 controller:后端控制器,…

[office] excel表格中双击鼠标左键有什么快捷作用- #经验分享#媒体

excel表格中双击鼠标左键有什么快捷作用? excel表格中双击鼠标左键有什么快捷作用&#xff1f;不要小看鼠标左键双击的作用&#xff0c;在excel中双击鼠标左键可以实现六个功能&#xff0c;提高工作效率&#xff0c;到底是那六个功能呢&#xff1f;请看下文详细介绍 在表格中…

MAVEN仓库和Nexus私服

仓库 仓库的类型 本地&#xff08;local&#xff09; Maven 的本地仓库&#xff0c;在安装 Maven 后并不会创建&#xff0c;它是在第一次执行 maven 命令的时候才被创建 中央&#xff08;central&#xff09; Maven 中央仓库是由 Maven 社区提供的仓库&#xff0c;其中包含了大…

爱普生32.768kHz晶振FC-135:小型化为高端产品带来的卓越优势

在电子设备快速发展的时代&#xff0c;晶振作为时钟源的核心元件&#xff0c;其性能和尺寸对产品的整体表现至关重要。爱普生32.768kHz晶振FC-135凭借其小型化设计和出色的性能&#xff0c;为高端产品带来了显著的优势。本文将介绍32.768kHz晶振FC-135的特点及其在高端产品中的…

Tiny Time Mixers (TTM)轻量级时间序列基础模型:无需注意力机制,并且在零样本预测方面表现出色

大语言模型的发展让研究人员专注于建立尽可能大的模型。但是其实较小的模型在某些任务中表现会优于较大的模型时&#xff0c;例如&#xff1a;Llama 3-8B在MMLU任务上的表现优于较大的Llama 2-70B ! 这就说明大模型并不是万能的&#xff0c;在一些特定任务中&#xff0c;小模型…

RK3568-修改fiq-debugger调试串口

瑞芯微SDK默认将uart2_m0作为调试串口,以下方法将调试串口修改为uart5_m1。修改bootloader 修改/OK3568-linux-source/rkbin/tools/ddrbin_param.txt文件,5表示串口5。1表示复用m1。执行./ddrbin_tool ddrbin_param.txt ../bin/rk35/rk3568_ddr_1560MHz_v1.11.bin命令修改ub…

Windows环境下搭建RocketMq集群(双主双从)

一、官网下载Rocket安装包 下载地址&#xff1a;https://rocketmq.apache.org/dowloading/releases/下载 | RocketMQhttps://rocketmq.apache.org/dowloading/releases/ 博主这里下载的是4.9.8版本的&#xff0c;大家根据自己的需要下载对应的版本即可。 二、环境变量配置 环…

再度牵手,制造升级 | 毅达科技IMS OS+通用产品集+行业套件项目正式启动!

在数字化与智能制造的浪潮中&#xff0c;制造业企业纷纷加快转型步伐&#xff0c;力求通过技术创新实现生产效率与质量的双重提升。近日&#xff0c;广东毅达医疗科技股份有限公司&#xff08;以下简称“毅达科技”&#xff09;再次携手盘古信息&#xff0c;正式启动了IMS 数字…

背包问题—动态规划

01背包问题&#xff1a;没有物品&#xff08;元素&#xff09;只能选择1次 【模板】01背包_牛客题霸_牛客网 (nowcoder.com) #include <array> #include <cstring> #include <iostream> #include<vector> using namespace std; int n,V; int dp[1001…

全球微型光谱仪市场规模逐渐扩大 智能手机为最大应用领域

全球微型光谱仪市场规模逐渐扩大 智能手机为最大应用领域 光谱仪又称为分光仪&#xff0c;是用来测量光谱成分的一种仪器&#xff0c;可以检测特定波长的电磁辐射形成的光谱&#xff0c;从而获取有关物质的结构和动力学等信息。微型光谱仪是光谱仪的细分产品之一&#xff0c;具…

原腾讯云副总裁张纾翔加入矩阵起源,共筑人工智能新篇章

近日&#xff0c;原腾讯云副总裁张纾翔先生正式加入矩阵起源&#xff0c;担任合伙人兼高级副总裁&#xff0c;全面负责矩阵起源商业化工作。 矩阵起源成立于2021年。公司创始团队来自腾讯云、Snowflake等国内外一流的互联网企业、软件公司、数字化企业和开源社区&#xff0c;核…

使用 Transformer 完成 IMDB 情感分类任务

前言 本文使用简单的 Transformer Block 实现对影评文本数据 IMDB 的情感分类任务。 数据 这里定义了两个关键的超参数&#xff1a; vocab_size&#xff1a;表示词汇表的大小&#xff0c;即允许在文本数据中使用的不同的单词数量。maxlen&#xff1a;表示文本序列的最大长度&…

AI大模型-机器学习中的集成学习

机器学习中的集成学习 集成学习概述及主要研究领域 1.1 集成学习概述&#x1f4a5; “众人拾柴火焰高”、“三个臭皮匠顶个诸葛亮”等词语都在表明着群体智慧的力量&#xff0c;所谓的“群体智慧”指的就是一群对某个主题具有平均知识的人集中在一起可以对某一些问题提供出更…

觅瑞集团两年亏损9亿:现金流承压营销成本近亿,应收账款周期过长

《港湾商业观察》黄懿 4月30日&#xff0c;Mirxes Holding Company Limited&#xff08;下称“觅瑞集团”&#xff09;递表港交所&#xff0c;拟在香港主板挂牌上市&#xff0c;中金和建银国际为联席保荐人&#xff0c;这是继2023年7月25日递表失效后的再一次申请。觅瑞集团国…

记录vue一个echarts页面 柱状图加平均分横线 双柱状图 横向双柱状图

<template><div class"app-container"><el-form :model"queryParams" ref"queryForm" size"small" v-show"showSearch" label-width"85px"><el-form-item label"园所名称" prop&q…

【Vue】智慧商城

步骤一般都是&#xff1a; 静态结构 > 封装接口 > 路由获取参数 > 获取数据 动态渲染 先封装接口再路由获取参数的原因是因为&#xff0c;只有先封装好了接口&#xff0c;才能知道我们需要哪些参数 接口文档&#xff1a;https://apifox.com/apidoc/shared-12ab6b18-a…

LabVIEW结构体内部缺陷振动检测

结构体内部缺陷会改变其振动特性&#xff0c;通过振动分析可以检测并定位这些缺陷。本文详细分析内部缺陷对振动的影响&#xff0c;从频谱分析、时域分析和模态分析等多角度探讨基于LabVIEW的检测方法&#xff0c;提供实施步骤和注意事项&#xff0c;帮助工程师有效利用LabVIEW…

安全生产信息化平台:高效构建安全台账管理体系

随着科技的飞速发展&#xff0c;信息化已成为推动企业安全生产管理的重要手段。传统的安全台账管理方式&#xff0c;涉及记录、整理、汇编等多个繁琐环节&#xff0c;不仅耗时费力&#xff0c;而且在查找和检索时也不便。安全生产信息化平台的出现&#xff0c;为企业提供了全新…

【Linux】线程(附源码)

目录 1.线程概述 2.创建线程 3.线程退出 4.线程回收 5.线程分离 1.线程概述 线程是轻量级的进程&#xff08;LWP&#xff1a;light weight process&#xff09;&#xff0c;在Linux环境下线程的本质仍是进程。在计算机上运行的程序是一组指令及指令参数的组合&#xff0c;…