strickvl/panlabel

Universal annotation converter

17

stars

177

commits

Rust

primary language

Aug 16, 2026

updated

annotation
annotation-conversion
converter
data-annotation
data-labeling

README

Panlabel

CI Crates.io Version PyPI Version GitHub License GitHub Repo stars Crates.io Total Downloads PyPI Downloads

The universal annotation converter

If you've ever written a one-off Python script to wrangle COCO annotations into YOLO format (or vice versa), panlabel is here to save you the trouble. It's a fast, single-binary CLI that converts between common object detection annotation formats — with built-in validation, clear lossiness warnings, and no Python dependencies to manage.

Panlabel’s current core scope is mainstream/static-image 2D axis-aligned object-detection bbox conversion. It does not provide first-class segmentation, keypoints/pose, oriented boxes, video tracking IDs, or 3D/multisensor labels. When broad schemas include richer structures, panlabel either skips/reports those structures or treats the conversion as lossy.

Panlabel is also available as a Rust library if you want to integrate format conversion into your own tools.

Note: Panlabel is in active development (v0.5.x). The CLI and library APIs may change between versions, so pin to a specific version if you're using it in production.

Installation

pip / uv (any platform)

pip install panlabel
# or
uv pip install panlabel

This installs a pre-built binary — no Rust toolchain needed.

Homebrew (macOS / Linux)

brew install strickvl/tap/panlabel

Shell script (macOS / Linux)

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/strickvl/panlabel/releases/latest/download/panlabel-installer.sh | sh

PowerShell (Windows)

powershell -ExecutionPolicy Bypass -c "irm https://github.com/strickvl/panlabel/releases/latest/download/panlabel-installer.ps1 | iex"

Cargo (from source)

cargo install panlabel
# Enable full HF support (remote Hub import + metadata.parquet)
cargo install panlabel --features hf

Pre-built binaries

Download from the latest GitHub Release. Builds are available for macOS (Intel + Apple Silicon), Linux (x86_64 + ARM64), and Windows.

Docker

docker pull strickvl/panlabel
# Convert a COCO file in your current directory to YOLO
docker run --rm -v "$PWD":/data strickvl/panlabel convert -f coco -t yolo -i /data/annotations.json -o /data/yolo_out --allow-lossy

Multi-arch images (amd64 + arm64) are published for each release.

As a Rust library

cargo add panlabel

Quick start

# Convert between formats (auto-detects the input)
panlabel convert --from auto --to yolo -i annotations.json -o ./yolo_out --allow-lossy

# Check a dataset for problems before training
panlabel validate --format coco annotations.json

# Get a quick overview of what's in a dataset
panlabel stats --format coco annotations.json

# Compare two datasets semantically
panlabel diff --format-a auto --format-b auto old.json new.json

# Sample a smaller subset for quick experiments
panlabel sample -i annotations.json -o sample.ir.json --from auto --to ir-json -n 100 --seed 42

# See every supported format and its capabilities
panlabel list-formats

The convert shape is always -f <source> -t <dest> -i <input> -o <output> — pick any source/destination from the Supported formats table. See More convert examples below for lossless vs. lossy conversions, machine-readable JSON reports, dry runs, and remote Hugging Face datasets.

What can panlabel do?

CommandWhat it does
convertConvert between annotation formats, with clear warnings about what (if anything) gets lost
validateCheck your dataset for common problems — duplicate IDs, missing references, invalid bounding boxes
statsShow rich dataset statistics in text, JSON, or HTML
diffCompare two datasets semantically (summary or detailed output)
sampleCreate subset datasets (random or stratified), with optional category filtering and JSON reports
list-formatsShow which formats are supported and their read/write/lossiness capabilities, including JSON discovery output

Supported formats

