19f939f1e8915.png

当 AI 不再只是识别“图里有什么”,而是开始判断“每个像素离我们有多远”,计算机视觉就从平面理解走向了空间理解。Depth Anything V2 做的事情,正是让普通 RGB 图像拥有近似“深度感”的能力。

01. 先说人话:Depth Anything V2 到底是什么?👀

Depth Anything V2 是一个面向单目深度估计的视觉模型。它输入一张普通 RGB 图片,输出一张与原图同尺寸的深度图,用颜色或灰度表达画面中不同区域的远近关系。

从项目文件来看,它主要提供两类能力:

– Relative Depth Estimation:相对深度估计,判断图像中不同区域的远近顺序。

– Metric Depth Estimation:度量深度估计,经过特定数据集微调后,输出以米为单位的深度值。

这意味着它既能服务于视觉效果、图像编辑、视频后期,也可以进一步接入机器人、AR、三维重建、空间计算等更“硬核”的场景。

02. 为什么它值得关注?🔥

传统深度估计常常依赖双目相机、深度相机、LiDAR 或多视角几何。Depth Anything V2 则更激进:

只看一张 RGB 图,就尝试恢复画面里的空间层次。

根据项目 README,Depth Anything V2 相比 V1 在两个方向上重点增强:

– 细粒度细节更好:物体边缘、局部结构、前后遮挡关系更清晰。

– 鲁棒性更强:面对复杂场景、非真实图像、反光透明物体、航拍、水下等场景时表现更稳定。

同时,它相比扩散模型类深度估计方案,强调:

  • 推理速度更快
  • 参数量更少
  • 深度准确性更高
  • 更适合工程部署

一句话总结:

Depth Anything V2 是一个更轻、更快、更稳的通用深度感知底座。

03. 项目结构速览:它不是 Demo 玩具,而是一套完整工程 🧩

项目中比较关键的文件包括:

Depth-Anything-V2/
  depth_anything_v2/
    dpt.py              # 模型主体:DINOv2 编码器 + DPT 解码头
    dinov2.py           # DINOv2 Vision Transformer 实现
    util/
      transform.py      # 图像预处理
      blocks.py         # DPT 特征融合模块
  metric_depth/
    README.md           # 度量深度说明
    depth_to_pointcloud.py
    train.py
  run.py                # 图片推理脚本
  run_video.py          # 视频推理脚本
  app.py                # Gradio Demo
  DA-2K.md              # DA-2K 相对深度评测基准说明

这套结构说明它不只是给出一个模型权重,而是覆盖了:

  • 单图推理
  • 视频推理
  • 在线交互 Demo
  • 度量深度微调
  • 点云转换
  • Benchmark 评测说明

05. 核心架构:DINOv2 做“视觉理解”,DPT 做“深度还原”🧠

Depth Anything V2 的模型主体在 depth_anything_v2/dpt.py 中。整体结构可以理解为:

19f93a574c626.png

其中,DINOv2 负责提取强语义、强泛化的视觉特征;DPT Head 负责把 Transformer token 重新组织成空间特征图,并逐级融合恢复到高分辨率深度预测。

06. 关键代码 1:模型如何选择不同规模?⚙️

run.py 中定义了不同规模模型的配置:

model_configs = {
    'vits': {'encoder': 'vits', 'features': 64, 'out_channels': [48, 96, 192, 384]},
    'vitb': {'encoder': 'vitb', 'features': 128, 'out_channels': [96, 192, 384, 768]},
    'vitl': {'encoder': 'vitl', 'features': 256, 'out_channels': [256, 512, 1024, 1024]},
    'vitg': {'encoder': 'vitg', 'features': 384, 'out_channels': [1536, 1536, 1536, 1536]}
}

这对应了 README 中的四个模型尺度:

模型 参数量 适合场景
Small 24.8M 移动端、实时性优先、轻量部署
Base 97.5M 通用场景,速度和效果折中
Large 335.3M 高质量深度估计、细节优先
Giant 1.3B 项目中标注为 Coming soon

实战建议很简单:

先用 Large 看上限,再根据部署成本往 Base 或 Small 收缩。

07. 关键代码 2:为什么它能保留细节?多层特征融合是重点 🔍

在 DepthAnythingV2 中,模型不是只拿 Transformer 最后一层特征,而是取多个中间层:

self.intermediate_layer_idx = {
    'vits': [2, 5, 8, 11],
    'vitb': [2, 5, 8, 11],
    'vitl': [4, 11, 17, 23],
    'vitg': [9, 19, 29, 39]
}

