def execute(self, image: sitk.Image, params: ImageRegistrationParameters = None) -> sitk.Image: """Registers an image. Args: image (sitk.Image): The image. params (ImageRegistrationParameters): The registration parameters. Returns: sitk.Image: The registered image. """ # todo: replace this filter by a registration. Registration can be costly, therefore, we provide you the # transformation, which you only need to apply to the image! # warnings.warn('No registration implemented. Returning unregistered image') atlas = params.atlas transform = params.transformation is_ground_truth = params.is_ground_truth # the ground truth will be handled slightly different if is_ground_truth: # apply transformation to ground truth and brain mask using nearest neighbor interpolation image = sitk.Resample(image, atlas, transform, sitk.sitkNearestNeighbor, 0, image.GetPixelIDValue()) else: # apply transformation to T1w and T2w images using linear interpolation image = sitk.Resample(image, atlas, transform, sitk.sitkLinear, 0.0, image.GetPixelIDValue()) # note: if you are interested in registration, and want to test it, have a look at # pymia.filtering.registration.MultiModalRegistration. Think about the type of registration, i.e. # do you want to register to an atlas or inter-subject? Or just ask us, we can guide you ;-) return image
def execute(self, image: sitk.Image, params: ImageRegistrationParameters = None) -> sitk.Image: """Registers an image. Args: image (sitk.Image): The image. params (ImageRegistrationParameters): The registration parameters. Returns: sitk.Image: The registered image. """ atlas = params.atlas transform = params.transformation is_ground_truth = params.is_ground_truth # the ground truth will be handled slightly different if is_ground_truth: # apply transformation to ground truth and brain mask using nearest neighbor interpolation image = sitk.Resample(image, atlas, transform, sitk.sitkNearestNeighbor, 0, image.GetPixelIDValue()) else: # apply transformation to T1w and T2w images using linear interpolation image = sitk.Resample(image, atlas, transform, sitk.sitkLinear, 0.0, image.GetPixelIDValue()) return image
def execute(self, image: sitk.Image, params: MultiModalRegistrationParams=None) -> sitk.Image: """Executes a multi-modal rigid registration. Args: image (sitk.Image): The moving image. params (MultiModalRegistrationParams): The parameters, which contain the fixed image. Returns: sitk.Image: The registered image. """ if params is None: raise ValueError("params is not defined") dimension = image.GetDimension() if dimension not in (2, 3): raise ValueError('Image dimension {} is not among the accepted (2, 3)'.format(dimension)) # set a transform that is applied to the moving image to initialize the registration if self.registration_type == RegistrationType.BSPLINE: transform_domain_mesh_size = [10] * image.GetDimension() initial_transform = sitk.BSplineTransformInitializer(params.fixed_image, transform_domain_mesh_size) else: if self.registration_type == RegistrationType.RIGID: transform_type = sitk.VersorRigid3DTransform() if dimension == 3 else sitk.Euler2DTransform() elif self.registration_type == RegistrationType.AFFINE: transform_type = sitk.AffineTransform(dimension) elif self.registration_type == RegistrationType.SIMILARITY: transform_type = sitk.Similarity3DTransform() if dimension == 3 else sitk.Similarity2DTransform() else: raise ValueError('not supported registration_type') initial_transform = sitk.CenteredTransformInitializer(sitk.Cast(params.fixed_image, image.GetPixelIDValue()), image, transform_type, sitk.CenteredTransformInitializerFilter.GEOMETRY) self.registration.SetInitialTransform(initial_transform, inPlace=True) if params.fixed_image_mask: self.registration.SetMetricFixedMask(params.fixed_image_mask) if params.callbacks is not None: for callback in params.callbacks: callback.set_params(self.registration, params.fixed_image, image, initial_transform) self.transform = self.registration.Execute(sitk.Cast(params.fixed_image, sitk.sitkFloat32), sitk.Cast(image, sitk.sitkFloat32)) if self.verbose: print('MultiModalRegistration:\n Final metric value: {0}'.format(self.registration.GetMetricValue())) print(' Optimizer\'s stopping condition, {0}'.format( self.registration.GetOptimizerStopConditionDescription())) elif self.number_of_iterations == self.registration.GetOptimizerIteration(): print('MultiModalRegistration: Optimizer terminated at number of iterations and did not converge!') return sitk.Resample(image, params.fixed_image, self.transform, self.resampling_interpolator, 0.0, image.GetPixelIDValue())
def resample_sitk_image(sitk_image: sitk.Image, new_size, interpolator="gaussian", fill_value=0) -> sitk.Image: """ modified version from: https://github.com/jonasteuwen/SimpleITK-examples/blob/master/examples/resample_isotropically.py """ # if pass a path to image if isinstance(sitk_image, str): sitk_image = sitk.ReadImage(sitk_image) assert (interpolator in _SITK_INTERPOLATOR_DICT.keys() ), "`interpolator` should be one of {}".format( _SITK_INTERPOLATOR_DICT.keys()) if not interpolator: interpolator = "linear" pixelid = sitk_image.GetPixelIDValue() if pixelid not in [1, 2, 4]: raise NotImplementedError( "Set `interpolator` manually, " "can only infer for 8-bit unsigned or 16, 32-bit signed integers" ) # 8-bit unsigned int if sitk_image.GetPixelIDValue() == 1: # if binary mask interpolate it as nearest interpolator = "nearest" sitk_interpolator = _SITK_INTERPOLATOR_DICT[interpolator] orig_pixelid = sitk_image.GetPixelIDValue() orig_origin = sitk_image.GetOrigin() orig_direction = sitk_image.GetDirection() # new spacing based on the desired output shape new_spacing = tuple( np.array(sitk_image.GetSpacing()) * np.array(sitk_image.GetSize()) / np.array(new_size)) # setup image resampler - SimpleITK 2.0 resample_filter = sitk.ResampleImageFilter() resample_filter.SetOutputSpacing(new_spacing) resample_filter.SetSize(new_size) resample_filter.SetOutputDirection(orig_direction) resample_filter.SetOutputOrigin(orig_origin) resample_filter.SetTransform(sitk.Transform()) resample_filter.SetDefaultPixelValue(orig_pixelid) resample_filter.SetInterpolator(sitk_interpolator) resample_filter.SetDefaultPixelValue(fill_value) # run it resampled_sitk_image = resample_filter.Execute(sitk_image) return resampled_sitk_image
def assert_sitk_img_equivalence(img: SimpleITK.Image, img_ref: SimpleITK.Image): assert img.GetDimension() == img_ref.GetDimension() assert img.GetSize() == img_ref.GetSize() assert img.GetOrigin() == img_ref.GetOrigin() assert img.GetSpacing() == img_ref.GetSpacing() assert (img.GetNumberOfComponentsPerPixel() == img_ref.GetNumberOfComponentsPerPixel()) assert img.GetPixelIDValue() == img_ref.GetPixelIDValue() assert img.GetPixelIDTypeAsString() == img_ref.GetPixelIDTypeAsString()
def execute(self, image: sitk.Image, params: MultiModalRegistrationParams = None) -> sitk.Image: """Executes a multi-modal rigid registration. Args: image (sitk.Image): The moving image. params (MultiModalRegistrationParams): The parameters, which contain the fixed image. Returns: sitk.Image: The registered image. """ if params is None: raise ValueError("params is not defined") # set a transform that is applied to the moving image to initialize the registration if self.registration_type == RegistrationType.RIGID: transform_type = sitk.VersorRigid3DTransform() elif self.registration_type == RegistrationType.AFFINE: transform_type = sitk.AffineTransform(3) else: raise ValueError('not supported registration_type') initial_transform = sitk.CenteredTransformInitializer( sitk.Cast(params.fixed_image, image.GetPixelIDValue()), image, transform_type, sitk.CenteredTransformInitializerFilter.GEOMETRY) self.registration.SetInitialTransform(initial_transform, inPlace=True) if params.fixed_image_mask: self.registration.SetMetricFixedMask(params.fixed_image_mask) if params.plot_directory_path: RegistrationPlotter(self.registration, params.fixed_image, image, initial_transform, params.plot_directory_path) self.transform = self.registration.Execute( sitk.Cast(params.fixed_image, sitk.sitkFloat32), sitk.Cast(image, sitk.sitkFloat32)) if self.verbose: print('MultiModalRegistration:\n Final metric value: {0}'.format( self.registration.GetMetricValue())) print(' Optimizer\'s stopping condition, {0}'.format( self.registration.GetOptimizerStopConditionDescription())) elif self.number_of_iterations == self.registration.GetOptimizerIteration( ): print( 'MultiModalRegistration: Optimizer terminated at number of iterations and did not converge!' ) return sitk.Resample(image, params.fixed_image, self.transform, sitk.sitkLinear, 0.0, image.GetPixelIDValue())
def get_largest_segment(image: sitk.Image, extract_background=False) -> sitk.Image: # get number of labels img_statistic = sitk.StatisticsImageFilter() img_statistic.Execute(image) min_val = int(img_statistic.GetMinimum()) max_val = int(img_statistic.GetMaximum()) # create empty output image img_out = sitk.Image(image.GetSize(), image.GetPixelIDValue()) img_out.CopyInformation(image) # setup connected components filter connected_comp_filter = sitk.ConnectedComponentImageFilter() connected_comp_filter.FullyConnectedOn() # extract largest segment for label in range(min_val, max_val + 1): img_label = image == label seg = connected_comp_filter.Execute(img_label != 0) if label == 0: # create temporary a new label for largest connected comp of the background seg = (sitk.RelabelComponent(seg) == 1) * (max_val + 1) * extract_background else: seg = (sitk.RelabelComponent(seg) == 1) * label img_out = img_out + seg # arr_image = sitk.GetArrayFromImage(img_out) # plt.imshow(arr_image[60,:,:], cmap='jet') # plt.show() return img_out
def execute( self, image: sitk.Image, params: RigidMultiModalRegistrationParams = None) -> sitk.Image: """Executes a multi-modal rigid registration. Args: image (sitk.Image): The moving image. params (RigidMultiModalRegistrationParams): The parameters, which contain the fixed image. Returns: sitk.Image: The registered image. """ if params is None: raise ValueError("params is not defined") initial_transform = sitk.CenteredTransformInitializer( sitk.Cast(params.fixed_image, image.GetPixelIDValue()), image, sitk.Euler3DTransform(), sitk.CenteredTransformInitializerFilter.GEOMETRY) self.registration.SetInitialTransform(initial_transform, inPlace=True) fixed_image = sitk.Normalize(params.fixed_image) image = sitk.Normalize(image) if params.plot_directory_path: RegistrationPlotter(self.registration, fixed_image, image, initial_transform, params.plot_directory_path) transform = self.registration.Execute( sitk.Cast(fixed_image, sitk.sitkFloat32), sitk.Cast(image, sitk.sitkFloat32)) if self.verbose: print('RigidMultiModalRegistration:\n Final metric value: {0}'. format(self.registration.GetMetricValue())) print(' Optimizer\'s stopping condition, {0}'.format( self.registration.GetOptimizerStopConditionDescription())) elif self.number_of_iterations == self.registration.GetOptimizerIteration( ): print( 'RigidMultiModalRegistration: Optimizer terminated at number of iterations and did not converge!' ) return sitk.Resample(image, params.fixed_image, transform, sitk.sitkLinear, 0.0, image.GetPixelIDValue())