1.原始的每個DCE序列中有多個dicom文件,經(jīng)過插值裁剪后轉成以一個3Dmatnii矩陣
2.現(xiàn)在的需求是把處理過的3Dnii矩陣還原成2Ddicom文件,并且保留原始dicom信息.
1.插值裁剪后的影像數(shù)據(jù)
每一個.nii.gz文件代表DCE-MRI中的一個序列
2.原始DCE-MRI影像數(shù)據(jù)中一個序列包含多個dcm文件
3.Python代碼:把3Dnii文件還原成2Ddicom文件,并且保留原始dicom信息.
導入需要的包
import os
import SimpleITK as sitk
import numpy as np
import pydicom as dicom
定義翻轉函數(shù)實現(xiàn)圖像的180°旋轉
def flip180(arr):#圖片反轉180°
new_arr =arr.copy()
new_arr = arr.reshape(arr.size)
new_arr = new_arr[::-1]
new_arr = new_arr.reshape(arr.shape)
return new_arr
定義給dicom的tag賦值的函數(shù)
def modify_dicom(ds,dcm):#把原始dicom的元數(shù)據(jù)寫進新的dicom中挤庇,否則無法成為一個序列
#PatientInfo
ds.PatientID = dcm.PatientID
ds.PatientName = dcm.PatientName
ds.PatientBirthDate = dcm.PatientBirthDate
ds.PatientSex = dcm.PatientSex
ds.PatientAge = dcm.PatientAge
ds.PatientWeight = dcm.PatientWeight
try:
ds.MagneticFieldStrength = dcm.MagneticFieldStrength
ds.Manufacturer = dcm.Manufacturer
except TypeError:
print("Error:沒有InstitutionName钞速、Manufacturer、InstitutionName tag")
#studyInfo
ds.StudyDate =dcm.StudyDate
ds.StudyTime = dcm.StudyTime
ds.StudyDescription = dcm.StudyDescription
ds.StudyInstanceUID = dcm.StudyInstanceUID
ds.StudyID = ds.StudyID
# seriesInfo
ds.SeriesInstanceUID = dcm.SeriesInstanceUID
ds.SeriesDescription = dcm.SeriesDescription
ds.Modality = dcm.Modality
ds.SeriesNumber = dcm.SeriesNumber
#ds.InstanceNumber = instanceNumber #Instance Number
ds.SeriesDate = dcm.SeriesDate
ds.SeriesTime = dcm.SeriesTime
ds.SOPClassUID = dcm.SOPClassUID
return ds
定義給nii轉dicom的核心函數(shù)
def nii2dicom(nii_img,save_dir,DCE_MR):
"""[將重采樣后的nii圖片轉dicom保存]
Args:
nii_img ([]): 一個3維nii類型嫡秕,shape=(W,H,切片數(shù))
save_dir ([type]): 轉成dicom序列文件保存路徑
"""
itk_img = sitk.ReadImage(nii_img)
img_3Dndarray = sitk.GetArrayFromImage(itk_img)#得到圖像矩陣
img_shape = img_3Dndarray.shape
print(img_shape,img_shape[0])#查看 3D 維度
img_num = img_3Dndarray.shape[0]
PixelSpacing = itk_img.GetMetaData('pixdim[1]')#pixdim[1] : 0.379464 pixdim[2] : 0.379464 pixel spacing
SliceThickness = itk_img.GetMetaData('pixdim[3]')#pixdim[3] : 1.2 層厚
BitsAllocated = itk_img.GetMetaData('bitpix')#16
Columns = itk_img.GetMetaData('dim[1]')#dim[1] : 896
Rows = itk_img.GetMetaData('dim[2]')
for i in range(img_num-13):
#從第13張slice開始渴语,13張之前的均是不完整的切片
####.nii切片倒著讀,并旋轉180度,也要變?yōu)閕nt16才行 img_num-i-1
out = flip180(img_3Dndarray[12+i,:,:]).astype('uint16')
itk_img_1 = sitk.GetImageFromArray(out)
InstanceNumber = ''
if (i+1) <10:
InstanceNumber = '0000'+str(i+1)
elif (i+1) <100:
InstanceNumber = '000'+str(i+1)
elif (i+1) <300:
InstanceNumber = '00'+str(i+1)
else:
print('Warning!!',InstanceNumber,"dicom數(shù)量大于300")
dicom_save_file_path = save_dir+'\\'+InstanceNumber+'.dcm'#to do i range
itk_img_1.SetMetaData('0028|0030',PixelSpacing)#0028,0030 修改 Pixel Spacing: 1.5625信息
itk_img_1.SetMetaData('0018|0050',SliceThickness)
itk_img_1.SetMetaData('0028|0100',str(16))#bitpix : 16 位數(shù)
itk_img_1.SetMetaData('0028|0011',Columns)#Columns
itk_img_1.SetMetaData('0028|0010',Rows)#Rows
itk_img_1.SetMetaData('0020|0013',str(i+1))#instanceNumber
sitk.WriteImage(itk_img_1,dicom_save_file_path)
######再讀文件昆咽,修改dicom的tag信息使這些圖片成為一個序列
read_dicom_path = DCE_MR+'\\'+'00010.dcm' #原始dcm文件的具體路徑
dcm = dicom.read_file(read_dicom_path)
ds = dicom.read_file(dicom_save_file_path)
if i == 0:
seriesInstanceUID = ds.SeriesInstanceUID
studyInstanceUID = ds.StudyInstanceUID
frameUID = ds[0X0020, 0X0052].value
else:
ds.SeriesInstanceUID = seriesInstanceUID #修改Series Instance UID
ds.StudyInstanceUID = studyInstanceUID
ds[0X0020, 0X0052].value = frameUID
ds = modify_dicom(ds,dcm)
ds.InstanceNumber = i+1 ###必須加驾凶,形成連續(xù)變化的序列牙甫,不然,dicom軟件讀取切片會變亂
ds.save_as(dicom_save_file_path)
返回具體nii文件的路徑
def get_NII_path(root_path,niidata_path,reliceniidata_path):
'''
返回具體nii文件的路徑
'''
count_study = 0
for every_study in os.listdir(niidata_path):#遍歷所有的病歷號
count_study +=1
tmp_MR_path = os.path.join(root_path,every_study,'MR')#DWI ,T2等
_renii_path =os.path.join(reliceniidata_path,every_study)
if count_study <80:
continue
for every_MRI in os.listdir(tmp_MR_path):#每個病歷號下面可能有多次MRI
tmp_MRI_path = os.path.join(tmp_MR_path,every_MRI)
tmp_DCEseries = tmp_MRI_path+"\DCE00000"
DCE_length = len(os.listdir(tmp_DCEseries))
print(tmp_DCEseries,"-->",DCE_length)
_rdicom_path = os.path.join(niidata_path,every_study,'ResliceMR',every_MRI)
for every_nii in os.listdir(_renii_path):
if DCE_length!=112 and "corDCE0000" in every_nii:
str1 = every_nii.replace(".nii.gz","")
str2 = str1.replace("cor","")
DCE_MR = os.path.join(tmp_MRI_path,str2)
every_niidata = os.path.join(_renii_path,every_nii)
print(every_niidata)
save_rDCE = os.path.join(_rdicom_path,str1)
if not os.path.exists(save_rDCE):
os.makedirs(save_rDCE)
print("create-->"+save_rDCE+"-->successfully!!")
else:
print(save_rDCE+" have exists!")
nii2dicom(every_niidata,save_rDCE,DCE_MR)
定義路徑,調用函數(shù)執(zhí)行
if __name__ =="__main__":
root_path = r"G:\DCE+T2+ADC"
niidata_path = r"G:\DCE90_NiiDATA"
reliceniidata_path =r"G:\DCE_ResliceNiiDATA"
get_NII_path(root_path,niidata_path,reliceniidata_path)
代碼執(zhí)行過程:
特別說明:本文為原創(chuàng)文章,參考或轉發(fā)本文需注明本文鏈接调违,有問題請聯(lián)系:nick.yu.jd@qq.com