我在MATLAB中有这个功能,它取两个体积的DICOM信息结构对应于同一患者的两个不同的MRI模态,并输出M,仿射变换矩阵,从info1描述的体积的图像坐标转换成info2描述的卷的图像坐标:
function [M,Rot] = GetTransformMatrix(info1, info2)
% This function calculates the 4x4 transform and 3x3 rotation matrix
% between two image coordinate system.
% M=Tipp*R*S*T0;
% Tipp:translation
% R:rotation
% S:pixel spacing
% T0:translate to center(0,0,0) if necessary
% info1: dicominfo of 1st coordinate system
% info2: dicominfo of 2nd coordinate system
% Rot: rotation matrix between coordinate system
[Mdti,Rdti] = TransMatrix(info1);
[Mtf,Rtf] = TransMatrix(info2);
% First we transform into patient coordinates by multiplying by Mdti, and
% then we convert again into image coordinates of the second volume by
% multiplying by inv(Mtf)
M = inv(Mtf) * Mdti;
Rot = inv(Rtf) * Rdti;
end
function [M,R] = TransMatrix(info)
%This function calculates the 4x4 transform matrix from the image
%coordinates to patient coordinates.
ipp=info.ImagePositionPatient;
iop=info.ImageOrientationPatient;
ps=info.PixelSpacing;
Tipp=[1 0 0 ipp(1); ...
0 1 0 ipp(2); ...
0 0 1 ipp(3); ...
0 0 0 1];
r=iop(1:3); c=iop(4:6); s=cross(r',c');
R = [r(1) c(1) s(1) 0; ...
r(2) c(2) s(2) 0; ...
r(3) c(3) s(3) 0; ...
0 0 0 1];
if info.MRAcquisitionType=='3D' % 3D turboflash
S = [ps(2) 0 0 0; 0 ps(1) 0 0; 0 0 info.SliceThickness 0 ; 0 0 0 1];
else % 2D epi dti
S = [ps(2) 0 0 0; ...
0 ps(1) 0 0; ...
0 0 info.SpacingBetweenSlices 0; ...
0 0 0 1];
end
T0 = [ 1 0 0 0; ...
0 1 0 0; ...
0 0 1 0; ...
0 0 0 1];
M = Tipp * R * S * T0;
end
为了将ADC图像坐标转换为T2图像坐标,我可以通过以下方式获得变换矩阵:
[M,Rot] = GetTransformMatrix(ADCHeader,T2Header);
M = M';
然后我获得了MATLAB仿射变换对象:
tform = affine3d(M);
随后将ADCVolume注册到T2音量:
[ADCVolume_reg,~] = imwarp(ADCVolume,tform,'Interp','cubic','FillValues',0,'OutputView',imref3d(size(T2Volume)));
当ADC和T2之间的DICOM参数info.SpacingBetweenSlices相同时,这会产生正确的结果,但是当它不同时我会得到错误的注册。
这可能是GetTransformMatrix函数的错误,还是我传递给imwarp的参数?
答案 0 :(得分:0)
毕竟,代码是对的。唯一的问题是我加载的头文件对应于所有卷的第一个切片(因为我使用的加载器加载了文件的头部和第一个InstanceNumber(0020,0000),这并不总是对应于第一个切片),这使我得到ImagePositionPatient(0020,0032)的错误值。
使用此装载程序后,所有内容都得到了解决:
通过SliceLocation(0020,1041)对标题进行排序,这是一个与切片编号一致的参数。