当前位置: 首页 > news >正文

Gaussian-Splatting-SLAM 结合前沿高斯泼溅与slam,这一篇我有时间会复现一下

Gaussian Splatting SLAM

  • 日期:2026-06-21
  • 论文链接:https://arxiv.org/abs/2312.06741
  • 代码仓库:https://github.com/muskie82/MonoGS
  • 项目主页:https://rmurai.co.uk/projects/GaussianSplattingSLAM/
  • 作者与机构:Hidenobu Matsuki, Riku Murai, Paul H. J. Kelly, Andrew J. Davison;Imperial College London / Dyson Robotics Lab 相关团队
  • 发表 venue / 年份:CVPR 2024 Highlight

一句话总结

Gaussian Splatting SLAM(仓库中常称 MonoGS)把 3D Gaussian Splatting 从“离线重建 + 已知 SfM 位姿”的范式改造成可在线运行的稠密 SLAM:用同一组 3D Gaussians 同时支持相机跟踪、局部建图和高质量渲染。它的工程核心不是再维护传统点云/TSDF/NeRF 隐式场,而是把高斯作为唯一地图表示,并通过可微光栅化把位姿和地图参数放进同一个优化闭环。

工程视角:这篇论文要实现什么

从实现角度看,系统要做的是一个 RGB 单目优先、可扩展到 RGB-D / Stereo 的在线稠密 SLAM。输入是按时间到来的图像帧,以及可选深度或双目几何;输出包括当前相机位姿、关键帧轨迹、持续增长和优化的 3D Gaussian 地图,以及可用于可视化的 novel-view 渲染图像。

运行时可拆成四类模块:

  1. Tracking 前端:给定上一帧位姿预测和当前 Gaussian 地图,渲染当前视角,最小化当前真实图像与渲染图像的 photometric / depth loss,优化当前帧相机位姿。
  2. Keyframe / Mapping 管理:决定当前帧是否成为关键帧,维护局部窗口内关键帧集合,为地图优化提供观测。
  3. Gaussian Map 更新:对高斯的均值、尺度、旋转、不透明度和颜色参数做局部优化;必要时新增、剪枝或重置高斯。
  4. GUI / Logging / Evaluation:实时显示轨迹和渲染结果,保存 checkpoint,计算 ATE、渲染质量等指标。

论文报告的在线速度约为数 FPS 量级;仓库 README 还提到 speed-up 分支在高端 GPU 上可达到更高帧率。工程上这类系统高度依赖 CUDA 可微 rasterizer、PyTorch autograd、关键帧数量控制和显存管理。

核心数据结构与状态量

传统 VSLAM 中地图点常是MapPoint{position, descriptor, observations};这里的地图基本单元变成 3D Gaussian。一个面向实现的结构体可以写成:

