一、实验背景
实验使用的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 )
3.2 插值之后的nii格式数据(896x923x162)
插值后的数据明显比插值前数据大
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
代码输出结果:
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
可以把shell命令写成批处理命令
批量的对影像数据进行裁剪
针对单个病例可以执行--在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
命令行窗口输出结果
递归调用遍历文件夹中的所有病例--在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
命令行窗口输出结果
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()
裁剪后的图像为倒置的
对图像进行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")
五、实验过程(三)—— 对插值裁剪后的结果重新保存成dicom文件
具体过程请参考之前的文章:python医学影像3Dnii文件转成2Ddicom文件(保留原始dicom信息)
Matlab NIfTI工具包:百度网盘-提取码:nosr
参考文章1: 常用线性插值的介绍和应用(双线性插值,三线性插值,平滑曲线插值)
参考文章2:双线性插值(Bilinear Interpol)原理及应用
参考文章3:FSL工具介绍及安装——FSL-Introduction
特别说明:本文为原创文章,参考或转发本文需注明本文链接,有问题请联系:[email protected]