NeRF这两年确实火得不行,ICCV 2023上NeRF相关文章铺天盖地,有优化速度精度的,也有专门处理动态场景这类特殊情况的。不过NeRF和SLAM结合,目前还属于一个比较前沿的方向。卡脖子的问题很明显:实时性不好保证,而且大多数结合工作更侧重于稠密建图。像iMAP和NICE-SLAM这种同时优化位姿和建图的方案已经比较少见,估计出的位姿精度也明显低于传统SLAM,大尺度场景下建图会有遗忘问题,能结合回环检测的就更少了。
GO-SLAM这项工作,似乎在一定程度上把这些问题都解决了。它是ICCV 2023最新开源的工作,一个能实时优化位姿并进行稠密建图的NeRF SLAM框架。最大的亮点,在于引入了回环和BA(束调整)来校正轨迹和3D场景,这在很大程度上拉近了NeRF SLAM与传统SLAM在轨迹精度上的差距。以前的工作很少这么干,因为回环处理不好,很容易让位姿和NeRF模型之间产生割裂。
今天就带大家深入解读一下这项工作。水平有限,理解不当的地方,欢迎一起讨论。
效果展示
先看看具体效果。
GO-SLAM的核心还是基于NeRF进行稠密重建。可以发现,相比NICE-SLAM这些SOTA方案,GO-SLAM重建场景的全局一致性要好得多,关键就在于它引入了回环和全局BA来优化累计误差。

在各种室内场景的3D稠密重建上,都取得了相当不错的效果。

在EuRoC数据集上的定性重建结果也很能说明问题。相比DROID-SLAM,GO-SLAM的重建结果要干净得多!
摘要
神经隐式表示最近在稠密同步定位与地图构建(SLAM)上展示了令人信服的结果,但在重建过程中,相机跟踪误差和场景畸变会不断累积。为此,本文提出了一种基于深度学习的稠密视觉SLAM框架——GO-SLAM,对位姿进行全局优化,并实现实时三维重建。其核心是鲁棒的姿态估计,由有效的闭环和在线全BA支撑,通过利用输入帧完整历史的学习全局几何来优化每一帧。同时,实时更新隐式和连续的表面表示,以确保三维重建的全局一致性。在多种合成和真实数据集上的实验结果表明,GO-SLAM在跟踪鲁棒性和重建精度方面均优于现有方法。此外,GO-SLAM具有很强的通用性,可以在单目、双目和RGB-D输入下运行。
算法解析
GO-SLAM是最新的进行隐式3D重建的SLAM方案,一方面不断更新全局位姿,另一方面实时重建连续的稠密3D场景。
GO-SLAM由三个并行线程组成:前端跟踪、后端跟踪,以及实例建图。前端跟踪线程直接用了DROID-SLAM的跟踪模块,训练过程也是直接调用DROID-SLAM的预训练权重,只不过加入了新的回环和BA优化。然后使用RAFT来计算新一帧相对于最后一个关键帧的光流,如果平均流大于阈值,则创建新关键帧。后端跟踪线程的重点是通过全BA生成全局一致的位姿和深度预测。最后,实例建图线程根据最新的位姿信息实时更新三维重建。输入可以是单目、双目,也可以是RGB-D,非常通用!

那么回环检测具体怎么实现呢?
本质上还是一个基于关键帧的图优化问题。回环过程分为两步:
(1)选择最近N个局部关键帧之间的高可视性连接;
(2)从局部关键帧和局部窗口外的历史帧中检测回环关系。
具体实现时,作者为回环检测和BA建立了一个大的共视矩阵,矩阵元素是通过反投影得到的平均刚体光流。如果平均光流大于阈值,则认为共视程度低,会被直接滤除。共视矩阵的维度就是N×关键帧数量。
共视矩阵建立后,就可以为具有邻接关系和高共视关系的关键帧对建立优化边,也就是图中的红色方框。这里有一个trick,为了避免冗余,当优化边(两个关键帧的连接关系)加入图以后,就会抑制这两个关键帧的邻域关系。具体的回环检测流程是:从共视矩阵的未探索部分按共视程度降序采样,连续检测三个回环候选帧,如果平均流均低于阈值,则认为检测到了回环,然后进行优化。这个方法其实和ORB-SLAM2很像。

之后,就可以进行优化了。这里直接使用DBA层(具体原理可参考DROID-SLAM论文)来求解非线性最小二乘问题,同时优化相机位姿G和逆深度d。其中(i,j)表示连接关系,Π表示投影函数,p表示像素位置,公式里面的G表示位姿变换关系。最后使用高斯牛顿法来优化局部关键帧的最优位姿和深度。

