首页
/ Ultralytics YOLO26-Depth 中的 TartanAir 深度数据集:AirSim 合成数据、80 米稠密真值与 uint16 PNG 深度格式

Ultralytics YOLO26-Depth 中的 TartanAir 深度数据集:AirSim 合成数据、80 米稠密真值与 uint16 PNG 深度格式

2026-09-05 23:32:02作者:袁立春Spencer

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 深度数据集分为两个子集:

  1. Train:55,660 张图像,配有成对的稠密深度图,用于训练;
  2. 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.npyimage_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: 1names: {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.ptyolo26s-depth.ptyolo26m-depth.ptyolo26l-depth.ptyolo26x-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}
}

小结与关键文件索引

掌握以上内容后,你可以:按 AirSim 原始 .npy 深度完成下载、天空置零、uint16 PNG 量化与 train/val 划分的全套转换;理解 depth_scale: 256max_depth: 80 在加载、损失和验证指标中的完整链路;并直接以 YAML + 预训练权重在 TartanAir 上训练 YOLO26-Depth 模型。

登录后查看全文
热门项目推荐
相关项目推荐