Commit d8dffd44 authored by Julien Michel's avatar Julien Michel

ENH: Rename (VInput -> VariadicInput) and add more checks

parent db803d3c
......@@ -83,7 +83,7 @@ template <class T> struct IsSuitableType<itk::VariableLengthVector<T>> {
};
/// Unwrap FixedArray
template <class T> struct IsSuitableType<itk::FixedArray<T>> {
template <class T, size_t N> struct IsSuitableType<itk::FixedArray<T,N>> {
static constexpr bool value = IsSuitableType<T>::value;
};
......@@ -218,7 +218,7 @@ template <typename C, typename R, typename... T> struct FunctorFilterSuperclassH
* - returns T or itk::VariableLengthVector<T>, with T a scalar type
*
* The returned filter is ready to use. Inputs can be set through the
* SetVInputs() method (see VariadicInputsImageFilter class for
* SetVariadicInputs() method (see VariadicInputsImageFilter class for
* details)
*
* \param f the Functor to build the filter from
......
......@@ -196,7 +196,7 @@ FunctorImageFilter<TFunction>
// Propagate to each variadic inputs, including possible radius
// TODO: For now all inputs are padded with the radius, even if they
// are not neighborhood based
functor_filter_details::SetInputRequestedRegions(this->GetVInputs(),requestedRegion, m_Radius);
functor_filter_details::SetInputRequestedRegions(this->GetVariadicInputs(),requestedRegion, m_Radius);
}
template <class TFunction>
......@@ -207,7 +207,7 @@ FunctorImageFilter<TFunction>::GenerateOutputInformation()
Superclass::GenerateOutputInformation();
// Get All variadic inputs
auto inputs = this->GetVInputs();
auto inputs = this->GetVariadicInputs();
// Retrieve an array of number of components per input
auto inputNbComps = functor_filter_details::GetNumberOfComponentsPerInput(inputs);
......@@ -228,7 +228,7 @@ FunctorImageFilter<TFunction>
itk::ImageScanlineIterator<OutputImageType> outIt(this->GetOutput(),outputRegionForThread);
itk::ProgressReporter p(this,threadId,outputRegionForThread.GetNumberOfPixels());
auto inputIterators = functor_filter_details::MakeIterators(this->GetVInputs(),outputRegionForThread, m_Radius,InputHasNeighborhood{});
auto inputIterators = functor_filter_details::MakeIterators(this->GetVariadicInputs(),outputRegionForThread, m_Radius,InputHasNeighborhood{});
while(!outIt.IsAtEnd())
{
......
......@@ -42,7 +42,7 @@ public:
itkNewMacro(Self);
template <std::size_t I> void SetVInput(const typename std::tuple_element<I,InputTypesTupleType>::type * inputPtr)
template <std::size_t I> void SetVariadicInput(const typename std::tuple_element<I,InputTypesTupleType>::type * inputPtr)
{
this->SetNthInput(I,const_cast<typename std::tuple_element<I,InputTypesTupleType>::type *>(inputPtr));
}
......@@ -51,7 +51,7 @@ public:
template<typename Tuple = InputTypesTupleType, typename Check = typename std::enable_if<n<=std::tuple_size<Tuple>::value >::type> \
void SetInput ## n(const typename std::tuple_element<n-1,Tuple>::type * img) \
{ \
this->template SetVInput<n-1>(img); \
this->template SetVariadicInput<n-1>(img); \
}
// The following defines legacy setters SetInput1()
......@@ -69,19 +69,19 @@ public:
#undef DefineLegacySetInputMacro
template <std::size_t I> const typename std::tuple_element<I,InputTypesTupleType>::type * GetVInput()
template <std::size_t I> const typename std::tuple_element<I,InputTypesTupleType>::type * GetVariadicInput()
{
using ImageType = typename std::tuple_element<I,InputTypesTupleType>::type;
return dynamic_cast<const ImageType *>(this->GetInput(I));
}
void SetVInputs(TInputs*... inputs)
void SetVariadicInputs(TInputs*... inputs)
{
auto inTuple = std::make_tuple(inputs...);
SetInputsImpl(inTuple,std::make_index_sequence<sizeof...(inputs)>{});
}
auto GetVInputs()
auto GetVariadicInputs()
{
return GetInputsImpl(std::make_index_sequence<sizeof...(TInputs)>{});
}
......@@ -97,12 +97,12 @@ protected:
private:
template<class Tuple, size_t...Is> auto SetInputsImpl(Tuple& t, std::index_sequence<Is...>)
{
return std::initializer_list<int>{(this->SetVInput<Is>(std::get<Is>(t)),0)...};
return std::initializer_list<int>{(this->SetVariadicInput<Is>(std::get<Is>(t)),0)...};
}
template <size_t...Is> auto GetInputsImpl(std::index_sequence<Is...>)
{
return std::make_tuple(this->GetVInput<Is>()...);
return std::make_tuple(this->GetVariadicInput<Is>()...);
}
VariadicInputsImageFilter(const Self&) = delete;
......
......@@ -39,25 +39,37 @@ template <typename T> struct TypesCheck
using ScalarType = T;
using ImageType = otb::Image<T>;
using VectorType = itk::VariableLengthVector<ScalarType>;
using FixedArrayType = itk::FixedArray<ScalarType,4>;
using RGBPixelType = itk::RGBPixel<ScalarType>;
using RGBAPixelType = itk::RGBAPixel<ScalarType>;
using VectorImageType = otb::VectorImage<ScalarType>;
using NeighborhoodType = itk::Neighborhood<ScalarType>;
using VectorNeighborhoodType = itk::Neighborhood<VectorType>;
// Test IsNeighborhood struct
static_assert(!otb::IsNeighborhood<ScalarType>::value,"");
static_assert(!otb::IsNeighborhood<VectorType>::value,"");
static_assert(otb::IsNeighborhood<NeighborhoodType>::value,"");
static_assert(otb::IsNeighborhood<VectorNeighborhoodType>::value,"");
static_assert(otb::IsNeighborhood<const NeighborhoodType &>::value,"");
static_assert(otb::IsNeighborhood<const VectorNeighborhoodType &>::value,"");
template <typename U> struct CheckIsNeighborhood
{
static constexpr bool value = !otb::IsNeighborhood<U>::value && otb::IsNeighborhood<itk::Neighborhood<U> >::value;
};
static_assert(CheckIsNeighborhood<T>::value,"");
static_assert(CheckIsNeighborhood<itk::VariableLengthVector<T>>::value,"");
static_assert(CheckIsNeighborhood<itk::FixedArray<T,4>>::value,"");
static_assert(CheckIsNeighborhood<itk::RGBPixel<T>>::value,"");
static_assert(CheckIsNeighborhood<itk::RGBAPixel<T>>::value,"");
// Test PixelTypeDeduction struct
static_assert(std::is_same<typename PixelTypeDeduction<ScalarType>::PixelType,ScalarType>::value,"");
static_assert(std::is_same<typename PixelTypeDeduction<VectorType>::PixelType,VectorType>::value,"");
static_assert(std::is_same<typename PixelTypeDeduction<NeighborhoodType>::PixelType,ScalarType>::value,"");
static_assert(std::is_same<typename PixelTypeDeduction<VectorNeighborhoodType>::PixelType,VectorType>::value,"");
static_assert(std::is_same<typename PixelTypeDeduction<const NeighborhoodType &>::PixelType,ScalarType>::value,"");
static_assert(std::is_same<typename PixelTypeDeduction<const VectorNeighborhoodType &>::PixelType,VectorType>::value,"");
template<typename U> struct CheckPixelTypeDeduction
{
static constexpr bool value = std::is_same<typename PixelTypeDeduction<U>::PixelType,U>::value
&& std::is_same<typename PixelTypeDeduction<itk::Neighborhood<U>>::PixelType,U>::value;
};
static_assert(CheckPixelTypeDeduction<T>::value,"");
static_assert(CheckPixelTypeDeduction<itk::VariableLengthVector<T>>::value,"");
static_assert(CheckPixelTypeDeduction<itk::FixedArray<T,4>>::value,"");
static_assert(CheckPixelTypeDeduction<itk::RGBPixel<T>>::value,"");
static_assert(CheckPixelTypeDeduction<itk::RGBAPixel<T>>::value,"");
// Test ImageTypeDeduction struct
static_assert(std::is_same<typename ImageTypeDeduction<ScalarType>::ImageType,ImageType>::value,"");
......@@ -102,10 +114,20 @@ template <typename T> struct TypesCheck
static_assert(FilterType::NumberOfInputs == 1,"");
static_assert(std::is_same<typename FilterType::template InputImageType<0>, InputImageType>::value, "");
filter->SetVInputs(in);
filter->SetVariadicInputs(in);
filter->SetInput1(in);
filter->template SetVInput<0>(in); // template keyword to avoid C++ parse ambiguity
filter->template SetVariadicInput<0>(in); // template keyword to avoid C++ parse ambiguity
filter->Update();
// Test with simple lambda
auto lambda = [] (const TIn &)
{
TOut ret(1);
return ret;
};
auto filterWithLambda = NewFunctorFilter(lambda,1, {{0,0}});
filterWithLambda->SetVariadicInputs(in);
filterWithLambda->Update();
}
TypesCheck()
......@@ -264,14 +286,14 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
// Test VariadicInputsImageFilter
auto filter = otb::VariadicInputsImageFilter<VectorImageType,VectorImageType,ImageType>::New();
filter->SetVInput<0>(vimage);
filter->SetVInput<1>(image);
filter->SetVariadicInput<0>(vimage);
filter->SetVariadicInput<1>(image);
filter->SetInput1(vimage);
filter->SetInput2(image);
filter->SetVInputs(vimage,image);
std::cout<<filter->GetVInput<0>()<< filter->GetVInput<1>()<<std::endl;
filter->SetVariadicInputs(vimage,image);
std::cout<<filter->GetVariadicInput<0>()<< filter->GetVariadicInput<1>()<<std::endl;
// test FunctorImageFilter with a lambda
......@@ -281,7 +303,7 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
return scale*p;
};
auto filterLambda = NewFunctorFilter(Lambda1);
filterLambda->SetVInputs(image);
filterLambda->SetVariadicInputs(image);
filterLambda->Update();
// test FunctorImageFilter with a lambda that returns a
......@@ -301,49 +323,49 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
// In this case, we use the helper function which allows to specify
// the number of outputs
auto filterLambda2 = NewFunctorFilter(Lambda2,vimage->GetNumberOfComponentsPerPixel(),{{3,3}});
filterLambda2->SetVInputs(image);
filterLambda2->SetVariadicInputs(image);
filterLambda2->Update();
// Test FunctorImageFilter with the VariadicConcatenate operator
using ConcatFunctorType = Functor::VariadicConcatenate<double, double, itk::VariableLengthVector<double> >;
auto concatenate = NewFunctorFilter(ConcatFunctorType{});
concatenate->SetVInputs(image,vimage);
concatenate->SetVariadicInputs(image,vimage);
concatenate->Update();
// Test FunctorImageFilter With VariadicAdd functor
using AddFunctorType = Functor::VariadicAdd<double, double, double>;
auto add = NewFunctorFilter(AddFunctorType{});
add->SetVInputs(image,image);
add->SetVariadicInputs(image,image);
add->Update();
// Test FunctorImageFilter with BandExtraction functor
using ExtractFunctorType = BandExtraction<double,double>;
ExtractFunctorType extractFunctor{1,2};
auto extract = NewFunctorFilter(extractFunctor);
extract->SetVInputs(vimage);
extract->SetVariadicInputs(vimage);
extract->Update();
// Test FunctorImageFilter With Mean functor
using MeanFunctorType = Mean<double,double>;
auto median = NewFunctorFilter(MeanFunctorType{},{{2,2}});
median->SetVInputs(image);
median->SetVariadicInputs(image);
median->Update();
// Test FunctorImageFilter with MaxInEachChannel
using MaxInEachChannelType = MaxInEachChannel<double>;
auto maxInEachChannel = NewFunctorFilter(MaxInEachChannelType{},{{3,3}});
maxInEachChannel->SetVInputs(vimage);
maxInEachChannel->SetVariadicInputs(vimage);
maxInEachChannel->Update();
// Test FunctorImageFilter with Module (complex=
using ModulusType = VectorModulus<double>;
auto modulus = NewFunctorFilter(ModulusType{});
modulus->SetVInputs(cvimage);
modulus->SetVariadicInputs(cvimage);
modulus->Update();
auto LambdaComplex = [] (const std::complex<double> & in) {return std::arg(in);};
auto argFilter = NewFunctorFilter(LambdaComplex);
argFilter->SetVInputs(cimage);
argFilter->SetVariadicInputs(cimage);
argFilter->Update();
return EXIT_SUCCESS;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment