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:
// 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?
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.
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, 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.
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: