#!/usr/bin/env python# Copyright 2020-2020 Biomedical Imaging Group Rotterdam, Departments of# Medical Informatics and Radiology, Erasmus MC, Rotterdam, The Netherlands## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.importSimpleITKassitkimportnumpyasnp
[docs]defresample_image(image,new_spacing=None,new_size=None,interpolator=sitk.sitkBSpline):"""Resample an image to another spacing. Parameters ---------- image : ITK Image Input image. new_spacing : list Spacing to resample image to Returns ------- resampled_image : ITK Image Output image. """ifnew_spacingisnotNoneandnew_sizeisnotNone:raiseValueError('Either provide resample_spacing OR resample_size as input!')ifnew_spacingisNoneandnew_sizeisNone:raiseValueError('Either provide resample_spacing OR resample_size as input!')# Get original settingsoriginal_size=image.GetSize()original_spacing=image.GetSpacing()# ITK can only do 3D imagesiflen(original_size)==2:original_size=original_size+(1,)iflen(original_spacing)==2:original_spacing=original_spacing+(1.0,)ifnew_sizeisNone:# Compute output sizenew_size=[int(original_size[0]*original_spacing[0]/new_spacing[0]),int(original_size[1]*original_spacing[1]/new_spacing[1]),int(original_size[2]*original_spacing[2]/new_spacing[2])]ifnew_spacingisNone:# Compute output spacingnew_spacing=[original_size[0]*original_spacing[0]/new_size[0],original_size[1]*original_spacing[1]/new_size[1],original_size[2]*original_spacing[2]/new_size[2]]# Set and execute the filterResampleFilter=sitk.ResampleImageFilter()ResampleFilter.SetInterpolator(interpolator)ResampleFilter.SetOutputSpacing(new_spacing)ResampleFilter.SetSize(new_size)ResampleFilter.SetOutputDirection(image.GetDirection())ResampleFilter.SetOutputOrigin(image.GetOrigin())ResampleFilter.SetOutputPixelType(image.GetPixelID())ResampleFilter.SetTransform(sitk.Transform())try:resampled_image=ResampleFilter.Execute(image)exceptRuntimeError:# Assume the error is due to the direction determinant being 0# Crude solution: simply set a correct directionprint('[Segmentix Warning] Bad output direction in resampling, resetting direction.')direction=(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0)ResampleFilter.SetOutputDirection(direction)image.SetDirection(direction)resampled_image=ResampleFilter.Execute(image)returnresampled_image
[docs]defcheck_image_orientation(image):"""Check the orientation of an ITK image."""direction_of_cosines=image.GetDirection()X_vector=np.abs(np.array(direction_of_cosines[0:3]))Y_vector=np.abs(np.array(direction_of_cosines[3:6]))X_index=np.argmax(X_vector)Y_index=np.argmax(Y_vector)ifX_index==0andY_index==1:# Axialorientation=1elifX_index==0andY_index==2:# Coronalorientation=2elifX_index==1andY_index==2:# Sagitalorientation=3else:# Don't know what this isorientation=4returnorientation
[docs]deftranspose_image(image,primary_axis='axial'):"""Transpose an ITK image, while keeping the metadata."""orientation=check_image_orientation(image)ifprimary_axis=='axial':iforientation==1:print('Already in axial orientation, skipping.')returnimageeliforientation==2:# From coronal to axialtransform=(1,0,2)flip=(False,True,False)direction_of_cosines=[0,1,2,3,5,4,6,7,8]else:raiseValueError(f'Orientation {orientation} not supported for {primary_axis}.')else:raiseValueError(f'Primary axis {primary_axis} not supported.')# Transform imagearray=sitk.GetArrayFromImage(image)array=np.transpose(array,transform)new_image=sitk.GetImageFromArray(array)new_image=sitk.Flip(new_image,flip)# Also Transform metadatanew_image.SetSpacing([image.GetSpacing()[t]fortintransform])new_image.SetOrigin([image.GetOrigin()[t]fortintransform])try:new_image.SetDirection([image.GetDirection()[d]fordindirection_of_cosines])exceptRuntimeError:# Bad determinant, just assume we have the correct direction alreadypassreturnnew_image