Ultralytics YOLO26-Depth DIODE 稠密室内外深度数据集:深度编码、YAML 配置与训练实战
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.png 配 scene_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/train、images/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,最后删除原始包 |
两点实用提示:
- 磁盘预算:YAML 头注释标明官方压缩包共约 84 GB,转换后约 90 GB,规划
datasets_dir容量时要留足空间; - 中断恢复:若下载中断留下残损数据集,删除
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 图像上报告。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00