Skip to main content

DSO Dissection (Direct Sparse Odometry 解构)

Published: arXiv 1607.02565 (2016) · IEEE TPAMI 2018 · Engel, Koltun, Cremers (TUM CV Group + Intel Labs) arXiv: https://arxiv.org/abs/1607.02565 · Code: https://github.com/JakobEngel/dso(2.4k ★ · 922 fork · GPL-3.0 · 66 commits · master 最近 commit 2018-ish · 视同冻结) 核心定位: 主流视觉 SLAM 没有走的那条路。直接法跳过 keypoint,直接在原始像素亮度上最小化光度误差 —— 在富梯度场景下子像素精度赢,但光度标定强制、曝光变化致命、完全没有闭环。DSO 是经典直接 VO 的顶点;2018 之后注意力转向 learned-BA(DROID-SLAM)+ feed-forward dense(DUSt3R / VGGT)。
Status: v1。UNVERIFIED 数字 inline 标注;GitHub-validated pitfalls 锚 atlas。 TL;DR: DSO 证明视觉 SLAM 可以不用描述子,但代价是把 ORB-SLAM3 留给闭环的最后一公里整段砍掉。选 DSO 的人是为了单目稠密初始化 + 低纹理高梯度场景(如长走廊、HDR 室内);选 ORB-SLAM3 的人是为了多 session + 多模态 + 闭环。两条路 2026 都没合流 —— 学界把希望挪给了 hybrid (3R-SLAM family) 和 feed-forward (VGGT)。

1 · X-Ray — 与 ORB-SLAM3 的架构对比

1.1 一句话差分

ORB-SLAM3 = ORB 特征 → 描述子匹配 → reprojection BA → DBoW2 闭环 → Atlas 多图 DSO = ~2000 个高梯度像素 → 直接 photometric BA on 滑窗 7 KFs → 没有闭环 → 没有 Atlas

1.2 ⚡ Eureka Moment

跳过特征提取 —— ORB-SLAM 留 1% 的像素丢 99%;DSO 直接在原始亮度上跑优化。 “keypoint” 是降维近似 —— 当你信任光度标定时,原始像素本身就是更好的 residual。
直接法的根本主张:特征 SLAM 把 image 蒸馏成 keypoint 是信息损失。如果你愿意付出光度标定(vignetting + 曝光时间 + 非线性响应),你能直接拿亮度做 residual,子像素精度免费送、半稠密地图免费送、对低纹理场景更稳健。代价是 —— 你需要永远精确地拿到曝光值。 ORB-SLAM 的赌注:keypoint 抽象 + Hamming 距离 + 旋转不变足以在 messy real-world 取胜。 DSO 的赌注:精确光度模型 + 高梯度像素 + 滑窗优化精度更高。 2026 实证:ORB-SLAM 赢了 deployment;DSO 赢了精度(在它的小工作包络内);hybrid(3R-SLAM)是真正的继任。

1.3 三线程?不,DSO 只有一个滑窗


2 · 数学核心

📌 Napkin Formula — Photometric Residual

直觉:
  • ORB 的 residual 单位是像素(reprojection),DSO 的 residual 单位是亮度差(光度)。
  • DSO 多出来的 (a_i, b_i):每 KF 一对 affine brightness 参数 —— 这是 DSO 不用 ORB 直接吃 HDR 切换 / 自动曝光的方式(理论上)。
  • 没有 (a, b) 联合优化时,自动曝光相机 1 秒内可以让 DSO drift 翻倍。这就是 DSO 论文 §2 的核心贡献。

2.1 一个公式,一个尺度(vs ORB-SLAM3 三尺度)


3 · 📍 研究全景时间线 — Direct vs Indirect vs Semi-direct

为什么 DSO 是终点不是中点?因为它要的”精确光度标定 + 全局曝光值”在真实相机栈(rolling shutter + auto-exposure + 温度漂焦距)里就是不可得的。Engel 后来去了 Oculus,Cremers 团队转向 DROID-SLAM。 没有继任者 = 不是没人想做,是物理学不让。

4 · 玩具例子:带数字走一遍

