Nii转png,Nii转dcm,Dcm转png

Nii转png,Nii转dcm,Dcm转png

  • 前言
  • Nii转PNG
  • Nii转DCM
  • DCM转PNG
  • 完整代码
  • 结束语

前言

这篇文章主要是对之前使用的nii文件进行一些格式的转换,nii文件是之前用的LITS数据集,因为需要将其转为png图片和DICOM格式的二维图片。原理基本一致,先把需要转换的文件读取成numpy矩阵,然后再进行转化,主要是保存的时候更改后缀名而已。

Nii转PNG

先将nii中的每个切片读取进来,然后再一张张切片分开保存,代码如下:
单个nii转png

def nii2png_single(nii_path, IsData = True):
    ori_data = sitk.ReadImage(nii_path)  # 读取一个数据
    data1 = sitk.GetArrayFromImage(ori_data)  # 获取数据的array
    if IsData:  #过滤掉其他无关的组织,标签不需要这步骤
        data1[data1 > 250] = 250
        data1[data1 < -250] = -250
    img_name = os.path.split(nii_path)  #分离文件名
    img_name = img_name[-1]
    img_name = img_name.split('.')
    img_name = img_name[0]
    i = data1.shape[0]
    png_path = './png/single_png'   #图片保存位置
    if not os.path.exists(png_path):
        os.makedirs(png_path)
    for j in range(0, i):   #将每一张切片都转为png
        if IsData:  # 数据
            #归一化
            slice_i = (data1[j, :, :] - data1[j, :, :].min()) / (data1[j, :, :].max() - data1[j, :, :].min()) * 255
            cv2.imwrite("%s/%s-%d.png" % (png_path, img_name, j), slice_i)  #保存
        else:   # 标签
            slice_i = data1[j, :, :] * 122
            cv2.imwrite("%s/%s-%d.png" % (png_path, img_name, j), slice_i)  # 保存

批量转换

def nii2png(data_path, label_path):
    dataname_list2 = os.listdir(label_path)
    for nii_label in dataname_list2:
        print("process:", nii_label)
        data1 = sitk.ReadImage(os.path.join(data_path, nii_label.replace('segmentation', 'volume'))) # 读取一个数据
        liver_tumor_data = sitk.GetArrayFromImage(data1)  # 获取数据的array
        data2 = sitk.ReadImage(os.path.join(label_path, nii_label))  # 读取一个数据
        liver_tumor_label = sitk.GetArrayFromImage(data2)  # 获取数据的array
        img_name = os.path.split(nii_label.replace('segmentation', 'volume'))     # 分离文件名,用以保存时的文件名前缀
        img_name = img_name[-1]
        img_name = img_name.split('.')
        img_name = img_name[0]
        i = liver_tumor_label.shape[0]
        liver_tumor_data[liver_tumor_data > 250] = 250
        liver_tumor_data[liver_tumor_data < -250] = -250
        outpath = r'./png/data_png'  # 数据保存文件夹
        outpath2 = r'./png/label_png'   # 标签保存文件夹
        if not os.path.exists(outpath):
            os.makedirs(outpath)
        if not os.path.exists(outpath2):
            os.makedirs(outpath2)
        for j in range(0, i):
            if liver_tumor_label[j, :, :].max() > 0:    # 只保存有肝脏的切片
                img1 = (liver_tumor_data[j, :, :] - liver_tumor_data[j, :, :].min()) / (liver_tumor_data[j, :, :].max() - liver_tumor_data[j, :, :].min()) * 255
                img2 = liver_tumor_label[j, :, :] * 122
                cv2.imwrite("%s/%s-%d.png" % (outpath, img_name, j), img1)
                cv2.imwrite("%s/%s-%d.png" % (outpath2, img_name, j), img2)

Nii转DCM

注意,因为原来的nii文件中就没有DICOM文件中特有的头文件信息,所以转换出来的DICOM文件实际上是缺少了头文件的信息的,算是伪DICOM文件,在使用的时候个人感觉并没有什么不对劲的地方,DICOM文件转为PNG图片显示出来的效果基本和Nii转PNG的效果一致,但是要特别注意的是读取DICOM文件的时候要强制读取。
单个Nii转DCM

