Compare commits
2 Commits
e1ed9206a3
...
8029a1e12b
| Author | SHA1 | Date | |
|---|---|---|---|
| 8029a1e12b | |||
| d37833076e |
+23
-38
@@ -143,17 +143,6 @@ def _draw_matches(scene: np.ndarray, matches: list[Match],
|
|||||||
nell'anteprima modello.
|
nell'anteprima modello.
|
||||||
"""
|
"""
|
||||||
out = scene.copy()
|
out = scene.copy()
|
||||||
# Baricentro UCS in coord template (calcolato una volta dal matcher
|
|
||||||
# se disponibile): mean delle feature di una variante a 0°. Questo e'
|
|
||||||
# lo stesso baricentro mostrato nell'anteprima modello.
|
|
||||||
bary_dx = bary_dy = 0.0
|
|
||||||
if matcher is not None and matcher.variants:
|
|
||||||
# Trova variante con angle_deg piu vicino a 0
|
|
||||||
v0 = min(matcher.variants, key=lambda v: abs(v.angle_deg))
|
|
||||||
if len(v0.levels[0].dx) > 0:
|
|
||||||
bary_dx = float(np.mean(v0.levels[0].dx))
|
|
||||||
bary_dy = float(np.mean(v0.levels[0].dy))
|
|
||||||
|
|
||||||
# Lunghezza assi UCS: stessa formula dell'anteprima modello
|
# Lunghezza assi UCS: stessa formula dell'anteprima modello
|
||||||
# (0.15 * max lato template) scalata per m.scale → coerenza dimensionale.
|
# (0.15 * max lato template) scalata per m.scale → coerenza dimensionale.
|
||||||
if matcher is not None and matcher.template_size != (0, 0):
|
if matcher is not None and matcher.template_size != (0, 0):
|
||||||
@@ -161,16 +150,15 @@ def _draw_matches(scene: np.ndarray, matches: list[Match],
|
|||||||
else:
|
else:
|
||||||
L_base = 30
|
L_base = 30
|
||||||
H_scene, W_scene = scene.shape[:2]
|
H_scene, W_scene = scene.shape[:2]
|
||||||
|
|
||||||
for i, m in enumerate(matches):
|
for i, m in enumerate(matches):
|
||||||
# Proietta baricentro template alla pose del match.
|
# UCS posizionato esattamente sul CENTRO POSE del match (m.cx, m.cy):
|
||||||
# cv2.getRotationMatrix2D con angle positivo applica:
|
# equivale al centro template traslato alla scena, ruotato con
|
||||||
# new_x = cos*x + sin*y new_y = -sin*x + cos*y
|
# m.angle_deg. Coerente con UCS dell'anteprima modello che ora
|
||||||
# Visivamente in image y-down e' rotazione anti-clockwise.
|
# e' anche sul centro ROI (vedi preview_edges).
|
||||||
ax = np.deg2rad(m.angle_deg)
|
ax = np.deg2rad(m.angle_deg)
|
||||||
ca, sa = np.cos(ax), np.sin(ax)
|
ca, sa = np.cos(ax), np.sin(ax)
|
||||||
bx_scene = m.cx + (bary_dx * ca + bary_dy * sa) * m.scale
|
cx, cy = int(round(m.cx)), int(round(m.cy))
|
||||||
by_scene = m.cy + (-bary_dx * sa + bary_dy * ca) * m.scale
|
|
||||||
cx, cy = int(round(bx_scene)), int(round(by_scene))
|
|
||||||
# Overlay edge del modello orientato (richiesta utente):
|
# Overlay edge del modello orientato (richiesta utente):
|
||||||
# warpa template alla pose, applica hysteresis identica al matcher,
|
# warpa template alla pose, applica hysteresis identica al matcher,
|
||||||
# disegna pixel edge come overlay verde tenue.
|
# disegna pixel edge come overlay verde tenue.
|
||||||
@@ -763,26 +751,23 @@ def preview_edges(p: EdgePreviewParams):
|
|||||||
b = int(fb[i])
|
b = int(fb[i])
|
||||||
col = bin_colors[b % len(bin_colors)]
|
col = bin_colors[b % len(bin_colors)]
|
||||||
cv2.circle(out, (int(fx[i]), int(fy[i])), 2, col, -1, cv2.LINE_AA)
|
cv2.circle(out, (int(fx[i]), int(fy[i])), 2, col, -1, cv2.LINE_AA)
|
||||||
# UCS sul baricentro feature (richiesta utente): assi X rosso, Y verde
|
# UCS sul CENTRO ROI (coerente con _draw_matches che usa centro pose).
|
||||||
bary_cx = bary_cy = None
|
# In questo modo l'UCS visualizzato nel modello = UCS del match (modulo
|
||||||
if len(fx) > 0:
|
# rotazione/traslazione data dalla pose del pezzo trovato).
|
||||||
bary_cx = float(np.mean(fx))
|
rh, rw = roi_img.shape[:2]
|
||||||
bary_cy = float(np.mean(fy))
|
bx, by = (rw - 1) // 2, (rh - 1) // 2
|
||||||
bx, by = int(round(bary_cx)), int(round(bary_cy))
|
axis_len = max(20, int(0.15 * max(rw, rh)))
|
||||||
axis_len = max(20, int(0.15 * max(out.shape[:2])))
|
cv2.arrowedLine(out, (bx, by), (bx + axis_len, by),
|
||||||
# X axis (rosso, verso destra)
|
(0, 0, 255), 2, cv2.LINE_AA, tipLength=0.2)
|
||||||
cv2.arrowedLine(out, (bx, by), (bx + axis_len, by),
|
cv2.putText(out, "X", (bx + axis_len + 4, by + 5),
|
||||||
(0, 0, 255), 2, cv2.LINE_AA, tipLength=0.2)
|
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
|
||||||
cv2.putText(out, "X", (bx + axis_len + 4, by + 5),
|
cv2.arrowedLine(out, (bx, by), (bx, by + axis_len),
|
||||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
|
(0, 255, 0), 2, cv2.LINE_AA, tipLength=0.2)
|
||||||
# Y axis (verde, verso il basso = convenzione image y-down)
|
cv2.putText(out, "Y", (bx + 4, by + axis_len + 12),
|
||||||
cv2.arrowedLine(out, (bx, by), (bx, by + axis_len),
|
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1, cv2.LINE_AA)
|
||||||
(0, 255, 0), 2, cv2.LINE_AA, tipLength=0.2)
|
cv2.circle(out, (bx, by), 4, (0, 0, 0), -1, cv2.LINE_AA)
|
||||||
cv2.putText(out, "Y", (bx + 4, by + axis_len + 12),
|
cv2.circle(out, (bx, by), 3, (255, 255, 255), -1, cv2.LINE_AA)
|
||||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1, cv2.LINE_AA)
|
bary_cx, bary_cy = float(bx), float(by)
|
||||||
# Origine: cerchio bianco con bordo nero
|
|
||||||
cv2.circle(out, (bx, by), 4, (0, 0, 0), -1, cv2.LINE_AA)
|
|
||||||
cv2.circle(out, (bx, by), 3, (255, 255, 255), -1, cv2.LINE_AA)
|
|
||||||
img_id = _store_image(out)
|
img_id = _store_image(out)
|
||||||
n_edge_strong = int((mag >= m.strong_grad).sum())
|
n_edge_strong = int((mag >= m.strong_grad).sum())
|
||||||
n_edge_total = int(edge_mask.sum() / 255)
|
n_edge_total = int(edge_mask.sum() / 255)
|
||||||
|
|||||||
Reference in New Issue
Block a user