[Insight-developers] GetInverse is unusable -- patch attached

Rupert Brooks rupe.brooks at gmail.com
Mon Oct 13 09:36:50 EDT 2008


Hi Pavel,

I really like the idea of having a GetInverse method at the Transform
Base class level.  It would also be nice to have a Compose() method
for similar reasons.   Its also clever to make the
InverseTransformType different from the current transform type
(obvious in retrospect... but i hadnt thought of it).

Its of course not up to me whether this gets implemented in the main
trunk.  Just a quick tip though - I have similar problems with my
code, but rather than patching ITK which as you point out is quite
painful for your users, i used a Facade class.  I tucked generic
Compose and Inverse methods (and misc other things) in there.  Much
less elegant though, it ends up amounting to a bunch of switch
statements.  Still, it might get you around your code distribution
issue in the short term.

http://en.wikipedia.org/wiki/Facade_pattern

In my case, my facade class takes a transform in its constructor, and
then supplies GetInverse(), and Compose methods(), and so forth for
that transform.

That being said, the transforms you have created sound extremely
useful - I for one would be very interested in seeing an Insight
journal submission or other release.  I had been considering writing
something similar to your NewtonMethodInverse but never found the
time.

Cheers,
Rupert B.


On Fri, Oct 10, 2008 at 10:55 AM, Pavel Koshevoy <koshevoy at sci.utah.edu> wrote:
> Hi,
>
> I've been patching ITK since version 1.8.1 to provide a usable GetInverse
> API for transforms which don't have an analytic inverse, or have an
> approximate inverse transform of a different type.
>
> Requiring a patched ITK is a hurdle in the path of developers trying to
> build my image registration apps.  I really, really hope you merge this
> patch into the trunk.
> It's a very small change.  Basically, I define an InverseTransformPointer
> type and add virtual InverseTransformPointer GetInverse() const method.  The
> patch implements this API for itk::Transform, itk::IdentityTransform,
> itk::MatrixOffsetTransformBase, itk::ScaleTransform,
> itk::TranslationTransform.
> These are useful changes that make the ITK Transform classes far more
> useful. In my image registration apps I implement this API in my Legender
> Polynomial Transform, a Radial Basis Function Transform, Triangle Mesh
> Transform, Radial Distortion Transform, Cascaded Transform, and a generic
> Newtons Method Numeric Inverse Transform.
>
> I really hope someone takes a look at this short patch and adds it to the
> main ITK trunk.
>
> Thank you,
>   Pavel.
>
>
>
> diff -uBbr InsightToolkit-3.8.0/Code/Common/itkIdentityTransform.h
> InsightToolkit-3.8.0-patched/Code/Common/itkIdentityTransform.h
> --- InsightToolkit-3.8.0/Code/Common/itkIdentityTransform.h     2007-07-18
> 14:12:24.000000000 -0600
> +++ InsightToolkit-3.8.0-patched/Code/Common/itkIdentityTransform.h
> 2008-08-31 08:54:07.702753172 -0600
> @@ -62,6 +62,10 @@
>   typedef SmartPointer< Self >   Pointer;
>   typedef SmartPointer< const Self >  ConstPointer;
>
> +  /** Base inverse transform type. */
> +  typedef typename Superclass::InverseTransformType InverseTransformType;
> +  typedef SmartPointer< InverseTransformType > InverseTransformPointer;
> +
>   /** New method for creating an object using a factory. */
>   itkNewMacro(Self);
>
> @@ -166,6 +170,10 @@
>     return this->m_Jacobian;
>     }
>
> +  /** Return an inverse of the identity transform - another identity
> transform. */
> +  virtual InverseTransformPointer GetInverse() const
> +  { return this->New().GetPointer(); }
> +
>   /** Indicates that this transform is linear. That is, given two
>    * points P and Q, and scalar coefficients a and b, then
>    *
> diff -uBbr InsightToolkit-3.8.0/Code/Common/itkMatrixOffsetTransformBase.h
> InsightToolkit-3.8.0-patched/Code/Common/itkMatrixOffsetTransformBase.h
> --- InsightToolkit-3.8.0/Code/Common/itkMatrixOffsetTransformBase.h
> 2008-06-29 06:58:58.000000000 -0600
> +++ InsightToolkit-3.8.0-patched/Code/Common/itkMatrixOffsetTransformBase.h
>     2008-08-31 08:55:25.010253114 -0600
> @@ -89,6 +89,10 @@
>   typedef SmartPointer<Self>                    Pointer;
>   typedef SmartPointer<const Self>              ConstPointer;
>
> +  /** Base inverse transform type. */
> +  typedef typename Superclass::InverseTransformType InverseTransformType;
> +  typedef SmartPointer< InverseTransformType > InverseTransformPointer;
> +
>   /** Run-time type information (and related methods).   */
>   itkTypeMacro( MatrixOffsetTransformBase, Transform );
>
> @@ -332,6 +336,12 @@
>     **/
>   bool GetInverse(Self * inverse) const;
>
> +  /** Return an inverse of this transform. */
> +  virtual InverseTransformPointer GetInverse() const
> +  {
> +    Pointer inv = New();
> +    return GetInverse(inv) ? inv.GetPointer() : NULL;
> +  }
>
>   /** \deprecated Use GetInverse instead.
>    *
> diff -uBbr InsightToolkit-3.8.0/Code/Common/itkScaleTransform.h
> InsightToolkit-3.8.0-patched/Code/Common/itkScaleTransform.h
> --- InsightToolkit-3.8.0/Code/Common/itkScaleTransform.h        2006-11-03
> 13:09:08.000000000 -0700
> +++ InsightToolkit-3.8.0-patched/Code/Common/itkScaleTransform.h
>  2008-08-31 08:53:33.326253437 -0600
> @@ -48,6 +48,10 @@
>   typedef SmartPointer<Self>        Pointer;
>   typedef SmartPointer<const Self>  ConstPointer;
>
> +  /** Base inverse transform type. */
> +  typedef typename Superclass::InverseTransformType InverseTransformType;
> +  typedef SmartPointer< InverseTransformType > InverseTransformPointer;
> +
>   /** New macro for creation of through a smart pointer. */
>   itkNewMacro( Self );
>
> @@ -146,6 +150,13 @@
>    * false is returned. */
>   bool GetInverse(Self* inverse) const;
>
> +  /** Return an inverse of this transform. */
> +  virtual InverseTransformPointer GetInverse() const
> +  {
> +    Pointer inv = New();
> +    return GetInverse(inv) ? inv.GetPointer() : NULL;
> +  }
> +
>   /** Set the transformation to an Identity
>    *
>    * This sets all the scales to 1.0 */
> diff -uBbr InsightToolkit-3.8.0/Code/Common/itkTransform.h
> InsightToolkit-3.8.0-patched/Code/Common/itkTransform.h
> --- InsightToolkit-3.8.0/Code/Common/itkTransform.h     2008-06-29
> 06:58:58.000000000 -0600
> +++ InsightToolkit-3.8.0-patched/Code/Common/itkTransform.h     2008-08-31
> 08:51:59.330253158 -0600
> @@ -72,6 +72,12 @@
>   typedef SmartPointer< Self >   Pointer;
>   typedef SmartPointer< const Self >  ConstPointer;
>
> +  /** Base inverse transform type. */
> +  typedef Transform< TScalarType, NOutputDimensions, NInputDimensions >
> +  InverseTransformType;
> +
> +  typedef SmartPointer< InverseTransformType > InverseTransformPointer;
> +
>   /** New method for creating an object using a factory. */
>   itkNewMacro(Self);
>
> @@ -221,6 +227,15 @@
>    */
>   bool GetInverse(Self * inverseTransform) const {return false;}
>
> +  /** Return an inverse of this transform. If the inverse has not been
> +   *  implemented, return NULL. The type of the inverse transform
> +   *  does not necessarily need to match the type of the forward
> +   *  transform. This allows one to return a numeric inverse transform
> +   *  instead.
> +   */
> +  virtual InverseTransformPointer GetInverse() const
> +  { return NULL; }
> +
>   /** Generate a platform independant name */
>   virtual std::string GetTransformTypeAsString() const;
>
> diff -uBbr InsightToolkit-3.8.0/Code/Common/itkTranslationTransform.h
> InsightToolkit-3.8.0-patched/Code/Common/itkTranslationTransform.h
> --- InsightToolkit-3.8.0/Code/Common/itkTranslationTransform.h  2007-07-15
> 10:38:25.000000000 -0600
> +++ InsightToolkit-3.8.0-patched/Code/Common/itkTranslationTransform.h
>  2008-08-31 08:56:40.298607372 -0600
> @@ -49,6 +49,10 @@
>   typedef SmartPointer<Self>        Pointer;
>   typedef SmartPointer<const Self>  ConstPointer;
>
> +  /** Base inverse transform type. */
> +  typedef typename Superclass::InverseTransformType InverseTransformType;
> +  typedef SmartPointer< InverseTransformType > InverseTransformPointer;
> +
>   /** New macro for creation of through the object factory.*/
>   itkNewMacro( Self );
>
> @@ -136,6 +140,13 @@
>    * false is returned.  */
>   bool GetInverse(Self* inverse) const;
>
> +  /** Return an inverse of this transform. */
> +  virtual InverseTransformPointer GetInverse() const
> +  {
> +    Pointer inv = New();
> +    return GetInverse(inv) ? inv.GetPointer() : NULL;
> +  }
> +
>   /** Compute the Jacobian Matrix of the transformation at one point */
>   virtual const JacobianType & GetJacobian(const InputPointType  &point )
> const;
>
>
> _______________________________________________
> Insight-developers mailing list
> Insight-developers at itk.org
> http://www.itk.org/mailman/listinfo/insight-developers
>
>



-- 
--------------------------------------------------------------
Rupert Brooks


More information about the Insight-developers mailing list