Skip to content

Phazertron/Annotator

Repository files navigation

Annotator

A fast, keyboard-driven desktop tool for building image annotation datasets. Define your labelling schema in a JSON file, point the tool at a folder of images, and start annotating — bounding boxes, points, hierarchical parent-child relationships, per-annotation flags, and tags all supported out of the box.

Annotations are stored in lightweight JSON sidecar files next to your images, so your dataset folder stays self-contained and version-control friendly. Export to COCO JSON or YOLO TXT whenever you are ready to train.


Key Features

Capability Description
Schema-driven labelling Define annotation types, colors, icons, flags, and tags in a plain JSON file — no code required
Multiple schemas Load several schemas at once and annotate the same image folder with different label sets simultaneously
Bounding boxes & points Draw rectangles or place keypoints; parent annotations unlock child annotations automatically
Hierarchical annotations Child types attach to a selected parent, enabling fine-grained part-level labelling
Per-annotation flags & tags Boolean flags and dropdown tags on individual annotations for quality, occlusion, or custom attributes
Image flags Schema-level per-image metadata (e.g. blur, lighting, quality ratings)
Mark Empty One-click or keyboard shortcut to mark images that contain no valid targets
ML Export Export annotated data to COCO JSON or YOLO TXT format for immediate model training
Batch operations Mark untagged images as no-target or delete all annotations of a type across the entire dataset
Statistical dashboard Per-schema progress, annotation geometry analytics, spatial heatmaps, and class-balance metrics
Backup & recovery Periodic automatic backups with crash-recovery dialog on next launch
Schema editor Create and edit schemas from inside the app — no need to hand-edit JSON
Dark mode System-aware dark/light theme toggle

Repository Structure

annotator/
├── annotator/
│   ├── canvas/
│   │   ├── graphics_scene.py      # AnnotationGraphicsScene — image + annotation items
│   │   └── graphics_view.py       # AnnotationGraphicsView — zoom, pan, rotation
│   ├── commands/
│   │   └── annotation_commands.py # Undo/redo command objects
│   ├── io/
│   │   ├── backup.py              # BackupManager — crash-recovery sidecar backups
│   │   ├── export.py              # COCO JSON and YOLO TXT exporters
│   │   ├── migration.py           # Sidecar format migration helpers
│   │   └── sidecar.py             # Read/write per-image annotation JSON files
│   ├── models/
│   │   ├── annotation.py          # ImageAnnotations, AnnotationRecord data classes
│   │   ├── image_list.py          # DatasetModel — image list with multi-schema state
│   │   └── schema.py              # SchemaConfig, AnnotationTypeDef loaders
│   ├── panels/
│   │   ├── annotation_tree.py     # Right dock — annotation list and selection
│   │   ├── image_browser.py       # Left dock — image list with progress indicators
│   │   ├── schema_editor.py       # Schema creation/editing dialog
│   │   ├── schema_panel.py        # Left dock — per-schema tool buttons
│   │   ├── statistics_panel.py    # Statistics tab — pyqtgraph charts and metrics
│   │   └── tool_options.py        # Right dock — flags, tags, shortcuts reference
│   ├── tools/
│   │   ├── base_tool.py           # BaseTool interface
│   │   ├── box_tool.py            # Bounding box draw tool
│   │   ├── point_tool.py          # Point/keypoint place tool
│   │   └── select_tool.py         # Selection, move, resize, nudge tool
│   ├── app.py                     # QApplication entry point
│   ├── main_window.py             # MainWindow — toolbar, menus, dock wiring
│   └── theme.py                   # Dark/light palette helpers
│
├── icons/
│   ├── app_icon.png               # Application window icon
│   └── system/                    # Toolbar and UI icons (see ATTRIBUTION.md)
│
├── schemas/                       # Example schemas (not tracked in production)
│
├── main.py                        # CLI entry point
├── run.ps1                        # PowerShell launcher (Windows)
├── Makefile                       # Common dev tasks
├── Dockerfile                     # Container build
├── docker-compose.yml             # Container run configuration
├── requirements.txt               # pip dependencies
└── ATTRIBUTION.md                 # Icon credits

