diff --git a/Modules/Core/Functor/include/otbFunctorImageFilter.h b/Modules/Core/Functor/include/otbFunctorImageFilter.h
index ddeb95167b3a85de92e4853edb2f7473d074f4fc..75a3fd1ab672d04f61ead3e7c71935d3db862430 100644
--- a/Modules/Core/Functor/include/otbFunctorImageFilter.h
+++ b/Modules/Core/Functor/include/otbFunctorImageFilter.h
@@ -21,7 +21,7 @@
 #ifndef otbFunctorImageFilter_h
 #define otbFunctorImageFilter_h
 
-#include "otbVariadicInputsImageFilter.h"
+#include "otbVariadicNamedInputsImageFilter.h"
 #include "otbImage.h"
 #include "otbVectorImage.h"
 #include "itkDefaultConvertPixelTraits.h"
@@ -122,29 +122,46 @@ template <class T> struct ImageTypeDeduction<const T &>
 * - InputHasNeighborhood a tuple of N false_type or true_type to denote
 * - if Ith arg of operator() expects a neighborhood.
 */
-template <typename T> struct FunctorFilterSuperclassHelper : public FunctorFilterSuperclassHelper<decltype(&T::operator())> {};
+
+
+template <typename T, typename TNameMap> struct FunctorFilterSuperclassHelper : public FunctorFilterSuperclassHelper<decltype(&T::operator()),TNameMap> {};
 
 /// Partial specialisation for R(*)(T...)
-template <typename R, typename... T> struct FunctorFilterSuperclassHelper<R(*)(T...)>
+template <typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<R(*)(T...),TNameMap>
 {
   using OutputImageType = typename ImageTypeDeduction<R>::ImageType;
-  using FilterType = VariadicInputsImageFilter<OutputImageType,typename ImageTypeDeduction<typename PixelTypeDeduction<T>::PixelType>::ImageType...>;
+  template <typename V> using InputImageType = typename ImageTypeDeduction<typename PixelTypeDeduction<V>::PixelType>::ImageType;
+  
+  using FilterType = typename std::conditional<std::is_void<TNameMap>::value,
+                                               VariadicInputsImageFilter<OutputImageType,InputImageType<T>...>,
+                                               VariadicNamedInputsImageFilter<OutputImageType,TNameMap,InputImageType<T>...>>::type;
+
   using InputHasNeighborhood = std::tuple<typename IsNeighborhood<T>::ValueType...>;
 };
 
 // Partial specialisation for R(C::*)(T...) const
-template <typename C, typename R, typename... T> struct FunctorFilterSuperclassHelper<R(C::*)(T...) const>
+template <typename C, typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<R(C::*)(T...) const, TNameMap>
 {
   using OutputImageType = typename ImageTypeDeduction<R>::ImageType;
-  using FilterType = VariadicInputsImageFilter<OutputImageType,typename ImageTypeDeduction<typename PixelTypeDeduction<T>::PixelType>::ImageType...>;
+  template <typename V> using InputImageType = typename ImageTypeDeduction<typename PixelTypeDeduction<V>::PixelType>::ImageType;
+  
+  using FilterType = typename std::conditional<std::is_void<TNameMap>::value,
+                                               VariadicInputsImageFilter<OutputImageType,InputImageType<T>...>,
+                                               VariadicNamedInputsImageFilter<OutputImageType,TNameMap,InputImageType<T>...>>::type;
+
   using InputHasNeighborhood = std::tuple<typename IsNeighborhood<T>::ValueType...>;
 };
 
 // Partial specialisation for R(C::*)(T...)
-template <typename C, typename R, typename... T> struct FunctorFilterSuperclassHelper<R(C::*)(T...)>
+template <typename C, typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<R(C::*)(T...), TNameMap>
 {
   using OutputImageType = typename ImageTypeDeduction<R>::ImageType;
-  using FilterType = VariadicInputsImageFilter<OutputImageType,typename ImageTypeDeduction<typename PixelTypeDeduction<T>::PixelType>::ImageType...>;
+  template <typename V> using InputImageType = typename ImageTypeDeduction<typename PixelTypeDeduction<V>::PixelType>::ImageType;
+  
+  using FilterType = typename std::conditional<std::is_void<TNameMap>::value,
+                                               VariadicInputsImageFilter<OutputImageType,InputImageType<T>...>,
+                                               VariadicNamedInputsImageFilter<OutputImageType,TNameMap,InputImageType<T>...>>::type;
+
   using InputHasNeighborhood = std::tuple<typename IsNeighborhood<T>::ValueType...>;
 };
 
