From 2bca68d700ecf59eb510bb204438cad15067b649 Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Fri, 24 Apr 2026 10:52:26 +0200 Subject: [PATCH] feat: 'Filtro falsi positivi' preset user-friendly (era verify_ncc) Rinomina il parametro tecnico verify_threshold in un preset semantico che operatore/cliente capisce senza leggere docs: off -> 0.00 (tutti i match shape-based passano) leggero -> 0.20 (tollera illuminazione/riflessi) medio -> 0.35 (consigliato, default) forte -> 0.50 (massima selettivita, scarta mismatch intensita) UI: dropdown etichettato 'Filtro falsi positivi (verifica intensita colori)' accanto a precisione angolare. Override tecnico (numerico) resta in sezione Avanzate. Co-Authored-By: Claude Opus 4.7 (1M context) --- pm2d/web/server.py | 16 ++++++++++++---- pm2d/web/static/app.js | 4 +++- pm2d/web/static/index.html | 12 ++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/pm2d/web/server.py b/pm2d/web/server.py index 723bb02..9cc75a6 100644 --- a/pm2d/web/server.py +++ b/pm2d/web/server.py @@ -210,6 +210,15 @@ PRECISION_ANGLE_STEP = { "preciso": 2.0, } +# "Filtro falsi positivi" = mapping semantico del verify NCC threshold. +# Un operatore sceglie il livello di rigore, non un numero astratto. +FILTRO_FP_MAP = { + "off": 0.0, # disabilitato: mantieni tutti i match shape-based + "leggero": 0.20, # tollera variazioni intensità/illuminazione forti + "medio": 0.35, # default bilanciato (consigliato) + "forte": 0.50, # scarta match con intensità molto diversa dal template +} + class SimpleMatchParams(BaseModel): model_id: str @@ -219,7 +228,8 @@ class SimpleMatchParams(BaseModel): simmetria: str = "nessuna" # chiave SYMMETRY_TO_ANGLE_MAX scala: str = "fissa" # chiave SCALE_PRESETS precisione: str = "normale" # chiave PRECISION_ANGLE_STEP - min_score: float = 0.70 + filtro_fp: str = "medio" # chiave FILTRO_FP_MAP + min_score: float = 0.65 max_matches: int = 25 @@ -270,9 +280,7 @@ def _simple_to_technical( "min_score": p.min_score, "max_matches": p.max_matches, "nms_radius": 0, - # Verify NCC più permissivo per match con variazione intensità - # (foro su sfondo variabile, parti di oggetto ecc.) - "verify_threshold": 0.25, + "verify_threshold": FILTRO_FP_MAP.get(p.filtro_fp, 0.35), } diff --git a/pm2d/web/static/app.js b/pm2d/web/static/app.js index f170ca0..7fa251b 100644 --- a/pm2d/web/static/app.js +++ b/pm2d/web/static/app.js @@ -47,6 +47,7 @@ function readUserParams() { simmetria: document.getElementById("p-simmetria").value, scala: document.getElementById("p-scala").value, precisione: document.getElementById("p-precisione").value, + filtro_fp: document.getElementById("p-filtro-fp").value, min_score: parseFloat(document.getElementById("p-min-score").value), max_matches: parseInt(document.getElementById("p-max-matches").value, 10), }; @@ -238,6 +239,7 @@ async function doMatch() { const SCALE_MAP = {fissa:[1,1,0.1], mini:[0.9,1.1,0.05], medio:[0.75,1.25,0.05], max:[0.5,1.5,0.05]}; const PREC_MAP = {veloce:10, normale:5, preciso:2}; + const FP_MAP = {off:0, leggero:0.20, medio:0.35, forte:0.50}; const [smin, smax, sstep] = SCALE_MAP[user.scala]; body = { model_id: state.model.id, scene_id: state.scene.id, roi: state.roi, @@ -250,7 +252,7 @@ async function doMatch() { strong_grad: adv.strong_grad ?? 60, spread_radius: adv.spread_radius ?? 5, pyramid_levels: adv.pyramid_levels ?? 3, - verify_threshold: adv.verify_threshold ?? 0.4, + verify_threshold: adv.verify_threshold ?? (FP_MAP[user.filtro_fp] ?? 0.35), nms_radius: adv.nms_radius ?? 0, }; } else { diff --git a/pm2d/web/static/index.html b/pm2d/web/static/index.html index f4c6547..2ee6725 100644 --- a/pm2d/web/static/index.html +++ b/pm2d/web/static/index.html @@ -81,6 +81,18 @@ +
+ + +
+