Everyone on the same network opens http://<host-ip>:5050 in their phone browser. Each person enters their name; images auto-assign so nobody labels the same plate twice. Click the 4 plate corners, type the plate text, save. Labels land as JSON in data/labels/.
Output: JSON files in data/labels/ — one per image. Run the checker to validate and produce a verification collage.
Improvement roadmap
From LABELER_PLAN.md — the labeler's future, in priority order:
✓ Plate text entry — after 4 corners are placed, show a text input for the plate text before saving. Corner flow → text input slides up → confirm → single save with corners + plate_text. Done.
Corner editing (drag to adjust) — after all 4 corners are placed, tap-drag individual corner dots to fine-tune. Eliminates undo-reset-retry.
Winding order validation — warn if corners aren't in proper TL→TR→BR→BL order; flag self-intersecting quadrilaterals with a ⚠️ badge.
Live rectified preview — small rectified view of the plate in the corner of the screen once 4 corners are down. "That doesn't look like WGE7330" → fix it immediately.
Review mode — browse finished labels with polygon overlays. Edit or reject bad ones. Filter by labeler.
Team presence (WebSocket) — replace 5-second polling with WebSocket for live progress and team visibility.
PWA / offline — service worker + manifest. "Add to Home Screen" → standalone app. Queue labels offline, sync on reconnect.
Multi-plate support — some images have multiple plates (front + back, two cars in frame). Allow labeling 1–N plates per image.
Production server — swap the Flask dev server for waitress or gunicorn. One-line change.