# Bspline Free form deformable registration

**URL:** <https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586>\
**Category:** Algorithms\
**Created:** [November 16, 2021, 5:54pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586 "2021-11-16T17:54:39Z")\
**Posts on this page:** 20\
**Page:** 2

<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:** [November 19, 2021, 2:14pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/21 "2021-11-19T14:14:04Z")

</div>

Hello @VeerBal,

Yes you need to cast. The fixed and moving images need to be of float type (sitkFloat32 or sitkFloat64). This is independent of the file format. If the original data in the file was in float then no need to cast, just read it. If it isn’t float, read and cast.

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 19, 2021, 2:24pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/22 "2021-11-19T14:24:30Z")

</div>

Yes . Thank you 🙂 . My image reading technique was kinda weird .

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 19, 2021, 3:31pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/23 "2021-11-19T15:31:08Z")

</div>

So in my Affine registration between the same subject , the graph for iterations and metric value looks something like this  
 ![image](https://discourse.itk.org/uploads/default/original/2X/3/37202a880bb1b6693611357135b2a56ee577e500.png)

Where there is a spike after 100th iteration . Is there a way to stop at the convergence value around 100th iteration . I’m using  
registration\_method.SetMetricAsCorrelation()  
registration\_method.SetInterpolator(sitk.sitkLinear)  
and

registration\_method.SetOptimizerAsGradientDescent(  
learningRate=1.0, numberOfIterations=100,convergenceMinimumValue=1e-6) # , estimateLearningRate=registration\_method.EachIteration)  
registration\_method.SetOptimizerScalesFromPhysicalShift()

final\_transform = sitk.AffineTransform(initial\_transform)  
registration\_method.SetInitialTransform(final\_transform)  
registration\_method.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1])  
registration\_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[2, 1, 0])  
registration\_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()

Thank you

---

<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:** [November 19, 2021, 3:44pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/24 "2021-11-19T15:44:02Z")

</div>

I assume that after 100 iterations the registration switches to higher-resolution version of your image. And that causes your metric to spike. The third star is where the highest resolution registration step starts. Overall, this registration seems fine, at least by looking at that graph. Does the result look fine?

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 19, 2021, 3:59pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/25 "2021-11-19T15:59:52Z")

</div>

So the registration in slicer between fixed and transform image looks like this .

 ![image](https://discourse.itk.org/uploads/default/original/2X/7/78eda569eb699cfebd9418d2a2db75ffb1d61ffb.png)

---

<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:** [November 19, 2021, 4:02pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/26 "2021-11-19T16:02:00Z")

</div>

That is very good. Does the alignment along the other 2 axes look as good? If so, it was a very successful registration.

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 19, 2021, 4:03pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/27 "2021-11-19T16:03:23Z")

</div>

So the other two coronal and sagittal looks the same . Just wasn’t sure what was going on with the spike .

Thanks 🙂

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 19, 2021, 4:43pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/28 "2021-11-19T16:43:01Z")

</div>

Sorry to bother .  
After my affine registration , I’m trying to do a Bspline registration where my moving and fixed images are .mha format and my fixed mask is .img ( mask for airway tree ) .

My question is what kind of moving and fixed points do I need and what is the minimum number of points .  
As I’m getting an error

Exception thrown in SimpleITK ImageRegistrationMethod\_Execute: d:\a\1\sitk-build\itk-prefix\include\itk-5.2\itkImageToImageMetricv4.hxx:270:  
ITK ERROR: MeanSquaresImageToImageMetricv4(000001F474731D80): VirtualSampledPointSet must have 1 or more points.

And my fixed and moving points are set to None

Thank you

---

<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:** [November 19, 2021, 6:37pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/29 "2021-11-19T18:37:11Z")

</div>

If your mask is very small relative to the entire volume of the image, as is the case of airways relative to entire chest and air around it captured by a CT image, it causes sampling issues. There is some fixed number of voxels chosen to be used in registration, and only a subset of that falls inside the fixed mask. And those voxels are mapped to the moving image, and only a subset that falls inside the moving mask participates in computation of the metric. In your case, all those intersections yield an empty set.

A quick and good way to proceed would be to ignore you have airway segmentation, and just do normal CT-CT registration without any masks. Have it initialized by your transform coming from registration of lung segmentations. That is easy to do, and should produce decent results.

If you insist on somehow utilizing your airway segmentation, a relatively fast way is to compute [distance fields](https://itk.org/Doxygen/html/classitk_1_1SignedMaurerDistanceMapImageFilter.html) on those binary segmentations and register those distance fields using mean square error as the metric.

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 19, 2021, 9:22pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/30 "2021-11-19T21:22:23Z")

</div>

