Spaces:
Sleeping
Sleeping
MathewKasbarian
feat(ai): tiled inference, machine API, and label JSON interchange in annotator
c640d68 |
Download CLAUDE.md from Infin8-AI/Annotation: direct link, hf CLI and curl.
- Browser
- Download file 3.01 kB
-
https://huggingface.co/spaces/Infin8-AI/Annotation/resolve/main/CLAUDE.md
- Command line
-
hf download hf://spaces/Infin8-AI/Annotation/CLAUDE.md
-
curl -L -o CLAUDE.md https://huggingface.co/spaces/Infin8-AI/Annotation/resolve/main/CLAUDE.md
3.01 kB
| # Annotator Tool | |
| Gradio annotation tool for facade frame detection. Deployed to HF Spaces as `Infin8-AI/Annotation`. | |
| ## Files | |
| - `app.py` β Gradio UI (3 tabs: Detect, Review & Edit, Send to Backend) + hidden machine API | |
| - `detection.py` β YOLO inference wrapper (tiled for full sheets) with OpenCV fallback | |
| - `requirements.txt` β Python deps for local dev and HF Spaces | |
| - `packages.txt` β System deps (poppler-utils) for HF Spaces | |
| - `best.pt` β YOLO11n weights (not in git β download from HF Hub or train locally) | |
| ## Detection | |
| Full drawing sheets are detected with **tiled inference** (`detect_tiled`: 640Γ640 windows, | |
| stride 480, cross-tile NMS IoU 0.5) at **200 DPI** β whole-sheet single-pass inference finds | |
| nothing because mullions shrink below detectable size. `detect_rectangles()` tiles | |
| automatically for images larger than one tile. Constants live in `detection.py` | |
| (`TILE_SIZE`, `TILE_STRIDE`, `TILE_MERGE_IOU`, `DETECTION_DPI`) and must match the | |
| training dataset builder. | |
| Model resolution order: `FACADE_MODEL_PATH` (local file) β `FACADE_MODEL_REPO` | |
| (HF Hub, e.g. `Infin8-AI/estimat8-vm-v1`, pin with `FACADE_MODEL_REVISION`, auth with | |
| `HF_TOKEN`) β `best.pt` next to `detection.py`. | |
| ## Machine API (for backends) | |
| Hidden endpoints exposed via the Gradio API, called with `gradio_client`: | |
| ```python | |
| from gradio_client import Client, handle_file | |
| client = Client("Infin8-AI/Annotation", hf_token=...) # or http://localhost:7860 | |
| result = client.predict(handle_file("page.png"), 0.25, api_name="/detect_image") | |
| # -> {"width_px", "height_px", "model_version", "boxes": [{x1,y1,x2,y2,conf}]} | |
| ``` | |
| - `/detect_image (image_file, conf)` β primary: caller renders the PDF page and uploads one PNG. | |
| - `/detect_page (pdf_file, page_number, dpi, conf)` β testing/fallback; avoid for big PDFs | |
| (gradio_client re-uploads the file every call). | |
| ## Label JSON import/export (Review & Edit tab) | |
| `β Labels` exports every annotated page as canonical per-page label JSON (coordinates in | |
| **PDF points**, provenance + rejected boxes preserved), zipped. The Import field loads such | |
| JSONs back (audited β approved, machine bootstrap β pending, rejected β rejected). This is | |
| the audit interchange format consumed by `scripts/annotation/` at the repo root. | |
| ## Deploying to HF Spaces | |
| HF Spaces builds from `hf/main`. The Space expects files at the repo root, so use git subtree: | |
| ```bash | |
| # Add remote once | |
| git remote add hf https://YOUR_HF_TOKEN@huggingface.co/spaces/Infin8-AI/Annotation | |
| # Push this subdirectory as the Space root | |
| git subtree push --prefix=tools/annotator hf main | |
| ``` | |
| ## Training loop | |
| See `scripts/build_dataset_from_events.py` and `scripts/train_facade_detector.py` at the repo root. | |
| ```bash | |
| # From repo root β after exporting events.jsonl from the Gradio tool | |
| python scripts/build_dataset_from_events.py --events events.jsonl --pdf source.pdf | |
| python scripts/train_facade_detector.py --version v2 | |
| cp models/yolo_facade_v2/best.pt tools/annotator/best.pt | |
| ``` | |