视觉SLAM笔记(57) 回环检测


1. 回环检测的意义

前端提供特征点的提取和轨迹、地图的初值
而后端负责对这所有的数据进行优化

然而,如果像 VO 那样仅考虑相邻时间上的关联
那么,之前产生的误差将不可避免地累计到下一个时刻,使得整个 SLAM 会出现累积误差
长期估计的结果将不可靠,或者说,无法构建全局一致的轨迹和地图

举例来说,假设在前端提取了特征,然后忽略掉特征点,在后端使用 Pose Graph 优化整个轨迹如图(a)

在这里插入图片描述
由于前端给出的只是局部的位姿间约束,比方说,可能是 x1 − x2, x2 − x3 等等
但是,由于 x1 的估计存在误差,而 x2 是根据 x1 决定的, x3又是由 x2 决定的
以此类推,误差就会被累积起来,使得后端优化的结果如图 (b),慢慢地趋向不准确

虽然后端能够估计最大后验误差,但所谓“好模型架不住烂数据”
只有相邻关键帧数据时,我们能做的事情并不很多,也无从消除累积误差

但是,回环检测模块,能够给出除了相邻帧之外的,一些时隔更加久远的约束:
例如 x1 − x100 之间的位姿变换,为什么它们之间会有约束呢?
这是因为察觉到相机经过了同一个地方, 采集到了相似的数据
而回环检测的关键,就是如何有效地检测出相机经过同一个地方这件事
如果能够成功地检测这件事,就可以为后端的 Pose Graph 提供更多的有效数据,使之得到更好的估计
特别是得到一个全局一致(Global Consistent)的估计
由于 Pose Graph 可以看成一个质点——弹簧系统
所以回环检测相当于在图像中加入了额外的弹簧,提高了系统稳定性
亦可直观地想象成回环边把带有累计误差的边“拉”到了正确的位置——如果回环本身是正确的话

回环检测对于 SLAM 系统意义重大
它关系到估计的轨迹和地图在长时间下的正确性
另一方面,由于回环检测提供了当前数据与所有历史数据的关联
在跟踪算法丢失之后,还可以利用回环检测进行 重定位
因此,回环检测对整个 SLAM 系统精度与鲁棒性的提升,是非常明显的
甚至在某些时候,把仅有前端和局部后端的系统称为VO,而把带有回环检测和全局后端的称为 SLAM


2. 实现方法

简单的方式就是对任意两张图像都做一遍特征匹配,根据正确匹配的数量确定哪两个图像存在关联
这确实是一种朴素且有效的思想
缺点在于,盲目地假设了“任意两个图像都可能存在回环”,使得要检测的数量实在太大:
对于 N 个可能的回环,要检测 C2N 那么多次,这是 O(N2) 的复杂度
随着轨迹变长增长太快,在大多数实时系统当中是不实用的

另一种朴素的方式是,随机抽取历史数据并进行回环检测,比如说在 n 帧当中随机抽 5 帧与当前帧比较
这种做法能够维持常数时间的运算量
但是这种盲目试探方法在帧数 N 增长时,抽到回环的几率又大幅下降,使得检测效率不高
上面说的朴素思路都过于粗糙

尽管随机检测在有些实现中确实有用
但至少希望有一个“哪处可能出现回环”的预计,才好不那么盲目地去检测
这样的方式大体分为两种思路:

  1. 基于里程计的几何关系(Odometry based)
  2. 基于外观(Appearance based)

基于几何关系是说,当发现当前相机运动到了之前的某个位置附近时,检测它们有没有回环关系
这自然是一种直观的想法
但是由于累积误差的存在,往往没法正确地发现“运动到了之前的某个位置附近”这件事实
回环检测也无从谈起

因此,这种做法在逻辑上存在一点问题
因为回环检测的目标在于发现“相机回到之前位置”的事实,从而消除累计误差
而基于几何关系的做法假设了“相机回到之前位置附近”,才能检测回环
这是有倒果为因的嫌疑的,因而也无法在累计误差较大时工作

另一种方法是基于外观的
它和前端后端的估计都无关,仅根据两张图像的相似性确定回环检测关系
这种做法摆脱了累计误差,使回环检测模块成为 SLAM 系统中一个相对独立的模块
当然前端可以为它提供特征点
自 21 世纪初被提出以来,基于外观的回环检测方式能够有效地在不同场景下工作
成为了视觉 SLAM 中主流的做法,并被应用于实际的系统中

在基于外观的回环检测算法中,核心问题是 如何计算图像间的相似性
比如对于图像 A 和图像 B,要设计一种方法,计算它们之间的相似性评分: s(A, B)
当然这个评分会在某个区间内取值,当它大于一定量后认为出现了一个回环

可能会有疑问:
计算两个图像之间的相似性很困难吗?
例如直观上看,图像能够表示成矩阵,那么直接让两个图像相减,然后取某种范数行不行呢:
在这里插入图片描述

为什么不这样做?

  1. 首先,前面也说过,像素灰度是一种不稳定的测量值,它严重受环境光照和相机曝光的影响
    假设相机未动,打开了一支电灯,那么图像会整体变亮一些
    这样,即使对于同样的数据,都会得到一个很大的差异值
  2. 另一方面,当相机视角发生少量变化时,即使每个物体的光度不变,它们的像素也会在图像中发生位移,造成一个很大的差异值

由于这两种情况的存在,实际当中,即使对于非常相似的图像, A − B 也会经常得到一个(不符合实际的)很大的值
所以说,这个函数 不能很好的反映图像间的相似关系

这里牵涉到一个“好”和“不好”的定义问题
要问,怎样的函数能够更好地反映相似关系,而怎样的函数不够好呢?
从这里可以引出感知偏差(Perceptual Aliasing)和感知变异(Perceptual Variability)两个概念
现在来更详细地讨论一下


3. 准确率和召回率

从人类的角度看,(至少自认为)能够以很高的精确度
感觉到“两张图像是否相似”或“这两张照片是从同一个地方拍摄的”这件事实
但由于目前尚未知道人脑的工作原理,无法清楚地描述自己是如何完成这件事的
在这里插入图片描述
从程序角度看,希望程序算法能够得出和人类,或者和事实一致的判断
当觉得,或者事实上就是,两张图像从同一个地方拍摄
那么回环检测算法也应该给出“这是回环”的结果

反之,如果觉得,或事实上是,两张图像是从不同地方拍摄的
那么程序也应该给出“这不是回环”的判断
当然,程序的判断并不总是与人类想法一致,所以可能出现下表中的四种情况:

在这里插入图片描述

这里阴性/阳性的说法是借用了医学上的说法
假阳性(False Positive)又称为感知偏差,而假阴性(False Negative)称为感知变异
为方便书写,记缩写 TP 为 True Positive,其余类推

由于希望算法和人类的判断一致,所以希望 TP 和 TN 要尽量的高,而 FP 和 FN 要尽可能的低
所以,对于某种特定算法,可以统计它在某个数据集上的 TP、TN、 FP、 FN 的出现次数
并计算两个统计量: 准确率召回率(Precision & Recall)

在这里插入图片描述

从公式字面意义上来看,准确率描述的是,算法提取的所有回环中,确实是真实回环的概率
而召回率则是说,在所有真实回环中,被正确检测出来的概率
这两个统计量有一定的代表性,并且通常来说是一个矛盾
在这里插入图片描述

一个算法往往有许多的设置参数

比方说,当提高某个阈值时,算法可能变得更加“严格”——它检出更少的回环,使准确率得以提高
但同时,由于检出的数量变少了,许多原本是回环的地方就可能被漏掉了,导致召回率的下降

反之,如果选择更加宽松的配置,那么检出的回环数量将增加,得到更高的召回率
但其中可能混杂了一些不是回环的情况,于是准确率下降了

为了评价算法的好坏,会测试它在各种配置下的 P 和 R 值,然后做出一条 Precision-Recall 曲线
当用召回率为横轴,用准确率为纵轴时,会关心整条曲线偏向右上方的程度、 100% 准确率下的召回率,或者 50% 召回率时候的准确率,作为评价算法的指标

不过请注意,除去一些“天壤之别”的算法,通常不能一概而论算法 A 就是优于算法 B 的
可能说 A 在准确率较高时还有很好的召回率
而 B 在 70% 召回率的情况下还能保证较好的准确率,诸如此类的评价

值得一提的是,在 SLAM 中,对准确率要求更高,而对召回率则相对宽容一些
由于假阳性的(检测结果是而实际不是的)回环将在后端的 Pose Graph 中添加根本错误的边
有些时候会导致优化算法给出完全错误的结果

想象一下,如果 SLAM 程序错误地将所有的办公桌当成了同一张,那建出来的图会怎么样
可能会看到走廓不直了,墙壁被交错在一起了,最后整个地图都失效了

而相比之下,召回率低一些,则顶多有部分的回环没有被检测到,地图可能受一些累积误差的影响
然而仅需一两次回环就可以完全消除它们了
所以说在选择回环检测算法时,更倾向于把参数设置地更严格一些,或者在检测之后再加上回环验证的步骤

那么,回到之前的问题,为什么不用 A − B 来计算相似性呢?
会发现它的准确率和召回率都很差,可能出现大量的 False Positive 或 False Negative 的情况
所以说这样做“不好”
那么,什么方法更好一些呢?


4. 词袋模型

既然直接用两张图像相减的方式不够好,那么需要一种更加可靠的方式
结合前面的内容,一种直观的思路是:为何不像 VO 那样特征点来做回环检测呢?
和 VO 一样,对两个图像的特征点进行匹配,只要匹配数量大于一定值,就认为出现了回环
进一步,根据特征点匹配,还能计算出这两张图像之间的运动关系
当然这种做法会存在一些问题,例如特征的匹配会比较费时、当光照变化时特征描述可能不稳定等
但离要介绍的词袋模型已经很相近了

先来讲词袋的做法,再来讨论数据结构之类的实现细节
词袋,也就是 Bag-of-Words(BoW),目的是 用“图像上有哪几种特征”来描述一个图像

例如,如果某个照片,说里面有一个人、一辆车
而另一张则有两个人、一只狗
根据这样的描述,可以度量这两个图像的相似性
再具体一些,要做以下几件事:

  1. 确定“人、车、狗”等概念
    对应于 BoW 中的 “单词”(Word),许多单词放在一起,组成了 “字典”(Dictionary)
  2. 确定一张图像中,出现了哪些在字典中定义的概念
    用单词出现的情况(或直方图)描述整张图像,这就把一个图像转换成了一个向量的描述
  3. 比较上一步中的描述的相似程度

以上面举的例子来说,首先通过某种方式,得到了一本“字典”
字典上记录了许多单词,每个单词都有一定意义,例如“人”、“车”、“狗”都是记录在字典中的单词
不妨记为 w1, w2, w3
然后,对于任意图像 A,根据它们含有的单词,可记为:
在这里插入图片描述
字典是固定的,所以只要用 [1, 1, 0]T 这个向量就可以表达 A 的意义
通过字典和单词,只需一个向量就可以描述整张图像了
该向量描述的是“图像是否含有某类特征”的信息,比单纯的灰度值更加稳定
又因为描述向量说的是“是否出现”,而不管它们“在哪儿出现”
所以与物体的空间位置和排列顺序无关
因此在相机发生少量运动时,只要物体仍在视野中出现
就仍然保证描述向量不发生变化
基于这种特性,称它为 Bag-of-Words 而不是什么 List-of-Words
强调的是 Words 的有无,而无关其顺序

因此,可以说字典类似于单词的一个集合
回到上面的例子,同理,用 [2, 0, 1]T 可以描述图像 B
如果只考虑“是否出现”而不考虑数量的话,也可以是 [1, 0, 1]T,这时候这个向量就是二值的
于是,根据这两个向量,设计一定的计算方式,就能确定图像间的相似性了

当然如果对两个向量求差仍然有一些不同的做法
比如说对于 a, b \in RW,可以计算:
在这里插入图片描述
其中范数取 L1 范数,即各元素绝对值之和

请注意在两个向量完全一样时,将得到 1,完全相反时(a 为 0 的地方 b 为 1)得到 0
这样就定义了两个描述向量的相似性,也就定义了图像之间的相似程度


参考:

《视觉SLAM十四讲》


相关推荐:

视觉SLAM笔记(56) 位姿图优化
视觉SLAM笔记(55) 位姿图
视觉SLAM笔记(54) Ceres 操作后端优化
视觉SLAM笔记(53) g2o 操作后端优化
视觉SLAM笔记(52) BA 与图优化


谢谢!

发布了217 篇原创文章 · 获赞 290 · 访问量 288万+

猜你喜欢

转载自blog.csdn.net/qq_32618327/article/details/103106441