推理时会调用:

features = self.pretrained.get_intermediate_layers(
    x,
    self.intermediate_layer_idx[self.encoder],
    return_class_token=True
)

这很关键。

深度估计既需要高层语义理解,比如“这是天空、地面、桌子、墙”,也需要低中层结构信息,比如“边缘在哪里、物体轮廓如何、纹理变化是否代表几何变化”。

多层特征融合让模型同时利用语义和细节。

08. 关键代码 3:DPT Head 如何把 token 变回深度图?🧱

Transformer 处理的是 token,但深度图需要回到二维空间。DPT Head 的核心动作就是:

  1. 把 token reshape 成 feature map
  1. 用 1×1 卷积调整通道
  1. 对不同层特征做上采样或下采样
  1. 逐级融合
  1. 输出单通道深度图

代码中可以看到这一段:

x = x.permute(0, 2, 1).reshape((x.shape[0], x.shape[-1], patch_h, patch_w))
x = self.projects[i](x)
x = self.resize_layers[i](x)
out.append(x)

随后进行四层融合:

path_4 = self.scratch.refinenet4(layer_4_rn, size=layer_3_rn.shape[2:])
path_3 = self.scratch.refinenet3(path_4, layer_3_rn, size=layer_2_rn.shape[2:])
path_2 = self.scratch.refinenet2(path_3, layer_2_rn, size=layer_1_rn.shape[2:])
path_1 = self.scratch.refinenet1(path_2, layer_1_rn)

最后插值会接近输入分辨率:

out = F.interpolate(
    out,
    (int(patch_h * 14), int(patch_w * 14)),
    mode="bilinear",
    align_corners=True
)

这也是 Depth Anything V2 能输出稠密深度图的关键:

先用 Transformer 理解全局,再用 DPT 解码器恢复空间细节。

09. 关键代码 4:一张图片如何被推理?📸

最小使用方式非常清楚:

import cv2
import torch

from depth_anything_v2.dpt import DepthAnythingV2

DEVICE = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'

model = DepthAnythingV2(
    encoder='vitl',
    features=256,
    out_channels=[256, 512, 1024, 1024]
)

model.load_state_dict(torch.load(
    'checkpoints/depth_anything_v2_vitl.pth',
    map_location='cpu'
))
model = model.to(DEVICE).eval()

raw_img = cv2.imread('your/image/path')
depth = model.infer_image(raw_img)

其中 infer_image 做了三件事:

  • 把 OpenCV 读入的 BGR 图片转成 RGB
  • 按输入尺寸进行 Resize、Normalize、PrepareForNet
  • 推理后插值回原图尺寸
depth = self.forward(image)
depth = F.interpolate(depth[:, None], (h, w), mode="bilinear", align_corners=True)[0, 0]

所以最终拿到的是一个 HxW 的 numpy 深度图。

10. 相对深度 vs 度量深度:差别在哪里?📏

Depth Anything V2 默认做的是 相对深度。它更关注“谁近谁远”,而不一定输出真实米制距离。

而 metric_depth/ 目录提供了度量深度版本。它在 Hypersim 和 Virtual KITTI 等数据集上微调,让输出深度具有物理尺度。

度量深度版本中,模型会通过 max_depth 控制输出范围:

depth = self.depth_head(features, patch_h, patch_w) * self.max_depth

项目中建议:

  • 室内场景:Hypersim 版本,常用 max_depth=20
  • 室外场景:Virtual KITTI 版本,常用 max_depth=80

这点非常实用。

如果只是做视觉效果、图像分层、背景虚化,相对深度通常够用;如果要做机器人导航、空间测量、点云生成,就需要度量深度。

11. 从深度图到点云:2D 图片可以变成 3D 点阵 🌐

metric_depth/depth_to_pointcloud.py 展示了一个很直接的应用:把深度图投影成点云。

核心逻辑如下:

x, y = np.meshgrid(np.arange(width), np.arange(height))
x = (x - width / 2) / args.focal_length_x
y = (y - height / 2) / args.focal_length_y
z = np.array(resized_pred)

points = np.stack(
    (np.multiply(x, z), np.multiply(y, z), z),
    axis=-1
).reshape(-1, 3)

这段代码把每个像素 (x, y) 和它对应的深度 z 变成三维点:

pixel + depth + camera focal length → 3D point

然后用 Open3D 保存为 .ply 点云:

pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
pcd.colors = o3d.utility.Vector3dVector(colors)
o3d.io.write_point_cloud(output_path, pcd)

