医学图像文件格式转换办法

1.将.nii.gz(.nii)文件转换.pkl或.pkl文件数据合成:

(下面有多个功能,建议看实例的输入输出文件格式,选择对应的功能)

'''
Author: <qilin>
Email: <EMAIL>
Date: 2024-02-28
'''
import pickle
import numpy as np
import nibabel as nib


'''
Part 1.
nii to pkl
'''
def transform_array(arr):
    # 获取arr的维度
    shape = np.shape(arr)
    # 创建一个与arr[0]形状相同的空数组brr
    brr = np.zeros(shape[1:], dtype=int)

    # 遍历arr中的元素
    for i, subarr in enumerate(arr):
        # 找到非零元素的索引
        indices = np.nonzero(subarr)
        # 将brr中相应位置的值设置为i+1
        brr[indices] = i + 1

    return brr


def nii_to_pkl(nii_file_path, label_file_path, pkl_file_path):
    # 加载 NIfTI 文件
    nii_img = nib.load(nii_file_path)
    label_img = nib.load(label_file_path)

    # 获取数据数组
    data = nii_img.get_fdata()
    labels = label_img.get_fdata()

    # 数据保存
    data = np.squeeze(data, axis=-1)  # 将数据维度从 (120, 128, 128, 1) 转换为 (120, 128, 128)
    image = np.array(list(data), dtype=np.float32)

    labels = np.transpose(labels.squeeze(), (3, 0, 1, 2))  # 将标签维度从 (120, 128, 128, 6) 转换为 (6, 120, 128, 128)
    seg = transform_array(labels)

    # 将数据存入元组中
    data = (image, seg)


    # 打开文件并保存数据
    with open(pkl_file_path, 'wb') as f:
        pickle.dump(data, f)

    print("数据已保存到文件:", pkl_file_path)

def main_1():
    for i in range(65,73):
        case_number = str(i).zfill(6)
        nii_file_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro/val/mr_images/case{case_number}.nii.gz'
        label_file_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro/val/mr_labels/case{case_number}.nii.gz'
        pkl_file_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro_pkl/mr/val/case{case_number}.pkl'
        nii_to_pkl(nii_file_path, label_file_path, pkl_file_path)


'''
Part 2.
pkl from mr and us to mr_and_us
'''


def mr_and_us(mr_path, us_path, mr_and_us_path):
    # 加载文件
    with open(mr_path, 'rb') as f:
        mr_img, mr_seg = pickle.load(f)
    with open(us_path, 'rb') as f:
        us_img, us_seg = pickle.load(f)
    # 赋值
    data_1 = np.array(list(mr_img), dtype=np.float32)
    data_2 = np.array(list(us_img), dtype=np.float32)
    data_3 = np.array(list(mr_seg), dtype=np.float32)
    data_4 = np.array(list(us_seg), dtype=np.float32)
    data = (data_1, data_2, data_3, data_4)
    # 打开文件并保存数据
    with open(mr_and_us_path, 'wb') as f:
        pickle.dump(data, f)

    print("数据已保存到文件:", mr_and_us_path)

def main_2():
    for i in range(65):
        case_number = str(i).zfill(6)
        mr_path = r'F:\program\database\Multimodal\muregpro_pkl\mr\val\case{case_number}.pkl'
        us_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro_pkl/us/train/case{case_number}.pkl'
        mr_and_us_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro_pkl/mr_and_us/train/case{case_number}.pkl'
        mr_and_us(mr_path, us_path, mr_and_us_path)



'''
Part 3.
pkl from mr and mr to mr_and_mr
'''
def mr_and_mr(mr_path_1, mr_path_2, mr_and_mr_path):
    # 加载文件
    with open(mr_path_1, 'rb') as f:
        mr_img, mr_seg = pickle.load(f)
    with open(mr_path_2, 'rb') as f:
        us_img, us_seg = pickle.load(f)
    # 赋值
    data_1 = np.array(list(mr_img), dtype=np.float32)
    data_2 = np.array(list(us_img), dtype=np.float32)
    data_3 = np.array(list(mr_seg), dtype=np.float32)
    data_4 = np.array(list(us_seg), dtype=np.float32)
    data = (data_1, data_2, data_3, data_4)
    # 打开文件并保存数据
    with open(mr_and_mr_path, 'wb') as f:
        pickle.dump(data, f)

    print("数据已保存到文件:", mr_and_mr_path)

def main_3():
    for i in range(65,72):
        case_number = str(i).zfill(6)
        case_number_2 = str(i+1).zfill(6)
        mr_path_1 = f'F:/program/database/Multimodal/muregpro_ql/us/val/case{case_number}.pkl'
        mr_path_2 = f'F:/program/database/Multimodal/muregpro_ql/us/val/case{case_number_2}.pkl'
        mr_and_mr_path = f'F:/program/database/Multimodal/muregpro_ql/us/test/case{case_number}.pkl'
        mr_and_us(mr_path_1, mr_path_2, mr_and_mr_path)

'''
Part 4.
pkl from us and us to us_and_us
'''
def mr_and_mr(us_path_1, us_path_2, us_and_us_path):
    # 加载文件
    with open(us_path_1, 'rb') as f:
        mr_img, mr_seg = pickle.load(f)
    with open(us_path_2, 'rb') as f:
        us_img, us_seg = pickle.load(f)
    # 赋值
    data_1 = np.array(list(mr_img), dtype=np.float32)
    data_2 = np.array(list(us_img), dtype=np.float32)
    data_3 = np.array(list(mr_seg), dtype=np.float32)
    data_4 = np.array(list(us_seg), dtype=np.float32)
    data = (data_1, data_2, data_3, data_4)
    # 打开文件并保存数据
    with open(us_and_us_path, 'wb') as f:
        pickle.dump(data, f)

    print("数据已保存到文件:", us_and_us_path)

def main_4():
    for i in range(65,72):
        case_number = str(i).zfill(6)
        case_number_2 = str(i+1).zfill(6)
        us_path_1 = f'F:/program/database/Multimodal/muregpro_pkl/us/val/case{case_number}.pkl'
        us_path_2 = f'F:/program/database/Multimodal/muregpro_pkl/us/val/case{case_number_2}.pkl'
        us_and_us_path = f'F:/program/database/Multimodal/muregpro_pkl/us/test/case{case_number}.pkl'
        mr_and_us(us_path_1, us_path_2, us_and_us_path)

'''
Part 5.
nii from (120, 128, 128, 1) to (120, 128, 128)
'''


def nii_to_0(nii_file_path, out_path):
    # 加载 NIfTI 文件
    nii_img = nib.load(nii_file_path)

    # 获取数据数组
    data = nii_img.get_fdata()

    # 转换数据维度
    data = data[:, :, :, 0]

    # 创建新的 NIfTI 图像对象
    new_img = nib.Nifti1Image(data, nii_img.affine)

    # 保存新的 NIfTI 文件
    nib.save(new_img, out_path)

    print("数据已保存到文件:", out_path)

def main_5():
    for i in range(65,73):
        case_number = str(i).zfill(6)
        nii_file_path = f'F:/program/database/Multimodal/muregpro/val/us_images/case{case_number}.nii.gz'
        out_path = f'F:/program/database/Multimodal/muregpro_pkl/us/test_nii/case{case_number}.nii.gz'
        nii_to_0(nii_file_path, out_path)



'''
Part 6.
nii from (120, 128, 128, 1) to (160, 192, 224)
nii's image and label compound
'''

def change_size():
    a = 1


def nii_to_pkl_new(image_path, label_path, out_path):
    # 加载 NIfTI 文件
    nii_img = nib.load(image_path)
    nii_label = nib.load(label_path)

    # 获取数据数组
    data_img = nii_img.get_fdata()
    data_label = nii_label.get_fdata()


    # 数据转换
    data_img = np.squeeze(data_img, axis=-1)  # 将数据维度从 (120, 128, 128, 1) 转换为 (160, 192, 224)
    image = np.array(list(data_img), dtype=np.float32)

    data_label = np.transpose(data_label.squeeze(), (3, 0, 1, 2))  # 将标签维度从 (120, 128, 128, 6) 转换为 (6, 120, 128, 128)
    seg = transform_array(data_label)  # 标签维度从(6, 120, 128, 128) 变为 (120, 128, 128)

    # 数据大小变换:从(120, 128, 128) 到 (160, 192, 224)
    target_shape = (160, 192, 224) # 定义目标维度
    pad_widths = [(0, target_shape[i] - image.shape[i]) for i in range(len(target_shape))] # 计算在每个维度上的填充量
    image = np.pad(image, pad_widths, mode='constant') # 使用numpy.pad()函数进行填充

    pad_widths = [(0, target_shape[i] - seg.shape[i]) for i in range(len(target_shape))] # 计算在每个维度上的填充量
    seg = np.pad(seg, pad_widths, mode='constant') # 使用numpy.pad()函数进行填充

    # 将数据存入元组中
    data = (image, seg)

    # 打开文件并保存数据
    with open(out_path, 'wb') as f:
        pickle.dump(data, f)

    print("数据已保存到文件:", out_path)




