SLAM【十一】建图

  • 概述
  • 单目稠密重建
    • 立体视觉
    • 极线搜索与块匹配
    • 高斯分布的深度滤波器
    • 像素梯度的问题
    • 逆深度
    • 图像间的变换
  • 点云地图
  • 八叉树地图
  • 参考

概述

建图的功能:

  1. 定位:第一次跑,就把地图保存下来,让机器人在下次开机后依然能够在地图中定位。
  2. 导航:需要创建稠密地图,因为要进行路径规划,需要知道地图中那些地方可以通过,那些地方不可以通过
  3. 避障:与导航类似,但更注重局部的、动态的障碍物的处理。也需要稠密地图。
  4. 重建: 创建周围环境的重建模型,用于展示,因此需要美观,能够像电子游戏中的三维场景那样。稠密地图
  5. 交互:人与地图之间的互动。例如用于增强现实。

具体的各种地图类型与用途之间的关系:


稀疏地图只建模感兴趣的部分,也就是前面说了很久的特征点(路标点)。
稠密地图是指建模所有看到过的部分。

单目稠密重建

立体视觉

在稠密重建中,我们需要知道每一个像素点的距离,对此的解决方案为:

  1. 使用单目相机,估计相机运动,并且三角化计算像素的距离。
  2. 使用双目相机,利用左右目的视差计算像素的距离(多目原理相同)
  3. 使用RGB-D相机直接获得像素距离。

单目双目的缺点:计算量巨大,最后得到不怎么可靠的深度估计。

因此,稠密地图的重建往往选择RGB-D。

RGB-D缺点:无法被很好的应用在室外、大场景场合中。而单目、双目仍能通过立体视觉估计深度信息。

针对单目的稠密估计,需要完成的是:在给定相机轨迹的基础上,如何根据一段时间的视频序列,来估计某张图像的深度。换言之,我们不考虑 SLAM,先来考虑稍为简单的建图问题。
假定有某一段视频序列,我们通过某种算法得到了每一帧对应的轨迹(当然也很可能是由视觉里程计前端估计所得)。现在我们以第一张图像为参考帧,计算参考帧中每一个像素的深度(或者说距离)。
在使用特征点时,通过以下两步完成这个过程:

  1. 首先,我们对图像提取特征,并根据描述子计算了特征之间的匹配。换言之,通过特征,我们对某一个空间点进行了跟踪,知道了它在各个图像之间的位置。
  2. 然后,由于我们无法仅用一张图像确定特征点的位置,所以必须通过不同视角下的观测,估计它的深度,原理即前面讲过的三角测量。

由于在在稠密深度估计中,不同之处是,在这里我们不能把每个像素当作特征点计算描述子。因此在这里匹配很重要。也就是要解决:如何确定第一幅图的某像素出现在其他图里的位置
当我们知道了某个像素在各个图中的位置,就能像特征点那样,利用三角测量确定它的深度。不过不同的是,在这里我们要使用很多次三角测量让深度估计收敛,而不仅是一次。我们希望深度估计,能够随着测量的增加,从一个非常不确定的量,逐渐收敛到一个稳定值。这就是深度滤波器技术

极线搜索与块匹配

根据题目,这一部分分为极线搜索块匹配
极线搜索就是:在相机在第一个视角拍摄到的图像中确定一个像素p1p_1p1​,根据目前相机的角度可以确定p1p_1p1​像素的深度在某个区域之内,某最小值到无穷远之间。故该像素点对应的空间点就分布在某条线段上。当相机变换了另一个视角,这条线段的投影也形成图像平面上的一条线,这条线就是极线当知道相机在这两个视角的运动时,这条极线就能够确定,最终的问题就是:极线上的哪一点是p1p_1p1​。现在是根据运动来匹配像素,与之前的前端不同的是:前端是先匹配特征点而不是所有的像素(因为不能每个像素都计算描述子),然后根据匹配的特征点来估计相机的运动。这里是根据相机的运动匹配像素


