首页
/ Ultralytics YOLO26-Depth DIODE 稠密室内外深度数据集:深度编码、YAML 配置与训练实战

Ultralytics YOLO26-Depth DIODE 稠密室内外深度数据集:深度编码、YAML 配置与训练实战

2026-09-05 18:11:47作者:段琳惟

DIODE(Dense Indoor/Outdoor DEpth)是 Ultralytics 深度估计任务中唯一同时覆盖室内与室外真实场景的稠密深度数据集,其地面真值由 FARO Focus 测量级激光扫描仪获取。本文基于 DIODE 官方文档页depth-diode.yaml 配置源码,完整讲解 DIODE 的数据构成、256 单位/米的 uint16 PNG 深度编码原理、数据集 YAML 各字段含义,以及如何用 Python 或 CLI 在该数据集上训练 YOLO26-Depth 模型。

1. DIODE 是什么:激光级稠密真值打通室内外

DIODE 官方站点可获取完整数据集。其核心特点(来自 文档页):

  • 测量级稠密真值:深度由 FARO Focus survey-grade 激光扫描仪采集,逐像素对齐 RGB 帧,质量远高于普通 RGB-D 传感器;
  • 同一传感器覆盖室内与室外:这是 DIODE 的独特之处——同一套传感器既采短距室内场景也采长距室外场景,使它在单目深度估计(monocular depth estimation)中成为连接室内(短程)与室外(长程)域的"高精度桥梁";
  • 深度范围跨度大:在 Ultralytics 的混合训练数据中,DIODE 的深度范围从室内近距一直延伸到室外约 80 m。

2. 数据集结构:25,458 训练 + 771 验证,256 单位/米

DIODE 拆分为两个子集:

子集 数量 用途
Train 25,458 张图像(带配对深度图) 训练
Val 771 张图像(带配对深度图) 训练中验证

每个样本由一张 RGB 图像和一张 uint16 深度 PNG 组成,depth_scale: 256,即 PNG 像素值 256 对应 1 米。这与 深度数据集格式规范 的约定一致:

约定 depth_scale 分辨率 uint16 可表示最大深度
默认 / ARKitScenes / NYU 1000 1 mm 65.535 m
DIODE / KITTI 256 3.90625 mm 255.996 m
Virtual KITTI 2 100 1 cm 655.35 m

scale = 256 意味着每一步长 1/256 = 3.90625 mm,65,535 个有效正值恰好覆盖 255.99 m——足以表示完整 80 m 室外量程。像素值 0 保留给无效深度(天空、镜面反射、遮挡等),会被自动排除在损失与指标计算之外。

2.1 源码印证:PNG 编解码如何保证"0 = 无效"

下载脚本最终调用 save_depth_png() 把以米为单位的浮点数组编码为 uint16 PNG。从源码看其关键约束:

valid = np.isfinite(depth) & (depth > 0)
encoded = np.zeros(depth.shape, dtype=np.uint16)
if valid.any():
    scaled = np.rint(depth[valid] * scale)
    if scaled.max() > np.iinfo(np.uint16).max:
        raise ValueError(f"Depth map exceeds the ... meter PNG limit")
    encoded[valid] = np.maximum(scaled, 1).astype(np.uint16)
  • 无效像素(非有限值或 <= 0)保持为 0
  • 有效像素经四舍五入缩放,并强制至少为 1,从而与"0 表示无效"的约定不冲突;
  • 超出 uint16 量程(65535/scale 米,256 尺度下约 255.99 m)会直接抛错。

读取端 load_depth() 支持 .npy(2D 浮点,单位米)与 .png(uint16,除以 depth_scale 还原为米)两种格式;数据加载时 depth_scale 来自 YAML,默认为 1000,见 DepthDataset 的缓存与读取逻辑

2.2 目录布局与文件配对规则

转换后的 DIODE 遵循标准并行目录结构:

depth-diode/
├── images/{train,val}   # RGB 图像
└── depth/{train,val}    # 配对 16-bit *.png 深度图(images/ -> depth/)

加载器通过把图像路径中的 images 目录分量替换为 depth 来定位深度文件,优先 .png、回退 .npy,两者必须同 stem(如 scene_001.pngscene_001.jpg)。训练前 verify_image_depth() 会逐一校验:深度文件必须存在、PNG 必须为整型灰度模式(I / I;16)、且深度图与图像的宽高比误差在 0.02 以内(允许深度图小于图像,训练时在内存中缩放对齐)。缺失或损坏的样本会被跳过并告警。

3. Dataset YAML:depth-diode.yaml 逐字段解读

仓库内置的 depth-diode.yaml 完整内容如下,字段含义对照深度数据集通用 YAML 规范

# parent
# ├── ultralytics
# └── datasets
#     └── depth-diode  ← 下载目录(84 GB 压缩包,转换后约 90 GB)
#         ├── images/{train,val}  # RGB 图像
#         └── depth/{train,val}   # 配对 16-bit *.png 深度图
# 若下载中断留下残损数据,删除 depth-diode 目录后重新运行即可。

path: depth-diode        # 数据集根目录(相对 Ultralytics 设置项 datasets_dir)
train: images/train      # 训练图像,相对 'path',共 25458 张
val: images/val          # 验证图像,相对 'path',共 771 张
max_depth: 80            # (m) 有效深度上限;验证指标中超出该值的 GT 像素被排除

nc: 1
names:
  0: depth

channels: 3
depth_scale: 256         # PNG 值 256 = 1 米;覆盖 80 m 室外量程

# Download script/URL (optional)
download: |
  import shutil
  from pathlib import Path

  import numpy as np

  from ultralytics.data.utils import save_depth_png
  from ultralytics.utils import TQDM
  from ultralytics.utils.downloads import download

  # 下载并解压官方压缩包(train 约 81 GB,val 约 2.6 GB),然后转换:
  # 把 <split>/<scene>/<scan>/*.png 展平为 images/<split>/,
  # 并将配对的 *_depth.npy(掩掉无效像素、80 m 截断)存为 depth/<split>/*.png
  dir = Path(yaml["path"])
  download([f"https://diode-dataset.s3.amazonaws.com/{s}.tar.gz" for s in ("train", "val")], dir=dir / "source", delete=True)
  for split in ("train", "val"):
      (dir / "images" / split).mkdir(parents=True, exist_ok=True)
      (dir / "depth" / split).mkdir(parents=True, exist_ok=True)
      for im in TQDM(sorted((dir / "source" / split).rglob("*.png")), desc=f"Converting {split}"):
          name = "_".join(im.relative_to(dir / "source").parts)
          depth = np.load(im.with_name(f"{im.stem}_depth.npy")).squeeze().astype(np.float32)
          depth[np.load(im.with_name(f"{im.stem}_depth_mask.npy")) == 0] = 0.0  # 无效像素清零
          save_depth_png(dir / "depth" / split / f"{name[:-4]}.png", depth.clip(max=80), scale=256)
          im.replace(dir / "images" / split / name)
  shutil.rmtree(dir / "source")

各字段说明:

字段 取值 说明
path depth-diode 数据集根目录,相对 Ultralytics 设置项 datasets_dir(默认 datasets/
train / val images/trainimages/val 图像目录,相对 path;深度图自动映射到 depth/ 同 stem 文件
max_depth 80 有效深度上限(米)。验证时遵循 Eigen 协议:GT 超出 (min_depth, max_depth) 的像素不参与指标,预测值也被截断到该范围,见 DepthMetrics 实现
nc / names 1 / {0: depth} 深度任务固定单类
depth_scale 256 PNG 每米对应的整数单位;深度数据集默认 1000,DIODE 与 KITTI 均用 256
download 内嵌 Python 脚本 首次引用该 YAML 训练/验证时自动执行:下载官方 S3 压缩包(train ~81 GB + val ~2.6 GB),展平目录结构、用 mask 清零无效像素、clip(max=80) 截断后经 save_depth_png 以 scale=256 写出配对 PNG,最后删除原始包

两点实用提示:

  1. 磁盘预算:YAML 头注释标明官方压缩包共约 84 GB,转换后约 90 GB,规划 datasets_dir 容量时要留足空间;
  2. 中断恢复:若下载中断留下残损数据集,删除 depth-diode 目录后重新运行即可重建(download 段会 delete=True 清掉已完成的压缩包)。

4. DIODE 在 YOLO26-Depth 预训练中的角色

YOLO26 depth 模型系列(yolo26n/s/m/l/x-depth.pt,模型骨架定义见 yolo26-depth.yaml)预训练于约 219 万(2.19M)图像–深度对的多数据集混合中,DIODE 是其中的训练源之一。据 深度数据集总览,混合数据覆盖从室内(≤10 m)到室外(约 80 m)的深度范围,训练后模型在 NYU、KITTI、Make3D、ETH3D 与 iBims-1 五个标准基准上零样本评估。

DIODE 的贡献在于:以单一传感器提供横跨室内外域的高精度稠密真值,帮助模型在短程与长程场景之间泛化——这正是纯室内数据集(如 NYU、ARKitScenes)和纯室外数据集(如 KITTI)各自无法覆盖的。

训练完成后还会自动进行可选的输出校准train.py 在校准阶段读取 self.data.get("max_depth") or 100.0,即优先采用本 YAML 中的 max_depth: 80,仅用 GT 位于 (0.001, 80) 米内的像素拟合比例校准(Eigen 口径),与验证指标保持同一像素总体,避免远端无效 GT 干扰拟合。

5. 训练实战:Python 与 CLI

在 DIODE 上训练 yolo26n-depth、图像尺寸 640 的完整示例(完整参数列表见 Train 模式文档):

Python:

from ultralytics import YOLO

# 加载模型
model = YOLO("yolo26n-depth.pt")  # 加载预训练深度模型(训练推荐)

# 训练
results = model.train(data="depth-diode.yaml", epochs=100, imgsz=640)

CLI:

# 从预训练 *.pt 模型开始训练
yolo depth train data=depth-diode.yaml model=yolo26n-depth.pt epochs=100 imgsz=640

补充三种常见加载方式(来自 Depth 任务页):

# 从 YAML 构建新模型并从头训练
yolo depth train data=depth-diode.yaml model=yolo26n-depth.yaml epochs=100 imgsz=640

# 从预训练 *.pt 开始训练
yolo depth train data=depth-diode.yaml model=yolo26n-depth.pt epochs=100 imgsz=640

# 从 YAML 构建、迁移预训练权重后训练
yolo depth train data=depth-diode.yaml model=yolo26n-depth.yaml pretrained=yolo26n-depth.pt epochs=100 imgsz=640

验证阶段会自动使用 val 子集(771 张)并按 max_depth: 80 的 Eigen 协议报告 delta1/delta2/delta3、abs_rel、rmse、silog 指标(见 val 初始化)。DIODE 的 val 分集深度上限恰与室外量程一致,是检验模型长程能力的合理验证集。

6. 预训练模型与引用

YOLO26 depth 家族各尺寸权重(如 YOLO26x-depth)自 Ultralytics 最新发布版本自动下载,可按精度与资源需求选择不同尺寸;各模型在五个基准上的精度与可下载权重列表见 Depth 任务页

若在你的研究中使用 DIODE 数据集,请引用其论文:

@article{vasiljevic2019diode,
      title={DIODE: A Dense Indoor and Outdoor DEpth Dataset},
      author={Vasiljevic, Igor and Kolkin, Nick and Zhang, Shanyi and Luo, Ruotian and Wang, Haochen and Dai, Falcon Z. and Daniele, Andrea F. and Mostajabi, Mohammadreza and Basart, Steven and Walter, Matthew R. and Shakhnarovich, Gregory},
      journal={arXiv preprint arXiv:1908.00463},
      year={2019}
}

7. 小结

  • DIODE 是 Ultralytics 深度混合数据中唯一同一激光传感器覆盖室内外的真实稠密深度源,25,458 训练 + 771 验证样本;
  • 采用 depth_scale: 256 的 uint16 PNG(3.90625 mm 分辨率、0 = 无效),与 KITTI 同约定,由 save_depth_png() 统一编码;
  • depth-diode.yaml 内置约 84 GB 的自动下载与目录转换脚本,max_depth: 80 同时约束验证指标与训练后校准的像素口径;
  • 一条 yolo depth train data=depth-diode.yaml model=yolo26n-depth.pt 即可完成全流程训练,验证指标按 Eigen 协议在 771 张 val 图像上报告。
登录后查看全文
热门项目推荐
相关项目推荐