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):
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.