You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模型测试阶段:如何从四元数(Quaternion)计算欧拉角?

从批量四元数计算欧拉角的实现方案

针对你的需求,提供两种可行的实现方式,均适配PyTorch批量张量(包括CUDA张量),且与你参考的旋转矩阵转欧拉角逻辑对齐:


方法1:四元数转旋转矩阵再复用现有欧拉角转换代码

先将批量四元数转换为旋转矩阵,再调用你参考的旋转矩阵转欧拉角函数计算结果,步骤如下:

批量四元数转旋转矩阵代码

import torch

def quat_to_rotmat(quats):
    # 输入:quats 形状为 Bx4,四元数顺序为 [x, y, z, w]
    x, y, z, w = quats[:, 0], quats[:, 1], quats[:, 2], quats[:, 3]
    batch_size = quats.shape[0]
    
    # 预计算元素项
    xx, yy, zz = x*x, y*y, z*z
    xy, xz, yz = x*y, x*z, y*z
    xw, yw, zw = x*w, y*w, z*w
    
    # 构造旋转矩阵
    rotmat = torch.zeros(batch_size, 3, 3, device=quats.device)
    rotmat[:, 0, 0] = 1 - 2*(yy + zz)
    rotmat[:, 0, 1] = 2*(xy - zw)
    rotmat[:, 0, 2] = 2*(xz + yw)
    
    rotmat[:, 1, 0] = 2*(xy + zw)
    rotmat[:, 1, 1] = 1 - 2*(xx + zz)
    rotmat[:, 1, 2] = 2*(yz - xw)
    
    rotmat[:, 2, 0] = 2*(xz - yw)
    rotmat[:, 2, 1] = 2*(yz + xw)
    rotmat[:, 2, 2] = 1 - 2*(xx + yy)
    
    return rotmat

使用示例

# 你的批量四元数输入
quats = torch.tensor([[ 0.0725, -0.0645,  0.0308,  0.9948],
                      [-0.5235, -0.2456,  0.0824,  0.8117]], device='cuda:0')

# 转旋转矩阵
rotmats = quat_to_rotmat(quats)
# 调用你参考的旋转矩阵转欧拉角函数
euler_angles = compute_euler_angles_from_rotation_matrices(rotmats)

方法2:直接从四元数计算欧拉角

跳过旋转矩阵转换步骤,直接通过公式计算Z-Y-X顺序(对应yaw-pitch-roll)的欧拉角,与你参考的旋转矩阵转换逻辑完全对齐:

批量四元数转欧拉角代码

import torch

def quat_to_euler(quats):
    # 输入:quats 形状为 Bx4,四元数顺序为 [x, y, z, w]
    # 输出:euler_angles 形状为 Bx3,欧拉角顺序为 [yaw, pitch, roll],单位为弧度
    x, y, z, w = quats[:, 0], quats[:, 1], quats[:, 2], quats[:, 3]
    
    # 计算roll(X轴旋转)
    sinr_cosp = 2 * (w * x + y * z)
    cosr_cosp = 1 - 2 * (x*x + y*y)
    roll = torch.atan2(sinr_cosp, cosr_cosp)
    
    # 计算pitch(Y轴旋转),处理数值稳定性避免asin输入越界
    sinp = 2 * (w * y - z * x)
    sinp = torch.clamp(sinp, -1.0, 1.0)
    pitch = torch.asin(sinp)
    
    # 计算yaw(Z轴旋转)
    siny_cosp = 2 * (w * z + x * y)
    cosy_cosp = 1 - 2 * (y*y + z*z)
    yaw = torch.atan2(siny_cosp, cosy_cosp)
    
    # 组合结果
    euler_angles = torch.stack([yaw, pitch, roll], dim=1)
    return euler_angles

使用示例

# 你的批量四元数输入
quats = torch.tensor([[ 0.0725, -0.0645,  0.0308,  0.9948],
                      [-0.5235, -0.2456,  0.0824,  0.8117]], device='cuda:0')

# 直接计算欧拉角
euler_angles = quat_to_euler(quats)

关键注意事项

  • 四元数顺序:上述代码基于你提供的[x,y,z,w]顺序编写,若你的四元数存储为[w,x,y,z],需调整代码中x/y/z/w的索引。
  • 欧拉角顺序:代码采用Z-Y-X(yaw-pitch-roll)顺序,与你参考的旋转矩阵转换逻辑一致,若需其他顺序需修改对应公式。
  • 数值稳定性:计算pitch时通过torch.clamp限制输入范围,避免浮点误差导致的计算错误。

内容的提问来源于stack exchange,提问作者Redhwan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 04:09:56