I'm currently working on an image processing application, mainly based on C++ and ITK.
1. The Situation
I have node classes (e.g. FlipFilter
) derived from the same base class. A node gets a struct with an image_ptr
and all of the meta-information (dimension of the Image
, PixelType
(e.g. RGB, RGBA, scalar) and ComponentType
(e.g. Float, int). The node has to instantiate an ITK-Filter
, based on these Meta-Informations
, which can change on every input-image.
2. The Problem
These ITK-Filters
need the ImageType
(e.g. RGB with ComponentType UCHAR
) as a template argument. A template class has to be instantiated at compile-time. My node is getting the image with its type at runtime. So I somehow have to create all permutations of the filter for each node and then use the appropriate instantiation.
3. My current Solution
This struct contains all the meta-information + a smart-pointer pointing towards the actual image. I'm using a base pointer of the image because the image itself is also a template (later I'm downcasting).
struct ImageData
{
short NumberOfDimensions;
itk::ImageIOBase::IOComponentType ComponentType;
itk::ImageIOBase::IOPixelType PixelType;
itk::DataObject::Pointer Image;
ImageData() {}
~ImageData() {}
};
This is the update function of my node. It is supposed to create the filter an execute it on an image.
void LitkFlipImageFilter::update()
{
if (Input1 == nullptr)
throw(std::runtime_error("Input1 not set"));
Input1->update();
ImageData Input1Data = Input1->getOutput();
switch (Input1Data.PixelType)
{
default:
{
throw std::runtime_error("Type not Supported");
break;
}
case itk::ImageIOBase::RGB:
{
switch (Input1Data.ComponentType)
{
default:
{
throw std::runtime_error("Type not Supported");
break;
}
case itk::ImageIOBase::IOComponentType::UCHAR:
{
using PixelType = itk::RGBPixel< unsigned char >;
using ImageType = itk::Image < PixelType, 2 >;
itk::FlipImageFilter<ImageType>::Pointer filter = itk::FlipImageFilter<ImageType>::New();
//do stuff
break;
}
break;
}
}
}
}
4. The Problem with my Solution
It's working but creates a lot of repetitive code and large nested switch cases. Do you know a more elegant way of solving this problem?
Thank you!