如何使用SimpleITK转置3D MRI图像轴切换视图且保留原始宽高比
问题描述
我需要使用SimpleITK转置3D MRI图像的轴以获得新的图像视图,同时保留初始视图的宽高比,现有代码如下:
def show_n_slices(array, start_from=0, step=10, columns=6, figsize=(18,10)): """ 绘制3D图像的N个切片 :param array: N维numpy数组(如3D图像) :param start_from: 起始切片索引 :param step: 切片间隔步长 :param columns: 绘图列数 :param figsize: 画布尺寸(单位英寸) """ array = np.swapaxes(array, 0, 2) fig, ax = plt.subplots(1, columns, figsize=figsize) slice_num = start_from for n in range(columns): ax[n].imshow(array[:, :, slice_num], 'gray') ax[n].set_xticks([]) ax[n].set_yticks([]) ax[n].set_title('Slice number: {}'.format(slice_num), color='r') slice_num += step fig.subplots_adjust(wspace=0, hspace=0) plt.show() def print_sitk_info(itk_image): """ 打印SimpleITK图像的元信息 :param itk_image: SimpleITK图像对象 """ print(f"[INFO]: 形状 - {itk_image.GetSize()}") print(f"[INFO]: 间距 - {itk_image.GetSpacing()}") print(f"[INFO]: 原点 - {itk_image.GetOrigin()}") print(f"[INFO]: 方向矩阵 - {itk_image.GetDirection()}\n") print("[INFO]: 重采样为各向同性分辨率前的图像信息:") print_sitk_info(itk_image) show_n_slices(sitk.GetArrayFromImage(itk_image), start_from=20, step=5)

我尝试通过以下代码转置图像轴来获取不同视图:
array2 = array.transpose(2, 0 ,1) itk_image2 = sitk.GetImageFromArray(array2) itk_image2.SetOrigin(itk_image.GetOrigin()) itk_image2.SetSpacing(itk_image.GetSpacing()) itk_image2.SetDirection(itk_image.GetDirection()) array2 = sitk.GetArrayFromImage(itk_image2) print_sitk_info(itk_image2) show_n_slices(array2, start_from=30, step=5)

请问上述操作存在什么问题?接下来是否需要对图像尺寸进行重采样?
补充更新(基于Dave Chen的回答调整后)
按正确顺序设置spacing后的运行结果
array2 = array.transpose(2, 0 ,1) spacing = itk_image.GetSpacing() itk_image2 = sitk.GetImageFromArray(array2) itk_image2.SetOrigin(itk_image.GetOrigin()) itk_image2.SetSpacing([spacing[2], spacing[0], spacing[1]]) itk_image2.SetDirection(itk_image.GetDirection()) array2 = sitk.GetArrayFromImage(itk_image2) print_sitk_info(itk_image2) show_n_slices(array2, start_from=30, step=5)

使用SimpleITK PermuteAxesImageFilter的运行结果
pa = sitk.PermuteAxesImageFilter() pa.SetOrder([2, 0 , 1]) i = pa.Execute(itk_image) print_sitk_info(i) show_n_slices(sitk.GetArrayFromImage(i), start_from=30, step=5)

问题解答
原有操作的核心问题
你最初的实现错误是没有同步调整轴置换后的图像元数据:
3D医学图像的每个轴都绑定了对应的物理间距(spacing)、方向矩阵(direction)元信息,你对numpy数组做transpose(2,0,1)轴置换后,直接把原图像的spacing、direction原封不动赋值给新图像,导致新图像的像素排列和物理空间参数不匹配,显示出来的宽高比自然会失真。
是否需要重采样
不需要额外做重采样操作。
只要正确同步轴置换后的元数据,就能保证视图的宽高比正确,不会损失图像精度,也不需要修改图像尺寸。你后续手动调整spacing顺序的操作已经可以解决问题,更推荐直接使用SimpleITK内置的PermuteAxesImageFilter,它会自动处理所有元数据的同步适配,不需要手动修改spacing、direction参数,避免人为操作出错。
内容的提问来源于stack exchange,提问作者CodingAddict
相关产品推荐
相关产品推荐

