什么是回环检测?

在讲解回环检测前,我们先来了解下回环的概念。在视觉SLAM问题中,位姿的估计往往是一个递推的过程,即由上一帧位姿解算当前帧位姿,因此其中的误差便这样一帧一帧的传递下去,也就是我们所说的累计误差。

我们的位姿约束都是与上一帧建立的,第五帧的位姿误差中便已经积累了前面四个约束中的误差。但如果我们发现第五帧位姿不一定要由第四帧推出来,还可以由第二帧推算出来,显然这样计算误差会小很多,因为只存在两个约束的误差了。像这样与之前的某一帧建立位姿约束关系就叫做回环。回环通过减少约束数,起到了减小累计误差的作用。

那么我们怎么知道可以由第二帧推算第五帧位姿呢?也许第一帧、第三帧也可以呢。确实,我们之所以用前一帧递推下一帧位姿,因为这两帧足够近,肯定可以建立两帧的约束,但是距离较远的两帧就不一定可以建立这样的约束关系了。找出可以建立这种位姿约束的历史帧,就是回环检测。

回环检测的意义

有了前端的视觉里程计及后端优化的SLAM系统,似乎已经比较好用了。但其在提高实时性的同时精度却降低了,一旦精度降低,又会面临长时间累计误差的问题,特别是像ORB-SLAM那样只做局部地图优化的方案。我们该如何平衡这个矛盾呢?

我们不妨先思考下,在一个陌生的环境中,我们人类是如何进行环境地图的建立?在局部区域,人不断的移动从而在脑海中建造增量式地图,时间长了大部分人也分不清东南西北了,与起始点的关系又如何。假如人正巧回到了之前路过的位置,在对环境足够敏感的情况下,他就能发现这个事实,从而修正自己之前对方位的判断。我们说,此时检测到了一个回环,显然,人可以通过面前看到的景象与脑海中残缺的印象来对比从而检测到回环的,对于SLAM来说也可以通过对比当前帧与过去关键帧的相似度,如相似度超过某一阀值时就可以被认为是检测到回环。

现在,问题的关键就在于如何判断两帧图片的相似度。最直观的做法是特征匹配,比较匹配的数量是否足够多。但由于特征匹配非常耗时,回环检测需要与过去所有关键帧匹配,这个运算量是绝对无法承受的。因此,有人提出了词袋模型,用来加速特征匹配。

什么是词袋模型?

词袋模型就是把特征看成是一个个单词,通过比较两张图片中单词的一致性,来判断两张图片是否属于同一场景。

为了能够把特征归类为单词,我们需要训练一个字典。所谓的字典就是包含了所有可能的单词的集合,为了提高通用性,需要使用海量的数据训练。

字典的训练其实是一个聚类的过程。假设所有图片中共提取了10,000,000个特征,可以使用K-means方法把它们聚成100,000个单词。但是,如果只是用这100,000个单词来匹配的话效率还是太低,因为每个特征需要比较100,000次才能找到自己对应的单词。为了提高效率,字典在训练的过程中构建了一个k个分支,深度为d的树,如下图所示。直观上看,上层结点提供了粗分类,下层结点提供了细分类,直到叶子结点。利用这个树,就可以将时间复杂度降低到对数级别,大大加速了特征匹配。

使用DBoW3库训练及使用词典

DBoW3库为我们提供了非常方便的训练词典和使用词典的方法。

训练词典时,只需要把所有训练用的图片的描述符传给DBoW3::Vocabulary的create方法就可以了。训练好的词袋模型保存在vocabulary.yml.gz文件中。

 

接下来,使用训练好的词袋模型对图片计算相似性评分。DBoW3为我们提供了两种计算相似性的方式,第一种是直接对两张图片比较;第二种是把图片集构造成一个数据库,再与另一张图片比较。

可以看出,图片越相似,评分越接近1。我们可以根据这个评分来判断两张图片是否是同一场景。但是直接给定一个绝对的阈值并不合适。通常,如果当前帧与之前某帧的相似度超过当前帧与上一个关键帧相似度的3倍,就认为可能存在回环。不过,这种做法要求关键帧之间的相似性不能太高,否则无法检测出回环。

浅谈SLAM的回环检测技术的更多相关文章

  1. segMatch:基于3D点云分割的回环检测

    该论文的地址是:https://arxiv.org/pdf/1609.07720.pdf segmatch是一个提供车辆的回环检测的技术,使用提取和匹配分割的三维激光点云技术.分割的例子可以在下面的图 ...

  2. ​综述 | SLAM回环检测方法

    本文作者任旭倩,公众号:计算机视觉life成员,由于格式原因,公式显示可能出问题,建议阅读原文链接:综述 | SLAM回环检测方法 在视觉SLAM问题中,位姿的估计往往是一个递推的过程,即由上一帧位姿 ...

  3. 一个基于深度学习回环检测模块的简单双目 SLAM 系统

    转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12634631.html 写在前面 最近在搞本科毕设,关于基于深度学 ...

  4. ORB-SLAM(六)回环检测

    上一篇提到,无论在单目.双目还是RGBD中,追踪得到的位姿都是有误差的.随着路径的不断延伸,前面帧的误差会一直传递到后面去,导致最后一帧的位姿在世界坐标系里的误差有可能非常大.除了利用优化方法在局部和 ...

  5. DLoopDetector回环检测算法

    词袋模型是一种文本表征方法,它应用到计算机视觉领域就称之为BoF(bag of features),通过BoF可以把一张图片表示成一个向量.DBoW2是一个视觉词袋库,它提供了生成和使用词典的接口,但 ...

  6. 【C++】链表回环检测

    //链表回环检测问题 #include<iostream> #include<cstdlib> using namespace std; ; struct node { int ...

  7. Code Reading: ORB-SLAM回环检测源码阅读+注释

    之前研究过一些回环检测的内容,首先要看的自然是用词袋回环的鼻祖和正当继承人(没有冒犯VINS和LDSO的意思)ORB-SLAM.下面是我的代码注释.因为代码都是自己手打的,不是在源码上注释的,所以一些 ...

  8. 浅谈C++ 内存泄漏及其检测工具

    浅谈C++ 内存泄漏及其检测工具 http://wenku.baidu.com/link?url=1DGkOOvd_ITZyB8IHAwfhCOx2tfO6id8UfuyQkAMHZU6sasaAXz ...

  9. VINS 回环检测与全局优化

    回环检测 VINS回环检测与全局优化都在pose_graph.cpp内处理.首先在pose_graph_node加载vocabulary文件给BriefDatabase用,如果要加载地图,会loadP ...

随机推荐

  1. Springboot-读取核心配置文件及自定义配置文件

    读取核心配置文件 核心配置文件是指在resources根目录下的application.properties或application.yml配置文件,读取这两个配置文件的方法有两种,都比较简单. 核心 ...

  2. windows编程之内核对象

          学好windows编程,理解内核对象还是至关重要的(●'◡'●).闲话不多说,下面先来了解一下关于内核对象的知识:       内核对象(kernel object):内核对象是用于管理进 ...

  3. java 将一个数组中的值按逆序重新存放,例如,原来顺序为:9,5,7,4,8,要求改为:8,4,7, 5,9。

    public class Test3 { public static void main(String[] args) { int[] grade = {87,88,89,98,78}; int m; ...

  4. noi2729 Blah数集

    Blah数集 大数学家高斯小时候偶然间发现一种有趣的自然数集合Blah,对于以a为基的集合Ba定义如下: (1) a是集合Ba的基,且a是Ba的第一个元素: (2)如果x在集合Ba中,则2x+1和3x ...

  5. [JAVA] 小数转百分数

    import java.text.NumberFormat; //获取格式化对象 NumberFormat format = NumberFormat.getPercentInstance(); // ...

  6. 通过input上传图片,判断不同浏览器及图片类型和大小的js代码

    1.jsp页面代码 <form id="userPhoto" name="userPhoto" method="post" actio ...

  7. 2018年计科五班秋季C语言基础课第1次作业

    ---恢复内容开始--- 1.翻阅邹欣老师博客关于师生关系博客,并回答下列问题: (1)大学和高中最大的不同是没有人天天看着你,请看大学理想的师生关系是?有何感想? 答:我认为是邹欣老师说的健身教练 ...

  8. 3.3.7 跳表 SkipList

    一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下,ConcurrentHashMap 存取速度是ConcurrentSki ...

  9. CodeForces 342A Xenia and Divisors (水题)

    题意:给定 n 个数(小于等于7),让你把它分成 m 组,每组有三个数,且满足,a < b < c,并且 a 能整除 b,b 能整除 c. 析:对于这个题,因为题目说了是不大于7的,那么一 ...

  10. 常用的String方法Math方法

    Arrays.sort();冒泡排序字符串.charAt(i);字符串索引i上的字符Integer.prsent(字符串) 字符串转整数equals(Object anObject) 将此字符串与指定 ...