I need to invert a nonlinear transform generated with the standard 3D Slicer ANTs extension, so it can be applied back to the fixed image to make it more like the moving, but it is becoming clear I do not understand how it behaves.
I am essentially running the default Quick SyN preset for registration in slicer (steps from Rigid, to Affine, to SyN). This generates an impressively accurate forward .h5 transform file that is on the order 15 GB. However, when I click “invert” on my large transform it seems to compute the inverse too fast and it doesn’t behave the way I expected when applied to the fixed image (looks nothing like the moving). Also, I’m curious if the steps (rigid, affine, SyN) need to be unraveled and applied in the reverse order (SyN, affine, rigid) to achieve my goal, or if the this presumed “displacement field” can be inverted in one step and applied. Can the linear transforms be extracted?
It’s my beginner understanding that the main version of ANTs (linux) under the hood is moving both images to a “middle” common point and, as part of this process, both the forward and inverse transforms are iteratively written in tandem and that either can be called up (from RAM, temp file?). Is there a way to retrieve this “default” inverse transform in Slicer? If not, is there a way to properly invert this transform within slicer (I assume it should take some time!).
Also, possibly related, I am not understanding how exactly the “output displacement field” tick box is behaving (see circled area in image). It seems to store the transform more as an image, but then I can’t apply it to any of my volumes. Which works better for inverting? It looks like there are tools for applying displacement fields, but on a first pass they didn’t work with my transform.
Thanks!
Our SlicerANTsPy extension expose both the forward and inverse warps, if you need that. However, the registration call itself is not as customizable as the SlicerANTs extension. You want to use the antsRegistrationQuickSyN[s] for the equivalent of QuickSyN in SlicerANTs extension you are currently using.
Note that I used the “General Registration (ANTs)” module rather than the “SlicerANTsPy” module (out of inertia rather than considered preference, and a namespace conflict has meant that it was not possible to have both extensions installed simultaneously).
In my experience, however, inverting a nonlinear transform calculated via ANTs has worked well for aligning a fixed volume to a moving volume, except sometimes near the edges of the image. Transform inversion appears impossibly quick in Slicer because all that is done is change a flag on the component transforms which basically says “use the inverse of the stored transform”; the inverse is not actually calculated at that time. Instead, when you want to look at a slice view transformed by this inverse transform, only the pixel points on that slice need to have their inverse transforms actually calculated, and this set of points is small enough that the inverse is quickly enough calculated that it appears instantaneous. Slicer set up very cleverly in that way, so that the calculations are only actually performed when they are needed for display.
To answer a different question you asked, yes, Slicer automatically reverses the order of application of the inverses of the rigid, affine, and grid transforms when you invert a composite transform.
It is also possible that you are encountering a recently fixed bug where cloning of a composite transform did not preserve the order of application of component transforms, see here: Cloning a composite transform yields incorrect result
If that isn’t the problem, then I would suggest considering the domains over which your transforms are defined (see the pdf notes from the first link above). If the moving image and fixed image have different spatial extents, then the grids over which the forward and reverse transforms make sense to be defined may differ. Alternatively, if you just want a transform which works in each direction (and don’t need them to represent more or less exact inverses of each other), you can do the registration twice in General Registration (ANTs), or it looks like you could do it once in SlicerANTsPy but set it to generate both output directions.