在这里开一个单元用来讨论和记录 Visual SLAM 相关的知识点。
SLAM(Simultaneous Localization And Mapping)同时定位与地图构建,根据名称我们就能清晰的看出,SLAM主要是用来解决定位(我在什么地方?)和建图(我周围环境是什么样的?)这两个问题的。下面我们来详细讨论一下。
经典 Visual SLAM 框架
如下图所示,经典 Visual SLAM 是有五部分组成,分别是:传感器(信息获取)、前端(视觉里程计)、后端(非线性优化)、回环检测(降低误差)、建图(地图构建)
整个 Visual SLAM 的流程如下所示:
1、传感器获取信息:在 SLAM 传感器的作用就是获取周围信息,主要有雷达、相机两种传感器。在 Visual SLAM 中主要是对相机图像的读取和预处理。如果是机器人,我们还需要获取码盘、惯性传感器等信息的读取和同步。
2、前端视觉里程计(Visual Odometry, VO):获取到图像信息之后,就需要视觉里程计去分析估计相邻图像之间相机的运动以及局部地图。
3、后端(非线性)优化(Optimization):后端则是通过获取前端传来的相机位姿和回环检测的信息,对他们进行优化,从而得到贴近与实际的相机运动轨迹和地图信息。
4、回环检测(Loop Closure Detection):回环检测判断机器人之前是否到达过当前位置,如果检测到回环(到达过)就会向后端提供信息。
5、建图(Mapping):根据估计的轨迹、构建与任务要求对应的地图。
传感器
想要向人类一下感受到到周围环境,机器人就需要人类一样的”眼睛”,那么机器人的”眼睛”就是相机。现在市场上主流的相机包括:单目(Monocular)相机、双目(Stereo)相机、深度(RGB-D)相机三大类。同时还有全景相机、Event相机等特殊和新兴相机。
单目相机
单目相机,顾名思义就是只有用一个摄像头的相机,这种类型的相机结构简单、成本低廉。
单目相机的数据其实就是一张照片,本质上就是某个环境场景在平面上的投影,相当于将三维世界记录在一个二维世界之中,那么就丢掉了在视觉 SLAM 中一个非常重要的信息:深度(或者距离)。没有了距离,我们就无法通过一张招聘得到各个物体与相机之间的远近,就失去人类拥有的空间感、距离感。所以你也不能在单张图片中判断物体的真实大小,因为会出现近大远小和远大近小的透视关系。
所以想要知道知道物体的真实大小我们必须通过改变相机的视角来获取更多的图片,所以需要移动相机,才能估计相机的运动,同时估计环境中物体的大小和远近。因为我们知道:同一个环境下,远处的物体移动的慢,近处的物体移动的快,无穷远的物体几乎不移动。那么通过这种视差我们就知道了物体的远近关系了。
获取了物体的远近之后我们又将面临一个问题–尺寸大小。因为相片是将三维物体投影到二维空间之上,我们获取的是该物体等比例缩小的投影,并不能获取器真实大小。我们将图像等比例放大之后也许会获得该物体的近似大小。称这一比例就是尺度,所以单目 SLAM 是无法获取真实尺度的,所以是 尺度不确定性。
双目相机
双目相机其实本质上就是将两个单目相机根据已知的距离(基线)固定在一起,通过这种手段可以测量和计算出物体和相机之间的距离,克服了单目相机无法获取距离和尺度不确定性的问题,解决了这两个问题就能通过单张图片来恢复三维环境了。基线距离越大能够测量的深度范围就越远,所以它更适用于室外环境。但是双目乃至多目相机的配置和标定也是非常复杂的,同时想要计算其环境物体的深度和精度受双目的基线和分辨率显示,而且视差的计算是非常消耗计算资源的,需要使用 GPU 和 FPGA 设备进行加速,才能实时的输出整张图像的距离信息。
深度相机
深度相机其最大的特点是可以通过红外结构光或 Time-of-Fight(ToF)原理,向激光传感器那样,通过主动向周围环境的物体发射光并接收返回的光来计算物体与相机的距离。并不向双目相机那样通过软件大量计算,而是通过物理的测量手段,相比于双目相机,节省了大量的计算资源。但是 RGB-D 相机还存在测量范围窄、噪声大、视野小、易受日光干扰、无法测量投射材质等问题,主要应用于室内环境。
视觉里程计
视觉里程计关心相邻图像之间的相机运动。在计算机视觉领域,对于人类来说一件十分自然的事情,在计算机视觉当中确实非常困难的。图像在计算机里只有一个数值矩阵,这个矩阵里表达的什么意义,计算机是毫无概念的,而在视觉SLAM中,我们只能看到一个个像素,视觉里程计及能够通过相邻帧之间的图像估计出相机的运动,并回复场景的空间结构。称它为”里程计”是因为它和实际的里程计一样,值计算相邻时刻的运动,和过去的信息没有关联,就像一种只有短时(不限于两帧,也许更多)记忆的物种。
有了视觉里程计,估计了两张图象间的相机运动,只要把相邻时刻运动”串”起来,就构成了机器人的运动轨迹,从而解决了定位问题。同时,根据每个时刻相机的位置,计算出各像素对应的空间点的位置,就得到了地图。但是通过仅视觉里程计来估计轨迹,将不可避免的出现累计漂移。由于估计是”串”起来的,那么之前的估计误差就会影响到之后的估计,长期积累下来,就会造成非常大的误差。为了解决这个问题,还需要两个技术:后端优化、回环检测。回环检测负责把”机器人回到原始位置”的事情检测出来,后端优化则是根据信息,矫正整个轨迹的形状。
后端(非线性)优化
虽然我们希望所有的数据都是准确的,但是再精确的传感器也带有一定噪声,后端优化考虑的问题,就是如何从这些带有噪声的数据中 估计整个系统的状态,以及这个状态估计的不确定性有多大——称为最大后验概率估计(Maximum-a-Posteriori,MAP)。这里的状态包括机器人自身的轨迹和地图。后端主要采用滤波器或非线性优化,估计状态的均值和不确定性(方差)。
回环检测
回环检测,又称闭环检测,主要解决位置估计随时时间漂移的问题。假设机器人经过一段时间的运动后回到了原点,但由于漂移,它的位置估计没有回到原点。我们利用某种手段,让机器人知道”回到了原点”,或者把原点识别出来,我们再把位置估计值”拉”过去,就可以消除漂移了。例如可以判断图象间的相似性来完成回环检测,如果回环检测成功,就可以显著的减小累计误差。所以回环检测实质上是一种图像数据相似性的算法。由于图像的信息非常丰富,使得正取回环检测的难度得以降低。
建图
度量地图(Metric Map):强调精确地表示地图中物体的位置关系,通常用稀疏(Sparse)与**稠密(Dense)对其分类。稀疏地图进行了一定程度的抽象,并不需要表达所有的物体。通常选择一部分有意义的东西。相对的,稠密地图着重于建模所有看到的东西。定位是用稀疏路标地图就足够了,但是用于导航时,往往需要稠密地图。稠密地图通常按照某种分辨率有许多小块组成(二维是小格子(Grid),三维是小方块(Voxel))。一方面这种地图需要存储每一个格点的状态,会消耗大量的存储空间,而且多数情况下的细节是无用的。另一方面,大规模度量地图有事会出现一致性的问题。很小的转向误差,可能会导致两间屋子的墙出现重叠,使地图失效。
拓扑地图(Topological Map):相比于度量地图的精确性,拓扑地图更强调地图元素之间的关系。拓扑地图是一个图,有节点和边组成,只考虑节点间的连通性。放松了精确位置的需要,去掉了地图的细节,是一种更为紧凑的表达方式。然而,拓扑地图不擅长表达具有复杂结构的地图,如何对地图进行分割,形成节点与边,有如何进行导航与路径规划,仍然存在很多问题。