def demons_registration(fixed_image, moving_image, fixed_points=None, moving_points=None): registration_method = sitk.ImageRegistrationMethod() # Create initial identity transformation. transform_to_displacment_field_filter = sitk.TransformToDisplacementFieldFilter( ) transform_to_displacment_field_filter.SetReferenceImage(fixed_image) # The image returned from the initial_transform_filter is transferred to the transform and cleared out. initial_transform = sitk.DisplacementFieldTransform( transform_to_displacment_field_filter.Execute(sitk.Transform())) # Regularization (update field - viscous, total field - elastic). initial_transform.SetSmoothingGaussianOnUpdate(varianceForUpdateField=0.0, varianceForTotalField=2.0) registration_method.SetInitialTransform(initial_transform) registration_method.SetMetricAsDemons( 10) # intensities are equal if the difference is less than 10HU # Multi-resolution framework. registration_method.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1]) registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[8, 4, 0]) registration_method.SetInterpolator(sitk.sitkLinear) # If you have time, run this code as is, otherwise switch to the gradient descent optimizer # registration_method.SetOptimizerAsConjugateGradientLineSearch(learningRate=1.0, numberOfIterations=20, # convergenceMinimumValue=1e-6, # convergenceWindowSize=10) registration_method.SetOptimizerAsGradientDescent( learningRate=1.0, numberOfIterations=20, convergenceMinimumValue=1e-6, convergenceWindowSize=10) registration_method.SetOptimizerScalesFromPhysicalShift() # If corresponding points in the fixed and moving image are given then we display the similarity metric # and the TRE during the registration. if fixed_points and moving_points: registration_method.AddCommand(sitk.sitkStartEvent, rc.metric_and_reference_start_plot) registration_method.AddCommand(sitk.sitkEndEvent, rc.metric_and_reference_end_plot) registration_method.AddCommand( sitk.sitkIterationEvent, lambda: rc.metric_and_reference_plot_values( registration_method, fixed_points, moving_points)) return registration_method.Execute(fixed_image, moving_image)
def bspline_intra_modal_registration(fixed_image, moving_image, fixed_image_mask=None, fixed_points=None, moving_points=None): registration_method = sitk.ImageRegistrationMethod() # Determine the number of BSpline control points using the physical spacing we want for the control grid. grid_physical_spacing = [4.0, 4.0, 4.0] # A control point every 50mm image_physical_size = [ size * spacing for size, spacing in zip(fixed_image.GetSize(), fixed_image.GetSpacing()) ] mesh_size = [int(image_size / grid_spacing + 0.5) \ for image_size, grid_spacing in zip(image_physical_size, grid_physical_spacing)] initial_transform = sitk.BSplineTransformInitializer( image1=fixed_image, transformDomainMeshSize=mesh_size, order=3) registration_method.SetInitialTransform(initial_transform) registration_method.SetMetricAsMattesMutualInformation( numberOfHistogramBins=20) # Settings for metric sampling, usage of a mask is optional. When given a mask the sample points will be # generated inside that region. Also, this implicitly speeds things up as the mask is smaller than the # whole image. registration_method.SetMetricSamplingStrategy(registration_method.RANDOM) registration_method.SetMetricSamplingPercentage(0.01) if fixed_image_mask: registration_method.SetMetricFixedMask(fixed_image_mask) # Multi-resolution framework. registration_method.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1]) registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[2, 1, 0]) registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn() registration_method.SetInterpolator(sitk.sitkLinear) registration_method.SetOptimizerAsLBFGSB(gradientConvergenceTolerance=1e-5, numberOfIterations=100) # If corresponding points in the fixed and moving image are given then we display the similarity metric # and the TRE during the registration. if fixed_points and moving_points: registration_method.AddCommand(sitk.sitkStartEvent, rc.metric_and_reference_start_plot) registration_method.AddCommand(sitk.sitkEndEvent, rc.metric_and_reference_end_plot) registration_method.AddCommand( sitk.sitkIterationEvent, lambda: rc.metric_and_reference_plot_values( registration_method, fixed_points, moving_points)) return registration_method.Execute(fixed_image, moving_image)
def test(): # show the standard fiducial list fixed_fiducial_points, moving_fiducial_points = ru.load_RIRE_ground_truth( fdata("ct_T1.standard")) print "The standard fiducial points are ", fixed_fiducial_points print "The standard fiducial points shape ", type(moving_fiducial_points) # test_data = fdata("training_001_ct.mha") fixed_data = "/home/maguangshen/PycharmProjects/SPL/Data_SPL/test_resampled_MRI.mha" fixed_img = sitk.ReadImage(fixed_data, sitk.sitkFloat32) moving_data = "/home/maguangshen/PycharmProjects/SPL/Data_SPL/test_US_before.mha" moving_img = sitk.ReadImage(moving_data, sitk.sitkFloat32) # This is the list -- can be used for numpy array # Read the MRI fiducial csv_MRI = "/home/maguangshen/PycharmProjects/SPL/Data_SPL/Case23-MRI.csv" fiducial_MRI, fiducial_MRI_list = Read_tsv(csv_MRI) print "The fiducials of MRI are ", fiducial_MRI_list # Read the US fiducial csv_US = "/home/maguangshen/PycharmProjects/SPL/Data_SPL/Case23-beforeUS.csv" fiducial_US, fiducial_US_list = Read_tsv(csv_US) print "The ficucials of US are ", fiducial_US_list R, t = ru.absolute_orientation_m(fiducial_MRI_list, fiducial_US_list) print "The testing R is ", R print "The testing T is ", t print "The R flatten is ", R.flatten() # Set up the registration parameters reference_transform = sitk.Euler3DTransform() # Euler 3D Transform reference_transform.SetMatrix(R.flatten()) # Flatten the R matrix reference_transform.SetTranslation(t) # Set the translation vector reference_errors_mean, reference_errors_std, _, reference_errors_max, _ = ru.registration_errors( reference_transform, fiducial_MRI_list, fiducial_US_list) print( 'Reference data errors (FRE) in millimeters, mean(std): {:.2f}({:.2f}), max: {:.2f}' .format(reference_errors_mean, reference_errors_std, reference_errors_max)) # Viz the results to map all the points # Generate a reference dataset from the reference transformation # Apply the transformation first based on the fiducial registration results fixed_points = ru.generate_random_pointset( image=fixed_img, num_points=100) # generate random point sets from the volume dataset moving_points = [ reference_transform.TransformPoint(p) for p in fixed_points ] # Compute the TRE prior to the registration pre_errors_mean, pre_errors_std, pre_errors_min, pre_errors_max, _ = ru.registration_errors( sitk.Euler3DTransform(), fixed_points, moving_points, display_errors=True) print( 'Before registration, errors (TRE) in millimeters, mean(std): {:.2f}({:.2f}), max: {:.2f}' .format(pre_errors_mean, pre_errors_std, pre_errors_max)) ## Initial alignment # Initialization of the transform initial_transform = sitk.CenteredTransformInitializer( sitk.Cast(fixed_img, moving_img.GetPixelID()), moving_img, sitk.Euler3DTransform(), sitk.CenteredTransformInitializerFilter.GEOMETRY) initial_errors_mean, initial_errors_std, initial_errors_min, initial_errors_max, _ = ru.registration_errors( initial_transform, fixed_points, moving_points, min_err=pre_errors_min, max_err=pre_errors_max, display_errors=True) print( 'After initialization, errors (TRE) in millimeters, mean(std): {:.2f}({:.2f}), max: {:.2f}' .format(initial_errors_mean, initial_errors_std, initial_errors_max)) # Begin registration registration_method = sitk.ImageRegistrationMethod() registration_method.SetMetricAsMattesMutualInformation( numberOfHistogramBins=50) # Define the number of bins as 50 registration_method.SetMetricSamplingStrategy( registration_method.RANDOM) # Define the registration_method.SetMetricSamplingPercentage( 0.01) # Default sampling percentage is 0.01 registration_method.SetInterpolator( sitk.sitkNearestNeighbor) # Replace with sitkLinear registration_method.SetOptimizerAsGradientDescent( learningRate=1.0, numberOfIterations=100) # Increase to 1000 registration_method.SetOptimizerScalesFromPhysicalShift( ) # Understand the optimization method registration_method.SetInitialTransform( initial_transform, inPlace=False) # Apply the initial transform # Add the callback to display the similarity value registration_method.AddCommand(sitk.sitkStartEvent, rc.metric_and_reference_start_plot) registration_method.AddCommand(sitk.sitkEndEvent, rc.metric_and_reference_end_plot) registration_method.AddCommand( sitk.sitkIterationEvent, lambda: rc.metric_and_reference_plot_values( registration_method, fixed_points, moving_points)) final_transform_single_scale = registration_method.Execute( sitk.Cast(fixed_img, sitk.sitkFloat32), sitk.Cast(moving_img, sitk.sitkFloat32)) print('Final metric value: {0}'.format( registration_method.GetMetricValue())) print('Optimizer\'s stopping condition, {0}'.format( registration_method.GetOptimizerStopConditionDescription())) final_errors_mean, final_errors_std, _, final_errors_max, _ = ru.registration_errors( final_transform_single_scale, fixed_points, moving_points, min_err=initial_errors_min, max_err=initial_errors_max, display_errors=True) print( 'After registration, errors in millimeters, mean(std): {:.2f}({:.2f}), max: {:.2f}' .format(final_errors_mean, final_errors_std, final_errors_max)) final_errors_mean, final_errors_std, _, final_errors_max, _ = ru.registration_errors( final_transform_single_scale, fixed_points, moving_points, display_errors=True)
def bspline_intra_modal_registration2(fixed_image, moving_image, fixed_image_mask=None, fixed_points=None, moving_points=None, isVis=True): registration_method = sitk.ImageRegistrationMethod() # Determine the number of BSpline control points using the physical spacing we # want for the finest resolution control grid. grid_physical_spacing = [50.0, 50.0, 50.0] # A control point every 50mm image_physical_size = [ size * spacing for size, spacing in zip(fixed_image.GetSize(), fixed_image.GetSpacing()) ] mesh_size = [int(image_size/grid_spacing + 0.5) \ for image_size,grid_spacing in zip(image_physical_size,grid_physical_spacing)] # The starting mesh size will be 1/4 of the original, it will be refined by # the multi-resolution framework. mesh_size = [int(sz / 4 + 0.5) for sz in mesh_size] initial_transform = sitk.BSplineTransformInitializer( image1=fixed_image, transformDomainMeshSize=mesh_size, order=3) # Instead of the standard SetInitialTransform we use the BSpline specific method which also # accepts the scaleFactors parameter to refine the BSpline mesh. In this case we start with # the given mesh_size at the highest pyramid level then we double it in the next lower level and # in the full resolution image we use a mesh that is four times the original size. registration_method.SetInitialTransformAsBSpline(initial_transform, inPlace=True, scaleFactors=[1, 2, 4]) registration_method.SetMetricAsMeanSquares() # Settings for metric sampling, usage of a mask is optional. When given a mask the sample points will be # generated inside that region. Also, this implicitly speeds things up as the mask is smaller than the # whole image. registration_method.SetMetricSamplingStrategy(registration_method.RANDOM) registration_method.SetMetricSamplingPercentage(0.01) if fixed_image_mask: registration_method.SetMetricFixedMask(fixed_image_mask) # Multi-resolution framework. registration_method.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1]) registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[2, 1, 0]) registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn() registration_method.SetInterpolator(sitk.sitkLinear) # Use the LBFGS2 instead of LBFGS. The latter cannot adapt to the changing control grid resolution. registration_method.SetOptimizerAsLBFGS2(solutionAccuracy=1e-5, numberOfIterations=100, deltaConvergenceTolerance=0.01) # If corresponding points in the fixed and moving image are given then we display the similarity metric # and the TRE during the registration. if isVis: if fixed_points and moving_points: registration_method.AddCommand(sitk.sitkStartEvent, rc.metric_and_reference_start_plot) registration_method.AddCommand(sitk.sitkEndEvent, rc.metric_and_reference_end_plot) registration_method.AddCommand( sitk.sitkIterationEvent, lambda: rc.metric_and_reference_plot_values( registration_method, fixed_points, moving_points)) else: registration_method.AddCommand(sitk.sitkStartEvent, vis.start_plot) registration_method.AddCommand(sitk.sitkEndEvent, vis.end_plot) registration_method.AddCommand( sitk.sitkMultiResolutionIterationEvent, vis.update_multires_iterations) registration_method.AddCommand( sitk.sitkIterationEvent, lambda: vis.plot_values(registration_method)) final_transform = registration_method.Execute( sitk.Cast(fixed_image, sitk.sitkFloat32), sitk.Cast(moving_image, sitk.sitkFloat32)) print('Final metric value: {0}'.format( registration_method.GetMetricValue())) print('Optimizer\'s stopping condition, {0}'.format( registration_method.GetOptimizerStopConditionDescription())) return final_transform