EuRoC MAV MH_01_easy(512×512 mono、20 Hz、室内、TUM mono dataset 光度标定)。x86 笔记本(Intel i7, 2018 测)UNVERIFIED: 对比 ORB-SLAM3 室内 30 Hz:tracking 17 ms / local mapping ~100 ms/KF(异步)。数字几乎一样 —— DSO 不是更快,而是更精确(在它的小工作包络内)。 实测 ATE(论文 EuRoC MAV 报告):DSO mono 室内 1-5 cm(在已光度标定 dataset 上);ORB-SLAM3 stereo+IMU 2-10 cm(在所有 EuRoC 序列)。 陷阱:DSO 的 1 cm 是光度标定可控 下;丢掉 vignetting calibration,DSO 精度直接掉 10×(README 原话 “poor calibration can reduce accuracy by 10x”)。这不是 ORB-SLAM 的常规预算。

5 · 工程:为什么 DSO 是 frozen at 2018

GitHub 站点信号: Jakob Engel 去 Oculus 之后,TUM Cremers 组的注意力整段转向 deep learning 路线(DROID-SLAM, DUSt3R, MASt3R, MonST3R 都源自 Cremers/Niessner 圈)。原仓视同论文 reproducer,不是产品。 DM-VIO(Engel/Cremers 2022,DSO + IMU 紧耦合)是非官方”DSO 2”,但同样维护稀疏。TartanVO / DROID-SLAM 才是 direct lineage 的真正延续 —— 但它们已经不是 direct 了,是 learned。

6 · 能力与失败模式

出货场景: 离线 mono 重建(已光度标定 dataset);研究用 photometric baseline;TUM mono dataset 复现;少数学术机器人 demo(地面慢速 + 已标定相机)。 失败场景:
  • Rolling-shutter 相机 —— DSO README 明说”not recommended for rolling-shutter”。手机 / D435 / 一切 IMX477 类 sensor 排除。
  • 自动曝光相机 —— 没有 a/b affine 模型外的 exposure metadata → drift 翻倍。
  • HDR / 强光切换 —— affine 模型只吃 first-order brightness 变化;窗户 / 阴影边界 fail。
  • 大基线 / 快速旋转 —— direct image alignment 收敛半径远小于 ORB 描述子匹配;快速旋转直接 lose tracking。
  • 闭环场景 —— 永远不会发生 → 漂移单调累积。回到起点的累积 yaw / position 误差不会被修。
  • 多 session —— 没有 Atlas。tracking lost = session 结束。
  • 低帧率 (<10 fps) —— photometric assumption 要求帧间 brightness 平滑过渡。

6.1 Hidden Assumptions(隐含假设)

  • 光度标定永远精确 —— vignetting / exposure time / non-linear response 三件都得标定 + 在每帧时间戳上拿到正确曝光值。任何一件 drift 就是 catastrophic。
  • 静态刚性世界 —— 跟 ORB-SLAM3 一样,动态物体污染光度模型。
  • Affine brightness 模型足够 —— 真实 HDR / 全局曝光变化超出 (a, b) 容量。
  • Global shutter —— rolling shutter 让 warp 模型瞬间崩。
  • 足够梯度像素 —— 全白墙 / 无纹理 → point selection 无候选 → tracking lost(feature SLAM 同样痛,但 DSO 没有 ORB fall-back)。
  • 滑窗够长 + FEJ 够稳 —— 没有闭环兜底,滑窗 marginalization 必须永远健康。

6.2 GitHub 实地失败(atlas 联动)

  • GitHub-validated:121 open issues + 主仓 6+ 年无动作 —— issue tracker 全是 build / 内存安全 / 依赖更新(Pangolin v0.6 / Boost / SuiteSparse),无 maintainer 回复;社区 fork 各做各的;详见 github_failure_atlas.md。
  • GitHub-validated:use-after-free 内存安全 issue #269(2024-03 open)—— C++ 历史代码的 segfault;产品部署必须自维 patch;ORB-SLAM3 #919 heap corruption 类似但至少有社区 fork (thien94/...),DSO 没有这样的归一 fork。
  • GitHub-validated:光度标定文档缺失 issue #263 “Where photometric error is in this project” —— 用户不知道光度模型在哪、怎么对自家相机标定;TUM mono dataset 的标定文件没法迁移到 D435 / iPhone;这印证了”光度标定永远精确”的隐含假设在生产线上根本不成立。

7 · 7.5 · GitHub-validated pitfalls (2026-05-24 deep dive)

