SimpleITK 调整图像大小

SimpleITK Resize images

我有一套 3D 书籍,我正在阅读 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)

执行此操作的方法是使用具有 fixed/arbitrary 大小和间距的重采样函数。下面是一段代码片段,显示了 "reference_image" space:

的构造
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)

对于交钥匙解决方案,请查看 this Jupyter notebook which illustrates how to do data augmentation with variable sized images in SimpleITK (code above is from the notebook). You may find the other notebooks from the SimpleITK notebook repository 的使用。

根据SimpleITK的文档,图像重采样的过程包括4个步骤:

  1. Image - 我们重采样的图像,在坐标系中给定;
  2. 重采样网格 - 坐标系中给定点的规则网格将映射到坐标系;
  3. 变换——将点从坐标系映射到坐标系;
  4. Interpolator - 一种从Image
  5. 定义的点的值中获取坐标系中任意点强度值的方法

以下代码段用于对保留其坐标系属性的图像进行下采样:

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)

在大脑 CT 扫描中使用上面的代码片段,我们得到: