ORB-SLAM2 --- LoopClosing::Run 回环检测线程解析

news2024/11/22 23:07:38

目录

1.函数作用

2.code

3.函数解析 

3.1 查看是否有待处理的回环关键帧LoopClosing::CheckNewKeyFrames

3.2 检测闭环LoopClosing::DetectLoop 

3.3 计算当前关键帧和上一步闭环候选帧的Sim3变换

3.4  闭环矫正


1.函数作用

         回环检测,又称闭环检测,主要解决位置估计随时间漂移的问题。怎么解决呢?假设实际情况下相机经过一段时间的运动后回到了原点,但是由于漂移,它的位置估计值却没有回到原点。怎么办呢?如果有某种手段,让相机知道“回到了原点”这件事,或者把“原点”识别出来,我们再把位置估计值“拉”过去,就可以消除漂移了。这就是所谓的回环检测。

2.code

// 回环线程主函数
void LoopClosing::Run()
{
    mbFinished =false;

    // 线程主循环
    while(1)
    {
        // Loopclosing中的关键帧是LocalMapping发送过来的,LocalMapping是Tracking中发过来的
        // 在LocalMapping中通过 InsertKeyFrame 将关键帧插入闭环检测队列mlpLoopKeyFrameQueue
        // Step 1 查看闭环检测队列mlpLoopKeyFrameQueue中有没有关键帧进来
        if(CheckNewKeyFrames())
        {
            // Detect loop candidates and check covisibility consistency
            if(DetectLoop())
            {
               // Compute similarity transformation [sR|t]
               // In the stereo/RGBD case s=1
               if(ComputeSim3())
               {
                   // Perform loop fusion and pose graph optimization
                   CorrectLoop();
               }
            }
        }

        // 查看是否有外部线程请求复位当前线程
        ResetIfRequested();

        // 查看外部线程是否有终止当前线程的请求,如果有的话就跳出这个线程的主函数的主循环
        if(CheckFinish())
            break;

        //usleep(5000);
		std::this_thread::sleep_for(std::chrono::milliseconds(5));

	}

    // 运行到这里说明有外部线程请求终止当前线程,在这个函数中执行终止当前线程的一些操作
    SetFinish();
}

3.函数解析 

3.1 查看是否有待处理的回环关键帧LoopClosing::CheckNewKeyFrames

        回环检测线程要处理的关键帧是局部建图线程经过判断冗余关键帧判定传来的:

mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);

        关键帧存储在mlpLoopKeyFrameQueue这个队列中。

// 将某个关键帧加入到回环检测的过程中,由局部建图线程调用
void LoopClosing::InsertKeyFrame(KeyFrame *pKF)
{
    unique_lock<mutex> lock(mMutexLoopQueue);
    // 注意:这里第0个关键帧不能够参与到回环检测的过程中,因为第0关键帧定义了整个地图的世界坐标系
    if(pKF->mnId!=0)
        mlpLoopKeyFrameQueue.push_back(pKF);
}

        因此我们进入回环检测的第一件事就是检测队列mlpLoopKeyFrameQueue是否为空,若不为空从中抽取一帧一帧进行闭环检测。

        总结一下:Loopclosing线程中的待处理关键帧是LocalMapping线程发送过来的,LocalMapping线程中的待处理关键帧是Tracking线程中发过来的。LocalMapping线程中通过 InsertKeyFrame 将关键帧插入闭环检测队列mlpLoopKeyFrameQueue中。

/*
 * 查看列表中是否有等待被插入的关键帧
 * @return 如果存在,返回true
 */
bool LoopClosing::CheckNewKeyFrames()
{
    unique_lock<mutex> lock(mMutexLoopQueue);
    return(!mlpLoopKeyFrameQueue.empty());
}

3.2 检测闭环LoopClosing::DetectLoop 

        函数的主要作用是经过一系列筛选操作筛选出当前帧mpCurrentKF的闭环候选关键帧,并将闭环候选关键帧存储在容器mvpEnoughConsistentCandidates中供其他函数使用,更新连续组关系mvConsistentGroups。详解请参阅我的博客:

ORB-SLAM2 --- LoopClosing::DetectLoop 函数解析https://blog.csdn.net/qq_41694024/article/details/128572938

3.3 计算当前关键帧和上一步闭环候选帧的Sim3变换

        本函数分两步,先是对4.2节中的所有候选匹配关键帧mvpEnoughConsistentCandidates进行筛选,主要是对每个闭环候选关键帧与当前帧匹配特征点:

        ①进行BoW匹配初筛:

ORB-SLAM2 ---- ORBmatcher::SearchByBoW函数解析icon-default.png?t=MBR7https://blog.csdn.net/qq_41694024/article/details/126322962        ②通过sim3变换剔除一部分不满足要求的闭环候选帧,对于剩下的闭环候选关键帧,我们遍历每一个闭环候选帧进行Sim3Solver求解,得到候选帧pKF到当前帧mpCurrentKF的R(R12),t(t12),变换尺度s(s12),再通过SearchBySim3方法查找更多的匹配。

        剩余详解请参阅我的博客:ORB-SLAM2 --- LoopClosing::ComputeSim3 函数解析icon-default.png?t=MBR7https://blog.csdn.net/qq_41694024/article/details/128584438        

3.4  闭环矫正

        主要分五步:

        1. 通过求解的Sim3以及相对姿态关系,调整与当前帧相连的关键帧位姿以及这些关键帧观测到的地图点位置(相连关键帧---当前帧) 
        2. 将闭环帧以及闭环帧相连的关键帧的地图点和与当前帧相连的关键帧的点进行匹配(当前帧+相连关键帧---闭环帧+相连关键帧)     
        3. 通过MapPoints的匹配关系更新这些帧之间的连接关系,即更新covisibility graph                 4. 对Essential Graph(Pose Graph)进行优化,MapPoints的位置则根据优化后的位姿做相对应的调整                        
        5. 创建线程进行全局Bundle Adjustment
        具体详解请参阅我的博客:

ORB-SLAM2 --- LoopClosing::CorrectLoop函数解析icon-default.png?t=MBR7https://blog.csdn.net/qq_41694024/article/details/128592728

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

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

相关文章

文件操作和IO

一.文件的概念&#xff1a;狭义的文件指&#xff1a;硬盘上的文件和目录广义上的文件指&#xff1a;计算机中的很多软硬件资源路径&#xff1a;绝对路径&#xff1a;以c&#xff1a;d盘符开头的路径&#xff0c;比如c:/Intel/Logs/text.txt相对路径&#xff1a;以当前所在的目录…

Vue - 完美解决小数的四则运算(加减乘除)导致精度丢失问题,提供详细计算示例代码vue数据计算丢失精度

前言 由于 JavaScript 语言的问题,两个小数进行四则运算时,会出现各种问题,一些财务系统是必须要解决的。 本文实现了 完美修复小数计算时,计算错误、精度丢失等问题, 您可以进行任意小数的四则运算,都能保证结果是正确的。 如下图所示,使用了本文提供的方法后,可以形…

ArcGIS修改图斑时替换几何的妙用!不要只会整型要素

我们时常通过整型要素来修改要素的形状&#xff0c;但是有时候我们改变整个要素的形状、位置&#xff0c;还要保留属性不变&#xff0c;那我们就要考虑&#xff0c;高级编辑中的“替换几何”工具了。 01 替换几何原理 1 、“替换几何”工具可以为要素创建全新形状。“替换几何…

【Java】Properties类

文章目录01 初识Properties02 Properties常用方法03 Properties使用案例01 初识Properties 创建这样一个配置文件&#xff1a; 传统方法&#xff1a; public static void main(String[] args) throws IOException {//读取mysql.properties文件&#xff0c;并得到ip、user、pw…

Dubbo集群容错

Dubbo集群容错 1. 集群容错 集群调用失败时&#xff0c;Dubbo 提供的容错方案。 在集群调用失败时&#xff0c;Dubbo 提供了多种容错方案&#xff0c;缺省为 failover 重试。 各节点关系&#xff1a; 这里的 Invoker 是 Provider 的一个可调用 Service 的抽象&#xff0c;I…

n皇后(回溯)

著名的n皇后问题 即在棋盘上任意两个皇后不能在同一行&#xff0c;同一列&#xff0c;或者斜对角线&#xff0c;反斜对角线的位置 以判断&#xff08;5&#xff0c;1&#xff09;位置为例 往右下方&#xff08;斜对角线&#xff09;一连串的位置 &#xff08;5&#xff0c;1&…

Naive-UI自定义TabPane样式

前言前端开发通常使用 第三方 UI 组件库&#xff0c;像大家熟悉的 Element-UI、AntD Vue 等最近发现一个 还比较好用的 组件库 Naive-UI 传送门 &#xff0c;Vue 3 组件库&#xff0c;使用 TypeScript &#xff0c;用起来感觉还不错&#xff0c;它的主题也可以切换 &#xff08…

首款自研成像雷达发布!国产玩家赋能智能驾驶“第四类”感知

4D成像雷达赛道的“战火”正在不断升级。 高工智能汽车研究院预计&#xff0c;4D成像雷达将从2023年初开始小规模前装导入&#xff0c;预计到2024年&#xff0c;定点/搭载量有望突破百万颗&#xff0c;到2025年占全部前向毫米波雷达的比重或超过40%。 伴随着中国自动驾驶的渗…

Java多线程:多线程 Thread 类 中常用的方法的使用

Java多线程&#xff1a;多线程 Thread 类 中常用的方法的使用 每博一文案 日本有一位方丈曾在其寺庙的公告栏上写下一句标语&#xff1a; ”没有失败的人生才最失败。“ 深以为然&#xff0c;不上高山&#xff0c;不知平地&#xff0c;不经大海&#xff0c;不懂宽阔的涵义&…

很少人知道的7个极酷HTML元素

搜索很酷的HTML元素&#xff0c;尤其是当您不知道要查找什么时&#xff0c;通常就像被扔进一堆垃圾中一样动图别担心&#xff0c;我为你做了肮脏的工作&#xff01;在浏览了看似无穷无尽的HTML元素之后&#xff0c;我挖出了一些很少使用的宝石&#xff01;1. meter&progres…

多线程Monitor工作原理

&#x1f34e;1. 什么是Monitor?我们都知道synchronized的作用是用来保证修饰的代码或者方法执行有且只有一个线程执行&#xff0c;也就是锁。那么在执行被锁住的方式时&#xff0c;synchronized就需要通过monitor来记录和保证锁的状态。所以monitor这里的作用其实就是起到了控…

RFID固定资产管理系统实现批量“秒”级盘点

面对成千上万&#xff0c;乃至几十万的固定资产&#xff0c;如何能高效管理&#xff0c;做到管理无漏洞&#xff0c;盘点无错漏呢&#xff1f;很多企业和软件厂商都在考虑这个问题。现如今&#xff0c;随着物联网的发展&#xff0c;企业可批量实现固定资产的秒级盘点&#xff0…

【C++核心编程】C++全栈体系(十一)

C核心编程 第四章 类和对象 七、多态 1. 多态的基本概念 多态是C面向对象三大特性之一 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态&#xff0c;复用函数名动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别&#xff1a; 静态多态的函数…

打印机共享遇到的常见问题与解决方法

共享打印机提示错误0X000006d9 解决方法: 1、桌面找到计算机或此电脑,然后再图标上右键选择管理选项菜单; 2、在打开的计算机管理对话框中选择服务和应用程序选项; 3、双击服务和应用程序选项就会打开一个对话框,然后再选择服务菜单双击;

01-JDK、JRE、JVM之间的区别?

1.JDK JDK(Java SE Development Kit)&#xff0c;Java标准开发包&#xff0c;它提供了编译、运⾏Java程序所需的各种⼯具和资源&#xff0c;包括Java编译器、Java运⾏时环境&#xff0c;以及常⽤的Java类库等. JDK安装目录中真正在运行java时起作用的是 bin、include、lib、…

一网打尽链表的经典OJ题!链表必考笔试题第二弹

目录 0.前言 1.合并两个排序链表 1.1 实用小妙招 1.2代码书写 2.链表分割 3.链表的回文结构 4.相交链表 4.1 实用小妙招&#xff08;假定指针法&#xff09; 4.2代码书写 5. 复制带随机指针的链表 0.前言 本文代码及分析图片资源都以上传Gitee&#xff0c;可自取&a…

【Java数据结构】堆与优先级队列(堆)的详解

文章目录 目录 文章目录 一、优先级队列(堆) 1.1优先级队列的概念 二、优先级队列的模拟实现 2.1堆的概念 2.2堆的存储方式 2.3堆的创建 2.4建堆的时间复杂度 2.5堆的插入和删除 三.常用的PriorityQueue介绍 3.1PriorityQueue特性 3.2PriorityQueue常用方法 3.3oj练习 一、优…

CANoe-Model Editor介绍以及如何创建一个服务

Model Editor,模型编辑器,可以打开导入的ARXML文件,编辑现有的或定义新的应用层对象(CO、DO) 什么是CO和DO? Model Editor页面的整体布局为: 在左侧的子窗口中,你可以选择要编辑的内容根据你的选择,相应的内容将显示在右侧根据你在此处的选择,你可以使用其他拆分器来…

Vue--》Vue3的setup语法糖到底香不香?你来看看就知道了

目录 setup语法糖 创建Vue3项目 setup语法糖的使用 快速生成setup语法糖模板 setup语法糖新增的API useSlots()和useAttrs() 顶层await setup语法糖 相信在了解过这篇文章的 setup函数讲解 人会觉得Vue3处理数据变得繁琐了&#xff0c;所有的变量都必须return出来才能使…

8步,用python实现进行自动化评论、点赞、关注脚本

嗨害大家好鸭&#xff01; 我是小熊猫~ 分享这个没啥&#xff0c;就是好玩 这里写目录标题嗨害大家好鸭&#xff01; 我是小熊猫~开发环境代码实现点击此处跳转文末名片获取1.请求伪装2.获取关键词3. 获取作品评论ID采集4. 设置评论相应内容5. 设置点赞操作6. 设置关注操作7. 获…