这属于一篇很成熟的论文了,网上的翻译和讲解也很多,这里只记录一下在关键部分的一些思路。
一、测量初始化(IV)
A-视觉处理前端: 对于每一帧的图片,使用稀疏光流法去追踪特征点,与此同时还要对新的角点进行检测,不断用新的去补充,从而让特征点处在一个合适的数目。并且在检测过程中也不断保证相邻特征点之间的距离满足一个最小间隔,从而保证均匀的特征分布。去除异常点使用RANSAC算法来进行,去除异常点之后的点会投射到单位球面上。
在这一步中同样还进行了一个关键帧的提取,关键帧的提取主要是两个原则:平均视差和跟踪质量。 平均视差要求当前帧和上一个关键帧所有跟踪点的平均视差保持在一定范围内,如果超出阈值,就设置为新的关键帧。跟踪质量要求如果跟踪的特征数量低于一定阈值,就作为新的关键帧。对于视差,平移和旋转都会产生视差,但是特征点再只有旋转的物体运动中是无法三角化的,为了避免这种现象,我们在计算视差的时候都会利用陀螺仪的短期积分来补偿旋转。由于陀螺仪含有较大的噪声或者存在偏置,我们只在关键帧的选择时使用这种旋转补偿,而在后续VINS公式计算中则不进行这一步,这样就算陀螺仪有偏差,也只会导致次优关键帧的选择结果,而并不会对估计质量产生较大的影响。 在视觉处理前端,主要的流程就是:维护窗口-从窗口内筛选符合要求的两帧图像-对两帧图像使用五点法得到这两张图像之间的变换关系-对两帧中的特征进行三角化-恢复特征点的三维信息-对窗口中剩下的图像使用pnp算法估计位姿-BA优化所有特征观测值的总重投影误差。
B-IMU预积分: IMU可以获取沿xyz三个方向的角速度和加速度,传统的导航算法中,使用IMU数据主要是在上一个时刻的基础上,用IMU测量的线加速度和角速度,通过积分计算得到当前时刻的状态信息,通过IMU传感器得到的数据主要是线加速度和旋转角速度,速度的变化是线加速度对时间的一次积分,位移是两次积分。那么如果想得到下一个时刻的速度、位置和位姿,就是在当前时刻的基础上,对这两个量积分,加速度对时间积分一次是速度,积分两次得到的是位移,也就是说,后一个时刻的数据是前一个时刻的基础上积分得到的。 在非线性的前端中,各个节点的状态量都是估计值,所以算法对其进行优化时,每次都需要在它们之间重新积分,也就是说绝对位姿被优化时会对状态量进行重复积分。就好比我要利用加速度积分去计算速度,如果IMU给出的加速度是不准确的,那么计算的速度也就是不准确的,在优化之后加速度变成新的值,所以更新速度的时候也需要重新积分一次。如果更新次数很多,重新计算速度的次数也就很多,并且这种重新积分会不断随着时间传递,这将耗费大量的时间。为此我们使用IMU预积分,希望对IMU的相对测量进行优化,使其与绝对位姿解耦,每次更新绝对位姿的时候只需要线性运算就可以优化,而不用重复进行积分。简单来说就是分离积分中的元素,让积分可以变成一个线性相加的过程,这样在优化的时候,就不需要再计算积分,而是直接做一个线性的修正。
对于上面图中的式子,在积分的部分中可以看到一个从body到world的转换,这部分的转换可以利用下面的式子拆开成两个变换: 这样拆开之后,好处是qwbi可以从积分中拿出去,因为这个量完全与时间t无关,之后表达式就可以换为下面的样子: 我们将下面这部分叫做预积分,这三个式子正好对应了两帧之间的位置、速度和姿态(旋转)增量。预积分量仅和IMU测量值有关,它将一段时间内的IMU数据直接积分起来就得到了预积分量。 可以发现,进行预积分之后,每次优化迭代的过程中,调整姿态都是相对于世界坐标系调整,也就是调整qwbi,而预积分的值是不变的,所以就不用重复计算积分,节省了大量的计算时间。
举个例子我要计算从楼门出发回家,路上可能会遭遇各种的情况,比如堵车、抛锚等情况,但是我无论如何都需要从楼门口走到校门口,那么我完全可以先计算这部分固定不变的,之后在每次的计算时,都去根据具体路上情况修正计算结果,从而跳过了复杂的部分。当然实际上预积分并不是这个例子中的过程,但是思路是一致的。
具体的预积分知识在这个链接里讲的很清楚: https://zhuanlan.zhihu.com/p/90213963
二、估计器初始化(V)
A-滑动窗口纯视觉SfM 这部分主要是获取每一帧图像的位姿。首先算法会维护一个滑动窗口,窗口内存储有很多的连续帧,对这些连续帧,首先检查最新帧和之前所有帧的特征对应关系,如果窗口中的一帧与最新帧之间存在稳定的特征跟踪并且有足够的视差,就用**五点法(PnP)**恢复这两帧之间的变换关系。利用这两帧和这两帧的变换关系,通过三角测量,恢复两帧中特征点的3d信息。之后基于这些特征的3d信息,与剩余的帧使用PnP算法,得到窗口中剩余帧的位姿变换。现在整个窗口中图像的位姿变换信息就都得到了,最后使用全局BA算法,最小化窗口内所有特征观测值的总投影误差,也就得到了一个优化的窗口内的各个图像的位姿。
对于BA优化,我们得到了窗口中所有帧的位姿,以及特征点的3d信息,利用这个信息,可以计算出特征点在当前位姿下投影到像素平面的位置,从而得到真实值与投影值之间的差距,最小化这个差距,即重投影误差,相当于优化了所有的位姿信息。 在纯视觉的SLAM中,由于没有世界坐标系的任何知识,所以所有坐标都是以第一张图为基准的,摄像机和IMU之间存在一个变换的外部参数,利用这个外部参数,可以建立一个旋转约束和一个平移约束,利用这两个约束可以进行后面的校正工作。 这两个约束的建立如下图: 参考链接:https://www.pianshen.com/article/2462901808/
B-视觉惯性联合校准 (1)陀螺仪偏置标定 陀螺仪偏置的标定主要是依靠前面的旋转约束。对于一个变换其实主要有两种实现方法,一个是先在相机坐标系下旋转,然后利用变换参数转换到body坐标系下,另一个是现在body坐标系下旋转,然后利用变换参数转换到相机坐标系,对上面的两个方式,理论上实现的效果是一样的,这就构成了一个约束,约束中存在一个变换外参,这个参数用于两个坐标系同一个时刻下的转换,利用这个约束,可以解出这个变换外参的值,当然这个值也可以直接用测量的方法去实现。现在得到了变换外参,现在我们要最小化一个误差,这个误差个人理解就是变换一圈之后产生的误差,理论上误差是零,但因为有偏置的存在,所以不是零,我们现在就是要从绕一圈的误差中分离出这个陀螺仪的偏置,这就构成了一个最小二乘问题,解这个问题,最后可以得到一个最优的个偏置,偏置的分离主要是用其中预积分的部分,在预积分的计算中会利用到这个偏置。利用这个去校正陀螺仪的后续信息,也就得到了更准确的IMU增量信息。 用这张图来解释,图中蓝色和黄色的两条路径,对于这个回路,如果没有误差,结果应该是完美重合的,即相乘的结果是一个单位四元数,但是因为误差的存在,乘下来一圈是一个别的值,这个值就是偏置值。 这个问题本身属于一个最小二乘问题,寻找一个最优的偏差bw,让整体的误差最小化,上式中本身不含有偏差,所以需要分离出来: s为尺度,主要是为了解决平移过程中单位不统一的问题,使用IMU得到的是米制单位,但是视觉计算的结果不一定是米制单位,这里就存在一个类似于单位的转换,用s表示,旋转不会产生这个问题,因为旋转都是角度上的操作,平移会因为旋转半径不同而产生尺度的差异,所以涉及视觉坐标系下的结果就应该使用一个尺度表示这个转换,带入尺度之后就有了图中的变换转换关系,整理这个变换关系,就可以得到两个几何约束,这两个几何约束分别用在后面的陀螺仪校正和速度、重力向量初始化上。
(2)初始化速度、重力和尺度 校正陀螺仪之后,就可以初始化其余重要的参数:速度、重力和尺度。经过第一步对陀螺仪的校正,现在我们认为IMU的信息已经是准确的了,也就是在IMU预积分中,得到的位置增量、速度增量以及旋转增量现在是可靠的,我们可以用这部分信息,去校正视觉的部分。校正本质的目的是让两种方式之间的差距最小,也就是说用IMU计算得到的两帧之间的增量要和视觉计算的结果尽可能接近。在预积分中满足的约束,在任何一个坐标系下应该依然满足,所以可以得到一个相机坐标系下预积分结果的表示方法。 将这个式子与平移约束联立,得到一个预积分与视觉待优化量之间的关系式,将待优化量单独拿到一边,整理得到一个等式,等式一侧只有现在已经准确的IMU信息,另一侧则包含待优化的量,对这个等式进行优化,从而得到更加准确的待优化量,也就是速度、重力和尺度。 现在待估计量为: 对两个平移约束整理,将待估计变量放在一边,可以得到下面的式子: 转化成线性最小二乘问题对状态量进行求解: 最终可以求得一个最优的速度、尺度和重力向量。
(3)重力的进一步优化 这一部分主要是在上一步的基础上,进一步优化重力向量,而重力加速度的值是9.8,我们在前面并没有加入向量模长度的限制,所以现在需要对重力向量补充一个优化。这里就涉及一个向量优化的思路,一个三维向量的模长固定为9.8,对应空间中一个球径为9.8的球面,从球心指向球面上任何一个点的向量都是模长为9.8的向量。 利用这个思路去固定模长,那么我们的优化就可以通过增加扰动的方式,也就是在刚才求出来的重力方向上,拉倒模长为9.8,之后给这个方向增加两个扰动,利用这个扰动,去变化重力向量的方向,找一个最优的扰动,从而找到一个重力向量的最优的方向。
(4)初始化的完成 得到第三步中校正的重力矢量,就可以利用这个矢量的方向,将重力方向与世界坐标系中的z轴联系在一起,得到一个世界坐标系与相机坐标系之间的转换关系,从而可以将所有变量从第一个相机坐标系转换到世界坐标系。
三、紧耦合单目VIO(VI)
A-优化公式 待优化量: 用一个状态向量表示,状态向量包括滑动窗口内的所有相机状态(位置P、旋转Q、速度V、加速度偏置ba、陀螺仪偏置bw)、相机到IMU的外参、所有3D点的逆深度。 目标函数: 包括三项,分别为边缘化的先验信息、IMU的测量残差和视觉的重投影残差。
B-IMU残差 这部分是优化公式中的第二部分,对应的是IMU信息的误差。这部分主要是通过状态量传播预测与IMU预积分的残差去校正IMU时刻下的p位置,v速度,Q旋转,两个偏置ba,bw。对校正内容整理,可以发现这部分的残差实际上是IMU预积分得到的理论值与实际测量的结果的差值,因为实际测量存在噪声,所以最小化这个差值,实际上就是让IMU的信息更加准确,更加接近理论计算的结果。
C-视觉测量残差 这部分是优化公式中的第三部分,对应的是视觉重投影的误差,所谓重投影,指的是根据3D点根据当前估计位姿进行投影得到的像素坐标与真实得到的坐标之间的差值,在这部分中,是对重新出现的特征进行误差的优化。假设一个特征l在窗口中的第i张图片被首次观测到,现在在第j张图片中又一次被观测到,在前面的初始化和校准中我们知道一个窗口内的位姿是知道且校准的,现在利用这个位姿,将首次观测到的点重投影到又一次观测到时候的归一化坐标系中,得到了一个差值,这个差值就是视觉测量的残差。在得到这个残差的过程中,还存在几个细节。首先是逆深度参数化,个人理解就是将三维坐标中的深度提出来,变成归一化平面上的像素坐标,在计算过程中采用这种方式,一方面是因为深度值过大会导致优化难以进行,另一方面这样做可以减少实际优化的参数量,也就是说残差的计算最后都是在归一化平面上进行的。其次就是公式中在计算残差后使用的b1b2矩阵,这个矩阵是因为论文中使用的是广角相机的球面模型,所以需要在正切平面上进行投影,如果使用的是一般的针孔相机则不需要考虑这一点。
D-先验信息 先验信息主要是体现在边缘化里面,边缘化的主要目的,就是限制窗口内关键帧的数量,从而让计算复杂度不会大到离谱。一般来说,我们提到限制一个窗口内的关键帧数目,第一反应就是留下新的,删除旧的,但是直接删除旧的关键帧和与其关联的信息,但是在SLAM问题中,旧的关键帧与后续的关键帧之间是存在联系的,所以这种暴力的删除不可避免会导致信息的丢失,这显然不是我们希望的,所以我们在这里使用边缘化的思想,通过引入先验,让损失不那么大。在VINS里面使用的边缘化有两种策略,根据次新帧的情况,判断应该采取哪一种的边缘化策略。当次新帧为关键帧的时候,将最老帧边缘化掉,连带着最老帧看到的路标点和相关的IMU数据,将这部分转换为先验信息,加到整体的目标函数中。当次新帧不是关键帧时,直接丢到次新帧和它的视觉观测信息,但是保留IMU信息。这样做是因为这种情况下我们认为次新帧和当前帧差别不大,丢弃并不会造成约束关系丢失太多,保留IMU信息则是为了保证IMU预积分的连贯性。通过边缘化的方式,在限制窗口内信息的同时,还保证了前面的关键帧的信息在不影响整体约束的情况下被删除,而且这种删除方式能够保证关键帧在窗口内分布的稀疏性,在三角化的时候有足够的视差。对应到优化公式中的第一部分,这个部分应该是为了让先验损失的内容尽可能小。
四、重定位
尽管滑动窗和边缘化减小了计算复杂度,但是仍旧引进了系统的累计漂移误差。论文采用紧耦合重定位模块与单目VIO进行组合实现漂移误差的消除。 vins的重定位模块主要包含回环检测、回环候选帧之间的特征匹配和紧耦合重定位三个部分。 重定位的部分对应图中的1-4步,剩下的是全图优化。 回环检测主要通过下面四步进行: 1、采用DBoW2词袋位置识别方法进行回环检测。经过时间空间一致性检验后,DBoW2返回回环检测候选帧。 2、除了用于单目VIO的角点特征外,还添加了500个角点并使用BRIEF描述子,描述子用作视觉词袋在数据库里进行搜索。这些额外的角点能用来实现更好的回环检测。 3、VINS只保留所有用于特征检索的BRIEF描述子,丢弃原始图像以减小内存。 4、单目VIO可以观测到滚动和俯仰角,VINS并不需要依赖旋转不变性。
之后进行特征点的过滤,主要是下面两步: 1、检测到回环时,通过BRIEF描述子匹配找到对应关系。但是直接的描述子匹配会导致很多外点。 2、本文提出两步几何剔除法: 1)2D-2D:使用RANSAC进行F矩阵测试, 2)3D-2D:使用RANSAC进行PnP,基于已知的滑动窗特征点的3D位置,和回路闭合候选处图像的2D观测(像素坐标)。 经过剔除之后,如果匹配点依然超过一定阈值,我们将该候选帧视为正确的循环检测并执行重定位。 可以看见,经过这一步两次的过滤,特征点对的数量明显减少,这种情况下再进行回环的判断,就可以提高回环判断的准确程度。
最后,对发现回环的窗口进行进一步的优化: 1、重定位过程使单目VIO维持的当前滑动窗口与过去的位姿图对齐。 2、将所有回环帧的位姿作为常量,利用所有IMU测量值、局部视觉测量和从回环中提取特征对应值,共同优化滑动窗口。 可以看见这个优化的式子实际上是在原来优化的基础上,增加了一个回环项,相当于利用旧的关键帧之间的约束信息,对新的信息再增加一些约束。
五、全局优化
全局优化中需要使用一种叫位姿图的结构,位姿图可以看作一种特殊的存储用数据结构,位姿图中点代表已经离开滑动窗口的关键帧,边有两种: 1、顺序边(Sequential Edge):关键帧将建立与之前关键帧的几个顺序边,一个顺序边表示局部滑动窗口中两个关键帧之间的相对转换,它的值直接从VIO中获取。 2、回环边(Loop Closure Edge):如果最新的边缘化掉的关键帧存在回路连接,它可以通过位姿图中的回路比河边和回路闭合帧相连接。回环边的值由重定位结果得出。 随着行程距离的增加,位姿图的大小可能会无限增长,从而限制了长时间系统的实时性。为此,我们实行了一个下采样过程:将位姿图数据库保持在有限的大小。所有具有回环约束的关键帧都将被保留,而其他与相邻帧过近或方向非常相似的关键帧可能会被删除。关键帧被移除的概率和其相邻帧的空间密度成正比。
当有一个新的关键帧进入位姿图,如果在位姿图内部检测到了回环,就对位姿图内的关键帧进行优化,通过最小化以下代价函数,对顺序边和回环边的整个图进行优化。 下面小总结一下重定位和全图优化的过程: 实时检测滑动窗口内和之前的旧关键帧,如果发现回环且经过特征点过滤特征点的数目依然超过阈值,认为真的发现了回环,进入重定位。 重定位将修正滑动窗口内的关键帧,在原来VIO优化的基础上增加一个回环项,利用旧关键帧的信息去辅助优化窗口内的位姿。 随着滑动窗口的推进,关键帧被边缘化出窗口,一旦检测到新进入位姿图的关键帧和之前的关键帧出现了回环,就对位姿图内的关键帧进行位姿的优化。
六、参考链接
光流法: https://blog.csdn.net/qq_28368377/article/details/104534273 IMU预积分: https://blog.csdn.net/try_again_later/article/details/97106200#2%E3%80%81%E5%9F%BA%E4%BA%8E%E8%88%92%E5%B0%94%E8%A1%A5%E7%9A%84%E8%BE%B9%E7%BC%98%E5%8C%96 https://blog.csdn.net/weixin_40347021/article/details/107160016 https://zhuanlan.zhihu.com/p/90213963 三角化: https://blog.csdn.net/qq_37746942/article/details/115539292 RANSAC: https://blog.csdn.net/robinhjwy/article/details/79174914 估计器初始化(V): https://zhuanlan.zhihu.com/p/113127198 https://www.pianshen.com/article/2462901808/ 紧耦合单目(VI): https://blog.csdn.net/qq_41839222/article/details/93593844 https://www.cnblogs.com/pacino12134/p/11104446.html 全文解析: https://www.cnblogs.com/ilekoaiq/p/8836970.html https://blog.csdn.net/qq_41839222/article/details/85793998
|