这意味着 Depth Anything V2 可以成为轻量级 3D 感知管线的第一步。

12. 图片、视频、Web Demo 都能跑 🛠️

图片推理

python run.py 
  --encoder vitl 
  --img-path assets/examples 
  --outdir depth_vis

可选参数包括:

  • --input-size:默认 518,增大后可能获得更细节的结果
  • --pred-only:只保存深度图
  • --grayscale:保存灰度深度图,不使用伪彩色

视频推理

python run_video.py 
  --encoder vitl 
  --video-path assets/examples_video 
  --outdir video_depth_vis

README 中特别提到:

更大的模型在视频上通常有更好的时间一致性。

Gradio Demo

python app.py

app.py 中的 Demo 会输出:

  • 带滑动对比的深度图
  • 灰度深度图
  • 16-bit raw output

这对产品展示和交互验证都很方便。

13. DA-2K:专门评估“谁离镜头更近”的 Benchmark 🧪

项目还提供了 DA-2K.md,介绍了 DA-2K 相对深度评测基准。

19f93b159225b.png

它覆盖八类代表性场景:

  • indoor
  • outdoor
  • non_real
  • transparent_reflective
  • adverse_style
  • aerial
  • underwater
  • object

DA-2K 由 1K 张高质量图片和 2K 条精确的点对相对深度标注组成。标注形式非常直观:

{
  "image_path": [
    {
         "point1": [*h*1, *w*1],
      "point2": [*h*2, *w*2],
      "closer_point": "point1"
    }
  ]
}

这种评测方式很贴合相对深度估计的核心问题:

不是问模型“这个点离相机几米”,而是问它“这两个点谁更近”。

14. 它能用在哪里?这些场景非常有想象力 🚀

19f93a84d9f80.png

1. 图像编辑与视觉特效

深度图可以帮助实现背景虚化、景深模拟、前景分割、空间雾效、2.5D 视差动画等效果。

对设计工具、短视频工具、AIGC 后期工具都很有价值。

2. AR 空间理解

AR 需要知道物体大致在空间中的位置。

Depth Anything V2 可以从普通摄像头画面中提供空间层次,为虚拟物体放置、遮挡关系、平面感知提供辅助。

3. 机器人和自动驾驶感知

在没有 LiDAR 或深度相机的情况下,单目深度估计可以作为低成本环境感知补充。

尤其在边缘设备或轻量机器人中,这类模型很有吸引力。

4. 三维内容生产

度量深度版本可以把图片转换为点云,再进一步进入 3D 编辑、重建或可视化流程。

它不一定直接替代专业三维扫描,但非常适合快速生成空间草图。

5. 多模态大模型的空间插件

未来视觉语言模型不只要回答“图里有什么”,还要理解“谁在前、谁在后、哪里可走、哪里被挡住”。

深度估计模型可以为多模态系统补上空间感。

15. 理性看待:Depth Anything V2 不是万能深度相机 🧯

它很强,但使用时要注意边界:

  • 单目深度存在天然尺度歧义,默认相对深度不等于真实距离。
  • 透明、镜面、强反光、极暗光照等场景仍可能出错。
  • 视频逐帧推理可能出现闪烁,更强的视频一致性需要专门的视频深度模型。
  • 度量深度依赖微调数据分布,室内/室外模型不能随意混用。
  • 商业使用要注意许可证:README 中说明 Small 为 Apache-2.0,Base/Large/Giant 为 CC-BY-NC-4.0。

正确姿势是:

把它当作强大的视觉深度先验,而不是绝对可靠的测距仪。

19f939a28eacf.png

16. 总结:Depth Anything V2 让 AI 从“看懂图片”走向“理解空间”🧭

Depth Anything V2 的意义,不只是把照片变成一张漂亮的伪彩色深度图。更重要的是,它把“空间层次”变成了一个可以被普通 RGB 图像模型快速预测的基础能力。

它的技术路线非常清晰:

– 用 DINOv2 获得强大的通用视觉表征

– 用 DPT Head 做多尺度细节融合

  • 用不同模型尺度适配不同部署场景
  • 用 metric depth 微调扩展到真实尺度
  • 用点云转换打通 2D 到 3D 的应用链路

如果说图像识别让机器知道“这是什么”,那么 Depth Anything V2 更进一步,让机器开始判断:

它在哪里?离我多远?和周围世界是什么空间关系?

这正是空间智能时代非常关键的一块拼图。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注