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
4 · 玩具例子:带数字走一遍
EuRoC MAVMH_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(不公开)]
读者实务含义:
- DSO 是 2016 论文实现,不是 2026 活跃产品 —— 选它等于选 Docker 锁 + 自维内存安全 patch + 自做光度标定。
- 工作包络:global-shutter mono + 已光度标定 dataset / 自标定鼓励 + 慢速运动 < 1 rad/s + 室内 + 静态场景。任一项偏离都进 #259/#260/#263/#269 已知坑。
- 真产品 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 的顶点)。- ORB-SLAM3(indirect VO 对照) →
./orb_slam3_dissection.md - SVO(semi-direct VO) →
./svo_dissection.md - LSD-SLAM 与 DSO 的合并对比(含 LSD 半稠密 vs DSO 稀疏) →
./direct_methods_dso_lsd.md - GitHub-validated 失败 atlas →
./github_failure_atlas.md - PnP / DLT 几何基础 →
./pnp_dlt_primer.md - Aerial 实时 VIO(VINS / OpenVINS / DROID) →
../../embodiments/aerial/vio/overview.md - Feed-forward 3D 继任(DUSt3R / VGGT) →
../feed-forward-3d/ - 3DGS-SLAM 后端 →
../3dgs-family/gs_slam_dissection.md - Ontology v3 Direct VO subdivision →
../../cheat-sheet/ontology.md§2
← Back to Classical SLAM · → ORB-SLAM3 dissection · → SVO dissection