SimpleITK Изменение размера изображений

У меня есть набор трехмерных томов, которые я читаю с SimpleITK

import SimpleITK as sitk
for filename in filenames:
    image = sitk.ReadImage(filename)

Каждый из томов имеет разный размер, интервал, происхождение и направление. Этот код дает разные значения для разных изображений:

print(image.GetSize())
print(image.GetOrigin())
print(image.GetSpacing())
print(image.GetDirection())

Мой вопрос: как преобразовать изображения, чтобы они имели одинаковый размер и интервал, чтобы все они имели одинаковое разрешение и размер при преобразовании в массивы numpy. Что-то вроде:

import SimpleITK as sitk
for filename in filenames:
    image = sitk.ReadImage(filename)
    image = transform(image, fixed_size, fixed_spacing)
    array = sitk.GetArrayFromImage(image)

person Miguel Monteiro    schedule 02.01.2018    source источник


Ответы (2)


Способ сделать это - использовать функцию Resample с фиксированным / произвольным размером и интервалом. Ниже приведен фрагмент кода, показывающий построение этого пространства "reference_image":

reference_origin = np.zeros(dimension)
reference_direction = np.identity(dimension).flatten()
reference_size = [128]*dimension # Arbitrary sizes, smallest size that yields desired results. 
reference_spacing = [ phys_sz/(sz-1) for sz,phys_sz in zip(reference_size, reference_physical_size) ]

reference_image = sitk.Image(reference_size, data[0].GetPixelIDValue())
reference_image.SetOrigin(reference_origin)
reference_image.SetSpacing(reference_spacing)
reference_image.SetDirection(reference_direction)

Готовое решение можно найти в блокноте Jupyter который иллюстрирует, как выполнять увеличение данных с помощью изображений переменного размера в SimpleITK (приведенный выше код взят из записной книжки). Вы также можете найти другие записные книжки в репозитории записных книжек SimpleITK.

person zivy    schedule 02.01.2018
comment
Какие преобразования следует использовать в функции Resample () в случае простого изменения размера? Также не могли бы вы прокомментировать параметры интерполятора и значения по умолчанию? Спасибо - person Miguel Monteiro; 02.01.2018
comment
Я создал github gist, который просто показывает, как выполнить повторную выборку. Для большинства ситуаций линейный интерполятор достаточно хорош, но для интерполяции меток вам нужен ближайший сосед. Default_intensity_value - это значение, которое необходимо установить, если отображается за пределами границ изображения. - person zivy; 03.01.2018
comment
Извините за то, что опять беспокою вас. При передискретизации до заданного разрешения и размера, а затем обратно, неизбежны потери. С обычными изображениями я обнаружил, что эти потери допустимы, но с помеченными изображениями я иногда получаю потери в 20% сегментированной области (даже при использовании интерполяции ближайшего соседа). Есть предложения о том, как решить эту проблему? - person Miguel Monteiro; 06.02.2018
comment
Единственная причина использования ближайшего соседа заключается в том, что он не вводит новые метки, но ухудшает артефакты сглаживания. Возможно, обработайте изображение сегментации как изображение с действительным знаком, а не двоичное, и используйте любой другой интерполятор с последующим пороговым значением, чтобы получить обратно двоичное изображение. Кроме того, сгладьте изображение при переходе на более грубое разрешение. Это просто смягчает проблему, а не решает ее. Для будущих обсуждений используйте discourse.itk.org (тег simpleitk), ограничение на количество символов stackoverflow в комментариях является ограничительным. . - person zivy; 07.02.2018

Согласно документации SimpleITK, процесс передискретизации изображения состоит из 4 шагов:

  1. Image - изображение, которое мы передискретируем, заданное в системе координат;
  2. Сетка передискретизации - регулярная сетка точек, заданная в системе координат, которая будет отображена в системе координат;
  3. Преобразование - отображает точки из системы координат в систему координат;
  4. Интерполятор - метод получения значений интенсивности в произвольных точках системы координат из значений точек, определенных Image

Следующий фрагмент предназначен для уменьшения разрешения изображения с сохранением его свойств системы координат:

def downsamplePatient(patient_CT, resize_factor):

    original_CT = sitk.ReadImage(patient_CT,sitk.sitkInt32)
    dimension = original_CT.GetDimension()
    reference_physical_size = np.zeros(original_CT.GetDimension())
    reference_physical_size[:] = [(sz-1)*spc if sz*spc>mx  else mx for sz,spc,mx in zip(original_CT.GetSize(), original_CT.GetSpacing(), reference_physical_size)]
    
    reference_origin = original_CT.GetOrigin()
    reference_direction = original_CT.GetDirection()

    reference_size = [round(sz/resize_factor) for sz in original_CT.GetSize()] 
    reference_spacing = [ phys_sz/(sz-1) for sz,phys_sz in zip(reference_size, reference_physical_size) ]

    reference_image = sitk.Image(reference_size, original_CT.GetPixelIDValue())
    reference_image.SetOrigin(reference_origin)
    reference_image.SetSpacing(reference_spacing)
    reference_image.SetDirection(reference_direction)

    reference_center = np.array(reference_image.TransformContinuousIndexToPhysicalPoint(np.array(reference_image.GetSize())/2.0))
    
    transform = sitk.AffineTransform(dimension)
    transform.SetMatrix(original_CT.GetDirection())

    transform.SetTranslation(np.array(original_CT.GetOrigin()) - reference_origin)
  
    centering_transform = sitk.TranslationTransform(dimension)
    img_center = np.array(original_CT.TransformContinuousIndexToPhysicalPoint(np.array(original_CT.GetSize())/2.0))
    centering_transform.SetOffset(np.array(transform.GetInverse().TransformPoint(img_center) - reference_center))
    centered_transform = sitk.Transform(transform)
    centered_transform.AddTransform(centering_transform)

    # sitk.Show(sitk.Resample(original_CT, reference_image, centered_transform, sitk.sitkLinear, 0.0))
    
    return sitk.Resample(original_CT, reference_image, centered_transform, sitk.sitkLinear, 0.0)

Используя приведенный выше фрагмент при компьютерной томографии мозга, мы получаем:  Исходная компьютерная томография

КТ с уменьшенной дискретизацией

person Miguel Rueda    schedule 27.07.2020
comment
centered_transform = sitk.Transform (преобразование) должно быть: centered_transform = sitk.CompositeTransform (преобразование) - person Ningrong Ye; 26.03.2021