def nii2dcm_single(nii_path, IsData = True):
    save_folder = './dcm/dcm_single'
    if not os.path.exists(save_folder):
        os.makedirs(save_folder)
    ori_data = sitk.ReadImage(nii_path)  # 读取一个数据
    data1 = sitk.GetArrayFromImage(ori_data)  # 获取数据的array
    if IsData:  # 过滤掉其他无关的组织,标签不需要这步骤
        data1[data1 > 250] = 250
        data1[data1 < -250] = -250
    img_name = os.path.split(nii_path)  #分离文件名
    img_name = img_name[-1]
    img_name = img_name.split('.')
    img_name = img_name[0]
    i = data1.shape[0]
    # 关键部分
    castFilter = sitk.CastImageFilter()
    castFilter.SetOutputPixelType(sitk.sitkInt16)
    for j in range(0, i):   #将每一张切片都转为png
        if IsData:  # 数据
            slice_i = data1[j, :, :]
            data_img = sitk.GetImageFromArray(slice_i)
            # Convert floating type image (imgSmooth) to int type (imgFiltered)
            data_img = castFilter.Execute(data_img)
            sitk.WriteImage(data_img, "%s/%s-%d.dcm" % (save_folder, img_name, j))
        else:   # 标签
            slice_i = data1[j, :, :] * 122
            label_img = sitk.GetImageFromArray(slice_i)
            # Convert floating type image (imgSmooth) to int type (imgFiltered)
            label_img = castFilter.Execute(label_img)
            sitk.WriteImage(label_img, "%s/%s-%d.dcm" % (save_folder, img_name, j))

批量转换

def nii2dcm(data_path, lable_path, IsTrain = False):
    save_folder = './dcm'
    nii_list = os.listdir(lable_path)
    for nii_label in nii_list:
        print("process:", nii_label)
        data1 = sitk.ReadImage(os.path.join(lable_path, nii_label)) # 读取一个数据
        liver_tumor_label = sitk.GetArrayFromImage(data1)  # 获取数据的array
        print(np.unique(liver_tumor_label))
        data2 = sitk.ReadImage(os.path.join(data_path, nii_label.replace('segmentation', 'volume')))  # 读取一个数据
        liver_tumor_data = sitk.GetArrayFromImage(data2)  # 获取数据的array
        slice_num = liver_tumor_label.shape[0]     # 获取切片数量
        if IsTrain:
            save_img = save_folder+'/train'
        else:
            save_img = save_folder + '/val'
        label_path = save_folder+'/label'     # 设置保存路径
        if not os.path.exists(save_img):      # 判断文件目录是否存在,不存在则创建
            os.makedirs(save_img)
        if not os.path.exists(label_path):
            os.makedirs(label_path)

        img_name = os.path.split(nii_label.replace('segmentation', 'volume'))     # 分离文件名,用以保存时的文件名前缀
        img_name = img_name[-1]
        img_name = img_name.split('.')
        img_name = img_name[0]

        for i in range(0, slice_num):
            # 关键部分
            if liver_tumor_label[i, :, :].max() > 0:    # 肝脏标签图片
                label_img = sitk.GetImageFromArray(liver_tumor_label[i, :, :] * 122)
                data_img = sitk.GetImageFromArray(liver_tumor_data[i, :, :])
                castFilter = sitk.CastImageFilter()
                castFilter.SetOutputPixelType(sitk.sitkInt16)
                # Convert floating type image (imgSmooth) to int type (imgFiltered)
                label_img = castFilter.Execute(label_img)
                data_img = castFilter.Execute(data_img)
                sitk.WriteImage(label_img, "%s/%s-%d.dcm" % (label_path, img_name, i))
                sitk.WriteImage(data_img, "%s/%s-%d.dcm" % (save_img, img_name, i))

DCM转PNG

单个DCM转PNG

def dcm2png_single(dcm_path):
    save_pa = r'./png/single'
    if not os.path.exists(save_pa):
        os.makedirs(save_pa)
    img_name = os.path.split(dcm_path.replace('.dcm', '.png'))  # 替换后缀名并分离路径
    img_name = img_name[-1]
    ds = pydicom.read_file(dcm_path, force=True)       # 注意这里,强制读取
    img = ds.pixel_array  # 提取图像信息
    cv2.imwrite(os.path.join(save_pa, img_name), img)

批量转换

def dcm2png(dcm_path, label_path):
    labellist = os.listdir(label_path)
    save_data = r'./png/dcm_png_data'
    save_lab = r'./png/dcm_png_lab'
    if not os.path.exists(save_data):
        os.makedirs(save_data)
    if not os.path.exists(save_lab):
        os.makedirs(save_lab)
    for lab in labellist:
        print('process', lab)
        ds = pydicom.read_file(os.path.join(label_path, lab), force=True)   # 注意这里,强制读取
        label = ds.pixel_array  # 提取图像信息
        ds1 = pydicom.read_file(os.path.join(dcm_path, lab), force=True)
        img = ds1.pixel_array  # 提取图像信息
        cv2.imwrite(os.path.join(save_data, lab.replace('.dcm', '.png')), img)
        cv2.imwrite(os.path.join(save_lab, lab.replace('.dcm', '.png')), label)

完整代码

import os
import SimpleITK as sitk
import cv2
import pydicom
import numpy as np


def nii2png_single(nii_path, IsData = True):
    ori_data = sitk.ReadImage(nii_path)  # 读取一个数据
    data1 = sitk.GetArrayFromImage(ori_data)  # 获取数据的array
    if IsData:  #过滤掉其他无关的组织,标签不需要这步骤
        data1[data1 > 250] = 250
        data1[data1 < -250] = -250
    img_name = os.path.split(nii_path)  #分离文件名
    img_name = img_name[-1]
    img_name = img_name.split('.')
    img_name = img_name[0]
    i = data1.shape[0]
    png_path = './png/single_png'   #图片保存位置
    if not os.path.exists(png_path):
        os.makedirs(png_path)
    for j in range(0, i):   #将每一张切片都转为png
        if IsData:  # 数据
            #归一化
            slice_i = (data1[j, :, :] - data1[j, :, :].min()) / (data1[j, :, :].max() - data1[j, :, :].min()) * 255
            cv2.imwrite("%s/%s-%d.png" % (png_path, img_name, j), slice_i)  #保存
        else:   # 标签
            slice_i = data1[j, :, :] * 122
            cv2.imwrite("%s/%s-%d.png" % (png_path, img_name, j), slice_i)  # 保存


def nii2png(data_path, label_path):
    dataname_list2 = os.listdir(label_path)
    for nii_label in dataname_list2:
        print("process:", nii_label)
        data1 = sitk.ReadImage(os.path.join(data_path, nii_label.replace('segmentation', 'volume'))) # 读取一个数据
        liver_tumor_data = sitk.GetArrayFromImage(data1)  # 获取数据的array
        data2 = sitk.ReadImage(os.path.join(label_path, nii_label))  # 读取一个数据
        liver_tumor_label = sitk.GetArrayFromImage(data2)  # 获取数据的array
        img_name = os.path.split(nii_label.replace('segmentation', 'volume'))     # 分离文件名,用以保存时的文件名前缀
        img_name = img_name[-1]
        img_name = img_name.split('.')
        img_name = img_name[0]
        i = liver_tumor_label.shape[0]
        liver_tumor_data[liver_tumor_data > 250] = 250
        liver_tumor_data[liver_tumor_data < -250] = -250
        outpath = r'./png/data_png'  # 数据保存文件夹
        outpath2 = r'./png/label_png'   # 标签保存文件夹
        if not os.path.exists(outpath):
            os.makedirs(outpath)
        if not os.path.exists(outpath2):
            os.makedirs(outpath2)
        for j in range(0, i):
            if liver_tumor_label[j, :, :].max() > 0:    # 只保存有肝脏的切片
                img1 = (liver_tumor_data[j, :, :] - liver_tumor_data[j, :, :].min()) / (liver_tumor_data[j, :, :].max() - liver_tumor_data[j, :, :].min()) * 255
                img2 = liver_tumor_label[j, :, :] * 122
                cv2.imwrite("%s/%s-%d.png" % (outpath, img_name, j), img1)
                cv2.imwrite("%s/%s-%d.png" % (outpath2, img_name, j), img2)


def nii2dcm_single(nii_path, IsData = True):
    save_folder = './dcm/dcm_single'
    if not os.path.exists(save_folder):
        os.makedirs(save_folder)
    ori_data = sitk.ReadImage(nii_path)  # 读取一个数据
    data1 = sitk.GetArrayFromImage(ori_data)  # 获取数据的array
    if IsData:  # 过滤掉其他无关的组织,标签不需要这步骤
        data1[data1 > 250] = 250
        data1[data1 < -250] = -250
    img_name = os.path.split(nii_path)  #分离文件名
    img_name = img_name[-1]
    img_name = img_name.split('.')
    img_name = img_name[0]
    i = data1.shape[0]
    # 关键部分
    castFilter = sitk.CastImageFilter()
    castFilter.SetOutputPixelType(sitk.sitkInt16)
    for j in range(0, i):   #将每一张切片都转为png
        if IsData:  # 数据
            slice_i = data1[j, :, :]
            data_img = sitk.GetImageFromArray(slice_i)
            # Convert floating type image (imgSmooth) to int type (imgFiltered)
            data_img = castFilter.Execute(data_img)
            sitk.WriteImage(data_img, "%s/%s-%d.dcm" % (save_folder, img_name, j))
        else:   # 标签
            slice_i = data1[j, :, :] * 122
            label_img = sitk.GetImageFromArray(slice_i)
            # Convert floating type image (imgSmooth) to int type (imgFiltered)
            label_img = castFilter.Execute(label_img)
            sitk.WriteImage(label_img, "%s/%s-%d.dcm" % (save_folder, img_name, j))


