Named inputs in FunctorImageFilter
This MR is an addition to the main MR !268 (closed) which is the target branch.
It introduces a new intermediate filter called VariadicNamedInputsImageFilter
which allows to statically name inputs of the filter, in the following manner:
// Test VariadicNamedInputsImageFilter
struct xs {}; // tag for xs input
struct pan {}; // tag for pan input
using Names = std::tuple<xs,pan>; // input mapping type
auto filterWithNames = otb::VariadicNamedInputsImageFilter<VectorImageType, Names, VectorImageType,ImageType>::New();
filterWithNames->SetVNamedInput<xs>(vimage);
filterWithNames->SetVNamedInput<pan>(image);
std::cout<<filterWithNames->GetVNamedInput<xs>()<< filterWithNames->GetVNamedInput<pan>()<<std::endl;
FunctorImageFilter
now has a second template parameter defaulted to void
, to hold this mapping. If the parameter value is void, superclass is VariadicInputsImageFilter
, and behavior is the same as in !268 (closed). Otherwise it is VariadicNamedInputsImageFilter
and the parameter is used to enable the SetVNamedInput<>()
setters.
Why all this ? One issue we ran into when actually trying to refactor old otb code with the new FunctorImageFilter
is that most functor usage in OTB imply the definition of a new Filter class, which is doing:
- Setting the number of output bands (now covered by
FunctorImageFilter
) - Passing parameters to the functor (can be easily replaced by
filter->GetFunctor().SetAlpha()
). - Exposing meaningful name for input setters: for instance
SetInput1()
->SetInputMask()
The latter is important, because otherwise you are left with guessing what is the order of inputs (which is derived from the functor).
Now, with the proposed named inputs interface, one could remove completely the definition of the class, and simply doing (example from the polarimetry module):
namespace polarimetry_tags
{
struct hh {};
struct hv {};
struct vh {};
struct vv {};
}
// This is the entire declaration of SinclairToCovarianceMatrixFilter
template <typename TInputImage, typename TOutputImage> SinclairToCovarianceMatrixFilter
= FunctorImageFilter< Functor::SinclairToCovarianceMatrixFunctor <typename TInputImage::PixelType,
typename TOutputImage::PixelType> ,
std::tuple<polarimetry_tags::hh,
polarimetry_tags::hv,
polarimetry_tags::vh,
polarimetry_tags::vv> >;
// This is how to use it
using namespace polarimetry_tags;
auto filter = SinclairToCovarianceMatrixFilter<InputImageType,OutputImageType>::New();
filter->SetVNamedInput<hh>(in1);
filter->SetVNamedInput<hv>(in2);
// ... Of course previous SetVinput<0>() SetVInput<1>() or even SetVInputs(in1,in2,in3,in4) still work
This would save a lot of code and be a real helper to refactor some Modules (for instance the radiometric indices).
The code is compiling and working, but I would like to get some feedback on this idea, hence the MR.