这里在寻找p2p_2p2​的过程中,不像特征点法那样计算描述子,这里没有计算,所以只能在极线上搜索和p1p_1p1​长得比较相似的点。所以叫极线搜索。如果一个一个比较像素,有点像直接法。易受光照影响,同时如果有与p1p_1p1​相似的点,但不是真的点呢。这不就有点像回环检测那一部分吗,相似性。
解决方法:在 p1p_1p1​ 周围取一个大小为 w×ww × ww×w 的小块,然后在极线上也取很多同样大小的小块进行比
较,就可以一定程度上提高区分性。这就是所谓的块匹配。从而假设变成了从像素的灰度不变性变成了图像块的灰度不变性。

取p1p_1p1​周围的小块A∈Rw×w\boldsymbol{A} \in \mathbb{R}^{w \times w}A∈Rw×w,极线上的nnn个小块记成Bi,...,n\boldsymbol{B}_i,...,nBi​,...,n。计算相似度:

  1. SAD(Sum of Absolute Difference)。顾名思义,即取两个小块的差的绝对值之和:
    S(A,B)SAD=∑i,j∣A(i,j)−B(i,j)∣S(\boldsymbol{A}, \boldsymbol{B})_{S A D}=\sum_{i, j}|\boldsymbol{A}(i, j)-\boldsymbol{B}(i, j)| S(A,B)SAD​=i,j∑​∣A(i,j)−B(i,j)∣

  2. SSD。 SSD 并不是说大家喜欢的固态硬盘,而是 Sum of Squared Distance(SSD)(平方和)的意思:
    S(A,B)SSD=∑i,j(A(i,j)−B(i,j))2S(\boldsymbol{A}, \boldsymbol{B})_{S S D}=\sum_{i, j}(\boldsymbol{A}(i, j)-\boldsymbol{B}(i, j))^{2} S(A,B)SSD​=i,j∑​(A(i,j)−B(i,j))2

  3. NCC(Normalized Cross Correlation)(归一化互相关)。这种方式比前两者要复杂一些,它计算的是两个小块的相关性:

S(A,B)NCC=∑i,jA(i,j)B(i,j)∑i,jA(i,j)2∑i,jB(i,j)2S(\boldsymbol{A}, \boldsymbol{B})_{N C C}=\frac{\sum_{i, j} \boldsymbol{A}(i, j) \boldsymbol{B}(i, j)}{\sqrt{\sum_{i, j} \boldsymbol{A}(i, j)^{2} \sum_{i, j} \boldsymbol{B}(i, j)^{2}}} S(A,B)NCC​=∑i,j​A(i,j)2∑i,j​B(i,j)2​∑i,j​A(i,j)B(i,j)​
注意:由于这里用的是相关性,所以相关性接近 0 表示两个图像不相似,而接近1才表示相似。前面两种距离则是反过来的,接近 0 表示相似,而大的数值表示不相似。

和我们遇到过的许多情形一样,这些计算方式往往存在一个精度——效率之间的矛盾。精度好的方法往往需要复杂的计算,而简单的快速算法又往往效果不佳。这需要我们在实际工程中进行取舍。另外,除了这些简单版本之外,我们可以先把每个小块的均值去掉,称为去均值的 SSD、去均值的 NCC 等等。去掉均值之后,我们允许像“小块 B 比 A 整体上亮一些,但仍然很相似”这样的情况,因此比之前的更加可靠一些。(这样好像可以避免掉光照的影响)

高斯分布的深度滤波器

就是估计深度,使之达到最优,同时计算量也不大。
第一种方法:假设深度值服从高斯分布,得到一种类卡尔曼式的方法。
第二种方法:均匀-高斯混合分布的假设,另一种形式更为复杂的深度滤波器。
这里主要介绍第一种方法:
设某个像素点的深度 ddd 服从:
P(d)=N(μ,σ2)P(d)=N\left(\mu, \sigma^{2}\right) P(d)=N(μ,σ2)

