三维坐标变换(旋转矩阵&旋转向量)

本文探讨了三维坐标变换中旋转矩阵的不便之处,并介绍了旋转向量的概念,旋转向量能更直观地表示旋转方向和角度。通过Rodrigues公式,解释了旋转向量与旋转矩阵之间的相互转换,指出旋转向量在opencv等库中的应用及其在3D几何优化中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

矩阵运算显然是计算机三维坐标变换最简单方便的计算方法,因此在 opencv、opengl、工业机器人等开发中,提到位姿旋转变换,多半用的是旋转矩阵。然而,用矩阵来表示一个旋转关系有两个缺点

首先,通过旋转矩阵不能直观地看出旋转的方向和角度,假设给定一个旋转矩阵,要求旋转方向不变,旋转角度变成一半,那么新的旋转矩阵计算起来就比较麻烦了。
另一方面,旋转变换本身只有3个自由度,但旋转矩阵有9个元素,因此旋转矩阵中的元素不是相互独立的,这在非线性优化中会带来问题。

用 opencv 进行过双目相机标定的同学都知道,单目标定 calibrateCamera() 函数能够对每一张标定图像计算出一对 rvec和 tvec,即旋转平移向量,代表世界坐标系到相机坐标系的转换关系。而 stereoCalibrate() 函数则可以计算出旋转矩阵 R 和平移向量 T,代表左右相机坐标系之间的转换关系。

旋转向量

向量旋转公式最早由 Rodrigues 提出,用一个三维向量来表示三维旋转变换,该向量的方向是旋转轴,其模则是旋转角度。

设旋转向量的单位向量为 r,模为 θ。三维点(或者说三维向量) p p p 在旋转向量 r r r 的作用下变换至 p ′ p′ p,则:
在这里插入图片描述

相互转换

转换可以参考半闲居士博客

opencv 中有函数 Rodrigues() 用于旋转矩阵和旋转向量的转换。参照opencv文档,设旋转向量的单位向量 r = [ r x   r y   r z ] T r=[r_x\ r_y\ r_z]^T r=[rx ry rz]T,旋转角度为 θ θ θ,对应的旋转矩阵为 R R R,则 r r r R R R 的转换是:
在这里插入图片描述
旋转矩阵到旋转向量的转换过程如下:
[公式]
可得转角 θ θ θ
[公式]
对于旋转向量的单位向量 r r r ,旋转轴上的向量在旋转后不发生改变。因此, r r r 是矩阵 R R R 特征值 1 对应的特征向量。


opencv 官方文档中的原话是:

A rotation vector is a convenient and most compact representation of a rotation matrix (since any rotation matrix has just 3 degrees of freedom). The representation is used in the global 3D geometry optimization procedures like calibrateCamera, stereoCalibrate, or solvePnP .

称旋转向量是旋转矩阵方便而且最紧凑的表示方法,被用于一些需要全局三维几何优化的函数中。

### Matlab 中实现三维坐标变换旋转矩阵 在Matlab中,可以通过定义旋转矩阵来完成三维坐标的旋转变换。对于给定的角度θ以及指定的旋转轴,可以构建相应的旋转矩阵并应用到目标向量上。 #### 定义旋转矩阵 当已知旋转角度`theta`(以弧度为单位)和平行于某条直线的方向矢量作为旋转轴时,可按照罗德里格斯公式构造旋转矩阵R: \[ R = I + \sin(\theta)K+(1-\cos(\theta))K^{2} \] 其中I表示单位阵;\( K=[k_{ij}] \),其元素由旋转轴上的单位向量u=(ux,uy,uz)决定: \[ K=\left[\begin{array}{ccc} 0 & -u_z & u_y \\ u_z & 0 & -u_x\\ -u_y& u_x & 0 \end{array}\right] \][^1] #### 实现三维坐标绕任意轴旋转的功能函数 下面给出一段具体的Matlab代码用于创建一个名为`rotatePointAroundAxis.m`的新文件,在此文件内编写如下功能函数,它接收待旋转点p、旋转轴axis及旋转角theta三个参数,并返回经过旋转后的坐标位置。 ```matlab function p_rotated = rotatePointAroundAxis(p,axis,theta) % 将输入角度转换成弧度制 theta=deg2rad(theta); % 计算正弦值与余弦值 c = cos(theta); s = sin(theta); % 获取旋转轴对应的单位化分量 ux = axis(1)/norm(axis); uy = axis(2)/norm(axis); uz = axis(3)/norm(axis); % 构建辅助变量 one_minus_c = 1-c; ux_uy_one_minus_c = ux*uy*one_minus_c; ux_uz_one_minus_c = ux*uz*one_minus_c; uy_uz_one_minus_c = uy*uz*one_minus_c; % 组合得到最终的旋转矩阵 rotationMatrix = [ c+ux^2*one_minus_c , ux_uy_one_minus_c-s*uz , ux_uz_one_minus_c+s*uy ; ux_uy_one_minus_c+s*uz , c+uy^2*one_minus_c , uy_uz_one_minus_c-s*ux ; ux_uz_one_minus_c-s*uy , uy_uz_one_minus_c+s*ux , c+uz^2*one_minus_c ]; % 应用旋转操作 p_rotated = rotationMatrix * transpose(p)'; end ``` 通过上述方式可以在Matlab环境中轻松地执行三维空间内的坐标变换任务[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值