Перенесите ось трехмерного МРТ-изображения на другой вид изображения

#image-processing #itk #simpleitk #medical-imaging

Вопрос:

Как я могу перенести 3D-МРТ-изображение с помощью SimpleITK в новое представление изображения, но сохранить соотношение сторон, как это было в первоначальном представлении? Вот мой код:

 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)
 

введите описание изображения здесь

Что я здесь делаю не так? Нужно ли мне в следующий раз менять размер изображения?

РЕДАКТИРОВАТЬ [На основе ответа Дэйва Ченса]:

Результат добавления интервалов в правильном порядке:

 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)
 

введите описание изображения здесь

Ответ №1:

Проблема в том, что вы используете расстояние между пикселями от исходного изображения. Вам нужно перенести расстояния между пикселями так же, как вы перемещаете пиксели. Значит, вы сделали бы что-то вроде этого:

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

Кроме того, обратите внимание, что в SimpleITK есть функция permutexes, которая может делать то же самое и сохранять метаданные изображения, поэтому вам не придется их копировать.

ОБНОВЛЕНИЕ: Хорошо, ниже приведен код, который я использовал. Я запускаю его в блокноте Jupyter и использую 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)
 

Комментарии:

1. Привет! Пожалуйста, взгляните на обновленный вопрос.

2. Что-то не так с отображаемыми изображениями из версии NumPy вашего кода. Интервал показывает, что теперь интервал X больше, 2,99, но изображения нарисованы растянутыми в Y. Можете ли вы поделиться со мной набором данных?

3. kaggle.com/c/… Вот оно 😉

4. Да, я загрузил данные и запустил код перестановки на аппарате МРТ, и это сработало отлично для меня. Я думаю, что это ваши «show_n_slices», которые неправильно справляются с расстоянием между пикселями.

5. Можете ли вы поделиться кодом, как вы на самом деле просматривали свои резюме?