[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