每当新的数据到来,我们都会观测到它的深度。同样的,假设这次观测亦是一个高斯分布:
P(dobs)=N(μobs,σobs2)P\left(d_{o b s}\right)=N\left(\mu_{o b s}, \sigma_{o b s}^{2}\right) P(dobs​)=N(μobs​,σobs2​)
于是,我们的问题是,如何使用观测的信息,更新原先 ddd 的分布。这正是一个信息融合问题。我们明白两个高斯分布的乘积依然是一个高斯分布。设融合后的 ddd的分布为N(μfuse ,σfuse 2)N\left(\mu_{\text {fuse }}, \sigma_{\text {fuse }}^{2}\right)N(μfuse ​,σfuse 2​),那么根据高斯分布的乘积,有:

μfuse=σobs2μ+σ2μobsσ2+σobs 2,σfuse 2=σ2σobs2σ2+σobs 2\mu_{f u s e}=\frac{\sigma_{o b s}^{2} \mu+\sigma^{2} \mu_{o b s}}{\sigma^{2}+\sigma_{\text {obs }}^{2}}, \quad \sigma_{\text {fuse }}^{2}=\frac{\sigma^{2} \sigma_{o b s}^{2}}{\sigma^{2}+\sigma_{\text {obs }}^{2}} μfuse​=σ2+σobs 2​σobs2​μ+σ2μobs​​,σfuse 2​=σ2+σobs 2​σ2σobs2​​

由于我们仅有观测方程而没有运动方程,所以这里深度仅用到了信息融合部分,而无须像完整的卡尔曼那样进行预测和更新。(这里也可以看成“运动方程为深度值固定不动”的卡尔曼滤波器)。那么现在的问题是:如何求μobs\mu_{o b s}μobs​和σobs2\sigma_{o b s}^{2}σobs2​
这里的不确定性包含两种,一种是几何不确定性和,另一种是光度不确定性。现在暂时只考虑几何不确定性。现在需要确定的是通过极线搜索和块匹配确定的某参考帧中某个像素的这个位置对深度的不确定性有多大。

以上图为例。考虑某次极线搜索,我们找到了 p1p_1p1​ 对应的 p2p_2p2​ 点,从而观测到了 p1p_1p1​的深度值,认为 p1p_1p1​ 对应的三维点为 PPP。从而,可记 O1PO_1PO1​P 为 ppp, O1O2O_1O_2O1​O2​ 为相机的平移 ttt,O2PO_2PO2​P 记为 aaa。并且,把这个三角形的下面两个角记作 α,βα, βα,β。现在,考虑极线 l2l_2l2​ 上存在着一个像素大小的误差,使得 βββ 角变成了 β′β^′β′,而 ppp 也变成了 p′p^′p′,并记上面那个角为 γγγ。我们要问的是,这一个像素的误差,会导致 p′p^′p′ 与 ppp 产生多大的差距呢?

根据上面的图,显然有:
a=p−tα=arccos⁡⟨p,t⟩β=arccos⁡⟨a,−t⟩\begin{aligned} a &=\boldsymbol{p}-\boldsymbol{t} \\ \alpha &=\arccos \langle\boldsymbol{p}, \boldsymbol{t}\rangle \\ \beta &=\arccos \langle\boldsymbol{a},-\boldsymbol{t}\rangle \end{aligned} aαβ​=p−t=arccos⟨p,t⟩=arccos⟨a,−t⟩​
对 p2p_2p2​ 扰动一个像素,将使得 βββ 产生一个变化量,成为β′β^′β′。根据几何关系:

β′=arccos⁡⟨O2p2′,−t⟩γ=π−α−β′\begin{aligned} \beta^{\prime} &=\arccos \left\langle\boldsymbol{O}_{2} \boldsymbol{p}_{2}^{\prime},-\boldsymbol{t}\right\rangle \\ \gamma &=\pi-\alpha-\beta^{\prime} \end{aligned} β′γ​=arccos⟨O2​p2′​,−t⟩=π−α−β′​

于是,由正弦定理,p′p^′p′的大小可以求得

∥p′∥=∥t∥sin⁡β′sin⁡γ\left\|\boldsymbol{p}^{\prime}\right\|=\|\boldsymbol{t}\| \frac{\sin \beta^{\prime}}{\sin \gamma} ∥p′∥=∥t∥sinγsinβ′​

