[Insight-users] make compiler expand all ITK-enum cases for a template call

Bradley Lowekamp blowekamp at mail.nih.gov
Thu Aug 22 09:13:24 EDT 2013


Hello,

On Aug 22, 2013, at 6:27 AM, Dr. Roman Grothausmann <grothausmann.roman at mh-hannover.de> wrote:

> Dear mailing list members,
> 
> 
> Can I somehow avoid extending the two nested switch-statements (currently commented out) by a third?
> Since I use enumeration types (which are definitely finite) for the template argument I'd expect that the compiler should be able to resolve any possible case.
> 

Yes, you should avoid using nested switch statements. I'd suggest parsing your argument in the main function, then calling a Dispatch() method with no template arguments. This first method would determine the type and dimensions of the first image and pass those as template parameters to Dispatch_T1<>,  add more template parameters for Dispatch_T2 and repeat until you achieve your goal, your compiler runs out of memory or time. This way each dispatch method just has one straight forward switch statement.

Alternatively, you could also use the typeless C++ layer that SimpleITK provides.  You can do most of what you did below with just a few lines of SimpleITK API. Here is a basic example[1]. You can also get more advance and use SimpleITK's dispatch system to create a new SimpleITK level filter composed of ITK filters, the generated SimpleITK filter code should provide an idea of what would be involve.

Good luck,
Brad

[1] http://www.itk.org/SimpleITKDoxygen/html/SimpleGaussian_8cxx-example.html


