OpenCV分解投影矩阵欧拉角方向错误?

时间:2019-01-23 22:53:13

标签: python opencv computer-vision

情况:我正在尝试估算头部姿势。我已经校准了相机并获得了相机矩阵。我有一个与图像点相对应的3D模型。我找到姿势并获得旋转和平移矢量:

_, rvec, tvec = cv2.solvePnP(model_points, image_points, camera_matrix, dist_coeffs, flags=...)

然后我从旋转矢量获得旋转矩阵:

rotation_matrix, _ = cv2.Rodrigues(rvec)

现在,我决定看一下欧拉角。我创建投影矩阵如下:

projection_matrix = camera_matrix.dot(np.hstack((rotation_matrix, tvec)))

所以我的投影矩阵现在是3x4。然后我得到了欧拉角:

angles = cv2.decomposeProjectionMatrix(projection_matrix)[-1]

问题::我在这篇文章(Python Opencv SolvePnP yields wrong translation vector)中找到了另一种获取欧拉角的方法,据作者所述,该方法应得到与我的角度相同的结果(确实如此)为他们):

 y_rot = math.asin(rotation_matrix[2][0])
 x_rot = math.acos(rotation_matrix[2][2]/math.cos(y_rot))
 z_rot = math.acos(rotation_matrix[0][0]/math.cos(y_rot))
 y_rot_angle = y_rot *(180/3.1415)
 x_rot_angle = x_rot *(180/3.1415)
 z_rot_angle = z_rot *(180/3.1415)

我从分解投影矩阵中得到的角度是:

[164.17979619 19.45087415 1.95279565]

此其他解决方案提供的内容:

[164.18463841290048, -19.451447820154847, 1.9528532437807946]

标量值相同,但是y角旋转的方向不同。我在想-也许我误会了什么?

1 个答案:

答案 0 :(得分:1)

我不确切知道从矩阵中获得euangle的实现是哪种排列,但是它与decomposeProjectionMatrix所使用的不同。 这就是角度不同的原因。

如前所述,欧拉角始终取决于顺序。有12种不同的排列。有关更多信息,请参见Euler Angles

opencv的decomposeProjectionMatrix使用“ XYZ”顺序表示欧拉角。

pypi上有不同的旋转库。我在本示例中使用transforms3d。 我正在手动设置输入参数,并通过transforms3d软件包的euler2mat函数设置旋转矩阵。 我使用XYZ约定创建一个Rotation矩阵,例如横滚角(X):90°,俯仰(Y):45°,横摆(X):180°

from transforms3d import euler
from math import pi,radians
rotation_matrix = euler.euler2mat(radians(90), radians(45), 
    radians(180), 'sxyz')
tvec = np.zeros(3).reshape(1,3).T
camera_matrix = np.array([[1500,0,320],[0,1500,256],[0,0,1]])
projection_matrix = camera_matrix.dot(np.hstack((rotation_matrix, tvec)))
rot = cv2.decomposeProjectionMatrix(projection_matrix)

rotation_matrix(输入)和rot [1](输出)是相同的(但仅具有正确的欧拉阶“ sxyz”):

array([[-7.07106781e-01, -7.07106781e-01,  7.91668771e-17],
   [ 8.65956056e-17,  2.53632657e-17,  1.00000000e+00],
   [-7.07106781e-01,  7.07106781e-01,  4.32978028e-17]])

rot [-1]是:

[[90.         ]
 [ 45.        ]
 [ 180.        ]]

3d旋转还有更多陷阱。例如。