a78884f950
Pannello "🔬 Anteprima edge / pulizia rumore" sotto il canvas modello. Permette tuning interattivo dei parametri di selezione edge per togliere "sporcizie" (rumore di sfondo, edge spuri) prima di trainare il matcher. Server: - POST /preview_edges: dato modello+ROI+param edge, ritorna immagine ROI con overlay: * heatmap magnitude gradient (sfondo) * verde scuro: pixel sopra hysteresis edge * cerchietti colorati per bin: feature scelte (palette 16 bin) * UCS rosso/verde sul baricentro feature (richiesta utente): asse X destra, Y giu' (image y-down) Ritorna anche stats: n_features, n_edge_strong, percentili magnitude, ucs_baricentro {cx, cy} UI: - Slider weak_grad/strong_grad/num_features/spacing + checkbox polarity - Re-fetch debounced (200ms) ad ogni input → preview live - Bottone "Applica ai parametri Avanzate": copia i valori scelti nei campi Avanzate del matcher principale - Auto-fetch quando il pannello viene aperto Use case: operatore vede SUBITO quali edge il matcher userebbe, regola soglie per escludere rumore, applica e poi MATCH. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
272 lines
10 KiB
HTML
272 lines
10 KiB
HTML
<!doctype html>
|
||
<html lang="it">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>Pattern Matching 2D</title>
|
||
<link rel="stylesheet" href="/static/style.css">
|
||
</head>
|
||
<body>
|
||
<header>
|
||
<h1>Pattern Matching 2D</h1>
|
||
<div class="toolbar">
|
||
<label class="tb-label">Modello:</label>
|
||
<div class="thumb-picker" id="picker-model">
|
||
<div class="picker-current" tabindex="0">
|
||
<span class="picker-text">-- seleziona --</span>
|
||
<span class="caret">▾</span>
|
||
</div>
|
||
<div class="picker-list"></div>
|
||
</div>
|
||
<label class="tb-label">Scena:</label>
|
||
<div class="thumb-picker" id="picker-scene">
|
||
<div class="picker-current" tabindex="0">
|
||
<span class="picker-text">-- seleziona --</span>
|
||
<span class="caret">▾</span>
|
||
</div>
|
||
<div class="picker-list"></div>
|
||
</div>
|
||
<button class="btn btn-go" id="btn-match">▶ MATCH</button>
|
||
<button class="btn" id="btn-autotune"
|
||
title="Analizza ROI e derivata parametri ottimali (Halcon-style)">
|
||
⚙ Auto-tune
|
||
</button>
|
||
<label class="btn" title="Carica nuovo file nella cartella immagini">
|
||
⬆ Carica file
|
||
<input type="file" id="file-upload" accept="image/*" hidden>
|
||
</label>
|
||
<span id="status">Seleziona modello, disegna ROI, seleziona scena</span>
|
||
</div>
|
||
</header>
|
||
|
||
<main>
|
||
<section class="col" id="col-model">
|
||
<h2>MODELLO</h2>
|
||
<div class="canvas-wrap">
|
||
<canvas id="c-model" width="380" height="420"></canvas>
|
||
</div>
|
||
<div id="roi-info">ROI: (nessuna)</div>
|
||
<details id="edge-preview-panel" style="margin-top:10px">
|
||
<summary>🔬 Anteprima edge / pulizia rumore</summary>
|
||
<div style="font-size:11px; color:#aaa; margin:4px 0">
|
||
Regola le soglie per togliere edge spuri (sporcizie). UCS rosso/verde
|
||
sul baricentro feature.
|
||
</div>
|
||
<div class="ep-grid">
|
||
<label class="ep-row">weak_grad <span id="ep-weak-v">30</span>
|
||
<input type="range" id="ep-weak" min="5" max="200" value="30" step="1">
|
||
</label>
|
||
<label class="ep-row">strong_grad <span id="ep-strong-v">60</span>
|
||
<input type="range" id="ep-strong" min="10" max="400" value="60" step="1">
|
||
</label>
|
||
<label class="ep-row">num_features <span id="ep-nf-v">96</span>
|
||
<input type="range" id="ep-nf" min="16" max="300" value="96" step="1">
|
||
</label>
|
||
<label class="ep-row">spacing <span id="ep-sp-v">3</span>
|
||
<input type="range" id="ep-sp" min="1" max="15" value="3" step="1">
|
||
</label>
|
||
<label class="ep-row" style="flex-direction:row; gap:6px">
|
||
<input type="checkbox" id="ep-pol"> polarity
|
||
</label>
|
||
<button class="btn" id="btn-edge-apply" type="button"
|
||
style="grid-column:1/-1">
|
||
✓ Applica ai parametri Avanzate
|
||
</button>
|
||
</div>
|
||
<div class="canvas-wrap" style="margin-top:6px">
|
||
<canvas id="c-edge-preview" width="380" height="380"></canvas>
|
||
</div>
|
||
<div id="edge-preview-info" style="font-size:11px; color:#888; margin-top:4px">
|
||
Disegna ROI e apri questo pannello per generare anteprima
|
||
</div>
|
||
</details>
|
||
</section>
|
||
|
||
<section class="col" id="col-scene">
|
||
<h2>SCENA</h2>
|
||
<div class="canvas-wrap">
|
||
<canvas id="c-scene" width="820" height="620"></canvas>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="col" id="col-params">
|
||
<h2>IMPOSTAZIONI</h2>
|
||
|
||
<div class="field">
|
||
<label>Tipo modello</label>
|
||
<select id="p-tipo">
|
||
<option value="intero">Oggetto intero</option>
|
||
<option value="parziale">Parte di oggetto</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Simmetria</label>
|
||
<select id="p-simmetria">
|
||
<option value="invariante">Invariante (cerchi — no rotazione)</option>
|
||
<option value="nessuna">Nessuna (0..360°)</option>
|
||
<option value="bilaterale">Bilaterale (speculare 180°)</option>
|
||
<option value="rot_3">Rotazionale 3× (120°)</option>
|
||
<option value="rot_4">Rotazionale 4× (90°)</option>
|
||
<option value="rot_6">Rotazionale 6× (60°)</option>
|
||
<option value="rot_8">Rotazionale 8× (45°)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Variazione scala</label>
|
||
<select id="p-scala">
|
||
<option value="fissa">Fissa (setup calibrato)</option>
|
||
<option value="mini">±10%</option>
|
||
<option value="medio">±25%</option>
|
||
<option value="max">±50%</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Precisione angolare</label>
|
||
<select id="p-precisione">
|
||
<option value="veloce">Veloce (10°)</option>
|
||
<option value="normale" selected>Normale (5°)</option>
|
||
<option value="preciso">Preciso (2°)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Filtro falsi positivi
|
||
<span class="hint">(verifica intensità colori)</span>
|
||
</label>
|
||
<select id="p-filtro-fp">
|
||
<option value="off">Disattivato (massimo recall)</option>
|
||
<option value="leggero">Leggero (tollera illuminazione)</option>
|
||
<option value="medio" selected>Medio (consigliato)</option>
|
||
<option value="forte">Forte (massima selettività)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Peso dimensione nel score
|
||
<span class="hint">(penalizza scala ≠ 1.0)</span>
|
||
</label>
|
||
<select id="p-penalita-scala">
|
||
<option value="0" selected>Nessuno (score shape puro)</option>
|
||
<option value="0.3">Leggero (−30% max)</option>
|
||
<option value="0.5">Medio (−50% max)</option>
|
||
<option value="0.8">Forte (−80% max)</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Score minimo <span id="v-score">0.65</span>
|
||
<span class="hint">(più basso = più match anche incerti)</span>
|
||
</label>
|
||
<input type="range" id="p-min-score" min="0.30" max="0.95" step="0.05" value="0.65">
|
||
</div>
|
||
|
||
<div class="field">
|
||
<label>Max match</label>
|
||
<input type="number" id="p-max-matches" value="25" min="1" max="200">
|
||
</div>
|
||
|
||
<details>
|
||
<summary>Modalità Halcon</summary>
|
||
<div class="halcon-grid">
|
||
<label class="hc-row" title="16-bin orientation polarity-aware (mod 2π)">
|
||
<input type="checkbox" id="hc-use-polarity">
|
||
<span>Polarity 16-bin (F)</span>
|
||
</label>
|
||
<label class="hc-row" title="Score continuo cos(θ_t-θ_s) invece di bin">
|
||
<input type="checkbox" id="hc-soft-score">
|
||
<span>Soft-margin score (Y)</span>
|
||
</label>
|
||
<label class="hc-row" title="Sub-pixel refinement gradient field LM">
|
||
<input type="checkbox" id="hc-subpixel-lm">
|
||
<span>Sub-pixel LM 0.05 px (Z)</span>
|
||
</label>
|
||
<label class="hc-row" title="Refine congiunto Nelder-Mead (cx,cy,θ)">
|
||
<input type="checkbox" id="hc-refine-joint">
|
||
<span>Refine pose joint</span>
|
||
</label>
|
||
<label class="hc-row" title="Pyramid candidates propagation">
|
||
<input type="checkbox" id="hc-pyr-propagate">
|
||
<span>Pyramid propagate</span>
|
||
</label>
|
||
<label class="hc-row" title="OpenCL GPU offload (silent fallback CPU)">
|
||
<input type="checkbox" id="hc-use-gpu">
|
||
<span>GPU OpenCL (R)</span>
|
||
</label>
|
||
|
||
<div class="hc-row hc-num">
|
||
<label>Min recall (M)</label>
|
||
<input type="number" id="hc-min-recall" value="0.0" min="0" max="1" step="0.05">
|
||
</div>
|
||
<div class="hc-row hc-num">
|
||
<label>NMS IoU thr (A)</label>
|
||
<input type="number" id="hc-nms-iou" value="0.3" min="0" max="1" step="0.05">
|
||
</div>
|
||
<div class="hc-row hc-num">
|
||
<label>Greediness</label>
|
||
<input type="number" id="hc-greediness" value="0.0" min="0" max="1" step="0.1">
|
||
</div>
|
||
<div class="hc-row hc-num">
|
||
<label>Coarse stride</label>
|
||
<input type="number" id="hc-coarse-stride" value="1" min="1" max="4" step="1">
|
||
</div>
|
||
<div class="hc-row hc-num" style="grid-column:1/-1">
|
||
<label title="Limita area di ricerca scena: x,y,w,h (vuoto = tutta scena)">
|
||
Search ROI (x,y,w,h)
|
||
</label>
|
||
<input type="text" id="hc-search-roi" placeholder="es. 100,50,800,400">
|
||
</div>
|
||
|
||
<div class="hc-row" style="grid-column:1/-1; border-top:1px solid #444; padding-top:8px">
|
||
<label>Ricetta pre-trained (V)</label>
|
||
<div style="display:flex; gap:6px; margin-top:4px">
|
||
<input type="text" id="hc-recipe-name" placeholder="nome_ricetta" style="flex:1">
|
||
<button class="btn" id="btn-save-recipe" type="button">💾 Salva</button>
|
||
</div>
|
||
<div style="display:flex; gap:6px; margin-top:6px; align-items:center">
|
||
<select id="hc-recipe-list" style="flex:1">
|
||
<option value="">— ricette disponibili —</option>
|
||
</select>
|
||
<button class="btn" id="btn-load-recipe" type="button">📂 Carica</button>
|
||
<button class="btn" id="btn-unload-recipe" type="button" disabled>✖ Stacca</button>
|
||
</div>
|
||
<div id="recipe-status" style="margin-top:4px; font-size:11px; color:#888">
|
||
Nessuna ricetta caricata
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
|
||
<details>
|
||
<summary>Avanzate</summary>
|
||
<div id="adv-form"></div>
|
||
</details>
|
||
|
||
<h2 style="margin-top:14px">TEMPI</h2>
|
||
<div class="kv"><span>train:</span><span id="t-train">-</span></div>
|
||
<div class="kv"><span>find:</span><span id="t-find">-</span></div>
|
||
<div class="kv"><span>varianti:</span><span id="t-var">-</span></div>
|
||
<div class="kv"><span>match:</span><span id="t-match">-</span></div>
|
||
|
||
<details id="diag-panel" style="margin-top:10px">
|
||
<summary>🔍 Diagnostica (CC)</summary>
|
||
<div id="diag-content" style="font-family:monospace; font-size:11px;
|
||
background:#1a1a1a; padding:8px;
|
||
border-radius:3px; margin-top:6px;
|
||
line-height:1.5">
|
||
<em style="color:#888">Esegui un MATCH per vedere la diagnostica</em>
|
||
</div>
|
||
</details>
|
||
</section>
|
||
</main>
|
||
|
||
<footer>
|
||
<h2>LEGENDA</h2>
|
||
<div id="legend"></div>
|
||
</footer>
|
||
|
||
<script src="/static/app.js"></script>
|
||
</body>
|
||
</html>
|