FormatExtension / LayoutDescriptionLossiness
ir-json.jsonPanlabel's own intermediate representationLossless
coco.jsonCOCO object detection formatConditional
ibm-cloud-annotations_annotations.json file or directoryIBM Cloud Annotations localization JSONLossy
cvat.xml / annotations.xml exportCVAT for images XML annotation exportLossy
label-studio.jsonLabel Studio task export JSON (rectanglelabels)Lossy
labelbox.json / .jsonl / .ndjsonLabelbox current export rows (data_row / projects.*.labels)Lossy
scale-ai.json file or directory (annotations/)Scale AI image annotation task/response JSONLossy
unity-perception.json file or SOLO-like directoryUnity Perception / SOLO synthetic-data bbox JSONLossy
tfod.csvTensorFlow Object Detection CSV (normalized bbox corners)Lossy
tfrecord.tfrecordTensorFlow Object Detection API-style tf.train.Example records (single-file, uncompressed, bbox-only in v1)Lossy
vott-csv.csvMicrosoft VoTT CSV export (image,xmin,ymin,xmax,ymax,label)Lossy
vott-json.json file or vott-json-export/ directoryMicrosoft VoTT JSON export (assets / per-asset JSON with regions)Lossy
yoloimages/ + labels/ directory, or split data.yaml pointing to image-list .txt filesYOLO .txt labels (flat, split-aware, Scaled-YOLOv4 aliases, optional confidence)Lossy
yolo-keras.txt file or directory (yolo_keras.txt, annotations.txt, train.txt)YOLO Keras absolute-coordinate TXT (image xmin,ymin,xmax,ymax,class_id ...)Lossy
yolov4-pytorch.txt file or directory (yolov4_pytorch.txt, train_annotation.txt, train.txt)YOLOv4 PyTorch absolute-coordinate TXT (image xmin,ymin,xmax,ymax,class_id ...)Lossy
vocAnnotations/ + JPEGImages/ directoryPascal VOC XMLLossy
hfmetadata.jsonl / metadata.parquet directoryHugging Face ImageFolder metadataLossy
sagemaker.manifest / .jsonl fileAWS SageMaker Ground Truth object-detection manifestLossy
labelme.json file or annotations/ directoryLabelMe per-image JSON annotationsLossy
create-ml.jsonApple CreateML annotation formatLossy
kittilabel_2/ + image_2/ directoryKITTI object detection labelsLossy
via.jsonVGG Image Annotator (VIA) JSONLossy
retinanet.csvkeras-retinanet CSV formatLossy
openimages.csvGoogle OpenImages CSV annotation formatLossy
kaggle-wheat.csvKaggle Global Wheat Detection CSVLossy
automl-vision.csvGoogle Cloud AutoML Vision CSVLossy
udacity.csvUdacity Self-Driving Car Dataset CSVLossy
superannotate.json file or annotations/ directorySuperAnnotate JSON exportLossy
supervisely.json file or ann/ / meta.json project directorySupervisely JSON project / datasetLossy
cityscapes.json, gtFine/, or dataset root with gtFine/Cityscapes polygon JSON; polygons become bbox envelopesLossy
marmot.xml file or directory with same-stem companion imagesMarmot XML document-layout composites; hex doubles become pixel bboxesLossy
datumaro.jsonDatumaro JSON annotation formatLossy
wider-face.txtWIDER Face aggregate TXT (single face class in panlabel)Lossy
oidv4directory with Label/ or .txtOIDv4 Toolkit TXT labels (directory probe uses Label/, not YOLO labels/)Lossy
bdd100k.jsonBDD100K / Scalabel JSON detection subsetLossy
v7-darwin.jsonV7 Darwin JSON bbox subsetLossy
edge-impulsebounding_boxes.labels file or containing directoryEdge Impulse bounding-box labels JSONLossy
openlabel.jsonASAM OpenLABEL JSON static-image 2D bbox subsetLossy
via-csv.csvVGG Image Annotator CSV (separate format from VIA JSON)Lossy

Run panlabel list-formats for the full details, or panlabel list-formats --output json for machine-readable format discovery.

TFRecord support in v1 is intentionally narrow: panlabel currently supports only single-file, uncompressed TensorFlow Object Detection API-style tf.train.Example bbox records (not arbitrary TFRecord payloads).

list-formats shows canonical names (for example label-studio), while commands also accept aliases (for example ls, label-studio-json). Across commands, --output-format is the consistent way to request JSON reports; convert and sample also keep --report as an alias. JSON is pretty-printed on a terminal and compact when piped or captured, which makes it friendlier for scripts and agents. stats also adapts its text renderer: rich/Unicode on a terminal, plain text layout when piped.

