Image Registration with no translation

Is it possible to register two images off of a point (not the center of the image) without translation? As in I have two images that are fixed at one point but I need to align the moving image using 3d rotation only.

I have tried this with AffineTranform, Euler3DTransform, and VersorRigid3DTransform:
image_center = post_resam.TransformIndexToPhysicalPoint((75, 250, 350))
new_transform = sitk.AffineTransform(3)
new_transform.SetCenter(image_center)
new_transform.SetTranslation((0, 0, 0))

parameters = {‘numberOfHistogramBins’: 50,
‘SamplingPercentage’: 0.01,
‘learningRate’: 1,
‘numberOfIterations’: 150,
‘convergenceMinimumValue’: 1e-7,
‘convergenceWindowSize’: 10,
‘shrinkFactors’: [4, 2, 1],
‘smoothingSigmas’: [2, 1, 0]}
registration_method = sitk.ImageRegistrationMethod()
registration_method.SetMetricAsMattesMutualInformation(numberOfHistogramBins=parameters[‘numberOfHistogramBins’])
registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
registration_method.SetMetricSamplingPercentage(parameters[‘SamplingPercentage’])
registration_method.SetInterpolator(sitk.sitkLinear)

registration_method.SetOptimizerAsGradientDescent(
learningRate=parameters[‘learningRate’],
numberOfIterations=parameters[‘numberOfIterations’],
convergenceMinimumValue=parameters[‘convergenceMinimumValue’],
convergenceWindowSize=parameters[‘convergenceWindowSize’])
registration_method.SetOptimizerScalesFromPhysicalShift()

registration_method.SetShrinkFactorsPerLevel(parameters[‘shrinkFactors’])
registration_method.SetSmoothingSigmasPerLevel(parameters[‘smoothingSigmas’])
registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()

registration_method.SetInitialTransform(new_transform, inPlace=False)

final_transform = registration_method.Execute(pre_left_sitk, post_left_sitk)

Thanks

Hello @csoconnor,

Yes. Use the VersorTransform. Set its center to the arbitrary center of rotation in the fixed image’s coordinate system:

arbitrary_center_of_rotation = fixed_image.TransformIndexToPhysicalPoint([10,20,30])
new_transform = sitk.VersorTransform()
new_transform.SetCenter(arbitrary_center_of_rotation)
...

Note that when using the versor transform there is no need to SetOptimizerScalesFromPhysicalShift.

1 Like

Thanks, much appreciated!

You could also set optimizer weights:

Take a look at this example of how to apply it.