I am trying to perform multi-resolution free form deformation/B-spline between two 2D images by following this: http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/Python_html/65_Registration_FFD.html
I don’t have any fixed or moving points as the images aren’t annotated.
outTx = bspline_intra_modal_registration(fixed_image=fixed_image,
moving_image=out,
# fixed_image_mask = (masks[fixed_image_index] == lung_label),
# fixed_points = points[fixed_image_index],
# moving_points = points[moving_image_index]
)
resampler = sitk.ResampleImageFilter()
resampler.SetReferenceImage(fixed_image)
resampler.SetInterpolator(sitk.sitkNearestNeighbor)
resampler.SetDefaultPixelValue(0)
resampler.SetTransform(outTx)
out = resampler.Execute(out)
But I am not getting the 3 stage iteration like the example:
Also the fixed and moving image sizes are: fixed moving size: (66, 57) (57, 86)
On top the images don’t change at all.
Moving image before registration:
Moving image after registration:
The fixed image is:
Where am I making mistakes? I also changed the grid_physical_spacing
but nothing significant happens.
MWE:
def command_iteration2(method):
global metric_values
print("metric value: {}".format(method.GetMetricValue()))
metric_values.append(method.GetMetricValue())
metric_values = []
registration_method = sitk.ImageRegistrationMethod()
grid_physical_spacing = [.2, .2, .2]#, 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)]
initial_transform = sitk.BSplineTransformInitializer(image1=fixed_image,
transformDomainMeshSize=mesh_size, order=3)
registration_method.SetMovingInitialTransform(compositeTx)
registration_method.SetInitialTransformAsBSpline(initial_transform,
inPlace=True,
scaleFactors=[1, 2, 4])
# Multi-resolution framework.
registration_method.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1])
registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[4, 2, 0.01])
# registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()
registration_method.SetInterpolator(sitk.sitkNearestNeighbor)
registration_method.SetMetricAsANTSNeighborhoodCorrelation(16)
registration_method.MetricUseFixedImageGradientFilterOff() # not sure what it does but saw it in example
registration_method.SetOptimizerScalesFromPhysicalShift()
# registration_method.SetMetricSamplingStrategy(registration_method.NONE)
registration_method.SetOptimizerAsLBFGS2(solutionAccuracy=1e-2,
numberOfIterations=250,
deltaConvergenceTolerance=1e-6)
registration_method.AddCommand(sitk.sitkIterationEvent, lambda: command_iteration2(registration_method))
outTx = registration_method.Execute(fixed_image, moving_image)
resampler = sitk.ResampleImageFilter()
resampler.SetReferenceImage(fixed_image)
resampler.SetInterpolator(sitk.sitkNearestNeighbor)
resampler.SetDefaultPixelValue(0)
resampler.SetTransform(outTx)
out = resampler.Execute(out)
plt.plot(metric_values)
plt.ylabel("Registration metric")
plt.xlabel("Iterations")
plt.show()