More convert examples

# COCO to IR JSON (lossless — no data lost)
panlabel convert -f coco -t ir-json -i input.json -o output.json

# IR JSON to TFOD (lossy — requires explicit opt-in)
panlabel convert -f ir-json -t tfod -i input.json -o output.csv --allow-lossy

# Auto-detect input format from file extension/content or directory layout
panlabel convert --from auto -t coco -i input.csv -o output.json

# Request a machine-readable conversion report
panlabel convert --from auto -t coco -i input.csv -o output.json --output-format json

# Preview a conversion without touching the output path
panlabel convert --from auto -t coco -i input.csv -o output.json --dry-run

# Convert a remote Hugging Face dataset repo to COCO JSON
# (requires --features hf when building from source)
panlabel convert -f hf -t coco --hf-repo rishitdagli/cppe-5 --split train -o coco_output.json

# Convert a zip-style HF dataset repo split to IR JSON (auto-detects extracted payload)
panlabel convert -f hf -t ir-json --hf-repo keremberke/football-object-detection --split train -o football.ir.json

Dry runs still do the real thinking work — format detection, validation, sampling/conversion analysis, and lossiness checks — but they skip the final filesystem write. That means they are good for “what would happen?” checks, but they do not prove that the output path is writable.

Getting help

panlabel --help              # See all commands
panlabel convert --help      # Help for a specific command
panlabel -V                  # Show version

Documentation

Want to go deeper? The full docs are readable right here on GitHub:

Contributing

Contributions are welcome! Whether it's a bug report, a new format adapter, or a documentation fix — we appreciate the help. For major changes, please open an issue first so we can discuss the approach.

See the contributing guide for details on the codebase structure and how to make changes.

License

MIT — see LICENSE for details.

Contributors

strickvl

161 commits

dependabot[bot]

16 commits

strickvl/panlabel

Universal annotation converter

17

stars

177

commits

Rust

primary language

Aug 16, 2026

updated

annotation
annotation-conversion
converter
data-annotation
data-labeling

README

Panlabel

CI Crates.io Version PyPI Version GitHub License GitHub Repo stars Crates.io Total Downloads PyPI Downloads

The universal annotation converter

If you've ever written a one-off Python script to wrangle COCO annotations into YOLO format (or vice versa), panlabel is here to save you the trouble. It's a fast, single-binary CLI that converts between common object detection annotation formats — with built-in validation, clear lossiness warnings, and no Python dependencies to manage.

Panlabel’s current core scope is mainstream/static-image 2D axis-aligned object-detection bbox conversion. It does not provide first-class segmentation, keypoints/pose, oriented boxes, video tracking IDs, or 3D/multisensor labels. When broad schemas include richer structures, panlabel either skips/reports those structures or treats the conversion as lossy.

Panlabel is also available as a Rust library if you want to integrate format conversion into your own tools.

Note: Panlabel is in active development (v0.5.x). The CLI and library APIs may change between versions, so pin to a specific version if you're using it in production.

Installation

pip / uv (any platform)

pip install panlabel
# or
uv pip install panlabel

This installs a pre-built binary — no Rust toolchain needed.

Homebrew (macOS / Linux)

brew install strickvl/tap/panlabel

Shell script (macOS / Linux)

curl --proto '=https' --tlsv1.2 -LsSf https://github.com/strickvl/panlabel/releases/latest/download/panlabel-installer.sh | sh

PowerShell (Windows)

powershell -ExecutionPolicy Bypass -c "irm https://github.com/strickvl/panlabel/releases/latest/download/panlabel-installer.ps1 | iex"

Cargo (from source)

cargo install panlabel
# Enable full HF support (remote Hub import + metadata.parquet)
cargo install panlabel --features hf

Pre-built binaries

Download from the latest GitHub Release. Builds are available for macOS (Intel + Apple Silicon), Linux (x86_64 + ARM64), and Windows.

Docker