@@ -173,7 +190,7 @@ template <typename C, typename R, typename... T> struct FunctorFilterSuperclassH
  * provided it returns a scalar type. If your lambda returns a
  * VariableLengthVector, see the other NewFunctorFilter implementation.
  */
-template <typename Functor> auto NewFunctorFilter(const Functor& f, itk::Size<2> radius = {{0,0}});
+template <typename Functor, typename TNameMap = void> auto NewFunctorFilter(const Functor& f, itk::Size<2> radius = {{0,0}});
 
 
 /** \class FunctorImageFilter
@@ -186,9 +203,9 @@ template <typename Functor> auto NewFunctorFilter(const Functor& f, itk::Size<2>
  *
  * \ingroup OTBFunctor
 */
-template <class TFunction>
+template <class TFunction, class TNameMap = void>
     class ITK_EXPORT FunctorImageFilter
-  : public FunctorFilterSuperclassHelper<TFunction>::FilterType
+  : public FunctorFilterSuperclassHelper<TFunction, TNameMap>::FilterType
 {
 
 public:
@@ -199,7 +216,8 @@ public:
   using ConstPointer = itk::SmartPointer<const Self>;
 
   // Superclass through the helper struct
-  using Superclass = typename FunctorFilterSuperclassHelper<TFunction>::FilterType;
+  using SuperclassHelper = FunctorFilterSuperclassHelper<TFunction,TNameMap>;
+  using Superclass = typename SuperclassHelper::FilterType;
   using OutputImageType = typename Superclass::OutputImageType;
   using OutputImageRegionType = typename OutputImageType::RegionType;
   
@@ -207,7 +225,7 @@ public:
 
   // A tuple of bool of the same size as the number of arguments in
   // the functor
-  using InputHasNeighborhood = typename FunctorFilterSuperclassHelper<TFunction>::InputHasNeighborhood;
+  using InputHasNeighborhood = typename SuperclassHelper::InputHasNeighborhood;
   using InputTypesTupleType = typename Superclass::InputTypesTupleType;
   template<size_t I> using InputImageType = typename Superclass::template InputImageType<I>;
   using Superclass::NumberOfInputs;
@@ -244,7 +262,7 @@ protected:
 
 private:
   /// Actual creation of the filter is handled by this free function
-  friend auto NewFunctorFilter<TFunction>(const TFunction& f, itk::Size<2> radius);
+  friend auto NewFunctorFilter<TFunction,TNameMap>(const TFunction& f, itk::Size<2> radius);
 
   /** Overload of ThreadedGenerateData  */
   void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) override;
@@ -268,9 +286,9 @@ private:
 };
 
 // Actual implementation of NewFunctorFilter free function
