[Insight-users] use of transform with itk volume

Luis Ibanez luis.ibanez@kitware.com
Wed, 27 Nov 2002 10:40:18 -0500


Hi Jorn,


The itk::Image contains a generic itkTransform.

The itkTransform is the base class of all transform
http://public.kitware.com/Insight/Doxygen/html/classitk_1_1Transform.html
(including of course the Affine transform).
http://public.kitware.com/Insight/Doxygen/html/classitk_1_1AffineTransform.html

The pointer to transform in the image is initialized
to an AffineTransform containing the spacing and origin of
the image but the pointer itself is still to itkTransform.

The GetIndexToPhysicalTransform() returns a pointer to the
generic itkTransform class.

Not all transforms are invertible, so the itkTransfrom can not
have a GetInverse() in the API (unless we want to go with something
like defining the method and throw exceptions when it is called
in non-invertible transforms...but considering that ITK is targeted
for medical applications we better solve all what we can at compile
time, since run-time for itk can end up being surgery-room time).

So, the call

     GetIndexToPhysicalTransform()->GetInverse()

is not a valid one.

You can easily get around with a dynamic_cast<> line like

typedef itk::AffineTransform<double,3> AffineType;
typedef itk::Transform<double,3,3> TransformType;

TransformType::Pointer transform = pInItk->GetOutput()->
                         GetIndexToPhysicalTransform();

AffineType::Pointer affine =
   dynamic_cast< AffineType *>( transform->GetPointer() );


pInItk->GetOutput()->SetIndexToPhysicalTransform(
    affine->GetInverse() );


Note that a dynamic_cast<> will anyways throw an exception
if the conversion is not valid. That is, if the actual
type of transform stored in the image is not an affine
transform or one of its derived classes.

The dynamic_cast must be placed inside a try/catch block
and your application will have to decide what to do in
the case the conversion is not valid...




About your second question:

The registration methods will only use the space an origin
in your image. Not the full transform. This is a performance
concern.  A similar question was raised recently on the list.
The place where the full transform is not supported is the
ImageFunctions/ImageInterpolators.

The difficulty here is to find a way of offering flexibility
for arbitrary transforms but yet reasonable efficiency.

If we manage arbitrary transforms in the ImageMetrics and
ImageInterpolators on the RegistrationFramework this will
cost additional virtual calls and smart pointer indirections
per pixels access.

I we have followed a full generic programming approach and
solved the metric type at compile time, this could have been
avoided but then you will not have the choice to select the
transform type at run time.

A possible solution could be to make this a compile option,
so only users interested in taking advantage of transform
flexibility will have to pay for the performance price
involved.


Please let us know if you have further questions,

Thanks


Luis



-===============================



This transform is initialized

J. Van Dalen wrote:

> Hi,
> 
> I have two itk questions that hopefully one of you can answer...
> 
> I try to make a registration using mutual information. Therefore, I want
> to make use of some initial transformations given in a vol-file.
> I start with vtk, read the dicom files and the initial transforms, for
> two images. Then, via a pipeline construction, I arrive at an itk volume.
> I try to connect the transform to the itk volume by using the following
> code:
>   
> spInItk->GetOutput()->GetIndexToPhysicalTransform()->SetParameters(quat);  
> 
> spInItk->GetOutput()->SetIndexToPhysicalTransform(spInItk->GetOutput()->
> GetIndexToPhysicalTransform()->GetInverse());
> 
> where spInItk is of type ImageImportType and quat is an array that
> contains the initial transformation.  
> 
> Now, my questions are: 
> * The second line gives an error: no matching function for call to
>   `itk::Transform<double, 3, 3>::GetInverse ()' 
>   I do not understand this error since spInItk->GetOutput()->
>   GetIndexToPhysicalTransform() is an AffineTransform (I see this when
>   I use the command: spInItk->GetOutput()->Print(cout);), and according
>   to the documentation, an inverse of an AffineTransform is defined.
> * When I have initial tranforms connected to the itk volumes that
>   I want to fuse (as I show above), will these transforms be used
>   when I call the ImageRegistrationMethod? 
> 
> Hope you can help me,
> Thanks,
> Jorn.
> 
> _______________________________________________
> Insight-users mailing list
> Insight-users@public.kitware.com
> http://public.kitware.com/mailman/listinfo/insight-users
> 
>