docker pull strickvl/panlabel
# Convert a COCO file in your current directory to YOLO
docker run --rm -v "$PWD":/data strickvl/panlabel convert -f coco -t yolo -i /data/annotations.json -o /data/yolo_out --allow-lossy

Multi-arch images (amd64 + arm64) are published for each release.

As a Rust library

cargo add panlabel

Quick start

# Convert between formats (auto-detects the input)
panlabel convert --from auto --to yolo -i annotations.json -o ./yolo_out --allow-lossy

# Check a dataset for problems before training
panlabel validate --format coco annotations.json

# Get a quick overview of what's in a dataset
panlabel stats --format coco annotations.json

# Compare two datasets semantically
panlabel diff --format-a auto --format-b auto old.json new.json

# Sample a smaller subset for quick experiments
panlabel sample -i annotations.json -o sample.ir.json --from auto --to ir-json -n 100 --seed 42

# See every supported format and its capabilities
panlabel list-formats

The convert shape is always -f <source> -t <dest> -i <input> -o <output> — pick any source/destination from the Supported formats table. See More convert examples below for lossless vs. lossy conversions, machine-readable JSON reports, dry runs, and remote Hugging Face datasets.

What can panlabel do?

CommandWhat it does
convertConvert between annotation formats, with clear warnings about what (if anything) gets lost
validateCheck your dataset for common problems — duplicate IDs, missing references, invalid bounding boxes
statsShow rich dataset statistics in text, JSON, or HTML
diffCompare two datasets semantically (summary or detailed output)
sampleCreate subset datasets (random or stratified), with optional category filtering and JSON reports
list-formatsShow which formats are supported and their read/write/lossiness capabilities, including JSON discovery output

Supported formats

FormatExtension / LayoutDescriptionLossiness
ir-json.jsonPanlabel's own intermediate representationLossless
coco.jsonCOCO object detection formatConditional
ibm-cloud-annotations_annotations.json file or directoryIBM Cloud Annotations localization JSONLossy
cvat.xml / annotations.xml exportCVAT for images XML annotation exportLossy
label-studio.jsonLabel Studio task export JSON (rectanglelabels)Lossy
labelbox.json / .jsonl / .ndjsonLabelbox current export rows (data_row / projects.*.labels)Lossy
scale-ai.json file or directory (annotations/)Scale AI image annotation task/response JSONLossy
unity-perception.json file or SOLO-like directoryUnity Perception / SOLO synthetic-data bbox JSONLossy
tfod.csvTensorFlow Object Detection CSV (normalized bbox corners)Lossy
tfrecord.tfrecordTensorFlow Object Detection API-style tf.train.Example records (single-file, uncompressed, bbox-only in v1)Lossy
vott-csv.csvMicrosoft VoTT CSV export (image,xmin,ymin,xmax,ymax,label)Lossy
vott-json.json file or vott-json-export/ directoryMicrosoft VoTT JSON export (assets / per-asset JSON with regions)Lossy
yoloimages/ + labels/ directory, or split data.yaml pointing to image-list .txt filesYOLO .txt labels (flat, split-aware, Scaled-YOLOv4 aliases, optional confidence)Lossy
yolo-keras.txt file or directory (yolo_keras.txt, annotations.txt, train.txt)YOLO Keras absolute-coordinate TXT (image xmin,ymin,xmax,ymax,class_id ...)Lossy
yolov4-pytorch.txt file or directory (yolov4_pytorch.txt, train_annotation.txt, train.txt)YOLOv4 PyTorch absolute-coordinate TXT (image xmin,ymin,xmax,ymax,class_id ...)Lossy
vocAnnotations/ + JPEGImages/ directoryPascal VOC XMLLossy
hfmetadata.jsonl / metadata.parquet directoryHugging Face ImageFolder metadataLossy
sagemaker.manifest / .jsonl fileAWS SageMaker Ground Truth object-detection manifestLossy
labelme.json file or annotations/ directoryLabelMe per-image JSON annotationsLossy
create-ml.jsonApple CreateML annotation formatLossy
kittilabel_2/ + image_2/ directoryKITTI object detection labelsLossy
via.jsonVGG Image Annotator (VIA) JSONLossy
retinanet.csvkeras-retinanet CSV formatLossy
openimages.csvGoogle OpenImages CSV annotation formatLossy
kaggle-wheat.csvKaggle Global Wheat Detection CSVLossy
automl-vision.csvGoogle Cloud AutoML Vision CSVLossy
udacity.csvUdacity Self-Driving Car Dataset CSVLossy
superannotate.json file or annotations/ directorySuperAnnotate JSON exportLossy
supervisely.json file or ann/ / meta.json project directorySupervisely JSON project / datasetLossy
cityscapes.json, gtFine/, or dataset root with gtFine/Cityscapes polygon JSON; polygons become bbox envelopesLossy
marmot.xml file or directory with same-stem companion imagesMarmot XML document-layout composites; hex doubles become pixel bboxesLossy
datumaro.jsonDatumaro JSON annotation formatLossy
wider-face.txtWIDER Face aggregate TXT (single face class in panlabel)Lossy
oidv4directory with Label/ or .txtOIDv4 Toolkit TXT labels (directory probe uses Label/, not YOLO labels/)Lossy
bdd100k.jsonBDD100K / Scalabel JSON detection subsetLossy
v7-darwin.jsonV7 Darwin JSON bbox subsetLossy
edge-impulsebounding_boxes.labels file or containing directoryEdge Impulse bounding-box labels JSONLossy
openlabel.jsonASAM OpenLABEL JSON static-image 2D bbox subsetLossy
via-csv.csvVGG Image Annotator CSV (separate format from VIA JSON)Lossy