So just to clarify , you mean doing a b spline CT-CT ( .mha files) between fixed and moving images and then initializing the transform from the registration of lung volume affine as previously performed .

Or should I do an affine registration for lung segmentation masks ( Lung airway masks) and then initialize that transformation to the B spline CT-CT ( .mha ) between fixed and moving images .

thanks 🙂

---

<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:** [November 19, 2021, 9:32pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/31 "2021-11-19T21:32:00Z")

</div>

> [@VeerBal](#):
>
> affine registration for lung segmentation masks and then initialize that transformation to the B spline CT-CT ( .mha ) between fixed and moving images

I meant this.

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 19, 2021, 9:34pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/32 "2021-11-19T21:34:15Z")

</div>

Okay Perfect . Thank you so much

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 22, 2021, 7:05pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/33 "2021-11-22T19:05:59Z")

</div>

I have all the voxel locations ( x, y ,z ) for the connected airway points at each bifurcations . Can those be ideal to use for my moving image and fixed image to do a B-spline registration .

---

<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:** [November 22, 2021, 7:43pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/34 "2021-11-22T19:43:16Z")

</div>

Yes! If they are in the same order for both time-points, you can treat them as [landmarks](https://itk.org/ITKExamples/src/Registration/Common/RegisterImageToAnotherUsingLandmarks/Documentation.html). If not, you can only treat them as [point sets](https://itk.org/Doxygen/html/classitk_1_1PointSetToPointSetRegistrationMethod.html).

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 22, 2021, 7:49pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/35 "2021-11-22T19:49:04Z")

</div>

okay perfect . Thank you 🙂

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 26, 2021, 5:11pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/36 "2021-11-26T17:11:40Z")

</div>

I am doing a B spline FFD registration . I have saved all the moving and the fixed points for the airway tree bifurcations as 2 DataFrame which contain all these (x, y ,z ) points as Float points .  
So my moving and fixed images are .mha format and my fixed mask is .img ( mask for airway tree ) .

When I run the registration I am getting this error

 ![image](https://discourse.itk.org/uploads/default/original/2X/b/b9cf3be7caf9d1082f77d8d5d44d8dfe7881003f.png)

Do I need to save these fixed and moving points as some other type

Thank you

---

<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:** [November 26, 2021, 6:30pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/37 "2021-11-26T18:30:52Z")

</div>

Yes, you should use [PointSet](https://itk.org/Doxygen/html/classitk_1_1PointSet.html). ITK has no idea how to handle Pandas DataFrame.

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 26, 2021, 7:05pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/38 "2021-11-26T19:05:57Z")

</div>

Oh I see what you mean. So is there a way to convert my DataFrame points to PointSet that is readable by itk .

---

<div class="post-metadata">

**Author:** ![jhlegarreta](https://discourse.itk.org/user_avatar/discourse.itk.org/jhlegarreta/32/476_2.png) [@jhlegarreta](https://discourse.itk.org/u/jhlegarreta)\
**Post date:** [November 26, 2021, 9:11pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/39 "2021-11-26T21:11:26Z")

</div>

> So is there a way to convert my DataFrame points to PointSet that is readable by itk .

@VeerBal you will need to see what your `pandas` `DataFrame` contains as data, extract it appropriately, and feed that to any of the `PointSet` class constructors or methods as they expect it. The official documentation of the `PointSet` class is here, as @dzenanz posted in the immediate previous answer:

[https://itk.org/Doxygen/html/classitk\_1\_1PointSet.html](https://itk.org/Doxygen/html/classitk_1_1PointSet.html)

The ITK Examples also [contain code](https://itk.org/ITKExamples/src/Core/Common/CreateAPointSet/Documentation.html) that shows how to use the class. See the related examples at the bottom of that page as well.

The [ITK Software Guide](https://itk.org/ItkSoftwareGuide.pdf) does also contain a section about the `PointSet` class. Section `4.2. PointSet` (p. 57).

Alternatively, you can also have a look at the tests ([this one](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/test/itkPointSetTest.cxx) and [this other one](https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/test/itkPointGTest.cxx)) to try to see what you need to feed to the `PointSet` instance and methods.

Hope this resources are helpful.

---

<div class="post-metadata">

**Author:** ![VeerBal](https://discourse.itk.org/letter_avatar_proxy/v4/letter/v/71c47a/32.png) [@VeerBal](https://discourse.itk.org/u/VeerBal)\
**Post date:** [November 29, 2021, 12:48am UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/40 "2021-11-29T00:48:59Z")

</div>

Thank you so much for your help .  
I converted my DataFrame into two separate lists that contains all the coordinates as floating points for both the fixed and the moving image . Right now I’m trying to import the list onto a Pointset class , but I don’t know if its the right way to proceed .

[Previous page](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586.md?page=1)

[Next page](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586.md?page=3)
