基于MATLAB NIFTI工具包的医学影像MRI序列插值

一、实验背景

实验使用的DCE序列(动态增强序列)数据层厚不一致,为了最后实验结果的准确性,需要把使用MRI数据的层厚统一成一样的;有两种层厚的数据分别是1.2mm和2.4mm,需要把2.4mm的影像数据插值成1.2mm。

二、实验环境

1.Windows 64操作系统 CPU i5-8500 @3.00GHz 内存16.0GB
2.Linux 64位操作系统 CPU Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz 内存62.64GB
3.Windows10操作系统上安装matlab 2018a及其以上版本
4.nii格式的MRI影像数据

三、实验过程(一)—— 插值

3.1 MRI nii格式的数据(896x896x72 )

image.png

3.2 插值之后的nii格式数据(896x923x162)
插值后的数据明显比插值前数据大

image.png

3.3 实验用的Matlab代码
代码可以修改路径后在服务器上运行,执行速度会比本地快很多。
shell命令:matlab -nodesktop -nosplash -r DCE_reslice_Linux
(DCE_reslice_Linux为.m文件的名字,这行命令就是在服务器上执行脚步,前提是数据先上传服务器)

%插值reslice,就用reslice_nii这个函数就可以了
%比如要采样到1mm就用reslice_nii('orginal.nii','new.nii',[1 1 1]);
clc
root = ['G:\ResearchData\DCE90_NiiDATA','\'];
save_root = ['G:\ResearchData\DCE_ResliceNiiDATA','\'];
patients=dir(root);%获取病例目录
for i=3%:length(patients) %i=3只取第一个文件
    disp(strcat('Processing--->',patients(i).name,'-->',num2str(i-2),'/',num2str(length(patients)-2)));
    temp_nii= [root,patients(i).name,'\MR2Nii\'];%MRI nii格式文件夹
    MRIs=dir(temp_nii);%有几次MRI
    for k=3
        Nii_path = [root,patients(i).name,'\MR2Nii\',MRIs(k).name,'\'];
        save_Re_dir = [save_root,patients(i).name,'\',MRIs(k).name,'\'];
        if ~exist(save_Re_dir,'dir')%判断文件夹是否存在,如果不存在则创建文件夹
            mkdir(save_Re_dir)
        end
        Niis = dir(Nii_path);%对应某次MRI下有几个nii文件
        for j=3:length(Niis)
            orginal_nii = [Nii_path,Niis(j).name];
            new_nii = [save_Re_dir,'r',Niis(j).name];%reslice后的文件名价加个r
            %插值原理Trilinear interpolation三线性插值  x y z 分辨率 单位mm
            reslice_nii(orginal_nii,new_nii,[0.3795 0.3795 1.2])
            disp(['save-->',new_nii,'-->successfully'])
        end
    end
end

代码输出结果:

image.png

3.4 实验(一)结果分析

插值之后的MRI序列的维度为(896x923x162),和原始影像数据的二维图像(896x896)不一样,所以需要把影像数据二维图像裁剪成(896x896),这一步需要在服务器上用fslroi函数进行校准(裁剪)
MATLAB代码中用到了reslice_nii函数,其插值原理是Trilinear interpolation三线性插值, 常用线性插值的介绍和应用(双线性插值,三线性插值,平滑曲线插值)

四、实验过程(二)—— 裁剪

4.1 利用fslroi对插值后的影像数据进行裁剪

shell命令:fslroi rDCE00000.nii test 0 896 0 896 0 144

image.png

可以把shell命令写成批处理命令
批量的对影像数据进行裁剪

image.png

针对单个病例可以执行--在xshell 下执行下面的命令

path_nii = "/DATA/102/nick/DCE_ResliceNiiDATA/00226023/"
for file in `ls ${path_nii} `
  do
    echo "NIi_file:$file"
    fslroi $file "co$file" 0 896 0 896 0 144
  done

命令行窗口输出结果

image.png

递归调用遍历文件夹中的所有病例--在xshell 下执行下面的命令

function travFolder(){ 
    echo "travFolder"
    flist=`ls $1`
    cd $1
    #echo $flist
    for f in $flist
    do
        if test -f $f
        then
            echo "file:$f"
            fslroi $f "co$f" 0 896 0 896 0 144
        else
            echo "dir:$f"
            travFolder $f
        fi
    done
   cd ../
}
dir="/DATA/102/nick/DCE_ResliceNiiDATA"
travFolder $dir

命令行窗口输出结果

image.png

4.2 查看裁剪后的结果

方法一:利用ITK_SNAP软件查看图像
方法二:自己写python脚本查看图像

python代码

import os
import SimpleITK as sitk
import numpy as np
import matplotlib.pyplot as plt
import pydicom as dicom

folderPath = r"G:\ResearchData\DCE_ResliceNiiDATA\00226023\20120608\corDCE00003.nii.gz"
print("reslice后的nii文件的大小:",float(os.path.getsize(folderPath)/1000000),"MB")
itk_img = sitk.ReadImage(folderPath)#读取nii图像
img = sitk.GetArrayFromImage(itk_img)#获取图像array
print("img.shape:",img.shape)#查看图像形状 (112, 896, 896)
#获取图像头信息
keys = itk_img.GetMetaDataKeys()
for key in keys:#输出dicom头文件信息
    print (key,':', itk_img.GetMetaData(key))
  
img_3Dndarray = sitk.GetArrayFromImage(itk_img)#得到图像矩阵
print(type(img_3Dndarray),"shape:",img_3Dndarray[48,:,:].shape,img_3Dndarray[48,:,:].dtype)
plt.imshow(img_3Dndarray[48,:,:],cmap="gray")
plt.axis('off')
plt.show()

裁剪后的图像为倒置的


image.png

对图像进行180°的旋转操作

arr = img_3Dndarray[48,:,:]
arr2 =arr.copy()
print(arr.size,arr.size/2)
arr2= arr.reshape(int(arr.size/2),2)
arr2 =np.array(arr2[::-1])#进行行逆置
arr2 = arr2.reshape(arr.shape[0],arr.shape[1])#对图像进行一次变换,变成 源图像的维度
plt.subplot(121)
plt.imshow(arr,cmap="gray")
plt.subplot(122)
plt.imshow(arr2,cmap="gray")
image.png

五、实验过程(三)—— 对插值裁剪后的结果重新保存成dicom文件

具体过程请参考之前的文章:python医学影像3Dnii文件转成2Ddicom文件(保留原始dicom信息)

Matlab NIfTI工具包:百度网盘-提取码:nosr
参考文章1: 常用线性插值的介绍和应用(双线性插值,三线性插值,平滑曲线插值)
参考文章2:双线性插值(Bilinear Interpol)原理及应用
参考文章3:FSL工具介绍及安装——FSL-Introduction

特别说明:本文为原创文章,参考或转发本文需注明本文链接,有问题请联系:[email protected]

你可能感兴趣的:(基于MATLAB NIFTI工具包的医学影像MRI序列插值)