Ultralytics YOLO26-Depth 深度估计训练指南:Hypersim 合成室内深度数据集的获取、格式转换与实战用法
本文围绕 Ultralytics 仓库中的 Hypersim 深度数据集文档(docs/en/datasets/depth/hypersim.md)展开,讲解这个由 Apple 发布的照片级真实感合成室内场景数据集如何为 YOLO26-Depth 单目深度估计模型提供干净、稠密的逐像素深度监督。读完后你将掌握:Hypersim 原始数据(tonemap RGB 帧 + depth_meters.hdf5)如何转换为 Ultralytics 深度数据集格式、配套的 depth-hypersim.yaml 配置如何工作,以及底层加载/编码实现(save_depth_png、DepthDataset)的关键细节,从而能够独立完成从原始数据下载到 yolo depth train 的完整流程。
数据集概述:为什么选择全合成的 Hypersim
Hypersim 是一个面向室内场景整体理解(holistic indoor scene understanding)的照片级真实感合成数据集:其图像基于专业制作的 Evermotion 3D 室内模型进行光线追踪(ray-tracing)渲染,每一帧都配有完美、稠密的逐像素深度真值。
由于 Hypersim 是全合成数据,每个像素都有精确的深度值,不存在传感器噪声、缺失回波或测量伪影。这使它成为训练单目深度估计模型的优质室内几何来源——文档将其定位为 Ultralytics 深度训练混合数据(multi-dataset mixture)中的“干净稠密室内几何”补充项,与带噪声的真实传感器数据(如 LiDAR 重建)形成互补。
关键特性汇总:
- 光线追踪渲染的合成室内场景,照片级真实感;
- 仅覆盖室内环境(indoor only);
- 稠密、无噪声、无缺失值的逐像素深度真值;
- 深度范围以 ≤10 m 为主(含少量更大距离);
- 为 Ultralytics 深度训练混合数据贡献 74,619 张图像(68,242 训练 / 6,377 验证)。
数据分为两个子集:
- Train:68,242 张图像,配对的稠密深度图,用于训练;
- Val:6,377 张图像,配对的稠密深度图,用于训练期间验证。
每张 RGB 图像都配对一个经缩放的 uint16 深度 PNG,遵循 Ultralytics 深度数据集格式(第 0 值保留给无效像素,PNG 整数值除以 depth_scale——默认 1000——还原为米)。
获取原始数据与目录组织
Hypersim 不支持自动下载(no autodownload):约 1.9 TB 的按场景打包 ZIP 由 Apple 以 CC BY-SA 3.0 协议分发,需要通过官方 ml-hypersim 仓库 的脚本下载(该仓库的 contrib/99991 中还提供了选择性下载工具):
git clone https://github.com/apple/ml-hypersim && cd ml-hypersim
python code/python/tools/dataset_download_images.py --downloads_dir ./downloads --decompress_dir ./scenes
下载解压后,原始数据的对应关系是:
- RGB 帧:各场景目录下的
frame.*.tonemap.jpg预览图(目录名为{cam}_final_preview); - 深度:
frame.*.depth_meters.hdf5。
这里有一个关键的物理含义陷阱:HDF5 中存储的数值是光线到相机中心的距离(ray distance),而不是垂直于成像平面的平面深度(planar depth)。因此保存前必须先做几何换算;同时,玻璃与天空等区域的像素为 NaN,需映射为 0(无效)。训练/验证的划分应使用官方 metadata_images_split_scene_v1.csv 的场景划分表逐场景指派。
参考转换脚本:从 HDF5 到 Ultralytics 深度格式
文档给出了完整的参考转换代码,它把原始场景目录转换为标准布局 datasets/depth-hypersim/{images,depth}/{train,val}:
import shutil
from pathlib import Path
import h5py
import numpy as np
from ultralytics.data.utils import save_depth_png
W, H, FOCAL = 1024, 768, 886.81 # Hypersim 相机内参
x, y = np.meshgrid(np.linspace(-W / 2, W / 2, W), np.linspace(-H / 2, H / 2, H))
ray2plane = (FOCAL / np.sqrt(x**2 + y**2 + FOCAL**2)).astype(np.float32) # 光线距离 → 平面深度
src, dst = Path("scenes"), Path("datasets/depth-hypersim")
out = "train" # 按 metadata_images_split_scene_v1.csv 逐场景指派
(dst / f"images/{out}").mkdir(parents=True, exist_ok=True)
(dst / f"depth/{out}").mkdir(parents=True, exist_ok=True)
for h5 in sorted(src.rglob("*.depth_meters.hdf5")):
scene, cam, frame = h5.parts[-4], h5.parent.name.split("_geometry")[0], h5.name.split(".")[1]
rgb = h5.parents[1] / f"{cam}_final_preview" / f"frame.{frame}.tonemap.jpg"
dist = np.asarray(h5py.File(h5)["dataset"], np.float32)
depth = np.nan_to_num(dist * ray2plane, nan=0.0) # NaN(天空、玻璃)→ 0 = 无效
name = f"{scene}_{cam}_{frame}"
save_depth_png(dst / f"depth/{out}/{name}.png", depth)
shutil.copy(rgb, dst / f"images/{out}/{name}.jpg")
逐点拆解这段脚本中值得注意的环节:
- 光线距离 → 平面深度换算:
ray2plane = FOCAL / sqrt(x² + y² + FOCAL²),其中(x, y)是以图像中心为原点、以像素为单位的网格坐标,FOCAL = 886.81为 Hypersim 固定相机焦距(对应 1024×768 分辨率)。像素离光轴越远,光线距离与平面深度差得越多,这个逐像素乘数正是二者之间的换算系数。 - NaN 处理:
np.nan_to_num(..., nan=0.0)把天空/玻璃等无回波区域编码为 0,与 Ultralytics 深度格式中“0 = 无效像素,从 loss 与指标计算中剔除”的约定完全一致。 save_depth_png:来自 ultralytics/data/utils.py 的官方工具函数。从源码看,它以DEPTH_PNG_SCALE = 1000(ultralytics/data/utils.py 中定义的常量)为默认缩放,把以米为单位的 float32 深度图编码为 uint16 PNG:对每个有效像素执行np.rint(depth * 1000)并保证最小为 1(0 保留给无效);若任一像素换算后超过uint16上限 65535,会直接抛出“Depth map exceeds the 65.535 meter PNG limit”错误——这意味着该格式默认支持 1 mm 分辨率、最深约 65.5 m,而 Hypersim 以 ≤10 m 为主的室内深度完全落在此范围内,无需自定义depth_scale。- 命名对齐:RGB 与深度 PNG 共用同一文件 stem(
{scene}_{cam}_{frame}),这是加载器配对的前提(下文详述)。
数据集 YAML 与加载器行为
仓库内置的配置 ultralytics/cfg/datasets/depth-hypersim.yaml 完整内容如下:
path: depth-hypersim # dataset root dir (relative to Ultralytics settings 'datasets_dir')
train: images/train # train images (relative to 'path') 68242 images
val: images/val # val images (relative to 'path') 6377 images
nc: 1
names:
0: depth
channels: 3
字段含义(参见 深度数据集格式总览):
| 字段 | 值 | 说明 |
|---|---|---|
path |
depth-hypersim |
数据集根目录,相对于 Ultralytics 设置的 datasets_dir |
train |
images/train |
68,242 张训练图像(相对 path) |
val |
images/val |
6,377 张验证图像(相对 path) |
nc / names |
1 / {0: depth} |
深度任务恒为单类 depth |
depth_scale |
(未设置) | 缺省即取默认 1000,对应 mm 级 uint16 PNG |
注意该 YAML 没有 depth_scale 字段——这符合 Hypersim 转换后采用默认毫米约定的事实;相比之下,KITTI(256)、DIODE/TartanAir(256)、Virtual KITTI 2(100)等室外数据集因深度范围更大而显式设置了不同的 depth_scale(见 depth-kitti.yaml、depth-vkitti2.yaml)。
加载侧的实现位于 ultralytics/data/dataset.py 的 DepthDataset 类,几个与 Hypersim 目录结构直接相关的行为值得了解:
- 深度文件配对规则(
_depth_path_for,dataset.py):把图像路径中最后一个images目录分量替换为depth,优先取.png,不存在则回退.npy。这解释了为什么转换脚本必须把深度 PNG 放在与images平行的depth/{train,val}下且 stem 一致。 - 深度读取(
_load_depth):调用 load_depth,PNG 走“uint16 解码后除以depth_scale”路径,读取时把depth_scale缺省值兜底为 1000。 - 对齐与无效掩码:
get_image_and_label会把深度图用最近邻插值(INTER_NEAREST)对齐到缩放后的 RGB 尺寸——最近邻保证深度值不被插值平滑破坏;深度≤ 0的像素在 loss 与指标计算中被剔除,正好承接转换时把 NaN 写为 0 的约定。 - 缓存键:
get_cache_hash把深度文件列表、图像列表和depth_scale一起纳入哈希(dataset.py),任何一对文件增删都会使旧缓存失效。
在 YOLO26-Depth 中的角色
Hypersim 是用于预训练 Ultralytics YOLO26-Depth 模型的训练来源之一。该预训练混合数据规模约 2.19M 张图像,横跨室内(≤10 m)到室外(约 80 m)深度范围,Hypersim 在其中提供干净、稠密的室内几何,补充噪声更大的真实传感器数据(来源构成详见 深度数据集总览 的 Supported Datasets 一节)。
有两点值得强调:
- 没有独立的 Hypersim 保留基准:该方案下不为 Hypersim 单设 held-out 评测集,模型最终在标准单目深度基准上评估——NYU Depth V2、KITTI、Make3D、ETH3D 与 iBims-1。
- 与无界 log 深度头的匹配:从 深度任务页 的 A/B 实验看,YOLO26-Depth 的深度头预测
exp(logit),输出无界(约 0.02–150 m),避免了固定max_depth上限;在单数据集微调实验中,Hypersim(深度以 ≤10 m 为主)即使使用有界头也能取得 δ1 0.74,说明其室内深度分布与有界假设兼容,而混合训练时正是 Hypersim 这类室内数据与室外数据共同塑造了跨量程能力。
训练用法
按文档示例,以图像尺寸 640 在 Hypersim 上训练 YOLO26n-Depth(完整参数列表参见 Training 文档):
from ultralytics import YOLO
# Load a model
model = YOLO("yolo26n-depth.pt") # load a pretrained model (recommended for training)
# Train the model
results = model.train(data="depth-hypersim.yaml", epochs=100, imgsz=640)
# Start training from a pretrained *.pt model
yolo depth train data=depth-hypersim.yaml model=yolo26n-depth.pt epochs=100 imgsz=640
对应的模型架构定义见 ultralytics/cfg/models/26/yolo26-depth.yaml。YOLO26 深度模型家族(yolo26n-depth.pt、yolo26s-depth.pt、yolo26m-depth.pt、yolo26l-depth.pt、yolo26x-depth.pt)会在首次使用时从 Ultralytics releases 自动下载预训练权重;这些权重的预训练数据即包含 Hypersim 在内的多数据集混合集。
引文与致谢
如果你在研究或开发中使用了 Hypersim 数据集,请引用其论文:
@inproceedings{roberts2021hypersim,
title={Hypersim: A Photorealistic Synthetic Dataset for Holistic Indoor Scene Understanding},
author={Mike Roberts and Jason Ramapuram and Anurag Ranjan and Atulit Kumar and Miguel Angel Bautista and Nathan Paczan and Russ Webb and Joshua M. Susskind},
booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision (ICCV)},
year={2021}
}
感谢 Hypersim 的创建者向计算机视觉社区开放了这个照片级真实感合成室内数据集。
小结
- Hypersim 以 74,619 张(68,242 train / 6,377 val)无噪声稠密室内深度样本,成为 YOLO26-Depth 约 2.19M 张预训练混合数据中的关键室内几何来源;
- 使用原始数据必须完成“光线距离 → 平面深度”的逐像素换算(
FOCAL / sqrt(x² + y² + FOCAL²),FOCAL=886.81)、NaN→0 的无效化,以及按官方metadata_images_split_scene_v1.csv的场景级 train/val 划分; - 转换产物遵循
images/↔depth/平行目录、同名 stem、默认depth_scale=1000的 Ultralytics 深度格式,由 depth-hypersim.yaml 声明,并经DepthDataset的路径替换、最近邻对齐与无效掩码机制消费; - 最终通过
yolo depth train data=depth-hypersim.yaml model=yolo26n-depth.pt epochs=100 imgsz=640即可在 Hypersim 上完成训练。
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 StartedRust0624
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