首页 > 编程语言 >根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现

根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现

时间:2024-11-22 20:49:28浏览次数:3  
标签:欧拉角 矩阵 旋转 RM np theta

文章目录

相机标定过程中,我们会得到一个3x3旋转矩阵,下面是我们把旋转矩阵欧拉角之间的相互转换:

1 旋转矩阵转换为欧拉角(Euler Angles)

1、旋转矩阵是一个3x3的矩阵,如下:

R = ( r 11 r 12 r 13 r 21 r 22 r 23 r 31 r 32 r 33 ) R=\left(\begin{array}{ccc} r_{11} & r_{12} & r_{13} \\ r_{21} & r_{22} & r_{23} \\ r_{31} & r_{32} & r_{33} \end{array}\right) R=⎝⎛​r11​r21​r31​​r12​r22​r32​​r13​r23​r33​​⎠⎞​

刚体旋转的旋转矩阵是由三个基本旋转矩阵复合而成的。

2、欧拉角(Euler Angles)

欧拉角来描述刚体在三维欧几里得空间取向

3、旋转矩阵转换为欧拉角的公式:

  • Z轴对应的欧拉角

θ z = arctan ⁡ 2 ( − r 31 , r 11 ) \theta_{z}=\arctan 2\left(-r_{31}, r_{11}\right) θz​=arctan2(−r31​,r11​)

  • Y轴对应的欧拉角

θ y = arctan ⁡ 2 ( − r 31 , r 31 2 + r 33 2 ) \theta_{y}=\arctan 2\left(-r_{31}, \sqrt{r_{31}{ }^{2}+r_{33}{ }^{2}}\right) θy​=arctan2(−r31​,r31​2+r33​2 ​)

  • X轴对应的欧拉角

θ x = arctan ⁡ 2 ( − r 32 , r 33 ) \theta_{x}=\arctan 2\left(-r_{32}, r_{33}\right) θx​=arctan2(−r32​,r33​)

注意:

上面公式计算测的欧拉角是弧度制

上面公式的意思是,相机坐标系想要转到与世界坐标系完全平行(即 x c x_c xc​平行于 x w x_w xw​, y c y_c yc​平行于 y w y_w yw​, z c z_c zc​平行于 z w z_w zw​,且他们的方向都是相同的),需要旋转3次,设原始相机坐标系C0

  • 1、C0绕其z轴旋转,得到新的坐标系C1;

  • 2、C1绕其y轴旋转,得到新的坐标系C2(注意旋转轴为C1的y轴,而非C0的y轴);

  • 3、C2绕其x轴旋转,得到新的坐标系C3。此时C3与世界坐标系W完全平行。

特别注意:旋转顺序为z y x,切记不能调换

在这里插入图片描述

4、python实现:旋转矩阵转换为欧拉角

import numpy as np

rotate_matrix = [[-0.0174524064372832, -0.999847695156391, 0.0],
                 [0.308969929589947, -0.00539309018185907, -0.951056516295153],
                 [0.950911665781176, -0.0165982248672099, 0.309016994374948]]

RM = np.array(rotate_matrix)


# 旋转矩阵到欧拉角(弧度值)
def rotateMatrixToEulerAngles(R):
    theta_z = np.arctan2(RM[1, 0], RM[0, 0])
    theta_y = np.arctan2(-1 * RM[2, 0], np.sqrt(RM[2, 1] * RM[2, 1] + RM[2, 2] * RM[2, 2]))
    theta_x = np.arctan2(RM[2, 1], RM[2, 2])
    print(f"Euler angles:\ntheta_x: {theta_x}\ntheta_y: {theta_y}\ntheta_z: {theta_z}")
    return theta_x, theta_y, theta_z

# 旋转矩阵到欧拉角(角度制)
def rotateMatrixToEulerAngles2(R):
    theta_z = np.arctan2(RM[1, 0], RM[0, 0]) / np.pi * 180
    theta_y = np.arctan2(-1 * RM[2, 0], np.sqrt(RM[2, 1] * RM[2, 1] + RM[2, 2] * RM[2, 2])) / np.pi * 180
    theta_x = np.arctan2(RM[2, 1], RM[2, 2]) / np.pi * 180
    print(f"Euler angles:\ntheta_x: {theta_x}\ntheta_y: {theta_y}\ntheta_z: {theta_z}")
    return theta_x, theta_y, theta_z



if __name__ == '__main__':
    rotateMatrixToEulerAngles(RM)
    rotateMatrixToEulerAngles2(RM)

输出结果如下:

Euler angles:
theta_x: -0.05366141770874149
theta_y: -1.2561686529408898
theta_z: 1.6272221428848495
Euler angles:
theta_x: -3.0745727573994635
theta_y: -71.97316217014685
theta_z: 93.23296111753567

5、C++实现:旋转矩阵转换为欧拉角


//计算出相机坐标系的三轴旋转欧拉角,旋转后可以转出世界坐标系。
//旋转顺序为z、y、x
const double PI = 3.141592653;
double thetaz = atan2(r21, r11) / PI * 180;
double thetay = atan2(-1 * r31, sqrt(r32*r32 + r33*r33)) / PI * 180;
double thetax = atan2(r32, r33) / PI * 180;

2 欧拉角转换为旋转矩阵

欧拉角转换为旋转矩阵,就是沿XYZ三个轴进行旋转,参考旋转矩阵

1、利用上面生成的弧度值的欧拉角,再转换为旋转矩阵

