我正在使用(作为概述)以下编码方案进行 3D 成像对齐:
ref = imref3d(size(img(:,:,:,1)),[0 32] ,[0 32] ,[0 20] );
[optimizer, metric] = imregconfig( 'monomodal');
tform=imregtform(img(:,:,:,2), ref, img(:,:,:,1), ref, 'rigid', optimizer, metric);
transform_mat=tform.T
为澄清起见,变量img
是 3D 图像的时间序列(其中每个 3D 图像都是 2D 横截面的堆栈)。在不同的时间点,我正在成像的物体可以移动。因此,上述代码的目的是生成一个几何变换,将3D体积的第二个时间点(img(:,:,:,2)
)最佳地对齐到参考图像,这是3D体积的第一个时间点(img(:,:,:,1)
)。优化算法最终选择的几何变换输出到对象tform
。tform
包含一个 4x4 矩阵作为其属性之一 (T
);正是这个 4x4 矩阵对平移和旋转信息进行编码。从上面的代码中可以看出,我将这个 4x4 矩阵存储在变量transform_mat
中。
在阅读了大量分散的 mathworks 文档后,我确定这个transform_mat
变量(表示仿射刚体变换矩阵)是">后乘法"形式,据我了解,这只是意味着它是传统上在线性代数教科书中看到的转置版本。
出于我的目的,我有兴趣从transform_mat
中提取特定的旋转信息。这是我到目前为止所做的:
rot_postmultiply=transform_mat(1:3,1:3); %extracting the elements that encode rotation-related info
rot_premultiply=rot_postmultply'; %transposing
为了快速插话,我创建了旋转矩阵的预乘版本,因为我相信作用于旋转矩阵的许多函数都假定它是预乘形式。
从这个 3x3 旋转矩阵中,我想提取围绕参考图像的 STATIC x 轴、y 轴和 z 轴的旋转(以弧度为单位)。我最初尝试执行此操作如下:
eul = rotm2eul(rot_premultiply);
rotm2eul
函数为我提供了与这个 3x3 旋转矩阵相关的 3个欧拉角。eul
是一个 1x3 向量,根据文档,"欧拉角旋转的默认顺序是'ZYX'"。但是,我不确定欧拉角是否真的描述了我想要提取的信息(即围绕参考图像的静态x,y,z轴的旋转)。
我没有很强的线性代数/几何变换背景,但我对欧拉角的理解是,每次旋转都会改变坐标系。例如,在绕 Z 轴(eul
向量中的第一个值)旋转后,我们现在有了新的X 轴和 Y 轴(称它们为 X' 和 Y')。那么"Y 轴旋转"(eul
中的第二个值)实际上是围绕 Y'...对最后的"X旋转"(实际上是关于X''轴)重复这个论点。
如果有人能提供一些关于如何进行的见解(如果我对欧拉角的担忧是正确的),我将不胜感激!
另外,如果">静态"一词是不正确的术语,则很抱歉。希望我已经提供了足够的背景,以免产生混淆。
如果我理解正确,您所需要的只是rotm2axang
将作为正交旋转矩阵给出的旋转rotm
转换为相应的轴角度表示,axang
.输入旋转矩阵必须采用旋转的预乘形式。
rot2axang
的输出是一个 n 轴角度旋转的 n x 4 矩阵。每行的前三个元素指定旋转轴,最后一个元素定义旋转角度(以弧度为单位)。
如果您无法访问具有该功能的机器人系统工具箱,请考虑此替代方法。
编辑:
可以通过以下步骤在 3D 空间中将点旋转的角度alpha
绕由两点(x1,y1,z1)
和(x2,y2,z2)
之间的直线定义的任意轴旋转:
- 平移,使旋转轴通过原点
- 绕 X 轴旋转,使旋转轴位于 xz 平面上(或投影在 xz 平面上)
- 绕 y 轴旋转,使旋转轴沿 z 轴定位(或在 z 轴上投影)
- 绕 Z 轴旋转
alpha
- 步骤 3 的反面
- 步骤 2 的反面
- 步骤 1 的反义词
您是在询问步骤 2,3 中的角度吗?
否则,您是否已经在旋转轴的原点中?
如果您确实需要步骤 2,3 中的角度,那么:
步骤 #1 通过转换矩阵 T 完成:
T = [ 1 0 0 -x1
0 1 0 -y1
0 0 1 -z1
0 0 0 1 ];
步骤#2通过以下方式完成: 假设v = (a,b,c)
是沿旋转轴的单位矢量,则d = sqrt(b^2 + c^2)
投影到 yz 平面上的长度。 然后按yz平面中旋转轴的投影与其yz投影的单位向量v
的z分量的点积给出的z轴之间的角度旋转。这个角度(beta
)由下式决定:cos(beta) = dot([0,0,c],[0,b,c]) /(c*d) = c/d , sin(beta) = cross( [0,0,c],[0,b,c]) /(c*d) = b/d
因此,旋转矩阵 Rx 用于:
Rx = [ 1 0 0 0
0 c/d -b/d 0
0 b/d c/d 0
0 0 0 1 ] ;
第 3 步,我们围绕 y 轴旋转,使旋转轴沿正 z 轴。使用点和叉积关系,角度的余弦是d
的,角度的正弦是a
的。围绕 y 轴 Ry 的旋转矩阵为
Ry = [ d 0 -a 0
0 1 0 0
a 0 d 0
0 0 0 1];
最后,我们仅按角度旋转 zalpha
Rz = [ cos(alpha) sin(alpha) 0 0
-sin(alpha) cos(alpha) 0 0
0 0 1 0
0 0 0 1 ] ;
我认为这个问题的答案应该对你有所帮助:将 3D 旋转分解为笛卡尔分量。