从之前的介绍中,我们了解到经典 SLAM 系统的组成包括:传感器、前端、后端、回环检测、建图,其中前端也被称为视觉里程计(Visual Odometry,VO)。所以传感器接收到的信息传给前端,前端是对这个数据信息做处理的。里程计的意义是为了估计和计算某一种运动过程,那么视觉里程计的作用就很清晰了:在运动(包括静止)的过程中通过视觉传感器(相机)传过来的图像,对这个相机的运动轨迹、状态进行估计。那么怎么能够完成这个估计,怎么能更贴实际情况呢?下面内容将介绍一些常用的算法和思路。
视觉里程计的算法主要分为两个大类:特征点法和直接法。基于特征点法的前端,一直到现在依旧是视觉里程计的主流方法,他具有稳定,对光照、动态物体不明感的优势,是相对较为成熟的解决方案。
特征点法
视觉里程计的核心问题就是如何根据图像估计相机运动。因为图像的本身是由亮度和色彩组成的矩阵,但是直接从数字矩阵层面去考虑运动的估计是相当困难的。比较方便的做法是选取比较有特点的点,称之为路标。通过这些数量较少的路标我们就能够大致的表示出这个图像。数字图像在计算机中是以灰度值矩阵的方式存储了,所以灰度值受光照、形变、物体材质的影响是非常严重的,导致选取特征点也收到很影响。那么如何更好的选取特征点?
众所周知,特征点就是一些特别的点,对于一个场景来说,各个区域的边界是特殊的。所以,一种直观的特征提取方式就是在不同的图像间辨认角点,并确定这些的关系来进行区域划分。角点的提取算法有很多,例如Harris角点、FAST角点、GFTT角点等。但是只根据角点去判断也是存在很多弊端的,比如当相机发生旋转时,角点的外观会发生变化;相机在远处的记录可能是角点,但到了近处可能就不显示为角点了。而且这些大都是2000年左右提出的算法。所以经过常年的研究和发现,出现了更加稳定的局部图像特征算法,如SIFT(Scale Invariant Feature Tansform,尺度不变特征变换)、SUPF(Speeded Up Robust Features,加速稳健特征)、ORB(Oriented FAST and Rotated BRIEF,快速特征点提取和描述)等等。
特征点由关键点(key-point)和描述子(Description)共同组成。关键点是指改特征点在图像里的位置,有些特征点还具有朝向、大小等信息。描述子通常是认为设计的描述了该关键点周围像素的信息。所以外观相似的特征应该有相似的描述子。
在一副图像中,同时提取1000个特征点的情况下,ORB 约花费15.3ms,SURF约花费217.3ms,SIFT约花费5228.7ms。
SIFT算法充分的考虑了图像变换过程中出现的光照、尺度、旋转等变化,随之而来的是极大的计算量。普通计算机的CPU很难实时的计算SIFT特征,需要引入GPU进行加速计算,提高了SLAM的成本。
SURT算法则是对SIFT算法的改进,该算子在保持SIFT优良性能特点的基础上,同时解决了SIFT计算复杂度高、耗时长的特点,提高了算法的执行效率。
ORB算法则通过适当的降低精度和鲁棒性,改进了FAST检验子不具有方向性的问题,并采用速度极快的纹紧致描述子BFIEF,使图像特征提取的环节大大加速。
ORB 特征
提取 ORB 特征分为如下两个步骤:
1、FAST角点提取:找到图像中的”角点”。相比于原版的FAST,ORB中计算了特征点的主方向,为后续的BRIEF描述子增加了旋转不变特性(采用灰度之心法实现),尺度不变性(构建图像金字塔实现)。
2、BRIEF描述子:为前一步提取出的特征点的周围图像区域进行描述。ORB对BRIEF进行了一些改进,主要是指在BRIEF中使用了先前计算的方向信息。
FAS关键点
FAST是一种角点,其主要检测局部像素灰度变化明显的地方,速度非常之快。检测思路是:如果一个像素和领域的像素差别较大,那么他就有可能是角点。
其特征点的检测过程为:
1、在图像中选取像素p,假设他的亮度I。
2、设置一个阈值T(比如I的20%)。
3、以像素p为中心,选取半径为3的圆上的16个像素点。
4、假如圆上有连续N个点的亮度大于I+T或小于I-T,那么像素p就可以认为是特征点。(通常N设置为9、11、12)
5、重复1 ~ 4,依次对图像中各个像素进行操作。
构建图像金字塔–实现尺度不变性
由于检测时固定取半径为3的圆,会存在尺度变换的问题:远处看着像角点的地方,接近后看到可能就不是角点了。所以为了结局额这个问题,ORB添加了尺度的描述,尺度不变性有构建图像金字塔,并在金字塔的每一层上检测角来实现。
如上图,图像金字塔可以匹配不同缩放倍率下的图像,来模拟相机远近的情况下的图像。金字塔底层是原始图像,没往上一层,就对图像进行一个固定倍率的缩放,这样就有了不同分辨率的图像。在特征匹配算法中,我们可以匹配不同层上的图像,从而实现尺度不变性。例如,如果相机后退,那么我们应该能够在上一个图像金字塔的上层和下一个图像金字塔的下层中找到匹配。
灰度质心法–实现旋转不变性
由于FAST角点不具有方向信息,所以在相机发生了旋转之后,FAST角点会发生旋转变化,所以为了实现旋转不变性,通过计算特征点附近的额图像灰度质心(以图像块灰度值为权重的中心),具体步骤如下:
1、在一个小的图像块B中,定义图像块的矩为:
$$m_{pq} = \sum_{x,y \in B} x^py^qI(x,y), p,q = { 0,1 }.$$
2、通过矩可以找到图像块的质心:
$$C = \begin{pmatrix} \frac{m_{10}}{m_{00}} , \frac{m_{01}}{m_{11}} \end{pmatrix}$$
3、连接图像块的集合中心 $\omicron$ 与质心 C,得到一个方向向量 $\overrightarrow{\omicron C}$,于是特征点的方向可以定义为:
$$\theta = arctan({m_{01}} / {m_{10}}).$$
通过以上方法,FAST角点便具有了尺度与旋转的描述,从而大大提升了其在不同图像之间表述的鲁棒性,所以在ORB中,把这种改进后的FAST称为Oriented FAST。
BRIEF 描述子
在提取 Oriented FAST 关键点后,我们对每个点计算其描述子。ORB 使用改进的 BRIEF 特征描述。
BRIEF 是一种二进制描述子,其描述向量有许多个 0 和 1 组成,0 和 1 编码了附近两个随机像素(比如 p 和 q)的大小关系:如果 p 比 q 大,则取 1,反之取 0。如果我们取了 128 个这样的 p 和 q,则最后得到了 128 维由 0、1 组成的向量。原始的 BRIEF 描述子不具有旋转不变性,因此在图像发生旋转时容易丢失,而 ORB 在 FAST 特征点提取阶段计算了方向,可以利用方向信息,计算旋转之后的”Steer BRIEF”特征时 ORB 的描述子具有较好的旋转不变性。同时,BRIEF 使用了随机选点的比较,速度非常快,有因为使用了二进制表达,存储起来十分方便,适用于实时的图像匹配系统。
特征匹配
特征匹配解决了 SLAM 中的数据关联问题,即确定当前看到的路标与之前看到的路标之间的对应关系。通过对描述子准确匹配,可以为后续的姿态估计、优化操作减轻大量负担。因为场景中可能存在大量的重复纹理,是的特征描述非常相似(即使相距非常远的特征点也有可能其描述子非常相似),但仅利用局部特征解决误匹配是非常困难的。
在正常匹配的情况下,考虑两个时刻的图像,如何找到来两个图像特征点集合元素的对应关系,最简单的特征匹配方法就是暴力匹配(Brute-Force Matcher):对上一时刻的每一个特征点与下一时刻的每一个特征点测量描述子的距离(表示两个特征之间的相似程度),然后排序,取最近的一个作为匹配点。对于浮点类型的描述子,使用欧几里得度量,对于二进制的描述子通常使用汉明距离(两个二进制串之间的汉明距离,指的是其不同位数的可数)。
当特征点数量很大时,暴力匹配法的运算量非常大,不符合实时性,可以使用比较成熟的快速近似最近邻(FLANN)算法,而且其实现已经集成到OpenCV,可以下面去了解学习一下。