def nii2dcm(data_path, lable_path, IsTrain = False):
    save_folder = './dcm'
    nii_list = os.listdir(lable_path)
    for nii_label in nii_list:
        print("process:", nii_label)
        data1 = sitk.ReadImage(os.path.join(lable_path, nii_label)) # 读取一个数据
        liver_tumor_label = sitk.GetArrayFromImage(data1)  # 获取数据的array
        print(np.unique(liver_tumor_label))
        data2 = sitk.ReadImage(os.path.join(data_path, nii_label.replace('segmentation', 'volume')))  # 读取一个数据
        liver_tumor_data = sitk.GetArrayFromImage(data2)  # 获取数据的array
        slice_num = liver_tumor_label.shape[0]     # 获取切片数量
        if IsTrain:
            save_img = save_folder+'/train'
        else:
            save_img = save_folder + '/val'
        label_path = save_folder+'/label'     # 设置保存路径
        if not os.path.exists(save_img):      # 判断文件目录是否存在,不存在则创建
            os.makedirs(save_img)
        if not os.path.exists(label_path):
            os.makedirs(label_path)

        img_name = os.path.split(nii_label.replace('segmentation', 'volume'))     # 分离文件名,用以保存时的文件名前缀
        img_name = img_name[-1]
        img_name = img_name.split('.')
        img_name = img_name[0]

        for i in range(0, slice_num):
            # 关键部分
            if liver_tumor_label[i, :, :].max() > 0:    # 肝脏标签图片
                label_img = sitk.GetImageFromArray(liver_tumor_label[i, :, :] * 122)
                data_img = sitk.GetImageFromArray(liver_tumor_data[i, :, :])
                castFilter = sitk.CastImageFilter()
                castFilter.SetOutputPixelType(sitk.sitkInt16)
                # Convert floating type image (imgSmooth) to int type (imgFiltered)
                label_img = castFilter.Execute(label_img)
                data_img = castFilter.Execute(data_img)
                sitk.WriteImage(label_img, "%s/%s-%d.dcm" % (label_path, img_name, i))
                sitk.WriteImage(data_img, "%s/%s-%d.dcm" % (save_img, img_name, i))


def dcm2png_single(dcm_path):
    save_pa = r'./png/single'
    if not os.path.exists(save_pa):
        os.makedirs(save_pa)
    img_name = os.path.split(dcm_path.replace('.dcm', '.png'))  # 替换后缀名并分离路径
    img_name = img_name[-1]
    ds = pydicom.read_file(dcm_path, force=True)       # 注意这里,强制读取
    img = ds.pixel_array  # 提取图像信息
    cv2.imwrite(os.path.join(save_pa, img_name), img)


def dcm2png(dcm_path, label_path):
    labellist = os.listdir(label_path)
    save_data = r'./png/dcm_png_data'
    save_lab = r'./png/dcm_png_lab'
    if not os.path.exists(save_data):
        os.makedirs(save_data)
    if not os.path.exists(save_lab):
        os.makedirs(save_lab)
    for lab in labellist:
        print('process', lab)
        ds = pydicom.read_file(os.path.join(label_path, lab), force=True)   # 注意这里,强制读取
        label = ds.pixel_array  # 提取图像信息
        ds1 = pydicom.read_file(os.path.join(dcm_path, lab), force=True)
        img = ds1.pixel_array  # 提取图像信息
        cv2.imwrite(os.path.join(save_data, lab.replace('.dcm', '.png')), img)
        cv2.imwrite(os.path.join(save_lab, lab.replace('.dcm', '.png')), label)


if __name__ == "__main__":
    # 单个nii文件转png
    nii_single = r'G:\Python\liversegment\ImageResource\ImageTraning\data\volume-0.nii'
    nii2png_single(nii_single, IsData=False)
    # 按照标签提取切片,只保存有肝脏的切片
    niipath = r'G:\Python\liversegment\ImageResource\ImageTraning\data'
    labpath = r'G:\Python\liversegment\ImageResource\ImageTraning\label'
    nii2png(niipath, labpath)

    # 单个nii转dcm
    nii2dcm_single(nii_single, True)
    # 批量nii转dcm
    nii2dcm(niipath, labpath, IsTrain=True)

    # 单个dcm转png
    dcm_single = r'F:\Liver\Unet_4_23\dcm\train\volume-0-55.dcm'
    dcm2png_single(dcm_single)
    # 批量dcm转png
    dcm_pa = r'F:\Liver\Unet_4_23\dcm\train'
    lab_dcm = r'F:\Liver\Unet_4_23\dcm\label'
    dcm2png(dcm_pa, lab_dcm)

结束语

代码基本上都是自己从网上找到,然后根据自己的实际来修改使用的,代码全部都测试过,自己用的时候没有问题。本人的水平有限,如有不当之处,敬请指正。

你可能感兴趣的:(深度学习,python,经验分享)