# 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:** 4

<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: [December 2, 2021, 5:11pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/61 "2021-12-02T17:11:16Z")

</div>

> [@VeerBal](#):
>
> image bifurcation points

Once you have points, they are points. It does not matter that they came from an image. You need to treat them as points, e.g. use point-set registration instead of image registration. That is currently not exposed in Python interface, which might be causing confusion for 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: [December 2, 2021, 5:18pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/62 "2021-12-02T17:18:14Z")

</div>

Oh I see what you mean . I have a follow up question as well .  
So for this second half of the B-spline registration

```auto
# Select the fixed and moving images, valid entries are in [0,9].
fixed_image_index = 0
moving_image_index = 7

tx = bspline_intra_modal_registration(fixed_image = images[fixed_image_index], 
                                      moving_image = images[moving_image_index],
                                      fixed_image_mask = (masks[fixed_image_index] == lung_label),
                                      fixed_points = points[fixed_image_index], 
                                      moving_points = points[moving_image_index]
                                     )
initial_errors_mean, initial_errors_std, _, initial_errors_max, initial_errors = ru.registration_errors(sitk.Euler3DTransform(), points[fixed_image_index], points[moving_image_index])
final_errors_mean, final_errors_std, _, final_errors_max, final_errors = ru.registration_errors(tx, points[fixed_image_index], points[moving_image_index])

plt.hist(initial_errors, bins=20, alpha=0.5, label='before registration', color='blue')
plt.hist(final_errors, bins=20, alpha=0.5, label='after registration', color='green')
plt.legend()
plt.title('TRE histogram');
print('Initial alignment errors in millimeters, mean(std): {:.2f}({:.2f}), max: {:.2f}'.format(initial_errors_mean, initial_errors_std, initial_errors_max))
print('Final alignment errors in millimeters, mean(std): {:.2f}({:.2f}), max: {:.2f}'.format(final_errors_mean, final_errors_std, final_errors_max)) 

```

There are fixed\_points = points[fixed\_image\_index], and moving\_points = points[moving\_image\_index] . So what exactly do these points corresponds do .

Thank you 🙂

---

<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: [December 2, 2021, 5:25pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/63 "2021-12-02T17:25:03Z")

</div>

Hello @VeerBal,

Those points are not used for registration. They are corresponding points (same points over the respiratory cycle) which were manually localized and are used in the code for evaluating the quality of the intensity based 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: [December 2, 2021, 5:30pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/64 "2021-12-02T17:30:16Z")

</div>

That makes sense . Thanks a lot . 🙂

---

<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: [December 2, 2021, 6:51pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/65 "2021-12-02T18:51:20Z")

</div>

Is there a way to implement this approach for my data set .

---

<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: [December 3, 2021, 4:47pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/66 "2021-12-03T16:47:17Z")

</div>

Here is an updated PR:

> <https://github.com/InsightSoftwareConsortium/ITK/pull/2920>
>
> PointSetToPointSetMetric and PointSetToPointSetRegistrationMethod Python wrappin…g added as requested in \[ITK Discourse\](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/56?u=dzenanz).
> 
> 
> \<!-- See the CONTRIBUTING (CONTRIBUTING.md) guide. Specifically:
> 
> Start ITK commit messages with a standard prefix (and a space):
> 
> \* BUG: fix for runtime crash or incorrect result
> \* COMP: compiler error or warning fix
> \* DOC: documentation change
> \* ENH: new functionality
> \* PERF: performance improvement
> \* STYLE: no logic impact (indentation, comments)
> \* WIP: Work In Progress not ready for merge
> 
> Provide a short, meaningful message that describes the change you made.
> 
> When the PR is based on a single commit, the commit message is usually left as
> the PR message.
> 
> A reference to a related issue or pull request (https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests)
> in your repository. You can automatically
> close a related issues using keywords (https://help.github.com/articles/closing-issues-using-keywords/)
> 
> @mentions (https://help.github.com/articles/basic-writing-and-formatting-syntax/#mentioning-people-and-teams)
> of the person or team responsible for reviewing proposed changes. --\>
> 
> \## PR Checklist
> \- \[X\] Added Python wrapping to new files (if any) as described in \[ITK Software Guide\](https://itk.org/ItkSoftwareGuide.pdf) Section 9.5
> 
> Refer to the \[ITK Software Guide\](https://itk.org/ItkSoftwareGuide.pdf) for
> further development details if necessary.

---

<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: [December 3, 2021, 4:56pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/67 "2021-12-03T16:56:18Z")

</div>

That’s awesome . Can you tell me a bit more how to use this PR for my code .

Thanks a lot .

---

<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: [December 3, 2021, 5:05pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/68 "2021-12-03T17:05:42Z")

</div>

You could [build from source](https://itkpythonpackage.readthedocs.io/en/master/Build_ITK_Python_packages.html). Or wait until this is integrated into master and makes its way into a release, so you can `pip install` it.

---

<div class="post-metadata">

### Author: ![Pranjal\_Sahu](https://discourse.itk.org/user_avatar/discourse.itk.org/pranjal_sahu/32/2698_2.png) [@Pranjal\_Sahu](https://discourse.itk.org/u/Pranjal_Sahu)
#### Post date: [December 3, 2021, 5:53pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/69 "2021-12-03T17:53:24Z")

</div>

You should be able to instantiate the registration method and metric as below:

```auto
registration_metric = itk.PointSetToPointSetMetric.PSF3.New()
registration_method = itk.PointSetToPointSetRegistrationMethod.REGF3F3.New()

```

---

<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: [December 3, 2021, 7:08pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/70 "2021-12-03T19:08:27Z")

</div>

> [@Pranjal\_Sahu](#):
>
> `registration_metric = itk.PointSetToPointSetMetric.PSF3.New()`

Alternatively, `registration_metric = itk.PointSetToPointSetMetric[PointSetType].New()`

---

<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: [December 3, 2021, 7:29pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/71 "2021-12-03T19:29:50Z")

</div>

Thank you so much @Pranjal_Sahu and @dzenanz . I will try this approach .

---

<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: [December 3, 2021, 7:34pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/72 "2021-12-03T19:34:01Z")

</div>

Just for clarification . In my Bspline registration function , I should replace  
registration\_method = sitk.ImageRegistrationMethod()  
and  
registration\_method.SetMetricAsMeanSquares()  
with  
registration\_metric = itk.PointSetToPointSetMetric[PointSetType].New()  
and  
registration\_method = itk.PointSetToPointSetRegistrationMethod.REGF3F3.New()

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: [December 3, 2021, 7:37pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/73 "2021-12-03T19:37:53Z")

</div>

Yes. But now you will need an extra call, something like `registration_method.SetMetric(registration_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: [December 3, 2021, 7:41pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/74 "2021-12-03T19:41:29Z")

</div>

> [@dzenanz](#):
>
> SetMetric

Perfect . Thanks for the clarification . Will keep you posted with the results 🙂

---

<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: [December 17, 2021, 4:27pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/76 "2021-12-17T16:27:30Z")

</div>

Hello  
So I was working on my code with the Bspline FFD and my code was similar to the one used in the POPI model . Previously I was getting an error [virtual sampled points must have one or more points]

This is the part of the code:

```auto
registration_method.SetInitialTransformAsBSpline(initial_transform,
                                                 inPlace=False,
                                                 scaleFactors=[1,2,4])

registration_method.SetMetricAsMeanSquares()
 registration_method.SetMetricAsJointHistogramMutualInformation()
registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
registration_method.SetMetricSamplingPercentage(0.01)
#registration_method.SetMetricFixedMask(Fixed_image_sitk_ffd_mask)
    
registration_method.SetShrinkFactorsPerLevel(shrinkFactors = [4,2,1])
registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[2,1,0])
registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()

registration_method.SetInterpolator(sitk.sitkLinear)
registration_method.SetOptimizerAsLBFGS2(solutionAccuracy=1e-2, numberOfIterations=100, deltaConvergenceTolerance=0.01)

registration_method.AddCommand(sitk.sitkIterationEvent, lambda: iteration_callback(registration_method))

final_transformation = registration_method.Execute(Fixed_image_sitk_ffd, Moving_image_sitk_ffd)
print('\nOptimizer\'s stopping condition, {0}'.format(registration_method.GetOptimizerStopConditionDescription())) 

```

so when I run this code without commenting the line registration\_method.SetMetricFixedMask(Fixed\_image\_sitk\_ffd\_mask) I still get the same error as above . But when I comment this line the code runs and gives me an output of  
-0.64  
Optimizer’s stopping condition, Already minimized

my moving and fixed images for now are the lung dicom images that have been saved as .mha files , but I haven’t used any mask files in this code .

Can you provide some insights about what might be causing that error in the place .

---

<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: [December 17, 2021, 4:39pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/77 "2021-12-17T16:39:41Z")

</div>

> [@VeerBal](#):
>
> Optimizer’s stopping condition, Already minimized

The optimizer cannot improve registration metric. Try setting tighter tolerances (e.g. `solutionAccuracy=1e-4`).

> [@VeerBal](#):
>
> I still get the same error as above

Please repeat the error message, as this thread is already long and it is not clear to which “above error” you are referring. Also consider starting a new discussion thread.

---

<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: [December 17, 2021, 4:53pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/78 "2021-12-17T16:53:23Z")

</div>

Sorry for not being clear in the first place .  
So by error I meant  
final\_transformation = registration\_method.Execute(Fixed\_image\_sitk\_ffd, Moving\_image\_sitk\_ffd)

File “C:\Users\singhgau\Anaconda3\lib\site-packages\SimpleITK\SimpleITK.py”, line 10387, in Execute  
return \_SimpleITK.ImageRegistrationMethod\_Execute(self, fixed, moving)

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

This is when I have registration\_method.SetMetricFixedMask(Fixed\_image\_sitk\_ffd\_mask) .

---

<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: [December 17, 2021, 5:01pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/79 "2021-12-17T17:01:23Z")

</div>

This probably means there is no overlap of your mask and your image. Potentially there is a small overlap, but none of the randomly chosen 1% of points do not fall there.

---

<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: [December 17, 2021, 5:04pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/80 "2021-12-17T17:04:27Z")

</div>

So is there a way to fix the error, or just not use this line at all .  
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: [December 17, 2021, 5:48pm UTC](https://discourse.itk.org/t/bspline-free-form-deformable-registration/4586/81 "2021-12-17T17:48:21Z")

</div>

Try increasing sampling percentage (`registration_method.SetMetricSamplingPercentage(0.01)` and make sure that your fixed mask is in the same physical space as your fixed image.

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

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