【问题标题】:Transpose 3-D MRI image axis to different image view将 3-D MRI 图像轴转置到不同的图像视图
【发布时间】:2021-08-18 22:39:49
【问题描述】:

如何使用 SimpleITK 将 3D MRI 图像转置到新的图像视图,但保持初始视图中的纵横比?这是我的代码:

def show_n_slices(array, start_from=0, step=10, columns=6, figsize=(18,10)):
    """ Plot N slices of a 3D image.
    :param array: N-dimensional numpy array (i.e. 3D image)
    :param start_from: slice index to start from
    :param step: step to take when moving to the next slice
    :param columns: number of columns in the plot
    :param figsize: figure size in inches
    """
    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):
    """ Prints SimpleITK image information
    :param itk_image: SimpleITK image object.
    """
    print(f"[INFO]: Shape - {itk_image.GetSize()}")
    print(f"[INFO]: Spacing - {itk_image.GetSpacing()}")
    print(f"[INFO]: Origin - {itk_image.GetOrigin()}")
    print(f"[INFO]: Direction - {itk_image.GetDirection()}\n")

print("[INFO]: Image Info before Resampling to Isotropic Resolution:")
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 Chens 的回答]:

按正确顺序添加间距的结果:

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)

【问题讨论】:

    标签: image-processing itk simpleitk medical-imaging


    【解决方案1】:

    问题在于您使用的是原始图像的像素间距。您需要以与转置像素相同的方式转置像素间距。所以你会做这样的事情:

    spacing = itk_image.GetSpacing()
    spacing2 = [spacing[2], spacing[0], spacing[1]]
    itk_image2.SetSpacing(spacing2)
    

    另外,请注意 SimpleITK 有一个 PermuteAxes 函数,它可以做同样的事情,并且会保留图像元数据,所以你不必复制它。

    更新:好的,下面是我使用的代码。我在 Jupyter Notebook 中运行它并使用 ITKWidgets 在笔记本中渲染 3d 图像。请注意,底部的每个视图调用都应位于其自己的笔记本单元格中。

    import SimpleITK as sitk
    import itkwidgets
    
    fnames = []
    for i in range(1,33):
        name = "Image-"+str(i)+".dcm"
        fnames.append(name)
    reader = sitk.ImageSeriesReader()
    reader.SetFileNames(fnames)
    img = reader.Execute()
    print(img)
    
    pa = sitk.PermuteAxesImageFilter()
    pa.SetOrder([2,0,1])
    img2 = pa.Execute(img)
    print(img2)
    
    # Render cell #1
    itkwidgets.view(img)
    
    # Render cell #2
    itkwidgets.view(img2)
    

    【讨论】:

    • 嗨!请查看更新后的问题。
    • 代码的 NumPy 版本的显示图像有问题。间距显示现在X间距更大了,2.99,但是图像是在Y方向拉伸绘制的。能分享一下数据集吗?
    • kaggle.com/c/… 在这里 ;)
    • 是的,我下载了数据,并在 MRI 设备上运行了置换代码,对我来说效果很好。我认为是您的“show_n_slices”没有正确处理像素间距。
    • 您能分享一下您实际查看结果的代码吗?
    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多