I am carrying out 3D imaging alignment using (as an overview) the following coding scheme:
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
For clarification, the variable img
is a time series of 3D images (where each 3D image is a stack of 2D cross sections). At different time points, the object I am imaging can move. Thus, the purpose of the above code is to generate a geometric transformation that optimally aligns the second time point of the 3D volume ( img(:,:,:,2)
) to a reference image, which is the first time point of the 3D volume ( img(:,:,:,1)
). The geometric transformation that is finally chosen by the optimization algorithm is output to the object tform
. tform
contains a 4x4 matrix as one of its properties (T
); it is this 4x4 matrix that encodes the translation and rotation information. As you can see from my above code, I stored this 4x4 matrix in the variable transform_mat
.
After reading through a lot of scattered mathworks documentation, I determined that this transform_mat
variable (representing an affine rigid body transformation matrix) is in a "post-multiplied" form, which, as I understand it, just means that it is the transposed version of what one would traditionally see in a linear algebra text book.
For my purposes, I am interested in extracting specific rotation information from transform_mat
. Here is what I have done so far:
rot_postmultiply=transform_mat(1:3,1:3); %extracting the elements that encode rotation-related info
rot_premultiply=rot_postmultply'; %transposing
Just to quickly interject, I created the premultiplied version of the rotation matrix because I believe that many of the functions that act on rotation matrices assume that it is in its premultiplied form.
From this 3x3 rotation matrix, I want to extract the rotations (in radians) about the STATIC x-axis, y-axis, and z-axis of the reference image. My initial attempt at carrying this out is as follows:
eul = rotm2eul(rot_premultiply);
The rotm2eul
function provides me the 3 Euler Angles associated with this 3x3 rotation matrix. eul
is a 1x3 vector and, according to documentation, the "default order for Euler angle rotations is 'ZYX' ". However, I am not certain that Euler Angles are actually describing the information I want to extract (i.e. rotations about the static x, y, z axes of the reference image).
I do not have a strong linear algebra/geometric transformation background, but my understanding of Euler Angles is that each rotation that takes place changes the coordinate system. For example, after the rotation about the Z axis (the first value in the eul
vector), we now have new X and Y axes (call them X' and Y'). Then the "Y-axis rotation" (the second value in eul
) is actually the rotation about Y'...not Y. Repeat this argument for the final "X-rotation" (which would really be about an X'' axis).
If anyone could offer some insight about how to proceed (and if my concerns about Euler Angles are correct), I would greatly appreciate it!
Also, sorry if the word "static" is the incorrect terminology. Hopefully, I have provided sufficient context so that no confusion arises.