# Jacobian coordinate system in itkDisplacementFieldTransform vs itkDisplacementFieldJacobianDeterminantFilter

**URL:** https://discourse.itk.org/t/jacobian-coordinate-system-in-itkdisplacementfieldtransform-vs-itkdisplacementfieldjacobiandeterminantfilter/7522
**Category:** Algorithms
**Tags:** itk
**Created:** [May 13, 2025, 12:05pm UTC](https://discourse.itk.org/t/jacobian-coordinate-system-in-itkdisplacementfieldtransform-vs-itkdisplacementfieldjacobiandeterminantfilter/7522 "2025-05-13T12:05:41Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![cookpa](https://discourse.itk.org/user_avatar/discourse.itk.org/cookpa/32/255_2.png) [@cookpa](https://discourse.itk.org/u/cookpa)
#### Post date: [May 13, 2025, 12:05pm UTC](https://discourse.itk.org/t/jacobian-coordinate-system-in-itkdisplacementfieldtransform-vs-itkdisplacementfieldjacobiandeterminantfilter/7522/1 "2025-05-13T12:05:41Z")

</div>

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

> <https://github.com/InsightSoftwareConsortium/ITK/blob/1f4534deae74146690a7831efdb1ef489a73d126/Modules/Filtering/DisplacementField/include/itkDisplacementFieldTransform.hxx#L276-L290>

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.

---

<div class="post-metadata">

### Author: ![cookpa](https://discourse.itk.org/user_avatar/discourse.itk.org/cookpa/32/255_2.png) [@cookpa](https://discourse.itk.org/u/cookpa)
#### Post date: [May 13, 2025, 11:11pm UTC](https://discourse.itk.org/t/jacobian-coordinate-system-in-itkdisplacementfieldtransform-vs-itkdisplacementfieldjacobiandeterminantfilter/7522/2 "2025-05-13T23:11:07Z")

</div>

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

---

<div class="post-metadata">

### Author: ![cookpa](https://discourse.itk.org/user_avatar/discourse.itk.org/cookpa/32/255_2.png) [@cookpa](https://discourse.itk.org/u/cookpa)
#### Post date: [May 14, 2025, 8:33pm UTC](https://discourse.itk.org/t/jacobian-coordinate-system-in-itkdisplacementfieldtransform-vs-itkdisplacementfieldjacobiandeterminantfilter/7522/3 "2025-05-14T20:33:59Z")

</div>

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

> **[GitHub - cookpa/antsJacobianExample: Example Jacobian computation from a simple test...](https://github.com/cookpa/antsJacobianExample)**
>
> Example Jacobian computation from a simple test case using ANTs CreateJacobianDeterminantImage

Here’s a version with precomputed results

> **[Box](https://upenn.box.com/s/k7b2p3zggp6pink9xogwz3uxg0psthxs)**

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

> <https://github.com/InsightSoftwareConsortium/ITK/blob/84cb6e8b5fc7784fff149ee2e27911c9dc80f7a2/Modules/Filtering/DisplacementField/test/itkDisplacementFieldJacobianDeterminantFilterTest.cxx>

---

<div class="post-metadata">

### Author: ![cookpa](https://discourse.itk.org/user_avatar/discourse.itk.org/cookpa/32/255_2.png) [@cookpa](https://discourse.itk.org/u/cookpa)
#### Post date: [May 21, 2025, 6:56pm UTC](https://discourse.itk.org/t/jacobian-coordinate-system-in-itkdisplacementfieldtransform-vs-itkdisplacementfieldjacobiandeterminantfilter/7522/4 "2025-05-21T18:56:30Z")

</div>

I think this might actually be a bug

> <https://github.com/InsightSoftwareConsortium/ITK/issues/5358>
>
> \### Description
> 
> Jacobian determinants from itk::DisplacementFieldJacobianDeterm…inantFilter differ from those derived from itkDisplacementFieldTransform.hxx if the displacement field image has non-identity direction matrix.
> 
> \### Steps to Reproduce
> 
> Here's a link to ITK code that computes Jacobian two ways: by using the itk::DisplacementFieldJacobianDeterminantFilter, and by iterating over each voxel calling \`transform-\>ComputeJacobianWithRespectToPosition\` on a displacement field transform object.
> 
> https://github.com/cookpa/antsJacobianExample/tree/master/itk\_jacobian
> 
> The warp fields I tested on were from ANTs, and are available here
> 
> https://upenn.box.com/s/voe2agpd30serkj4kn0fvt9bit8pg5nx
> 
> By integrating the Jacobian over each label in the fixed space, I computed the expected volume of the deformed moving image. For an identity direction matrix, the two methods are similar.
> 
> But for the case where the direction matrix is diag(-1,-1,1), the determinant filter is very different.
>  
> 
> \### Expected behavior
> 
> Determinants are similar, if not exactly the same. They should both approximate the volume change within a region due to the warp.
> 
> 
> \### Actual behavior
> 
> Differences of a few percent for oblique direction matrices, large differences for D = diag(-1,-1, 1).
> 
> 
> \### Reproducibility
> 
> Consistent on my test data.
> 
> \### Versions
> 
> v5.4.3
> 
> \### Environment
> 
> Mac OS Intel
> Python 3.11
> Apple clang version 16.0.0 (clang-1600.0.26.6)
> 
> 
> \### Additional Information
> 
> Code at https://github.com/cookpa/antsJacobianExample
> 
> The box link above contains data and code.