Application Overview

flowchart TD
    classDef ui fill:#1f77b4,stroke:#0d3a63,stroke-width:1px,color:white
    classDef model fill:#2ca02c,stroke:#145214,stroke-width:1px,color:white
    classDef io fill:#ff7f0e,stroke:#a64b00,stroke-width:1px,color:white
    classDef tool fill:#9467bd,stroke:#4b2e7f,stroke-width:1px,color:white

    subgraph UI["UI Layer"]
        MW[MainWindow]:::ui
        IB[ImageBrowser]:::ui
        SP[SchemaPanel]:::ui
        AT[AnnotationTree]:::ui
        TO[ToolOptions<br/>Flags · Tags]:::ui
        STAT[StatisticsPanel]:::ui
    end

    subgraph Canvas["Canvas"]
        GV[GraphicsView<br/>Zoom · Pan · Rotate]:::ui
        GS[GraphicsScene<br/>Image + Annotation Items]:::ui
    end

    subgraph Tools["Tools"]
        SEL[SelectTool]:::tool
        BOX[BoxTool]:::tool
        PT[PointTool]:::tool
    end

    subgraph Models["Models"]
        DM[DatasetModel<br/>Image list · Schema state]:::model
        SC[SchemaConfig<br/>Types · Flags · Tags]:::model
        IA[ImageAnnotations<br/>Records · Undo stack]:::model
    end

    subgraph IO["I/O"]
        SIDE[Sidecar JSON<br/>per-image files]:::io
        BK[BackupManager]:::io
        EXP[Exporter<br/>COCO · YOLO]:::io
    end

    MW --> IB & SP & AT & TO & STAT
    MW --> GV --> GS
    MW --> SEL & BOX & PT
    MW --> DM --> SC & IA
    IA <--> SIDE
    IA --> BK
    DM --> EXP
Loading

Screenshots

Screenshots below use the Plastic Bottles Dataset — a publicly available collection of plastic bottle images, used here solely for illustration purposes.

Main annotation view — bounding box tool

Main annotation view

Multi-schema workflow

Multi-schema panel

Statistics dashboard

Statistics tab

Dark theme

Schema editor


Getting Started

Prerequisites

  • Python 3.10+
  • One of: pip + venv, Docker, or PowerShell (Windows)

Installation

pip (recommended)

python -m venv .venv

# Linux / macOS
source .venv/bin/activate

# Windows (PowerShell)
.\.venv\Scripts\Activate.ps1

pip install -r requirements.txt

Make (Linux / macOS / WSL2)

make setup    # Creates .venv and installs dependencies
make run      # Launches the application

PowerShell (Windows)

.\run.ps1

The script auto-discovers all *.json files in the schemas/ folder and launches the annotator with them.

Docker

docker compose up

Note: The Docker container requires an X11 display. On Windows use VcXsrv or WSLg; on macOS use XQuartz.


Usage

1 — Prepare your schema

Create a JSON file in the schemas/ directory. The schema defines your annotation types, their visual appearance, and optional flags/tags. You can also use the built-in Schema Editor (toolbar button) to create and edit schemas from inside the app.

Minimal schema example:

{
  "schema_name": "MyDataset",
  "annotation_types": [
    {
      "id": "object",
      "label": "Object",
      "type": "box",
      "color": "#e74c3c"
    },
    {
      "id": "keypoint",
      "label": "Keypoint",
      "type": "point",
      "color": "#3498db",
      "parent": "object"
    }
  ],
  "image_flags": [
    { "id": "blurry", "label": "Blurry", "default": false }
  ]
}

2 — Open your dataset

Launch the app and click Open Dataset (toolbar) or pass the folder path as a command-line argument:

python main.py /path/to/images --schemas schemas/my_schema.json

Multiple schemas can be passed simultaneously:

python main.py /path/to/images --schemas schemas/schema_a.json schemas/schema_b.json

3 — Annotate

