Annotations¶
Annotations in LightlyStudio allow you to view, create, edit, and delete annotations on your samples in the GUI or via the Python API. Supported annotation types include object detection, segmentation, and classification. You can import annotations from common formats like COCO or YOLO and more. See Image Dataset and Video Dataset for the available import workflows and supported formats.
Terminology
- Annotation — a classification, object-detection box, or segmentation mask attached to a sample.
- Annotation class — the category of an annotation, e.g.
"dog"or"cat". - Annotation source — a named group of annotations from one origin, e.g. ground truth, a model's predictions, or an annotator.
Annotations in the GUI¶
Annotations are shown in sample detail view and in dedicated annotation-focused views in the app. Use Edit Annotations to create, update, or delete annotations directly in the GUI.
Annotations in Python¶
Use the Python API when you want to inspect annotations programmatically, generate them from model
predictions, or import custom annotation outputs. Predictions and human annotations are treated as the same concept in LightlyStudio. Any functions for annotations can also process predictions. Predictions can additionally have an optional confidence value. See
Annotation API Reference for the full API surface.
Annotation sources¶
Every annotation belongs to an annotation source. Annotation sources group related annotations, for example ground truth, predictions from one model run, or annotations from different annotators.
This lets you keep multiple annotation sources for the same samples separate. In the GUI, you can inspect individual annotation sources, visualize multiple sources together, and compare them via evaluation runs.
Adding annotations¶
For most workflows, the easiest way to add annotations is to import them from supported formats such as COCO and YOLO, either while adding samples to the dataset or later by attaching annotations to already indexed samples:
# Add images and annotations together.
dataset.add_samples_from_coco(
annotations_json="/path/to/instances.json",
images_path="/path/to/images",
)
# Add annotations to images that are already indexed.
# Prediction confidence is loaded from the JSON `score` field.
dataset.add_annotations_from_coco(
annotations_json="/path/to/predictions.json",
images_root="/path/to/images",
annotation_source="predictions",
)
When images are already in the dataset, the dataset-level add_annotations_from_* helpers import
annotations into a named annotation source. This named-source workflow is currently supported for image
datasets via
add_annotations_from_coco,
add_annotations_from_yolo, and
add_annotations_from_labelformat.
All of these helpers take an annotation_source argument, which becomes the annotation source name.
Reusing the same annotation_source appends annotations to the existing annotation source. Using a new annotation_source creates a new
annotation source.
import lightly_studio as ls
dataset = ls.ImageDataset.create()
dataset.add_images_from_path(path="./path/to/images")
dataset.add_annotations_from_coco(
annotations_json="./ground_truth.json",
images_root="./path/to/images",
annotation_source="ground_truth",
)
dataset.add_annotations_from_coco(
annotations_json="./predictions_model_a.json",
images_root="./path/to/images",
annotation_source="model_a",
)
dataset.add_annotations_from_yolo(
data_yaml="./yolo_dataset/data.yaml",
annotation_source="annotator_b",
)
This is the recommended way to keep multiple annotation sources separate in the same dataset. If
your predictions are already stored in COCO format, add_annotations_from_coco(...) also supports
loading them. For prediction files, LightlyStudio looks for a score field in each COCO
annotation object and stores it as annotation confidence.
See ImageDataset and
VideoDataset for the full import workflows and supported
formats. Predictions can be added the same way as other annotations, including optional confidence
scores. If you need to create annotations directly from Python, add them to samples with
add_annotation. The
following example creates an object detection annotation:
from lightly_studio.core.annotation import CreateObjectDetection
sample.add_annotation(
CreateObjectDetection(
class_name="car",
confidence=0.9, # optional
x=10,
y=20,
width=30,
height=40,
)
)
There are also CreateClassification and CreateSegmentationMask classes for the other annotation types.
For segmentation annotations, prefer
from_binary_mask,
which automatically derives the bounding box and mask encoding from a 2D numpy array:
import numpy as np
from lightly_studio.core.annotation import CreateSegmentationMask
mask = np.array([
[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0],
])
sample.add_annotation(
CreateSegmentationMask.from_binary_mask(
class_name="car",
binary_mask=mask,
confidence=0.85, # optional
)
)
If you already have masks in RLE form, use
from_rle_mask.
RLE mask format details
For segmentation annotations
(CreateSegmentationMask), segmentation_mask
is expected to be a list of integers representing the binary mask in a row-wise
Run-Length Encoding (RLE) format.
The format follows these rules:
- The encoding is flattened row by row.
- The first number represents the count of 0s (background) at the start.
- If the mask starts with a 1 (foreground), the first number must be 0.
- Subsequent numbers represent alternating counts of 1s and 0s.
Example 2x4 mask:
[[0, 1, 1, 0],
[1, 1, 1, 1]]
Flattened row-wise, this becomes:
[0, 1, 1, 0, 1, 1, 1, 1]
The resulting segmentation_mask is:
[1, 2, 1, 4]
Accessing annotations¶
You can access annotations of each sample after creating them in the GUI, importing them from a dataset format such as COCO or YOLO, or adding them programmatically from Python.
from lightly_studio.core.annotation import ObjectDetectionAnnotation
for sample in dataset:
for annotation in sample.annotations:
if isinstance(annotation, ObjectDetectionAnnotation):
print(annotation.x, annotation.y, annotation.width, annotation.height)
There are 3 annotation types: ClassificationAnnotation, SegmentationMaskAnnotation, and ObjectDetectionAnnotation.
See Annotation for the full annotation API reference and Search and Filter for annotation-based querying. For end-to-end dataset setup examples, see Image Dataset and Video Dataset.