Jacobian coordinate system in itkDisplacementFieldTransform vs itkDisplacementFieldJacobianDeterminantFilter

I’ve been working on fixing problems in ANTs tensor / vector coordinates lately, which has led me to look at the local Jacobian calculations. I am trying to better understand how the coordinate system of Jacobians work in different classes. In itkDisplacementFieldTransform, the Jacobian is computed on physical displacements, in a voxel neighborhood. Because the neighborhood sampling for central differences is done on the voxel grid, the Jacobian is with respect to voxel coordinates. It is transformed to physical coordinates by applying the direction matrix

This all makes sense to me. But I can’t find the equivalent of that last step in itkDisplacementFieldJacobianDeterminantFilter. There is an option to set custom weights, but I’m not sure that can represent the application of the direction matrix.

Am I missing something? I am trying to figure out how itkDisplacementFieldJacobianDeterminantFilter can provide Jacobians in physical space, if the image has a non-identity direction matrix.

Wait, this is just the determinant, not the full matrix, so it should be invariant under rotation. Sorry!

Now I’m really confused, because I’m seeing divergent results for Jacobians estimated from the two methods. I put example data and code here

Here’s a version with precomputed results

Basically, I register two images of concentric cubes, with different cube size. The images are the same in each test case, but with different direction matrices:

identity/ - identity transform

flip/ - I used c3d -swapdim LPI so that the direction matrix is diag[-1, -1, 1]

oblique/ - I used SimpleITK to set the direction matrix to an oblique rotation. Therefore these are in a different physical space to the other two.

The Jacobian determinant from the transform is roughly similar to that from the determinant filter for the identity case, but in the flipped case, it’s like the sign of the determinant is flipped as well.

I guess I haven’t understood the math fully but it seems the row-by-row transformation that happens to the gradient in the itkDisplacementFieldTransform method is necessary to get the determinants correct.

I had a look at the test case but it appears to use an identity transform as well

1 Like