fix: cap adattivo al 50% varianti + form e finestra risultati ridimensionabili

- max_vars_full = max(max_matches*8, n_variants // 2): protegge perf con
  molte scale mantenendo metà delle varianti al full-res (vs intero senza cap
  che dava 22s su 864 varianti, vs 80s screenshot utente)
- Dialog tkinter: resizable, minsize 360x420, Entry col peso 2 espandibile
- Finestra risultati cv2: WINDOW_NORMAL con resizeWindow iniziale 1600x900

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-24 01:57:20 +02:00
parent 9a0da7aac8
commit d27676cfe6
2 changed files with 18 additions and 4 deletions
+13 -2
View File
@@ -55,21 +55,29 @@ def edit_params(defaults: dict, template_bgr: np.ndarray | None = None) -> dict
""" """
root = tk.Tk() root = tk.Tk()
root.title("Parametri Pattern Matching 2D") root.title("Parametri Pattern Matching 2D")
root.resizable(True, True)
root.minsize(360, 420)
try: try:
root.attributes("-topmost", True) root.attributes("-topmost", True)
except Exception: except Exception:
pass pass
# Grid root: fa espandere la cella (0, 0)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
result: dict = {} result: dict = {}
entries: dict[str, tk.Entry] = {} entries: dict[str, tk.Entry] = {}
frame = ttk.Frame(root, padding=12) frame = ttk.Frame(root, padding=12)
frame.grid(row=0, column=0, sticky="nsew") frame.grid(row=0, column=0, sticky="nsew")
frame.columnconfigure(0, weight=1)
frame.columnconfigure(1, weight=2)
for i, (key, label, _typ) in enumerate(PARAM_SCHEMA): for i, (key, label, _typ) in enumerate(PARAM_SCHEMA):
ttk.Label(frame, text=label).grid(row=i, column=0, sticky="w", padx=4, pady=3) ttk.Label(frame, text=label).grid(row=i, column=0, sticky="w", padx=4, pady=3)
e = ttk.Entry(frame, width=14) e = ttk.Entry(frame)
e.insert(0, str(defaults.get(key, ""))) e.insert(0, str(defaults.get(key, "")))
e.grid(row=i, column=1, padx=4, pady=3) e.grid(row=i, column=1, padx=4, pady=3, sticky="ew")
entries[key] = e entries[key] = e
hint_var = tk.StringVar(value="") hint_var = tk.StringVar(value="")
@@ -392,6 +400,9 @@ def show_results(
else: else:
composed = annotated composed = annotated
disp = _fit_for_display(composed, max_side=1600) disp = _fit_for_display(composed, max_side=1600)
cv2.namedWindow(WINDOW_RESULT, cv2.WINDOW_NORMAL)
cv2.resizeWindow(WINDOW_RESULT, min(disp.shape[1], 1600),
min(disp.shape[0], 900))
cv2.imshow(WINDOW_RESULT, disp) cv2.imshow(WINDOW_RESULT, disp)
print("\n[r] parametri [o] nuovo ROI [m] nuovo modello [s] nuova scena [q/Esc] chiudi") print("\n[r] parametri [o] nuovo ROI [m] nuovo modello [s] nuova scena [q/Esc] chiudi")
action = "quit" action = "quit"
+5 -2
View File
@@ -542,9 +542,12 @@ class LineShapeMatcher:
if not kept_variants: if not kept_variants:
return [] return []
# Cap: tutte le varianti che superano top_thresh passano al full-res. # Cap adattivo: ordina per score top-level e mantieni le più promettenti.
# Ordinamento per score decrescente (early matches hanno priorità). # Min: max_matches*8 (margine per NMS cross-variant)
# Max: 50% delle varianti totali (protegge performance con molte scale)
kept_variants.sort(key=lambda t: -t[1]) kept_variants.sort(key=lambda t: -t[1])
max_vars_full = max(max_matches * 8, len(self.variants) // 2)
kept_variants = kept_variants[:max_vars_full]
# Full-res (parallelizzato per variante) # Full-res (parallelizzato per variante)
resp0 = self._response_map(gray0) resp0 = self._response_map(gray0)