[ITK] templating typdef question

Dr Bernhard Schaffer bschaffer at superstem.org
Thu Oct 30 03:43:51 EDT 2014


Thanks for the fast reply. I'll give it a try and let you know if I hit any obstacles.  
(The next time I can spend some time on ITK coding - it comes in waves as it's a spare time project).

A general question for this community though:

I've emailed to "community at itk.org" a couple of weeks ago and didn't receive any answer (I don't mind too much, I just don't want to do it incorrectly). 
This time I've written to community at itk.org and to insight-users at itk.org separately. Which one is the preferred group to ask these questions?

Further, do you generally prefer getting coding questions on this mailing list, or on more general sites like Stackoverflow.com?

And finally (after listening in to this group for 3 weeks or so): Thank you Matt for being so responsive! I know from experience that keeping responsive in such a site is a lot of effort. Very much appreciated.

Regards,
   Bernhard


-----Original Message-----
From: Matt McCormick [mailto:matt.mccormick at kitware.com] 
Sent: 29 October 2014 22:28
To: Dr Bernhard Schaffer
Cc: community at itk.org
Subject: Re: [ITK] templating typdef question

Hi Bernhard,

Welcome to ITK!

The basic strategy is to put all the templated code in a template function or class.  This prevents duplicated code (the root of almost all evil).  Then, use a switch statement and call the appropriate templates.  An example is here [1], which is long because it switches over both a number of pixel types and dimensions, but it demonstrates the idea.

Inside the templated code, use for loops instead explicit assignment to set each dimension value.  Also, use code like

  Image::SpacingType spacing;
  spacing.Fill( 1.0 );

instead of

  itk::SpacePrecisionType spacing[2];
  spacing[0] = 1.0;
  spacing[1] = 1.0;

Hope this helps,
Matt


[1] http://itk.org/ITKExamples/src/IO/ImageBase/ReadUnknownImageType/Documentation.html

On Wed, Oct 29, 2014 at 5:03 PM, Dr Bernhard Schaffer <bschaffer at superstem.org> wrote:
> Hi,
>
> This is my second email to this list. I’m still not so familiar with 
> typedefs in coding, and I’ve the current problem:
>
>
>
> I have my own “image” objects which can be 2D or 3D and of different 
> number type.  If I assume they are only 2D and float I can do something like this:
>
> (The cyan lines show methods of  ‘my’ object.)
>
>
>
>
>
> const unsigned int DIMENSION = 2;
>
>
>
>           typedef itk::ImportImageFilter<float, DIMENSION > 
> ImportFilterType;
>
> ImportFilterType::Pointer importFilter = ImportFilterType::New();
>
>
>
> ImportFilterType::SizeType  size;
>
>           size[0]  = MYIMAGE.GetXSIZE();
>
> size[1]  = MYIMAGE.GetYSIZE();
>
>
>
>           ImportFilterType::IndexType start;
>
>           start.Fill( 0 );
>
>
>
>           ImportFilterType::RegionType region;
>
>           region.SetIndex( start );
>
>           region.SetSize(  size  );
>
> importFilter->SetRegion( region );
>
>
>
> const itk::SpacePrecisionType origin[ DIMENSION ] = { 0.0, 0.0 };
>
>           importFilter->SetOrigin( origin );
>
>
>
>           const itk::SpacePrecisionType  spacing[ DIMENSION ] =  { 
> 1.0, 1.0 };
>
> importFilter->SetSpacing( spacing );
>
>
>
>           const bool importImageFilterWillOwnTheBuffer = false;
>
>
>
>           float *localBuffer = MYIMAGE.GETPOINTER();
>
>           importFilter->SetImportPointer( localBuffer, 
> size[0]*size[1], importImageFilterWillOwnTheBuffer );
>
>
>
>           typedef itk::Image< float,DIMENSION >   InputImageType;
>
>           typedef itk::Image< float,DIMENSION >   OutputImageType;
>
>
>
>           typedef itk::CurvatureFlowImageFilter< InputImageType, 
> OutputImageType >  FilterType;
>
>           FilterType::Pointer filter = FilterType::New();
>
>
>
>           filter->SetInput( importFilter->GetOutput() );
>
>           filter->SetTimeStep( timeStep );
>
>           filter->SetNumberOfIterations( iterations );
>
>           filter->Update();
>
>           typedef itk::ImageRegionIterator< OutputImageType > 
> IteratorType;
>
>           OutputImageType::Pointer filtered = filter->GetOutput();
>
>           […]
>
>
>
> If my image is 3D I can do accordingly: (Yellow is the difference to 
> above)
>
>
>
> const unsigned int DIMENSION = 3;
>
>
>
>           typedef itk::ImportImageFilter<float, DIMENSION > 
> ImportFilterType;
>
> ImportFilterType::Pointer importFilter = ImportFilterType::New();
>
>
>
> ImportFilterType::SizeType  size;
>
>           size[0]  = MYIMAGE.GetXSIZE();
>
> size[1]  = MYIMAGE.GetYSIZE();
>
> size[2]  = MYIMAGE.GetZSIZE();
>
>
>
>
>
>           ImportFilterType::IndexType start;
>
>           start.Fill( 0 );
>
>
>
>           ImportFilterType::RegionType region;
>
>           region.SetIndex( start );
>
>           region.SetSize(  size  );
>
> importFilter->SetRegion( region );
>
>
>
> const itk::SpacePrecisionType origin[ DIMENSION ] = { 0.0, 0.0, 0.0 };
>
>           importFilter->SetOrigin( origin );
>
>
>
>           const itk::SpacePrecisionType  spacing[ DIMENSION ] =  { 
> 1.0, 1.0,
> 1.0 };
>
> importFilter->SetSpacing( spacing );
>
>
>
>           const bool importImageFilterWillOwnTheBuffer = false;
>
> float *localBuffer = MYIMAGE.GETPOINTER();
>
>           importFilter->SetImportPointer( localBuffer, 
> size[0]*size[1]*size[2], importImageFilterWillOwnTheBuffer );
>
>
>
>           typedef itk::Image< float,DIMENSION >   InputImageType;
>
>           typedef itk::Image< float,DIMENSION >   OutputImageType;
>
>
>
>           typedef itk::CurvatureFlowImageFilter< InputImageType, 
> OutputImageType >  FilterType;
>
>           FilterType::Pointer filter = FilterType::New();
>
>
>
>           filter->SetInput( importFilter->GetOutput() );
>
>           filter->SetTimeStep( timeStep );
>
>           filter->SetNumberOfIterations( iterations );
>
>           filter->Update();
>
>           typedef itk::ImageRegionIterator< OutputImageType > 
> IteratorType;
>
>           OutputImageType::Pointer filtered = filter->GetOutput();
>
>           […]
>
>
>
> The problem I have is the following. I can query my object about its 
> dimensionality, but I can’t do the following:
>
>
>
> const unsigned int DIMENSION = MYIMAGE.GETDIMENSIONALITY();
>
>
>
> because the typedefs are evaluated on compilation not on runtime.   So my
> way around this is, to actually duplicate  all the code and have both 
> my examples in a switch-case:
>
>
>
>           switch(MYIMAGE.GETDIMENSIONALITY())
>
>           {
>
>           case(2):
>
>                     {
>
> … EXAMPLE 2D as above
>
> }
>
>                    break;
>
>           case(3):
>
>                     {
>
> … EXAMPLE 3D as above
>
> }
>
>                    break;
>
> }
>
>
>
> Which is rather obvious code duplication. Is there a better way to do this?
> (there has to!)  The problem branches out, if I also allow the type 
> float to be specified by my object as in
>
>           switch(MYIMAGE.GETDATATYPE())
>
>           {
>
>           case(1):…float…;
>
>           case(2):…double…;
>
>           case(3):…
>
>>
> }
>
>
>
>
>
> I would very much appreciate a few lines of (pseudo-) code showing me 
> how I can do this better.
>
>
>
> Thank you very much,
>
>    Best regards,
>
>    Bernhard
>
>
>
>
> _______________________________________________
> Community mailing list
> Community at itk.org
> http://public.kitware.com/mailman/listinfo/community
>



More information about the Community mailing list