-template <typename Functor> auto NewFunctorFilter(const Functor& f, itk::Size<2> radius)
+template <typename Functor, typename TNameMap> auto NewFunctorFilter(const Functor& f, itk::Size<2> radius)
 {
-  using FilterType = FunctorImageFilter<Functor>;
+  using FilterType = FunctorImageFilter<Functor,TNameMap>;
   using PointerType = typename FilterType::Pointer;
 
   PointerType  p = new FilterType(f,radius);
@@ -325,11 +343,11 @@ private:
 
  */ 
 
-template <typename Functor> auto NewFunctorFilter(const Functor& f, unsigned int numberOfOutputBands, itk::Size<2> radius)
+template <typename Functor, typename TNameMap = void> auto NewFunctorFilter(const Functor& f, unsigned int numberOfOutputBands, itk::Size<2> radius)
 {
   using FunctorType = NumberOfOutputBandsDecorator<Functor>;
   FunctorType decoratedF(f,numberOfOutputBands);
-  return  NewFunctorFilter(decoratedF,radius);
+  return  NewFunctorFilter<FunctorType,TNameMap>(decoratedF,radius);
 }
 
 
diff --git a/Modules/Core/Functor/include/otbFunctorImageFilter.hxx b/Modules/Core/Functor/include/otbFunctorImageFilter.hxx
index 4d80e69c3057070ee44996c683fab0933554ab18..cc6573d3c77e701fdb1ee680412eac06c6cb5922 100644
--- a/Modules/Core/Functor/include/otbFunctorImageFilter.hxx
+++ b/Modules/Core/Functor/include/otbFunctorImageFilter.hxx
@@ -176,9 +176,9 @@ template <class F, class T, size_t N> struct NumberOfOutputComponents<F,otb::Vec
 
 } // end namespace functor_filter_details
 
-template <class TFunction>
+template <class TFunction, class TNameMap>
 void
-FunctorImageFilter<TFunction>
+FunctorImageFilter<TFunction, TNameMap>
 ::GenerateInputRequestedRegion()
 {
   // Get requested region for output
@@ -191,9 +191,9 @@ FunctorImageFilter<TFunction>
   functor_filter_details::SetInputRequestedRegions(this->GetVInputs(),requestedRegion, m_Radius);
 }
 
-template <class TFunction>
+template <class TFunction, class TNameMap>
 void
