代码实践:将四维的MRI图像转换为三维的图像的算法

在数据处理的过程中,我们经常碰到有的医学影像,例如MRI除了X, Y, Z三个维度外,还拥有第四个维度(通常,这个维度是时间维度),这使得我们无法按照常规的方式进行重采样,resize等预处理操作。所以我们需要将四维图像转换为三维,代码如下:

import SimpleITK as sitk
import numpy as np

def normalize_direction_matrix(matrix):
    """
    将方向矩阵归一化为正交矩阵。
    """
    matrix = np.array(matrix).reshape(3, 3)
    u, _, vh = np.linalg.svd(matrix)  # 奇异值分解
    ortho_matrix = np.dot(u, vh)  # 重新计算正交矩阵
    return ortho_matrix.flatten().tolist()


def reorder_axes_for_itk_snap(direction):
    """
    调整方向矩阵以匹配ITK-SNAP中水平面、矢状面、冠状面的顺序。
    """
    direction_matrix = np.array(direction).reshape(3, 3)
    reordered_matrix = direction_matrix[[0, 2, 1], :]  # 调整顺序
    return reordered_matrix.flatten().tolist()

def flip_image_axes(img_array):
    """
    翻转图像以纠正上下或左右颠倒的问题。
    顺时针旋转 180 度并左右镜像变换等价于沿 z 和 x 轴翻转。
    """
    # 沿y轴翻转图像 (上下翻转)
    return np.flip(img_array, axis=1)  # 沿Y轴翻转

def convert_4d_to_3d(input_path, output_path):
    """
    将四维MRI图像(x, y, z, t)转换为三维图像(x, y, z)。
    参数:
    - input_path: 输入四维图像的路径(.nii或.nii.gz文件)。
    - output_path: 输出三维图像的路径。
    """
    # 读取四维图像
    img_4d = sitk.ReadImage(input_path)
    img_array = sitk.GetArrayFromImage(img_4d)  # 转换为numpy数组,形状为 (t, z, y, x)

    # 检查输入的维度是否为4D
    if img_array.ndim != 4:
        raise ValueError("输入图像不是四维图像,请检查输入文件。")

    # 取第四维的第一个切片 (t=0)
    img_3d_array = img_array[0, :, :, :]  # 取第一个时间点的3D数据

    # 翻转图像纠正上下颠倒
    img_3d_array = flip_image_axes(img_3d_array)

    # 将numpy数组转换回SimpleITK图像
    img_3d = sitk.GetImageFromArray(img_3d_array)

    # 调整方向矩阵和其他元信息
    original_direction = img_4d.GetDirection()[:9]  # 方向只保留3x3部分
    reordered_direction = reorder_axes_for_itk_snap(original_direction)  # 调整方向矩阵顺序
    normalized_direction = normalize_direction_matrix(reordered_direction)  # 归一化方向矩阵
    img_3d.SetDirection(normalized_direction)
    img_3d.SetSpacing(img_4d.GetSpacing()[:3])  # 间距只保留前3个值
    img_3d.SetOrigin(img_4d.GetOrigin()[:3])  # 原点只保留前3个值

    # 保存三维图像
    sitk.WriteImage(img_3d, output_path)
    print(f"3D图像已保存至: {output_path}")



# 示例用法
if __name__ == "__main__":
    input_file = "input_4d_image.nii"  # 替换为你的输入文件路径
    output_file = "output_3d_image.nii"  # 替换为你的输出文件路径
    convert_4d_to_3d(input_file, output_file, method="min")

MRI图像具有四个维度 (x, y, z, t),其中最后一个维度 t 通常代表时间、通道或特定采样情况。在你的场景中,可以通过合适的策略将四维数据处理为三维。常用的策略包括:

  1. 按时间维度取平均值:对 t 维度的数据取平均,生成一个单通道的三维图像。
  2. 选择特定通道:如果知道 t 维度对应具体的通道,可以选择其中一个通道。
  3. 按时间维度取最大值或最小值:对 t 维度的值取最大或最小值。

参数说明

  1. method:

    • "mean":对时间维度取平均值(默认)。
    • "max":取时间维度的最大值。
    • "min":取时间维度的最小值。
    • "channel":选择特定通道(需要修改代码中的 channel_index)。
  2. 输入和输出路径

    • 替换 input_file 和 output_file 为你的实际文件路径。

修改后的三维图像

运行代码后,输出的 .nii 文件将只有 (x, y, z) 这三个维度,可以直接用于后续分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Trouville01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值