Skip to content
advancedimage

KITTI - 3D Object Annotation on Lidar Point Clouds

Autonomous-driving benchmark from Geiger, Lenz and Urtasun (CVPR 2012). Annotators place oriented 3D cuboids on the lidar scan, with calibration projecting every box into the camera images for verification in 2D.

About this dataset

The KITTI Vision Benchmark Suite was introduced by Andreas Geiger and Philip Lenz of the Karlsruhe Institute of Technology and Raquel Urtasun of the Toyota Technological Institute at Chicago, in "Are we ready for Autonomous Driving? The KITTI Vision Benchmark Suite" at CVPR 2012. The paper builds benchmarks for stereo, optical flow, visual odometry and SLAM, and 3D object detection from recordings made with an instrumented car.

The object benchmark labels each traffic participant with an oriented 3D box in the rectified reference camera frame, alongside a 2D box in the image, a truncation fraction, and an occlusion code. Each line of a label_2 file carries fifteen fields: type, truncated, occluded, alpha, the four 2D box corners, the three box dimensions, the three location coordinates, and the rotation about the vertical axis.

Object classes are Car, Van, Truck, Pedestrian, Person_sitting, Cyclist, Tram and Misc. DontCare is not a class: KITTI uses it to mark regions excluded from evaluation, usually distant or ambiguous objects. Occlusion is coded 0 for fully visible, 1 for partly occluded, 2 for largely occluded and 3 for unknown.

Potato annotates the lidar scan directly with the spatial_annotation schema. That is what the label format describes in the first place. Octree level-of-detail keeps a full scan interactive, orthographic slab panels give axis-aligned editing, and calibration supplied per item projects every cuboid into each camera image so orientation can be checked in 2D while editing in 3D.

Potato stores cuboid rotation as a quaternion rather than a single yaw angle. Importing from KITTI is therefore lossless, including the camera-to-lidar mounting tilt that a yaw-only field discards silently; exporting back to KITTI drops pitch and roll and reports how much orientation it had to discard. Each scene goes to two annotators, and agreement over the cuboids is computed with exact rotated 3D IoU, which is correct under arbitrary rotation rather than only for level boxes.

Object classes
8 (plus DontCare as an exclusion marker)
Occlusion codes
0 fully visible - 3 unknown
Label fields per object
15
Sensors
Velodyne lidar, stereo cameras, GPS/IMU
Venue / Year
CVPR 2012
Labels:outdoornatureurbanpeopleanimal+

Configuration Fileconfig.yaml

This Potato config reproduces the annotation task. Save it as config.yaml and run potato start config.yaml to try it.

yaml
# yaml-language-server: $schema=https://potatoannotator.readthedocs.io/en/latest/schemas/potato-config.schema.json
#
# KITTI — 3D Object Annotation on Lidar Point Clouds
#
# Paper:   Geiger, Lenz & Urtasun, "Are we ready for Autonomous Driving?
#          The KITTI Vision Benchmark Suite", CVPR 2012
#          https://www.cvlibs.net/publications/Geiger2012CVPR.pdf
# Dataset: https://www.cvlibs.net/datasets/kitti/
#
# KITTI's object benchmark labels each traffic participant with an oriented 3D
# box in the rectified reference camera frame, plus a 2D box in the image, a
# truncation fraction and an occlusion code. Each `label_2/*.txt` line is
# fifteen fields:
#
#   type truncated occluded alpha  x1 y1 x2 y2  h w l  x y z  ry
#
# This config annotates the lidar scan directly with `spatial_annotation`,
# which is what the label format actually describes. Calibration is supplied
# per item, so every cuboid drawn in 3D projects into the camera images and can
# be checked in 2D without leaving the task.
#
# Reproduction notes
# ------------------
# Occlusion codes are the devkit's: 0 fully visible, 1 partly occluded,
# 2 largely occluded, 3 unknown.
#
# `DontCare` is deliberately absent from the label list. KITTI uses it to mark
# regions excluded from evaluation, usually distant or ambiguous objects, and
# it is not an object class. Potato imports it under its own label so the
# exclusion survives a round trip, but an annotator should not be drawing one.
#
# Potato stores cuboid rotation as a quaternion. KITTI stores a single yaw
# (`ry`), so exporting back to KITTI discards pitch and roll and reports how
# much orientation it had to drop. Importing from KITTI is lossless, including
# the camera-to-lidar mounting tilt that a yaw-only field would silently
# discard.
#
# Two annotators per scene, so agreement over the cuboids is defined. Potato
# scores 3D box agreement with exact rotated 3D IoU, which is correct under
# arbitrary rotation rather than only for axis-aligned boxes.

port: 8000
annotation_task_name: "KITTI - 3D Object Annotation"
task_dir: "."
media_directory: media
output_annotation_dir: "annotation_output/"
output_annotation_format: "json"

data_files:
  - sample-data.json

item_properties:
  id_key: "id"
  text_key: "point_cloud"

user_config:
  allow_all_users: true
  users: []

num_annotators_per_item:
  default: 2

annotation_schemes:
  - annotation_type: spatial_annotation
    name: objects
    description: "Put an oriented 3D box around every traffic participant."
    source_field: point_cloud
    tools:
      - cuboid_3d
    labels:
      - name: Car
        color: "#FF6B6B"
        key_value: "1"
      - name: Van
        color: "#F79256"
        key_value: "2"
      - name: Truck
        color: "#4ECDC4"
        key_value: "3"
      - name: Pedestrian
        color: "#FFD93D"
        key_value: "4"
      - name: Person_sitting
        color: "#C9A0DC"
        key_value: "5"
      - name: Cyclist
        color: "#6C8AE4"
        key_value: "6"
      - name: Tram
        color: "#95E1A3"
        key_value: "7"
      - name: Misc
        color: "#9AA0A6"
        key_value: "8"
    # Projects each 3D box into every calibrated camera, so orientation can be
    # verified against the image while editing in 3D.
    calibration_field: calibration
    color_mode: height
    point_size: 2.0
    lod: true
    max_points: 400000
    slab_thickness: 2.0
    default_box_height: 1.7
    fit_box_height: true

  - annotation_type: radio
    name: scene_occlusion
    description: "Overall, how occluded are the objects in this scene?"
    labels:
      - name: fully_visible
        tooltip: "KITTI occlusion code 0"
      - name: partly_occluded
        tooltip: "KITTI occlusion code 1"
      - name: largely_occluded
        tooltip: "KITTI occlusion code 2"
      - name: unknown
        tooltip: "KITTI occlusion code 3"
    label_requirement:
      required: true

  - annotation_type: text
    name: notes
    description: "Anything unclear about this scene? (optional)"

annotation_instructions: |
  Each item is one lidar scan from the KITTI recording platform, with the
  synchronized camera images beside it.

  For every traffic participant in the scan:
  1. Choose its class (Car, Van, Truck, Pedestrian, Person_sitting, Cyclist,
     Tram or Misc). Number keys 1-8 select classes directly.
  2. Draw an oriented 3D box around it. Fit the box to the object's own axes
     rather than to the world axes: heading matters.
  3. Check the box in the camera panels. A box that looks right in the bird's
     eye view and wrong in the image is usually rotated.

  Use the orthographic slab panels for axis-aligned adjustment when a box is
  close to correct but not tight.

  Do not draw boxes for regions KITTI would mark `DontCare`. That marker exists
  to exclude distant or ambiguous objects from evaluation and is not a class.

Sample Datasample-data.json

json
[
  {
    "id": "kitti_001",
    "point_cloud": "velodyne/0000000003.bin",
    "calibration": "calib/0000000003.txt",
    "cameras": {
      "image_2": "image_2/0000000003.png",
      "image_3": "image_3/0000000003.png"
    },
    "scene_type": "urban",
    "context": "Residential street, parked cars on both sides, one cyclist."
  },
  {
    "id": "kitti_002",
    "point_cloud": "velodyne/0000000017.bin",
    "calibration": "calib/0000000017.txt",
    "cameras": {
      "image_2": "image_2/0000000017.png",
      "image_3": "image_3/0000000017.png"
    },
    "scene_type": "city",
    "context": "Intersection with a tram, several pedestrians on the crossing."
  }
]

// ... and 8 more items

Get This Design

View on GitHub

Clone or download from the repository

Quick start:

git clone https://github.com/davidjurgens/potato-showcase.git
cd potato-showcase/image/driving/kitti
potato start config.yaml

Dataset & paper

Geiger et al., CVPR 2012

Citation (BibTeX)

bibtex
@inproceedings{geiger2012kitti,
    title = {Are we ready for Autonomous Driving? The {KITTI} Vision Benchmark Suite},
    author = {Geiger, Andreas and Lenz, Philip and Urtasun, Raquel},
    booktitle = {Conference on Computer Vision and Pattern Recognition (CVPR)},
    year = {2012}
}

Details

Annotation Types

spatial_annotationradiotext

Domain

Computer VisionRobotics

Use Cases

3D Object DetectionAutonomous DrivingPoint Cloud AnnotationSensor Fusion

Tags

kitti3d-object-detectionpoint-cloudlidarcuboidautonomous-drivingcvpr2012calibrationsensor-fusion

Found an issue or want to improve this design?

Open an Issue