#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. Можете ли вы поделиться кодом, как вы на самом деле просматривали свои резюме?