diff --git a/Modules/Core/Functor/include/otbFunctorImageFilter.h b/Modules/Core/Functor/include/otbFunctorImageFilter.h index 5bb3f5012e05ef56eedc63a55feca46c68fecc2e..56a7251465362bc7ec52a28e280f165f9244429a 100644 --- a/Modules/Core/Functor/include/otbFunctorImageFilter.h +++ b/Modules/Core/Functor/include/otbFunctorImageFilter.h @@ -141,8 +141,6 @@ template <class T> struct PixelTypeDeduction<T &> using PixelType = typename PixelTypeDeduction<T>::PixelType; }; - - /** * \struct ImageTypeDeduction * \brief Helper struct to derive ImageType from template parameter @@ -179,8 +177,14 @@ template <typename T> struct FunctorFilterSuperclassHelper : public FunctorFilte /// Partial specialisation for R(*)(T...) template <typename R, typename... T> struct FunctorFilterSuperclassHelper<R(*)(T...)> { + // OutputImageType is derived from return type R using OutputImageType = typename ImageTypeDeduction<R>::ImageType; + + // PixelTypeDeduction<T> discards the itk::Neighborhood if present + // ImageTypeDeduction<> knows when to build VectorImage or Image for + // valid pixel type. using FilterType = VariadicInputsImageFilter<OutputImageType,typename ImageTypeDeduction<typename PixelTypeDeduction<T>::PixelType>::ImageType...>; + // InputHasNeighborhood is a tuple expanding IsNeighborhood<T> using InputHasNeighborhood = std::tuple<typename IsNeighborhood<T>::ValueType...>; }; @@ -229,12 +233,13 @@ template <typename C, typename R, typename... T> struct FunctorFilterSuperclassH /** * \brief This helper method builds a fully functional FunctorImageFilter from a functor instance * - * Functor can be any operator() that matches the following: + * Functor can be any operator() (const or non-const) that matches the following: * - Accepts any number of arguments of T, * (const) itk::VariableLengthVector<T> (&),(const) * itk::Neighborhood<T> (&), (const) * itk::Neighborhood<itk::VariableLengthVector<T>> (&) with T a scalar type * - returns T or itk::VariableLengthVector<T>, with T a scalar type + * or returns void and has first parameter as output (i.e. T& or itk::VariableLengthVector<T>&) * * The returned filter is ready to use. Inputs can be set through the * SetVariadicInputs() method (see VariadicInputsImageFilter class for @@ -257,6 +262,16 @@ template <typename Functor> auto NewFunctorFilter(const Functor& f, itk::Size<2> /** \class FunctorImageFilter * \brief A generic functor filter templated by its functor * + * TFunction can be any operator() (const or non-const) that matches the following: + * - Accepts any number of arguments of T, + * (const) itk::VariableLengthVector<T> (&),(const) + * itk::Neighborhood<T> (&), (const) + * itk::Neighborhood<itk::VariableLengthVector<T>> (&) with T a scalar type + * - returns T or itk::VariableLengthVector<T>, with T a scalar type + * or returns void and has first parameter as output (i.e. T& or itk::VariableLengthVector<T>&) + * + * All image types will be deduced from the TFunction operator(). + * * \sa VariadicInputsImageFilter * \sa NewFunctorFilter * @@ -280,8 +295,6 @@ public: using Superclass = typename FunctorFilterSuperclassHelper<TFunction>::FilterType; using OutputImageType = typename Superclass::OutputImageType; using OutputImageRegionType = typename OutputImageType::RegionType; - - using ProcessObjectType = itk::ProcessObject; // A tuple of bool of the same size as the number of arguments in // the functor @@ -291,7 +304,7 @@ public: using Superclass::NumberOfInputs; /** Run-time type information (and related methods). */ - itkTypeMacro(FunctorImageFilter, ImageToImageFilter); + itkTypeMacro(FunctorImageFilter, VariadicInputsImageFilter); /** Get the functor object. * diff --git a/Modules/Core/Functor/include/otbFunctorImageFilter.hxx b/Modules/Core/Functor/include/otbFunctorImageFilter.hxx index eff6074b92f8da67b12678cca4d89a628447cc9b..10f44b9c49fbd5f96f1a666024792be67f0d4e06 100644 --- a/Modules/Core/Functor/include/otbFunctorImageFilter.hxx +++ b/Modules/Core/Functor/include/otbFunctorImageFilter.hxx @@ -279,6 +279,7 @@ FunctorImageFilter<TFunction> itk::ImageScanlineIterator<OutputImageType> outIt(this->GetOutput(),outputRegionForThread); itk::ProgressReporter p(this,threadId,outputRegionForThread.GetNumberOfPixels()); + // This will build a tuple of iterators to be used auto inputIterators = functor_filter_details::MakeIterators(this->GetVariadicInputs(),outputRegionForThread, m_Radius,InputHasNeighborhood{}); // Build a default value @@ -287,8 +288,11 @@ FunctorImageFilter<TFunction> while(!outIt.IsAtEnd()) { + // MoveIterartors will ++ all iterators in the tuple for(;!outIt.IsAtEndOfLine();++outIt,functor_filter_details::MoveIterators(inputIterators)) { + // This will call the operator with inputIterators Get() results + // and fill outputValueHolder with the result. functor_filter_details::CallOperator(outputValueHolder,m_Functor,inputIterators); outIt.Set(outputValueHolder); // Update progress