feat: background locale + verify NCC per eliminare falsi positivi

Problema: matcher linemod con solo orientamento gradient può dare score alto
su texture dense/rumore che per caso accumulano orientamenti compatibili.
Esempio: template ruota dentata su scena clip → match a score 0.9 (errati).

Fix in 2 livelli:

1. Background score LOCALE nel find()
   - _bg_map(resp, box_size) = densità media bin attivi in bbox template
   - Rinormalizza score: s' = max(0, (s - bg) / (1 - bg))
   - Annulla contributo di zone sature ma preserva pattern puliti

2. Verify NCC post-hoc
   - _verify_ncc(): warpa template alla pose (cx, cy, angle, scale) e
     calcola NCC classico su intensità con la scena sottostante
   - Threshold di default 0.4 elimina FP con edge orientati casualmente
   - Parametro esposto in GUI (verify_threshold)

Rimossa penalty di saturazione nel response_map (ridondante).

Test regression (ruote dentate vs clip, clip vs ruote dentate):
  no verify:  12+ falsi positivi con score ~0.7
  verify 0.4: 1-2 falsi positivi rimanenti, true positive invariati
  verify 0.5: 0 falsi positivi, 1 TP scale piccola perso

Benchmark clip→clip (13 istanze):
  full pipeline (Numba + threads + refine + subpix + verify): 1.12s

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 01:37:01 +02:00
parent b20b11c029
commit faebccb69e
3 changed files with 90 additions and 8 deletions
+1
View File
@@ -190,6 +190,7 @@ def auto_tune(template_bgr: np.ndarray, mask: np.ndarray | None = None) -> dict:
"strong_grad": round(strong_grad, 1),
"spread_radius": spread_radius,
"pyramid_levels": pyr,
"verify_threshold": 0.4,
# meta (non in PARAM_SCHEMA, usato per log)
"_symmetry_order": sym["order"],
"_symmetry_conf": round(sym["confidence"], 2),