[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