DPABISurf 预处理结果的朝向问题

严老师以及各位老师好,我最近用DPABISurf (dpabi 4.3)预处理了一些数据,然后想提取全脑和皮下的时间序列。为此我用DPABI的QC工具生成一个组的全脑mask,皮下mask用的是Tian的atlas(Nature Neuroscience,2020)。我准备用python的nibabel或者matlab的Nifti工具包来提取时间序列,但是我发现DPABISurf的结果(FunVoluWCFS)的orient是RPI,生成的组的全脑mask 也是这个方向,而fmriprep的输出是LPI的,MNI152NLin2009cAsym空间的原始T1像以及Tian的atlas似乎也都是LPI朝向。所以DPABISurf可能处理的时候把方向重新扭到的RPI方向? 我是用AFNI 的3dinfo查看这些文件的orient的。

进一步我还发现MNI空间的左右边界也是不一样的,fmriprep的结果为R-to-L extent:   -95.500 [R] -to-    96.500 [L] -step-     2.000 mm [ 97 voxels],与Tian的atlas一致,而DPABISurf的结果(FunVoluWCFS)为R-to-L extent:   -96.500 [R] -to-    95.500 [L] -step-     2.000 mm [ 97 voxels]。我尝试用将DPABISurf的结果作为reference,使用DPABI的Image Resclicer 来重定向Tian的atlas,虽然此时左右边界和DPABISurf结果一致,但是用DPABI_VIEW打开发现重定向的atlas比原始的atlas稍微向左平移了一点,使用load_nii读取的矩阵也有偏移。

所以请问各位老师,DPABISurf是用什么程序改变结果的朝向的?因为我读取文件的时候必须使数据和mask的朝向、边界完全一致才能正确将他们的矩阵对齐来提取信号。我感觉好像DPAISurf不仅将头文件的LPI改成了RPI还将矩阵翻转后平移了一个单位,如果如此的话,那么对其预处理结果有影响么?或者说这个影响只限于数据空间平移了一个单位?我上述用Image Resclicer重定向后能否保证FunVoluWCFS中的数据,DPABIQC工具生成的组的全脑mask以及Tian的皮下atlas这三者在完全一致的空间(用python的nibabel或者matlab的Nifti包读取的数据矩阵的indices是对应的)?或者可能该问题不存在于DPABISurf的高版本中?

谢谢各位老师!

 

不同的软件处理可能有不同的朝向,RPI,LPI,LAI等等。

DPABI为了让数据和各种mask,atlas保持同一朝向,统一用RPI朝向。

你可以研究一下y_ReadRPI.m,看看是怎么改变朝向的。如果有进一步的问题,可以继续探讨:

if sum(sum(Header.mat(1:3,1:3)-diag(diag(Header.mat(1:3,1:3)))~=0))==0 % If the image has no rotation (no non-diagnol element in affine matrix), then transform to RPI coordination.

    if Header.mat(1,1)>0 %R

        Data = flipdim(Data,1);

        Header.mat(1,:) = -1*Header.mat(1,:);

    end

    if Header.mat(2,2)<0 %P

        Data = flipdim(Data,2);

        Header.mat(2,:) = -1*Header.mat(2,:);

    end

    if Header.mat(3,3)<0 %I

        Data = flipdim(Data,3);

        Header.mat(3,:) = -1*Header.mat(3,:);

    end

end

谢谢严老师的回复,我又检查了一下,afni的3dresample和DPABI产生的RPI图像的矩阵是一致的,只是在左右边界的坐标定义上差个1mm(和问题中的描述一样),可能是由于不同软件的处理不一样,比如对这种坐标含小数的处理方法(图像分辨率2mm)。

现在我想通过将mask文件的矩阵直接“盖到”预处理后fMRI数据上来提取相应的时间序列,是否将Tian的atlas转换到RPI方向即可保证矩阵是匹配的?

代码如下:

[Data, VoxelSize, Header] = y_ReadRPI('Tian_Subcortex_S4_3T_2009cAsym.nii.gz');

y_Write(Data,Header,'Tian_Subcortex_S4_3T_2009cAsym_RPI.nii');

mask=load_untouch_nii('Tian_Subcortex_S4_3T_2009cAsym_RPI.nii')

data=load_untouch_nii('Filtered_4DVolume.nii')

mask=reshape(mask.img,1,[]);

data=reshape(data.img,[],size(data.img,4));

TC=data(mask>0,:);

或者:

mask= y_ReadRPI('Tian_Subcortex_S4_3T_2009cAsym.nii.gz');

data = y_ReadRPI('Filtered_4DVolume.nii');

mask=reshape(mask,1,[]);

data=reshape(data,[],size(data,4));

TC=data(mask>0,:);

谢谢严老师。

你都用y_ReadRPI就能保持一致了。