Displacement field to (BSpline) Transform

Dear community,

I am looking for a way to obtain a (bspline) transformation given a displacement field (x y z 3) defined on a regular grid. The reason I want to obtain this transformation is to reduce the memory consumption and increase the processing speed.

I understand that this operation requires fitting. Is it possible to do it using ITK?

I believe that something similar is called ScatteredTransform in 3D Slicer and it is done using multi-level Bspline interpolation algorithm. Does ITK provide similar functionality?

Any help would be appreciated.

Hi @Mikhail ,

To obtain a displacement field from a b-spline or other transform, use TransformToDisplacementFieldFilter.

This filter is available in the itk-5.3rc1 Python packages.

Try

displacement_field = itk.transform_to_displacement_field_filter(bspline_transform, 
                                                                                                     use_reference_image=True, 
                                                                                                     reference_image=my_reference_image)

Hi @Mikhail,

I suspect the filter you are looking for is BSplineScatteredDataPointSetToImageFilter.

@matt.mccormick, you are pointing in the opposite direction :wink: .

1 Like

@zivy yes, that will go in the other direction :slight_smile:

My understanding that @Mikhail actually asks for displacement field to bspline conversion. BSplineScatteredDataPointSetToImageFilter could be used but it would be probably very slow.

Actually both displacement field and bspline transforms are 3D volumes with vector voxels. The only difference between them is that displacement field uses linear interpolation between the grid points by default, while bspline transform uses bspline interpolation.

Since these are essentially 3D images, you can convert between them using any of the image resampling filters. As always, if you downsample an image, you need to apply a low-pass filter first (for example, a windowed sinc or Gaussian).

While this is true, BSpline image usually has 2^dim orders of magnitude lower size and different content (coefficients instead of displacements).

Fitting a BSpline transform to an arbitrary displacement filed is an optimization problem (BSplineScatteredDataPointSetToImageFilter seems to be solving a more general problem). It can be made less computationally demanding by low-pass filtering and downsizing the displacement field.

While this is true, BSpline image usually has 2^dim orders of magnitude lower size and different content (coefficients instead of displacements).

It is just a convention that you use lower resolution when you use bspline interpolation. Of course this makes sense for biomedical images because there the displacement is often smooth and therefore it can be represented with less control points if a smooth interpolation is used between them.

Correct. Note that VTK has a more specialized filter to compute spline coefficients from displacements defined on a regular grid: vtkImageBSplineCoefficients, which I would expect to work faster than a more general filter. This paper gives a nice practical overview of this topic.

1 Like

Thank you for the help! I think that it is what I am looking for, even though it appears to be quite complicated.

I saw that there are only C++ examples in the documentation. It is possible to use these functionality from Python? Do you maybe have a code example in Python?

I don’t think there is a Python example for this filter, but you could look at BoundingBoxOfAPointSet and ResampleAnImage for inspiration.