# Interpolate between VersorRigid3DTransforms (with different centers of rotation)

**URL:** https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655
**Category:** Beginner Questions
**Created:** [December 9, 2021, 5:46am UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655 "2021-12-09T05:46:48Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![dperl](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/9d8465/32.png) [@dperl](https://discourse.itk.org/u/dperl)
#### Post date: [December 9, 2021, 5:46am UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/1 "2021-12-09T05:46:48Z")

</div>

I want to rigidly register two very large microCT volumes (~1000x1000x1000 voxels) of a material sample taken at different times. The sample has small features (eg. roughly 10x10x10 voids), homogeneously distributed across the volume. Registration on the full volume is intractable, and if I drastically downsample first, all the volume features get washed out and the registration fails. However if I take small crops of the volume (say 100x100x100), the registration succeeds. Rather than rely on the registration of a single crop, I’d like to “average” or “interpolate between” the registrations of a few crops across the volume to be more robust to any small deformations there may be across the sample, or noise in the registration optimization.

Specifically, if I have two VersorRigid3DTransforms which represent registrations of 100x100x100 crops from opposing corners of the volume (eg, crops centered at [50,50,50] and [950,950,950]).

1. How can I interpolate between the transforms (perhaps using slerp?) to get a single rigid transform I can apply to my full volume?
2. Should the original crop transforms have the same center of rotation? Or is it possible to somehow adjust the center of rotation from the crop center (eg. [50,50,50]) to the full volume center ( [500,500,500])?

---

<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 9, 2021, 1:53pm UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/2 "2021-12-09T13:53:40Z")

</div>

To make the averaging problem easier, you could set all your transforms to use the same center (center of your volume) using `transform->SetCenter(volumeCenterPoint);`.

Averaging translations should be simple enough.

And for averaging angle, I am not sure whether just simple average of the quaternions would do it. Unless you find some math describing averaging of quaternions, simple mean is worth a shot.

---

<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 9, 2021, 2:11pm UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/3 "2021-12-09T14:11:09Z")

</div>

Hello @dperl

SLERP is appropriate if you have two quaternions.

To average multiple quaternions while retaining the unit norm see [the paper](http://www.acsu.buffalo.edu/~johnc/ave_quat07.pdf) by Markley et al. “Averaging Quaternions”. Readily implemented as it only involves computing the eigenvector corresponding to the largest eigenvalue of a specific matrix.

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [December 9, 2021, 2:21pm UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/4 "2021-12-09T14:21:09Z")

</div>

I would consider a different approach.

I the local rotation of the transform can be extrapolated to the global / average.

I’d consider solving the problem a set of local “landmark” based registrations. With these local transformation, a point set can be generated in the local “landmark” patched. Then the global transform could be solved from this point set.

---

<div class="post-metadata">

### Author: ![dperl](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/9d8465/32.png) [@dperl](https://discourse.itk.org/u/dperl)
#### Post date: [December 9, 2021, 5:50pm UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/5 "2021-12-09T17:50:59Z")

</div>

Thanks zivy. Two quaternions is probably enough for me, at least at first. Is there a SLERP implementation or example in ITK?

---

<div class="post-metadata">

### Author: ![dperl](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/9d8465/32.png) [@dperl](https://discourse.itk.org/u/dperl)
#### Post date: [December 9, 2021, 5:53pm UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/6 "2021-12-09T17:53:04Z")

</div>

Interesting, do you propose the landmarks be generated from the cropped registrations, or in some other way? Is there an example for how to generate these landmarks in ITK?  
Thanks

---

<div class="post-metadata">

### Author: ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)
#### Post date: [December 9, 2021, 6:51pm UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/7 "2021-12-09T18:51:58Z")

</div>

> [@dperl](#):
>
> Interesting, do you propose the landmarks be generated from the cropped registrations, or in some other way? Is there an example for how to generate these landmarks in ITK?  
> Thanks

My suggestion was inspired by the 3D Slicer Landmark Registration module:

> **[GitHub - Slicer/LandmarkRegistration: An interactive registration tool that...](https://github.com/Slicer/LandmarkRegistration)**
>
> An interactive registration tool that manages viewing and manipulating of sets of fiducials - GitHub - Slicer/LandmarkRegistration: An interactive registration tool that manages viewing and manipul...

The module first registers cropped regions around user selected points ( local affine registration ). Then performs a global fitting of the corresponding fixed to moving point sets. It has options for a global affine and global thin plate spline.

> [@dzenanz](#):
>
> To make the averaging problem easier, you could set all your transforms to use the same center (center of your volume) using `transform->SetCenter(volumeCenterPoint);`.

Setting center of the local transform to the global volume center, would make the averaging problem easier at the cost of the robustness and/or stability of the optimization for the local registration.

---

<div class="post-metadata">

### Author: ![dperl](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/9d8465/32.png) [@dperl](https://discourse.itk.org/u/dperl)
#### Post date: [December 13, 2021, 7:26pm UTC](https://discourse.itk.org/t/interpolate-between-versorrigid3dtransforms-with-different-centers-of-rotation/4655/8 "2021-12-13T19:26:02Z")

</div>

Ok thanks, I’ll have a look at this, maybe it’s an easier way to get global registration than my original approach.