因此,确定了由单个像素的不确定性引起的深度不确定性。如果认为极线搜索的块匹配仅一个像素的误差,那么就可以设:

σobs=∥p∥−∥p′∥\sigma_{\mathrm{obs}}=\|\boldsymbol{p}\|-\left\|\boldsymbol{p}^{\prime}\right\| σobs​=∥p∥−∥p′∥

如果极线搜索的不确定性大于一个像素是,可以按照次推导放大这个不确定性。
在实际工程中,当不确定性小于一定阈值时,就可以认为深度数据已经收敛了。

因此,估计稠密深度的一个完整过程为:

  1. 假设所有像素的深度满足某个初始的高斯分布;
  2. 当新数据产生时,通过极线搜索和块匹配确定投影点位置;
  3. 根据几何关系计算三角化后的深度以及不确定性;
  4. 将当前观测融合进上一次的估计中。若收敛则停止计算,否则返回 2。

这些步骤组成了一套可行的深度估计方式。书上说:这里的深度值是O1PO_1PO1​P的长度,与针孔相机模型李提到的“深度”有少许不同,针孔模型中的深度是指像素的z值。这里有些不懂,为什么不一样?懂的朋友希望评论区教我一下,感谢!

像素梯度的问题

在块匹配的过程中,过度依赖物体的纹理,即有明显梯度的小块匹配的准确性高,梯度不明显的反之。进而影响深度计算的精度。


像素梯度垂直于极线方向,以及平行于极线方向。先来看平行的情况。在平行的例子里,即使小块有明显梯度,但是当我们沿着极线去做块匹配时,会发现匹配程度都是一样的,因此得不到有效的匹配。反之,在垂直的例子里,我们能够精确地确定匹配度最高点出现在何处。而实际当中,梯度与极线的情况很可能位于二者之间:既不是完全垂直亦不是完全平行。这时,我们说,当像素梯度与极线夹角较小时,极线匹配的不确定性大;而当夹角较大时,匹配的不确定性变小。而在演示程序中,我们统一地把这些情况都当成一个像素的误差,实质是不够精细的。考虑到极线与像素梯度的关系后,应该使用更精确的不确定性模型。

逆深度

假设深度值满足高斯分布d∼N(μ,σ2)d \sim N\left(\mu, \sigma^{2}\right)d∼N(μ,σ2),会出现一些不合理的点:

  1. 我们实际想表达的是:这个场景深度大概是 5-10 米,可能有一些更远的点,但近处肯定不会小于相机焦距(或认为深度不会小于 0)。这个分布并不是像高斯分布那样,形成一个对称的形状。它的尾部可能稍长,而负数区域则为零。
  2. 在一些室外应用中,可能存在距离非常远,乃至无穷远处的点。我们的初始值中难以涵盖这些点,并且用高斯分布描述它们会有一些数值计算上的困难。

而逆深度为高斯分布是比较有效的,逆深度就是深度的代数d(−1)d_(-1)d(​−1)

图像间的变换

问题:我们假设了图像小块在相机运动时保持不变,而这个假设在相机平移能够保持成立,但当相机发生明显的旋转时,就难以继续保持了。特别地,当相机绕光心旋转时,一个下黑上白的图像可能会变成一个上黑下白的图像块,导致相关性直接变成了负数(尽管仍然是同样一个块)。

解决方案:将当前帧的图像小块变换到关键帧上对应的小块,使用关键帧上对应的图像小块进行匹配。也就是在块匹配之前,把参考帧与当前帧之间的运动考虑进来。

根据相机模型,参考帧上的一个像素 PRP_RPR​ 与真实的三维点世界坐标 PWP_WPW​ 有以下关系:

dRPR=K(RRWPW+tRW)d_{R} \boldsymbol{P}_{R}=\boldsymbol{K}\left(\boldsymbol{R}_{R W} \boldsymbol{P}_{W}+\boldsymbol{t}_{R W}\right) dR​PR​=K(RRW​PW​+tRW​)

类似的,对于当前帧,它亦有 PWP_WPW​ 在它上边的投影,记作 PCP_CPC​:

dCPC=K(RCWPW+tCW)d_{C} \boldsymbol{P}_{C}=\boldsymbol{K}\left(\boldsymbol{R}_{C W} \boldsymbol{P}_{W}+\boldsymbol{t}_{C W}\right) dC​PC​=K(RCW​PW​+tCW​)
消去PWP_WPW​,进而得到两幅图像的像素关系:

dCPC=dRKRCWRRWTK−1PR+KtCW−KRCWRRWTKtRWd_{C} \boldsymbol{P}_{C}=d_{R} \boldsymbol{K} \boldsymbol{R}_{C W} \boldsymbol{R}_{R W}^{T} \boldsymbol{K}^{-1} \boldsymbol{P}_{R}+\boldsymbol{K} \boldsymbol{t}_{C W}-\boldsymbol{K} \boldsymbol{R}_{C W} \boldsymbol{R}_{R W}^{T} \boldsymbol{K} \boldsymbol{t}_{R W} dC​PC​=dR​KRCW​RRWT​K−1PR​+KtCW​−KRCW​RRWT​KtRW​

当知道 dR,PRd_R,P_RdR​,PR​ 时,可以计算出 PCP_CPC​ 的投影位置。再给 PRP_RPR​ 两个分量各一个增量 du,dvdu, dvdu,dv,就可以求得 PCP_CPC​ 的增量 duc,dvcdu_c, dv_cduc​,dvc​。通过这种方式,算出在局部范围内,参考帧和当前帧图像坐标变换的一个线性关系,构成仿射变换:

[ducdvc]=[ducduducdvdvcdudvcdv][dudv]\left[\begin{array}{l} d u_{c} \\ d v_{c} \end{array}\right]=\left[\begin{array}{ll} \frac{d u_{c}}{d u} & \frac{d u_{c}}{d v} \\ \frac{d v_{c}}{d u} & \frac{d v_{c}}{d v} \end{array}\right]\left[\begin{array}{l} d u \\ d v \end{array}\right] [duc​dvc​​]=[duduc​​dudvc​​​dvduc​​dvdvc​​​][dudv​]

根据仿射变换矩阵,我们可以把当前帧(或参考帧)的像素进行变换后,再进行块匹配,以期获得对旋转更好的效果。

点云地图


点云地图为我们提供了比较基本的可视化地图,让我们能够大致了解环境的样子。它以三维方式存储,使得我们能够快速地浏览场景的各个角落,乃至在场景中进行漫游。点云的一大优势是可以直接由 RGB-D 图像高效地生成,不需要额外的处理。它的滤波操作也非常直观,且处理效率尚能接受。不过,使用点云表达地图仍然是十分初级的。
点云地图是“基础”的或“初级的”,是指它更接近于传感器读取的原始数据。它具有一些基本的功能,但通常用于调试和基本的显示,不便直接用于应用程序。如果我们希望地图有更高级的功能,点云地图是一个不错的出发点。

缺陷:

  1. 点云地图通常规模很大,所以一个 pcd 文件也会很大。
  2. 点云地图无法处理运动物体。

八叉树地图

八叉树地图有点像我的世界那样,使用一个一个方块进行堆叠。是一种灵活的、压缩的、又能随时更新的地图形式。

参考

1.视觉SLAM十四讲

