applying saved transforms/registration to the subsequent channels

Suppose I am using the red channel of a RGB image, as it carries the most details.
Now I applied a working registration method as following:

initial_transform = sitk.Euler2DTransform(sitk.CenteredTransformInitializer(
registration_method = sitk.ImageRegistrationMethod()
# then registration attributes...
registration_method.SetInitialTransform(initial_transform, inPlace=True)
eulerTx = registration_method.Execute(fixed_image, moving_image)
# then resample attributes...
affine = sitk.AffineTransform(fixed_image.GetDimension())
registration_method.SetInitialTransform(affine, inPlace=True)
# registration attributes again... 
affineTx = registration_method.Execute(fixed_image, moving_image)
compositeTx = sitk.CompositeTransform([eulerTx, affineTx])
out = resampler.Execute(moving_image)
# then final non-rigid transform
registration_method = sitk.ImageRegistrationMethod()
transform_to_displacment_field_filter = sitk.TransformToDisplacementFieldFilter()
# then multi-scale transform...
outTx = registration_method.Execute(fixed_image, moving_image)
# finally the registration...
out = resampler.Execute(out)

Now how do I apply these 3 transforms to the other channels of the image?
I think I can save the transforms as:

outTxFile = 'channel{}_{}_OutTx.tfm'.format(nChannel, nSlice)
sitk.WriteTransform(outTx, outTxFile)

Do I save the three transforms separately? or all three transforms can be saved in a single .tfm file?

Hello @banikr,

After the multi-step registration you should have a single composite transform in hand, comprised of the rigid, affine, displacement. Save it to a single file (sitk.WriteTransform). Do not use .tfm which is ASCII, readable for human but very slow IO for displacement field. Instead use a binary format, the extension .hdf. You won’t be able to look at the file with an editor but the format is much more appropriate for IO of displacement fields.


Hi @zivy
could you give some code example on how to read a saved transformation and apply it to different images?

The way I am doing is not working:

outTxFile = os.path.join(dataFold, 'saved_outTx.hdf')
outTx = sitk.ReadTransform(outTxFile)
fixed_image = sitk.Cast(sitk.GetImageFromArray(theFixedImageWhichGotOutTx), sitk.sitkFloat32)
moving_image = sitk.Cast(sitk.GetImageFromArray(newImageToApplyOutTx), sitk.sitkFloat32)
resampler = sitk.ResampleImageFilter()
resampler.SetInterpolator(sitk.Linear)  # linear or NN, outTx was achieved by NN but 
#moving image is not labeled segmentation. 
out = resampler.Execute(moving_image)
displayImage(sitk.GetArrayFromImage(out), Title_='transformed ion image')

One thing is I didn’t create a composite transform as following:

finalTx = sitk.CompositeTransform([eulerTx, affineTx, outTx]) 

and then save it and read it for applying.
I will try that and share with you if that works.

The composite method above worked!!

Thanks @zivy

Hello @banikr,


One comment with respect to the SimpleITK API. When you need to perform a one time operation, we recommend using the procedural interface, it is more concise. When the operation is repeated multiple times use the object-oriented interface, so you create objects once and use them multiple times, potentially with different settings. The procedural interface creates new objects every time under the hood.

Resampling in this case becomes:

out = sitk.Resample(moving_image, fixed_image, outTx, sitk.Linear, 0)

Thanks, @zivy you’ve been very helpful.