Ultralytics YOLO26-Depth 与 SUN RGB-D:多传感器室内深度数据的格式、转换流水线与训练实战
本文以 Ultralytics 仓库中的 SUN RGB-D 深度数据集文档(docs/en/datasets/depth/sunrgbd.md)为主体,结合仓库内置的数据集 YAML(ultralytics/cfg/datasets/depth-sunrgbd.yaml)与数据加载源码(ultralytics/data/dataset.py、ultralytics/data/utils.py),系统讲解这个多传感器室内 RGB-D 数据集的构成、Ultralytics 深度数据集格式、depth_bfx 位旋转解码转换流程,以及用它训练 YOLO26-Depth 单目深度估计模型的完整方法。读完后,你可以直接复制仓库内的 YAML 与训练命令开展实验,并理解从原始传感器数据到 uint16 毫米深度图的每一步实现细节。
为什么 SUN RGB-D 适合单目深度估计
SUN RGB-D 是普林斯顿大学发布的真实室内场景理解基准,使用四种不同的 RGB-D 传感器采集:Intel RealSense、Asus Xtion,以及 Microsoft Kinect v1 和 Kinect v2。这种多传感器设计正是它在 Ultralytics 中价值所在:
- 真实的多传感器多样性:同一批室内场景由不同硬件采集,深度噪声模式、量程和精度各不相同,能暴露模型对不同消费级 RGB-D 设备的泛化能力;
- 广泛的真实室内场景:覆盖客厅、办公室、厨房等室内场景,面向场景理解研究;
- 深度量程约 10 m 以内:符合消费级室内 RGB-D 采集的典型范围;
- 传感器原始深度真值:深度图与 RGB 帧对齐,且来自传感器真实测量,而非标注或拟合结果。
文档明确指出,SUN RGB-D 是 Ultralytics YOLO26-Depth 多数据集预训练混合集(约 219 万张图像—深度对)中的训练数据源,其贡献正是"真实多传感器室内多样性"——让模型接触由多种不同消费级 RGB-D 设备采集的深度数据。
数据划分与样本格式
SUN RGB-D 深度数据集分为两个子集:
| 子集 | 数量 | 用途 |
|---|---|---|
| Train | 9,245 张 | 训练 |
| Val | 1,090 张 | 训练过程中的验证 |
每个样本由一张 RGB 图像和一张配对的缩放 uint16 深度 PNG 组成,遵循 Ultralytics 深度数据集格式。格式要点如下:
- 深度文件为 2 维 uint16 灰度 PNG,数值除以数据集级
depth_scale得到米值; - SUN RGB-D 的内置转换以毫米为单位写出,因此默认
depth_scale: 1000即生效——数值1500表示 1.5 米; - 编码值
0表示无效像素(传感器噪点、无深度区域),这些像素会被同时排除在损失计算和指标统计之外; - 由于 uint16 保留 0 给无效值,可用的正深度值共 65,535 个:按 1 mm 分辨率覆盖 0.001 m 到 65.535 m;
- 深度图可以与 RGB 图不同分辨率,只要宽高比一致即可,训练时会在内存中统一缩放。
目录结构采用标准的"并行文件夹"布局:
depth-sunrgbd/
├── images/
│ ├── train/ # 9245 张 RGB 图像
│ └── val/ # 1090 张 RGB 图像
└── depth/
├── train/ # 配对的 16 位 PNG 深度图
└── val/
加载器通过将图像路径中的 images 目录组件替换为 depth 来定位深度文件,images/train/scene_001.jpg 对应 depth/train/scene_001.png。
数据集 YAML:完整配置与注释
数据集配置由 YAML 文件定义,仓库内置文件为 ultralytics/cfg/datasets/depth-sunrgbd.yaml。关键配置段(去除下载脚本)如下:
path: depth-sunrgbd # 数据集根目录(相对于 Ultralytics 设置的 'datasets_dir')
train: images/train # 训练图像(相对于 'path')9245 张
val: images/val # 验证图像(相对于 'path')1090 张
nc: 1
names:
0: depth
channels: 3
各字段含义(与 深度数据集格式文档 一致):
| 键 | 说明 |
|---|---|
path |
数据集根目录 |
train |
训练图像路径,相对于 path(或绝对路径) |
val |
验证图像路径 |
nc |
类别数——深度估计恒为 1 |
names |
类别名映射——恒为 {0: depth} |
depth_scale |
可选,PNG 每米对应的整数单位;缺省为 1000。SUN RGB-D 未显式设置,即默认按毫米解析 |
该 YAML 还包含一段较长的 download 脚本字段,负责自动下载原始归档并完成格式转换,下面一节专门解析。另外文件头注释说明了磁盘占用:约 6.5 GB 的官方归档,转换后约 14 GB;若中断下载留下残缺数据,删除 depth-sunrgbd 目录后重新运行即可重建。
从源码看:自动下载与 depth_bfx 位旋转解码
depth-sunrgbd.yaml 中的 download 字段是一个内嵌 Python 脚本,首次训练时由框架自动执行。梳理该脚本,转换流水线分为四步:
第 1 步:下载官方归档。 从普林斯顿的 SUNRGBD.zip(约 6.5 GB)下载到 depth-sunrgbd/source/ 并解压。
第 2 步:枚举场景。 脚本扫描 source/SUNRGBD 下所有 depth_bfx 目录(共 10,335 个场景),以场景相对路径拼接的字符串作为规范化文件名(如目录名用下划线连接)。
第 3 步:解码深度图。 这是 SUN RGB-D 特有的技术细节:depth_bfx 子目录里的 PNG 并非普通毫米深度图,其编码值需要经过官方定义的位旋转才能还原:
# refined depth_bfx PNG 经 SUN RGB-D 位旋转 (d>>3 | d<<13) 解码为毫米,截断在 10 m
d = cv2.imread(str(next((scene / "depth_bfx").glob("*.png"))), cv2.IMREAD_ANYDEPTH)
d = (((d >> 3) | (d << 13)) / 1000.0).clip(max=10).astype(np.float32) # 位旋转毫米 -> 米
即对原始编码值 d 执行 (d >> 3) | (d << 13) 还原出毫米单位深度,再除以 1000 得到米值,并裁剪上限为 10 m(对应"深度量程约 10 m"的数据集特性)。
第 4 步:切分并写出。 用一个确定性随机子集划分验证集:random.Random(0).sample(names, k=1090)——以种子 0 从全部场景名中固定抽取 1,090 个场景作为 val,其余 9,245 个为 train。这意味着 train/val 的划分是可复现的,任何人重复运行都会得到同一划分。随后调用 save_depth_png() 把米值数组写成毫米 uint16 PNG,并把 image/ 目录下的 RGB jpg 移入 images/{split}/,全部完成后删除 source/ 目录。
save_depth_png() 的实现位于 ultralytics/data/utils.py,其核心规则:
- 输入必须是 2 维数组;
scale默认 1000(模块级常量DEPTH_PNG_SCALE); - 无效像素(非有限值或 ≤ 0)编码为
0,有效像素取max(rint(depth * scale), 1),保证最小有效深度编码为 1; - 若缩放后超过 uint16 上限(即超过约 65.535 m),直接抛出
ValueError,防止静默溢出。
与之配套的 load_depth()(同文件 L84-L100)负责反向解析:PNG 分支严格校验图像格式为 PNG 且模式为 I/I;16(即 2 维 uint16),数值除以 scale 得到米值;NPY 分支则要求 2 维浮点数组且单位直接是米,并把 NaN/Inf 归一化为 0(即无效)。
这套"写入—读取"的对称设计解释了文档中"内置转换以毫米写出、默认 depth_scale: 1000 生效"的表述:SUN RGB-D 的 YAML 无需声明 depth_scale,因为转换端与加载端都锚定在 1000 这一默认值上。
加载器行为:DepthDataset 如何配对、校验与缩放
训练时深度样本由 ultralytics/data/dataset.py 中的 DepthDataset 类处理,几个关键行为值得开发者了解:
- 路径映射(
_depth_path_for,L451-L459):从图像路径尾部向前找到images目录组件并替换为depth,文件扩展名优先尝试.png,不存在时回退.npy; - 缓存指纹(
get_cache_hash,L471-L477):哈希覆盖图像路径、深度路径以及depth_scale值,因此修改depth_scale会自动使旧缓存失效; - 扫描校验:首次加载会对每对图像—深度文件执行
verify_image_depth校验,缺失或损坏的样本分别计数并在缓存扫描后以警告形式丢弃,扫描摘要形如"nf images, nm missing depth, nc corrupt"; - 尺寸对齐(
get_image_and_label,L514-L522):深度图以原分辨率加载后,若与图像缩放后的形状不一致,用cv2.resize(..., INTER_NEAREST)缩放到目标尺寸——INTER_NEAREST保留了深度的像素级取值,避免插值制造出"不存在"的深度值; - 数据增强约束(
build_transforms,L524-L539):深度任务强制关闭 mosaic、mixup、cutmix 和 copy-paste 增强(这些增强会把多幅图像的深度语义拼在一起),验证阶段则使用scale_fill的 LetterBox 直接拉伸而非填充。
以上行为均可在 ultralytics/data/dataset.py 中逐行核对,也解释了为什么文档强调"深度文件名必须与图像同名同干名、深度图可以较小但宽高比要一致"。
训练实战:Python 与 CLI
在 SUN RGB-D 上训练 YOLO26n-depth 模型(图像尺寸 640)的标准用法如下,完整参数列表见 训练文档。
Python:
from ultralytics import YOLO
# 加载预训练深度模型(训练推荐)
model = YOLO("yolo26n-depth.pt")
# 在 SUN RGB-D 上训练
results = model.train(data="depth-sunrgbd.yaml", epochs=100, imgsz=640)
CLI:
# 从预训练 *.pt 模型开始训练
yolo depth train data=depth-sunrgbd.yaml model=yolo26n-depth.pt epochs=100 imgsz=640
首次运行时,框架会执行 YAML 中的下载脚本:拉取 6.5 GB 归档、逐场景解码位旋转深度图并写出约 14 GB 的转换后数据,随后进入正常的训练循环。如果希望先验证整条管线再跑全量数据,可以用同源的 Depth8 数据集(ultralytics/cfg/datasets/depth8.yaml):它是从 SUN RGB-D 的 Kinect v1/v2 采集中抽出的 8 张图像(4 train / 4 val),1.3 MB 压缩包秒级下载、无需转换步骤,格式与 SUN RGB-D 完全一致——在 Depth8 上能跑通的管线,可原样迁移到全量数据集。
验证阶段的指标采用标准深度估计指标集:delta1 / delta2 / delta3(预测与真值比值落在 1.25×、1.25²×、1.25³× 阈值内的像素百分比,越高越好)、abs_rel(平均绝对相对误差)、rmse(米为单位的均方根误差)、silog(尺度不变对数误差),后三者越低越好。
在 YOLO26-Depth 预训练体系中的定位
SUN RGB-D 在 YOLO26-Depth 的数据体系中扮演的是"训练源"角色:它与 ARKitScenes、DIODE、Hypersim、TartanAir、Virtual KITTI 2、KITTI 及伪标签 ImageNet 等共同组成约 219 万图像—深度对的预训练混合集,覆盖从室内(≤10 m)到室外(约 80 m)的深度范围。各数据集的专门介绍见 深度数据集总览。
文档同时说明:SUN RGB-D 本身不是评测基准。YOLO26 深度模型族最终在五个标准基准上评估——NYU Depth V2(室内主基准)、KITTI Eigen(室外驾驶)、ETH3D(高精度室内+室外)、Make3D(室外、分布外)与 iBims-1(高质量室内);各模型在这些基准上的精度与可下载权重见 Depth Estimation 任务页。YOLO26 深度系列模型(例如 YOLO26x-depth)会从最新的 Ultralytics release 自动下载。
引用与致谢
若在研究或开发中使用了 SUN RGB-D 数据集,请引用下列论文:
@inproceedings{song2015sunrgbd,
title={SUN RGB-D: A RGB-D Scene Understanding Benchmark Suite},
author={Song, Shuran and Lichtenberg, Samuel P. and Xiao, Jianxiong},
booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
year={2015}
}
SUN RGB-D 是计算机视觉领域维护多年的重要资源,其多传感器室内深度数据为单目深度估计研究提供了不可替代的真实世界基准。
小结
- SUN RGB-D 在 Ultralytics 中以"9,245 训练 + 1,090 验证"的确定性划分提供真实多传感器室内深度,深度量程约 10 m;
- 数据集以标准
images/+depth/并行目录组织,深度为 uint16 毫米 PNG(默认depth_scale: 1000,0表示无效); - depth-sunrgbd.yaml 的下载脚本自动完成 6.5 GB 归档的下载、
depth_bfx位旋转解码((d>>3)|(d<<13),裁剪 10 m)与种子 0 的验证集切分,转换结果约 14 GB; DepthDataset负责按文件干名配对、缓存校验、INTER_NEAREST对齐缩放,并强制关闭 mosaic/mixup 等与深度语义冲突的增强;- 训练入口即
yolo depth train data=depth-sunrgbd.yaml model=yolo26n-depth.pt epochs=100 imgsz=640,管线调试可先用 1.3 MB 的 Depth8 数据集快速验证。
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