[Insight-users] use Euler2DTransform or Euler3DTransform in a template function: template<class ImageDimension> void TempFunc(...)

Luis Ibanez luis.ibanez at kitware.com
Thu Mar 25 12:04:42 EDT 2010


Hi Haiyong,


The typical solution to this problem is to use "Traits".


In your case, the traits could take the following form:

1) Write the generic form of the Trait:

class TransformTraits<unsigned int dimension>
{
public:
   typedef AffineTransform<dimension,double>  TransformType;
};

Don't worry about the fact that the default option is the
affine Transform, that one will not actually be instantiated
in your case.


2) Provide specialization for 2D

template <>
class TransformTraits<2>
{
public:
   typedef Euler2DTransform<double>  TransformType;
};


3) Provide specialization for 3D

template <>
class TransformTraits<3>
{
public:
   typedef Euler3DTransform<double>  TransformType;
};


4) Finally, use the Traits from your class:


class MyRegistration< class ImageType >
{
public:

  itkStaticConstMacro( ImageDimension,
     unsigned int, TInputImage::ImageDimension);

  typedef typename
     TransformTraits< ImageDimension >::TransformType  TransformType;

  typename TransformType::Pointer    myTransform;
...
  };


5)  Note that this will get you through the type
     instantiation issue.  You still have to delegate
     proper initialization of transform parameters
     for each transform.  This is something that
     you could also do with the Traits.  For example,
     you could add to the TransformTraits class a
     set of methods for initializing parameters as
     well as the optimizer scales that are so critical
     for image registration.



   Enjoy Generic Programming  !   :-)



      Regards,


           Luis



-------------------------------------------------------------------------
On Wed, Mar 24, 2010 at 8:53 AM, Haiyong Xu <haiyeong at gmail.com> wrote:
> Hi there,
>
> I'm writing a template function with ImageType as a template argument.
> The question is that how can I create a itk::Transform<> instance
> according to the image's dimension.
>
> Euler2DTransform and Euler3DTransform are concrete child classes of
> abstract class itk::Transform< TScalarType, NInputDimensions,
> NOutputDimensions>.
>
> An obvious way to do this is following:
>
> /*******************************
>
> other_itk_template_class; // this class takes ImgeType as template argument
>
> 1:   if (ImateType::ImageDimension == 2)
> 2:      other_itk_template_class->SetTransform(
> Euler2DTransform<double>::New() );
> 3:   else if (ImageDImension == 3)
> 4:      other_itk_template_class->SetTransform(
> Euler3DTransform<double>::New() );
>
> // this causes a compile error. Because after instantiation of
> other_itk_template_class, it only processes either 2D or 3D Image
> object, therefore the Transform object have to be either 2D or 3D. If
> we instantiate the other_itk_template_class with 2D image data, line 4
> causes compile error; if we instantiate the other_itk_template_class
> with 3D image data, line 2 causes compile error.
>
> ******************************/
>
> I tried to use "#define", but it does not work either:
>
> /***********************************
>
> #define NTransform(num, name)
> itk::Euler##num##DTransform<double>::Pointer  name
> NTransform(InputImage::ImageDimension, transform);
>
> **********************************/
>
> Appreciate any hints or helps.
>
> --Haiyong Xu
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>


More information about the Insight-users mailing list