structGaussian{Vec3 mu_world;// 3D 均值,世界坐标Quat q_world;// 各向异性椭球旋转Vec3 log_scale;// 三轴尺度,通常优化 log-space 保证正数floatopacity_logit;// alpha,不透明度参数,常用 sigmoid 映射Vec3 sh_dc_or_rgb;// 低阶颜色;完整 3DGS 可用 SH 系数VecN sh_rest;// 可选高阶 spherical harmonicsintlast_seen_kf;intobs_count;};structFrame{intid;Image rgb;Optional<Image>depth;Mat3 K;SE3 T_cw;// world -> camera 或 camera -> world,必须全工程统一boolis_keyframe;};structKeyframe:Frame{Image grad_mask;// 选择有信息量像素Image valid_depth_mask;// RGB-D / Stereo 时使用vector<int>visible_gaussians;};structGaussianMap{Tensor xyz;// [N,3]Tensor rotation;// [N,4]Tensor scaling;// [N,3]Tensor opacity;// [N,1]Tensor features;// [N,C]Optimizer map_optimizer;};

状态量分两层:

  • 相机状态:当前帧T_cwT_wc。单目场景中尺度和深度初始化是难点,系统需要从几何验证、深度先验或多视角增量中稳定地图。
  • 地图状态:所有 Gaussian 参数。实际代码里通常以 PyTorchnn.Parameter/ Tensor 形式批量存储,而不是大量 C++ 对象,否则 autograd 和 GPU kernel 调用会非常低效。

如果要在 C++/CUDA 中复写,建议逻辑层保留类,但优化层必须是 SOA(structure of arrays):float* xyz, *scale, *quat, *opacity, *color,便于 rasterizer coalesced memory access。

算法主流程

在线主循环可以抽象成下面的伪代码:

map=GaussianMap()keyframes=[]T_prev=Identity()forframeinstream:ifnotmap.initialized:T_cw,init_gaussians=initialize(frame,next_frame_or_depth)map.add(init_gaussians)keyframes.append(make_keyframe(frame,T_cw))continue# 1. Tracking:只优化当前位姿,不大幅改地图T_init=motion_model(T_prev)T_cw=optimize_pose_by_rendering(frame.rgb,frame.depth,map,T_init,K,iters=tracking_iters,loss_weights={"rgb":w_rgb,"depth":w_depth})# 2. 判断是否关键帧ifneed_new_keyframe(frame,T_cw,keyframes,map):kf=make_keyframe(frame,T_cw)keyframes.append(kf)# 3. 用当前观测补充新高斯candidates=find_unexplained_pixels(frame,render(map,T_cw))new_gaussians=backproject_or_triangulate(candidates,frame,keyframes)map.add(new_gaussians)# 4. Mapping:优化局部窗口内高斯和可选关键帧位姿local_window=select_local_keyframes(keyframes)foriinrange(mapping_iters):k=sample(local_window)pred=differentiable_render(map,k.T_cw,k.K)loss=photometric_loss(pred.rgb,k.rgb,mask=k.mask)loss+=depth_loss(pred.depth,k.depth,mask=k.valid_depth)loss+=regularization(map)loss.backward()map.optimizer.step()prune_or_densify_if_needed(map)T_prev=T_cw

注意:论文和官方实现的具体调度会更细,例如单目初始化、几何验证、关键帧采样和 GUI 进程通信;但主干就是“位姿用当前地图 render 对齐,地图用关键帧 render 反向传播更新”。

关键模块实现细节

1. 前端跟踪:rendering-based direct tracking

输入:当前 RGB 图、可选深度图、内参 K、上一帧位姿预测、当前 GaussianMap。
输出:当前帧位姿T_cw和 tracking loss / valid mask。

实现步骤:

  1. 把位姿参数化为 Lie algebrase3增量或可优化 quaternion + translation。
  2. 用可微 Gaussian rasterizer 在当前位姿下渲染 RGB、深度、silhouette / alpha。
  3. 构造 loss:
    • RGB:L1L1 + SSIM
    • 深度:有深度传感器时加|D_render - D_obs|
    • mask:只在有足够 alpha、非动态、非无效深度区域计算。
  4. 只更新 pose optimizer,地图参数先requires_grad=False或不传给 optimizer。

关键超参:tracking 迭代次数、金字塔层数或图像下采样倍率、RGB/depth 权重、有效 alpha 阈值、鲁棒核阈值。
坑点:

  • T_wc/T_cw方向极易写反。建议所有渲染接口显式命名world_to_camera
  • 单目 photometric tracking 在纯旋转、低纹理、曝光变化时会陷入局部最小。
  • 可微 rasterizer 的 pose gradient 需要支持相机位姿反传;官方 README 指向了带 pose gradient 的 rasterizer fork。

2. 后端优化:局部关键帧上的 differentiable mapping

输入:局部关键帧集合、当前 GaussianMap。
输出:更新后的 Gaussian 参数,必要时更新关键帧位姿。

工程上不应每次用所有关键帧优化全图,否则显存和时间都会爆。常见策略:

  • 维护滑窗:最近若干关键帧 + 与当前视角重叠高的关键帧;
  • 每次迭代随机采样一个或几个 keyframe;
  • 对每个 keyframe 渲染全图或可见高斯子集;
  • 用 Adam 优化 Gaussian 参数。
forstepinrange(num_steps):kf=random.choice(local_keyframes)render_pkg=rasterize(map.params,kf.T_cw,kf.K,H,W)loss_rgb=l1_ssim(render_pkg.rgb,kf.rgb,mask)loss_d=depth_l1(render_pkg.depth,kf.depth,valid_depth)ifhas_depthelse0loss=loss_rgb+lambda_d*loss_d+lambda_reg*reg_terms(map)optimizer.zero_grad()loss.backward()optimizer.step()

复杂度主要取决于可见 Gaussian 数量、图像分辨率和 rasterizer tile 排序。实现上应尽量避免 Python 层逐点循环。

3. 地图更新:新增、剪枝与几何验证

论文强调为了在线 SLAM,需要突破原始 3DGS 对离线 SfM 位姿的依赖。代码里通常要回答两个问题:哪里需要新高斯?哪些高斯不可信?

  • 新增高斯:在当前帧中找渲染解释不好的像素,例如 alpha 低、photometric residual 高、depth residual 高;有深度时直接反投影;单目时可由相邻关键帧几何或初始化策略给深度。
  • 几何验证:检查候选高斯是否在多帧投影一致、深度顺序合理、不是漂浮噪声。
  • 剪枝:删除 opacity 长期很低、尺度异常、观测次数太少或总是产生高 residual 的高斯。
  • 局部 densification:类似 3DGS,根据梯度和尺度把大高斯 split / clone;但在线系统要更保守,否则实时性和显存会失控。

4. Keyframe 管理

Keyframe 策略直接决定稳定性。常见触发条件:

  • 与最近关键帧平移/旋转超过阈值;
  • 当前视角可见地图比例低;
  • tracking loss 或 unexplained pixels 比例高;
  • 距离上次关键帧已有固定帧数。

局部窗口选择可用 covisibility:渲染时统计哪些 keyframe 共享高斯,优先保留重叠高且时间近的帧。坑点是窗口太小会遗忘,太大则 mapping 卡顿。

5. 初始化、重定位、失败恢复

单目高斯 SLAM 的初始化比 RGB-D 难很多。一个最小实现可以先从 RGB-D 或 Replica/TUM depth 版本做起:第一帧按深度反投影生成高斯,再逐步加入 tracking。若必须单目,建议先实现两帧特征匹配 + Essential matrix + 三角化,得到稀疏点和相对位姿,再把稀疏点膨胀为初始高斯。

失败恢复方面,工程上应记录:tracking loss、有效像素比例、位姿增量范数、渲染 alpha 覆盖率。一旦超阈值,可以回退到上一关键帧位姿、扩大迭代次数、降低分辨率、或触发基于图像检索的 relocalization。原始系统主要聚焦在线重建和跟踪,生产级闭环/重定位仍需额外模块。

数学模型到代码的对应关系

3D Gaussian 在世界坐标中有均值mu和协方差Sigma = R S S^T R^T。给定相机位姿和投影函数,rasterizer 把 3D 高斯投到 2D 椭圆,并按深度排序做 alpha blending。代码中你通常不手写完整 Jacobian,而是依赖 CUDA rasterizer + PyTorch autograd;但你必须清楚变量流:

Gaussian params + Camera pose -> project / rasterize -> rendered_rgb, rendered_depth, alpha -> residual against observed image/depth -> backward gradients -> Adam updates pose or map

Tracking residual 可写成:

r_rgb[p]=I_obs[p]-I_render[p;T_cw,G]r_d[p]=D_obs[p]-D_render[p;T_cw,G]loss=sum(mask[p]*rho(abs(r_rgb[p])))+lambda_d*sum(valid[p]*rho(abs(r_d[p])))

代码对应关系:

  • T_cw是优化变量时,Gaussian 参数 detach;
  • 地图优化时,xyz/scaling/rotation/opacity/color是优化变量,关键帧位姿可固定或少量联合优化;
  • rho可以先用 L1/Huber,动态场景多时必须加入 mask 或鲁棒核;
  • 深度监督不是必须,但 RGB-D 模式显著降低初始化和尺度漂移难度。

一个常见错误是把 alpha 很低的像素也纳入 photometric loss,导致背景未建模区域把位姿拉偏。因此有效 mask 应结合 rendered alpha、观测深度、图像梯度和边界裁剪。

关键创新点

  1. 把 3D Gaussians 作为 SLAM 唯一地图表示:不再同时维护稀疏点云、TSDF 或 NeRF MLP,tracking 和 mapping 都通过同一 GaussianMap 完成。
  2. 基于 3DGS 的直接相机跟踪:通过可微渲染对当前相机位姿做 photometric alignment,使原本依赖 SfM pose 的 3DGS 能在线闭环运行。
  3. 面向单目在线建图的几何验证与地图管理:解决新高斯插入、错误高斯抑制和漂浮物问题,属于从离线 3DGS 到 SLAM 的关键工程改造。
  4. RGB-D / Stereo 可扩展性:同一框架可用深度观测增强 residual 和初始化,使工程复现可以先从有深度版本开始。
  5. 实时交互式稠密渲染能力:地图天然可渲染,方便可视化、调试和下游 AR/机器人任务。

实验与结果

论文在多种室内 SLAM / novel-view synthesis 场景中验证,包括 TUM RGB-D、Replica 等常见数据集,并与传统 SLAM、NeRF-SLAM 或其他稠密重建方法比较。指标通常包括:

  • 轨迹精度:ATE / RPE;
  • 渲染质量:PSNR、SSIM、LPIPS;
  • 运行效率:tracking / mapping FPS、显存占用;
  • 地图质量:重建完整性和视觉伪影。

原文表格中给出了具体数值,本文不复述具体数值,以免脱离论文版本产生误差。主要结论是:该方法在保持在线运行的同时能获得比许多传统稠密 SLAM 更高质量的可渲染地图,并展示了单目 3DGS SLAM 的可行性。

复现路线:从零写一个最小版本

建议不要一上来复现完整单目 MonoGS,而按以下 MVP 递进:

阶段 0:环境和数据

  • Ubuntu + CUDA GPU;Windows 上建议 WSL2 或 Linux 服务器。
  • PyTorch、CUDA extension、diff-gaussian-rasterization-w-pose。
  • 数据集先选 Replica 或 TUM RGB-D,保证有内参、时间戳和深度。

阶段 1:离线单帧 Gaussian 初始化

  1. 读取 RGB-D 第一帧;
  2. 按深度反投影成点云;
  3. 每个采样点生成一个小 Gaussian;
  4. 用固定相机位姿渲染回原视角,确认颜色和深度大致正确。

验证日志:Gaussian 数量、alpha 覆盖率、render FPS、rendered depth min/max。

阶段 2:只做 tracking

  1. 固定地图;
  2. 读取下一帧;
  3. 优化se3位姿增量,使渲染图对齐观测图;
  4. 与数据集 GT 比较相对位姿误差。

最小 tracking optimizer:

xi=torch.zeros(6,requires_grad=True,device="cuda")opt=torch.optim.Adam([xi],lr=1e-3)foritinrange(50):T=exp_se3(xi)@ T_init pred=render(gaussians.detach(),T,K)loss=masked_l1(pred.rgb,image,pred.alpha>0.5)opt.zero_grad();loss.backward();opt.step()

阶段 3:关键帧 mapping

  • 每隔固定帧数插入 keyframe;
  • 对局部 keyframe 优化 Gaussian 颜色、opacity、scale、xyz;
  • 加入 opacity pruning,避免地图无限增长。

阶段 4:新增高斯

  • alpha < threshold或 depth residual 大的像素反投影;
  • 限制每帧新增数量,例如随机采样 1k-5k 点;
  • 对新高斯设置较小初始尺度和 opacity。

阶段 5:单目化

  • 用两帧初始化或预训练深度估计提供初始深度;
  • 引入尺度一致性检查;
  • 增加关键帧间几何验证。

代码阅读指南

官方仓库:https://github.com/muskie82/MonoGS

建议阅读顺序:

  1. README.md:安装、数据下载、运行 demo;确认使用的是 CVPR 2024 对应主分支还是 speed-up 分支。
  2. slam.py:通常是系统入口,先看配置解析、进程/线程启动、主循环调度。
  3. configs/:查看 mono、rgbd、stereo 不同模式的 tracking/mapping 迭代次数、学习率、关键帧阈值。
  4. gaussian_splatting/:理解 GaussianModel、render 调用、optimizer 参数组。
  5. utils/:通常包含相机、loss、数据集 reader、评估工具。
  6. gui/:可最后看,主要用于可视化,不是算法主干。
  7. submodule 中的diff-gaussian-rasterization-w-pose:如果 tracking 梯度异常,必须深入看这里的 forward/backward 和相机 pose gradient。

阅读时建议先跑:

gitclone https://github.com/muskie82/MonoGS.git--recursivecdMonoGS condaenvcreate-fenvironment.yml conda activate MonoGSbashscripts/download_tum.sh python slam.py--configconfigs/mono/tum/fr3_office.yaml

若只是学习算法,可以先在配置中降低分辨率、减少迭代次数,并打开更多 loss / timing 日志。

工程调参与踩坑

  • CUDA 扩展编译:PyTorch、CUDA、gcc 版本不匹配会导致 rasterizer 编译失败;先严格按 README 推荐版本。
  • 位姿梯度不可用:普通 3DGS rasterizer 不一定支持 camera pose gradient,需要仓库指定 fork。
  • 显存增长:新增高斯无上限会迅速 OOM;必须有 pruning、keyframe window 和最大新增点数。
  • 尺度漂移:单目模式下深度初始化和尺度约束不足会导致地图整体膨胀或收缩。
  • 曝光变化:纯 RGB loss 对自动曝光敏感,可加入 affine brightness correction 或更鲁棒的颜色归一化。
  • 动态物体:人和移动物体会被写进高斯地图,导致 tracking 偏移;工程部署要接语义/运动 mask。
  • 低纹理区域:photometric gradient 弱,pose 优化不稳定;可提高几何项权重或依赖 IMU/深度。
  • 关键帧太密:mapping 变慢、重复高斯多;太稀则新增区域少、跟踪容易丢。
  • 坐标系混乱:OpenGL / OpenCV 相机坐标、列主序/行主序、T_wc/T_cw要统一写单元测试。
  • 实时性:Python 主循环、GUI、rasterizer、optimizer 都可能成为瓶颈;要记录 per-frame tracking time、mapping time、Gaussian count。

局限性与改进方向

  • 闭环能力有限:与 ORB-SLAM3 / DROID-SLAM 等相比,生产级 place recognition、loop closure、global BA 仍需增强。
  • 单目初始化脆弱:强依赖早期视差和场景纹理;加入 IMU 或 learned depth 会更稳。
  • 动态场景处理不足:需要语义分割、运动一致性或可变对象层表示。
  • 大场景扩展性:全局 Gaussian 数量巨大时,需 submap、空间哈希、LOD 或 out-of-core 管理。
  • 优化稳定性:3DGS 参数多且耦合强,学习率、densification、opacity reset 过激都会导致发散。
  • 机器人部署:若要上车/上机,需要时间同步、滚快门处理、在线标定、IMU/轮速融合和确定性实时调度。

延伸阅读

  1. 3D Gaussian Splatting for Real-Time Radiance Field Rendering,Kerbl et al., SIGGRAPH 2023:理解 Gaussian 表示和 rasterizer 的基础。
  2. DROID-SLAM,Teed and Deng, NeurIPS 2021:学习 dense correspondence + recurrent update 的高精度视觉 SLAM。
  3. NICE-SLAM,Zhu et al., CVPR 2022:代表性 NeRF/隐式场 RGB-D SLAM,可与 Gaussian SLAM 对比地图表示。
  4. SplaTAM,Keetha et al., 2023/2024:另一条 3DGS SLAM 路线,适合理解 RGB-D Gaussian tracking/mapping。
  5. ORB-SLAM3,Campos et al., T-RO 2021:工程化 SLAM 系统的多地图、重定位、回环和 BA 设计参考。
http://www.jsqmd.com/news/1072306/

相关文章:

  • 抚顺黄金白银回收铂金旧金回收无套路门店 TOP 榜单 实地测评资料整理
  • UNiTY疑难杂症
  • 如何三步彻底解决C盘爆红问题:Windows Cleaner实战指南
  • 先导01:SEMI 行业标准体系总览 E4/E5/E37/E87/E40/E94 完整拆解
  • 武汉全屋定制秘籍:转角柜这样设计,衣柜收纳空间大提升!
  • Google研究:对话式医疗系统AMIE升级,管理推理能力不劣于人类医生!
  • 鸿蒙 Next 小众爱好图鉴 App 开发实战:兴趣发现 + 分类系统 + 收藏管理
  • 数据分析向云迁移时如何避免混乱
  • 分人群定制:不同角色如何用好AI建站工具?
  • Python:第11天:异常处理 —— 让程序不轻易崩溃
  • AutoGen 核心 Agent 聊天与对话模式
  • 2026 年企业级大模型API聚合网关选型实录:十款主流平台技术横评与场景匹配
  • 2026年最新选购参考:天学网和科大讯飞到底哪个更适合入手?
  • 三年累亏超3亿、现金流持续为负,思必驰凭什么再闯科创板?
  • 6个本科绿牌专业薪资大揭秘,3S专业就业差距在哪?
  • 告别GitHub英文困扰:5分钟实现中文界面的完整指南
  • AI教材写作必备:低查重AI工具,助你快速打造精品教材!
  • 2026年AI聚合平台大揭秘!哪家公司更胜一筹?
  • 手把手教你从0到1搭建一个AI Agent(智能体)
  • 深度解密:掌握微信数据库AES-256-CBC加密逆向工程核心技术
  • 工业品短视频推广/必打标+必触达+必搜到,工业品短视频推广整套降本打法
  • NS-USBLoader终极指南:3步搞定Switch游戏管理与系统破解
  • AI 时代软件工程巨变:瓶颈转移、角色模糊,未来何去何从?
  • 显卡驱动彻底清理终极指南:为什么你需要Display Driver Uninstaller?
  • 2026气液增压器品牌格局重塑:国际、台系与国产的三方博弈
  • 终极QQ音乐解密工具qmcdump:三步解锁加密音乐自由播放
  • 洛雪音乐六音音源终极修复指南:5分钟恢复完整音乐体验
  • 知名的GPRC5D(Detergent)膜蛋白厂家名声
  • 不再依赖L6和C2C12:云克隆大鼠骨骼肌细胞(SkMC)原代细胞为肌肉研究提供“未经改造”的真实视角
  • 如何快速上手AlienFX Tools:Alienware灯光、风扇和电源控制的终极指南