Depth Anything 3:用任意视角图片“拼”出 3D 世界

核心问题:有没有一种极简架构,能把单张图、视频或多视角照片一次性变成一致、可量度的 3D 几何?Depth Anything 3 给出的答案是——“只要一个普通 ViT 就够”。


本文欲回答的核心问题

  1. DA3 到底“极简”在哪?
  2. 它怎么用一张图或多张图同时输出深度、相机位姿、甚至 3D 高斯?
  3. 不同任务该选哪个预训练权重?
  4. 真实项目落地要注意哪些坑?

1. 一句话看懂 DA3:把“深度+光线”当成唯一预测目标

  • 不拆任务:深度、位姿、点云不再分别训练,而是统一预测“每像素深度 + 每像素光线”。
  • 不改网络: backbone 就是原生 DINOv2 ViT,连 patch embedding 都没换。
  • 不挑输入:单图、多图、视频、有/无相机参数,同一套权重通吃。

2. 架构速览:单 ViT 如何做到跨视角一致性?

模块 作用 是否新增参数量
DINOv2 ViT 特征提取 0(完全复用)
Input-adaptive Cross-view Self-attention 让 token 在多图之间动态重组 0(仅重排计算图)
Camera Token (可选) 把已知内参/外参塞进 Transformer 一个 64-dim MLP
Dual-DPT Head 共享解码器,分两路输出深度 & 光线 0.05 B

反思:过去做多视角几何,总想“给网络加更多先验”。DA3 反其道而行——先验越少、越依赖预训练 ViT 的通用特征,结果跨域反而更稳。


3. 训练套路:Teacher-Student 三部曲

  1. Teacher:只在合成数据上训练单目深度,输出“干净”的相对深度。
  2. 对齐:用 RANSAC 把 Teacher 深度与真实稀疏深度对齐,得到带尺度的伪真值。
  3. Student(即 DA3):用对齐后的深度+光线伪真值,继续做多视角训练。

场景化说明
在 ARKitScenes 这种 LiDAR 稀疏、噪声大的数据上,直接拿原始深度当标签会学歪;先用 Teacher 补全细节,再对齐,重建出的墙面明显少了“波浪纹”。


4. 模型动物园:一张表选对尺寸

系列 权重名 参数量 单目深度 多目深度 位姿估计 度量深度 3D 高斯 许可证
Any-View DA3-Giant 1.15 B CC BY-NC 4.0
Any-View DA3-Large 0.35 B CC BY-NC 4.0
Any-View DA3-Base 0.12 B Apache 2.0
Metric DA3Metric-Large 0.35 B Apache 2.0
Monocular DA3Mono-Large 0.35 B Apache 2.0
Nested* DA3Nested-Giant-Large 1.40 B CC BY-NC 4.0

*Nested = Giant (任意视角) + Metric (尺度对齐) 级联,同一前向推理即可输出公制点云


5. 5 分钟上手:安装到出图的完整流程

5.1 安装

# 1. 创建环境
conda create -n da3 python=3.10 -y && conda activate da3
# 2. 拉仓库
git clone https://github.com/DepthAnything/Depth-Anything-3.git && cd Depth-Anything-3
# 3. 按需安装
pip install torch>=2 torchvision
pip install -e .                    # 基础推理
pip install -e ".[gs]"              # 若想导出 3D Gaussian
pip install -e ".[app]"             # 若想启用 Gradio Web UI

5.2 三行代码跑推理

from depth_anything_3.api import DepthAnything3
import torch, glob, os

model = DepthAnything3.from_pretrained("depth-anything/DA3NESTED-GIANT-LARGE").cuda()
images = sorted(glob.glob("assets/examples/SOH/*.png"))
pred = model.inference(images)      # 自动完成前处理、归一化、对齐

# 结果字段
pred.depth            # [N,H,W] float32 深度图
pred.conf             # [N,H,W] 0~1 置信度
pred.extrinsics       # [N,3,4] 世界→相机
pred.intrinsics       # [N,3,3] 已按最长边 504 等比缩放

场景化示例
把 10 张手机环绕拍摄的 JPG 扔进同一文件夹,无需标定板,也无需 EXIF,脚本跑完直接得到 pred.glb,拖进 Blender 即可与激光扫描件对比误差。


6. CLI:一条命令批量导出 glb / 3DGS 视频

# 启动后台常驻,避免重复加载 1.4 B 模型
da3 backend --model-dir depth-anything/DA3NESTED-GIANT-LARGE --gallery-dir ./cache

# 自动识别目录下图片,导出带纹理网格
da3 auto ./my_photos \
        --export-format glb \
        --export-dir ./output \
        --use-backend

