# applying saved transforms/registration to the subsequent channels

**URL:** https://discourse.itk.org/t/applying-saved-transforms-registration-to-the-subsequent-channels/5797
**Category:** Uncategorized
**Tags:** saving-tfm, transforms
**Created:** [March 13, 2023, 10:06pm UTC](https://discourse.itk.org/t/applying-saved-transforms-registration-to-the-subsequent-channels/5797 "2023-03-13T22:06:16Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![banikr](https://discourse.itk.org/user_avatar/discourse.itk.org/banikr/32/3296_2.png) [@banikr](https://discourse.itk.org/u/banikr)
#### Post date: [March 13, 2023, 10:06pm UTC](https://discourse.itk.org/t/applying-saved-transforms-registration-to-the-subsequent-channels/5797/1 "2023-03-13T22:06:16Z")

</div>

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:

```auto
initial_transform = sitk.Euler2DTransform(sitk.CenteredTransformInitializer(
        fixed_image,
        moving_image,
        sitk.Euler2DTransform(),
        sitk.CenteredTransformInitializerFilter.MOMENTS)) 
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.SetMovingInitialTransform(eulerTx)
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:

```auto
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?

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [March 13, 2023, 10:27pm UTC](https://discourse.itk.org/t/applying-saved-transforms-registration-to-the-subsequent-channels/5797/2 "2023-03-13T22:27:59Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![banikr](https://discourse.itk.org/user_avatar/discourse.itk.org/banikr/32/3296_2.png) [@banikr](https://discourse.itk.org/u/banikr)
#### Post date: [March 14, 2023, 4:50pm UTC](https://discourse.itk.org/t/applying-saved-transforms-registration-to-the-subsequent-channels/5797/3 "2023-03-14T16:50:05Z")

</div>

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:

```auto
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.SetReferenceImage(fixed_image)
resampler.SetInterpolator(sitk.Linear) # linear or NN, outTx was achieved by NN but 
#moving image is not labeled segmentation. 
resampler.SetDefaultPixelValue(0)
resampler.SetTransform(outTx)
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:

```auto
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.

**Update**  
The composite method above worked!!

Thanks @zivy

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [March 15, 2023, 12:22am UTC](https://discourse.itk.org/t/applying-saved-transforms-registration-to-the-subsequent-channels/5797/4 "2023-03-15T00:22:05Z")

</div>

Hello @banikr,

Congrats!

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:

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

```

---

<div class="post-metadata">

### Author: ![banikr](https://discourse.itk.org/user_avatar/discourse.itk.org/banikr/32/3296_2.png) [@banikr](https://discourse.itk.org/u/banikr)
#### Post date: [March 15, 2023, 3:20pm UTC](https://discourse.itk.org/t/applying-saved-transforms-registration-to-the-subsequent-channels/5797/5 "2023-03-15T15:20:59Z")

</div>

Thanks, @zivy you’ve been very helpful.