> Any help or hints are very much appreciated
> Roman
> 
> 
> 
> _________________________________________
> 
> 
> 
> //program to mask an image with another one (can mask float images, i.e. is not bound to the C++ AND requirement)
> //runs multithreaded
> //02: multi dim, multi type
> //03: multi dim, multi type for different input types //not working yet...
> 
> 
> #include <itkImageFileReader.h>
> #include <itkImageFileWriter.h>
> 
> #include <itkMaskImageFilter.h>
> #include "itkFilterWatcher5.h"
> 
> 
> template<typename InputPixelType1, typename InputPixelType2, size_t Dimension>
> //template<itk::ImageIOBase::IOComponentType InputPixelType1, itk::ImageIOBase::IOComponentType InputPixelType2, size_t Dimension>
> int DoIt(int argc, char *argv[]){
> 
>    typedef InputPixelType1  OutputPixelType;
> 
>    typedef itk::Image<InputPixelType1, Dimension>  InputImageType1;
>    typedef itk::Image<InputPixelType2, Dimension>  InputImageType2;
>    typedef itk::Image<OutputPixelType, Dimension>  OutputImageType;
> 
>    typedef itk::ImageFileReader<InputImageType1> ReaderType1;
>    typename ReaderType1::Pointer reader1 = ReaderType1::New();
> 
>    reader1->SetFileName(argv[1]);
>    FilterWatcher watcherI1(reader1);
>    try
>        {
>        reader1->Update();
>        }
>    catch (itk::ExceptionObject &ex)
>        {
> 	if (!strcmp(ex.GetDescription(), "Filter does not have progress.")){
>            std::cerr << ex << std::endl;
>            //std::cerr << ex.GetDescription() << std::endl;
>            return EXIT_FAILURE;
>            }
>        }
> 
> 
>    typedef itk::ImageFileReader<InputImageType2> ReaderType2;
>    typename ReaderType2::Pointer reader2 = ReaderType2::New();
> 
>    reader2->SetFileName(argv[2]);
>    FilterWatcher watcherI2(reader2);
>    try
>        {
>        reader2->Update();
>        }
>    catch (itk::ExceptionObject &ex)
>        {
> 	if (!strcmp(ex.GetDescription(), "Filter does not have progress.")){
>            std::cerr << ex << std::endl;
>            //std::cerr << ex.GetDescription() << std::endl;
>            return EXIT_FAILURE;
>            }
>        }
> 
> 
> 
>    typedef itk::MaskImageFilter<InputImageType1, InputImageType2, OutputImageType> MFilterType;
>    typename MFilterType::Pointer mask = MFilterType::New();
> 
>    mask->SetInput(reader1->GetOutput()); //mask->SetInput1(filter->GetOutput());
>    mask->SetMaskImage(reader2->GetOutput()); //mask->SetInput2(reader2->GetOutput());
> 
>    FilterWatcher watcher1(mask);
>    try {
>        mask->Update();
>        //std::cout << std::endl;
>        }
>    catch (itk::ExceptionObject &ex)
>        {
>        std::cout << ex << std::endl;
>        return EXIT_FAILURE;
>        }
> 
> 
>    typedef itk::ImageFileWriter<OutputImageType>  WriterType;
>    typename WriterType::Pointer writer = WriterType::New();
> 
>    FilterWatcher watcherO(writer);
>    writer->SetFileName(argv[3]);
>    writer->SetInput(mask->GetOutput());
>    writer->UseCompressionOn();
>    //writer->SetUseCompression(atoi(argv[3]));
>    try
>        {
>        writer->Update();
>        }
>    catch (itk::ExceptionObject &ex)
>        {
>        std::cout << ex << std::endl;
>        return EXIT_FAILURE;
>        }
> 
> 
> 
> 
>    return EXIT_SUCCESS;
> 
>    }
> 
> 
> ////from http://itk-users.7.n7.nabble.com/Pad-image-with-0-but-keep-its-type-what-ever-it-is-td27442.html
> //namespace itk{
>  // Description:
>  // Get the PixelType and ComponentType from fileName
> 
> void GetImageType (std::string fileName,
>    itk::ImageIOBase::IOPixelType &pixelType,
>    itk::ImageIOBase::IOComponentType &componentType,
>    size_t &dimensionType
>    //ImageIOBase::IODimensionType &dimensionType
>    ){
>    typedef itk::Image<unsigned char, 3> ImageType;
>    itk::ImageFileReader<ImageType>::Pointer imageReader= itk::ImageFileReader<ImageType>::New();
>    imageReader->SetFileName(fileName.c_str());
>    imageReader->UpdateOutputInformation();
> 
>    pixelType = imageReader->GetImageIO()->GetPixelType();
>    componentType = imageReader->GetImageIO()->GetComponentType();
>    dimensionType= imageReader->GetImageIO()->GetNumberOfDimensions();
> 
>    //std::cout << "Pixel Type is " << imageReader->GetImageIO()->GetComponentTypeAsString(pixelType) << std::endl;
>    std::cout << "Pixel Type is " << imageReader->GetImageIO()->GetComponentTypeAsString(componentType) << std::endl;
>    std::cout << "numDimensions: " << dimensionType << std::endl;
>    std::cout << "component size: " << imageReader->GetImageIO()->GetComponentSize() << std::endl;
>    std::cout << "pixel type (string): " << imageReader->GetImageIO()->GetPixelTypeAsString(imageReader->GetImageIO()->GetPixelType()) << std::endl;
>    std::cout << "pixel type: " << pixelType << std::endl;
> 
>    }
> 
> 
> 
> int main(int argc, char *argv[]){
>    if ( argc != 4 )
> 	{
> 	std::cerr << "Missing Parameters: "
> 		  << argv[0]
> 		  << " Input_Image"
> 		  << " Mask_Image"
> 		  << " Output_Image"
>    		  << std::endl;
> 
> 	return EXIT_FAILURE;
> 	}
> 
>    std::string ifn = argv[1];
> 
>    itk::ImageIOBase::IOPixelType pixelType1;
>    typename itk::ImageIOBase::IOComponentType componentType1;
>    //itk::ImageIOBase::IOComponentType componentType1;
>    //itk::ImageIOBase::IODimensionType dimensionType1;
>    size_t dimensionType1;
> 
>    itk::ImageIOBase::IOPixelType pixelType2;
>    typename itk::ImageIOBase::IOComponentType componentType2;
>    //itk::ImageIOBase::IOComponentType componentType2;
>    //itk::ImageIOBase::IODimensionType dimensionType2;
>    size_t dimensionType2;
> 
>    try
>        {
>        GetImageType(argv[1],
> 		     pixelType1,
> 		     componentType1,
> 		     dimensionType1);
>        GetImageType(argv[2], pixelType2, componentType2, dimensionType2);
> 
> 	if ((componentType1==itk::ImageIOBase::UNKNOWNCOMPONENTTYPE) || (componentType2==itk::ImageIOBase::UNKNOWNCOMPONENTTYPE)){
> 	  std::cout << "unknown component type" << std::endl;
> 	  return EXIT_FAILURE;
> 	}
> 	else{
> 	  switch (dimensionType1){
> 	  case 2:
> 	    DoIt<componentType1, componentType2, 2>(argc, argv);
> 	    break;
> 	  case 3:
> 	    DoIt<componentType1, componentType2, 3>(argc, argv);
> 	    break;
> 	  default:
> 	    std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
> 	    break;
> 	  }
> 	}//else
> 
>        // switch (componentType)
>        //     {
>        //     case itk::ImageIOBase::UCHAR:{
>        //         typedef unsigned char InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1: //this case does not work for BinaryShapeOpeningImageFilter
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
>        //         break;
>        //         }
>        //     case itk::ImageIOBase::CHAR:{
>        //         typedef char InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1:
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
>        //         break;
>        //         }
>        //     case itk::ImageIOBase::USHORT:{
>        //         typedef unsigned short InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1:
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
> 
>        //         break;
>        //         }
>        //     case itk::ImageIOBase::SHORT:{
>        //         typedef short InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1:
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
> 
>        //         break;
>        //         }
>        //     case itk::ImageIOBase::UINT:{
>        //         typedef unsigned int InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1:
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
> 
>        //         break;
>        //         }
>        //     case itk::ImageIOBase::INT:{
>        //         typedef int InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1:
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
> 
>        //         break;
>        //         }
>        //     case itk::ImageIOBase::ULONG:{
>        //         typedef unsigned long InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1:
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
> 
>        //         break;
>        //         }
>        //     case itk::ImageIOBase::LONG:{
>        //         typedef long InputPixelType;
>        //         switch (dimensionType){
>        //             // case 1:
>        //             //     DoIt<InputPixelType, 1>(argc, argv);
>        //             //     break;
>        //         case 2:
>        //             DoIt<InputPixelType, 2>(argc, argv);
>        //             break;
>        //         case 3:
>        //             DoIt<InputPixelType, 3>(argc, argv);
>        //             break;
>        //         default:
>        //             std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //             break;
>        //             }
> 
>        //         break;
>        //         }
>        //         case itk::ImageIOBase::FLOAT:{
>        //             typedef float InputPixelType;
>        //             switch (dimensionType){
>        //             case 1:
>        //                 DoIt<InputPixelType, 1>(argc, argv);
>        //                 break;
>        //             case 2:
>        //                 DoIt<InputPixelType, 2>(argc, argv);
>        //                 break;
>        //             case 3:
>        //                 DoIt<InputPixelType, 3>(argc, argv);
>        //                 break;
>        //             default:
>        //                 std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //                 break;
>        //                 }
> 
>        //             break;
>        //             }
>        //         case itk::ImageIOBase::DOUBLE:{
>        //             typedef double InputPixelType;
>        //             switch (dimensionType){
>        //             case 1:
>        //                 DoIt<InputPixelType, 1>(argc, argv);
>        //                 break;
>        //             case 2:
>        //                 DoIt<InputPixelType, 2>(argc, argv);
>        //                 break;
>        //             case 3:
>        //                 DoIt<InputPixelType, 3>(argc, argv);
>        //                 break;
>        //             default:
>        //                 std::cout << "Images of dimension " << dimensionType << " are not supported!" << std::endl;
>        //                 break;
>        //                 }
> 
>        //             break;
>        //             }
>        //     case itk::ImageIOBase::UNKNOWNCOMPONENTTYPE:
>        //     default:
>        //         std::cout << "unknown component type" << std::endl;
>        //         break;
>        //     }
> 
> 
>        }//try
>    catch( itk::ExceptionObject &excep)
>        {
>        std::cerr << argv[0] << ": exception caught !" << std::endl;
>        std::cerr << excep << std::endl;
>        return EXIT_FAILURE;
>        }
> 
>    return EXIT_SUCCESS;
>    }
> 
> 
> 
> -- 
> Dr. Roman Grothausmann
> 
> Tomographie und Digitale Bildverarbeitung
> Tomography and Digital Image Analysis
> 
> Institut für Funktionelle und Angewandte Anatomie, OE 4120
> Medizinische Hochschule Hannover
> Carl-Neuberg-Str. 1
> D-30625 Hannover
> 
> Tel. +49 511 532-9574
> _____________________________________
> 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.php
> 
> 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