SyneRBI / SIRF

Main repository for the CCP SynerBI software
http://www.ccpsynerbi.ac.uk
Other
60 stars 29 forks source link

Jacobian of b-spline coefficients #658

Open rijobro opened 4 years ago

rijobro commented 4 years ago

We've discussed this several times, but for motion estimation algorithms, we're going to need to be able to calculate (or apply) the Jacobian of our motion b-spline coefficients.

This should be possible with SuPreMo, with a bit of refactoring. Alternatively, we could go down the VTK/ITK route, as discussed on their respective discourses here and here. I'll leave it a while to see what the answers are on those forums (fora?) before we make a decision.

rijobro commented 4 years ago

From the VTK discourse:

The vtkBSplineTransform::InternalTransformDerivative() method does this, it is declared in the vtkAbstractTransform base class:

  /**
   * This will transform a point and, at the same time, calculate a
   * 3x3 Jacobian matrix that provides the partial derivatives of the
   * transformation at that point.  This method does not call Update.
   * Meant for use only within other VTK classes.
   */
  virtual void InternalTransformDerivative(
    const float in[3], float out[3], float derivative[3][3]) = 0;
  virtual void InternalTransformDerivative(
    const double in[3], double out[3], double derivative[3][3]) = 0;

This method computes the partial derivatives of the output coords with respect to the input coords. It’s called “Internal” just because it’s primary purpose is to be used internally by other vtkAbstractTransform methods, but it’s a public method so it’s fine to call it directly. Of course this method only computes the Jacobian at a single point.

Most VTK users do not grab the Jacobian directly. A more typical usage pattern, e.g. if someone has a finite element mesh that includes vector data, is to use vtkTransformFilter to apply a transform to the mesh. In this case, VTK takes care of the details of applying the Jacobian to the vectors.

rijobro commented 4 years ago

And from ITK discourse:

A few pointers:

itk::BSplineTransform ComputeJacobianFromBSplineWeightsWithRespectToPosition itk::BSplineTransform ComputeJacobianWithRespectToParameters itk::TransformToDisplacementFieldFilter itk::DisplacementFieldJacobianDeterminantFilter