Registering two Images

Hello everyone,

I am new with Image Registration and i am trying to register images similar to the following ones.


In most cases it works really well but in cases like this the algorithm stops after a few steps.
I think the problem is that I need to rotate first the moving image to bring it as close as possible to fixed one. but I am not sure how to fix it. I ve tried to apply an affine transformation and then pass it to the bspline as initial transformation but it makes things worse. Any ideas are more than welcome.

One more issue that I have is that I dont know how to extract the inverse
I read that it’s not implemented for the Bsplines but I cannot find any instructions on how to extract it manually.
I would appreciate any help.

here is the registration output


and here is the code and method that worked best from what i’ve tried

Blockquote
fixed_image = sitk.ReadImage(os.path.join(fixed_image_ref), sitk.sitkFloat32)

moving_image = sitk.ReadImage(os.path.join(moving_image_ref), sitk.sitkFloat32)

control_pts = 3

transformDomainMeshSize = [control_pts] * moving_image.GetDimension()

initial_transform = sitk.BSplineTransformInitializer(fixed_image, transformDomainMeshSize)

registration_method = sitk.ImageRegistrationMethod()

registration_method.SetMetricSamplingStrategy(registration_method.REGULAR)

registration_method.SetMetricSamplingPercentage(0.1)

registration_method.SetMetricAsCorrelation()

registration_method.SetOptimizerAsLBFGSB(gradientConvergenceTolerance=1e-5,

                                         numberOfIterations=200,

                                         maximumNumberOfCorrections=5,

                                         maximumNumberOfFunctionEvaluations=1000,

                                         costFunctionConvergenceFactor=1e+7)

registration_method.SetInitialTransform(initial_transform, inPlace=True)

registration_method.SetInterpolator(sitk.sitkLinear)

registration_method.AddCommand(sitk.sitkIterationEvent, lambda: command_iteration(registration_method))

final_transform = registration_method.Execute(fixed_image, moving_image)

Hello @cntontis,

Strange looking images, but here goes.

Generally speaking using FFD as the only step in registration assumes the images are relatively well aligned in the global sense, rigid or affine transformation. This is related to registration initialization. When you don’t explicitly initialize it means you are implicitly initializing with the identity transform. My recommendation is to start with a rigid or affine step before doing the FFD. A discussion of various initialization strategies can be found in this Jupyter notebook.

With respect to inverting a bounded transformation, please see this Jupyter notebook’s section titled “Inverting bounded transforms”.

Our notebook repository may contain additional information that can help you along.

You could also extract points from those images, and then do point-set registration.

First of all thank you both for your recommendations.
Just to give you some context of what I am trying to achieve.
I have two sets of nympy arrays with points in the 2D space and I am trying to label the ones in the (fixed image) like an array topology. For example, in the first “line” there are 2 dots which should be labeled as 1,6
and 1,12. In the second image I know the labels of each dot. So my idea was to create two images. register them, and pass the points from the second one in the transformation to map to the other set.
I dont know if it makes my goal more clear.
But I will check the resources that you provided me. Especially with what @dzenanz suggested seems like I dont even need the images but instead I could work with the numpy arrays

1 Like