使用Nibabel在Python中重采样NIfTI图像时切片显示异常
解决Nibabel重采样NIfTI图像后切片显示异常的问题
问题分析
你的代码存在两个核心问题:一是未定义from_data变量,运行会直接报错;二是重采样后图像切片显示仅呈现原图像单切片的部分区域,这大概率是空间坐标系对齐错误或切片选取逻辑不当导致的,和体素大小无关。
修正步骤与代码
1. 修复基础语法错误
原代码中from_data未定义,需替换为from_img.get_fdata(),否则无法正常获取原图像数据。
2. 优化重采样与切片匹配逻辑
直接取重采样图像的中间索引切片,和原图像的中间切片并非同一解剖空间位置,这是显示内容异常的主要原因。需要通过坐标转换找到对应空间位置的切片,同时调整插值参数提升重采样质量。
修正后的完整代码
import nibabel as nib import matplotlib.pyplot as plt from nibabel.processing import resample_to_output # 加载原图像并获取数据 from_img = nib.load("AX_T2_TSE_2024520_20_i006.nii.gz") from_data = from_img.get_fdata() # 重采样到(1,1,1)体素大小,使用三次插值保留更多细节 from_img_resampled = resample_to_output(from_img, voxel_sizes=(1,1,1), order=3) resampled_data = from_img_resampled.get_fdata() # 保存重采样后的图像 nib.save(from_img_resampled, "from_img_resampled2.nii.gz") # 验证重采样前后的空间范围是否匹配(排查是否存在区域丢失) orig_min = from_img.affine.dot([0,0,0,1])[:3] orig_max = from_img.affine.dot(from_data.shape + (1,))[:3] resampled_min = from_img_resampled.affine.dot([0,0,0,1])[:3] resampled_max = from_img_resampled.affine.dot(resampled_data.shape + (1,))[:3] print(f"原图像空间范围: {orig_min} 到 {orig_max}") print(f"重采样后空间范围: {resampled_min} 到 {resampled_max}") # 匹配同一解剖位置的切片(而非索引位置) orig_slice_idx = from_data.shape[-1] // 2 # 将原图像切片索引转换为空间坐标,再转换为重采样图像的索引 orig_xyz = from_img.affine.dot([0, 0, orig_slice_idx, 1]) resampled_slice_idx = round((orig_xyz[2] - from_img_resampled.affine[2,3]) / from_img_resampled.affine[2,2]) # 绘制对比图 fig, ax = plt.subplots(1, 2, figsize=(12,6)) ax[0].matshow(from_data[:, :, orig_slice_idx], cmap="gray") ax[0].set_title("原图像切片") ax[1].matshow(resampled_data[:, :, resampled_slice_idx], cmap="gray") ax[1].set_title("重采样后对应切片") plt.show()
关键说明
- 空间位置匹配:通过坐标转换找到原切片对应的重采样图像切片索引,确保对比的是同一解剖区域,而非单纯的中间索引位置。
- 插值参数:使用
order=3的三次插值比默认的线性插值(order=1)能保留更多图像细节,避免模糊或边缘失真。 - 空间范围验证:打印空间范围可确认重采样后的图像是否完整覆盖原图像的解剖区域,如果范围不一致,需检查原图像的affine矩阵是否存在坐标系翻转或原点偏移问题。
内容的提问来源于stack exchange,提问作者Tayssir B
相关产品推荐
相关产品推荐

