介紹如何使用 ITK 的 ResampleImageFilter
進行影像的各種座標轉換以及重新取樣。
ITK 的 ResampleImageFilter
可以用來套用 ITK 的各種轉換(transform),並且以指定的內插方法(interpolator)進行影像的重新取樣(resample),得到新座標系統下的影像。
這裡我們以一張簡單的 2D 影像作為示範用的資料。
import itk import matplotlib.pyplot as plt # 影像像素資料類型 PixelType = itk.SS # 影像維度 Dimension = 2 # 影像類型 ImageType = itk.Image[PixelType, Dimension] # 建立影像 Reader ReaderType = itk.ImageFileReader[ImageType] reader = ReaderType.New() reader.SetFileName("moving.mhd") reader.Update() # 讀取影像 inputImage = reader.GetOutput() # 取得影像基本資訊 size = inputImage.GetLargestPossibleRegion().GetSize() spacing = inputImage.GetSpacing() origin = inputImage.GetOrigin() print("Size: {}".format(size)) print("Spacing: {}".format(spacing)) print("Origin: {}".format(origin))
Size: itkSize2 ([256, 256]) Spacing: itkVectorD2 ([1, 1]) Origin: itkPointD2 ([0, 0])
ScaleTransform
縮放轉換以下是一個以 ResampleImageFilter
套用 ScaleTransform
轉換的簡單範例,可將影像以指定的比例放大或縮小。
# 實體座標系統用的資料類型 ScalarType = itk.D # 計算中心點實體座標 centralPixel = itk.Index[Dimension]() centralPixel[0] = int(size[0] / 2) centralPixel[1] = int(size[1] / 2) centralPoint = itk.Point[ScalarType, Dimension]() centralPoint[0] = origin[0] + centralPixel[0] / spacing[0] centralPoint[1] = origin[1] + centralPixel[1] / spacing[1] # 建立 ScaleTransform 縮放轉換 scaleTransform = itk.ScaleTransform[ScalarType, Dimension].New() # 設定轉換參數 parameters = scaleTransform.GetParameters() parameters[0] = 1.5 # X 軸 Scale parameters[1] = 1.5 # Y 軸 Scale scaleTransform.SetParameters(parameters) scaleTransform.SetCenter(centralPoint) # 建立內插器 interpolatorType = itk.LinearInterpolateImageFunction[ImageType, ScalarType] interpolator = interpolatorType.New() # 建立 Resampler resamplerType = itk.ResampleImageFilter[ImageType, ImageType] resampleFilter = resamplerType.New() # 設定 Resampler 各項參數 resampleFilter.SetInput(inputImage) resampleFilter.SetTransform(scaleTransform) resampleFilter.SetInterpolator(interpolator) resampleFilter.SetSize(size) resampleFilter.SetOutputSpacing(spacing) # 實際執行 resampleFilter.Update() # 分開顯示兩張影像 fig, axs = plt.subplots(1, 2) axs[0].imshow(itk.GetArrayViewFromImage(inputImage), cmap='gray') axs[0].set_title('Input Image') axs[1].imshow(itk.GetArrayViewFromImage(resampleFilter.GetOutput()), cmap='gray') axs[1].set_title('Output Image') plt.show()
ResampleImageFilter
在重新取樣時,需要設定輸出的影像資料(size 與 spacing 等),除了逐一設定之外,亦可使用 SetReferenceImage()
直接從另外一張影像將這些資訊複製過來。
ResampleImageFilter
亦可使用串流(streaming)的方式來處理大型影像(例如搭配 ImageFileWriter
或 StreamingImageFilter
建立串流),但前提是套用的轉換必須是線性(linear)的;若搭配非線性(non-linear)的轉換,則在 ResampleImageFilter
這一步就必須將整張影像的資料湊齊才能進行處理,但在這一步之前或之後,可以分開拆成串流處理。
TranslationTransform
平移轉換以下是一個以 ResampleImageFilter
套用 TranslationTransform
轉換的簡單範例,可將影像做平移轉換。
# 建立 TranslationTransform 平移轉換 translationTransform = itk.TranslationTransform[ScalarType, Dimension].New() parameters = translationTransform.GetParameters() parameters[0] = 29 # X 軸平移 parameters[1] = 14 # Y 軸平移 translationTransform.SetParameters(parameters) # 建立 Resampler resamplerType = itk.ResampleImageFilter[ImageType, ImageType] resampleFilter = resamplerType.New() # 設定 Resampler 各項參數 resampleFilter.SetInput(inputImage) resampleFilter.SetTransform(translationTransform) resampleFilter.SetInterpolator(interpolator) resampleFilter.SetSize(size) resampleFilter.SetOutputSpacing(spacing) # 實際執行 resampleFilter.Update() # 分開顯示兩張影像 fig, axs = plt.subplots(1, 2) axs[0].imshow(itk.GetArrayViewFromImage(inputImage), cmap='gray') axs[0].set_title('Input Image') axs[1].imshow(itk.GetArrayViewFromImage(resampleFilter.GetOutput()), cmap='gray') axs[1].set_title('Output Image') plt.show()
AffineTransform
線性轉換以下是一個以 ResampleImageFilter
套用 AffineTransform
轉換的簡單範例,可將影像做各種線性轉換。
# 建立 AffineTransform 線性轉換 affineTransform = itk.AffineTransform[ScalarType, Dimension].New() # 設定旋轉與平移參數 affineTransform.Rotate2D(0.4) offset = itk.Vector[ScalarType, Dimension]() offset[0] = 45.0 offset[1] = -32.0 affineTransform.Translate(offset) # 建立 Resampler resamplerType = itk.ResampleImageFilter[ImageType, ImageType] resampleFilter = resamplerType.New() # 設定 Resampler 各項參數 resampleFilter.SetInput(inputImage) resampleFilter.SetTransform(affineTransform) resampleFilter.SetInterpolator(interpolator) resampleFilter.SetSize(size) resampleFilter.SetOutputSpacing(spacing) # 實際執行 resampleFilter.Update() # 分開顯示兩張影像 fig, axs = plt.subplots(1, 2) axs[0].imshow(itk.GetArrayViewFromImage(inputImage), cmap='gray') axs[0].set_title('Input Image') axs[1].imshow(itk.GetArrayViewFromImage(resampleFilter.GetOutput()), cmap='gray') axs[1].set_title('Output Image') plt.show() # 顯示轉換參數 parameters = affineTransform.GetParameters() print("Affine Transfrom Parameters:") for r in range(len(parameters)): print(parameters[r])
Affine Transfrom Parameters: 0.9210609940028851 -0.3894183423086505 0.3894183423086505 0.9210609940028851 45.0 -32.0
參考資料:ITKExamples