SLAM【十一】建图相关推荐

  1. 探索无人驾驶汽车:SLAM自主建图技术。

    有一天,我会放开双手,任由汽车带着我遨游山河. 有一天,我会放松身心,透过车窗去看这美丽景色. 无人驾驶,随着科技的不断进步倍受关注,它不再是一个遥不可及的设想,也不再是只有在科幻片里才能看到的景象. ...

  2. 从零开始搭建ROS下无人机激光雷达SLAM——hector_slam建图入门——综述篇

    首先我们看下最终无人机SLAM定位的计算图,然后根据计算图追根溯源分析实现算法在ROS中实现的流程 从图中可以看出总共包含的ros节点有5个,分别所属三个包,其中包1.2是ROS官方现成直接可以使用的 ...

  3. 疑难杂症篇(十八)--ROS系统中使用SLAM算法建图时出现地图漂移的几种原因

    本篇主要介绍在ROS系统中使用SLAM算法建地图时出现地图定位漂移的几种原因及可以采取的措施. 1.SLAM建图时出现的定位漂移现象 2.原因分析 里程计数据发生异常: 计算机的配置不高,计算机建图过 ...

  4. 机器人学习--定位、建图、SLAM(声呐、激光等扫描束方案)的发展史

    本文作为学习激光SLAM尤其是2D激光SLAM的学习笔记,理清楚很多问题的前因后果,历史发展事件等, 读史使人明智. 假设已经知道了激光SLAM的代表方案:ROS wiki官方集成了的2D激光slam ...

  5. 移动机器人建图与导航代码实现——1.Hector SLAM

    Hector SLAM 这一部分利用hector slam完成建图和定位,暂无全局定位功能,使用2D激光雷达和里程计.测试中使用的GUI改编自https://www.cnblogs.com/scomu ...

  6. 高精地图构建与SLAM感知优化建图策略

    高精度地图对自动驾驶系统功能研发的影响已经越来越明显,整体上来讲主要包含但不仅限于提升车端感知性能.拓展自动驾驶新功能.动态建图等相关应用.具体体现在如下几个重要方面: 如上所述提升车端感知能力是通过 ...

  7. 【论文阅读记录】基于视觉SLAM建图的无人机路径规划 作者:王海

    目录 一.论文前瞻问题 二.论文内容概述 1.SLAM建图与路径规划综述 2.关键问题 3.SLAM中前后端设计部分 4.三维路径规划 三.拓展 一.论文前瞻问题 智能体在陌生环境中的一次自主导航任务 ...

  8. 【SLAM】基于explore_lite的移动机器人自主建图

    系列文章目录 ·[SLAM]基于explore_lite的移动机器人自主建图 ·[SLAM]基于rrt_explore的移动机器人自主建图 ·[问题解决]rrt_exploration功能包使用过程中 ...

  9. 基于Cartographer的建图与导航

    一. RoboSense 16线雷达驱动安装 2 二. Cartographer的安装 2 三. 配置文件结构说明 4 四. 配置文件详解 4 2D lua文件的配置 5 2D launch文件的配置 ...

最新文章

  1. 初探团队基于session的探索性测试
  2. python封装类连接mysql数据_python操作mysql数据库基本类封装
  3. 像小猪佩奇那样生活,需要多少钱?
  4. apache phoenix 入门_实现Phoenix入门
  5. c语言程序设计 高等教育,[高等教育]c语言程序设计.doc
  6. 双系统安装和ros安装踩坑
  7. gtest简短,简单易用
  8. 02 . 在 Linux 上安装Oracle11g 数据库
  9. 查看Jetson系列产品JetPack的版本信息
  10. Greensock平台
  11. python deap,安装Deap for Python(Spyder)
  12. ddwrt open*** tun
  13. 微信开发者工具控制台空白问题解决方案
  14. 多穿立体库系统四向车PLC流程控制
  15. understand学习
  16. linux红帽分区安装教程,RedHat Linux 9.0 硬盘安装教程手把手全部详细教程
  17. Elasticsearch之基础
  18. 计算机毕业设计-问答交流论坛小程序系统【代码讲解+安装调试+文档指导】
  19. 织女星开发板不能调试
  20. 拆赛欧2012款 左前门 门板

热门文章

  1. 天玥系列微型计算机,【简讯】AMD正式发布RX 6000系列显卡;OPPO K7x宣布…
  2. nvidia-driver-460防止驱动更新
  3. 什么牌子的蓝牙耳机音质好?2022好音质蓝牙耳机推荐
  4. ear的英语怎么念_ear是什么意思_ear翻译_读音_用法_翻译
  5. 教师在家长群内表扬配合家长的话术
  6. 牛语 and 采蘑菇的拖拉机
  7. 怎样制作Lrc歌词文件
  8. 腾讯云创建二级域名并解析
  9. java 使用Spire.Doc实现Word文档插入图片
  10. 〔首届CSDN.南京区程序员聚会〕正式报名情况[每日更新7月19日 17:30]