后端优化这块,显然不能直接优化所有历史帧。作者的做法是:开启一个新的共视关键帧图,在插入新边后抑制冗余邻域边,这样可以很大程度上降低计算量。GO-SLAM考虑了输入帧的完整历史信息,并连续对齐所有关键帧位姿。它还使用对齐策略实现瞬时闭环和全局结构的校正,在内存和时间上都很高效。

现在可以用获得的位姿和深度图进行NeRF了。那问题又来了,如何确保更新后的重建保持全局一致呢?同时用所有关键帧来做NeRF,肯定能保证全局一致性,但也就没办法实时了。
这里作者对参与稠密重建的关键帧进行了筛选:
首先,确保包含最新的两个关键帧和未经建图优化的关键帧。然后将所有关键帧按照当前和上次更新状态之间的位姿差降序排列,并从排序列表中选择前10个关键帧。最后,为了解决遗忘问题,还使用分层抽样从所有可用的关键帧中选择10个关键帧。
后面NeRF的渲染就直接使用了现成的NeuS模型。
损失函数设置得比较多,除了常用的图像光度损失和深度损失,还引入了正则化项来优化SDF:

为了监督SDF进行精确的表面重建,还计算采样点xi到关键帧深度Dm的距离来近似采样点xi的真实SDF。在Dm - 预测深度(b)为不同值时,采取不同的损失函数策略:

最终的损失函数是几项小损失的加权和:
实验
实验部分,运行设备是i9-10920X CPU和一块3090。作者分别评估了轨迹精度和建图精度,更侧重轨迹精度,使用的数据集包括TUM RGB-D、EuRoC、ETH3D-SLAM、ScanNet还有Replica,轨迹评估非常全面。评估指标方面,主要使用ATE,其他指标包括准确率、完成率、完成比值,还有F指数,以及用L1评估深度估计的精度。
下面是在TUM数据集上的ATE对比结果,左侧是单目结果,右侧是RGB-D结果。GO-SLAM的精度达到最优,这也是第一次看到NeRF SLAM的精度超越传统方法。这个实验做得很详细,之前的NICE-SLAM和iMAP也只是对比了fr1/desk、fr2/xyz和fr3/office这三个序列,但GO-SLAM对比的序列很多,还同时对比了传统方法和学习方法。不过需要指出的是,ORB-SLAM3并没有在那么多序列上跟踪失败,实验结果中ORB-SLAM2/3的表现可能受到序列选择的影响。

下面是EuRoC实验,GO-SLAM的精度同样出彩。值得注意的是,传统SLAM在单目序列上容易跟踪失败,但GO-SLAM可以保持鲁棒性。

在EuRoC和ETH3D上还对比了稠密重建效果,GO-SLAM的重建精度优于DROID-SLAM。

下面是在ETH3D上的实验,y轴是成功的轨迹,x轴是RMSE精度,最大误差是2cm。这个结果说明GO-SLAM优于基于点、基于surfel、基于体素的方案。BundleFusion和GO-SLAM有点类似,只是更侧重稠密重建,但BundleFusion的姿态估计极易受误差影响,导致重建质量较差。

ScanNet上的结果表明,DROID-SLAM在短序列和RGB-D输入上表现较好,但在单目场景下处理较长序列时,精度急剧下降。相比之下,GO-SLAM的结果始终很稳定。此外,由于没有全局优化来消除累积误差,iMAP和NICE-SLAM在位姿估计和三维重建方面效果都不太理想。

最后是Replica实验,对比的方案也很全面,最新的Orbeez-SLAM都有。这里可以看出NICE-SLAM的运行速度确实太慢了。

大家肯定很关心运行效率。作者对比了CPU频率、GPU显存、FPS和最终精度。整体来看,GO-SLAM需要的计算资源还是比较多的,运行速度也不算快,但它在CPU/GPU需求和精度之间找到了一个平衡点。

总结
NeRF和SLAM结合是一个非常新兴的方向,有大量值得挖掘的点。GO-SLAM是ICCV 2023的最新工作,同时优化SLAM的轨迹和NeRF的稠密重建,效果非常出色。最大的意义在于,它第一次在NeRF-based SLAM中引入了回环检测和全局BA,以此来消除累积误差。这项工作目前还没有完全开源,感兴趣的朋友可以关注一下相关的Github进展。