-FunctorImageFilter<TFunction>::GenerateOutputInformation()
+FunctorImageFilter<TFunction, TNameMap>::GenerateOutputInformation()
 {
   // Call Superclass implementation
   Superclass::GenerateOutputInformation();
@@ -211,9 +211,9 @@ FunctorImageFilter<TFunction>::GenerateOutputInformation()
 /**
  * ThreadedGenerateData Performs the neighborhood-wise operation
  */
-template <class TFunction>
+template <class TFunction, class TNameMap>
 void
-FunctorImageFilter<TFunction>
+FunctorImageFilter<TFunction, TNameMap>
 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
 {
   // Build output iterator
diff --git a/Modules/Core/Functor/include/otbVariadicNamedInputsImageFilter.h b/Modules/Core/Functor/include/otbVariadicNamedInputsImageFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..a2c342ffc6129f54ca97a82f6c194fdcf8dcfa5b
--- /dev/null
+++ b/Modules/Core/Functor/include/otbVariadicNamedInputsImageFilter.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef otb_VariadicNamedInputsImageFilter_h
+#define otb_VariadicNamedInputsImageFilter_h
+
+#include "otbVariadicInputsImageFilter.h"
+
+namespace otb {
+
+/// TODO: Documentation
+
+namespace internal
+{
+template<typename Arg, typename Tuple> struct tuple_index;
+template<typename Arg, typename...Args> struct tuple_index<Arg, std::tuple<Arg,Args...> >
+{
+  static constexpr std::size_t value = 0;
+};
+
+template<typename Arg, typename NotMatching, typename...Args> struct tuple_index<Arg, std::tuple<NotMatching,Args...>>
+{
+  static_assert(sizeof...(Args)>0,"Could not find requested type in tuple");
+  static constexpr std::size_t value = 1 + tuple_index<Arg,std::tuple<Args...>>::value;
+};
+}
+
+template<class TOuptut, class TInputNameMap, class ... TInputs> class VariadicNamedInputsImageFilter : public VariadicInputsImageFilter<TOuptut,TInputs...>
+{
+public:
+  using Self         = VariadicNamedInputsImageFilter<TOuptut,TInputNameMap, TInputs...>;
+  using Pointer      = itk::SmartPointer<Self>;
+  using ConstPointer = itk::SmartPointer<const Self>;
+  using Superclass   = VariadicInputsImageFilter<TOuptut, TInputs...>;;
+
+  using InputTypesTupleType                = typename Superclass::InputTypesTupleType;
+  template <size_t I> using InputImageType = typename Superclass::template InputImageType<I>;
+  static constexpr size_t NumberOfInputs   = Superclass::NumberOfInputs;
+
+  static_assert(std::tuple_size<TInputNameMap>::value == NumberOfInputs,"Tuple for input name does not match the size of ... TInputs");
+  
+  itkNewMacro(Self);
+  
+  template <typename Tag> void SetVNamedInput(const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value> * inputPtr)
+  {
+    constexpr size_t idx = internal::tuple_index<Tag, TInputNameMap>::value;
+    this->SetNthInput(idx,const_cast<InputImageType<idx> *>(inputPtr));
+  }
+  
+  template <typename Tag> const InputImageType<internal::tuple_index<Tag,TInputNameMap>::value> * GetVNamedInput()
+  {
+    constexpr size_t idx = internal::tuple_index<Tag, TInputNameMap>::value;
+    return dynamic_cast<const InputImageType<idx> *>(this->GetInput(idx));
+  }
+
+protected:
+  VariadicNamedInputsImageFilter() = default;
+  ~VariadicNamedInputsImageFilter() = default;
+  
+private:
+  VariadicNamedInputsImageFilter(const Self&) = delete;
+  void operator=(const Self&) = delete;
+};
+
+}
+
+#endif
diff --git a/Modules/Core/Functor/test/otbFunctorImageFilter.cxx b/Modules/Core/Functor/test/otbFunctorImageFilter.cxx
index e1cd5360e2713ed13d4f5c5761a7b4b58c7ed871..df88b7a10821e9a8cf61585575c4274af79636f0 100644
--- a/Modules/Core/Functor/test/otbFunctorImageFilter.cxx
+++ b/Modules/Core/Functor/test/otbFunctorImageFilter.cxx
@@ -25,6 +25,7 @@
 #include "itkNeighborhood.h"
 #include "otbVariadicAddFunctor.h"
 #include "otbVariadicConcatenateFunctor.h"
+#include "otbVariadicNamedInputsImageFilter.h"
 #include <tuple>
 
 #include <numeric>
@@ -99,7 +100,7 @@ template <typename T> struct TypesCheck
   // Build and run filter
   auto functor = TestOperator<TOut,TIn>{};
   auto filter = NewFunctorFilter(functor);
-
+  
   using FilterType = typename decltype(filter)::ObjectType;
   static_assert(FilterType::NumberOfInputs == 1,"");
   static_assert(std::is_same<typename FilterType::template InputImageType<0>, InputImageType>::value, "");
@@ -108,6 +109,13 @@ template <typename T> struct TypesCheck
   filter->SetInput1(in);
   filter->template SetVInput<0>(in); // template keyword to avoid C++ parse ambiguity
   filter->Update();
+
+  // Test named input version
+  struct tag{};
+  using inputNames = std::tuple<tag>;
+  auto filter1 = NewFunctorFilter<decltype(functor),inputNames>(functor);
+  filter1->template SetVNamedInput<tag>(in);
+  filter1->Update();
   }
 
   TypesCheck()
@@ -274,6 +282,17 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
   filter->SetVInputs(vimage,image);
   std::cout<<filter->GetVInput<0>()<< filter->GetVInput<1>()<<std::endl;
 
+  // Test VariadicNamedInputsImageFilter
+  struct xs {};
+  struct pan {};
+  using Names = std::tuple<xs,pan>; 
+   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;
+
+  
   
   // test FunctorImageFilter with a lambda
   double scale = 10.;  
@@ -314,6 +333,8 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
   // Test FunctorImageFilter With VariadicAdd functor
   using AddFunctorType = Functor::VariadicAdd<double, double, double>;
   auto add = NewFunctorFilter(AddFunctorType{});
+  add->SetVInput<0>(image);
+  add->SetVInput<1>(image);
   add->SetVInputs(image,image);
   add->Update();
 
@@ -346,7 +367,7 @@ int otbFunctorImageFilter(int itkNotUsed(argc), char * itkNotUsed(argv) [])
   auto argFilter = NewFunctorFilter(LambdaComplex);
   argFilter->SetVInputs(cimage);
   argFilter->Update();
-
+  
  return EXIT_SUCCESS;
 }