# 欧拉角转换为旋转矩阵
# 输入为欧拉角为 弧度制
# euler_angles = [-0.05366141770874149, -1.2561686529408898, 1.6272221428848495]
def eulerAnglesToRotationMatrix(theta):
    R_x = np.array([[1, 0, 0],
                    [0, np.cos(theta[0]), -np.sin(theta[0])],
                    [0, np.sin(theta[0]), np.cos(theta[0])]
                    ])

    R_y = np.array([[np.cos(theta[1]), 0, np.sin(theta[1])],
                    [0, 1, 0],
                    [-np.sin(theta[1]), 0, np.cos(theta[1])]
                    ])

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

    R = np.dot(R_z, np.dot(R_y, R_x))
    print(f"Rotate matrix:\n{R}")
    return R

if __name__ == '__main__':
    euler_angles = [-0.05366141770874149, -1.2561686529408898, 1.6272221428848495]
    eulerAnglesToRotationMatrix(euler_angles)

输出结果:

Rotate matrix:
[[-1.74524064e-02 -9.99847695e-01 -7.38075162e-16]
 [ 3.08969930e-01 -5.39309018e-03 -9.51056516e-01]
 [ 9.50911666e-01 -1.65982249e-02  3.09016994e-01]]

参考:https://www.cnblogs.com/singlex/p/RotateMatrix2Euler.html
参考:https://zhuanlan.zhihu.com/p/259999988
参考:https://blog.csdn.net/qq_15642411/article/details/83583695

标签:欧拉角,矩阵,旋转,RM,np,theta
From: https://blog.csdn.net/2401_88244350/article/details/143888433

相关文章

  • Java旋转算法Collections.rotate
    Java旋转算法Collections.rotatepackagecom.example.core.mydemo.javaDemo;importjava.util.ArrayList;importjava.util.Collections;/***原始集合:[1,2,3,4,5]*旋转后的集合:[4,5,1,2,3]*/publicclassRotateExample{publicstaticvoidmain(St......
  • 【51单片机】程序实验5&6.独立按键-矩阵按键
    主要参考学习资料:B站【普中官方】51单片机手把手教学视频前置知识:C语言单片机套装:普中STC51单片机开发板A4标准版套餐7码字不易,求点赞收藏加关注(´•ω•̥`)有问题欢迎评论区讨论~目录独立按键按键介绍实验5独立按键矩阵按键矩阵按键介绍实验6-1行列式扫描实......
  • 【每日一题】3248. 矩阵中的蛇
    大小为 nxn 的矩阵 grid 中有一条蛇。蛇可以朝 四个可能的方向 移动。矩阵中的每个单元格都使用位置进行标识: grid[i][j]=(i*n)+j。蛇从单元格0开始,并遵循一系列命令移动。给你一个整数 n 表示 grid 的大小,另给你一个字符串数组 commands,其中包括 "UP"......
  • C++:探索AVL树旋转的奥秘
    文章目录前言AVL树为什么要旋转?一、插入一个值的大概过程1.插入一个值的大致过程2.平衡因子更新原则3.旋转处理的目的二、左单旋1.左单旋旋转方式总处理图2.左单旋具体会遇到的情况3.左单旋代码总结三、右单旋1.右单旋旋转方式总处理图2.右单旋具体会遇到的......
  • SS241121B. Soso 的模法矩阵(modmat)
    SS241121B.Soso的模法矩阵(modmat)题意给你长度为\(n\)的\(\{a_i\}\),长度为\(m\)的\(\{b_i\}\),设\(a_i'=\prod_{j=1}^ia_i,b_i'=\prod_{j=1}^ib_i\),对所有\(i\in[1,n],j\in[1,m]\),求\[(a_i'\bmodb_j')\bmod998244353......
  • 2536. 子矩阵元素加1
    2536.子矩阵元素加1classSolution{public:vector<vector<int>>rangeAddQueries(intn,vector<vector<int>>&queries){vector<vector<int>>dif(n+5,vector<int>(n+5,0));for(inti=0;i<q......
  • 元素和小于k的子矩阵数目
    https://leetcode.cn/problems/count-submatrices-with-top-left-element-and-sum-less-than-k/description/intcountSubmatrices(int**grid,intgridSize,int*gridColSize,intk){intx=gridSize,y=*gridColSize;inta[x][y];memset(a,0,sizeof(a));intcount=......
  • 人工智能之机器学习线代基础——矩阵分类
    1.按维度和大小 方阵(SquareMatrix): 行数和列数相等的矩阵。 列矩阵(ColumnMatrix): 只有一列的矩阵。 行矩阵(RowMatrix): 只有一行的矩阵。 零矩阵(ZeroMatrix): 所有元素均为0。 单位矩阵(IdentityMatrix): 对角线为1,其他元素为0的方阵。 对角矩......
  • 如何在Linux系统实现屏幕旋转?触觉智能RK3568鸿蒙开发板演示
    本文介绍Linux系统实现屏幕角度旋转的方法,以解决不同产品形态的展现方式,其中Ubuntu、Debian系统可以通过xrandr工具实现屏幕旋转。使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568芯片,搭载四核A55处理器,主频2.0Ghz;1T算力NPU;现已发布全新OpenHarmony5.0Release固件。Linux旋......
  • 字节青训-判断数组是否单调、判断回旋镖的存在、字符串解码问题、小F的矩阵值调整、数
    目录一、判断数组是否单调问题描述测试样例解题思路:解题思路数据结构选择算法步骤 最终代码:运行结果:​编辑  二、判断回旋镖的存在问题描述测试样例解题思路: 解题思路算法步骤最终代码:运行结果:​编辑 三、字符串解码问题问题描述测试样例 解题思......