コード例 #1
0
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)
コード例 #2
0
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)
コード例 #3
0
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)
コード例 #4
0
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