nii 转 nrrd
前言
目的:想把nii的图像转为h5格式
一、nii 转 nrrd
二、nrrd 转 h5
1.数据:下载左心房MRI图像2018
2.模型:UA-MT
3.代码:
import numpy as np
from glob import glob
from tqdm import tqdm
import h5py
import nrrd
output_size =[112, 112, 80]
def covert_h5():
listt = glob('../../LA_dataset/2018LA_Seg_Training Set/*/lgemri.nrrd')
for item in tqdm(listt):
image, img_header = nrrd.read(item)
label, gt_header = nrrd.read(item.replace('lgemri.nrrd', 'laendo.nrrd'))
label = (label == 255).astype(np.uint8)
w, h, d = label.shape
tempL = np.nonzero(label)
minx, maxx = np.min(tempL[0]), np.max(tempL[0])
miny, maxy = np.min(tempL[1]), np.max(tempL[1])
minz, maxz = np.min(tempL[2]), np.max(tempL[2])
px = max(output_size[0] - (maxx - minx), 0) // 2
py = max(output_size[1] - (maxy - miny), 0) // 2
pz = max(output_size[2] - (maxz - minz), 0) // 2
minx = max(minx - np.random.randint(10, 20) - px, 0)
maxx = min(maxx + np.random.randint(10, 20) + px, w)
miny = max(miny - np.random.randint(10, 20) - py, 0)
maxy = min(maxy + np.random.randint(10, 20) + py, h)
minz = max(minz - np.random.randint(5, 10) - pz, 0)
maxz = min(maxz + np.random.randint(5, 10) + pz, d)
image = (image - np.mean(image)) / np.std(image)
image = image.astype(np.float32)
image = image[minx:maxx, miny:maxy]
label = label[minx:maxx, miny:maxy]
print(label.shape)
f = h5py.File(item.replace('lgemri.nrrd', 'mri_norm2.h5'), 'w')
f.create_dataset('image', data=image, compression="gzip")
f.create_dataset('label', data=label, compression="gzip")
f.close()
if __name__ == '__main__':
covert_h5()
4.注:
主要流程:lgemri.nrrd是原始mri;laendo.nrrd是原始mri所对应的mask。如果处理own data的话,需要将所有mri和mask的nrrrd格式全部命名成一样的名字。将所有的mri和对应的mask以此读取,然后保存label 值为255的地方(如果你得label 是用1表示的,这里就是1)(多标签比方说标签是1,2,3,4。可以将判断条件改为label!=0)。随后经过处理保存为mri_norm2.h5文件
总结
想总结一下一些医学图像常见转化方法
dicom to nii (也可以用软件:MRIcroGL_win)
import SimpleITK as sitk
import os
import pydicom
import matplotlib.pyplot as plt
os.chdir( 'C:\\Users\\xxxx\\Desktop\\DemoData\\DemoRaw\\DemoData\\FunRaw')
#避免因路径中含中文导致SimpleITK无法读取
def dcm2nii(dcms_path, nii_path):
# 1.构建dicom序列文件阅读器,并执行(即将dicom序列文件“打包整合”)
reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames(dcms_path)
reader.SetFileNames(dicom_names)
image2 = reader.Execute()
#print(image2)
# 2.将整合后的数据转为array,并获取dicom文件基本信息
image_array = sitk.GetArrayFromImage(image2) # z, y, x
origin = image2.GetOrigin() # x, y, z
spacing = image2.GetSpacing() # x, y, z
direction = image2.GetDirection() # x, y, z
# 3.将array转为img,并保存为.nii.gz
image3 = sitk.GetImageFromArray(image_array)
image3.SetSpacing(spacing)
image3.SetDirection(direction)
image3.SetOrigin(origin)
sitk.WriteImage(image3, nii_path)
dcms_path = r'.\Sub_002' # dicom序列文件所在路径
nii_path = r'.\Sub_002\test.nii' # 所需.nii文件保存路径
###将dicom(.dcm)文件转为nifti(.nii)文件###
dcm2nii(dcms_path, nii_path)
nii to dicom
dicom格式的医学图像含有头信息,转化为别的格式之后会丢掉头信息,使得没办法转回dicom格式的图片。
需要做的就是给nii.gz等格式的医学图片添加一个头信息。
import SimpleITK as sitk
image = sitk.ReadImage("01.dcm") # 读取一个含有头信息的dicom格式的医学图像
keys = image.GetMetaDataKeys() # 获取它的头信息
image2=sitk.ReadImage(*****.nii.gz)# 读取要转换格式的图像
for key in keys:
image2.SetMetaData(key, image.GetMetaData(key)) # 把第一张图像的头信息,插入到第二张图像
sitk.WriteImage(image2, '*****.dcm') # 把插入过头信息的图像输出为dicom格式