目标:理解单目SLAM中稠密深度估计的原理。通过实验了解单目稠密重建的过程。了解几种RGB-D重建中的地图形式。
简介:前面介绍的前端和后端,重点关注同时估计相机运动轨迹与特征点空间位置的问题。实际应用中还希望地图能够用于定位、导航、避障和交互,特征点地图不能满足所有需求。所以本讲将详细讨论各种形式地图。
目录
1、概述
- 地图用途归纳:
- 定位。
- 导航。机器人在地图中进行路径规划,寻找路径,控制自己运动到目标点。需要稠密的地图才可以。
- 避障。需要稠密地图。
- 重建。用于展示,或者用于通信。需要稠密地图。
- 交互。需要机器人对地图有更高层面的任职——语义地图。
2、单目稠密重建
2.1 立体视觉
- 稠密重建,需要知道每个像素点(大部分)的距离,解决方案:
- 单目相机,估计相机运动,并且三角化计算像素距离。
- 双目相机,利用左右目视差计算像素的距离
- RGB-D相机直接获得像素距离。
- 单目和双目方式称为立体视觉,与RDB-D相比,优缺点:
- 单目、双目方式,计算量巨大,结果不一定可靠。
- RGB-D,无法很好的应用与室外、大场景。
- 在给定相机轨迹的基础上,如何根据一段时间的视频序列估计某幅图像的深度。以第一幅图像为参考帧,计算参考帧中每个像素的深度。
- 匹配:确定第一幅图的某像素出现在其他图里的位置。用到极线搜索和块匹配技术。
- 深度:三角测量确定深度。这里需要很多次三角测量让深度收敛。用到深度滤波器技术。
2.2 极线搜索和块匹配
- 相机1观测的某个像素,对应的空间点分布在某条射线上,从相机2看,这条线段的投影也形成图像平面上的一条线,叫做极线。(当知道两相机间的运动,极线是确定的。)问题是,极线上哪个点对应?
- 在周围取小块,在极线上取很多同样大小的小块比较,可以提高区分性,即块匹配。该算法的假设:从像素的灰度不变性变成图像块的灰度不变性,一定程度是更强。
- 计算小块与小块间差异的方法:
- SAD(Sum of Absolute Difference),两个小块的差的绝对值之和
- SSD(Sum of Squared Distance),平方和
- NCC(Normalized Cross Correlation),归一化互相关。计算两小块的相关性。
- 除了以上简单版本,还可以先把每个小块的均值去掉,称为去均值的SSD、去均值NCC。
2.3 高斯分布的深度滤波器
- 对像素深度的估计,本身也可建模为一个状态估计问题,因此存在滤波器与非线性优化两种求解。考虑到实时性,建图通常采用计算量较少的滤波器方式。
- 对深度的分布假设存在不同做法。一种是假设深度值服从高斯分布;一种是均匀-高斯混合分布。这里介绍相对简单的第一种方式。
- 某个像素深度d服从:,每当薪数据到来,我们观测到它的深度,假设这次观测也是一个高斯分布:。
- 如何用观测的信息更新原先d的分布?根据高斯分布的乘积有:,。
- 我们仅有观测方程没有运动方程,因此这里深度仅用到了信息融合部分,无需像完整的卡尔曼滤波那样进行预测和更新。当前问题仍然存在:如何确定我们观测到深度的分布?即如何计算?
- 极线上一个像素大小的误差会导致与产生多大的差距呢?实际工程中,当不确定性小于一定阈值时,就可以认为深度数据已经收敛了。
- 综上,估计稠密深度(这里指长度,与针孔相机模型的深度不同,那个是像素的z值)的完整过程:
- 假设所有像素的深度满足某个初始的高斯分布
- 当新数据产生时,通过极线搜素和块匹配确定投影点位置
- 根据几何关系计算三角化后的深度及不确定性
- 将当前观测融合进上一次的估计中。若收敛则停止计算,否则返回第2步
3、实践:单目稠密重建
- 深度估计是一个动态的过程——从一个不怎么确定的初始值逐渐收敛到稳定值的过程。运行程序发现,稳定后的深度图,大致可以看出地板和桌子的区别,而桌上的物体深度则接近于桌子,整体估计大部分正确,但也存在大量错误估计。
- 待改进的地方
- 像素梯度问题
- 在块匹配时,有明显梯度的小块将具有良好的区分度,不易误匹配。但是梯度不明显的像素,难以有效估计深度。反映了立体视觉一个常见的问题:对物体纹理的依赖性。该问题无法在现有算法流程上加以改进并解决。
- 另外,像素梯度平行极线方向,以及垂直于极线方向,是两种极端的情况。
- 逆深度
- 深度的正态分布存在问题:实际上分布并不是高斯分布那样,是对称形状,它的尾部可能稍长,而负数区域则为0。而室外可能存在距离非常远的点,我们初始值难以涵盖这些点,用高斯分布描述它们存在难度。
- 而逆深度,为高斯分布式比较有效的。
- 图像间的变换
- 块匹配之前,做一次图像到图像间的变换是一种常见的预处理方式。例如,块匹配之前,通常将参考帧与当前帧之间的运动考虑进来。
- 并行化:效率问题
- 例如在示例中,二重循环中遍历所有像素,逐个进行极线搜索。可以通过GPU加速。
- 其他改进
- 各像素计算式独立的,深度估计结果不平滑。可以给深度估计加上空间正则项,可以使得深度图更平滑。
- 外点的处理
- 错误匹配的处理
- 像素梯度问题
- 当前,虽然双目和移动单目能够建立稠密地图,但通常认为它们过于依赖环境纹理和光照,不可靠。
4、RGB-D稠密建图
- RGB-D稠密建图相对更容易。最简单的方法:
- 根据估算的相机位姿,将RGB-D数据转为点云,然后拼接,最后得到一个由离散点组成的点云地图
- 在此基础上,若希望估计物体表面,可使用三角网格(Mesh)、面片(Surfel)进行建图
- 另外,可通过体素(Voxel)建立占据网格地图(Occupancy Map),可知道地图的障碍物信息。
4.1 实践:点云地图
- 用到两种滤波器:外点去除滤波器和体素网格的降采样滤波器。
- 与第5讲《相机与图像》不同处:
- 生成每帧点云时,去掉深度值无效的点。
- 利用统计滤波器方法去除孤立点。统计每个点与距离它最近N个点的距离值的分布,去除距离均值过大的点。
- 利用体素网格滤波器进行降采样。保证一定大小的立方体内仅有一个点,相当于对三维空间进行了降采样。
- 点云地图是基础的、初级的,更接近传感器读取的原始数据,具备一些基础功能,不便于直接用于应用程序。如果希望地图有更高级的功能,点云地图是一个不错的出发点,可以从点云构建占据网格地图或物体表面。
4.2 从点云重建网格
- 从点云文件基础上建立网格大致思路:计算点云法线,再从法线计算网格。
4.3 八叉树地图
- 点云地图缺陷:
- 文件大,有一些不必要的细节,浪费资源。
- 无法处理运动物理。
- 八叉树地图(Octo-map):导航中比较常用、本身有较好压缩性能的地图。
- 从一个大立方体均匀分成八块,直到变成最小的方块为止。
- 八叉树,在节点中存储它是否被占据的信息,当某个方块的所有子节点都被占据或者都不被占据时,就没必要展开这个节点。因此相比点云节省大量存储空间。
- 用概率对数值描述某节点被占据。
- 假设在RGB-D图像中观测到某个像素带有深度d,说明:在深度值对应的空间点上观察了一个占据数据,并且,从相机光心出发到这个点的线段上是没有物体的(否则会被遮挡)。利用该信息,可以对八叉树更新,并处理运动结构。
4.4 实践:八叉树地图
5、TSDF地图和Fusion系列
下面介绍一种以“建图”为主体,定位居于次要地位的做法,即实时三维重建。
- TSDF地图(Truncated Signed Distance Function),翻译为截断符号距离函数。
- 是一种网格式地图。不同的是,TSDF地图整个存储在显存而不是内存中,可利用GPU并行特性。
- 每个TSDF体素内存储了该小块与距其最近的物体表面的距离。若小块在该物体前面,则它是正值,否则,是负值。
- TSDF也有“定位”、“建图”两个问题。
- 定位问题:主要是如何把当前RGB-D图像与GPU中的TSDF地图进行比较,估计位姿。
- 建图问题:如何根据估计的相机位姿,对TSDF地图进行更新。
6、小结
- 本讲地图偏重于度量地图,而不是拓扑地图。