merge: angle restrict helper
This commit is contained in:
+21
-3
@@ -152,14 +152,27 @@ def _cache_key(template_bgr: np.ndarray, mask: np.ndarray | None) -> str:
|
|||||||
return h.hexdigest()
|
return h.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def auto_tune(template_bgr: np.ndarray, mask: np.ndarray | None = None) -> dict:
|
def auto_tune(
|
||||||
|
template_bgr: np.ndarray,
|
||||||
|
mask: np.ndarray | None = None,
|
||||||
|
angle_tolerance_deg: float | None = None,
|
||||||
|
angle_center_deg: float = 0.0,
|
||||||
|
) -> dict:
|
||||||
"""Analizza template e ritorna dict parametri suggeriti.
|
"""Analizza template e ritorna dict parametri suggeriti.
|
||||||
|
|
||||||
Chiavi compatibili con edit_params PARAM_SCHEMA.
|
Chiavi compatibili con edit_params PARAM_SCHEMA.
|
||||||
|
|
||||||
|
angle_tolerance_deg: se != None, restringe angle_range a
|
||||||
|
(center - tol, center + tol). Usare quando l'orientamento del
|
||||||
|
pezzo e' noto a priori (feeder con guida, posizionamento
|
||||||
|
meccanico): training molto piu rapido (24x meno varianti per
|
||||||
|
tol=15° vs 360° pieno).
|
||||||
|
|
||||||
Risultato cachato in-memory (LRU): ri-chiamare con stessa ROI è O(1).
|
Risultato cachato in-memory (LRU): ri-chiamare con stessa ROI è O(1).
|
||||||
"""
|
"""
|
||||||
ck = _cache_key(template_bgr, mask)
|
ck = _cache_key(template_bgr, mask)
|
||||||
|
if angle_tolerance_deg is not None:
|
||||||
|
ck = f"{ck}|tol={angle_tolerance_deg}|c={angle_center_deg}"
|
||||||
cached = _TUNE_CACHE.get(ck)
|
cached = _TUNE_CACHE.get(ck)
|
||||||
if cached is not None:
|
if cached is not None:
|
||||||
_TUNE_CACHE.move_to_end(ck)
|
_TUNE_CACHE.move_to_end(ck)
|
||||||
@@ -208,7 +221,12 @@ def auto_tune(template_bgr: np.ndarray, mask: np.ndarray | None = None) -> dict:
|
|||||||
# spread_radius proporzionale a risoluzione + pyramid (tolleranza ~1% dim)
|
# spread_radius proporzionale a risoluzione + pyramid (tolleranza ~1% dim)
|
||||||
spread_radius = int(np.clip(max(3, min_side * 0.02), 3, 8))
|
spread_radius = int(np.clip(max(3, min_side * 0.02), 3, 8))
|
||||||
|
|
||||||
# angle range ridotto se simmetria rotazionale
|
# angle range: priorita' a tolerance hint utente, poi simmetria rotazionale.
|
||||||
|
if angle_tolerance_deg is not None:
|
||||||
|
angle_min = float(angle_center_deg - angle_tolerance_deg)
|
||||||
|
angle_max = float(angle_center_deg + angle_tolerance_deg)
|
||||||
|
else:
|
||||||
|
angle_min = 0.0
|
||||||
angle_max = 360.0 / sym["order"] if sym["order"] > 1 else 360.0
|
angle_max = 360.0 / sym["order"] if sym["order"] > 1 else 360.0
|
||||||
|
|
||||||
# min_score: se entropia orient alta → template distintivo → soglia alta ok
|
# min_score: se entropia orient alta → template distintivo → soglia alta ok
|
||||||
@@ -228,7 +246,7 @@ def auto_tune(template_bgr: np.ndarray, mask: np.ndarray | None = None) -> dict:
|
|||||||
|
|
||||||
result = {
|
result = {
|
||||||
"backend": "line",
|
"backend": "line",
|
||||||
"angle_min": 0.0,
|
"angle_min": angle_min,
|
||||||
"angle_max": angle_max,
|
"angle_max": angle_max,
|
||||||
"angle_step": angle_step,
|
"angle_step": angle_step,
|
||||||
"scale_min": 1.0,
|
"scale_min": 1.0,
|
||||||
|
|||||||
@@ -226,6 +226,26 @@ class LineShapeMatcher:
|
|||||||
np.array(picked_y, np.int32),
|
np.array(picked_y, np.int32),
|
||||||
np.array(picked_b, np.int8))
|
np.array(picked_b, np.int8))
|
||||||
|
|
||||||
|
def set_angle_range_around(
|
||||||
|
self, center_deg: float, tolerance_deg: float,
|
||||||
|
) -> None:
|
||||||
|
"""Restringe angle_range a (center - tol, center + tol).
|
||||||
|
|
||||||
|
Comodo helper per scenari in cui l'orientamento del pezzo e'
|
||||||
|
noto a priori entro ±tolerance_deg (es. feeder vibrante con
|
||||||
|
guida meccanica). Riduce drasticamente le varianti generate
|
||||||
|
in train(): es. ±15° vs 360° = 24x meno varianti, training
|
||||||
|
e matching molto piu veloci.
|
||||||
|
|
||||||
|
Esempio:
|
||||||
|
m.set_angle_range_around(0, 20) # cerca solo in [-20, +20]
|
||||||
|
m.train(template)
|
||||||
|
"""
|
||||||
|
self.angle_range_deg = (
|
||||||
|
float(center_deg - tolerance_deg),
|
||||||
|
float(center_deg + tolerance_deg),
|
||||||
|
)
|
||||||
|
|
||||||
def _scale_list(self) -> list[float]:
|
def _scale_list(self) -> list[float]:
|
||||||
s0, s1 = self.scale_range
|
s0, s1 = self.scale_range
|
||||||
if s0 >= s1 or self.scale_step <= 0:
|
if s0 >= s1 or self.scale_step <= 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user