Skip to main content
Label Studio is a popular data labeling tool. Panlabel supports reading and writing Label Studio task export JSON for rectanglelabels (object detection).

Overview

  • Path type: JSON file (.json)
  • Lossiness: Lossy (see below)
  • Bbox format: Percentage-based [x, y, width, height] (0..100)
  • Use case: Label Studio integration, annotation workflows

Key Features

✓ Supports task export array format
✓ Rectanglelabels bbox annotations
✓ Handles annotations and predictions separately
✓ Maps score to/from IR confidence
✓ Preserves rotation metadata (flattened to axis-aligned envelope)
✓ Supports legacy completions fallback
⚠️ Rotation is flattened (angle stored as attribute ls_rotation_deg)
⚠️ Requires unique image basenames

Structure

Label Studio uses a task array format:
[
  {
    "id": 1,
    "data": {
      "image": "https://example.com/img1.jpg",
      "width": 640,
      "height": 480
    },
    "annotations": [
      {
        "result": [
          {
            "type": "rectanglelabels",
            "from_name": "label",
            "to_name": "image",
            "original_width": 640,
            "original_height": 480,
            "value": {
              "x": 10.0,
              "y": 20.0,
              "width": 30.0,
              "height": 40.0,
              "rectanglelabels": ["person"]
            },
            "rotation": 0
          }
        ]
      }
    ],
    "predictions": [
      {
        "result": [
          {
            "type": "rectanglelabels",
            "from_name": "label",
            "to_name": "image",
            "original_width": 640,
            "original_height": 480,
            "value": {
              "x": 50.0,
              "y": 60.0,
              "width": 20.0,
              "height": 25.0,
              "rectanglelabels": ["car"]
            },
            "score": 0.95
          }
        ]
      }
    ]
  }
]

Bounding Box Format

Label Studio uses percentage-based coordinates (0 to 100):
"value": {
  "x": 10.0,        // Left edge at 10% of image width
  "y": 20.0,        // Top edge at 20% of image height
  "width": 30.0,    // Box width is 30% of image width
  "height": 40.0    // Box height is 40% of image height
}
Panlabel converts to/from pixel-space XYXY.

Conversion Example

Label Studio value:
{"x": 10.0, "y": 20.0, "width": 30.0, "height": 40.0}
Image size: 640 × 480 pixels Conversion to pixel XYXY:
  1. xmin = (10.0 / 100.0) × 640 = 64.0
  2. ymin = (20.0 / 100.0) × 480 = 96.0
  3. xmax = ((10.0 + 30.0) / 100.0) × 640 = 256.0
  4. ymax = ((20.0 + 40.0) / 100.0) × 480 = 288.0
IR bbox: [64.0, 96.0, 256.0, 288.0]

Annotations vs Predictions

Label Studio distinguishes between:
  • annotations: Human-labeled ground truth (no score)
  • predictions: Model predictions (with score)
Panlabel maps this to IR confidence:
Label StudioIR confidence
annotationsNone
predictions with scoreSome(score)

Writing Behavior

When writing Label Studio JSON:
  • IR annotations with confidence == Noneannotations
  • IR annotations with confidence == Some(_)predictions + score

Image Reference Handling

Label Studio stores full image URLs/paths in data.image:
"data": {
  "image": "https://example.com/assets/train/img1.jpg"
}
Panlabel derives file_name from the basename (query/fragment stripped):
  • https://example.com/assets/train/img1.jpgimg1.jpg
  • /local/path/img2.jpgimg2.jpg
  • img3.jpg?size=largeimg3.jpg
The full reference is preserved as Image.attributes["ls_image_ref"].
Panlabel requires unique basenames across all tasks. Duplicate basenames (e.g., train/img.jpg and val/img.jpg) will cause an error.

Rotation Handling

Label Studio supports rotated rectangles via the rotation field (degrees):
{
  "value": {...},
  "rotation": 35.0
}
Panlabel flattens rotated boxes to axis-aligned envelopes (smallest XYXY box containing the rotated box). The rotation angle is stored as Annotation.attributes["ls_rotation_deg"].

Example

Input:
{"x": 10, "y": 10, "width": 20, "height": 10, "rotation": 45}
Conversion:
  1. Compute rotated corners
  2. Find axis-aligned bounding envelope
  3. Store ls_rotation_deg: "45"
IR:
{
  "bbox": [envelope_xmin, envelope_ymin, envelope_xmax, envelope_ymax],
  "attributes": {"ls_rotation_deg": "45"}
}

Reader Behavior

Supported Input

  • Empty array [] (empty dataset)
  • Task export array with:
    • annotations OR legacy completions (not both)
    • Optional predictions
    • At most one result-set per task

Validation

  • Enforces type == "rectanglelabels"
  • Requires exactly one label per result
  • Requires original_width and original_height on each result
  • Falls back to data.width/data.height if no results present
  • Requires consistent from_name/to_name within a task

Deterministic IDs

  • Image IDs: by derived basename (lexicographic)
  • Category IDs: by label name (lexicographic)
  • Annotation IDs: by image order then result order

Writer Behavior

Output Format

Writes task export JSON array:
[
  {
    "id": 1,
    "data": {...},
    "annotations": [...],
    "predictions": [...]
  },
  ...
]

Field Defaults

  • from_name: Uses Image.attributes["ls_from_name"] or defaults to "label"
  • to_name: Uses Image.attributes["ls_to_name"] or defaults to "image"
  • image: Uses Image.attributes["ls_image_ref"] or falls back to file_name

Rotation

Writes rotation from Annotation.attributes["ls_rotation_deg"] if present:
{
  "rotation": 35.0,
  "value": {...}
}

Lossiness

Label Studio format is lossy:

Preserved ✓

  • Image basenames and dimensions
  • Category names
  • Bounding boxes (percentage ↔ pixel conversion)
  • Confidence (score ↔ IR confidence)
  • Rotation angle (as attribute)
  • from_name/to_name (as attributes)

Not Preserved ✗

  • Dataset-level metadata/licenses
  • Rotation geometry (flattened to envelope)
  • Custom annotation attributes (except rotation)
  • Label Studio-specific metadata
Rotation is flattened to axis-aligned geometry. The angle is retained as ls_rotation_deg but the rotated shape is lost.

Usage

Read Label Studio

panlabel convert tasks.json output.json --input-format label-studio --output-format ir-json
Aliases: label-studio-json, ls

Write Label Studio

panlabel convert input.json output.json --input-format ir-json --output-format label-studio

Legacy Completions Support

Label Studio’s legacy completions key is supported as fallback:
{
  "completions": [{"result": [...]}]
}
Reads completions if annotations is absent. Having both is an error.

See Also

CVAT Format

Another annotation tool format

Format Overview

Compare all supported formats

Build docs developers (and LLMs) love