【问题标题】:DICOM affine matrix transformation from image space to patient space in MatlabMatlab中从图像空间到患者空间的DICOM仿射矩阵变换
【发布时间】:2014-02-13 15:51:38
【问题描述】:

从 nifti 标头很容易获得仿射矩阵。但是在 DICOM 标头中有很多条目,但我不清楚哪些条目描述了哪个参数到哪个新空间的转换。

我找到了一个相当详细的tutorial,但我找不到他们引用的条目。此外,该教程是为 Python 而不是 Matlab 编写的。它列出了这些标题条目:

Entries needed:
Image Position (0020,0032)
Image Orientation (0020,0037)
Pixel Spacing (0028,0030)

如果我用 dicominfo() 加载标题,我找不到这些。也许它们是特定于供应商的,或者它们嵌套在结构中的某个地方。他们引用的像素间距也包含两个值,所以我认为他们的教程只适用于单片转换。需要更多关于切片厚度和切片间隙的标题条目。计算z坐标的正确变换也不容易。

有人知道如何找到这些条目或如何将图像坐标转换为患者坐标以及来自 DICOM 标头的其他信息吗?我使用 Matlab。

【问题讨论】:

    标签: matlab dicom affinetransform


    【解决方案1】:

    好的,所以它们被嵌套在结构的供应商特定条目中。在 Matlab 中加载时,嵌套的名称是 inf.PerFrameFunctionalGroupsSequence.Item_X.,然后是帧号,然后是一些更直接/不言自明的嵌套,所以我不需要在这里添加它。但是在那里搜索您需要的条目。切片间距称为SpacingBetweenSlices(或单切片情况下的切片厚度),像素间距称为PixelSpacing 然后有 ImagePositionPatient 用于平移和 ImageOrientationPatient 用于旋转。以下是我按照下面的 nipy 链接中的步骤编写的代码。

    发生的情况是,您将direction cosines 加载到旋转矩阵中以对齐基向量,然后将像素间距和切片间距加载到矩阵中以缩放基向量,然后加载图像位置以转换新坐标系统。找到 z 方向的方向余弦需要一些计算,因为 dicom 显然是为 2d 图像设计的。在单切片情况下,z 方向余弦是与 x 和 y 方向余弦正交的单位向量(两者之间的叉积),在多切片情况下,您可以根据切片之间平移的所有差异来计算它。在此之后你仍然想apply the transformation 这也不是很直接。

    %load the header
    inf = dicominfo(filename, 'dictionary', yourvendorspecificdictfilehere);
    
    nSl = double(inf.MRSeriesNrOfSlices);
    nY = double(inf.Height);
    nX = double(inf.Width);
    T1 = double(inf.PerFrameFunctionalGroupsSequence.Item_1.PlanePositionSequence.Item_1.ImagePositionPatient);
    
    %load pixel spacing / scaling / resolution
    RowColSpacing = double(inf.PerFrameFunctionalGroupsSequence.Item_1.PixelMeasuresSequence.Item_1.PixelSpacing);
    %of inf.PerFrameFunctionalGroupsSequence.Item_1.PrivatePerFrameSq.Item_1.Pixel_Spacing;
    dx = double(RowColSpacing(1));
    dX = [1; 1; 1].*dx;%cols
    dy = double(RowColSpacing(2));
    dY = [1; 1; 1].*dy;%rows
    dz = double(inf.SpacingBetweenSlices);%inf.PerFrameFunctionalGroupsSequence.Item_1.PrivatePerFrameSq.Item_1.SliceThickness; %thickness of spacing?
    dZ = [1; 1; 1].*dz;
    
    %directional cosines per basis vector
    dircosXY = double(inf.PerFrameFunctionalGroupsSequence.Item_1.PlaneOrientationSequence.Item_1.ImageOrientationPatient);
    dircosX = dircosXY(1:3);
    dircosY = dircosXY(4:6);
    if nSl == 1;
        dircosZ = cross(dircosX,dircosY);%orthogonal to other two direction cosines!
    else
        N = nSl;%double(inf.NumberOfFrames);
        TN = double(-eval(['inf.PerFrameFunctionalGroupsSequence.Item_',sprintf('%d', N),'.PlanePositionSequence.Item_1.ImagePositionPatient']));
        dircosZ = ((T1-TN)./nSl)./dZ;
    end
    
    %all dircos together
    dimensionmixing = [dircosX dircosY dircosZ];
    
    %all spacing together
    dimensionscaling = [dX dY dZ];
    
    %mixing and spacing of dimensions together
    R = dimensionmixing.*dimensionscaling;%maps from image basis to patientbasis
    
    %offset and R together
    A = [[R T1];[0 0 0 1]];
    
    %you probably want to switch X and Y
    %(depending on how you load your dicom into a matlab array)
    Aold = A;
    A(:,1) = Aold(:,2);
    A(:,2) = Aold(:,1);
    

    这导致了这个仿射公式:

    所以基本上我遵循了this 教程。最大的困难是让 Z 方向和平移正确。对我来说,找到识别和转换正确的条目也不是一件容易的事。我确实认为我的回答为该教程添加了一些内容,因为很难找到它们引用的条目,现在我编写了一些 Matlab 代码,从 DICOM 标头获取仿射矩阵。在使用找到的仿射矩阵之前,您可能还需要找到所有帧的 Z 坐标,如果您的数据集有四个以上的维度,这可能不是一件容易的事(dicomread 将所有更高的维度放在 one big fourth dimension 中)

    -编辑- 修正了 Z 方向和变换的平移

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多