Enterprise-ready security: ISO 27001 + SOC 2 Type I compliant.

Link to this sectionKITTI Depth Dataset#

The KITTI dataset is a real-world outdoor autonomous-driving benchmark captured from a moving vehicle in and around the city of Karlsruhe. For monocular depth estimation, the ground-truth depth is derived from a Velodyne HDL-64 LiDAR scanner and densified using the method of Uhrig et al. 2017. The resulting depth maps remain sparse, with roughly 16–20% of pixels carrying a valid depth value. KITTI is the only real outdoor long-range source in the YOLO26-Depth pretraining mix and also serves as the KITTI Eigen evaluation benchmark.

Link to this sectionKey Features#

  • Real outdoor driving scenes with depths spanning up to roughly 80 m, far beyond the typical indoor range.
  • Depth ground truth obtained from a Velodyne HDL-64 LiDAR and densified with the Sparsity Invariant CNNs approach of Uhrig et al. 2017.
  • Sparse supervision: only about 16–20% of pixels per image carry a valid depth value; invalid pixels are masked out of the loss and metrics.
  • Stereo image pairs (left image_02 and right image_03) provide additional viewpoints for training.
  • Depth values are stored as .npy float32 arrays in meters, following the Ultralytics depth dataset format.

Link to this sectionDataset Structure#

The KITTI depth data used by Ultralytics is split into two subsets:

  1. Training split: 60,040 images (left image_02 and right image_03). The 28 KITTI Eigen test drives are excluded from training to keep evaluation fair.
  2. Evaluation split: the KITTI Eigen test split, 32,378 images (both cameras). Evaluation uses the Garg crop, an 80 m depth cap, and log-least-squares alignment between predictions and ground truth.

The depth range reaches approximately 80 m, and the dataset YAML (depth-kitti.yaml) sets max_depth: 80 accordingly.

Link to this sectionRole in YOLO26-Depth#

KITTI supplies the only real outdoor, long-range supervision in the YOLO26-Depth pretraining mix, complementing the predominantly indoor sources. It is also the standard KITTI Eigen benchmark for reporting driving-scene depth accuracy.

KITTI is a key example of why the depth head is unbounded (log mode): a fixed 10 m output ceiling cannot represent 80 m driving scenes. See the depth task page for details on the head output range and max_depth handling.

Link to this sectionResults#

KITTI Eigen delta1 accuracy by model size (higher is better):

ModelKITTI Eigen δ1
YOLO26n-Depth0.888
YOLO26s-Depth0.882
YOLO26m-Depth0.924
YOLO26l-Depth0.927
YOLO26x-Depth0.939

Link to this sectionDataset YAML#

A YAML (Yet Another Markup Language) file is used to define the dataset configuration. It contains information about the dataset's paths, classes, and other relevant information such as the maximum depth.

ultralytics/cfg/datasets/depth-kitti.yaml
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license

# KITTI dataset for monocular depth estimation — real outdoor driving, Velodyne HDL-64 LiDAR (densified), sparse, up to ~80 m
# Documentation: https://docs.ultralytics.com/datasets/depth/kitti
# Example usage: yolo depth train data=depth-kitti.yaml model=yolo26n-depth.pt
# parent
# ├── ultralytics
# └── datasets
#     └── depth-kitti  ← downloads here (~190 GB archives, ~230 GB converted)
#         ├── images/{train,val}  # RGB images
#         └── depth/{train,val}   # paired *.npy, float32 meters (images/ -> depth/)
# If an interrupted download leaves a partial dataset, delete the depth-kitti dir and re-run to rebuild it.

path: depth-kitti # dataset root dir (relative to Ultralytics settings 'datasets_dir')
train: images/train # train images (relative to 'path') 60040 images
val: images/val # val images (relative to 'path') 32378 images (KITTI Eigen test split)
max_depth: 80 # (m) maximum valid depth; GT beyond this is excluded from val metrics

nc: 1
names:
  0: depth

channels: 3

# Download script/URL (optional)
download: |
  import shutil
  from pathlib import Path

  import cv2
  import numpy as np

  from ultralytics.utils import TQDM
  from ultralytics.utils.downloads import download

  # Drives of the 28 KITTI Eigen test scenes -> val; every other annotated drive -> train
  VAL_DRIVES = """2011_09_26_drive_0002 2011_09_26_drive_0009 2011_09_26_drive_0013 2011_09_26_drive_0020
  2011_09_26_drive_0023 2011_09_26_drive_0027 2011_09_26_drive_0029 2011_09_26_drive_0036 2011_09_26_drive_0046
  2011_09_26_drive_0048 2011_09_26_drive_0052 2011_09_26_drive_0056 2011_09_26_drive_0059 2011_09_26_drive_0064
  2011_09_26_drive_0084 2011_09_26_drive_0086 2011_09_26_drive_0093 2011_09_26_drive_0096 2011_09_26_drive_0101
  2011_09_26_drive_0106 2011_09_26_drive_0117 2011_09_28_drive_0002 2011_09_29_drive_0026 2011_09_29_drive_0071
  2011_09_30_drive_0016 2011_10_03_drive_0034 2011_10_03_drive_0042 2011_10_03_drive_0047""".split()
  # Annotated drives excluded from the release training set (raw data was unavailable at build time)
  SKIP_DRIVES = {"2011_09_28_drive_0104", "2011_09_28_drive_0135", "2011_09_28_drive_0177", "2011_09_28_drive_0214"}

  # Download the improved sparse GT (~14 GB) and the raw recordings it covers (~175 GB)
  dir = Path(yaml["path"])  # dataset root dir
  base = "https://s3.eu-central-1.amazonaws.com/avg-kitti"
  download([f"{base}/data_depth_annotated.zip"], dir=dir / "source", delete=True, exist_ok=True)
  gt_drives = sorted(p for p in (dir / "source" / "data_depth_annotated").glob("*/*_sync") if p.name[:-5] not in SKIP_DRIVES)
  urls = [f"{base}/raw_data/{p.name[:-5]}/{p.name}.zip" for p in gt_drives]
  download(urls, dir=dir / "source" / "raw", delete=True, exist_ok=True, threads=4)

  # Convert: GT PNGs are uint16 meters*256; RGB frames come from the matching raw drive
  for split in ("train", "val"):
      (dir / "images" / split).mkdir(parents=True, exist_ok=True)
      (dir / "depth" / split).mkdir(parents=True, exist_ok=True)
  for gt in TQDM(gt_drives, desc="Converting"):
      drive = gt.name[:-5]  # 2011_09_26_drive_0002
      split = "val" if drive in VAL_DRIVES else "train"
      for cam in ("image_02", "image_03"):
          for png in sorted((gt / "proj_depth" / "groundtruth" / cam).glob("*.png")):
              name = f"{drive}_{cam[-2:]}_{png.stem}"
              depth = cv2.imread(str(png), cv2.IMREAD_ANYDEPTH).astype(np.float32) / 256.0
              np.save(dir / "depth" / split / f"{name}.npy", depth)
              raw = dir / "source" / "raw" / drive[:10] / gt.name / cam / "data" / png.name
              raw.replace(dir / "images" / split / f"{name}.png")
  shutil.rmtree(dir / "source")

Link to this sectionUsage#

To train a YOLO26n-Depth model on the KITTI dataset for 100 epochs, you can use the following code snippets. For a comprehensive list of available arguments, refer to the model Training page.

Train Example
from ultralytics import YOLO

# Load a pretrained depth model
model = YOLO("yolo26n-depth.pt")

# Train the model on KITTI
results = model.train(data="depth-kitti.yaml", epochs=100, imgsz=640)

Link to this sectionPretrained Models#

Pretrained YOLO26-Depth models auto-download from the Ultralytics v8.4.0 assets release when first referenced by name:

Link to this sectionCitations and Acknowledgments#

If you use the KITTI dataset in your research or development work, please cite the following papers:

Quote
@article{geiger2013vision,
      title={Vision meets Robotics: The KITTI Dataset},
      author={Geiger, Andreas and Lenz, Philip and Stiller, Christoph and Urtasun, Raquel},
      journal={The International Journal of Robotics Research},
      year={2013},
      publisher={SAGE Publications}
}

@inproceedings{uhrig2017sparsity,
      title={Sparsity Invariant CNNs},
      author={Uhrig, Jonas and Schneider, Nick and Schneider, Lukas and Franke, Uwe and Brox, Thomas and Geiger, Andreas},
      booktitle={International Conference on 3D Vision (3DV)},
      year={2017}
}

We would like to acknowledge the Karlsruhe Institute of Technology and Toyota Technological Institute at Chicago for creating and maintaining the KITTI dataset, and Uhrig et al. for the depth densification method that makes dense supervision possible.

Contributors

Comments