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

Dr. Roman Grothausmann grothausmann.roman at mh-hannover.de
Thu Aug 22 06:27:33 EDT 2013


Dear mailing list members,


With the help of Bill Lorensen mailing list instructions, I managed to create a 
small code construct that allows to call ITK-filters without having to restrict 
the program to operate on a specific image dimension or type.
Now I've come across itkMaskImageFilter which needs two input images which have 
to have the same dim and size but not necessarily the same type. While I tried 
to extend my code construct I noticed that doing it as suggested by Bill I'd end 
up with three nested long switch-statements.
Is there any way to avoid switch statements for all allowed dimensions, types 
and such and instead just to prevent execution for specific cases i.e. for 
filters that do not work on 1D images or floating point types?
My current approach below (only disallowing UNKNOWNCOMPONENTTYPE) does not 
compile with the message:

error: ?componentType1? cannot appear in a constant-expression
/net/home/grothama/itk/simple/mask_03.cxx:182:27: error: ?componentType2? cannot 
appear in a constant-expression
/net/home/grothama/itk/simple/mask_03.cxx:182:56: error: no matching function 
for call to ?DoIt(int&, char**&)?
/net/home/grothama/itk/simple/mask_03.cxx:182:56: note: candidate is:
/net/home/grothama/itk/simple/mask_03.cxx:16:5: note: template<class 
InputPixelType1, class InputPixelType2, long unsigned int Dimension> int 
DoIt(int, char**)
/net/home/grothama/itk/simple/mask_03.cxx:16:5: note:   template argument 
deduction/substitution failed:
/net/home/grothama/itk/simple/mask_03.cxx:182:56: error: template argument 1 is 
invalid
/net/home/grothama/itk/simple/mask_03.cxx:182:56: error: template argument 2 is 
invalid

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.

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


More information about the Insight-users mailing list