Files
Shape_Model_2D/ROADMAP.md
T

128 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Roadmap - Possibili Sviluppi
Lista ragionata di miglioramenti futuri. Priorità = impatto / effort, non urgenza temporale.
## Fase 2 COMPLETATA (precisione rotazione + robustezza + perf)
Root cause della rotazione imprecisa: lo score satura a 1.0 sulla spread
bitmap dilatata (raggio 4-5) → il refine non vedeva gradiente né in angolo
né in posizione, e `cv2.minMaxLoc` sul plateau saturo spostava il centro
sull'angolo della finestra (errore sistematico 3·√2 ≈ 4.24 px).
| Fix | Dettaglio |
|---|---|
| Refine su bitmap fine | `_refine_angle` ottimizza su spread raggio 1 (`spread_fine`, cached); score finale ricalcolato su spread coarse per mantenere semantica soglie |
| Picco sub-pixel nel refine | centroide plateau / fit quadratico al posto di minMaxLoc (bias top-left) |
| LM least-squares pos+angolo | `_subpixel_refine_lm` riscritto: snap edge ±2px lungo normale + LSQ 3x3 (dx, dy, dθ), ON di default |
| Round feature offsets | troncamento `astype(int32)``np.round` (bias ~0.25 px) |
| Centro rotazione coerente | `_prepare_padded_template`: rotazione attorno al centro reale del template nel padding (bias ≤0.5 px dipendente dall'angolo) |
| `_angle_list` include estremo | range parziali ±tol ora testano anche +tol |
| `_refine_pose_joint` rimosso | Nelder-Mead su funzione a gradini satura: terminava subito; param ora alias di refine_angle |
| pyramid_propagate di default | kernel windowed (feature campionano l'intera scena: prima il crop troncava le feature → score 0); picchi = massimi locali (non top-K pixel); disattivato automaticamente per template elongati (>2:1) dove il picco top-level non localizza |
| Piramide 3 livelli default | con clamp automatico sulla dimensione template (min 12 px al top) |
| Cache scena: hash completo | prima hashava solo i primi 64KB → collisioni tra scene con stessa banda superiore → risultati della scena sbagliata |
| Web server | lock matcher (race con threadpool FastAPI), LRU `_IMG_CACHE`, clamp ROI ovunque (400/422 invece di 500), `filtro_fp=off` disabilita davvero NCC, `_draw_matches` su crop locale |
| GUI/legacy | centro overlay `(W-1)/2``W/2`, spread_radius default 5→4, EdgeShapeMatcher: angle list endpoint + cap candidati + save template_gray |
Misure (GT sintetica 7 pose, scena 900x700, VPS 2 core):
- Errore angolare mediano: **2.3° → 0.05°** (step 5°); a step 2° era 4.4° → **0.03°**
- Errore posizione mediano: **4.24 px → 0.04 px**
- find GT scene: 4.7s → 1.7s; scena reale 646x482: 1.14s → 0.81s
- Benchmark suite 16 scenari: 96.5s → 84.2s, match count ≥ baseline
(eccezioni: dado_full -1 = match borderline su parte diversa;
lama_part_preciso 25→18 con baseline al cap max_matches)
## Fase 1 COMPLETATA (branch `speedFase1`)
| ID | Voce | Status | Note |
|---|---|---|---|
| V1 | Coarse-to-fine angolare (step coarse al top-level) | ✅ | `coarse_angle_factor=2` default, safe anche su template allungati |
| V11 | Cache matcher in-memory LRU (capacità 8) | ✅ | Key = hash(ROI bytes + params). Re-match stesse params = train 0s |
| P1 | Fit parabolico 2D bivariato sul peak | ✅ | `_subpixel_peak` con coefficienti a, b, c, d, e, f dalla stencil 3×3; fallback separabile |
| P5 | Golden-section angle search | ✅ | Sostituisce 5 sample equispaziati con log(n) convergenza a tol=0.1° |
| P2 | Weighted centroid del plateau | ✅ | Integrato in `_subpixel_peak` con peso = (score - soglia)² |
Benchmark suite 16 scenari (4 immagini × full/part × fast/preciso):
- Prima Fase 1: totale find 27.3s
- Dopo Fase 1: totale find 25.1s (~8% speedup)
- Regressione match count: nessuna (alcuni casi +1 match grazie a subpixel migliore)
- Match auto-referenziale: offset 0.00 px, angolo 0.000° (era -3.5 px, -2.5°)
## Performance CPU
| Sviluppo | Effort | Speed-up atteso | Dipendenze | Priorità |
|---|---|---|---|---|
| Numba JIT su `_score_by_shift` | basso | 3-5× | numba (~200MB) | alta |
| Numba JIT su `_response_map` | basso | 2-3× | numba | alta |
| FFT-based score per varianti dense | medio | 2× su template grandi | scipy | media |
| Rewrite `_score_by_shift` in Cython | alto | 5-8× | cython build | bassa |
| SIMD via `pypy` runtime | medio | 2-4× | pypy interpreter | bassa (dipendenza runtime) |
| Memory layout: struct-of-arrays compatto int8 | medio | 1.5× (cache) | - | media |
## Performance GPU
| Sviluppo | Effort | Speed-up atteso | Dipendenze | Priorità |
|---|---|---|---|---|
| Backend CuPy per `_score_by_shift` + `_response_map` | medio | 5-10× | cupy-cuda12x (~600MB) | alta |
| Kernel CUDA custom (Numba CUDA o RawKernel) | medio-alto | 10-20× | numba-cuda / cupy | media |
| PyTorch backend (conv2d per feature dense) | basso-medio | 3-8× | torch (~2GB) | bassa |
| OpenCV CUDA (build custom) | altissimo | 5× | build da sorgenti | bassa |
| Multi-GPU matching (scene partitioning) | alto | N× | - | bassa |
## Algoritmiche
| Sviluppo | Effort | Beneficio | Priorità |
|---|---|---|---|
| Coarse-to-fine angolare (top-level step grosso, full step fine) | medio | 3-5× velocità con stesso precisione | alta |
| Linear memory linemod (meiqua) | alto | 10× match, -memoria | media |
| NMS cross-variant (dedup pose simili tra angoli/scale) | basso | meno duplicati | alta |
| ICP pose refinement sub-pixel | medio | <0.1 px precisione | media |
| Score calibrato probabilistico | medio | soglia adattiva | media |
| Rilevazione simmetria rotazionale robusta | medio | angle_range auto ridotto | alta |
| Template piramidato con feature per livello | fatto | ✓ | - |
| Refinement angolare sub-step | fatto | ✓ | - |
| Subpixel posizione (parabolic fit) | fatto | ✓ | - |
| Multi-template support (modello con varianti) | medio | generalizzazione | media |
| Confidence ellipse (uncertainty quantification) | basso | diagnostic | bassa |
## Feature di prodotto
| Sviluppo | Effort | Beneficio | Priorità |
|---|---|---|---|
| Supporto DXF (tassellazione + rasterizzazione via ezdxf) | medio | input CAD | alta |
| ROI poligonale (non rettangolare) nella GUI | basso | modello parziale preciso | alta |
| Analisi distintività modello (entropia, self-corr) nella UI | basso | warning al training | media |
| Salvataggio/caricamento modello `.npz` con thumbnail | basso | ricette riusabili | alta |
| Batch matching su cartella scene | basso | throughput offline | media |
| Esportazione JSON risultati per integrazione | basso | pipeline | alta |
| Live camera matching (webcam) | basso-medio | demo | bassa |
| REST API wrapper (FastAPI) | medio | integrazione Vision Suite | media |
| NATS messaging (per Vision Suite) | medio | microservizio | bassa |
| Web UI (Gradio o React) sostituiva di tk/cv2 | alto | deploy remoto | media |
| Benchmark suite automatica con GT labels | medio | non-regression | alta |
## Qualità codice
| Sviluppo | Effort | Beneficio | Priorità |
|---|---|---|---|
| Unit test (pytest) con dataset sintetico | basso | robustezza | alta |
| Type annotations complete + mypy strict | basso | manutenibilità | media |
| CI GitHub Actions: lint + test + build | medio | qualità PR | media |
| Profiling automatico baseline + regression check | medio | evitare lentezze | bassa |
| Packaging pip (`pip install pm2d`) | basso | distribuzione | bassa |
## Target performance produzione
Obiettivi da documento tecnico Vision Suite (Fase Beta):
- [x] **Precisione posizionale mediana**: <0.5 px → **0.04 px misurato su GT sintetica (Fase 2)**
- [x] **Precisione angolare mediana**: <1.0° → **0.05° misurato su GT sintetica (Fase 2)**
- [ ] **Latency mediana**: <50 ms su 1920×1080 → **~0.8s su 646×482 con 2 core; da misurare su hardware produzione**
- [ ] **F1 score dataset sintetico**: >0.95 → **da misurare con dataset sintetico**
Prossimo blocker per target: **latency**. Nota: i kernel hot sono gia'
Numba JIT (≈ velocita' C, prange parallelo): un port C++ dei kernel vale
solo il margine SIMD esplicito (~2-4x con AVX2 su AND+popcount byte-wise).
Prima di scriverlo conviene esaurire le vie algoritmiche rimaste:
riduzione varianti al top-level (auto angle step per livello, stile
Halcon), greediness di default, e GPU (CuPy/OpenCL) per scene 1080p.