Spaces:
Sleeping
Sleeping
File size: 3,012 Bytes
470f937 c640d68 470f937 c640d68 470f937 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # 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
```
|