在数据处理的过程中,我们经常碰到有的医学影像,例如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
通常代表时间、通道或特定采样情况。在你的场景中,可以通过合适的策略将四维数据处理为三维。常用的策略包括:
- 按时间维度取平均值:对
t
维度的数据取平均,生成一个单通道的三维图像。 - 选择特定通道:如果知道
t
维度对应具体的通道,可以选择其中一个通道。 - 按时间维度取最大值或最小值:对
t
维度的值取最大或最小值。
参数说明
-
method
:"mean"
:对时间维度取平均值(默认)。"max"
:取时间维度的最大值。"min"
:取时间维度的最小值。"channel"
:选择特定通道(需要修改代码中的channel_index
)。
-
输入和输出路径:
- 替换
input_file
和output_file
为你的实际文件路径。
- 替换
修改后的三维图像
运行代码后,输出的 .nii
文件将只有 (x, y, z)
这三个维度,可以直接用于后续分析。