KITTI Bounding Boxes
The KITTI dataset is a widely-used computer vision dataset for benchmarking and evaluating autonomous driving systems. Due to the popularity of this dataset, many researchers and developers have adopted its label format for their own datasets and applications. Encord Active enhances your experience by migrating such labels to the Encord format.
The following approach only works for bounding boxes.
When running an importer, any previously imported predictions will be overwritten! To ensure the ability to revert to previous model iterations, it is important to version your projects.
If you possess KITTI predictions saved as TXT or CSV files, a utility function is available to import the predictions from those files, provided that each file is associated with a single image and its filename contains the data_hash
of the related image.
The following file structure is required:
labels_root
├── labels
│ ├── aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee__whatever_you_may_need.txt
│ ├── ...
│ └── aaaaaaaa-bbbb-cccc-dddd-ffffffffffff__whatever_you_may_need.csv
└── ontology_label_map.json
That is, a root directory with two components:
- A subdirectory named "labels" that contains TXT/CSV files with filenames that begin with the
data_hash
followed by two underscores. - A json file which maps class names to Encord ontology classes.
We cover these two components in detail below.
Label Files Format
The KITTI importer supports the label format described here with the addition of a column corresponding to the model confidence.
An example:
car 0.00 0 0.00 587.01 173.33 614.12 200.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 97.85
cyclist 0.00 0 0.00 665.45 160.00 717.93 217.99 0.00 0.00 0.00 0.00 0.00 0.00 0.00 32.65
pedestrian 0.00 0 0.00 423.17 173.67 433.17 224.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 3.183
Columns are:
class_name
: strignoredtruncation
: floatignoredocclusion
: intignoredalpha
: floatxmin
: floatymin
: floatxmax
: floatymax
: floatignoredheight
: floatignoredwidth
: floatignoredlength
: floatignoredlocation_x
: floatignoredlocation_y
: floatignoredlocation_z
: floatignoredrotation_y
: floatconfidence
: float
The columns flagged as ignored
have to appear in the label format but their values will be ignored.
The JSON Class Map
The JSON class map should follow a specific format where the keys should correspond to the featureNodeHash
of the bounding box objects in the project ontology, and the values should correspond to their respective KITTI class names.
{
# featureNodeHash: class_name
"OTk2MzM3": "pedestrian",
"NzYyMjcx": "cyclist",
"Nzg2ODEx": "car"
}
To obtain a list of available featureNodeHash
es for your project, you can use the following script:
import json
from encord_active.lib.project import ProjectFileStructure
fs = ProjectFileStructure("/path/to/your/project/root")
ontology = json.loads(fs.ontology.read_text())
print({o["featureNodeHash"]: o["name"] for o in ontology["objects"]})
# Example output:
# {'OTk2MzM3': 'Pedestrian', 'NzYyMjcx': 'Cyclist', 'Nzg2ODEx': 'Car'}
Importing the Predictions
Once you have a valid KITTI predictions folder, you can import the predictions into an Encord Active project running the following script:
import json
from pathlib import Path
from encord import EncordUserClient
from encord_active.lib.model_predictions.importers import import_KITTI_labels
from encord_active.lib.model_predictions.writer import PredictionWriter
from encord_active.lib.project import Project
from encord_active.lib.project.metadata import fetch_project_meta
project_path = Path("/path/to/your/project/root")
project_meta = fetch_project_meta(project_path)
private_key = Path(project_meta["ssh_key_path"]).read_text()
client = EncordUserClient.create_with_ssh_private_key(private_key)
encord_project = client.get_project(project_hash=project_meta["project_hash"])
predictions_root = Path("/path/to/your/predictions/root")
object_map = json.loads((predictions_root / "ontology_label_map.json").read_text())
with PredictionWriter(project=Project(project_path), custom_object_map=object_map) as writer:
import_KITTI_labels(encord_project, data_root=predictions_root, prediction_writer=writer)