Ultralytics YOLO26-Depth 中的 TartanAir 深度数据集:AirSim 合成数据、80 米稠密真值与 uint16 PNG 深度格式
TartanAir 是 Ultralytics YOLO26-Depth 单目深度估计预训练混合数据集中规模最大、环境多样性最强的合成数据来源之一。本篇基于仓库文档 tartanair.md 与配套 YAML 配置 depth-tartanair.yaml 展开,讲解其数据获取与转换流程、depth_scale: 256 的 uint16 PNG 深度存储约定、max_depth: 80 在验证指标中的实际作用,以及如何用 Python 与 CLI 在 TartanAir 上训练 YOLO26-Depth 模型。
TartanAir 数据集关键特性
TartanAir 是在 AirSim 模拟器中生成的大规模合成数据集,最初目标是突破视觉 SLAM 的性能极限。其对深度估计任务的价值主要体现在以下几点:
- 合成数据:完全由 AirSim 模拟器渲染,几何与深度真值天然精确;
- 室内外环境多样:覆盖城市(urban)、自然(nature)等场景,并包含季节、天气、光照变化与多种挑战性条件;
- 稠密深度真值:所有场景均配有逐像素稠密深度图;
- 深度量程约 80 m:适合室外远距离几何建模;
- 规模:向 Ultralytics 深度训练混合集贡献 61,470 张图像(55,660 张训练 / 5,810 张验证)。
在 YOLO26-Depth 的约 219 万张多数据集预训练混合中,TartanAir 提供的是合成环境多样性与室外远场几何,与室内和真实数据来源互补。
数据集结构:图像与深度对的划分
TartanAir 深度数据集分为两个子集:
- Train:55,660 张图像,配有成对的稠密深度图,用于训练;
- Val:5,810 张图像,配有成对的稠密深度图,用于训练过程中的验证。
每张 RGB 图像都与一张 scaled uint16 深度 PNG 配对,采用 256 个单位对应 1 米(depth_scale: 256)的约定,遵循 Ultralytics 深度数据集格式。该约定可以用约 4 毫米的分辨率(3.90625 mm)表示完整的 80 m 量程。
目录布局
YAML 头部注释给出了标准布局:
parent
├── ultralytics
└── datasets
└── depth-tartanair
├── images/{train,val} # RGB images
└── depth/{train,val} # paired 16-bit *.png depth maps (images/ -> depth/)
加载器会将路径中最后一段 images 目录组件替换为 depth 来定位深度文件,优先 .png、回退 .npy。这一行为在源码 DepthDataset._depth_path_for 中可以直接验证:
def _depth_path_for(self, im_file: str) -> str:
"""Map an image path to its companion PNG or NPY depth target."""
parts = list(Path(im_file).parts)
for i in range(len(parts) - 1, -1, -1):
if parts[i] == "images":
parts[i] = "depth"
break
path = Path(*parts).with_suffix(".png")
return str(path if path.is_file() else path.with_suffix(".npy"))
即 images/train/urban_1_000000_left.png 会自动配对到 depth/train/urban_1_000000_left.png。文件名主干(stem)必须一致,深度图可以比 RGB 图像小(宽高比一致即可),训练时会在内存中用最近邻插值调整到目标尺寸(见 get_image_and_label)。
获取数据:tartanair_tools 下载与格式转换
TartanAir 不支持自动下载(YAML 中明确标注 No autodownload)。源数据由 CMU 的 AirLab 分发,需要通过其 tartanair_tools 脚本下载:
git clone https://github.com/castacks/tartanair_tools && cd tartanair_tools
python download_training.py --output-dir ./data --rgb --depth --only-left --unzip
下载后,深度已经以 float32 .npy、单位米 存储(depth_left/*_left_depth.npy 与 image_left/*_left.png 相邻)。因此转换工作主要是:重新组织目录结构,并将天空(渲染为极远距离)标记为无效。官方发布的混合数据在 80 m 处截断,以匹配数据集 YAML。TartanAir 没有官方 val 划分,惯例是预留一个或多个环境(environment)作为验证集。
仓库文档给出的参考转换脚本:
import shutil
from pathlib import Path
import numpy as np
from ultralytics.data.utils import save_depth_png
VAL_ENVS = {"neighborhood"} # environments held out for validation
src, dst = Path("data"), Path("datasets/depth-tartanair")
for depth_file in sorted(src.rglob("depth_left/*_left_depth.npy")):
env, traj = depth_file.parts[-5], depth_file.parts[-3]
out = "val" if env.lower() in VAL_ENVS else "train"
(dst / f"images/{out}").mkdir(parents=True, exist_ok=True)
(dst / f"depth/{out}").mkdir(parents=True, exist_ok=True)
depth = np.load(depth_file)
depth[depth > 80.0] = 0.0 # sky/extreme range → 0 = invalid
frame = depth_file.name.replace("_depth.npy", "") # e.g. 000000_left
name = f"{env}_{traj}_{frame}"
save_depth_png(dst / f"depth/{out}/{name}.png", depth, scale=256)
shutil.copy(depth_file.parents[1] / "image_left" / f"{frame}.png", dst / f"images/{out}/{name}.png")
脚本要点:
- 从
.npy路径中提取env(环境)与traj(轨迹)两个路径组件,构造{env}_{traj}_{frame}的唯一起名,避免不同环境间文件名冲突; depth[depth > 80.0] = 0.0将超过 80 m 的天空/极远像素置为 0——在 Ultralytics 深度格式中,0(以及≤ 0的值)表示无效像素,这些像素会被排除在损失与指标计算之外;save_depth_png(..., scale=256)完成米 → uint16 PNG 的量化。
底层实现:save_depth_png 与 load_depth
转换脚本依赖的核心函数是 save_depth_png:
def save_depth_png(path: str | Path, depth: np.ndarray, scale: float = DEPTH_PNG_SCALE) -> None:
"""Save metric depth as a scaled uint16 PNG with zero reserved for invalid pixels."""
...
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 {np.iinfo(np.uint16).max / scale:g} meter PNG limit")
encoded[valid] = np.maximum(scaled, 1).astype(np.uint16)
它做了三件与 TartanAir 约定直接相关的事:非有限值与 ≤ 0 的像素保留为 0(无效标记);深度乘以 scale(此处 256)四舍五入到 uint16;并对超出 65535 单位的深度直接报错(对 scale=256 即约 255.9 m 上限)。读取侧的 load_depth 则把 PNG 的整数像素值除以 depth_scale 还原为米制 float32 数组,因此 TartanAir YAML 中的 depth_scale: 256 与转换时 scale=256 必须一致,否则深度值会整体错一个系数。
不同 depth_scale 的存储精度/量程权衡(来自 深度数据集格式文档):
| 约定 | depth_scale |
分辨率 | 最大深度 |
|---|---|---|---|
| 默认 / ARKitScenes | 1000 |
1 mm | 65.535 m |
| KITTI(TartanAir 同约定) | 256 |
3.90625 mm | 255.99609375 m |
| Virtual KITTI 2 | 100 |
1 cm | 655.35 m |
这些是存储极限而非训练上限;数据集可以独立设置更小的 max_depth 用于损失标定与评测。
数据集 YAML 配置逐项解析
TartanAir 的完整配置见 depth-tartanair.yaml:
# Ultralytics AGPL-3.0 License - https://ultralytics.com/license
# TartanAir dataset for monocular depth estimation — synthetic indoor + outdoor (AirSim), dense depth up to ~80 m
# Example usage: yolo depth train data=depth-tartanair.yaml model=yolo26n-depth.pt
# No autodownload — obtain the source data (see docs) and arrange it as below.
path: depth-tartanair # dataset root dir (relative to Ultralytics settings 'datasets_dir')
train: images/train # train images (relative to 'path') 55660 images
val: images/val # val images (relative to 'path') 5810 images
max_depth: 80 # (m) maximum valid depth; GT beyond this is excluded from val metrics
nc: 1
names:
0: depth
channels: 3
depth_scale: 256 # PNG value 256 = 1 meter; represents the 80 m outdoor range
各字段的作用:
path: depth-tartanair:数据集根目录,相对于 Ultralytics 设置中的datasets_dir(默认~/datasets或用户自定义目录),对应上文转换脚本输出到datasets/depth-tartanair;train/val:相对于path的图像目录,深度文件由加载器按images → depth规则自动推导,无需在 YAML 中声明;nc: 1与names: {0: depth}:深度估计任务的固定约定——只有一个“类别”,即逐像素深度;channels: 3:RGB 三通道输入;depth_scale: 256:PNG 整数单位与米的换算系数,读取时由 dataset 缓存与加载逻辑 以self.data.get("depth_scale", 1000)的形式传入load_depth(默认值 1000,即毫米约定);max_depth: 80:最大有效深度。验证时,真值超出该范围的像素会从指标计算中排除,预测值也被钳制在该范围内。
max_depth: 80 在验证管线中的落地
从源码看,max_depth 并非仅存在于注释层面。DepthValidator 在初始化指标时读取它:
self.metrics = DepthMetrics(max_depth=self.data.get("max_depth") or 100.0)
而 DepthMetrics 按标准 Eigen 评测协议执行:mask = (gi > min_depth) & (gi < max_depth),只对真值落在 (0.001, max_depth) 内的像素计分,预测值同样被 clamp 到该区间。因此 TartanAir 的 max_depth: 80 意味着:训练时天空已置 0(无效),验证时 80 m 之外的真值像素(即便残留)也不会污染 delta1/abs_rel/rmse/silog 等指标。这与文档中“发布混合在 80 m 处截断以匹配 YAML”的描述一致。
在 YOLO26-Depth 训练混合中的角色
TartanAir 是约 219 万张图像多数据集混合(multi-dataset mix)的预训练来源之一,与 ARKitScenes、SUN RGB-D、DIODE、Hypersim、Virtual KITTI 2、KITTI 及伪标签 ImageNet 等来源共同构成 YOLO26 深度模型的预训练基础。TartanAir 在其中补充的是合成环境多样性与远场室外几何。
需要特别说明评测口径:该设置下没有独立的 TartanAir 留出基准。训练结果最终在标准单目深度基准上评测——NYU Depth V2(nyu-depth-v2.md)、KITTI、Make3D、ETH3D 与 iBims-1。
用法:Python 与 CLI 训练示例
在 TartanAir 数据集上以 640 图像尺寸训练 YOLO26n-Depth:
Python:
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-tartanair.yaml", epochs=100, imgsz=640)
CLI:
# Start training from a pretrained *.pt model
yolo depth train data=depth-tartanair.yaml model=yolo26n-depth.pt epochs=100 imgsz=640
完整可训练参数可参考 Training 模式文档。训练/验证时,depth 键的 batch 在 collate_fn 中被 torch.stack 成张量,验证侧 DepthValidator.preprocess 将其保持为 float32 并传入 DepthMetrics。
预训练模型与引用
YOLO26 深度模型族——yolo26n-depth.pt、yolo26s-depth.pt、yolo26m-depth.pt、yolo26l-depth.pt、yolo26x-depth.pt——会从 Ultralytics releases 自动下载,且正是在包含 TartanAir 的多数据集混合上训练得到的(模型结构配置见 yolo26-depth.yaml)。
如果在使用 TartanAir 数据集的研究或开发工作中引用它,请引用以下论文:
@inproceedings{wang2020tartanair,
title={TartanAir: A Dataset to Push the Limits of Visual SLAM},
author={Wenshan Wang and Delong Zhu and Xiangwei Wang and Yaoyu Hu and Yuheng Qiu and Chen Wang and Yafei Hu and Ashish Kapoor and Sebastian Scherer},
booktitle={IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
year={2020}
}
小结与关键文件索引
- 数据集文档:tartanair.md
- 深度格式总览(PNG/NPY 约定、
depth_scale、目录布局):index.md - 数据集配置:depth-tartanair.yaml
- 深度 PNG 读写实现:save_depth_png / load_depth
- 图像-深度配对与加载:DepthDataset
- 验证指标(Eigen 协议 +
max_depth过滤):DepthMetrics、DepthValidator
掌握以上内容后,你可以:按 AirSim 原始 .npy 深度完成下载、天空置零、uint16 PNG 量化与 train/val 划分的全套转换;理解 depth_scale: 256 与 max_depth: 80 在加载、损失和验证指标中的完整链路;并直接以 YAML + 预训练权重在 TartanAir 上训练 YOLO26-Depth 模型。
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