def main_7():
    for i in range(65,73):
        case_number = str(i).zfill(6)
        image_path = f'F:/program/database/Multimodal/muregpro/val/us_images/case{case_number}.nii.gz'
        label_path = f'F:/program/database/Multimodal/muregpro/val/us_labels/case{case_number}.nii.gz'
        out_path = f'F:/program/database/Multimodal/muregpro_ql/us/val/case{case_number}.pkl'
        nii_to_pkl_new(image_path, label_path, out_path)


main_3()

2.将.pkl文件转换.nii.gz(.nii):

import os
import numpy as np
import pickle
import nibabel as nib


'''
Part 0.
局部函数:维度互转
'''

# 0.1 :多尺度二值化数据转化为单尺度多值化
def transform_array(arr):
    # 获取arr的维度
    shape = np.shape(arr)
    # 创建一个与arr[0]形状相同的空数组brr
    brr = np.zeros(shape[1:], dtype=int)

    # 遍历arr中的元素
    for i, subarr in enumerate(arr):
        # 找到非零元素的索引
        indices = np.nonzero(subarr)
        # 将brr中相应位置的值设置为i+1
        brr[indices] = i + 1

    return brr


# 0.2 :单尺度多值化转化为多尺度二值化数据
def transform_array_Anti(brr):
    # 确定arr的行数,brr中的最大值加1
    num_rows = max(brr) + 1 if brr.any() else 0
    # 确定arr的列数,brr的长度
    num_cols = len(brr)

    # 初始化arr为全0数组
    arr = np.zeros((num_rows, num_cols), dtype=int)

    # 遍历brr,根据brr的值在arr中放置元素
    for i, value in enumerate(brr):
        if value != 0:
            arr[value - 1, i] = 1  # 索引从1变为0,所以减1

    return arr


'''
Part 1.
pkl to nii
'''
def load_pkl_and_save_nii(pkl_file_path, nii_file_path, label_file_path):
    # 打开Pickle文件并读取数据
    with open(pkl_file_path, 'rb') as f:
        data = pickle.load(f)

    # 检查data是否为元组且包含两个元素
    if not isinstance(data, tuple) or len(data) != 2:
        raise ValueError("Pickle文件中的数据不是一个包含两个元素的元组。")

    # 分别获取图像和分割数据
    image, seg = data

    # 将图像和分割数据转换为NIfTI格式
    image_nii = nib.Nifti1Image(image, affine=np.eye(4))  # 假设affine矩阵为单位矩阵
    seg_nii = nib.Nifti1Image(seg, affine=np.eye(4))  # 假设affine矩阵为单位矩阵

    # 保存NIfTI图像和标签文件
    image_nii.to_filename(nii_file_path)
    seg_nii.to_filename(label_file_path)

    print(f"图像和标签文件已保存到: {nii_file_path} 和 {label_file_path}")


def main_1():
    for i in range(65, 73):
        case_number = str(i).zfill(6)
        pkl_file_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro_pkl/mr/val/case{case_number}.pkl'
        nii_file_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro/val/mr_images/case{case_number}.nii.gz'
        label_file_path = f'F:/文件/麒麟/program/python/TransMorph_Transformer_for_Medical_Image_Registration-main/Data/muregpro/val/mr_labels/case{case_number}.nii.gz'

        # 检查文件是否存在
        if not os.path.exists(pkl_file_path):
            print(f"文件 {pkl_file_path} 不存在。")
            continue

        load_pkl_and_save_nii(pkl_file_path, nii_file_path, label_file_path)





if __name__ == "__main__":
    main_1()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值