热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

openvslam(33)文件结构全局优化模块(globaloptimizationmodule):回环检测、posegraph优化、globalBA优化

博客地址https:blog.csdn.netu011341856articledetails109491058 这篇博客主要介绍OpenVSLAM的全局优化模块(global_o

博客地址

https://blog.csdn.net/u011341856/article/details/109491058

 

这篇博客主要介绍OpenVSLAM的全局优化模块(global_optimization_module),该模块是单独运行在一个线程中的。

它主要执行的工作是:SLAM的回环检测,以及回环成功之后的回环矫正,还包括紧随着回环检测成功之后的pose graph优化和全局的BA优化。

 


1.全局优化模块入口

 类的定义

 

 

 测试样例

 

说是全局优化模块,其实也就是一个普通的类。对于类,第一步肯定就是实例化构造对象,全局优化模块的实例化过程是在system.cc代码中的system的构造函数处,对应的代码的如下:

global_optimizer_ = new global_optimization_module(map_db_, bow_db_, bow_vocab_,
camera_->setup_type_ != camera::setup_type_t::Monocular);

可见全局优化模块和其它模块共用的数据包括

map_db_(地图的数据库)、

bow_db_(词袋数据库)、

bow_vocab_(词袋模型),

最后一个参数来控制优化时是否优化尺度(scale),

对于单目由于存在尺度漂移,所以需要优化尺度。

至此,全局优化模块构造完成。

另外由于它需要在一个独立的线程中运行,所以还需要新建一个线程,将该对象中的代码运行在这个线程中。

新建线程的代码在system.cc文件中的system::startup()函数中,对应的代码如下:

global_optimization_thread_ = std::unique_ptr(new std::thread(&openvslam::global_optimization_module::run, global_optimizer_));

 注意std::thread运行对象中函数的用法!


2.全局优化模块线程在干啥?

经过简单地配置,全局优化线程就欢脱的跑起来了,现在就让我们来看看它都具体干了啥?首先祭出一张流程图:

 

 

 

全局优化线程是一个死循环,只要程序正常运行,它将不停地在做同样的重复性工作,好无聊啊!

(1)首先,先检查一下SLAM的状态,确保没有收到SLAM要暂停、停止或者重启的命令!

这里命令的发出主要是通过显示模块中在pangolin的窗口上的那几个按钮!

(2)从关键帧队列中(keyfrms_queue_),取出最前面的一帧关键帧。如果关键帧队列中啥东西都没有,那怎么办呢?哎,这一趟循环了个屁,重新循环吧!心累

keyfrms_queue_这个成员变量主要用来存储关键帧,用于回环检测。其中关键帧数据主要是来自建图模块(mapping_module)的输入,只要建图模块成功的生成了一个关键帧,那么就将关键帧放入这个队列。

(3)将队列中取出来的这一个关键帧,与地图数据集中的所有关键帧进行比较,找到和自己的相似的关键帧,将其作为备选的回环关键帧。

如果找到了(闭环了),那就继续往下执行,全局优化

没有找到的话(没有闭环),又是一个无用的循环,那就回到开始,重新下一次循环吧!

这一步对应的函数是loop_detector::detect_loop_candidates(),这是一个重要的函数,下面的内容单独讲解这个函数。

(4)检测到了一些和自己相似的回环候选帧之后,需要验证这些候选关键帧是不是确实是一个真正的回环。

如果经过验证这些候选回环关键帧中没有真正的回环帧,那么这次循环就结束了,重新循环!

这一步对应的函数loop_detector::validate_candidates(),它也是一个重要的函数,后面会专门介绍。

(5)经过验证之后,确实是一个成功的回环,那么就需要执行回环矫正!

这一步对应的函数global_optimization_module::correct_loop(),这个函数后面介绍!

以上步骤中,一共出现了三个很重要的函数:



  • loop_detector::detect_loop_candidates()

  • loop_detector::validate_candidates()

  • global_optimization_module::correct_loop()

 

接下来我们一个一个去学习


2.1 检测回环候选帧

 

首先来看第一个函数loop_detector::detect_loop_candidates(),它主要是用来进行回环候选帧的检测,经过它的检测之后,可以获得很多的回环候选帧,这些候选帧中也许有真正的回环帧,也许没有!让我们来看看它都做了啥?首先祭出它的流程图:

 

 

 

让我向你具体介绍它都做了啥吧!

(1)首先,检测是否开启回环检测功能,另外如果距离上一次回环检测成功还没有超过10个关键帧,那就先不要进行回环检测,不然的话太频繁了,也不符合实际情况!如果不满足这两个条件,那就退出这个函数!

你可以想象一下,刚做完回环检测,你又回到原地的情况应该还是比较少见的吧!

 

(2)根据共视关系计算回环检测的最小评分。可以想象一下,如果拿着当前帧到地图数据库中去找和我比较相似的,那怎么判断拿个和我算比较相似,那个算比较不相似呢?如果设置的阈值过高可能错过了回环,如果阈值过低可能会检测到很多候选帧。于是作者这里的策略是把当前帧的共视关键帧取出来,以此作为判断依据,将共视关键帧中和自己bow评分最低的那个得分最为评判回环候选帧的阈值。

这一步操作对应的函数是loop_detector::compute_min_score_in_covisibilities()。这一点你是可以想象的,既然是回环帧,那至少和我们看起来还是比较相似的,至于取用共视关键帧中的最低评分,我估计作者是做了大量的实验之后,得出来的一个经验做法!
(3)根据上一步计算出来的评分,去地图数据库进行查找,那些只要和当前帧相似评分大于这个最低阈值的关键帧,都将作为回环候选帧取出来。

(4)如果没有得到任何的回环候选帧,那么结束当前函数。

(5)将每一个回环候选帧以及这个候选帧对应的所有共视关键帧打包组成一个集合(类似于下图虚线框起来的那样),以备后用。注意,这里其实有一个连续性检测条件,也就是算法认为,如果确实是一个真正的回环,那么应该是可以连续被检测到的,不可能上次检测到,这一次检测不到了。

这个理解起来还是比较难的,我通过一张向你解释一下这个过程吧!

 

 

 

上图中的三角形和圆形都是关键帧,为了以示区分我把它画成关键帧加共视关键帧组合的形式(图中虚线框起来的那样)。红色的三角形是当前的关键帧,它经过回环候选帧检测之后,获得了上图所示的四个虚线框组成的组合。连续性检测认为,如果下一次再进行回环候选帧检测,检测出来的组合和上一次检测出来的组合没有交集,那么它们就都不是可能的候选回环帧。例如,上图是本次的回环候选帧检测结果,下一次检测得到的回环候选帧组合与当前检测结果没有相交(所谓的相交,就是虚线框中这样的组合之间是否有公共的关键帧),则这两次结果里都不存在回环候选帧。
你品,你细品! 

 

(6)如果打包的关键帧集合连续被观测到三次,也就是说当前观测组成的回环帧集合,下一次又被检测到,总共被检测到三次,那么这个回环候选关键帧很可能是真正的回环帧,将其记录下来。

注意,如果连续性检测某一次失败了,那么之前累计的连续性结果也都归零,重新开始新的连续性检测。

通过以上算法之后,可能会获得很多回环候选帧,下一步就需要进行验证到底是不是真的回环!

 


2.2 验证回环候选帧

经过检测现在已经获得了很多回环候选帧,loop_detector::validate_candidates()函数主要就是用来对回环候选帧中的关键帧做检验,找到其中真正的回环帧。它的原理主要是做几何校验,验证其是否满足投影关系。

废话不多说,首先祭出流程图:

 

 

(1)首先,对候选关键帧与当前关键帧进行Sim3变换的几何校验。找到满足投影关系的回环候选关键帧。这一步对应的函数是:loop_detector::select_loop_candidate_via_Sim3()它的主要算法过程如下:



  • 通过bow加速搜索,获得候选关键帧与当前关键帧的匹配特征点;

  • 如果匹配的特征点少于20个,则说明当前候选关键帧不是一个好的候选关键帧,结束当前循环,进行下一次循环;

  • 根据搜索出来的匹配特征点对,求解当前关键帧到候选关键帧的Sim3变换,内点数量小于20,则认为不是一个好的候选帧;

  • 通过计算出来的Sim3变换,将两个关键帧对应的地图点相互向对方关键帧投影,获得更多的匹配关系;

  • 对获得的匹配关系进行优化,获得更加准确的结果;

  • 如果最终得到的内点数量大于20个,则认为当前候选关键帧是一个真正的回环帧,否则进行下一次循环,对下一个候选帧执行上述步骤。

 

(2)对上一步找到的回环帧,取出它的所有共视关键帧,以及共视关键帧赌赢的地图点。
(3)将上一步获得的地图点,全部向当前关键帧进行投影,获得更多的匹配关系,然后再重新计算一次Sim3变换,如果最终的匹配点对数量大于40个,则又进一步印证了当前检测出来的回环帧确实是一个回环帧。

经过上面的回环帧验证之后,我们获得的回环帧,也确实是一个真正的、可靠的回环帧了,下面该要执行的就是通过这个回环帧去消除掉累计误差了!

 

2.3 进行回环矫正
回环矫正对应的函数是:global_optimization_module::correct_loop()。它其中有一些细节还是比较难的,你可能需要关注一下它是怎么处理那些重复的关键帧,以及重复的地图点,怎么构建一个pose graph优化!

废话不多说,继续祭出我亲手画的流程图:

 

 

 

 

(1)首先,将我们辛辛苦苦取得的回环帧取出来,它可是咱们的宝贝啊,千呼万唤才弄出来的。
(2)如果目前系统中还正有一个回环全局优化在执行,就关闭它。毕竟又出现了新的回环帧之后,前面的累计误差可以消除,在此之前的别的回环优化都是浪费。
(3)确保mapp_module模块已经暂停。
(4)更新一下当前关键帧的连接关系,包括共视关系、权重等等。
(5)将当前关键帧以及它的共视关键帧,通过之前就算出来的Sim3变换进行位姿修正,并且也要将地图点也修正到它本该在的地方。
(6)替换当前关键帧以及共视关键帧和回环关键帧以及共视关键帧重复的地图点。

 你可以想象一下,既然是回环成功了,那肯定说明相机回到了以前出现过的地方,那么它们必然看到一样的地图点,但是由于存在累计误差,同样的地图点却出现了不同的坐标,所以是不是应该需要删除这些重复的地图点呢?如果当前帧和回环帧有共同的地图点,用回环帧中的地图点替换当前帧的地图点。而对于

 



推荐阅读
  • binlog2sql,你该知道的数据恢复工具
    binlog2sql,你该知道的数据恢复工具 ... [详细]
  • 尽管在WPF中工作了一段时间,但在菜单控件的样式设置上遇到了一些基础问题,特别是关于如何正确配置前景色和背景色。 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • 题目描述:计算从起点到终点的最小能量消耗。如果下一个单元格的风向与当前单元格相同,则消耗为0,否则为1。共有8个可能的方向。 ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
  • 解决ADODB连接Access时出现80004005错误的方法
    本文详细介绍了如何解决在使用ADODB连接Access数据库时遇到的80004005错误,包括错误原因分析和具体的解决步骤。 ... [详细]
  • 本文详细介绍了 Redis 中的主要数据类型,包括 String、Hash、List、Set、ZSet、Geo 和 HyperLogLog,并提供了每种类型的基本操作命令和应用场景。 ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • Fiddler 安装与配置指南
    本文详细介绍了Fiddler的安装步骤及配置方法,旨在帮助用户顺利抓取用户Token。文章还涵盖了一些常见问题的解决方案,以确保安装过程顺利。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 在尝试加载支持推送通知的iOS应用程序的Ad Hoc构建时,遇到了‘no valid aps-environment entitlement found for application’的错误提示。本文将探讨此错误的原因及多种可能的解决方案。 ... [详细]
  • 问题描述现在,不管开发一个多大的系统(至少我现在的部门是这样的),都会带一个日志功能;在实际开发过程中 ... [详细]
  • 知识图谱与图神经网络在金融科技中的应用探讨
    本文详细介绍了融慧金科AI Lab负责人张凯博士在2020爱分析·中国人工智能高峰论坛上的演讲,探讨了知识图谱与图神经网络模型如何在金融科技领域发挥重要作用。 ... [详细]
  • 入门指南:使用FastRPC技术连接Qualcomm Hexagon DSP
    本文旨在为初学者提供关于如何使用FastRPC技术连接Qualcomm Hexagon DSP的基础知识。FastRPC技术允许开发者在本地客户端实现远程调用,从而简化Hexagon DSP的开发和调试过程。 ... [详细]
  • 电商高并发解决方案详解
    本文以京东为例,详细探讨了电商中常见的高并发解决方案,包括多级缓存和Nginx限流技术,旨在帮助读者更好地理解和应用这些技术。 ... [详细]
author-avatar
上海外国灬语大学-校友粉丝团
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有