Action How
Draw bounding box Select box tool → click and drag
Place keypoint Select point tool → click
Select / move / resize V key or Select tool → click annotation
Nudge selected Arrow keys (+ Shift for ×10)
Delete selected Del
Zoom Mouse wheel
Pan Middle-click drag or Ctrl+Left-click drag
Fit to view F
Rotate view Ctrl+R (right) / Ctrl+Shift+R (left)
Switch tool by index 19
Cycle schema Tab
Mark image empty Space or E button
Next untagged image N
Navigate images Ctrl+← / Ctrl+→
Undo / Redo Ctrl+Z / Ctrl+Y
Save Ctrl+S

4 — Export

Go to File > Export to export annotations in ML-ready formats:

  • COCO JSON — standard COCO instance annotation format (bounding boxes → bbox, points → keypoints)
  • YOLO TXT — one .txt per image with normalized class x_center y_center width height values, plus a classes.txt mapping file

Annotation Format

Each image produces a sidecar file named {image_stem}.{schema_name}.json alongside the image:

{
  "schema": "MyDataset",
  "image": "photo_001.jpg",
  "image_flags": { "blurry": false },
  "no_target": false,
  "annotations": [
    {
      "uid": "a1b2c3d4",
      "type_id": "object",
      "box": [120, 45, 380, 210],
      "flags": { "occluded": false },
      "tags": { "condition": "good" },
      "children": [
        {
          "uid": "e5f6g7h8",
          "type_id": "keypoint",
          "point": [250, 130],
          "flags": {},
          "tags": {}
        }
      ]
    }
  ]
}

Fields:

  • box[x1, y1, x2, y2] in original image pixel coordinates
  • point[x, y] in original image pixel coordinates
  • Image rotation is display-only and stored in image_flags["_rotation"] — export coordinates are always in original image space

Statistics Dashboard

Switch to the Statistics tab to get a live view of your annotation progress:

Panel Metrics
Overview Annotated / total images per schema, annotation counts per type
Box Geometry Area distribution, size category breakdown, aspect ratio histogram
Spatial Distribution 10×10 center-of-mass heatmap, edge-touching rate, inter-annotation overlap
Quality Metrics Shannon diversity, evenness, Gini coefficient, imbalance ratio, class balance chart

Configuration

The annotator is fully schema-driven — there is no global config file. All behaviour is controlled per-schema in the JSON files. Schema fields:

Field Type Description
schema_name string Display name (also used as sidecar file suffix)
annotation_types list List of type definitions (see below)
image_flags list Per-image boolean flags

Annotation type fields:

Field Type Description
id string Unique identifier
label string Display label
type "box" | "point" Geometry type
color string Hex color (e.g. "#e74c3c")
icon string Optional relative path to a PNG icon
parent string Optional parent type id (makes this a child annotation)
annotation_flags list Per-annotation boolean flags
tag_groups list Per-annotation dropdown tag groups

Future Features

Internal Wiki

A built-in annotation guide wiki that teams can write directly inside the app. Each schema would carry an optional wiki document with labelling guidelines, example images for edge cases, and decision trees for ambiguous objects. Annotators could open the wiki panel without leaving the application, reducing context switching and improving inter-annotator agreement.

Polygon / Segmentation Masks

Support for pixel-accurate segmentation masks alongside bounding boxes. Rather than fitting a rectangle around an object, the annotator would allow tracing a freehand polygon (or a SAM-assisted auto-mask) that tightly follows object boundaries. This produces richer training data — particularly useful for instance segmentation models (Mask R-CNN, YOLO-seg) where the exact object silhouette matters. Planned output formats: COCO RLE masks and binary PNG mask files.


License

This project is licensed under the MIT License. See LICENSE for details.

Attribution

Icons used in the toolbar and UI are sourced from Flaticon. See ATTRIBUTION.md for full credits.

Author

Claudio Bendini (2026)

About

Schema-driven image annotation suite supporting complex labeling workflows. Customise colors, icons, and metadata flags via JSON. Built for rapid dataset creation with multi-schema support, undo/redo commands, and automated sidecar backups.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages