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