Compare commits
2 Commits
5f0c4542d3
...
e1ed9206a3
| Author | SHA1 | Date | |
|---|---|---|---|
| e1ed9206a3 | |||
| e84ae199ac |
+39
-13
@@ -154,29 +154,55 @@ def _draw_matches(scene: np.ndarray, matches: list[Match],
|
|||||||
bary_dx = float(np.mean(v0.levels[0].dx))
|
bary_dx = float(np.mean(v0.levels[0].dx))
|
||||||
bary_dy = float(np.mean(v0.levels[0].dy))
|
bary_dy = float(np.mean(v0.levels[0].dy))
|
||||||
|
|
||||||
|
# Lunghezza assi UCS: stessa formula dell'anteprima modello
|
||||||
|
# (0.15 * max lato template) scalata per m.scale → coerenza dimensionale.
|
||||||
|
if matcher is not None and matcher.template_size != (0, 0):
|
||||||
|
L_base = int(0.15 * max(matcher.template_size))
|
||||||
|
else:
|
||||||
|
L_base = 30
|
||||||
|
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
|
# Proietta baricentro template alla pose del match.
|
||||||
# (delta-rotation rispetto alla variante a 0)
|
# cv2.getRotationMatrix2D con angle positivo applica:
|
||||||
|
# new_x = cos*x + sin*y new_y = -sin*x + cos*y
|
||||||
|
# Visivamente in image y-down e' rotazione anti-clockwise.
|
||||||
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
|
bx_scene = m.cx + (bary_dx * ca + bary_dy * sa) * m.scale
|
||||||
by_scene = m.cy + (-bary_dx * sa + bary_dy * ca) * m.scale
|
by_scene = m.cy + (-bary_dx * sa + bary_dy * ca) * m.scale
|
||||||
cx, cy = int(round(bx_scene)), int(round(by_scene))
|
cx, cy = int(round(bx_scene)), int(round(by_scene))
|
||||||
# Lunghezza assi: 30% del lato bbox per essere visibile e scalato
|
# Overlay edge del modello orientato (richiesta utente):
|
||||||
if m.bbox_poly is not None and len(m.bbox_poly) >= 2:
|
# warpa template alla pose, applica hysteresis identica al matcher,
|
||||||
L = int(np.linalg.norm(m.bbox_poly[1] - m.bbox_poly[0]) * 0.4)
|
# disegna pixel edge come overlay verde tenue.
|
||||||
else:
|
if template_gray is not None and matcher is not None:
|
||||||
L = 40
|
t = template_gray
|
||||||
L = max(20, L)
|
th, tw = t.shape
|
||||||
# X axis (rosso) ruotato secondo angle del match
|
cx_t = (tw - 1) / 2.0; cy_t = (th - 1) / 2.0
|
||||||
x_end = (int(cx + L * np.cos(ax)), int(cy - L * np.sin(ax)))
|
M = cv2.getRotationMatrix2D((cx_t, cy_t), m.angle_deg, m.scale)
|
||||||
|
M[0, 2] += m.cx - cx_t
|
||||||
|
M[1, 2] += m.cy - cy_t
|
||||||
|
warped_gray = cv2.warpAffine(
|
||||||
|
t, M, (W_scene, H_scene),
|
||||||
|
flags=cv2.INTER_LINEAR, borderValue=0)
|
||||||
|
mag, _ = matcher._gradient(warped_gray)
|
||||||
|
if matcher.weak_grad < matcher.strong_grad:
|
||||||
|
edge_mask = matcher._hysteresis_mask(mag)
|
||||||
|
else:
|
||||||
|
edge_mask = mag >= matcher.strong_grad
|
||||||
|
if edge_mask.any():
|
||||||
|
edge_overlay = np.zeros_like(out)
|
||||||
|
edge_overlay[edge_mask] = (0, 220, 0) # verde brillante
|
||||||
|
out = cv2.addWeighted(out, 1.0, edge_overlay, 0.6, 0)
|
||||||
|
L = max(20, int(L_base * m.scale))
|
||||||
|
# X axis = rotazione di (1, 0) con cv2 matrix → (cos, -sin)
|
||||||
|
x_end = (int(cx + L * ca), int(cy - L * sa))
|
||||||
|
# Y axis = rotazione di (0, 1) con cv2 matrix → (sin, cos)
|
||||||
|
# A m.angle_deg=0 deve puntare GIU' (image y-down convenzione modello)
|
||||||
|
y_end = (int(cx + L * sa), int(cy + L * ca))
|
||||||
cv2.arrowedLine(out, (cx, cy), x_end,
|
cv2.arrowedLine(out, (cx, cy), x_end,
|
||||||
(0, 0, 255), 2, cv2.LINE_AA, tipLength=0.2)
|
(0, 0, 255), 2, cv2.LINE_AA, tipLength=0.2)
|
||||||
cv2.putText(out, "X", (x_end[0] + 4, x_end[1] + 5),
|
cv2.putText(out, "X", (x_end[0] + 4, x_end[1] + 5),
|
||||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
|
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
|
||||||
# Y axis (verde) perpendicolare; +90° in image coords = giu' visivo
|
|
||||||
y_end = (int(cx + L * np.cos(ax + np.pi / 2)),
|
|
||||||
int(cy - L * np.sin(ax + np.pi / 2)))
|
|
||||||
cv2.arrowedLine(out, (cx, cy), y_end,
|
cv2.arrowedLine(out, (cx, cy), y_end,
|
||||||
(0, 255, 0), 2, cv2.LINE_AA, tipLength=0.2)
|
(0, 255, 0), 2, cv2.LINE_AA, tipLength=0.2)
|
||||||
cv2.putText(out, "Y", (y_end[0] + 4, y_end[1] + 12),
|
cv2.putText(out, "Y", (y_end[0] + 4, y_end[1] + 12),
|
||||||
|
|||||||
Reference in New Issue
Block a user