fixed: per axis Euler angles are now correct!

This commit is contained in:
2025-12-03 17:32:45 +01:00
parent e47018229f
commit facc115e30
3 changed files with 13 additions and 16 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ import math
import cv2 as cv import cv2 as cv
import numpy as np import numpy as np
from pathlib import Path from pathlib import Path
from ar_tag_pose.utils import to_board_pose_euler from ar_tag_pose.utils import to_euler
import mimetypes import mimetypes
RESULTS_FOLDER = "results" RESULTS_FOLDER = "results"
@@ -155,7 +155,7 @@ class BoardPose(abc.ABC):
success, r_vec, t_vec = self._process(img) success, r_vec, t_vec = self._process(img)
if success: if success:
r_vec_obj, _ = to_board_pose_euler(r_vec, t_vec) r_vec_obj, _ = to_euler(r_vec, t_vec)
rot = [round(180.0 / math.pi * v, 1) for v in r_vec_obj] rot = [round(180.0 / math.pi * v, 1) for v in r_vec_obj]
print("\r ", end='') print("\r ", end='')
print(f"\rTilt: {rot[0]:.1f}, Roll: {rot[1]:.1f}, Azimuth: {rot[2]:.1f}", end='') print(f"\rTilt: {rot[0]:.1f}, Roll: {rot[1]:.1f}, Azimuth: {rot[2]:.1f}", end='')
+2 -8
View File
@@ -7,7 +7,7 @@ import argparse
import mimetypes import mimetypes
import json import json
from pathlib import Path from pathlib import Path
from ar_tag_pose.utils import to_tf, to_board_pose_euler from ar_tag_pose.utils import to_tf, to_euler
from detector_board import BoardDetector from detector_board import BoardDetector
from detector_board_aruco import BoardDetectorAruco from detector_board_aruco import BoardDetectorAruco
from detector_board_charuco import BoardDetectorCharuco from detector_board_charuco import BoardDetectorCharuco
@@ -105,8 +105,6 @@ class Detector(abc.ABC):
out = None out = None
r_vec = None r_vec = None
t_vec = None t_vec = None
tvec_world = None
rvec_world = None
while cap.isOpened(): while cap.isOpened():
if self.src_images: if self.src_images:
cap.set(cv.CAP_PROP_POS_FRAMES, frame_num) cap.set(cv.CAP_PROP_POS_FRAMES, frame_num)
@@ -156,11 +154,7 @@ class Detector(abc.ABC):
for det in self.detector: for det in self.detector:
success, r_vec, t_vec = det.process(img) success, r_vec, t_vec = det.process(img)
if success: if success:
if rvec_world is not None: rot_e = to_euler(to_tf(r_vec, t_vec))
rot_e = to_board_pose_euler(to_tf(rvec_world, tvec_world), to_tf(r_vec, t_vec))
else:
rot_e = to_board_pose_euler(to_tf(r_vec, t_vec))
rot = [round(180.0 / math.pi * v, 1) for v in rot_e] rot = [round(180.0 / math.pi * v, 1) for v in rot_e]
cv.putText(img, f"{det}: Tilt: {rot[0]:.1f}, Roll: {rot[1]:.1f}, Azimuth: {rot[2]:.1f}", cv.putText(img, f"{det}: Tilt: {rot[0]:.1f}, Roll: {rot[1]:.1f}, Azimuth: {rot[2]:.1f}",
(30, y_pos), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 2) (30, y_pos), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 2)
+9 -6
View File
@@ -1,8 +1,6 @@
import numpy as np import numpy as np
import cv2 as cv import cv2 as cv
import math import math
import vg
from scipy.spatial.transform import RigidTransform as Tf
from scipy.spatial.transform import Rotation as R from scipy.spatial.transform import Rotation as R
def rotation_matrix_to_euler_angles(R: np.ndarray) -> np.ndarray: def rotation_matrix_to_euler_angles(R: np.ndarray) -> np.ndarray:
@@ -27,15 +25,20 @@ def to_tf(r_vec: np.ndarray, t_vec: np.ndarray) -> np.ndarray:
r_mat = np.vstack((r_mat, np.array([0, 0, 0, 1]))) r_mat = np.vstack((r_mat, np.array([0, 0, 0, 1])))
return r_mat return r_mat
def to_board_pose_euler(t1: np.ndarray, t2: np.ndarray | None = None) -> np.ndarray: def to_euler(t1: np.ndarray, t2: np.ndarray | None = None, euler_axis: str= "XYZ") -> np.ndarray:
# Transform t2 to t1 coordinate system
if t2 is None: if t2 is None:
tf = np.linalg.inv(t1) tf = np.linalg.inv(t1)
else: else:
tf = np.linalg.inv(t1)*t2 tf = np.linalg.inv(t1)*t2
res = np.array([0,0,0], dtype=np.float64) # Get new r_vec from Rmat = tf[0:3, 0:3]
# res = rotation_matrix_to_euler_angles(tf) r_vec = np.array([0,0,0], dtype=np.float64)
cv.Rodrigues(tf[0:3, 0:3], res) cv.Rodrigues(tf[0:3, 0:3], r_vec)
# Convert to euler angles
r = R.from_rotvec(r_vec)
res = R.as_euler(r, euler_axis)
return res return res