[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