diff --git a/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.h
index b7a5dfbdcd7160a7cc5b484f395c61663b9bfc7b..9125660e60424c20423c71106a5a91a0aac35d62 100644
--- a/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.h
@@ -26,6 +26,7 @@
 #include "otbImage.h"
 #include "otbVectorImage.h"
 #include "itkConstNeighborhoodIterator.h"
+#include "itkImageScanlineIterator.h"
 #include "itkImageRegionConstIterator.h"
 #include "itkProcessObject.h"
 #include <type_traits>
@@ -37,16 +38,76 @@ namespace otb
 
 namespace functor_filter_details
 {
+// Variadic SetRequestedRegion
+template<class T> int SetInputRequestedRegion(const T * img, const itk::ImageRegion<2> & region, const itk::Size<2>& radius)
+{
+  auto currentRegion = region;
+  currentRegion.PadByRadius(radius);
+
+  // The ugly cast in all ITK filters
+  T * nonConstImg = const_cast<T*>(img);
+
+  if(currentRegion.Crop(img->GetLargestPossibleRegion()))
+    {
+    nonConstImg->SetRequestedRegion(currentRegion);
+    return 0;
+    }
+  else
+    {
+    nonConstImg->SetRequestedRegion(currentRegion);
+        
+    // build an exception
+    itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
+    std::ostringstream msg;
+    msg << "::SetInputRequestedRegion<>()";
+    e.SetLocation(msg.str());
+    e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
+    e.SetDataObject(nonConstImg);
+    throw e;
+    }
+
+  return 0;
+}
+
+template <class Tuple, size_t...Is> auto SetInputRequestedRegionsImpl(Tuple & t, const itk::ImageRegion<2> & region, std::index_sequence<Is...>,const itk::Size<2> & radius)
+{
+  return std::make_tuple(SetInputRequestedRegion(std::get<Is>(t),region,radius)...);
+}
+
+template <typename... T> auto SetInputRequestedRegions(std::tuple<T...> && t,const itk::ImageRegion<2> & region, const itk::Size<2> & radius)
+{
+  return SetInputRequestedRegionsImpl(t,region,std::make_index_sequence<sizeof...(T)>{},radius);
+}
+
+
 // Variadic creation of iterator tuple
-template <class T> auto MakeIterator(itk::SmartPointer<T> img)
+template <class T> auto MakeIterator(const T * img, const itk::ImageRegion<2> & region)
+{
+  itk::ImageRegionConstIterator<T> it(img,region);
+  return it;
+}
+
+template <class T> auto MakeIterator(itk::SmartPointer<T> img, const itk::ImageRegion<2> & region)
+{
+  itk::ImageRegionConstIterator<T> it(img,region);
+  return it;
+}
+
+template <class T> auto MakeIterator(itk::SmartPointer<const T> img, const itk::ImageRegion<2> & region)
 {
-  itk::ImageRegionConstIterator<T> it(img,img->GetLargestPossibleRegion());
+  itk::ImageRegionConstIterator<T> it(img,region);
   return it;
 }
 
-template<class... T>  auto MakeIterators(itk::SmartPointer<T>... args)
+
+template <class Tuple, size_t...Is> auto MakeIteratorsImpl(const Tuple& t, const itk::ImageRegion<2> & region, std::index_sequence<Is...>)
+{
+  return std::make_tuple(MakeIterator(std::get<Is>(t),region)...);
+}
+
+template<typename... T> auto MakeIterators(std::tuple<T...> &&t, const itk::ImageRegion<2> & region)
   {
-    return std::make_tuple(MakeIterator(args)...);
+    return MakeIteratorsImpl(t,region,std::make_index_sequence<sizeof...(T)>{});
   }
 
 // Variadic call of operator from iterator tuple
@@ -73,14 +134,6 @@ template<typename ... Args> void MoveIterators(std::tuple<Args...> & t)
 
 } // end namespace functor_filter_details
 
-template<typename T>
-using FTraits = typename FunctionTraits::function_traits<T>;
-
-template<typename T>
-using FResultType = typename FTraits<T>::result_type;
-
-template<typename T, size_t i>
-using ArgType = typename FTraits<T>::template arg<i>::type;
 
 template <class T> struct IsNeighborhood
 {
@@ -142,6 +195,24 @@ template <typename C, typename R, typename... T> struct FunctorFilterSuperclassH
   using FilterType = VariadicInputsImageFilter<OutputImageType,typename TInputImage<T>::ImageType...>;
 };
 
+// Default implementation does nothing
+template <class F, class O, class cond = void> struct NumberOfOutputComponents
+{
+  // We can not be here if output type is VectorImage
+  //static_assert(std::is_same<O, otb::VectorImage<typename O::InternalPixelType> >::value,"Return type of Functor is a VariableLenghtVector, add a constexpr size_t OutputSize member");
+  static void Set(const F&, O *){}
+};
+
+// Case 1: O is a VectorImage AND F has a fixed OuptutSize unsigned
+// int constexpr
+template <class F, class T> struct NumberOfOutputComponents<F,T,typename std::enable_if<std::is_same<size_t, decltype(F::OutputSize)>::value>::type >
+{
+static void Set(const F &, otb::VectorImage<T> * outputImage)
+  {
+    std::cout<<"Use OutputSize to set number of output components"<<std::endl;
+    outputImage->SetNumberOfComponentsPerPixel(F::OutputSize);
+  }
+};
 
 /** \class FunctorImageFilter
  * \brief Implements 
@@ -163,17 +234,6 @@ public:
   using Pointer = itk::SmartPointer<Self>;
   using ConstPointer = itk::SmartPointer<const Self>;
 
-  // using InputImageType = typename TInputImage<TFunction,0>::ImageType;
-  // using InputImagePointer = typename InputImageType::ConstPointer;
-  // using InputImageRegionType = typename InputImageType::RegionType;
-  // using InputImagePixelType = typename InputImageType::PixelType;
-  // using InputImageSizeType = typename InputImageType::SizeType;
-  // using InputImageIndexType = typename InputImageType::IndexType;
-
-  // using OutputImageType = typename TOutputImage<TFunction>::ImageType;
-  // using OutputImagePointer = typename OutputImageType::Pointer;
-  // using OutputImageRegionType = typename OutputImageType::RegionType;
-  // using OutputImagePixelType = typename OutputImageType::PixelType;
   using Superclass = typename FunctorFilterSuperclassHelper<TFunction>::FilterType;
   using OutputImageType = typename Superclass::OutputImageType;
   using OutputImageRegionType = typename OutputImageType::RegionType;
@@ -246,7 +306,8 @@ protected:
    */
   virtual void GenerateInputRequestedRegion(void) override;
 
-
+  virtual void GenerateOutputInformation() override;
+  
   FunctorType m_Functor;
 };
 
diff --git a/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.hxx b/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.hxx
index fa05faf502fabe89bbc420b00e4d8db224ed20e9..e8b7808c82d640b3d06de7e015ed50ade77fc877 100644
--- a/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.hxx
+++ b/Modules/Filtering/ImageManipulation/include/otbFunctorImageFilter.hxx
@@ -50,6 +50,20 @@ FunctorImageFilter<TFunction>
 {
   // call the superclass' implementation of this method
   Superclass::GenerateInputRequestedRegion();
+
+  // Get requested region for output
+  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
+  auto requestedRegion = outputPtr->GetRequestedRegion();
+
+  // Propagate to each variadic inputs, including possible radius
+  functor_filter_details::SetInputRequestedRegions(this->GetVInputs(),requestedRegion, {{0,0}});
+}
+
+template <class TFunction>
+void
+FunctorImageFilter<TFunction>::GenerateOutputInformation()
+{
+  NumberOfOutputComponents<TFunction,OutputImageType>::Set(m_Functor,this->GetOutput());
 }
 
 /**
@@ -60,8 +74,23 @@ void
 FunctorImageFilter<TFunction>
 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
 {
-  (void) outputRegionForThread;
-  (void) threadId;
+
+  
+  itk::ImageScanlineIterator<OutputImageType> outIt(this->GetOutput(),outputRegionForThread);
+  itk::ProgressReporter p(this,threadId,outputRegionForThread.GetNumberOfPixels());
+
+  auto inputIterators = functor_filter_details::MakeIterators(this->GetVInputs(),outputRegionForThread);
+  
+  while(!outIt.IsAtEnd())
+    {
+    for(;!outIt.IsAtEndOfLine();++outIt,functor_filter_details::MoveIterators(inputIterators))
+      {
+      outIt.Set(functor_filter_details::CallOperator(m_Functor,inputIterators));
+      // Update progress
+      p.CompletedPixel();
+      }
+    outIt.NextLine();
+    }
 }
 
 } // end namespace otb
diff --git a/Modules/Filtering/ImageManipulation/include/otbVariadicInputsImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbVariadicInputsImageFilter.h
index ecc6269c632814078ed3ca25947818a5049a7734..5c02f97177c27b09e8c758c36b85d6f8758dacaa 100644
--- a/Modules/Filtering/ImageManipulation/include/otbVariadicInputsImageFilter.h
+++ b/Modules/Filtering/ImageManipulation/include/otbVariadicInputsImageFilter.h
@@ -52,6 +52,11 @@ public:
     SetInputsImpl(inTuple,std::make_index_sequence<sizeof...(inputs)>{});
   }
 
+  auto GetVInputs()
+  {
+    return GetInputsImpl(std::make_index_sequence<sizeof...(TInputs)>{});
+  }
+
 protected:
   VariadicInputsImageFilter()
   {
@@ -65,6 +70,11 @@ private:
   {
     return std::initializer_list<int>{(this->SetVInput<Is>(std::get<Is>(t)),0)...};
   }
+
+  template <size_t...Is> auto GetInputsImpl(std::index_sequence<Is...>)
+  {
+    return std::make_tuple(this->GetVInput<Is>()...);
+  }
   
   VariadicInputsImageFilter(const Self&) = delete;
   void operator=(const Self&) = delete;
diff --git a/Modules/Filtering/ImageManipulation/test/otbFunctorImageFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbFunctorImageFilter.cxx
index 49986b1e5a0e72fd512bec0acb813bb19e69462f..466fc7d0c85353c541ba98e05e6c0a2781cc3904 100644
--- a/Modules/Filtering/ImageManipulation/test/otbFunctorImageFilter.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbFunctorImageFilter.cxx
@@ -32,7 +32,7 @@
 
 struct Funct1
 {
-  double operator()(double p)
+  double operator()(double p) const
   {
     return p;
   }
@@ -42,16 +42,18 @@ struct Funct2
 {
   itk::VariableLengthVector<double> operator()(double p) const
   {
-    itk::VariableLengthVector<double> result(2);
+    itk::VariableLengthVector<double> result(OutputSize);
     result[0] = result[1] = p;
     return result;
   }
+
+  static constexpr size_t OutputSize = 2;
 };
 
 using IntImageNeighborhood = itk::Neighborhood<int>;
 struct Funct3
 {
-  double operator()(const IntImageNeighborhood & p)
+  double operator()(const IntImageNeighborhood & p) const
   {
     return static_cast<double>(p.GetCenterValue());
   }
@@ -67,7 +69,7 @@ struct Funct4
   itk::VariableLengthVector<double> operator()(double p, const itk::VariableLengthVector<double> & vp) const
   {
     itk::VariableLengthVector<double> result(2);
-    result[0] = result[1] = p;
+    result.Fill(p);
     return result;
   }
 };
@@ -87,7 +89,7 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
 {
   // test functions in functor_filter_details namespace
   using VectorImageType = VectorImage<double>;
-  using ImageType       = Image<unsigned int>;
+  using ImageType       = Image<double>;
   using RegionType      = typename ImageType::RegionType;
   using SizeType        = typename RegionType::SizeType;
   using IndexType       = typename RegionType::IndexType;
@@ -98,12 +100,20 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
   auto vimage = VectorImageType::New();
   auto image  = ImageType::New();
 
-  SizeType size = {200,200};
+  SizeType size = {{200,200}};
   
   vimage->SetRegions(size);
+  vimage->SetNumberOfComponentsPerPixel(2);
+  vimage->Allocate();
+  itk::VariableLengthVector<double> v(2);
+  v.Fill(0);
+  vimage->FillBuffer(v);
+  
   image->SetRegions(size);
+  image->Allocate();
+  image->FillBuffer(0);
 
-  auto iterators = MakeIterators(image,vimage);
+  auto iterators = MakeIterators(std::make_tuple(image,vimage),image->GetBufferedRegion());
 
   MoveIterators(iterators);
 
@@ -126,8 +136,23 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
   // test FunctorImageFilter
   auto filter1 = otb::FunctorImageFilter<Funct1>::New(Funct1{});
   auto filter2 = otb::FunctorImageFilter<Funct2>::New(Funct2{});
-  auto filter3 = otb::FunctorImageFilter<Funct3>::New(Funct3{});
- auto filter4 = otb::FunctorImageFilter<decltype(Lambda1)>::New(Lambda1);
+  //auto filter3 = otb::FunctorImageFilter<Funct3>::New(Funct3{});
+  auto filter4 = otb::FunctorImageFilter<Funct4>::New(Funct4{});
+  auto filterLambda = otb::FunctorImageFilter<decltype(Lambda1)>::New(Lambda1);
+
+  filter1->SetVInputs(image);
+  filter1->Update();
+  
+  filter2->SetVInputs(image);
+  filter2->Update();
+
+  filter4->SetVInputs(image,vimage);
+  filter4->Update();
+
+  filterLambda->SetVInputs(image);
+  filterLambda->Update();
+
+  
  return EXIT_SUCCESS;
 }