SimpleITK 读取 NIfTI 后,数组默认是zhw顺序((z, y, x))
- 若需
(x, y, z)顺序,需手动转置(np.transpose(array, (2, 1, 0)))。 - 元数据(如
GetSize())仍遵循 NIfTI 的(x, y, z)约定,需注意区分数组顺序和元数据顺序。
1 simpleitk和numpy的维度问题
- NumPy 数组:始终使用
(D, H, W)顺序(3D)或(H, W)顺序(2D)。 - SimpleITK 图像:
GetImageFromArray和GetArrayFromImage会自动处理 DHW ↔ WHD 的转换,无需手动转置。# 正确用法示例 arr_dhw = np.random.rand(64, 256, 256) # (D, H, W) itk_img = sitk.GetImageFromArray(arr_dhw) # 自动转为 ITK (W, H, D) arr_back = sitk.GetArrayFromImage(itk_img) # 自动转回 (D, H, W)
GetImageFromArray会丢失原始图像的物理坐标信息(如像素间距、原点)。- 解决:手动设置元数据:
itk_img = sitk.GetImageFromArray(arr_dhw) itk_img.SetSpacing([1.0, 1.0, 1.0]) # 设置体素间距 (x, y, z) itk_img.SetOrigin([0, 0, 0]) # 设置原点
验证交互正确性的方法
# 检查 NumPy 和 ITK 的维度一致性 arr_dhw = np.random.rand(64, 256, 256) itk_img = sitk.GetImageFromArray(arr_dhw) # 验证转换无失真 assert arr_dhw.shape == (64, 256, 256) # NumPy (D, H, W) assert itk_img.GetSize() == (256, 256, 64) # ITK (W, H, D) assert np.allclose(arr_dhw, sitk.GetArrayFromImage(itk_img))坚持使用(D, H, W)顺序的 NumPy 数组与 SimpleITK 交互,可避免维度错误。
2 SetDirection()和GetDirection()的矛盾性
使用过程发现读取nii后GetDirection得到实施一个一维16个元素的元组,直接SetDirection失败。原因如下:
direction = src.GetDirection() # 如果是 3D 图像(9 个元素) if len(direction) == 9: direction_matrix = tuple(direction) # 直接传入 9 个元素的元组 # 或者构造 3x3 矩阵(可选) # direction_matrix = ( # direction[0], direction[1], direction[2], # direction[3], direction[4], direction[5], # direction[6], direction[7], direction[8] # ) # 如果是 2D 图像(4 个元素) elif len(direction) == 4: direction_matrix = tuple(direction) # 直接传入 4 个元素的元组 # 或者构造 2x2 矩阵(可选) # direction_matrix = ( # direction[0], direction[1], # direction[2], direction[3] # ) # 如果是 16 个元素(4x4 矩阵),需要提取前 9 个(3x3) elif len(direction) == 16: direction_matrix = ( direction[0], direction[1], direction[2], direction[4], direction[5], direction[6], direction[8], direction[9], direction[10] ) else: raise ValueError("Unsupported direction format!") # 设置方向 target_img = sitk.GetImageFromArray(arr) # 你的目标图像 target_img.SetDirection(direction_matrix) # 正确设置方向import SimpleITK as sitk import numpy as np # 读取源图像 src = sitk.ReadImage("source.nii") direction = src.GetDirection() # 检查方向矩阵的形状 if len(direction) == 9: # 3D 图像 direction_matrix = direction elif len(direction) == 4: # 2D 图像 direction_matrix = direction elif len(direction) == 16: # 4x4 矩阵,提取 3x3 direction_matrix = ( direction[0], direction[1], direction[2], direction[4], direction[5], direction[6], direction[8], direction[9], direction[10] ) else: raise ValueError("Unsupported direction format!") # 创建目标图像并设置方向 arr = sitk.GetArrayFromImage(src) # 获取 NumPy 数组 target_img = sitk.GetImageFromArray(arr) target_img.SetDirection(direction_matrix) # 正确设置方向 # 保存 sitk.WriteImage(target_img, "output.nii")如果是9个元素,直接target_img.SetDirection(src.GetDirection())
如果是 16 个元素(4x4 矩阵),提取前 9 个构造 3x3 方向矩阵