Run panlabel list-formats for the full details, or panlabel list-formats --output json for machine-readable format discovery.

TFRecord support in v1 is intentionally narrow: panlabel currently supports only single-file, uncompressed TensorFlow Object Detection API-style tf.train.Example bbox records (not arbitrary TFRecord payloads).

list-formats shows canonical names (for example label-studio), while commands also accept aliases (for example ls, label-studio-json). Across commands, --output-format is the consistent way to request JSON reports; convert and sample also keep --report as an alias. JSON is pretty-printed on a terminal and compact when piped or captured, which makes it friendlier for scripts and agents. stats also adapts its text renderer: rich/Unicode on a terminal, plain text layout when piped.

More convert examples

# COCO to IR JSON (lossless — no data lost)
panlabel convert -f coco -t ir-json -i input.json -o output.json

# IR JSON to TFOD (lossy — requires explicit opt-in)
panlabel convert -f ir-json -t tfod -i input.json -o output.csv --allow-lossy

# Auto-detect input format from file extension/content or directory layout
panlabel convert --from auto -t coco -i input.csv -o output.json

# Request a machine-readable conversion report
panlabel convert --from auto -t coco -i input.csv -o output.json --output-format json

# Preview a conversion without touching the output path
panlabel convert --from auto -t coco -i input.csv -o output.json --dry-run

# Convert a remote Hugging Face dataset repo to COCO JSON
# (requires --features hf when building from source)
panlabel convert -f hf -t coco --hf-repo rishitdagli/cppe-5 --split train -o coco_output.json

# Convert a zip-style HF dataset repo split to IR JSON (auto-detects extracted payload)
panlabel convert -f hf -t ir-json --hf-repo keremberke/football-object-detection --split train -o football.ir.json

Dry runs still do the real thinking work — format detection, validation, sampling/conversion analysis, and lossiness checks — but they skip the final filesystem write. That means they are good for “what would happen?” checks, but they do not prove that the output path is writable.

Getting help

panlabel --help              # See all commands
panlabel convert --help      # Help for a specific command
panlabel -V                  # Show version

Documentation

Want to go deeper? The full docs are readable right here on GitHub:

Contributing

Contributions are welcome! Whether it's a bug report, a new format adapter, or a documentation fix — we appreciate the help. For major changes, please open an issue first so we can discuss the approach.

See the contributing guide for details on the codebase structure and how to make changes.

License

MIT — see LICENSE for details.

Contributors

strickvl

161 commits

dependabot[bot]

16 commits

Languages

Rust

99.4%