# How to apply an existing BSpline transformation to points, TransformPoint not working for me?

**URL:** https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199
**Category:** Beginner Questions
**Tags:** simpleitk
**Created:** [August 30, 2024, 4:55pm UTC](https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199 "2024-08-30T16:55:50Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![G\_Y](https://discourse.itk.org/user_avatar/discourse.itk.org/g_y/32/3996_2.png) [@G\_Y](https://discourse.itk.org/u/G_Y)
#### Post date: [August 30, 2024, 4:55pm UTC](https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199/1 "2024-08-30T16:55:50Z")

</div>

Hi, I have an existing BSpline transform as a result of registering a pair of images. Now I want to apply this existing transform to a set of 3D points. My idea is to create a new BSplineTransform and call its TransformPoint() function, but something must be missing, my transferred points are exactly the same as before:

```auto
// all information are stored in TransformParameters[1], such as TransformParameters[1]["GridOrigin"] etc
Image coeffImage = new sitk.Image(gridSize, PixelIDValueEnum.sitkVectorFloat32, 3);
coeffImage.SetOrigin(gridOrigin);
coeffImage.SetSpacing(gridSpacing);

// read grid points from TransformParameters[1]
var buffer = coeffImage.GetBufferAsFloat();
var numGridPoints = gridSize[0] * gridSize[1] * gridSize[2] * 3;
var gridPointsVectorString = TransformParameters[1]["TransformParameters"];
for (int i = 0; i < numGridPoints; i++)
{
    gridPoints[i] = float.Parse(gridPointsVectorString[i]);
}
Marshal.Copy(buffer, gridPoints, 0, gridPoints.Length);

VectorUInt32 transformDomainMeshSize = new VectorUInt32(3) { (uint)image.XSize, (uint)image.YSize, (uint)image.ZSize, 2 /* what is this last parameter for? */ };
var bSplineTransform = SimpleITK.BSplineTransformInitializer(coeffImage, transformDomainMeshSize);

// ready to TransformPoint?
var ptTransformed = bSplineTransform.TransformPoint(new VectorDouble(3) { 0, 0, 0 });
ptTransformed = bSplineTransform.TransformPoint(new VectorDouble(3) { 10, 10, 10 });
ptTransformed = bSplineTransform.TransformPoint(new VectorDouble(3) { 300, 200, 6 });
// still the same! Why?

```

Any help would be appreciated!

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [August 30, 2024, 5:40pm UTC](https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199/2 "2024-08-30T17:40:05Z")

</div>

If you already have a transform, why do you want to construct another one? For transforming the points, you usually want the inverse of the resampling transform.

---

<div class="post-metadata">

### Author: ![G\_Y](https://discourse.itk.org/user_avatar/discourse.itk.org/g_y/32/3996_2.png) [@G\_Y](https://discourse.itk.org/u/G_Y)
#### Post date: [August 30, 2024, 8:50pm UTC](https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199/3 "2024-08-30T20:50:23Z")

</div>

I do not want to construct another one, I want to apply the existing transform to a set of 3D points. The original BSpline transform was done by registering a fixed image - moving image pair, and the moving image has been deformed to match the fixed image, this is all good. The transform parameters are all saved into disk for future use. Now if there are some special points or geometry drawn on the moving image, say a manual segmentation of an object, how do I apply the transformation to this segmentation (not an image)? I thought I should create the transform (maybe this is what you mean by “construct”) by loading the already saved transform parameters, then call `TransformPoint()` to transform my points one-by-one, thus the above code. The code ran but doesn’t really do anything. Do I create the transform the right way, or do I miss something?

I think my question is related to [SimpleITK: Using TransformPoint() to Transform Mask Vertices](https://discourse.itk.org/t/simpleitk-using-transformpoint-to-transform-mask-vertices/4244), where in their case the `TransformPoint()` did output new positions for the points, although initially inverted. In my case the points returned by `TransformPoint()` is simply the same as the input points.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [August 30, 2024, 9:10pm UTC](https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199/4 "2024-08-30T21:10:57Z")

</div>

Instead of saving your transform in some custom format, why not use [transform IO](https://simpleitk.readthedocs.io/en/master/IO.html#transformations)?

---

<div class="post-metadata">

### Author: ![G\_Y](https://discourse.itk.org/user_avatar/discourse.itk.org/g_y/32/3996_2.png) [@G\_Y](https://discourse.itk.org/u/G_Y)
#### Post date: [August 30, 2024, 9:54pm UTC](https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199/5 "2024-08-30T21:54:14Z")

</div>

The transform were done by using Elastix, then `SimpleITK.WriteParameterFile()` and `ParameterMap p = SimpleITK.ReadParameterFile(file)` are used to write and read the parameters (currently in .txt format).

Thanks for your question, I found it is different from SimpleITK’s transform format, because calling `var transform = SimpleITK.ReadTransform(transformFile);` gave me error:  
…\itkTxtTransformIO.cxx:160:  
ITK ERROR: TxtTransformIOTemplate(00000176365766E0): Tags must be delimited by :’  
my input transformFile (by Elastix) looks like this:

```auto
(BSplineTransformSplineOrder 3)
(Direction 1 0 0 0 1 0 0 0 1)
(FixedImageDimension 3)
(FixedInternalImagePixelType "float")
(GridDirection 1 0 0 0 1 0 0 0 1)
(GridIndex 0 0 0)
(GridOrigin -108.6132815 -419.105469 -204.75)
(GridSize 15 21 16)
(GridSpacing 15 15 15)
...

```

Then I just tried to write out my newly created BSpline transfrom:

```auto
var bSplineTransform = SimpleITK.BSplineTransformInitializer(coeffImage, transformDomainMeshSize);
SimpleITK.WriteTransform(bSplineTransform, "c:/temp/bSplineTransform.txt");

```

It gives me these:

```auto
#Insight Transform File V1.0
#Transform 0
Transform: BSplineTransform_double_3_3
Parameters: 0 0 0 0 0 0 0 0 0 0 0 0 0 ................
FixedParameters: 515 515 140 -118.43505859375 -429.10302734375 -215.90419708029196 0.44677734375 0.62255859375 1.7791970802919708 1 0 0 0 1 0 0 0 1

```

So I guess my code couldn’t convert the Elastix based transform file to the SimpleITK.BSplineTransform, although I believe they are closely related.

Is there a way to convert the Elastix based transform to `SimpleITK.BSplineTransform`?

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [August 30, 2024, 11:37pm UTC](https://discourse.itk.org/t/how-to-apply-an-existing-bspline-transformation-to-points-transformpoint-not-working-for-me/7199/6 "2024-08-30T23:37:29Z")

</div>

I don’t know about SimpleITK, but ITKPython has a way, both [ITK-\>Elastix](https://github.com/InsightSoftwareConsortium/ITKElastix/issues/246) and [Elastix-\>ITK](https://github.com/InsightSoftwareConsortium/ITKElastix/issues/245). Both of these ways are imperfect, but they exist.
