python 用SimpleITK+pydicom 将4dnii图像转为单张dicom,并重新添加图像头信息

您所在的位置:网站首页 dicom格式转换mp4 python 用SimpleITK+pydicom 将4dnii图像转为单张dicom,并重新添加图像头信息

python 用SimpleITK+pydicom 将4dnii图像转为单张dicom,并重新添加图像头信息

2023-08-14 10:12| 来源: 网络整理| 查看: 265

最近在处理一套心脏数据,需要将4dnii图像转换成单张的dicom图像进行试验,看了很多博客,发现SimpleITK是一个处理医学图像的很好用的包,里面支持很多医学图像的读取以及处理,以及对图像头信息的查看及修改。

首先,可以用sitk.ReadImage读取4dnii图像,如下:

itk_img = sitk.ReadImage('E:/cardic_data/training/patient009/patient009_4d.nii.gz')#读取nii图像 img = sitk.GetArrayFromImage(itk_img)#获取图像array print(img.shape)#查看图像形状 #获取图像头信息 keys = itk_img.GetMetaDataKeys() print(keys) for key in keys: print (key,':', itk_img.GetMetaData(key)

读取nii图像ndarray后,就可以numpy及切片将图像保存为单张dicom了:

simpleitk读取图像是按照(t,slice,height,width)读取的 我们可以用numpy转换成想要的形状,便于切片:

img = sitk.GetArrayFromImage(itk_img) print(img.shape) img =np.transpose(img,(1,0,2,3)) print(img.shape) 结果: (35, 10, 256, 208) (10, 35, 256, 208) 切片并保存: import pydicom import numpy as np import SimpleITK as sitk import nibabel as nib import os import pydicom itk_img = sitk.ReadImage('E:/cardic_data/training/patient009/patient009_4d.nii.gz') itk_img = sitk.ReadImage('E:/DICOM_data_cardic/patient001_4d_0_1.dcm') img = sitk.GetArrayFromImage(itk_img) print(img.shape) img =np.transpose(img,(1,0,2,3)) print(img.shape) keys = itk_img.GetMetaDataKeys() #pixel = itk_img.GetMetaData('pixdim[1]') #print('pixel:',pixel) for key in keys: print (key,':', itk_img.GetMetaData(key)) print("img shape:",img.shape) for i in range(img.shape[0]): for j in range(img.shape[1]): out = sitk.GetImageFromArray(img[i,j,:,:].astype('int16'))#这里需要把切边图像保存为‘int16’,不然保存会出错 sitk.WriteImage(out, 'E:/DICOM_data_cardic/patient009/patient009_4d_{}_{}.dcm'.format(i,j))

img[i,j,:,:].astype('int16'),这里保存为'int16'主要是因为读取nii图像array是默认的是float32,然后在保存时有些数据会保存不了,出现以下错误:

Traceback (most recent call last):   File "E:/pycharm/ss1/Nii2Dicom.py", line 42, in     sitk.WriteImage(out, 'E:/DICOM_data_cardic/patient009/patient009_4d_{}_{}.dcm'.format(i,j))   File "D:\Anaconda\envs\tensorflow\lib\site-packages\SimpleITK\SimpleITK.py", line 8207, in WriteImage     return _SimpleITK.WriteImage(*args) RuntimeError: Exception thrown in SimpleITK WriteImage: D:\a\1\sitk-build\ITK\Modules\IO\GDCM\src\itkGDCMImageIO.cxx:1058: itk::ERROR: GDCMImageIO(000001BED1A840C0): A Floating point buffer was passed but the stored pixel type was not specified.This is currently not supported  

对于修改header信息,主要是使用SimpleITK 在修改Series Instance UID 时使用了pydicom,主要是我用SimpleITK修改时保存后不是我修改的值,修改不了,后面发现可以用pydicom修改代码如下:

import pydicom import numpy as np import SimpleITK as sitk import nibabel as nib import pydicom itk_img = sitk.ReadImage('E:/cardic_data/training/patient009/patient009_4d.nii.gz') img = sitk.GetArrayFromImage(itk_img)#这里主要是为了读取nii原图像array然后索引单张dicom,对每张图像添加header信息 pixel = itk_img.GetMetaData('pixdim[1]') print(pixel) img =np.transpose(img,(1,0,2,3)) print(img.shape) #base_path = 'E:/DICOM_data_cardic/patient001' for i in range(img.shape[0]): for j in range(img.shape[1]): itk_img_1 = sitk.ReadImage('E:/DICOM_data_cardic/patient009/patient009_4d_{}_{}.dcm'.format(i,j)) itk_img_1.SetMetaData('0020|1041', '{}'.format(float(i)))#0020,1041 添加 Slice Location: 信息 #itk_img_1.EraseMetaData('0020|000e')#0020,000E 修改 Series Instance UID: 001这里修改不了,后面用pydicom实现 itk_img_1.SetMetaData('0028|0030',pixel)#0028,0030 修改 Pixel Spacing: 1.5625信息 m = 30*(j+1) itk_img_1.SetMetaData('0018|1060', str(m))#0018,1060 修改 Trigger Time: 30 #out = sitk.Cast(itk_img_1, sitk.sitkFloat32) out = sitk.WriteImage(itk_img_1, 'E:/DICOM_data_cardic1/patient009/patient009_4d_{}_{}.dcm'.format(i,j)) ds=pydicom.read_file('E:/DICOM_data_cardic1/patient009/patient009_4d_{}_{}.dcm'.format(i,j)) ds.SeriesInstanceUID = '9'#修改Series Instance UID ds.save_as('E:/DICOM_data_cardic2/patient009/patient009_4d_{}_{}.dcm'.format(i,j))

 

这里推荐一个SimpleITK的API document:

https://itk.org/SimpleITKDoxygen/html/namespaceitk_1_1simple.html

很有用!!!

以上就是全过程!

代码下载地址:

https://download.csdn.net/download/qq_38895920/13582657



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3