四元数转旋转矩阵

目录

[gsplat 四元数转旋转矩阵等同代码实现](#gsplat 四元数转旋转矩阵等同代码实现)

[scipy 四元数转旋转矩阵替换代码](#scipy 四元数转旋转矩阵替换代码)


gsplat 四元数转旋转矩阵等同代码实现

python 复制代码
import torch
import torch.nn.functional as F


def quat_act(x: torch.Tensor) -> torch.Tensor:
    return x / x.norm(dim=-1, keepdim=True)

def normalized_quat_to_rotmat(quat: torch.Tensor) -> torch.Tensor:
    # 源码来自: from gsplat.utils import normalized_quat_to_rotmat
    """Convert normalized quaternion to rotation matrix.

    Args:
        quat: Normalized quaternion in wxyz convension. (..., 4)

    Returns:
        Rotation matrix (..., 3, 3)
    """
    assert quat.shape[-1] == 4, quat.shape
    w, x, y, z = torch.unbind(quat, dim=-1)
    mat = torch.stack(
        [
            1 - 2 * (y**2 + z**2),
            2 * (x * y - w * z),
            2 * (x * z + w * y),
            2 * (x * y + w * z),
            1 - 2 * (x**2 + z**2),
            2 * (y * z - w * x),
            2 * (x * z - w * y),
            2 * (y * z + w * x),
            1 - 2 * (x**2 + y**2),
        ],
        dim=-1,
    )
    return mat.reshape(quat.shape[:-1] + (3, 3))

def quat2mat(quat):
    qw, qx, qy, qz = torch.unbind(quat, dim=-1)  # 原为wxyz
    quat_xyzw = torch.stack([qx, qy, qz, qw], dim=-1)  # 转为xyzw顺序
    # 后续代码保持原逻辑
    qx, qy, qz, qw = torch.unbind(quat_xyzw, dim=-1)

    # 计算旋转矩阵
    R00 = 1 - 2 * (qy ** 2 + qz ** 2)
    R01 = 2 * (qx * qy - qw * qz)
    R02 = 2 * (qx * qz + qw * qy)

    R10 = 2 * (qx * qy + qw * qz)
    R11 = 1 - 2 * (qx ** 2 + qz ** 2)
    R12 = 2 * (qy * qz - qw * qx)

    R20 = 2 * (qx * qz - qw * qy)
    R21 = 2 * (qy * qz + qw * qx)
    R22 = 1 - 2 * (qx ** 2 + qy ** 2)

    # 将旋转矩阵堆叠在一起
    matrix = torch.stack([R00, R01, R02, R10, R11, R12, R20, R21, R22], dim=-1)

    # 变换为 3x3 的矩阵
    return matrix.view(-1, 3, 3)

x=torch.range(0,3*4-1)

x=x.reshape(-1,4)

print(x)

# 调用 quat_act 函数进行归一化
normalized_x = quat_act(x)

aa=F.normalize(x, dim=-1)

print('diff',(normalized_x-aa).sum(dim=-1))
print("\nNormalized x:")
print(aa)  # 应该返回一个全为 1 的张量


if 1:
    mat= normalized_quat_to_rotmat(aa)
    print(mat)

    mat2=quat2mat(aa)

    print('diff2', (mat2 - mat).sum(dim=-1))

scipy 四元数转旋转矩阵替换代码

python 复制代码
import torch
from scipy.spatial.transform import Rotation as R
import torch.nn.functional as F
def quat2mat_scipy(quat):
    # 从四元数中提取 qx, qy, qz, qw
    qx, qy, qz, qw = torch.unbind(quat, dim=-1)

    # 计算旋转矩阵
    R00 = 1 - 2 * (qy ** 2 + qz ** 2)
    R01 = 2 * (qx * qy - qw * qz)
    R02 = 2 * (qx * qz + qw * qy)

    R10 = 2 * (qx * qy + qw * qz)
    R11 = 1 - 2 * (qx ** 2 + qz ** 2)
    R12 = 2 * (qy * qz - qw * qx)

    R20 = 2 * (qx * qz - qw * qy)
    R21 = 2 * (qy * qz + qw * qx)
    R22 = 1 - 2 * (qx ** 2 + qy ** 2)

    # 将旋转矩阵堆叠在一起
    matrix = torch.stack([R00, R01, R02, R10, R11, R12, R20, R21, R22], dim=-1)

    # 变换为 3x3 的矩阵
    return matrix.view(-1, 3, 3)

if 1:
    x = torch.range(0, 3 * 4 - 1)

    x = x.reshape(-1, 4)

    aa = F.normalize(x, dim=-1)
    r = R.from_quat(aa.numpy())
    mat3= r.as_matrix()

    mat4=quat2mat_scipy(aa)
    print('diff3', (mat4.numpy() - mat3).sum(axis=-1))
相关推荐
fthux11 小时前
装闭 RenoPit 源码解析(07):装修闭坑知识库与AI Prompt构建
人工智能·ai·开源·github·open source·renopit
zyplayer-doc13 小时前
VuePress类静态文档站和动态知识库怎么选:两种技术路线的适用场景
javascript·人工智能·后端·安全·智能手机
leisoo809713 小时前
100GBA股股票数据怎么存ClickHouseRedisMySQLJSON完整对比
大数据·linux·服务器·开发语言·python
KKKlucifer14 小时前
拨开接口黑盒迷雾:运营商第三方合作接口安全审计与准入管控落地实践
网络·人工智能·安全
WangYan202214 小时前
基于XGBoost与AI的生态—地学多源数据建模:植被与土地利用识别、土壤碳氮空间预测、生物多样性驱动机制、土壤微生物功能预测、生态退化与风险识别
python·机器学习·xgboost
梦梦代码精14 小时前
连锁品牌数字化:从门店扩张到用户资产运营的技术底座
大数据·人工智能·低代码·docker·开源·代码规范
咕噜咕噜啦啦14 小时前
vLLM框架
人工智能·qwen·vllm
启雀AI14 小时前
AI 驱动的视频课程自动摘要与知识点提取:ASR + LLM 流水线工程实践
人工智能·阿里云·华为云·音视频·培训saas平台
Mac的实验室14 小时前
2026年8月最新实操:谷歌Gmail邮箱手机号注册扫码发短信提示“无法验证”怎么办?(附100%成功绕过指南)
人工智能