|
|
|
@@ -336,6 +336,7 @@ async function doMatchRecipe() {
|
|
|
|
|
document.getElementById("t-find").textContent = `${data.find_time.toFixed(2)}s`;
|
|
|
|
|
document.getElementById("t-var").textContent = data.num_variants;
|
|
|
|
|
document.getElementById("t-match").textContent = data.matches.length;
|
|
|
|
|
renderDiag(data.diag, data.matches.length);
|
|
|
|
|
setStatus(`${data.matches.length} match trovati (ricetta ${state.active_recipe})`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -409,6 +410,7 @@ async function doMatch() {
|
|
|
|
|
document.getElementById("t-find").textContent = `${data.find_time.toFixed(2)}s`;
|
|
|
|
|
document.getElementById("t-var").textContent = data.num_variants;
|
|
|
|
|
document.getElementById("t-match").textContent = data.matches.length;
|
|
|
|
|
renderDiag(data.diag, data.matches.length);
|
|
|
|
|
setStatus(`${data.matches.length} match trovati${hasAdv ? " (avanzato)" : ""}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -436,6 +438,61 @@ function setStatus(s) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- Init ----------
|
|
|
|
|
// ---------- CC: Diagnostica match ----------
|
|
|
|
|
function renderDiag(diag, n_matches) {
|
|
|
|
|
const el = document.getElementById("diag-content");
|
|
|
|
|
if (!diag) {
|
|
|
|
|
el.innerHTML = '<em style="color:#888">Diagnostica non disponibile</em>';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const dropTotal = (diag.drop_ncc_low || 0) + (diag.drop_min_score_post_avg || 0)
|
|
|
|
|
+ (diag.drop_recall_low || 0) + (diag.drop_bbox_out_of_scene || 0)
|
|
|
|
|
+ (diag.drop_nms_iou || 0);
|
|
|
|
|
// Hint contestuali se 0 match
|
|
|
|
|
let hint = "";
|
|
|
|
|
if (n_matches === 0) {
|
|
|
|
|
if (diag.n_after_pre_nms === 0) {
|
|
|
|
|
hint = `<div style="color:#f88; margin-top:6px">⚠ Nessun candidato sopra soglia.
|
|
|
|
|
Prova: ↓ <b>min_score</b> o ↓ <b>top_thresh</b> (currently ${diag.top_thresh_used.toFixed(2)})</div>`;
|
|
|
|
|
} else if (diag.drop_ncc_low > 0 && dropTotal === diag.drop_ncc_low) {
|
|
|
|
|
hint = `<div style="color:#f88; margin-top:6px">⚠ ${diag.drop_ncc_low} candidati droppati da NCC.
|
|
|
|
|
Prova: ↓ <b>verify_threshold</b> (filtro_fp più leggero)</div>`;
|
|
|
|
|
} else if (diag.drop_min_score_post_avg > 0) {
|
|
|
|
|
hint = `<div style="color:#f88; margin-top:6px">⚠ ${diag.drop_min_score_post_avg} match sotto min_score post-NCC.
|
|
|
|
|
Prova: ↓ <b>min_score</b></div>`;
|
|
|
|
|
} else if (diag.drop_recall_low > 0) {
|
|
|
|
|
hint = `<div style="color:#f88; margin-top:6px">⚠ ${diag.drop_recall_low} match con recall < ${diag.min_recall_used}.
|
|
|
|
|
Prova: ↓ <b>min_recall</b></div>`;
|
|
|
|
|
} else if (diag.drop_bbox_out_of_scene > 0) {
|
|
|
|
|
hint = `<div style="color:#f88; margin-top:6px">⚠ ${diag.drop_bbox_out_of_scene} match con bbox fuori scena.
|
|
|
|
|
Centro derivato male: aumenta <b>min_score</b> o restringi <b>search_roi</b></div>`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const flags = [];
|
|
|
|
|
if (diag.use_polarity) flags.push("polarity");
|
|
|
|
|
if (diag.use_soft_score) flags.push("soft");
|
|
|
|
|
if (diag.subpixel_lm) flags.push("subpix-LM");
|
|
|
|
|
el.innerHTML = `
|
|
|
|
|
<div><b>Pipeline pruning:</b></div>
|
|
|
|
|
<div>varianti: ${diag.n_variants_total} → top_eval=${diag.n_variants_top_evaluated}
|
|
|
|
|
→ top_pass=${diag.n_variants_top_passed} → full_eval=${diag.n_variants_full_evaluated}</div>
|
|
|
|
|
<div><b>Candidati:</b> raw=${diag.n_raw_candidates}
|
|
|
|
|
→ pre_nms=${diag.n_after_pre_nms} → final=${diag.n_final}</div>
|
|
|
|
|
<div><b>Drop reasons:</b> NCC=${diag.drop_ncc_low}, score=${diag.drop_min_score_post_avg},
|
|
|
|
|
recall=${diag.drop_recall_low}, bbox=${diag.drop_bbox_out_of_scene}, NMS=${diag.drop_nms_iou}</div>
|
|
|
|
|
<div><b>Soglie:</b> top=${diag.top_thresh_used.toFixed(2)},
|
|
|
|
|
min_score=${diag.min_score_used.toFixed(2)},
|
|
|
|
|
NCC=${diag.verify_threshold_used.toFixed(2)},
|
|
|
|
|
recall=${diag.min_recall_used.toFixed(2)}</div>
|
|
|
|
|
${flags.length ? `<div><b>Flag attivi:</b> ${flags.join(", ")}</div>` : ""}
|
|
|
|
|
${hint}
|
|
|
|
|
`;
|
|
|
|
|
// Auto-apri pannello se 0 match (segnala problema)
|
|
|
|
|
if (n_matches === 0) {
|
|
|
|
|
document.getElementById("diag-panel").open = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------- Auto-tune (Halcon-style) ----------
|
|
|
|
|
async function doAutoTune() {
|
|
|
|
|
if (!state.model || !state.roi) {
|
|
|
|
|