我有一个整数值的3D数组和一个方向向量。我希望能够沿着这个向量选择X切片,方向是切片器看的方向(也就是说,切片的X和Y坐标是方向向量的两个法线,垂直于每个其他)。
我有以下解决方案,但结果显示在方向向量的Y轴上预期的90度偏移,我无法弄清楚原因。
%Get "up" and "right" direction vectors
up = get_rotated_direction(direction, 90,0,0);
right = get_rotated_direction(direction, 0,90,0);
z = 0;
for i=1:zStep:zCount
z = z +1;
%Slicer follows a path denoted by "points"
point = points(i,:);
%topLeft holds the coordinates in the data volume of the point at [X=0,Y=0] in the slice.
topLeft = point - right * width / 2 - up * height / 2;
for x=1:width
for y=1:height
offsetPoint = round(topLeft + up*y+ right*x);
result(x,y,z) = data(offsetPoint(1),offsetPoint(2),offsetPoint(3));
end
end
end
结果是一个有效的图像,但方向错误,所以我认为问题在于get_rotated_direction
或我对它的调用,但是在测试时使用单位向量[0,0,1],[ 0,1,0]和[1,0,0]结果似乎是正确的。
get_rotated_direction
看起来像这样:
function result = get_rotated_direction (direction, x_angle,y_angle,z_angle)
%get the rotation from origin to direction
rot = vrrotvec([0,0,1],direction);
%Turn this into a quaternion
rotquat = angle2quat(rot(1)*rot(4),rot(2)*rot(4),rot(3)*rot(4),'XYZ');
%get the angles in radians
x_angle = deg2rad(x_angle);
y_angle = deg2rad(y_angle);
z_angle = deg2rad(z_angle);
%Create the desired rotation from the origin
desiredRot = angle2quat(x_angle,y_angle,z_angle,'XYZ');
%Rotate the origin to our desired rotation
%Then rotate that by the rotation from origin to our direction
%This should produce a direction that has been locally rotated.
direction= quatrotate(rotquat,quatrotate(desiredRot,[0,0,1]));
%Normalize the direction and return
result = direction/norm(direction);
end
答案 0 :(得分:1)
使用转换矩阵,这是一种更通用的方法。我遇到了类似的问题并使用了this回答,我试图将其推广到下面的3D案例中:
%example data
load mri; olddata = squeeze(D);
phi = 90; theta = 90; psi = 0;
r = [phi, theta, psi]; r = r*(pi/180);
dims = size(olddata);
p0 = [round(dims(1)/2);round(dims(2)/2);round(dims(3)/2)]; %image center
%I assume that spacing between points is equal in all three dimensions
Rx=[1 0 0 0;
0 cos(r(1)) sin(r(1)) 0;
0 -sin(r(1)) cos(r(1)) 0;
0 0 0 1];
Ry=[cos(r(2)) 0 -sin(r(2)) 0;
0 1 0 0;
sin(r(2)) 0 cos(r(2)) 0;
0 0 0 1];
Rz=[cos(r(3)) sin(r(3)) 0 0;
-sin(r(3)) cos(r(3)) 0 0;
0 0 1 0;
0 0 0 1];
R = Rz*Ry*Rx;
%make affine matrix to rotate about center of image instead of origin
T = ( eye(3)-R(1:3,1:3) ) * p0(1:3);
A = R;
A(1:3,4) = T;
Rold2new = A;
Rnew2old = inv(Rold2new);
%this is the transformation
%I assume you want a volume with the same dimensions as your old volume
[xx yy zz] = meshgrid(1:dims(1),1:dims(2),1:dims(3));
coordinates_axes_new = [xx(:)';yy(:)';zz(:)'; ones(size(zz(:)))']; % the coordinates you want to find a value for
coordinates_axes_old = Rnew2old*coordinates_axes_new; % the coordinates where you can find those values
Xcoordinates = reshape(coordinates_axes_old(1,:), dims(1), dims(2), dims(3));
Ycoordinates = reshape(coordinates_axes_old(2,:), dims(1), dims(2), dims(3));
Zcoordinates = reshape(coordinates_axes_old(3,:), dims(1), dims(2), dims(3));
%this is where you get the values for your new coordinates
method = 'nearest'; %you have integers only so you probably want the nearest neighbour?
newdata = interp3(olddata, Xcoordinates, Ycoordinates, Zcoordinates, method);
figure; subplot(1,2,1); imshow(olddata(:,:,13), []); title('original'); subplot(1,2,2); imshow(newdata(:,:,13), []); title('rotated')
导致此次轮换: