perf: coarse step angolare auto al top-level (Halcon-style)
Al livello top le feature distano R/2^top dal centro: lo spread tollera una rotazione ~atan(spread/(max_side_top/2)), molto piu' ampia dello step full-res. Si valuta al top 1 variante ogni cf_auto (clamp 1..8), le intermedie vengono riprese dall'espansione ai vicini. Con step 2° e template 160px: top_eval 180 -> 30 varianti a parita' di recall (rimosso il forzato cf=1 per step <= 3 che valutava tutto). Inclusa pulizia lint: variabili/import inutilizzati. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,6 @@ Tutta la logica algoritmica vive in pm2d.matcher.EdgeShapeMatcher.
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from tkinter import Tk, filedialog
|
from tkinter import Tk, filedialog
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
|||||||
+20
-12
@@ -38,7 +38,6 @@ _GOLDEN = (math.sqrt(5.0) - 1.0) / 2.0 # ≈ 0.618
|
|||||||
|
|
||||||
from pm2d._jit_kernels import (
|
from pm2d._jit_kernels import (
|
||||||
score_by_shift as _jit_score_by_shift,
|
score_by_shift as _jit_score_by_shift,
|
||||||
score_bitmap as _jit_score_bitmap,
|
|
||||||
score_bitmap_rescored as _jit_score_bitmap_rescored,
|
score_bitmap_rescored as _jit_score_bitmap_rescored,
|
||||||
score_bitmap_rescored_window as _jit_score_bitmap_rescored_window,
|
score_bitmap_rescored_window as _jit_score_bitmap_rescored_window,
|
||||||
score_bitmap_greedy as _jit_score_bitmap_greedy,
|
score_bitmap_greedy as _jit_score_bitmap_greedy,
|
||||||
@@ -326,8 +325,6 @@ class LineShapeMatcher:
|
|||||||
n_vars = len(self.variants)
|
n_vars = len(self.variants)
|
||||||
n_levels = len(self.variants[0].levels)
|
n_levels = len(self.variants[0].levels)
|
||||||
var_meta = np.zeros((n_vars, 6), dtype=np.float32) # ang, scale, kh, kw, cxl, cyl
|
var_meta = np.zeros((n_vars, 6), dtype=np.float32) # ang, scale, kh, kw, cxl, cyl
|
||||||
all_dx, all_dy, all_bin, all_offsets = [], [], [], []
|
|
||||||
offset = 0
|
|
||||||
all_offsets_per_level = [[] for _ in range(n_levels)]
|
all_offsets_per_level = [[] for _ in range(n_levels)]
|
||||||
all_dx_per_level = [[] for _ in range(n_levels)]
|
all_dx_per_level = [[] for _ in range(n_levels)]
|
||||||
all_dy_per_level = [[] for _ in range(n_levels)]
|
all_dy_per_level = [[] for _ in range(n_levels)]
|
||||||
@@ -1483,12 +1480,9 @@ class LineShapeMatcher:
|
|||||||
if nms_radius is None:
|
if nms_radius is None:
|
||||||
nms_radius = max(8, min(self.template_size) // 2)
|
nms_radius = max(8, min(self.template_size) // 2)
|
||||||
# Pruning adattivo allo step angolare: con step piccolo (<= 3 deg)
|
# Pruning adattivo allo step angolare: con step piccolo (<= 3 deg)
|
||||||
# ci sono molte varianti vicine, gli score top-level sono ravvicinati
|
# ci sono molte varianti vicine e gli score top-level sono
|
||||||
# e top_thresh*0.5 e' troppo aggressivo: scarta varianti valide che
|
# ravvicinati: top_thresh*0.5 e' troppo aggressivo, scarta varianti
|
||||||
# sarebbero state riprese al full-res. Stessa cosa per
|
# valide che sarebbero state riprese al full-res.
|
||||||
# coarse_angle_factor (skip 1 ogni 2): con step fine non e' utile.
|
|
||||||
# Risultato osservato: precisione "veloce" 10° dava risultati
|
|
||||||
# migliori di "preciso" 2° proprio perche evitava il pruning.
|
|
||||||
# Il path windowed (pyramid_propagate) assume che il picco
|
# Il path windowed (pyramid_propagate) assume che il picco
|
||||||
# top-level localizzi la posizione entro il margine finestra.
|
# top-level localizzi la posizione entro il margine finestra.
|
||||||
# Su template ALLUNGATI (es. lama 40x280, o ROI parziale lungo un
|
# Su template ALLUNGATI (es. lama 40x280, o ROI parziale lungo un
|
||||||
@@ -1503,10 +1497,25 @@ class LineShapeMatcher:
|
|||||||
pyramid_propagate = False
|
pyramid_propagate = False
|
||||||
eff_step = self._effective_angle_step()
|
eff_step = self._effective_angle_step()
|
||||||
top_factor = self.top_score_factor
|
top_factor = self.top_score_factor
|
||||||
cf_eff = max(1, coarse_angle_factor)
|
|
||||||
if eff_step <= 3.0:
|
if eff_step <= 3.0:
|
||||||
top_factor = max(top_factor, 0.7)
|
top_factor = max(top_factor, 0.7)
|
||||||
cf_eff = 1
|
# Coarse step angolare AUTO al top-level (Halcon-style): al livello
|
||||||
|
# top le feature distano R/2^top dal centro, quindi lo spread
|
||||||
|
# (raggio in px, costante per livello) tollera una rotazione
|
||||||
|
# ~atan(spread / (max_side_top/2)) — molto piu' ampia dello step
|
||||||
|
# richiesto a full-res. Si valuta al top 1 variante ogni cf_eff;
|
||||||
|
# le intermedie vengono riprese dall'espansione ai vicini.
|
||||||
|
# Es: template 160 px, 3 livelli, step 2° → tolleranza top ~11°
|
||||||
|
# → cf 6 → top-pruning ~6x piu' veloce a parita' di recall.
|
||||||
|
if self.template_size != (0, 0):
|
||||||
|
max_side_top = max(self.template_size) / (2 ** top)
|
||||||
|
else:
|
||||||
|
max_side_top = 64.0
|
||||||
|
step_top_tol = math.degrees(
|
||||||
|
math.atan2(float(self.spread_radius), max(8.0, max_side_top / 2.0))
|
||||||
|
)
|
||||||
|
cf_auto = int(np.clip(round(step_top_tol / max(eff_step, 1e-6)), 1, 8))
|
||||||
|
cf_eff = max(1, coarse_angle_factor, cf_auto)
|
||||||
top_thresh = min_score * top_factor
|
top_thresh = min_score * top_factor
|
||||||
diag["top_thresh_used"] = float(top_thresh)
|
diag["top_thresh_used"] = float(top_thresh)
|
||||||
|
|
||||||
@@ -1562,7 +1571,6 @@ class LineShapeMatcher:
|
|||||||
dtype=bool,
|
dtype=bool,
|
||||||
)
|
)
|
||||||
if scene_bins.any():
|
if scene_bins.any():
|
||||||
n_scene_active = int(scene_bins.sum())
|
|
||||||
# Soglia: variante deve avere >= 50% delle sue feature in bin
|
# Soglia: variante deve avere >= 50% delle sue feature in bin
|
||||||
# presenti nella scena. Sotto = score certamente < 0.5.
|
# presenti nella scena. Sotto = score certamente < 0.5.
|
||||||
pruned_idx_list = []
|
pruned_idx_list = []
|
||||||
|
|||||||
Reference in New Issue
Block a user