如何将XYZ格式NIfTI MRI图像转为XYZ格式NumPy数组并正确显示切片
解决NIfTI转XYZ格式NumPy数组及切片正方形显示问题
核心问题分析
NIfTI格式的MRI图像默认采用RAS空间轴序(右-前-上),和你期望的XYZ轴序(X/Y为切片平面、Z为切片数量)常存在映射偏差,导致读取后轴对应错误;切片显示变形则是因为默认显示未强制等比例缩放。
分步解决方法
1. 正确映射NIfTI轴到XYZ格式
读取NIfTI文件后先打印data.shape,根据输出调整轴序:
- 若原始shape为
(Z, X, Y)或(X, Z, Y)这类非XYZ结构,用np.transpose调整轴顺序,确保最终shape为(X, Y, Z)(X/Y是单切片宽高,Z是切片总数); - 若原始数据已经是
(X, Y, Z),则无需额外转置。
2. 修正切片旋转方向
你代码中np.rot90(slice, axes=(1,0))等价于默认旋转90度,可能导致轴方向颠倒。可通过调整旋转次数(0/1/2/3)匹配正确的解剖方向。
3. 强制切片显示为正方形
用matplotlib显示切片时,添加plt.axis('equal')或plt.gca().set_aspect('equal', adjustable='box'),强制X/Y轴等比例缩放,避免图像拉伸变形。
修改后的完整代码
import os import numpy as np import nibabel as nib import matplotlib.pyplot as plt # 读取NIfTI文件 img = nib.load(os.path.join(data_path, f"{list_dir[i]}.nii.gz")) data = img.get_fdata() print(f"原始数据shape: {data.shape}") # 调整轴序为XYZ格式(根据实际shape修改转置参数) # 示例:若原始shape是(Z, X, Y),转置为(X, Y, Z)则用np.transpose(data, (1, 2, 0)) data = np.transpose(data, (0, 1, 2)) # 保留原代码转置逻辑,实际需根据输出调整 print(f"调整后XYZ格式shape: {data.shape}") # 提取所有切片并调整方向 slices = [] for z_idx in range(data.shape[2]): # 获取X-Y平面的切片 slice_data = data[:, :, z_idx] # 调整旋转方向(根据显示效果选0/1/2/3) slice_data = np.rot90(slice_data, k=1) # k为旋转次数,每次90度 slices.append(slice_data) # 转换为XYZ格式的NumPy数组 slices_array = np.array(slices) print(f"最终切片数组shape: {slices_array.shape}") # 测试显示切片并强制正方形 test_slice = slices_array[0] plt.imshow(test_slice, cmap="gray") plt.axis("equal") # 强制等比例,显示为正方形 plt.show()
关键注意事项
- 轴序调整需根据
data.shape实际输出修改np.transpose参数,比如原始shape为(150, 200, 150),若150是切片数,需转置为(200, 150, 150)对应(X,Y,Z); - 旋转次数
k需根据切片解剖方向调整,比如旋转1次后图像颠倒,可改为k=3(等价逆时针转270度); - 处理JPEG转XYZ数组时,确保JPEG宽高对应X/Y轴,读取后堆叠为Z轴即可,逻辑和NIfTI处理一致。
内容的提问来源于stack exchange,提问作者ap08082000
相关产品推荐
相关产品推荐