扫描 121 个 open issue,分布于 build hell / 光度标定不通 / memory safety / rolling-shutter 误用四大类。引用 issue 链接 + 原文。
Repo health signal:2.4k ★ / 122 PR closed / 121 open issues / 0 ROS 2 主仓支持 / last commit ~2018 / 商业版分流 / Engel 个人 GitHub 主活动转向 [Oculus 内部 stack(不公开)] 读者实务含义:
  1. DSO 是 2016 论文实现,不是 2026 活跃产品 —— 选它等于选 Docker 锁 + 自维内存安全 patch + 自做光度标定。
  2. 工作包络:global-shutter mono + 已光度标定 dataset / 自标定鼓励 + 慢速运动 < 1 rad/s + 室内 + 静态场景。任一项偏离都进 #259/#260/#263/#269 已知坑。
  3. 真产品 candidate 应该是 ORB-SLAM3(多 session + IMU)或 DROID-SLAM(learned BA, GPU 必备)或 3R-SLAM Hybrid(feed-forward + classical backend)。DSO 留作历史 + 光度法 baseline。

8 · 比较 & 面试 Tip

🎤 Interview Tip:「DSO vs ORB-SLAM3 我们项目选哪个?」 正确答:「99% 选 ORB-SLAM3。DSO 的工作包络是 global-shutter + 已光度标定 + 慢速运动 + 室内 + 静态 + 不需要闭环 + 不需要多 session。这个交集小到几乎只有 TUM mono dataset 复现实验。如果项目允许 RGB-D / stereo / IMU,ORB-SLAM3 直接赢;如果只能 mono 且要 deployment,看 DSO 的 fork DM-VIO 或干脆走 VINS-Mono。如果是研究 photometric baseline,DSO 仍是 gold standard,但要接受 6 年无主线维护。」 错答:「DSO 比 ORB-SLAM 精度高所以选 DSO」—— 这是把光度标定可控的 dataset 测试当成生产环境精度。在自动曝光 / rolling-shutter / 户外 / 动态场景里,DSO 输得很难看。
追问:「为什么 direct method 没赢?」 答:「(1) 光度标定在真实相机栈不可得(vignetting drift + 自动曝光 + 温度漂焦距);(2) 没有闭环 → 长 session 必然漂;(3) ORB-SLAM 的 DBoW2 + Atlas 把闭环和多 session 工程化了,direct method 一直没有等价物;(4) 2020 后 learned-BA(DROID-SLAM)+ feed-forward(VGGT)直接吃掉了 direct method 的’稠密 + 子像素’卖点。」

9 · Falsifiable Predictions(可证伪预测)


10 · For the Reader(读者实务)

如果你正在 …
  • … 复现 DSO 论文 → 用 Docker 锁 Ubuntu 18.04 + Pangolin v0.6;只在 TUM mono dataset 测;不要换相机。
  • … 想做 mono SLAM 项目 → 先评 ORB-SLAM3 mono mode;只有当 ORB 找不到角点(白墙 / 高梯度但无纹理)且你能控制相机时再看 DSO。
  • … 要 mono + IMU → 看 DM-VIO(Stumberg/Engel 2022)或 VINS-Mono;不是原 DSO。
  • … 想加闭环 → 别用 DSO;DSO 没有 place recognition 模块,硬加要自己整 DBoW3 + RANSAC + photometric refine,工程量等于重写。
  • … 想理解直接法 vs 特征法的根本张力 → 读 DSO 论文 §2-3 + 这篇 dissection §1-2。
  • … 想看 direct method 的未来 → 看 DROID-SLAM (2021) → MASt3R-SfM (2024) → 3R-SLAM Hybrid family (2025-2026)。

11 · References

  • DSO — Engel, Koltun, Cremers. IEEE TPAMI 2018. arXiv:1607.02565 · https://arxiv.org/abs/1607.02565
  • LSD-SLAM — Engel, Schöps, Cremers. ECCV 2014(DSO 前身,半稠密)
  • DTAM — Newcombe, Lovegrove, Davison. ICCV 2011(稠密直接法祖宗)
  • DM-VIO — Stumberg, Cremers. ICRA 2022(DSO + IMU 紧耦合 fork)
  • TUM mono dataset photometric calibration — Engel, Usenko, Cremers. arXiv 1607.02555
  • Cadena SLAM survey — Cadena et al. IEEE T-RO 2016 · https://arxiv.org/abs/1606.05830(Direct vs Indirect 经典分类)
  • DROID-SLAM — Teed, Deng. NeurIPS 2021(direct method learned 继任者)
  • Code — https://github.com/JakobEngel/dso(GPL-3.0, 2.4k ★, frozen 2018)

12 · Boundary(与相邻文件的分工)

这一篇只管 DSO(direct sparse VO 的顶点)。
← Back to Classical SLAM · → ORB-SLAM3 dissection · → SVO dissection