# 把 4K 无人机视频拆帧+下采样+导出 Gaussian 视频
da3 video ./drone.mp4 \
        --fps 15 \
        --process-res-method lower_bound_resize \
        --export-format glb-feat_vis \
        --feat-vis-fps 15 \
        --export-dir ./drone_3dgs

7. 自定义模型配置:复制一份 Yaml 就能玩

# my_giant.yaml
__object__:
  path: depth_anything_3.model.da3
  name: DepthAnything3Net
net:
  name: vitg                       # 直接换 vitl / vitb / vits
  out_layers: [5, 7, 9, 11]        # 可微调 skip 层
head:
  dim_in: 1536
  features: 256                    # 解码通道加大,提升细节
from depth_anything_3.cfg import load_config, create_object
MyModel = create_object(load_config("my_giant.yaml"))

8. 真实落地:作者踩过的 4 个坑

现象 解决方案
1. 老显卡无 xFormers 24 G 显存只够跑 6 张 2K 图 升级 torch2.2+ 或 export XFORMERS_FORCE_DISABLE=1 回退 memory_efficient_attention
2. 手机超广角畸形 深度边缘漂浮 --intrinsics 参数里传入 crop & resize 后的等效焦距,或改用 BASE 模型(对 FOV 更鲁棒)
3. 玻璃/镜面缺纹理 重建表面被“挖空” 先手动 Mask 透明区域,把 pred.conf < 0.3 直接置零,再补洞
4. 度量尺度漂移 重建房高只有 1.5 m Nested 系列才带公制头;若只用 Giant,需在脚本后段跑全局相似变换对齐已知尺寸

9. 性能对照:同尺寸下速度/显存/精度三杀

模型 显存占用 (504×336×8 views) FPS (A100) AUC3↑ (ScanNet++) F1↑ (ETH3D)
VGGT-1.19B 19.8 GB 34.1 62.6 70.2
DA3-Giant 18.4 GB 37.6 85.0 91.2
DA3-Large 7.2 GB 78.4 60.2 86.9

反思:速度提升并不是“魔改 CUDA”,而是把冗余的跨阶段子网络全部砍掉,注意力矩阵一次性算完——再一次证明“结构越简单,越能吃到硬件红利”。


10. 可视化效果:从点云到 3D Gaussian 只隔一条命令

图片来源:Unsplash
Living room shot

左侧为单图输入,右侧为 DA3Nested 在 3 秒内生成的 3D Gaussian,Blender 中直接 Eevee 实时漫游,边缘误差 < 2 cm(与 Matterport 真值对比)。


11. 结论与实用清单

  • 极简:单 ViT + 深度/光线两路输出,就能统一单目/多目/位姿/度量。
  • 好用:pip 安装 → 三行脚本 → glb/3DGS 直接落地。
  • 不贵:Base 模型 0.12 B、126 FPS,边缘 3060 也能跑。
  • 可改:Yaml 配置即插即用,科研党能任意换 backbone、改 head。

一页速览(One-page Summary)

  1. 装环境:pip install -e ".[gs]"
  2. 选权重:要尺度 → Nested,只玩深度 → Mono-Large,快速预览 → Base
  3. 跑推理:da3 auto ./pics --export-format glb
  4. 调细节:改 Yaml / 给内参 / 用置信度滤玻璃
  5. 上线:显存不够就 --process-res-method lower_bound_resize,精度不够就换 Giant

FAQ

  1. Q:手机拍 30 张,没标定能重建吗?
    A:能。DA3 任何系列都不依赖先验内参,会自动估算;若想公制尺寸,用 Nested 或在后期加一把尺子做相似变换即可。

  2. Q:Base 和 Giant 的 depth 差距大吗?
    A:室内平滑墙面差距 < 1 mm;室外窄基线高楼,Giant 对远处细结构鲁棒性明显更好。

  3. Q:为什么我的显存占用比论文高?
    A:检查是否关闭 gradient checkpoint;把 --max-side 降到 504 以下;或先用 Base 跑低分辨率预览。

  4. Q:可以商用吗?
    A:Base / Small / Metric / Mono 系列 Apache 2.0 可商用;Giant / Large / Nested 为 CC BY-NC 4.0,需获额外授权。

  5. Q:想集成到 UE/Unity?
    A:导出 .ply.glb 即可直接拖进引擎;实时流可用 Python-TCP 把 depth+pose 推到 C++ 插件做 GPU 纹理上传,延迟 < 50 ms。

  6. Q: Teacher 模型会开放吗?
    A:代码仓已含训练脚本,权重随 Nested 包自动下载,可单独做度量深度微调。

  7. Q:为什么有时玻璃区域被“挖空”?
    A:透明表面缺乏特征,网络置信度自动下降;建议手动掩膜+后处理补洞,或拍一张带反光贴纸的图提高纹理。