将旋转矩阵转换为欧拉角并返回 - 特殊情况?

8
我正在对一个旋转矩阵进行分解为欧拉角(Tait-Bryan角度,具体顺序为x-y-z,即先绕x轴旋转),然后再转回旋转矩阵。我使用了transforms3d Python库 (https://github.com/matthew-brett/transforms3d),并且遵循了这个教程:www.gregslabaugh.net/publications/euler.pdf,两者都给出了相同的结果。
问题在于重新组装的旋转矩阵与我最初使用的不一致。
我正在处理的矩阵是通过openCV的“decomposeHomographyMat”函数创建的,因此我希望它是有效的旋转矩阵。也许这是一个特殊情况呢? 该矩阵是: 三个角度分别为[-1.8710997, 0.04623301, -0.03679793]。如果我将它们转换回旋转矩阵,得到的结果是:

其中 R_23 不能是一个舍入误差。

根据上述论文,绕 y 轴(β)的旋转可以通过 asin(-R_31) 计算。另一个有效角度是 pi-asin(-R_31)。 绕 x 轴(α)的角度可以通过 atan2(R_32,R_33) 计算。我也可以通过 asin(R_32/cos(beta)) 或 acos(R_33/cos(beta)) 得到 α。如果使用后两个方程,只有在使用 beta = pi-arcsin(-R_31) 时才会得到相同的 alpha 结果,这意味着 beta 只有一个有效解。atan2(R_32,R_33) 与两者都不同。

总之,我的矩阵似乎有问题,或者我无法弄清楚为什么分解不起作用。

import numpy as np

def rot2eul(R):
    beta = -np.arcsin(R[2,0])
    alpha = np.arctan2(R[2,1]/np.cos(beta),R[2,2]/np.cos(beta))
    gamma = np.arctan2(R[1,0]/np.cos(beta),R[0,0]/np.cos(beta))
    return np.array((alpha, beta, gamma))

def eul2rot(theta) :

    R = np.array([[np.cos(theta[1])*np.cos(theta[2]),       np.sin(theta[0])*np.sin(theta[1])*np.cos(theta[2]) - np.sin(theta[2])*np.cos(theta[0]),      np.sin(theta[1])*np.cos(theta[0])*np.cos(theta[2]) + np.sin(theta[0])*np.sin(theta[2])],
                  [np.sin(theta[2])*np.cos(theta[1]),       np.sin(theta[0])*np.sin(theta[1])*np.sin(theta[2]) + np.cos(theta[0])*np.cos(theta[2]),      np.sin(theta[1])*np.sin(theta[2])*np.cos(theta[0]) - np.sin(theta[0])*np.cos(theta[2])],
                  [-np.sin(theta[1]),                        np.sin(theta[0])*np.cos(theta[1]),                                                           np.cos(theta[0])*np.cos(theta[1])]])

    return R


R = np.array([[ 0.9982552 , -0.03323557, -0.04880523],
       [-0.03675031,  0.29723396, -0.95409716],
       [-0.04621654, -0.95422606, -0.29549393]])

ang = rot2eul(R)
eul2rot(ang)

import transforms3d.euler as eul
ang = eul.mat2euler(R, axes='sxyz')
eul.euler2mat(ang[0], ang[1], ang[2], axes='sxyz')
2个回答

5

4
也许您可以使用scipy。
from scipy.spatial.transform import Rotation   

### first transform the matrix to euler angles
r =  Rotation.from_matrix(rotation_matrix)
angles = r.as_euler("zyx",degrees=True)

#### Modify the angles
print(angles)
angles[0] += 5

#### Then transform the new angles to rotation matrix again
r = Rotation.from_euler("zyx",angles,degrees=True)
new_rotation_matrix = new_r.as_matrix()

我认为 r = Rotation.from_euler("zyx",angles,degrees=True) 应该改为 new_r = Rotation.from_euler("zyx",angles,degrees=True)。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接