diff --git a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
index 10f7d79fb6a5df18a045dfccf4311aefb283d854..dd56cec77eb722adb01eb3ec7ad1984b7a518cbf 100644
--- a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
+++ b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
@@ -21,20 +21,17 @@
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
-
-#include "otbReciprocalHAlphaImageFilter.h"
 #include "otbReciprocalBarnesDecompImageFilter.h"
 #include "otbReciprocalHuynenDecompImageFilter.h"
 #include "otbReciprocalPauliDecompImageFilter.h"
+#include "otbReciprocalHAlphaImageFilter.h"
 
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
 #include "otbPerBandVectorImageFilter.h"
 #include "itkMeanImageFilter.h"
-// #include "otbNRIBandImagesToOneNComplexBandsImage.h"
 #include "otbImageListToVectorImageFilter.h"
 #include "otbImageList.h"
 
+#include "otbSinclairToReciprocalCoherencyMatrixImageFilter.h"
 
 namespace otb
 {
@@ -50,28 +47,22 @@ public:
   typedef itk::SmartPointer<Self>             Pointer;
   typedef itk::SmartPointer<const Self>       ConstPointer;
 
-  
-  
+
   typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
                                     ComplexDoubleImageType::PixelType,
                                     ComplexDoubleImageType::PixelType,
                                     ComplexDoubleVectorImageType::PixelType>								FunctorType;
-                                    
-                                    								
-  typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleVectorImageType, 
-											 FunctorType > 												    SRFilterType;
-  
-  
+
+
+  using SRFilterType = otb::SinclairToReciprocalCoherencyMatrixImageFilter<ComplexDoubleImageType, ComplexDoubleVectorImageType>;
+
   typedef itk::MeanImageFilter<ComplexDoubleImageType, ComplexDoubleImageType>                                         MeanFilterType;
   typedef otb::PerBandVectorImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType, MeanFilterType>    PerBandMeanFilterType;
   //typedef otb::NRIBandImagesToOneNComplexBandsImage<DoubleVectorImageType, ComplexDoubleVectorImageType>               NRITOOneCFilterType;
   typedef otb::ImageList<ComplexDoubleImageType>                                                                       ImageListType;
   typedef ImageListToVectorImageFilter<ImageListType, ComplexDoubleVectorImageType >                                   ListConcatenerFilterType;
-  
-  
+
+
   typedef otb::ReciprocalHAlphaImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> 			       HAFilterType;
   typedef otb::ReciprocalBarnesDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>           BarnesFilterType;
   typedef otb::ReciprocalHuynenDecompImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>           HuynenFilterType;
@@ -91,17 +82,17 @@ private:
 
     // Documentation
     SetDocName("SARDecompositions");
-    SetDocLongDescription("From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
-                          "All the decompositions implemented are intended for the mono-static case (transmitter and receiver are co-located).\n"
-                          "There are two kinds of decomposition: coherent ones and incoherent ones.\n"
-                          "In the coherent case, only the Pauli decomposition is available.\n"
-                          "In the incoherent case, there the decompositions available: Huynen, Barnes, and H-alpha-A.\n"   
-						  "User must provide three one-band complex images HH, HV or VH, and VV (mono-static case <=> HV = VH).\n"
-						  "Incoherent decompositions consist in averaging 3x3 complex coherency/covariance matrices; the user must provide the size of the averaging window, thanks to the parameter inco.kernelsize."
-						  );
-						  
-						  
-						  
+    SetDocLongDescription(
+        "From one-band complex images (HH, HV, VH, VV), returns the selected decomposition.\n \n"
+        "All the decompositions implemented are intended for the mono-static case (transmitter and receiver are co-located).\n"
+        "There are two kinds of decomposition: coherent ones and incoherent ones.\n"
+        "In the coherent case, only the Pauli decomposition is available.\n"
+        "In the incoherent case, there the decompositions available: Huynen, Barnes, and H-alpha-A.\n"
+        "User must provide three one-band complex images HH, HV or VH, and VV (mono-static case <=> HV = VH).\n"
+        "Incoherent decompositions consist in averaging 3x3 complex coherency/covariance matrices; the user must provide the size of the averaging window, "
+        "thanks to the parameter inco.kernelsize.");
+
+
     SetDocLimitations("Some decompositions output real images, while this application outputs complex images for general purpose.\n"
                       "Users should pay attention to extract the real part of the results provided by this application.\n");
     SetDocAuthors("OTB-Team");
@@ -111,21 +102,21 @@ private:
 
     AddParameter(ParameterType_InputImage,  "inhh",   "Input Image");
     SetParameterDescription("inhh", "Input image (HH)");
-    
+
     AddParameter(ParameterType_InputImage,  "inhv",   "Input Image");
     SetParameterDescription("inhv", "Input image (HV)");
     MandatoryOff("inhv");
-    
+
     AddParameter(ParameterType_InputImage,  "invh",   "Input Image");
     SetParameterDescription("invh", "Input image (VH)");
     MandatoryOff("invh");
-    
+
     AddParameter(ParameterType_InputImage,  "invv",   "Input Image");
     SetParameterDescription("invv", "Input image (VV)");
-    
+
     AddParameter(ParameterType_OutputImage, "out",  "Output Image");
     SetParameterDescription("out", "Output image");
-    
+
     AddParameter(ParameterType_Choice, "decomp", "Decompositions");
     AddChoice("decomp.haa","H-alpha-A incoherent decomposition");
     SetParameterDescription("decomp.haa","H-alpha-A incoherent decomposition");
@@ -135,10 +126,9 @@ private:
     SetParameterDescription("decomp.huynen","Huynen incoherent decomposition");
     AddChoice("decomp.pauli","Pauli coherent decomposition");
     SetParameterDescription("decomp.pauli","Pauli coherent decomposition");
-    
+
     AddParameter(ParameterType_Group,"inco","Incoherent decompositions");
     SetParameterDescription("inco","This group allows setting parameters related to the incoherent decompositions.");
-    
     AddParameter(ParameterType_Int, "inco.kernelsize",   "Kernel size for spatial incoherent averaging");
     SetParameterDescription("inco.kernelsize", "Minute (0-59)");
     SetMinimumParameterIntValue("inco.kernelsize", 1);
@@ -167,83 +157,83 @@ private:
 
   void DoExecute() override
   {
-	  
-	bool inhv = HasUserValue("inhv");
+
+  bool inhv = HasUserValue("inhv");
 	bool invh = HasUserValue("invh");
-		
-	if ( (!inhv) && (!invh) )
+
+  if ( (!inhv) && (!invh) )
 	  otbAppLogFATAL( << "Parameter inhv or invh not set. Please provide a HV or a VH complex image.");
-    
+
     m_SRFilter = SRFilterType::New();
-	m_HAFilter = HAFilterType::New();
-	m_MeanFilter = PerBandMeanFilterType::New();
+    m_HAFilter   = HAFilterType::New();
+    m_MeanFilter = PerBandMeanFilterType::New();
     MeanFilterType::InputSizeType radius;
     m_BarnesFilter = BarnesFilterType::New();
     m_HuynenFilter = HuynenFilterType::New();
     m_PauliFilter = PauliFilterType::New();
     m_Concatener = ListConcatenerFilterType::New();
-    m_ImageList = ImageListType::New();    
-    
+    m_ImageList    = ImageListType::New();
+
     switch (GetParameterInt("decomp"))
       {
 		case 0: // H-alpha-A
-		
-		if (inhv)
-		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
-	    else if (invh)
-		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
-
-		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-        radius.Fill( GetParameterInt("inco.kernelsize") );
-        m_MeanFilter->GetFilter()->SetRadius(radius);
-		
-		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
-		m_HAFilter->SetInput(m_MeanFilter->GetOutput());
-		SetParameterOutputImage("out", m_HAFilter->GetOutput() );
-    
-		break;
-        
-		case 1: // Barnes
+
+    if (inhv)
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
+      else if (invh)
+        m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
+
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      radius.Fill(GetParameterInt("inco.kernelsize"));
+      m_MeanFilter->GetFilter()->SetRadius(radius);
+
+      m_MeanFilter->SetInput(m_SRFilter->GetOutput());
+      m_HAFilter->SetVariadicInput<0>(m_MeanFilter->GetOutput());
+      SetParameterOutputImage("out", m_HAFilter->GetOutput());
+
+      break;
+
+    case 1: // Barnes
 
 		if (inhv)
-		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
-	    else if (invh)
-		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
-
-		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-        radius.Fill( GetParameterInt("inco.kernelsize") );
-        m_MeanFilter->GetFilter()->SetRadius(radius);
-		
-		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
-		m_BarnesFilter->SetInput(m_MeanFilter->GetOutput());
-		SetParameterOutputImage("out", m_BarnesFilter->GetOutput() );
-    
-		break;
-        
-		case 2: // Huynen
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
+      else if (invh)
+        m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
+
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      radius.Fill(GetParameterInt("inco.kernelsize"));
+      m_MeanFilter->GetFilter()->SetRadius(radius);
+
+      m_MeanFilter->SetInput(m_SRFilter->GetOutput());
+      m_BarnesFilter->SetVariadicInput<0>(m_MeanFilter->GetOutput());
+      SetParameterOutputImage("out", m_BarnesFilter->GetOutput());
+
+      break;
+
+    case 2: // Huynen
 
 		if (inhv)
-		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
-	    else if (invh)
-		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
-
-		m_SRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_SRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-        radius.Fill( GetParameterInt("inco.kernelsize") );
-        m_MeanFilter->GetFilter()->SetRadius(radius);
-		
-		m_MeanFilter->SetInput(m_SRFilter->GetOutput());
-		m_HuynenFilter->SetInput(m_MeanFilter->GetOutput());
-		SetParameterOutputImage("out", m_HuynenFilter->GetOutput() );
-    
-		break;
-        
-		case 3: // Pauli
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
+      else if (invh)
+        m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
+
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_SRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      radius.Fill(GetParameterInt("inco.kernelsize"));
+      m_MeanFilter->GetFilter()->SetRadius(radius);
+
+      m_MeanFilter->SetInput(m_SRFilter->GetOutput());
+      m_HuynenFilter->SetVariadicInput<0>(m_MeanFilter->GetOutput());
+      SetParameterOutputImage("out", m_HuynenFilter->GetOutput());
+
+      break;
+
+    case 3: // Pauli
 
         m_ImageList->PushBack(GetParameterComplexDoubleImage("inhh"));
 
@@ -253,18 +243,16 @@ private:
 		  m_ImageList->PushBack(GetParameterComplexDoubleImage("invh"));
 
 		m_ImageList->PushBack(GetParameterComplexDoubleImage("invv"));
-        
-        m_Concatener->SetInput( m_ImageList );        
-        m_PauliFilter->SetInput(m_Concatener->GetOutput());
-        
-		SetParameterOutputImage("out", m_PauliFilter->GetOutput() );
-    
-		break;
+
+    m_Concatener->SetInput(m_ImageList);
+    m_PauliFilter->SetVariadicInput<0>(m_Concatener->GetOutput());
+
+    SetParameterOutputImage("out", m_PauliFilter->GetOutput() );
+
+    break;
 	  }
-   	 
   }
 
-  //MCPSFilterType::Pointer m_MCPSFilter;
   SRFilterType::Pointer m_SRFilter;
   HAFilterType::Pointer m_HAFilter;
   BarnesFilterType::Pointer m_BarnesFilter;
@@ -273,8 +261,7 @@ private:
   PerBandMeanFilterType::Pointer m_MeanFilter;
   ListConcatenerFilterType::Pointer  m_Concatener;
   ImageListType::Pointer        m_ImageList;
-  
-}; 
+};
 
 } //end namespace Wrapper
 } //end namespace otb
diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
index 104630ca5b62fde63931083a6c57d2641448542c..f02da7f77454bc2211b879845c25707fe5f0db4c 100644
--- a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
@@ -21,37 +21,23 @@
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
+#include "otbSinclairToCoherencyMatrixImageFilter.h"
+#include "otbSinclairToCovarianceMatrixImageFilter.h"
+#include "otbSinclairToCircularCovarianceMatrixImageFilter.h"
+#include "otbSinclairToMuellerMatrixImageFilter.h"
 
+#include "otbSinclairToReciprocalCoherencyMatrixImageFilter.h"
+#include "otbSinclairToReciprocalCovarianceMatrixImageFilter.h"
+#include "otbSinclairToReciprocalCircularCovarianceMatrixImageFilter.h"
 
-
-
-//monostatic case
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
-#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
-#include "otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h"
+#include "otbMuellerToReciprocalCovarianceImageFilter.h"
+#include "otbMuellerToPolarisationDegreeAndPowerImageFilter.h"
 
 #include "otbReciprocalCoherencyToReciprocalMuellerImageFilter.h"
 #include "otbReciprocalCovarianceToCoherencyDegreeImageFilter.h"
 #include "otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h"
 #include "otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h"
 
-
-//bistatic case
-#include "otbSinclairImageFilter.h"
-#include "otbSinclairToCoherencyMatrixFunctor.h"
-#include "otbSinclairToCovarianceMatrixFunctor.h"
-#include "otbSinclairToCircularCovarianceMatrixFunctor.h"
-#include "otbSinclairToMuellerMatrixFunctor.h"
-
-#include "otbMuellerToReciprocalCovarianceImageFilter.h"
-#include "otbMuellerToPolarisationDegreeAndPowerImageFilter.h"
-
-
-
-
-
-
 namespace otb
 {
 namespace Wrapper
@@ -61,122 +47,30 @@ class SARPolarMatrixConvert : public Application
 {
 public:
   /** Standard class typedefs. */
-  typedef SARPolarMatrixConvert                   Self;
-  typedef Application                         Superclass;
-  typedef itk::SmartPointer<Self>             Pointer;
-  typedef itk::SmartPointer<const Self>       ConstPointer;
-
-  
-  //Monostatic case
-    typedef otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleVectorImageType::PixelType>								RCoherencyFunctorType;
-                                    
-    typedef otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleVectorImageType::PixelType>								RCovarianceFunctorType;
-                                    
-    typedef otb::Functor::SinclairToReciprocalCircularCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleVectorImageType::PixelType>								RCircularCovarianceFunctorType;
-                                                                  
-                                    								
-    typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleVectorImageType, 
-											 RCoherencyFunctorType > 									RCohSRFilterType;
-											 
-											 
-    typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleVectorImageType, 
-											 RCovarianceFunctorType > 									RCovSRFilterType;
-											 
-	typedef SinclairReciprocalImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleVectorImageType, 
-											 RCircularCovarianceFunctorType > 							RCCSRFilterType;
-											 
-											 
-    typedef otb::ReciprocalCoherencyToReciprocalMuellerImageFilter<ComplexDoubleVectorImageType, DoubleVectorImageType> RCRMFilterType;
-	
-	typedef otb::ReciprocalCovarianceToCoherencyDegreeImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> RCCDFilterType;
-	
-	typedef otb::ReciprocalCovarianceToReciprocalCoherencyImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> RCRCFilterType;
-	
-	typedef otb::ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> RLCRCCFilterType;
-											 
-  
-	//Bistatic case
-	typedef otb::Functor::SinclairToCoherencyMatrixFunctor<ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleVectorImageType::PixelType>								CoherencyFunctorType;
-                                    
-                                    
-	typedef otb::Functor::SinclairToCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleVectorImageType::PixelType>								CovarianceFunctorType;
-                                    
-                                   
-	typedef otb::Functor::SinclairToCircularCovarianceMatrixFunctor<ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleVectorImageType::PixelType>								CircularCovarianceFunctorType;
-                                    
-                                    	
-    typedef otb::Functor::SinclairToMuellerMatrixFunctor<ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    ComplexDoubleImageType::PixelType,
-                                    DoubleVectorImageType::PixelType>									MuellerFunctorType;
-                                    
-    
-    typedef SinclairImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType,
-											 ComplexDoubleImageType, 
-											 ComplexDoubleVectorImageType, 
-											 CoherencyFunctorType > 									CohSRFilterType;
-											 
-											 
-    typedef SinclairImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType,
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleVectorImageType, 
-											 CovarianceFunctorType > 									CovSRFilterType;
-											 
-	typedef SinclairImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType,
-											 ComplexDoubleImageType, 
-											 ComplexDoubleVectorImageType, 
-											 CircularCovarianceFunctorType > 							CCSRFilterType;
-                                    
-	typedef SinclairImageFilter<ComplexDoubleImageType, 
-											 ComplexDoubleImageType, 
-											 ComplexDoubleImageType,
-											 ComplexDoubleImageType, 
-											 DoubleVectorImageType, 
-											 MuellerFunctorType > 										MSRFilterType;
-											 
-											 
-	typedef otb::MuellerToReciprocalCovarianceImageFilter<DoubleVectorImageType, ComplexDoubleVectorImageType>  MRCFilterType;									 
-	
-	typedef otb::MuellerToPolarisationDegreeAndPowerImageFilter<DoubleVectorImageType, DoubleVectorImageType>   MPDPFilterType;
-  
-  
+  typedef SARPolarMatrixConvert         Self;
+  typedef Application                   Superclass;
+  typedef itk::SmartPointer<Self>       Pointer;
+  typedef itk::SmartPointer<const Self> ConstPointer;
+
+  // Monostatic case
+  using RCohSRFilterType = SinclairToReciprocalCoherencyMatrixImageFilter<ComplexDoubleImageType, ComplexDoubleVectorImageType>;
+  using RCovSRFilterType = SinclairToReciprocalCovarianceMatrixImageFilter<ComplexDoubleImageType, ComplexDoubleVectorImageType>;
+  using RCCSRFilterType  = SinclairToReciprocalCircularCovarianceMatrixImageFilter<ComplexDoubleImageType, ComplexDoubleVectorImageType>;
+
+  using RCRMFilterType = otb::ReciprocalCoherencyToReciprocalMuellerImageFilter<ComplexDoubleVectorImageType, DoubleVectorImageType>;
+  using RCCDFilterType = otb::ReciprocalCovarianceToCoherencyDegreeImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>;
+  using RCRCFilterType = otb::ReciprocalCovarianceToReciprocalCoherencyImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>;
+
+  using RLCRCCFilterType = otb::ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType>;
+
+  // Bistatic case
+  using CohSRFilterType = SinclairToCoherencyMatrixImageFilter<ComplexDoubleImageType, ComplexDoubleVectorImageType>;
+  using CovSRFilterType = SinclairToCovarianceMatrixImageFilter<ComplexDoubleImageType, ComplexDoubleVectorImageType>;
+  using CCSRFilterType  = SinclairToCircularCovarianceMatrixImageFilter<ComplexDoubleImageType, ComplexDoubleVectorImageType>;
+  using MSRFilterType   = SinclairToMuellerMatrixImageFilter<ComplexDoubleImageType, DoubleVectorImageType>;
+
+  using MRCFilterType  = otb::MuellerToReciprocalCovarianceImageFilter<DoubleVectorImageType, ComplexDoubleVectorImageType>;
+  using MPDPFilterType = otb::MuellerToPolarisationDegreeAndPowerImageFilter<DoubleVectorImageType, DoubleVectorImageType>;
 
   /** Standard macro */
   itkNewMacro(Self);
@@ -192,40 +86,43 @@ private:
     // Documentation
     SetDocName("SARPolarMatrixConvert");
     SetDocLongDescription(
-    
-    "This application allows converting classical polarimetric matrices to each other.\n"
-    "For instance, it is possible to get the coherency matrix from the Sinclar one, or the Mueller matrix from the coherency one.\n"
-    "The filters used in this application never handle matrices, but images where each band is related to their elements.\n"
-    "As most of the time SAR polarimetry handles symmetric/hermitian matrices, only the relevant elements are stored, so that the images representing them have a minimal number of bands.\n"
-    "For instance, the coherency matrix size is 3x3 in the monostatic case, and 4x4 in the bistatic case: it will thus be stored in a 6-band or a 10-band complex image (the diagonal and the upper elements of the matrix).\n"
-    "\n"
-    "The Sinclair matrix is a special case: it is always represented as 3 or 4 one-band complex images (for mono- or bistatic case).\n"
-    "The available conversions are listed below:\n"
-    
-	"\n--- Monostatic case ---\n" 
-    
-    "1 msinclairtocoherency --> Sinclair matrix to coherency matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
-    "2 msinclairtocovariance --> Sinclair matrix to covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
-    "3 msinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
-    "4 mcoherencytomueller --> Coherency matrix to Mueller matrix (input: 6 complex channels | 16 real channels)\n"
-    "5 mcovariancetocoherencydegree --> Covariance matrix to coherency degree (input: 6 complex channels | 3 complex channels)\n"
-    "6 mcovariancetocoherency --> Covariance matrix to coherency matrix (input: 6 complex channels | 6 complex channels)\n"
-    "7 mlinearcovariancetocircularcovariance --> Covariance matrix to circular covariance matrix (input: 6 complex channels | output: 6 complex channels)\n"
-    
-    "\n--- Bistatic case ---\n"
-    
-    "8 bsinclairtocoherency --> Sinclair matrix to coherency matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | 10 complex channels)\n"
-    "9 bsinclairtocovariance --> Sinclair matrix to covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex channels)\n"
-    "10 bsinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex channels)\n"
-    
-    "\n--- Both cases ---\n"
-    
-    "11 sinclairtomueller --> Sinclair matrix to Mueller matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 16 real channels)\n"
-    "12 muellertomcovariance --> Mueller matrix to covariance matrix (input: 16 real channels | output: 6 complex channels)\n"
-    "13 muellertopoldegandpower --> Mueller matrix to polarization degree and power (input: 16 real channels | output: 4 real channels)"
-
- );
-						  
+
+        "This application allows converting classical polarimetric matrices to each other.\n"
+        "For instance, it is possible to get the coherency matrix from the Sinclar one, or the Mueller matrix from the coherency one.\n"
+        "The filters used in this application never handle matrices, but images where each band is related to their elements.\n"
+        "As most of the time SAR polarimetry handles symmetric/hermitian matrices, only the relevant elements are stored, so that the images representing them "
+        "have a minimal number of bands.\n"
+        "For instance, the coherency matrix size is 3x3 in the monostatic case, and 4x4 in the bistatic case: it will thus be stored in a 6-band or a 10-band "
+        "complex image (the diagonal and the upper elements of the matrix).\n"
+        "\n"
+        "The Sinclair matrix is a special case: it is always represented as 3 or 4 one-band complex images (for mono or bistatic case).\n"
+        "The available conversions are listed below:\n"
+
+        "\n--- Monostatic case ---\n"
+
+        "1 msinclairtocoherency --> Sinclair matrix to coherency matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+        "2 msinclairtocovariance --> Sinclair matrix to covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex channels)\n"
+        "3 msinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 3 x 1 complex channel (HH, HV or VH, VV) | output:  6 complex "
+        "channels)\n"
+        "4 mcoherencytomueller --> Coherency matrix to Mueller matrix (input: 6 complex channels | 16 real channels)\n"
+        "5 mcovariancetocoherencydegree --> Covariance matrix to coherency degree (input: 6 complex channels | 3 complex channels)\n"
+        "6 mcovariancetocoherency --> Covariance matrix to coherency matrix (input: 6 complex channels | 6 complex channels)\n"
+        "7 mlinearcovariancetocircularcovariance --> Covariance matrix to circular covariance matrix (input: 6 complex channels | output: 6 complex channels)\n"
+
+        "\n--- Bistatic case ---\n"
+
+        "8 bsinclairtocoherency --> Sinclair matrix to coherency matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | 10 complex channels)\n"
+        "9 bsinclairtocovariance --> Sinclair matrix to covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex channels)\n"
+        "10 bsinclairtocircovariance --> Sinclair matrix to circular covariance matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 10 complex "
+        "channels)\n"
+
+        "\n--- Both cases ---\n"
+
+        "11 sinclairtomueller --> Sinclair matrix to Mueller matrix (input: 4 x 1 complex channel (HH, HV, VH, VV) | output: 16 real channels)\n"
+        "12 muellertomcovariance --> Mueller matrix to covariance matrix (input: 16 real channels | output: 6 complex channels)\n"
+        "13 muellertopoldegandpower --> Mueller matrix to polarization degree and power (input: 16 real channels | output: 4 real channels)"
+
+    );
     SetDocLimitations("None");
     SetDocAuthors("OTB-Team");
     SetDocSeeAlso("SARPolarSynth, SARDecompositions");
@@ -256,86 +153,85 @@ private:
     AddParameter(ParameterType_InputImage, "invv", "Input one-band complex image (VV)");
     SetParameterDescription("invv", "Input: one-band complex image (VV)");
     MandatoryOff("invv");
-    
-    AddParameter(ParameterType_OutputImage, "outc",  "Output Complex Image");
+
+    AddParameter(ParameterType_OutputImage, "outc", "Output Complex Image");
     SetParameterDescription("outc", "Output Complex image.");
     MandatoryOff("outc");
-    
-    AddParameter(ParameterType_OutputImage, "outf",  "Output Real Image");
+
+    AddParameter(ParameterType_OutputImage, "outf", "Output Real Image");
     SetParameterDescription("outf", "Output Real image.");
     MandatoryOff("outf");
-    
-    
-    
+
+
     AddParameter(ParameterType_Choice, "conv", "Conversion");
 
-    //Monostatic case 
-    
+    // Monostatic case
+
     // #1
     // SinclairToReciprocalCoherency
     AddChoice("conv.msinclairtocoherency","1 Monostatic: Sinclair matrix to coherency matrix (complex output)");
     SetParameterDescription("conv.msinclairtocoherency","1 Monostatic: Sinclair matrix to coherency matrix (complex output)");
-    
+
     // #2
     // SinclairToReciprocalCovariance
     AddChoice("conv.msinclairtocovariance","2 Monostatic: Sinclair matrix to covariance matrix (complex output)");
     SetParameterDescription("conv.msinclairtocovariance","2 Monostatic: Sinclair matrix to covariance matrix (complex output)");
-    
-    // #3 
+
+    // #3
     // SinclairToReciprocalCircularCovariance
     AddChoice("conv.msinclairtocircovariance","3 Monostatic: Sinclair matrix to circular covariance matrix (complex output)");
     SetParameterDescription("conv.msinclairtocircovariance","3 Monostatic: Sinclair matrix to circular covariance matrix (complex output)");
-    
-    // #4 
+
+    // #4
     // ReciprocalCoherencyToReciprocalMuellerImageFilter
-    AddChoice("conv.mcoherencytomueller","4 Monostatic: Coherency matrix to Mueller matrix"); 
-    SetParameterDescription("conv.mcoherencytomueller","4 Monostatic: Coherency matrix to Mueller matrix"); 
-    
+    AddChoice("conv.mcoherencytomueller", "4 Monostatic: Coherency matrix to Mueller matrix");
+    SetParameterDescription("conv.mcoherencytomueller", "4 Monostatic: Coherency matrix to Mueller matrix");
+
     // #5
-    // ReciprocalCovarianceToCoherencyDegreeImageFilter 
-    AddChoice("conv.mcovariancetocoherencydegree","5 Monostatic: Covariance matrix to coherency degree"); 
-    SetParameterDescription("conv.mcovariancetocoherencydegree","5 Monostatic: Covariance matrix to coherency degree "); 
-    
+    // ReciprocalCovarianceToCoherencyDegreeImageFilter
+    AddChoice("conv.mcovariancetocoherencydegree", "5 Monostatic: Covariance matrix to coherency degree");
+    SetParameterDescription("conv.mcovariancetocoherencydegree", "5 Monostatic: Covariance matrix to coherency degree ");
+
     // #6
     // ReciprocalCovarianceToReciprocalCoherencyImageFilter
-    AddChoice("conv.mcovariancetocoherency","6 Monostatic: Covariance matrix to coherency matrix (complex output)"); 
-    SetParameterDescription("conv.mcovariancetocoherency","6 Monostatic: Covariance matrix to coherency matrix (complex output)");  
-    
+    AddChoice("conv.mcovariancetocoherency", "6 Monostatic: Covariance matrix to coherency matrix (complex output)");
+    SetParameterDescription("conv.mcovariancetocoherency", "6 Monostatic: Covariance matrix to coherency matrix (complex output)");
+
     // #7
     // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
-    AddChoice("conv.mlinearcovariancetocircularcovariance","7 Monostatic: Covariance matrix to circular covariance matrix (complex output)"); 
-    SetParameterDescription("conv.mlinearcovariancetocircularcovariance","7 Monostatic: Covariance matrix to circular covariance matrix (complex output)");  
-    
+    AddChoice("conv.mlinearcovariancetocircularcovariance", "7 Monostatic: Covariance matrix to circular covariance matrix (complex output)");
+    SetParameterDescription("conv.mlinearcovariancetocircularcovariance", "7 Monostatic: Covariance matrix to circular covariance matrix (complex output)");
+
     // #8
-    // MuellerToReciprocalCovarianceImageFilter 
+    // MuellerToReciprocalCovarianceImageFilter
     AddChoice("conv.muellertomcovariance","8 Bi/mono: Mueller matrix to monostatic covariance matrix");
     SetParameterDescription("conv.muellertomcovariance","8 Bi/mono: Mueller matrix to monostatic covariance matrix");
-    
+
     //Bistatic case
-    
+
     // #9
     // SinclairToCoherency
     AddChoice("conv.bsinclairtocoherency","9 Bistatic: Sinclair matrix to coherency matrix (complex output)");
     SetParameterDescription("conv.bsinclairtocoherency","9 Bistatic: Sinclair matrix to coherency matrix (complex output)");
-    
+
     // #10
-    // SinclairToCovariance  
+    // SinclairToCovariance
     AddChoice("conv.bsinclairtocovariance","10 Bistatic: Sinclair matrix to covariance matrix (complex output)");
     SetParameterDescription("conv.bsinclairtocovariance","10 Bistatic: Sinclair matrix to covariance matrix (complex output)");
-    
+
     // #11
-    // SinclairToCircularCovariance 
+    // SinclairToCircularCovariance
     AddChoice("conv.bsinclairtocircovariance","11 Bistatic: Sinclair matrix to circular covariance matrix (complex output)");
     SetParameterDescription("conv.bsinclairtocircovariance","11 Bistatic: Sinclair matrix to circular covariance matrix (complex output)");
-    
+
     //Both case
-    
+
     // #12
     // SinclairToMueller
     AddChoice("conv.sinclairtomueller","12 Bi/mono: Sinclair matrix to Mueller matrix");
     SetParameterDescription("conv.sinclairtomueller","12 Bi/mono: Sinclair matrix to Mueller matrix");
-    
-    
+
+
     // #13
     // MuellerToPolarisationDegreeAndPowerImageFilter
     AddChoice("conv.muellertopoldegandpower","13 Bi/mono: Mueller matrix to polarisation degree and power");
@@ -348,9 +244,9 @@ private:
 
     // Doc example parameter settings
     SetDocExampleParameterValue("inhh", "HH.tif");
-	SetDocExampleParameterValue("invh", "VH.tif");
-	SetDocExampleParameterValue("invv", "VV.tif");
-	SetDocExampleParameterValue("conv", "msinclairtocoherency"); 
+    SetDocExampleParameterValue("invh", "VH.tif");
+    SetDocExampleParameterValue("invv", "VV.tif");
+    SetDocExampleParameterValue("conv", "msinclairtocoherency");
     SetDocExampleParameterValue("outc", "mcoherency.tif");
 
     SetOfficialDocLink();
@@ -358,331 +254,317 @@ private:
 
   void DoUpdateParameters() override
   {
-    
+
     int convType = GetParameterInt("conv");
-    
-    if ( (convType>=0) && (convType<=2)) //msinclairtocoherency msinclairtocovariance msinclairtocircovariance
-	{
-	    GetParameterByKey("inc")->SetActive(false);
-	    GetParameterByKey("inf")->SetActive(false); 
-	    GetParameterByKey("inhh")->SetActive(true);
-	    GetParameterByKey("inhv")->SetActive(true); 
-	    GetParameterByKey("invh")->SetActive(true);
-	    GetParameterByKey("invv")->SetActive(true); 
-	    GetParameterByKey("outc")->SetActive(true);
-	    GetParameterByKey("outf")->SetActive(false);
-	}
-	else if ( (convType>=3) && (convType<=6)) // mcoherencytomueller mcovariancetocoherencydegree mcovariancetocoherency mlinearcovariancetocircularcovariance
-	{  
-	    GetParameterByKey("inc")->SetActive(true);
-	    GetParameterByKey("inf")->SetActive(false); 
-	    GetParameterByKey("inhh")->SetActive(false);
-	    GetParameterByKey("inhv")->SetActive(false); 
-	    GetParameterByKey("invh")->SetActive(false);
-	    GetParameterByKey("invv")->SetActive(false); 
-	    
-	    if (convType == 3)
-	    {
-			GetParameterByKey("outc")->SetActive(false);
-			GetParameterByKey("outf")->SetActive(true);
-		}
-		else
-		{
-			GetParameterByKey("outc")->SetActive(true);
-			GetParameterByKey("outf")->SetActive(false);
-		}
-	}
-	else if ( convType==7) // muellertomcovariance
-	{
-		GetParameterByKey("inc")->SetActive(false);
-	    GetParameterByKey("inf")->SetActive(true); 
-	    GetParameterByKey("inhh")->SetActive(false);
-	    GetParameterByKey("inhv")->SetActive(false); 
-	    GetParameterByKey("invh")->SetActive(false);
-	    GetParameterByKey("invv")->SetActive(false); 
-	    GetParameterByKey("outc")->SetActive(true);
-		GetParameterByKey("outf")->SetActive(false);	
-	}
-	else if ( (convType>=8) && (convType<=11)) // bsinclairtocoherency bsinclairtocovariance bsinclairtocircovariance sinclairtomueller
-	{
-	    GetParameterByKey("inc")->SetActive(false);
-	    GetParameterByKey("inf")->SetActive(false); 
-	    GetParameterByKey("inhh")->SetActive(true);
-	    GetParameterByKey("inhv")->SetActive(true); 
-	    GetParameterByKey("invh")->SetActive(true);
-	    GetParameterByKey("invv")->SetActive(true); 
-	    	    
-	    if (convType == 11)
-	    {
-			GetParameterByKey("outc")->SetActive(false);
-			GetParameterByKey("outf")->SetActive(true);
-		}
-		else
-		{
-			GetParameterByKey("outc")->SetActive(true);
-			GetParameterByKey("outf")->SetActive(false);
-		}
-	    
-	}
-	else if ( convType==12 )  // muellertopoldegandpower
-	{
-	    GetParameterByKey("inc")->SetActive(false);
-	    GetParameterByKey("inf")->SetActive(true); 
-	    GetParameterByKey("inhh")->SetActive(false);
-	    GetParameterByKey("inhv")->SetActive(false); 
-	    GetParameterByKey("invh")->SetActive(false);
-	    GetParameterByKey("invv")->SetActive(false); 
-	    GetParameterByKey("outc")->SetActive(false);
-		GetParameterByKey("outf")->SetActive(true);	    
-	}
-	
-    
-    
+
+    if ((convType >= 0) && (convType <= 2)) // msinclairtocoherency msinclairtocovariance msinclairtocircovariance
+    {
+      GetParameterByKey("inc")->SetActive(false);
+      GetParameterByKey("inf")->SetActive(false);
+      GetParameterByKey("inhh")->SetActive(true);
+      GetParameterByKey("inhv")->SetActive(true);
+      GetParameterByKey("invh")->SetActive(true);
+      GetParameterByKey("invv")->SetActive(true);
+      GetParameterByKey("outc")->SetActive(true);
+      GetParameterByKey("outf")->SetActive(false);
+    }
+    else if ((convType >= 3) &&
+             (convType <= 6)) // mcoherencytomueller mcovariancetocoherencydegree mcovariancetocoherency mlinearcovariancetocircularcovariance
+    {
+      GetParameterByKey("inc")->SetActive(true);
+      GetParameterByKey("inf")->SetActive(false);
+      GetParameterByKey("inhh")->SetActive(false);
+      GetParameterByKey("inhv")->SetActive(false);
+      GetParameterByKey("invh")->SetActive(false);
+      GetParameterByKey("invv")->SetActive(false);
+
+      if (convType == 3)
+      {
+        GetParameterByKey("outc")->SetActive(false);
+        GetParameterByKey("outf")->SetActive(true);
+      }
+      else
+      {
+        GetParameterByKey("outc")->SetActive(true);
+        GetParameterByKey("outf")->SetActive(false);
+      }
+    }
+    else if (convType == 7) // muellertomcovariance
+    {
+      GetParameterByKey("inc")->SetActive(false);
+      GetParameterByKey("inf")->SetActive(true);
+      GetParameterByKey("inhh")->SetActive(false);
+      GetParameterByKey("inhv")->SetActive(false);
+      GetParameterByKey("invh")->SetActive(false);
+      GetParameterByKey("invv")->SetActive(false);
+      GetParameterByKey("outc")->SetActive(true);
+      GetParameterByKey("outf")->SetActive(false);
+    }
+    else if ((convType >= 8) && (convType <= 11)) // bsinclairtocoherency bsinclairtocovariance bsinclairtocircovariance sinclairtomueller
+    {
+      GetParameterByKey("inc")->SetActive(false);
+      GetParameterByKey("inf")->SetActive(false);
+      GetParameterByKey("inhh")->SetActive(true);
+      GetParameterByKey("inhv")->SetActive(true);
+      GetParameterByKey("invh")->SetActive(true);
+      GetParameterByKey("invv")->SetActive(true);
+
+      if (convType == 11)
+      {
+        GetParameterByKey("outc")->SetActive(false);
+        GetParameterByKey("outf")->SetActive(true);
+      }
+      else
+      {
+        GetParameterByKey("outc")->SetActive(true);
+        GetParameterByKey("outf")->SetActive(false);
+      }
+    }
+    else if (convType == 12) // muellertopoldegandpower
+    {
+      GetParameterByKey("inc")->SetActive(false);
+      GetParameterByKey("inf")->SetActive(true);
+      GetParameterByKey("inhh")->SetActive(false);
+      GetParameterByKey("inhv")->SetActive(false);
+      GetParameterByKey("invh")->SetActive(false);
+      GetParameterByKey("invv")->SetActive(false);
+      GetParameterByKey("outc")->SetActive(false);
+      GetParameterByKey("outf")->SetActive(true);
+    }
   }
 
   void DoExecute() override
   {
 
     //****************************************
-	//* Check inputs and outputs consistency *
-	//****************************************
-	
-    bool inc = HasUserValue("inc");
-    bool inf = HasUserValue("inf");
-	bool inhh = HasUserValue("inhh");
-	bool inhv = HasUserValue("inhv");
-	bool invh = HasUserValue("invh");
-	bool invv = HasUserValue("invv");
-	bool outc = HasUserValue("outc"); 
-	bool outf = HasUserValue("outf"); 
-	
-	int convType = GetParameterInt("conv");
-	
-	
-	if ( (!outc) && (!outf) )
-	        otbAppLogFATAL( << "No output image provided; please, set the parameter 'outc' or 'outf'.");
-
-	
-	if ( (convType>=0) && (convType<=2)) //msinclairtocoherency msinclairtocovariance msinclairtocircovariance
-	{
-		if ( (!inhv) && (!invh) )
-	        otbAppLogFATAL( << "Parameter 'inhv' or 'invh' not set.");
-	    if ( !inhh )
-	        otbAppLogFATAL( << "Parameter 'inhh' not set.");
-	    if ( !invv )
-	        otbAppLogFATAL( << "Parameter 'invv' not set.");
-	        
-	}
-	
-	else if ( (convType>=3) && (convType<=6)) // mcoherencytomueller mcovariancetocoherencydegree mcovariancetocoherency mlinearcovariancetocircularcovariance
-	{
-		if ( !inc )
-	        otbAppLogFATAL( << "Parameter 'inc' not set.");
-	}
-	else if ( (convType>=8) && (convType<=11)) // bsinclairtocoherency bsinclairtocovariance bsinclairtocircovariance sinclairtomueller
-	{
-	    if ( (!inhh) || (!inhv) || (!invh) || (!invv) )
-	        otbAppLogFATAL( << "Please, ensure that HH, HV, VH and VV complex images have been provided (parameters inhh, inhv, invh, invv).");
-	}
-	else if ( (convType==7) || (convType==12) ) // muellertomcovariance muellertopoldegandpower
-	{
-		if ( !inf )
-	        otbAppLogFATAL( << "Parameter 'inf' not set.");
-	}
-
-		
-	switch (GetParameterInt("conv"))
-      {
-		  
-		//***************************************
-		//*             MONOSTATIC              *
-		//***************************************
-		
-		case 0: // SinclairToReciprocalCoherency
-	  	m_RCohSRFilter = RCohSRFilterType::New();
-	  	
-	    if (inhv)
-		  m_RCohSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
-	    else if (invh)
-		  m_RCohSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
-	  	
-		m_RCohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_RCohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-		SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
-		
-		break;
-
-		
-		case 1: // SinclairToReciprocalCovariance	
-	
-		m_RCovSRFilter = RCovSRFilterType::New();
-		
-		if (inhv)
-		  m_RCovSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
-	    else if (invh)
-		  m_RCovSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
-		
-		m_RCovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_RCovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-		SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
-		
-		break;
-		
-		
-		
-		case 2: // SinclairToReciprocalCircularCovariance
-		
-		m_RCCSRFilter = RCCSRFilterType::New();
-		
-		if (inhv)
-		  m_RCCSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
-	    else if (invh)
-		  m_RCCSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
-		
-		m_RCCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_RCCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-		SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input: 3 x 1 complex channel | output:  6 complex channels
-		
-		break;
-		
-		
-	    case 3: // ReciprocalCoherencyToReciprocalMuellerImageFilter
-		
-		m_RCRMFilter = RCRMFilterType::New();
-		m_RCRMFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
-		
-		SetParameterOutputImage("outf", m_RCRMFilter->GetOutput() ); // input: 6 complex channels | 16 real channels
-		
-		break;
-		
-	
-		
-		case 4: // ReciprocalCovarianceToCoherencyDegreeImageFilter
-		
-		m_RCCDFilter = RCCDFilterType::New();
-		m_RCCDFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
-		
-		SetParameterOutputImage("outc", m_RCCDFilter->GetOutput() ); // input: 6 complex channels | 3 complex channels
-		
-		break;
-
-
-	    case 5: // ReciprocalCovarianceToReciprocalCoherencyImageFilter
-		
-		m_RCRCFilter = RCRCFilterType::New();
-		m_RCRCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
-		
-		SetParameterOutputImage("outc", m_RCRCFilter->GetOutput() ); // input: 6 complex channels | 6 complex channels
-		
-		break;
-		
-	    
-
-	    case 6: // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
-		
-		m_RLCRCCFilter = RLCRCCFilterType::New();
-		m_RLCRCCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc"));
-		
-		SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input: 6 complex channels | output: 6 complex channels
-		
-		break;
-		
-		
-		case 7: // MuellerToReciprocalCovarianceImageFilter
-		
-		m_MRCFilter = MRCFilterType::New();
-		
-		m_MRCFilter->SetInput(GetParameterDoubleVectorImage("inf"));
-		
-		SetParameterOutputImage("outc", m_MRCFilter->GetOutput() ); // input: 16 real channels | output: 6 complex channels
-		
-		break;
-		
-		
-	    //***************************************
-		//*               BISTATIC              * 
-		//***************************************
-		
-	    case 8: // SinclairToCoherency
-			
-	  	m_CohSRFilter = CohSRFilterType::New();
-	  	
-		m_CohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_CohSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
-		m_CohSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
-		m_CohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-		SetParameterOutputImage("outc", m_CohSRFilter->GetOutput() ); // input: 4 x 1 complex channel | 10 complex channels
-		
-		break;
-		
-			
-    
-		case 9: // SinclairToCovariance	
-		
-		m_CovSRFilter = CovSRFilterType::New();
-		
-		m_CovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_CovSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
-		m_CovSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
-		m_CovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-		SetParameterOutputImage("outc", m_CovSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 10 complex channels
-		
-		break;
-		
-		
-		case 10: // SinclairToCircularCovariance
-		
-		m_CCSRFilter = CCSRFilterType::New();
-		
-		m_CCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_CCSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
-		m_CCSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
-		m_CCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-		SetParameterOutputImage("outc", m_CCSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 10 complex channels
-		
-		break;
-		
-		
-		//***************************************
-		//*             BOTH CASES              * 
-		//***************************************
-		
-				
-		case 11: // SinclairToMueller
-		m_MSRFilter = MSRFilterType::New();
-		
-		m_MSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_MSRFilter->SetInputHV(GetParameterComplexDoubleImage("inhv"));
-		m_MSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh"));
-		m_MSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
-		
-		SetParameterOutputImage("outf", m_MSRFilter->GetOutput() ); // input: 4 x 1 complex channel | output: 16 real channels
-		
-		break;
-		
-		
-		case 12: // MuellerToPolarisationDegreeAndPowerImageFilter
-		m_MPDPFilter = MPDPFilterType::New();
-		
-		m_MPDPFilter->SetInput(GetParameterDoubleVectorImage("inf"));
-		
-		SetParameterOutputImage("outf", m_MPDPFilter->GetOutput() ); //  input: 16 real channels | output: 4 real channels
-		
-		break;
-		
-	  }
-	  
-
-    
+    //* Check inputs and outputs consistency *
+    //****************************************
+
+    bool inc  = HasUserValue("inc");
+    bool inf  = HasUserValue("inf");
+    bool inhh = HasUserValue("inhh");
+    bool inhv = HasUserValue("inhv");
+    bool invh = HasUserValue("invh");
+    bool invv = HasUserValue("invv");
+    bool outc = HasUserValue("outc");
+    bool outf = HasUserValue("outf");
+
+    int convType = GetParameterInt("conv");
+
+
+    if ((!outc) && (!outf))
+      otbAppLogFATAL(<< "No output image provided; please, set the parameter 'outc' or 'outf'.");
+
+
+    if ((convType >= 0) && (convType <= 2)) // msinclairtocoherency msinclairtocovariance msinclairtocircovariance
+    {
+      if ((!inhv) && (!invh))
+        otbAppLogFATAL(<< "Parameter 'inhv' or 'invh' not set.");
+      if (!inhh)
+        otbAppLogFATAL(<< "Parameter 'inhh' not set.");
+      if (!invv)
+        otbAppLogFATAL(<< "Parameter 'invv' not set.");
+    }
+
+    else if ((convType >= 3) &&
+             (convType <= 6)) // mcoherencytomueller mcovariancetocoherencydegree mcovariancetocoherency mlinearcovariancetocircularcovariance
+    {
+      if (!inc)
+        otbAppLogFATAL(<< "Parameter 'inc' not set.");
+    }
+    else if ((convType >= 8) && (convType <= 11)) // bsinclairtocoherency bsinclairtocovariance bsinclairtocircovariance sinclairtomueller
+    {
+      if ((!inhh) || (!inhv) || (!invh) || (!invv))
+        otbAppLogFATAL(<< "Please, ensure that HH, HV, VH and VV complex images have been provided (parameters inhh, inhv, invh, invv).");
+    }
+    else if ((convType == 7) || (convType == 12)) // muellertomcovariance muellertopoldegandpower
+    {
+      if (!inf)
+        otbAppLogFATAL(<< "Parameter 'inf' not set.");
+    }
+
+
+    switch (GetParameterInt("conv"))
+    {
+
+      //***************************************
+      //*             MONOSTATIC              *
+      //***************************************
+
+    case 0: // SinclairToReciprocalCoherency
+      m_RCohSRFilter = RCohSRFilterType::New();
+
+      if (inhv)
+        m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
+      else if (invh)
+        m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
+
+      m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput()); // input: 3 x 1 complex channel | output :  6 complex channels
+
+      break;
+
+
+    case 1: // SinclairToReciprocalCovariance
+
+      m_RCovSRFilter = RCovSRFilterType::New();
+
+      if (inhv)
+        m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
+      else if (invh)
+        m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
+
+      m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput()); // input: 3 x 1 complex channel | output :  6 complex channels
+
+      break;
+
+
+    case 2: // SinclairToReciprocalCircularCovariance
+
+      m_RCCSRFilter = RCCSRFilterType::New();
+
+      if (inhv)
+        m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
+      else if (invh)
+        m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
+
+      m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput()); // input: 3 x 1 complex channel | output :  6 complex channels
+
+      break;
+
+
+    case 3: // ReciprocalCoherencyToReciprocalMuellerImageFilter
+
+      m_RCRMFilter = RCRMFilterType::New();
+      m_RCRMFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
+
+      SetParameterOutputImage("outf", m_RCRMFilter->GetOutput()); // input: 6 complex channels | 16 real channels
+
+      break;
+
+
+    case 4: // ReciprocalCovarianceToCoherencyDegreeImageFilter
+
+      m_RCCDFilter = RCCDFilterType::New();
+      m_RCCDFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
+
+      SetParameterOutputImage("outc", m_RCCDFilter->GetOutput()); // input: 6 complex channels | 3 complex channels
+
+      break;
+
+
+    case 5: // ReciprocalCovarianceToReciprocalCoherencyImageFilter
+
+      m_RCRCFilter = RCRCFilterType::New();
+      m_RCRCFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
+
+      SetParameterOutputImage("outc", m_RCRCFilter->GetOutput()); // input: 6 complex channels | 6 complex channels
+
+      break;
+
+
+    case 6: // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
+
+      m_RLCRCCFilter = RLCRCCFilterType::New();
+      m_RLCRCCFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
+
+      SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput()); // input: 6 complex channels | output : 6 complex channels
+
+      break;
+
+
+    case 7: // MuellerToReciprocalCovarianceImageFilter
+
+      m_MRCFilter = MRCFilterType::New();
+
+      m_MRCFilter->SetVariadicInput<0>(GetParameterDoubleVectorImage("inf"));
+
+      SetParameterOutputImage("outc", m_MRCFilter->GetOutput()); // input: 16 real channels | output : 6 complex channels
+
+      break;
+
+
+      //***************************************
+      //*               BISTATIC              *
+      //***************************************
+
+    case 8: // SinclairToCoherency
+
+      m_CohSRFilter = CohSRFilterType::New();
+      m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
+      m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
+      m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      SetParameterOutputImage("outc", m_CohSRFilter->GetOutput()); // input: 4 x 1 complex channel | 10 complex channels
+
+      break;
+
+
+    case 9: // SinclairToCovariance
+
+      m_CovSRFilter = CovSRFilterType::New();
+      m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
+      m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
+      m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      SetParameterOutputImage("outc", m_CovSRFilter->GetOutput()); // input: 4 x 1 complex channel | output : 10 complex channels
+
+      break;
+
+
+    case 10: // SinclairToCircularCovariance
+
+      m_CCSRFilter = CCSRFilterType::New();
+      m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
+      m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
+      m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      SetParameterOutputImage("outc", m_CCSRFilter->GetOutput()); // input: 4 x 1 complex channel | output : 10 complex channels
+
+      break;
+
+
+      //***************************************
+      //*             BOTH CASES              *
+      //***************************************
+
+
+    case 11: // SinclairToMueller
+      m_MSRFilter = MSRFilterType::New();
+
+      m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
+      m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
+      m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
+      m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
+
+      SetParameterOutputImage("outf", m_MSRFilter->GetOutput()); // input: 4 x 1 complex channel | output : 16 real channels
+
+      break;
+
+
+    case 12: // MuellerToPolarisationDegreeAndPowerImageFilter
+      m_MPDPFilter = MPDPFilterType::New();
+
+      m_MPDPFilter->SetVariadicInput<0>(GetParameterDoubleVectorImage("inf"));
+
+      SetParameterOutputImage("outf", m_MPDPFilter->GetOutput()); //  input: 16 real channels | output : 4 real channels
+
+      break;
+    }
   }
 
-  //Monostatic
+  // Monostatic
   RCohSRFilterType::Pointer m_RCohSRFilter;
   RCovSRFilterType::Pointer m_RCovSRFilter;
   RCCSRFilterType::Pointer  m_RCCSRFilter;
@@ -690,24 +572,19 @@ private:
   RCCDFilterType::Pointer   m_RCCDFilter;
   RCRCFilterType::Pointer   m_RCRCFilter;
   RLCRCCFilterType::Pointer m_RLCRCCFilter;
-  
-  //Bistatic
+
+  // Bistatic
   CohSRFilterType::Pointer m_CohSRFilter;
   CovSRFilterType::Pointer m_CovSRFilter;
   CCSRFilterType::Pointer  m_CCSRFilter;
   MSRFilterType::Pointer   m_MSRFilter;
-  
-  //Both cases
-  MRCFilterType::Pointer   m_MRCFilter;
-  MPDPFilterType::Pointer  m_MPDPFilter;
-  
-
-
 
-  
-}; 
+  // Both cases
+  MRCFilterType::Pointer  m_MRCFilter;
+  MPDPFilterType::Pointer m_MPDPFilter;
+};
 
-} //end namespace Wrapper
-} //end namespace otb
+} // end namespace Wrapper
+} // end namespace otb
 
 OTB_APPLICATION_EXPORT(otb::Wrapper::SARPolarMatrixConvert)
diff --git a/Modules/Filtering/Polarimetry/include/otbMuellerToPolarisationDegreeAndPowerImageFilter.h b/Modules/Filtering/Polarimetry/include/otbMuellerToPolarisationDegreeAndPowerImageFilter.h
index dabc7bc88db3843ad9a8ee88b0cf41b1a57d9041..855acade533bf0611c654a1cee7862647bfeb615 100644
--- a/Modules/Filtering/Polarimetry/include/otbMuellerToPolarisationDegreeAndPowerImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbMuellerToPolarisationDegreeAndPowerImageFilter.h
@@ -22,12 +22,13 @@
 #ifndef otbMuellerToPolarisationDegreeAndPowerImageFilter_h
 #define otbMuellerToPolarisationDegreeAndPowerImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
 #include "itkNumericTraits.h"
 #include "itkMatrix.h"
 #include "itkVector.h"
 #include "otbMath.h"
 
+#include "otbFunctorImageFilter.h"
+
 namespace otb
  {
 
@@ -67,6 +68,8 @@ namespace Functor {
  * - channel #2 : \f$ DegP_{min} \f$
  * - channel #3 : \f$ DegP_{max} \f$
  *
+ * Use otb::MuellerToPolarisationDegreeAndPowerImageFilter to apply
+ *
  * \ingroup Functor
  * \ingroup SARPolarimetry
  *
@@ -84,8 +87,8 @@ public:
   typedef itk::Matrix<double, 4, 4>                 MuellerMatrixType;
   typedef itk::Vector<double, 4>                   StokesVectorType;
 
-  inline TOutput operator()( const TInput & Mueller ) const
-    {
+  inline void operator()(TOutput& result, const TInput& Mueller) const
+  {
     double P;
     double deg_pol;
     double tau;
@@ -98,9 +101,6 @@ public:
     double l_PolarisationDegreeMin(itk::NumericTraits<double>::max());
     double l_PolarisationDegreeMax(itk::NumericTraits<double>::min());
 
-     TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
     MuellerMatrixType muellerMatrix;
     muellerMatrix[0][0] = Mueller[0];
     muellerMatrix[0][1] = Mueller[1];
@@ -172,70 +172,35 @@ public:
     result[1] = l_PowerMax;
     result[2] = l_PolarisationDegreeMin;
     result[3] = l_PolarisationDegreeMax;
-
-
-    return result;
     }
 
-  unsigned int GetOutputSize()
-  {
-    return m_NumberOfComponentsPerPixel;
+    constexpr size_t OutputSize(...) const
+    {
+      // Size of the result
+      return 4;
   }
-
-   /** Constructor */
-   MuellerToPolarisationDegreeAndPowerFunctor() : m_NumberOfComponentsPerPixel(4), m_Epsilon(1e-6), m_PI_90(2*CONST_PI_180) {}
-
-   /** Destructor */
-   virtual ~MuellerToPolarisationDegreeAndPowerFunctor() {}
-
 private:
-    unsigned int m_NumberOfComponentsPerPixel;
-    const double m_Epsilon;
-    const double m_PI_90;
+  static constexpr double m_Epsilon = 1e-6;
+  static constexpr double m_PI_90   = 2 * CONST_PI_180;
 };
-}
+} // namespace Functor
 
-
-/** \class otbMuellerToPolarisationDegreeAndPowerImageFilter
- * \brief Compute the polarization degree and power (4 channels : Power min and max, Polarization degree min and max)
- * from the Mueller image (16 real channels)
- * For more details, please refer to the class MuellerToPolarisationDegreeAndPowerFunctor.
- *
- * \ingroup SARPolarimetry
- * \sa MuellerToPolarisationDegreeAndPowerFunctor
+/**
+ * \typedef MuellerToPolarisationDegreeAndPowerImageFilter
+ * \brief Applies otb::Functor::MuellerToPolarisationDegreeAndPowerFunctor
+ * \sa otb::Functor::MuellerToPolarisationDegreeAndPowerFunctor
  *
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT MuellerToPolarisationDegreeAndPowerImageFilter :
-   public UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::MuellerToPolarisationDegreeAndPowerFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef MuellerToPolarisationDegreeAndPowerImageFilter  Self;
-  typedef typename Functor::MuellerToPolarisationDegreeAndPowerFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
+template <typename TInputImage, typename TOutputImage>
+using MuellerToPolarisationDegreeAndPowerImageFilter =
+    FunctorImageFilter<Functor::MuellerToPolarisationDegreeAndPowerFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 
-   /** Runtime information support. */
-   itkTypeMacro(MuellerToPolarisationDegreeAndPowerImageFilter, UnaryFunctorImageFilter);
-
-
-protected:
-   MuellerToPolarisationDegreeAndPowerImageFilter() {}
-  ~MuellerToPolarisationDegreeAndPowerImageFilter() override {}
-
-private:
-  MuellerToPolarisationDegreeAndPowerImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-};
 
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h b/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h
index 6e078f7cb57e688a0d37c0d28c5f363383b53b9d..31a7adf1d7ec8dd6fb627e4574f7c1595e4262e8 100644
--- a/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbMuellerToReciprocalCovarianceImageFilter.h
@@ -22,7 +22,7 @@
 #ifndef otbMuellerToReciprocalCovarianceImageFilter_h
 #define otbMuellerToReciprocalCovarianceImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
+#include "otbFunctorImageFilter.h"
 
 namespace otb
  {
@@ -54,6 +54,8 @@ namespace Functor {
  * The output image has 6 channels : the diagonal and the upper element of the reciprocal matrix.
  * Element are stored from left to right, line by line.
  *
+ * Use otb::MuellerToReciprocalCovarianceImageFilter to apply
+ *
  * \ingroup Functor
  * \ingroup SARPolarimetry
  *
@@ -71,12 +73,8 @@ public:
   typedef std::complex<double>                      ComplexType;
   typedef typename TOutput::ValueType               OutputValueType;
 
-
-  inline TOutput operator()( const TInput & Mueller ) const
+  inline void operator()(TOutput& result, const TInput& Mueller) const
   {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
     // Keep the upper diagonal of the matrix
     const double M11 =  static_cast<double>(Mueller[0]);
     const double M12 =  static_cast<double>(Mueller[1]);
@@ -89,7 +87,7 @@ public:
     const double M34 =  static_cast<double>(Mueller[11]);
     const double M44 =  static_cast<double>(Mueller[15]);
 
-    
+
     const ComplexType A(0.5*(M11+M22+2*M12));
     const ComplexType B(0.5*std::sqrt(2.0)*(M13+M23), 0.5*std::sqrt(2.0)*(M14+M24));
     const ComplexType C(-0.5*(M33+M44), -M34);
@@ -103,67 +101,32 @@ public:
     result[3] = static_cast<OutputValueType>( E );
     result[4] = static_cast<OutputValueType>( F );
     result[5] = static_cast<OutputValueType>( I );
-
-    return result;
   }
 
-  unsigned int GetOutputSize()
-    {
-     return m_NumberOfComponentsPerPixel;
-    }
-
-  /** Constructor */
-  MuellerToReciprocalCovarianceFunctor() : m_NumberOfComponentsPerPixel(6)  {}
-
-  /** Destructor */
-  virtual ~MuellerToReciprocalCovarianceFunctor() {}
-
- private:
-  unsigned int m_NumberOfComponentsPerPixel;
+  constexpr size_t OutputSize(...) const
+  {
+    // Size of the result
+    return 6;
+  }
 };
-}
+} // namespace Functor
 
-
-/** \class otbMuellerToReciprocalCovarianceImageFilter
- * \brief Compute the MLC  image
- * from the Mueller image (16 real channels)
- * For more details, lease refer to the class MuellerToReciprocalCovarianceFunctor.
- *
- * \ingroup SARPolarimetry
- * \sa MuellerToReciprocalCovarianceFunctor
+/**
+ * \typedef MuellerToReciprocalCovarianceImageFilter
+ * \brief Applies otb::Functor::MuellerToReciprocalCovarianceFunctor
+ * \sa otb::Functor::MuellerToReciprocalCovarianceFunctor
  *
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT MuellerToReciprocalCovarianceImageFilter :
-   public UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::MuellerToReciprocalCovarianceFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef MuellerToReciprocalCovarianceImageFilter  Self;
-   typedef Functor::MuellerToReciprocalCovarianceFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
+template <typename TInputImage, typename TOutputImage>
+using MuellerToReciprocalCovarianceImageFilter =
+    FunctorImageFilter<Functor::MuellerToReciprocalCovarianceFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(MuellerToReciprocalCovarianceImageFilter, UnaryFunctorImageFilter);
-
-
-protected:
-   MuellerToReciprocalCovarianceImageFilter() {}
-  ~MuellerToReciprocalCovarianceImageFilter() override {}
-
-private:
-  MuellerToReciprocalCovarianceImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-};
 
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbPolarimetryTags.h b/Modules/Filtering/Polarimetry/include/otbPolarimetryTags.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d82b22961981588f16d25b95e131bed6b676ab8
--- /dev/null
+++ b/Modules/Filtering/Polarimetry/include/otbPolarimetryTags.h
@@ -0,0 +1,46 @@
+/*
+ * 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 otbPolarimetryTags_h
+#define otbPolarimetryTags_h
+
+namespace otb
+{
+namespace polarimetry_tags
+{
+struct hh
+{
+};
+struct hv
+{
+};
+struct vh
+{
+};
+struct vv
+{
+};
+struct hv_or_vh
+{
+};
+} // end namespace polarimetry_tags
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalBarnesDecompImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalBarnesDecompImageFilter.h
index 2e584c720344e8d0ffe1c1ad76f8f4373ba3f26a..fcf02e08ee9e7ea98199fa40001761461fd02f7a 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalBarnesDecompImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalBarnesDecompImageFilter.h
@@ -22,20 +22,23 @@
 #ifndef otbReciprocalBarnesDecompImageFilter_h
 #define otbReciprocalBarnesDecompImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
 #include "otbMath.h"
 #include "vnl/algo/vnl_complex_eigensystem.h"
 #include <algorithm>
 
+#include "otbFunctorImageFilter.h"
+
 namespace otb
  {
 
 namespace Functor {
 
 /** \class otbBarnesDecompFunctor
- * 
+ *
  * \brief Evaluate the Huynen decomposition from the reciprocal Sinclair matrix image.
  *
+ * Use otb::BarnesDecompImageFilter to apply
+ *
  * \ingroup OTBPolarimetry
  */
 template< class TInput, class TOutput>
@@ -49,14 +52,11 @@ public:
   typedef std::vector<double>           VectorType;
   typedef typename TOutput::ValueType   OutputValueType;
 
+  inline void operator()(TOutput& result, const TInput& Covariance) const
+  {
+
+    VNLMatrixType qi(3, 1);
 
-  inline TOutput operator()( const TInput & Covariance ) const
-    {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-    
-	VNLMatrixType qi(3,1);
-	
 
     VNLMatrixType cov(3, 3);
     cov[0][0] = ComplexType(Covariance[0]);
@@ -70,95 +70,62 @@ public:
     cov[2][2] = ComplexType(Covariance[5]);
 
 
-	qi[0][0]=ComplexType(1.,0.);
-	qi[1][0]=ComplexType(0.,0.);
-	qi[2][0]=ComplexType(0.,0.);
-	ComplexType norm =  (qi.conjugate_transpose()*cov*qi)[0][0];
-	VNLMatrixType ki = cov*qi / std::sqrt(norm);
+    qi[0][0]           = ComplexType(1., 0.);
+    qi[1][0]           = ComplexType(0., 0.);
+    qi[2][0]           = ComplexType(0., 0.);
+    ComplexType   norm = (qi.conjugate_transpose() * cov * qi)[0][0];
+    VNLMatrixType ki   = cov * qi / std::sqrt(norm);
     result[0] = static_cast<OutputValueType>(ki[0][0]);
     result[1] = static_cast<OutputValueType>(ki[1][0]);
     result[2] = static_cast<OutputValueType>(ki[2][0]);
-    
-    
-	qi[0][0]=ComplexType(0.,0.);
-	qi[1][0]=ComplexType(1./std::sqrt(2.),0.);
-	qi[2][0]=ComplexType(0.,1./std::sqrt(2.));
-	norm =  (qi.conjugate_transpose()*cov*qi)[0][0];
-	ki = cov*qi / std::sqrt(norm);
+
+
+    qi[0][0]  = ComplexType(0., 0.);
+    qi[1][0]  = ComplexType(1. / std::sqrt(2.), 0.);
+    qi[2][0]  = ComplexType(0., 1. / std::sqrt(2.));
+    norm      = (qi.conjugate_transpose() * cov * qi)[0][0];
+    ki        = cov * qi / std::sqrt(norm);
     result[3] = static_cast<OutputValueType>(ki[0][0]);
     result[4] = static_cast<OutputValueType>(ki[1][0]);
     result[5] = static_cast<OutputValueType>(ki[2][0]);
-    
-    
+
+
     qi[0][0]=ComplexType(0.,0.);
-	qi[1][0]=ComplexType(0.,1./std::sqrt(2.));
-	qi[2][0]=ComplexType(1./std::sqrt(2.),0.);
-	norm =  (qi.conjugate_transpose()*cov*qi)[0][0];
-	ki = cov*qi / std::sqrt(norm);
+    qi[1][0]  = ComplexType(0., 1. / std::sqrt(2.));
+    qi[2][0]  = ComplexType(1. / std::sqrt(2.), 0.);
+    norm      = (qi.conjugate_transpose() * cov * qi)[0][0];
+    ki        = cov * qi / std::sqrt(norm);
     result[6] = static_cast<OutputValueType>(ki[0][0]);
     result[7] = static_cast<OutputValueType>(ki[1][0]);
     result[8] = static_cast<OutputValueType>(ki[2][0]);
+  }
 
-    return result;
-    }
-
-   unsigned int GetOutputSize()
-   {
-     return m_NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalBarnesDecompFunctor() : m_Epsilon(1e-6) {}
-
-   /** Destructor */
-   virtual ~ReciprocalBarnesDecompFunctor() {}
+  constexpr size_t OutputSize(...) const
+  {
+    // Size of the result
+    return 9;
+  }
 
 private:
-   itkStaticConstMacro(m_NumberOfComponentsPerPixel, unsigned int, 9);
-   const double m_Epsilon;
+  static constexpr double m_Epsilon = 1e-6;
 };
-}
+} // namespace Functor
 
-
-/** \class otbBarnesDecompImageFilter
- * \brief Compute the Barnes decomposition image (9 complex channels)
- * from the Reciprocal Covariance image (6 complex channels)
+/**
+ * \typedef ReciprocalBarnesDecompImageFilter
+ * \brief Applies otb::Functor::ReciprocalBarnesDecompFunctor
+ * \sa otb::Functor::ReciprocalBarnesDecompFunctor
  *
- * For more details, please refer to the class ReciprocalBarnesDecompFunctor.
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
- * \sa ReciprocalBarnesDecompFunctor
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalBarnesDecompImageFilter :
-   public otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalBarnesDecompFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalBarnesDecompImageFilter  Self;
-   typedef typename Functor::ReciprocalBarnesDecompFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalBarnesDecompImageFilter, UnaryFunctorImageFilter);
-
-protected:
-   ReciprocalBarnesDecompImageFilter() {}
-  ~ReciprocalBarnesDecompImageFilter() override {}
-
-private:
-  ReciprocalBarnesDecompImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-};
-
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalBarnesDecompImageFilter =
+    FunctorImageFilter<Functor::ReciprocalBarnesDecompFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 } // end namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h
index 315239c7d643c1cd044541d05c8c0501e186e7ef..2a7e947801096d0b68907b8cca3ca843bbb45de8 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalCoherencyToReciprocalMuellerImageFilter.h
@@ -22,7 +22,7 @@
 #ifndef otbReciprocalCoherencyToReciprocalMuellerImageFilter_h
 #define otbReciprocalCoherencyToReciprocalMuellerImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
+#include "otbFunctorImageFilter.h"
 
 namespace otb
  {
@@ -51,9 +51,9 @@ namespace Functor {
  * - channel #15 : \f$ 0.5.Re(VAL0) \f$
  *
  * With:
- * VAL0 = C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*}   
- * VAL1 = -C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*} 
- * 
+ * VAL0 = C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*}
+ * VAL1 = -C_{33}+C_{12}-C_{11}-(C_{12}-C_{22})^{*}
+ *
  * Where Coherency is the input pixel and contains:
  * - channel #0 : \f$ 0.5*(S_{hh}+S_{vv}).(S_{hh}+S_{vv})^{*} \f$
  * - channel #1 : \f$ 0.5*(S_{hh}+S_{vv}).(S_{hh}-S_{vv})^{*} \f$
@@ -65,6 +65,9 @@ namespace Functor {
  * The output pixel has 16 channels
  * Element are stored from left to right, line by line.
  *
+ *  Use otb::ReciprocalCoherencyToReciprocalMuellerImageFilter to apply
+ *  it to an image.
+ *
  * \ingroup SARPolarimetry
  *
  *
@@ -77,100 +80,58 @@ public:
   typedef typename std::complex <double>         ComplexType;
   typedef typename TOutput::ValueType              OutputValueType;
 
-  inline TOutput operator()( const TInput & Coherency ) const
-    {
-    TOutput result;
-    result.SetSize(NumberOfComponentsPerPixel);
-
+  inline void operator()(TOutput& result, const TInput& Coherency) const
+  {
     const double T1 = static_cast<double>(Coherency[0].real());
     const double T2 = static_cast<double>(Coherency[3].real());
     const double T3 = static_cast<double>(Coherency[5].real());
-    
+
     ComplexType VAL4 = static_cast<ComplexType>( (Coherency[1] - Coherency[3]) );
     ComplexType VAL5 = static_cast<ComplexType>( (Coherency[1] - Coherency[0]) );
-	ComplexType VAL0 = static_cast<ComplexType>( Coherency[5] ) + VAL5 - std::conj(VAL4);
+    ComplexType VAL0 = static_cast<ComplexType>(Coherency[5]) + VAL5 - std::conj(VAL4);
     ComplexType VAL1 = static_cast<ComplexType>( -Coherency[5] ) + VAL5 - std::conj(VAL4);
 
-    result[0] = 0.5*(T1+T2+T3);                               
+    result[0]  = 0.5 * (T1 + T2 + T3);
     result[1] = static_cast<double>( Coherency[1].real()+Coherency[3].imag() );
-    result[2] = static_cast<double>( Coherency[2].real() );   
-    result[3] = static_cast<double>( Coherency[4].imag() );                           
-    result[4] = static_cast<double>( Coherency[1].real() );  
-    result[5] = 0.5*(T1+T2-T3); 
+    result[2]  = static_cast<double>(Coherency[2].real());
+    result[3]  = static_cast<double>(Coherency[4].imag());
+    result[4]  = static_cast<double>(Coherency[1].real());
+    result[5]  = 0.5 * (T1 + T2 - T3);
     result[6] = static_cast<double>( Coherency[4].real() );
-    result[7] = static_cast<double>( Coherency[2].imag() ); 
+    result[7]  = static_cast<double>(Coherency[2].imag());
     result[8] = static_cast<double>( -Coherency[2].real() );
     result[9] = static_cast<double>( -Coherency[4].real() );
-	result[10] = static_cast<double>( 0.5*VAL1.real() ); 
-	result[11] = static_cast<double>( 0.5*VAL0.imag() ); 
-	result[12] = static_cast<double>( Coherency[4].imag() ); 
-	result[13] = static_cast<double>( Coherency[2].imag() );
-	result[14] = static_cast<double>( 0.5*std::conj(VAL1).imag() ); 
-	result[15] = static_cast<double>( 0.5*VAL0.real() ); 
-
-    return result;
-    }
-
-   unsigned int GetOutputSize()
-   {
-     return NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalCoherencyToReciprocalMuellerFunctor() {}
-
-   /** Destructor */
-   virtual ~ReciprocalCoherencyToReciprocalMuellerFunctor() {}
-
-private:
-   itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 16);
+    result[10] = static_cast<double>(0.5 * VAL1.real());
+    result[11] = static_cast<double>(0.5 * VAL0.imag());
+    result[12] = static_cast<double>(Coherency[4].imag());
+    result[13] = static_cast<double>(Coherency[2].imag());
+    result[14] = static_cast<double>(0.5 * std::conj(VAL1).imag());
+    result[15] = static_cast<double>(0.5 * VAL0.real());
+  }
+
+  constexpr size_t OutputSize(...) const
+  {
+    // Size of the reciprocal mueller matrix
+    return 16;
+  }
 };
-}
+} // namespace Functor
 
-
-/** \class otbReciprocalCoherencyToReciprocalMuellerImageFilter
- * \brief Compute the reciprocal Mueller matrix image (10 real channels)
- * from the Reciprocal coherency image (6 complex channels)
- *
- * For more datails, please refer to ReciprocalCoherencyToReciprocalMuellerFunctor.
- *
- * \ingroup SARPolarimetry
- * \sa ReciprocalCoherencyToReciprocalMuellerFunctor
+/**
+ * \typedef ReciprocalCoherencyToReciprocalMuellerImageFilter
+ * \brief Applies otb::Functor::ReciprocalCoherencyToReciprocalMuellerFunctor
+ * \sa otb::Functor::ReciprocalCoherencyToReciprocalMuellerFunctor
  *
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalCoherencyToReciprocalMuellerImageFilter :
-   public UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalCoherencyToReciprocalMuellerFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalCoherencyToReciprocalMuellerImageFilter  Self;
-   typedef typename Functor::ReciprocalCoherencyToReciprocalMuellerFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalCoherencyToReciprocalMuellerImageFilter, UnaryFunctorImageFilter);
-
-
-protected:
-   ReciprocalCoherencyToReciprocalMuellerImageFilter() {}
-  ~ReciprocalCoherencyToReciprocalMuellerImageFilter() override {}
-
-
-private:
-  ReciprocalCoherencyToReciprocalMuellerImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-};
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalCoherencyToReciprocalMuellerImageFilter =
+    FunctorImageFilter<Functor::ReciprocalCoherencyToReciprocalMuellerFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToCoherencyDegreeImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToCoherencyDegreeImageFilter.h
index 9e559850bc52e064e045e50afd33755689ea168d..b0ada3fd7076b25a55cbfb5be2eebf96e6b0f3c9 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToCoherencyDegreeImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToCoherencyDegreeImageFilter.h
@@ -22,7 +22,7 @@
 #ifndef otbReciprocalCovarianceToCoherencyDegreeImageFilter_h
 #define otbReciprocalCovarianceToCoherencyDegreeImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
+#include "otbFunctorImageFilter.h"
 
 namespace otb
  {
@@ -56,12 +56,8 @@ public:
   typedef typename std::complex <double>           ComplexType;
   typedef typename TOutput::ValueType              OutputValueType;
 
-  inline TOutput operator()( const TInput & Covariance ) const
-    {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-    result.Fill(0.0);
-
+  inline void operator()(TOutput& result, const TInput& Covariance) const
+  {
     /* Using the convention
      * \f$ C_{11} = S_{hh}*S_{hh}^* \f$
      * \f$ C_{12} = S_{hh}*S_{hv}^* \f$
@@ -91,71 +87,34 @@ public:
       {
       result[2] = std::abs(C12) / std::sqrt(C11 * C22);  // |<hh.hv*|/sqrt(<hh.hh*><hv.hv*>)
       }
-
-    return result;
     }
 
-   unsigned int GetOutputSize()
-   {
-     return m_NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalCovarianceToCoherencyDegreeFunctor() : m_NumberOfComponentsPerPixel(3), m_Epsilon(1e-6) {}
-
-   /** Destructor */
-   virtual ~ReciprocalCovarianceToCoherencyDegreeFunctor() {}
+    constexpr size_t OutputSize(...) const
+    {
+      // Size of the result
+      return 3;
+    }
 
-private:
-    unsigned int m_NumberOfComponentsPerPixel;
-    const double m_Epsilon;
+  private:
+    static constexpr double m_Epsilon = 1e-6;
 };
-}
-
+} // namespace Functor
 
-/** \class otbReciprocalCovarianceToCoherencyDegreeImageFilter
- * \brief Compute the Coherency Degree coefficient
- * from the MLC image (6 complex channels)
- * For more details, lease refer to the class ReciprocalCovarianceToCoherencyDegreeFunctor.
- *
- * \ingroup SARPolarimetry
- * \sa ReciprocalCovarianceToCoherencyDegreeFunctor
+/**
+ * \typedef ReciprocalCovarianceToCoherencyDegreeImageFilter
+ * \brief Applies otb::Functor::ReciprocalCovarianceToCoherencyDegreeFunctor
+ * \sa otb::Functor::ReciprocalCovarianceToCoherencyDegreeFunctor
  *
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalCovarianceToCoherencyDegreeImageFilter :
-   public UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalCovarianceToCoherencyDegreeFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalCovarianceToCoherencyDegreeImageFilter  Self;
-   typedef typename Functor::ReciprocalCovarianceToCoherencyDegreeFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalCovarianceToCoherencyDegreeImageFilter, UnaryFunctorImageFilter);
-
-
-protected:
-  ReciprocalCovarianceToCoherencyDegreeImageFilter() {}
-  ~ReciprocalCovarianceToCoherencyDegreeImageFilter() override {}
-
-private:
-  ReciprocalCovarianceToCoherencyDegreeImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-
-};
-
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalCovarianceToCoherencyDegreeImageFilter =
+    FunctorImageFilter<Functor::ReciprocalCovarianceToCoherencyDegreeFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 } // end namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h
index c5cff9de09cfa45e2ce9cfa161b475f953b1ff7c..663c6faed62bfd5be00f491dcf9f9c282e8d2b8e 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.h
@@ -22,7 +22,7 @@
 #ifndef otbReciprocalCovarianceToReciprocalCoherencyImageFilter_h
 #define otbReciprocalCovarianceToReciprocalCoherencyImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
+#include "otbFunctorImageFilter.h"
 
 namespace otb
  {
@@ -46,6 +46,9 @@ namespace Functor {
  * \ingroup Functor
  * \ingroup SARPolarimetry
  *
+ * Use otbReciprocalCovarianceToReciprocalCoherencyImageFilter to apply
+ * it to an image.
+ *
  * \sa CovarianceToCircularCoherencyDegreeImageFilter
  * \sa ReciprocalCovarianceToReciprocalCoherencyDegreeImageFilter
  *
@@ -59,22 +62,18 @@ public:
   typedef typename std::complex <double>           ComplexType;
   typedef typename TOutput::ValueType              OutputValueType;
 
-  inline TOutput operator()( const TInput & Covariance ) const
-    {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
-   
+  inline void operator()(TOutput& result, const TInput& Covariance) const
+  {
     const ComplexType C11 =  static_cast<ComplexType>(Covariance[0]);
     const ComplexType C12 =  static_cast<ComplexType>(Covariance[1]);
     const ComplexType C13 =  static_cast<ComplexType>(Covariance[2]);
     const ComplexType C22 =  static_cast<ComplexType>(Covariance[3]);
     const ComplexType C23 =  static_cast<ComplexType>(Covariance[4]);
     const ComplexType C33 =  static_cast<ComplexType>(Covariance[5]);
-    
+
     const ComplexType two = ComplexType(2.0, 0.0);
     const ComplexType rootTwo = ComplexType(std::sqrt(2.0), 0.0);
-    
+
     result[0] = static_cast<OutputValueType>( C33 + C13 + std::conj(C13) + C11 );
     result[1] = static_cast<OutputValueType>( -C33 - C13 + std::conj(C13) + C11 );
     result[2] = static_cast<OutputValueType>( rootTwo*C12 + rootTwo*std::conj(C23) );
@@ -83,69 +82,31 @@ public:
     result[5] = static_cast<OutputValueType>( two * C22 );
 
     result /= 2.0;
-
-    return result;
     }
 
-   unsigned int GetOutputSize()
-   {
-     return m_NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalCovarianceToReciprocalCoherencyFunctor() : m_NumberOfComponentsPerPixel(6)  {}
-
-   /** Destructor */
-   virtual ~ReciprocalCovarianceToReciprocalCoherencyFunctor() {}
-
-private:
-    unsigned int m_NumberOfComponentsPerPixel;
+    constexpr size_t OutputSize(...) const
+    {
+      // Size of the result
+      return 6;
+    }
 };
-}
-
+} // namespace Functor
 
-/** \class otbReciprocalCovarianceToReciprocalCoherencyImageFilter
- * \brief Compute the Coherency image (6 complex channels)
- * from the Covariance image (6 complex channels)
+/**
+ * \typedef ReciprocalCovarianceToReciprocalCoherencyImageFilter
+ * \brief Applies ReciprocalCovarianceToReciprocalCoherencyFunctor
+ * \sa ReciprocalCovarianceToReciprocalCoherencyFunctor
  *
- * For more details, please refer to the class ReciprocalCovarianceToReciprocalCoherencyFunctor.
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
- * \ingroup SARPolarimetry
- * \sa ReciprocalCovarianceToReciprocalCoherencyFunctor
  *
- * \ingroup OTBPolarimetry
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalCovarianceToReciprocalCoherencyImageFilter :
-   public UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalCovarianceToReciprocalCoherencyFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalCovarianceToReciprocalCoherencyImageFilter  Self;
-   typedef Functor::ReciprocalCovarianceToReciprocalCoherencyFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctorType;
-   typedef UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctorType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalCovarianceToReciprocalCoherencyImageFilter, UnaryFunctorImageFilter);
-
-
-protected:
-  ReciprocalCovarianceToReciprocalCoherencyImageFilter() {}
-  ~ReciprocalCovarianceToReciprocalCoherencyImageFilter() override {}
-
-private:
-  ReciprocalCovarianceToReciprocalCoherencyImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-
-};
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalCovarianceToReciprocalCoherencyImageFilter =
+    FunctorImageFilter<Functor::ReciprocalCovarianceToReciprocalCoherencyFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h
index 04c7035f9315a6ea6a314b16b8aed9599bfa6c09..d716753e31c9481b16679e267f8da596dee3c9e1 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalHAlphaImageFilter.h
@@ -22,10 +22,13 @@
 #ifndef otbReciprocalHAlphaImageFilter_h
 #define otbReciprocalHAlphaImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
 #include "otbMath.h"
 #include "vnl/algo/vnl_complex_eigensystem.h"
 #include <algorithm>
+#include <vector>
+#include <complex>
+
+#include "otbFunctorImageFilter.h"
 
 namespace otb
  {
@@ -39,6 +42,8 @@ namespace Functor {
  * eigen values of the matrix sorted in decrease order. \f$ SortedEigenVector \f$ the corresponding list
  * of eigen vector.
  *
+ * Use otb::ReciprocalHAlphaImageFilter to apply
+ *
  * Output value are:
  * - channel #0 : \f$ entropy = -\sum_{i=0}^{2}{p[i].\log{p[i]}} / \log{3} \f$
  * - channel #1 : \f$ \alpha = \sum_{i=0}^{2}{p[i].\alpha_{i} \f$
@@ -67,11 +72,8 @@ public:
   typedef typename TOutput::ValueType   OutputValueType;
 
 
-  inline TOutput operator()( const TInput & Coherency ) const
-    {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
+  inline void operator()(TOutput& result, const TInput& Coherency) const
+  {
     const double T0 = static_cast<double>(Coherency[0].real());
     const double T1 = static_cast<double>(Coherency[3].real());
     const double T2 = static_cast<double>(Coherency[5].real());
@@ -128,11 +130,11 @@ public:
         totalEigenValues += sortedRealEigenValues[k];
       }
 
-      
+
     for (unsigned int k = 0; k < 3; ++k)
       {
         p[k] = sortedRealEigenValues[k] / totalEigenValues;
-        
+
         if (p[k]<m_Epsilon) //n=log(n)-->0 when n-->0
 			plog[k]=0.0;
 		else
@@ -162,72 +164,36 @@ public:
     // Anisotropy estimation
     anisotropy=(sortedRealEigenValues[1] - sortedRealEigenValues[2])/(sortedRealEigenValues[1] + sortedRealEigenValues[2] + m_Epsilon);
 
-
     result[0] = static_cast<OutputValueType>(entropy);
     result[1] = static_cast<OutputValueType>(alpha);
     result[2] = static_cast<OutputValueType>(anisotropy);
-
-    return result;
     }
 
-   unsigned int GetOutputSize()
-   {
-     return m_NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalHAlphaFunctor() : m_Epsilon(1e-6) {}
-
-   /** Destructor */
-   virtual ~ReciprocalHAlphaFunctor() {}
+    constexpr size_t OutputSize(...) const
+    {
+      // Size of the result (entropy, alpha, anisotropy)
+      return 3;
+    }
 
-private:
-   itkStaticConstMacro(m_NumberOfComponentsPerPixel, unsigned int, 3);
-   const double m_Epsilon;
+  private:
+    static constexpr double m_Epsilon = 1e-6;
 };
-}
+} // namespace Functor
 
-
-/** \class otbHAlphaImageFilter
- * \brief Compute the H-Alpha image (3 channels)
- * from the Reciprocal coherency image (6 complex channels)
+/**
+ * \typedef ReciprocalHAlphaImageFilter
+ * \brief Applies otb::Functor::ReciprocalHAlphaFunctor
+ * \sa otb::Functor::ReciprocalHAlphaFunctor
  *
- * For more details, please refer to the class ReciprocalHAlphaFunctor.
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
- * \sa ReciprocalHAlphaFunctor
- *
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalHAlphaImageFilter :
-   public otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalHAlphaFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalHAlphaImageFilter  Self;
-   typedef typename Functor::ReciprocalHAlphaFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalHAlphaImageFilter, UnaryFunctorImageFilter);
-
-protected:
-   ReciprocalHAlphaImageFilter() {}
-  ~ReciprocalHAlphaImageFilter() override {}
-
-private:
-  ReciprocalHAlphaImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-};
-
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalHAlphaImageFilter = FunctorImageFilter<Functor::ReciprocalHAlphaFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 } // end namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalHuynenDecompImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalHuynenDecompImageFilter.h
index 9522a3dc54f21098973ebe4552ff697faf10bb24..b92a7b53658d4109b7aa8a8b69a9ad09a4afe79f 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalHuynenDecompImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalHuynenDecompImageFilter.h
@@ -18,12 +18,10 @@
  * limitations under the License.
  */
 
-
 #ifndef otbReciprocalHuynenDecompImageFilter_h
 #define otbReciprocalHuynenDecompImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
-
+#include "otbFunctorImageFilter.h"
 
 namespace otb
  {
@@ -31,9 +29,11 @@ namespace otb
 namespace Functor {
 
 /** \class ReciprocalHuynenDecompFunctor
- * 
+ *
  * \brief Evaluate the Huynen decomposition from the reciprocal Sinclair matrix image.
  *
+ * Use otb::HuynenDecompImageFilter to apply
+ *
  * \ingroup OTBPolarimetry
  */
 template< class TInput, class TOutput>
@@ -43,12 +43,8 @@ public:
 
   typedef typename TOutput::ValueType   OutputValueType;
 
-
-  inline TOutput operator()( const TInput & Covariance ) const
-    {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-    
+  inline void operator()(TOutput& result, const TInput& Covariance) const
+  {
     OutputValueType A0 = static_cast<OutputValueType>(Covariance[0].real() / 2.0);
     OutputValueType B0 = static_cast<OutputValueType>((Covariance[3] + Covariance[5]).real() / 2.0);
     OutputValueType B = static_cast<OutputValueType>(Covariance[3].real() - B0);
@@ -58,7 +54,7 @@ public:
     OutputValueType F = static_cast<OutputValueType>(Covariance[4].imag());
     OutputValueType G = static_cast<OutputValueType>(Covariance[2].imag());
     OutputValueType H = static_cast<OutputValueType>(Covariance[2].real());
-    
+
     result[0] = A0;
     result[1] = B0;
     result[2] = B;
@@ -68,68 +64,34 @@ public:
     result[6] = F;
     result[7] = G;
     result[8] = H;
-
-    return result;
     }
 
-   unsigned int GetOutputSize()
-   {
-     return m_NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalHuynenDecompFunctor() : m_Epsilon(1e-6) {}
-
-   /** Destructor */
-   virtual ~ReciprocalHuynenDecompFunctor() {}
+    constexpr size_t OutputSize(...) const
+    {
+      // Size of the result
+      return 9;
+    }
 
-private:
-   itkStaticConstMacro(m_NumberOfComponentsPerPixel, unsigned int, 9);
-   const double m_Epsilon;
+  private:
+    static constexpr double m_Epsilon = 1e-6;
 };
-}
+} // namespace Functor
 
-
-/** \class ReciprocalHuynenDecompImageFilter
- * \brief Compute the Huynen decomposition image (9 complex channels)
- * from the Reciprocal Covariance image (6 complex channels)
+/**
+ * \typedef ReciprocalHuynenDecompImageFilter
+ * \brief Applies otb::Functor::ReciprocalHuynenDecompFunctor
+ * \sa otb::Functor::ReciprocalHuynenDecompFunctor
  *
- * For more details, please refer to the class ReciprocalHuynenDecompFunctor.
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
- * \sa ReciprocalHuynenDecompFunctor
- *
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalHuynenDecompImageFilter :
-   public otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalHuynenDecompFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalHuynenDecompImageFilter  Self;
-   typedef typename Functor::ReciprocalHuynenDecompFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalHuynenDecompImageFilter, UnaryFunctorImageFilter);
-
-protected:
-   ReciprocalHuynenDecompImageFilter() {}
-  ~ReciprocalHuynenDecompImageFilter() override {}
-
-private:
-  ReciprocalHuynenDecompImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-};
-
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalHuynenDecompImageFilter =
+    FunctorImageFilter<Functor::ReciprocalHuynenDecompFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 } // end namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h
index 6cf8ea7e2ae5fe4071ca435c273fc7d0a0bb0c28..d247d0dd01c8aa4f73467b96ebe418807158fa42 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.h
@@ -22,7 +22,7 @@
 #ifndef otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter_h
 #define otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter_h
 
-#include "itkUnaryFunctorImageFilter.h"
+#include "otbFunctorImageFilter.h"
 #include <complex>
 
 namespace otb
@@ -64,21 +64,16 @@ public:
   typedef typename std::complex <double>           ComplexType;
   typedef typename TOutput::ValueType              OutputValueType;
 
-  inline TOutput operator()( const TInput & Covariance ) const
-    {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-    result.Fill(0.0);
-    
-    
+  inline void operator()(TOutput& result, const TInput& Covariance) const
+  {
     const ComplexType C11 =  static_cast<ComplexType>(  Covariance[0]    );     //   <hh.hh*>
     const ComplexType C12 =  static_cast<ComplexType>(  Covariance[1]    );     //   <sqrt(2).hh.hv*>
     const ComplexType C13 =  static_cast<ComplexType>(  Covariance[2]    );     //   <hh.vv*>
     const ComplexType C22 =  static_cast<ComplexType>(  Covariance[3]    );     //   <2.hv.hv*>
     const ComplexType C23 =  static_cast<ComplexType>(  Covariance[4]    );     //   <sqrt(2).hv.vv*>
     const ComplexType C33 =  static_cast<ComplexType>(  Covariance[5]    );     //   <vv.vv*>
-    
-    
+
+
     const ComplexType cst1 = ComplexType(0.0, std::sqrt(2.0));
     const ComplexType two = ComplexType(2.0, 0 );
 
@@ -90,66 +85,31 @@ public:
     result[5] = static_cast<ComplexType>( C33+cst1*C23-C13-cst1*std::conj(C23)-std::conj(C13)+two*C22+cst1*C12-cst1*std::conj(C12)+C11 ) ;
 
 	result /= 4.0;
-
-    return result;
     }
 
-   unsigned int GetOutputSize()
-   {
-     return m_NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor() : m_NumberOfComponentsPerPixel(6)  {}
-
-   /** Destructor */
-   virtual ~ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor() {}
-
-private:
-    unsigned int m_NumberOfComponentsPerPixel;
+    constexpr size_t OutputSize(...) const
+    {
+      // Size of the result (entropy, alpha, anisotropy)
+      return 6;
+    }
 };
-}
-
+} // namespace Functor
 
-/** \class otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
- * \brief Compute the reciprocal Covariance circular matrix image from the reciprocal Covariance linear matrix image.
- * For more details, please refer to the class ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor.
+/**
+ * \typedef ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
+ * \brief Applies otb::Functor::ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor
+ * \sa otb::Functor::ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor
  *
- * \ingroup SARPolarimetry
- * \sa ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
  */
- template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter :
-   public itk::UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter  Self;
-   typedef typename Functor::ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef itk::UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter, itk::UnaryFunctorImageFilter);
-
-
-protected:
-  ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter() {}
-  ~ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter() override {}
-
-private:
-  ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-};
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter = FunctorImageFilter<
+    Functor::ReciprocalLinearCovarianceToReciprocalCircularCovarianceFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbReciprocalPauliDecompImageFilter.h b/Modules/Filtering/Polarimetry/include/otbReciprocalPauliDecompImageFilter.h
index 6fdd423457435481485bc1cb9f190cec1144666c..b087ac0102bd7f2bc36e6f84424faa4b61c0e446 100644
--- a/Modules/Filtering/Polarimetry/include/otbReciprocalPauliDecompImageFilter.h
+++ b/Modules/Filtering/Polarimetry/include/otbReciprocalPauliDecompImageFilter.h
@@ -22,8 +22,7 @@
 #ifndef otbReciprocalPauliDecompImageFilter_h
 #define otbReciprocalPauliDecompImageFilter_h
 
-#include "otbUnaryFunctorImageFilter.h"
-
+#include "otbFunctorImageFilter.h"
 
 namespace otb
  {
@@ -31,9 +30,11 @@ namespace otb
 namespace Functor {
 
 /** \class ReciprocalPauliDecompFunctor
- * 
+ *
  * \brief Evaluate the Pauli decomposition from the reciprocal Sinclair matrix image.
  *
+ * Use otb::PauliDecompImageFilter to apply
+ *
  * \ingroup OTBPolarimetry
  */
 template< class TInput, class TOutput>
@@ -44,82 +45,45 @@ public:
   typedef typename TInput::ValueType   InputValueType;
   typedef typename TOutput::ValueType  OutputValueType;
 
-
-  inline TOutput operator()( const TInput & Sinclair ) const
-    {
-    TOutput result;
-    result.SetSize(m_NumberOfComponentsPerPixel);
-    
+  inline void operator()(TOutput& result, const TInput& Sinclair) const
+  {
     InputValueType sqrt2(std::sqrt(2.0),0.0);
-    
+
     InputValueType Shh = static_cast<InputValueType>(Sinclair[0]);
     InputValueType Shv = static_cast<InputValueType>(Sinclair[1]);
     InputValueType Svv = static_cast<InputValueType>(Sinclair[2]);
-    
+
     result[0] = (Shh+Svv)/sqrt2;
     result[1] = (Shh-Svv)/sqrt2;
     result[2] = sqrt2*Shv;
-    
-    return result;
     }
 
-   unsigned int GetOutputSize()
-   {
-     return m_NumberOfComponentsPerPixel;
-   }
-
-   /** Constructor */
-   ReciprocalPauliDecompFunctor() : m_Epsilon(1e-6) {}
-
-   /** Destructor */
-   virtual ~ReciprocalPauliDecompFunctor() {}
+    constexpr size_t OutputSize(...) const
+    {
+      // Size of the result
+      return 3;
+    }
 
-private:
-   itkStaticConstMacro(m_NumberOfComponentsPerPixel, unsigned int, 3);
-   const double m_Epsilon;
+  private:
+    static constexpr double m_Epsilon = 1e-6;
 };
-}
+} // namespace Functor
 
-
-/** \class ReciprocalPauliDecompImageFilter
- * \brief Compute the Pauli decomposition image (3 complex channels)
- * from the Reciprocal Sinclair image (6 complex channels)
+/**
+ * \typedef ReciprocalPauliDecompImageFilter
+ * \brief Applies otb::Functor::ReciprocalPauliDecompFunctor
+ * \sa otb::Functor::ReciprocalPauliDecompFunctor
  *
- * For more details, please refer to the class ReciprocalPauliDecompFunctor.
+ * Set inputs with:
+ * \code
+ * SetVariadicInput<0>(inputPtr);
+ * \endcode
  *
  * \ingroup OTBPolarimetry
- * \sa ReciprocalPauliDecompFunctor
- *
  */
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ReciprocalPauliDecompImageFilter :
-   public otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, Functor::ReciprocalPauliDecompFunctor<
-    typename TInputImage::PixelType, typename TOutputImage::PixelType> >
-{
-public:
-   /** Standard class typedefs. */
-   typedef ReciprocalPauliDecompImageFilter  Self;
-   typedef typename Functor::ReciprocalPauliDecompFunctor<
-     typename TInputImage::PixelType, typename TOutputImage::PixelType> FunctionType;
-   typedef otb::UnaryFunctorImageFilter<TInputImage, TOutputImage, FunctionType> Superclass;
-   typedef itk::SmartPointer<Self>        Pointer;
-   typedef itk::SmartPointer<const Self>  ConstPointer;
-
-   /** Method for creation through the object factory. */
-   itkNewMacro(Self);
-
-   /** Runtime information support. */
-   itkTypeMacro(ReciprocalPauliDecompImageFilter, UnaryFunctorImageFilter);
-
-protected:
-   ReciprocalPauliDecompImageFilter() {this->SetNumberOfThreads(1);}
-  ~ReciprocalPauliDecompImageFilter() override {}
-
-private:
-  ReciprocalPauliDecompImageFilter(const Self&) = delete;
-  void operator=(const Self&) = delete;
-
-};
+template <typename TInputImage, typename TOutputImage>
+using ReciprocalPauliDecompImageFilter =
+    FunctorImageFilter<Functor::ReciprocalPauliDecompFunctor<typename TInputImage::PixelType, typename TOutputImage::PixelType>>;
 
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairImageFilter.h b/Modules/Filtering/Polarimetry/include/otbSinclairImageFilter.h
deleted file mode 100644
index b4a12784ea744b5f4dba72e2edce88616a6bf5e8..0000000000000000000000000000000000000000
--- a/Modules/Filtering/Polarimetry/include/otbSinclairImageFilter.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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 otbSinclairImageFilter_h
-#define otbSinclairImageFilter_h
-
-#include "otbQuaternaryFunctorImageFilter.h"
-#include "otbSinclairToCovarianceMatrixFunctor.h"
-#include <complex>
-
-namespace otb
-{
-
-/** \class SinclairImageFilter
- * \brief Computes the Covariance matrix for the sinclair one.
- *
- * This class is parameterized over the type of the input images and
- * the type of the output image. It is also parameterized by the
- * operation to be applied, using a Functor style.
- *
- * The output image has 10 channels : the diagonal and the upper element of the matrix.
- * Element are stored from left to right, line by line.
- *
- * The class is templated by the 4 input image (HH, HV, VH and VV) and the used functor.
- * Available functors are :
- * - SinclairToCircularCovarianceMatrixFunctor (default one)
- * - SinclairToCoherencyMatrixFunctor
- * - SinclairToCovarianceMatrixFunctor
- * - SinclairToMuelleMatrixrFunctor
- *
- *  \ingroup SARPolarimetry
- *
- *  \sa SinclairImageFilter
- *  \sa SinclairToCircularCovarianceMatrixFunctor
- *  \sa SinclairToCoherencyMatrixFunctor
- *  \sa SinclairToCovarianceMatrixFunctor
- *  \sa SinclairToMuelleMatrixrFunctor
- *
- *
- * \ingroup OTBPolarimetry
- */
-
-template <class TInputImageHH, class TInputImageHV,
-          class TInputImageVH, class TInputImageVV, class TOutputImage,
-    class TFunction = Functor::SinclairToCovarianceMatrixFunctor<
-        typename TInputImageHH::PixelType,
-        typename TInputImageHV::PixelType,
-        typename TInputImageVH::PixelType,
-        typename TInputImageVV::PixelType,
-        typename TOutputImage::PixelType> >
-class ITK_EXPORT SinclairImageFilter :  public otb::QuaternaryFunctorImageFilter<TInputImageHH,
-      TInputImageHV, TInputImageVH,
-      TInputImageVV, TOutputImage,
-      TFunction>
-{
-public:
-
-  /** Standard typedefs */
-  typedef SinclairImageFilter Self;
-  typedef otb::QuaternaryFunctorImageFilter<TInputImageHH, TInputImageHV,
-      TInputImageVH, TInputImageVV, TOutputImage, TFunction>  Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Type macro */
-  itkNewMacro(Self);
-
-  /** Creation through object factory macro */
-  itkTypeMacro(SinclairImageFilter, QuaternaryFunctorImageFilter);
-
-  /** Template parameters typedefs */
-  typedef typename Superclass::Input1ImageType     HHInputImageType;
-  typedef typename Superclass::Input1ImagePointer  HHInputImagePointer;
-  typedef typename Superclass::Input2ImageType     HVInputImageType;
-  typedef typename Superclass::Input2ImagePointer  HVInputImagePointer;
-  typedef typename Superclass::Input3ImageType     VHInputImageType;
-  typedef typename Superclass::Input3ImagePointer  VHInputImagePointer;
-  typedef typename Superclass::Input4ImageType     VVInputImageType;
-  typedef typename Superclass::Input4ImagePointer  VVInputImagePointer;
-  typedef typename Superclass::OutputImageType     OutputImageType;
-  typedef typename OutputImageType::Pointer        OutputImagePointer;
-  typedef typename OutputImageType::RegionType     OutputImageRegionType;
-  typedef typename Superclass::FunctorType         FunctorType;
-
-  void SetInputHH(const TInputImageHH * image);
-  void SetInputHV(const TInputImageHV * image);
-  void SetInputVH(const TInputImageVH * image);
-  void SetInputVV(const TInputImageVV * image);
-
-
-protected:
-  /**  Constructor */
-  SinclairImageFilter() {}
-  /**  Destructor */
-  ~SinclairImageFilter() override {}
-
-  void GenerateOutputInformation() override;
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-
-  SinclairImageFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-};
-
-
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbSinclairImageFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairImageFilter.hxx b/Modules/Filtering/Polarimetry/include/otbSinclairImageFilter.hxx
deleted file mode 100644
index 201ef1c0f6a096cf82c3ee7d3d060f8b8316d5c3..0000000000000000000000000000000000000000
--- a/Modules/Filtering/Polarimetry/include/otbSinclairImageFilter.hxx
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 otbSinclairImageFilter_hxx
-#define otbSinclairImageFilter_hxx
-
-#include "otbSinclairImageFilter.h"
-#include "otbMath.h"
-
-namespace otb
-{
-
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV, class TInputImageVH, class TInputImageVV, class TOutputImage,
-    class TFunction>
-void
-SinclairImageFilter<TInputImageHH, TInputImageHV, TInputImageVH, TInputImageVV, TOutputImage, TFunction>
-::SetInputHH(const TInputImageHH * image)
-{
-  this->SetInput1(image);
-}
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV, class TInputImageVH, class TInputImageVV, class TOutputImage,
-    class TFunction>
-void
-SinclairImageFilter<TInputImageHH, TInputImageHV, TInputImageVH, TInputImageVV, TOutputImage, TFunction>
-::SetInputHV(const TInputImageHV * image)
-{
-  this->SetInput2(image);
-}
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV, class TInputImageVH, class TInputImageVV, class TOutputImage,
-    class TFunction>
-void
-SinclairImageFilter<TInputImageHH, TInputImageHV, TInputImageVH, TInputImageVV, TOutputImage, TFunction>
-::SetInputVH(const TInputImageVH * image)
-{
-  this->SetInput3(image);
-}
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV, class TInputImageVH, class TInputImageVV, class TOutputImage,
-    class TFunction>
-void
-SinclairImageFilter<TInputImageHH, TInputImageHV, TInputImageVH, TInputImageVV, TOutputImage, TFunction>
-::SetInputVV(const TInputImageVV * image)
-{
-  this->SetInput4(image);
-}
-
-/**
- * Printself
- */
-template <class TInputImageHH, class TInputImageHV, class TInputImageVH, class TInputImageVV, class TOutputImage,
-    class TFunction>
-void
-SinclairImageFilter<TInputImageHH, TInputImageHV, TInputImageVH, TInputImageVV, TOutputImage, TFunction>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-
-template <class TInputImageHH, class TInputImageHV, class TInputImageVH, class TInputImageVV, class TOutputImage,
-    class TFunction>
-void
-SinclairImageFilter<TInputImageHH, TInputImageHV, TInputImageVH, TInputImageVV, TOutputImage, TFunction>
-::GenerateOutputInformation()
-{
-  // Call to the superclass implementation
-  Superclass::GenerateOutputInformation();
-  typename Superclass::OutputImagePointer     outputPtr = this->GetOutput();
-
-  // initialize the number of channels of the output image
-  outputPtr->SetNumberOfComponentsPerPixel( this->GetFunctor().GetNumberOfComponentsPerPixel() );
-
-}
-
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairReciprocalImageFilter.h b/Modules/Filtering/Polarimetry/include/otbSinclairReciprocalImageFilter.h
deleted file mode 100644
index 1ccee11854fa4c7e003baa5330905027221d8d52..0000000000000000000000000000000000000000
--- a/Modules/Filtering/Polarimetry/include/otbSinclairReciprocalImageFilter.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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 otbSinclairReciprocalImageFilter_h
-#define otbSinclairReciprocalImageFilter_h
-
-#include "itkTernaryFunctorImageFilter.h"
-#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
-#include <complex>
-
-namespace otb
-{
-
-/** \class SinclairReciprocalImageFilter
- * \brief Convert the Sinclair reciprocal matrix.
- *
- * This class is parameterized over the type of the input images and
- * the type of the output image. It is also parameterized by the
- * operation to be applied, using a Functor style.
- *
- * The output image has 6 channels : the diagonal and the upper element of the reciprocal matrix.
- * Element a sotored from left to right, line by line.
- *
- * The class is templated by the 3 input image (HH, HV_VH and VV) and the used functor.
- * Available functors are :
- * - SinclairToReciprocalCovarianceMatrixFunctor (default one)
- * - SinclairToReciprocalCircularCovarianceMatrixFunctor
- * - SinclairToReciprocalCoherencyMatrixFunctor
- *
- *  \ingroup SARPolarimetry
- *
- *  \sa SinclairImageFilter
- *  \sa SinclairToReciprocalCircularCovarianceMatrixFunctor
- *  \sa SinclairToReciprocalCoherencyMatrixFunctor
- *  \sa SinclairToReciprocalCovarianceMatrixFunctor
- *
- *
- * \ingroup OTBPolarimetry
- */
-
-
-template <class TInputImageHH, class TInputImageHV_VH,
-          class TInputImageVV, class TOutputImage,
-    class TFunction = Functor::SinclairToReciprocalCovarianceMatrixFunctor<
-        typename TInputImageHH::PixelType,
-        typename TInputImageHV_VH::PixelType,
-        typename TInputImageVV::PixelType,
-        typename TOutputImage::PixelType> >
-class ITK_EXPORT SinclairReciprocalImageFilter :  public itk::TernaryFunctorImageFilter<TInputImageHH,
-      TInputImageHV_VH, TInputImageVV,
-      TOutputImage, TFunction>
-{
-public:
-
-  /** Standard typedefs */
-  typedef SinclairReciprocalImageFilter Self;
-  typedef itk::TernaryFunctorImageFilter<TInputImageHH, TInputImageHV_VH,
-      TInputImageVV, TOutputImage, TFunction>  Superclass;
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  /** Type macro */
-  itkNewMacro(Self);
-
-  /** Creation through object factory macro */
-  itkTypeMacro(SinclairReciprocalImageFilter, itk::TernaryFunctorImageFilter);
-
-  /** Template parameters typedefs */
-  typedef typename Superclass::Input1ImageType     HHInputImageType;
-  typedef typename Superclass::Input1ImagePointer  HHInputImagePointer;
-  typedef typename Superclass::Input2ImageType     HV_VHInputImageType;
-  typedef typename Superclass::Input2ImagePointer  HV_VHInputImagePointer;
-  typedef typename Superclass::Input3ImageType     VVInputImageType;
-  typedef typename Superclass::Input3ImagePointer  VVInputImagePointer;
-  typedef typename Superclass::OutputImageType     OutputImageType;
-  typedef typename OutputImageType::Pointer        OutputImagePointer;
-  typedef typename OutputImageType::RegionType     OutputImageRegionType;
-  typedef typename Superclass::FunctorType         FunctorType;
-
-  void SetInputHH(const TInputImageHH * image);
-  // This method set the second input, same as SetInputVH
-  void SetInputHV(const TInputImageHV_VH * image);
-  // This method set the second input, same as SetInputHV
-  void SetInputVH(const TInputImageHV_VH * image);
-  // This method set the second input, same as SetInputHV and SetInputHV
-  void SetInputHV_VH(const TInputImageHV_VH * image);
-  void SetInputVV(const TInputImageVV * image);
-
-
-protected:
-  /**  Constructor */
-  SinclairReciprocalImageFilter() {}
-  /**  Destructor */
-  ~SinclairReciprocalImageFilter() override {}
-
-  void GenerateOutputInformation() override;
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-
-  SinclairReciprocalImageFilter(const Self &) = delete;
-  void operator =(const Self&) = delete;
-
-};
-
-
-} // end namespace otb
-
-#ifndef OTB_MANUAL_INSTANTIATION
-#include "otbSinclairReciprocalImageFilter.hxx"
-#endif
-
-#endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairReciprocalImageFilter.hxx b/Modules/Filtering/Polarimetry/include/otbSinclairReciprocalImageFilter.hxx
deleted file mode 100644
index 37549c96926854a4581898db6439b12cc89d4516..0000000000000000000000000000000000000000
--- a/Modules/Filtering/Polarimetry/include/otbSinclairReciprocalImageFilter.hxx
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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 otbSinclairReciprocalImageFilter_hxx
-#define otbSinclairReciprocalImageFilter_hxx
-
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbMath.h"
-
-namespace otb
-{
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV_VH, class TInputImageVV, class TOutputImage, class TFunction>
-void
-SinclairReciprocalImageFilter<TInputImageHH, TInputImageHV_VH, TInputImageVV, TOutputImage, TFunction>
-::SetInputHH(const TInputImageHH * image)
-{
-  this->SetInput1(image);
-}
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV_VH, class TInputImageVV, class TOutputImage, class TFunction>
-void
-SinclairReciprocalImageFilter<TInputImageHH, TInputImageHV_VH, TInputImageVV, TOutputImage, TFunction>
-::SetInputHV(const TInputImageHV_VH * image)
-{
-  this->SetInput2(image);
-}
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV_VH, class TInputImageVV, class TOutputImage, class TFunction>
-void
-SinclairReciprocalImageFilter<TInputImageHH, TInputImageHV_VH, TInputImageVV, TOutputImage, TFunction>
-::SetInputVH(const TInputImageHV_VH * image)
-{
-  this->SetInput2(image);
-}
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV_VH, class TInputImageVV, class TOutputImage, class TFunction>
-void
-SinclairReciprocalImageFilter<TInputImageHH, TInputImageHV_VH, TInputImageVV, TOutputImage, TFunction>
-::SetInputHV_VH(const TInputImageHV_VH * image)
-{
-  this->SetInput2(image);
-}
-
-/**
- * Connect one of the operands for pixel-wise addition
- */
-template <class TInputImageHH, class TInputImageHV_VH, class TInputImageVV, class TOutputImage, class TFunction>
-void
-SinclairReciprocalImageFilter<TInputImageHH, TInputImageHV_VH, TInputImageVV, TOutputImage, TFunction>
-::SetInputVV(const TInputImageVV * image)
-{
-  this->SetInput3(image);
-}
-
-/**
- * Printself
- */
-template <class TInputImageHH, class TInputImageHV_VH, class TInputImageVV, class TOutputImage, class TFunction>
-void
-SinclairReciprocalImageFilter<TInputImageHH, TInputImageHV_VH, TInputImageVV, TOutputImage, TFunction>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os, indent);
-}
-
-
-template <class TInputImageHH, class TInputImageHV_VH, class TInputImageVV, class TOutputImage, class TFunction>
-void
-SinclairReciprocalImageFilter<TInputImageHH, TInputImageHV_VH, TInputImageVV, TOutputImage, TFunction>
-::GenerateOutputInformation()
-{
-  // Call to the superclass implementation
-  Superclass::GenerateOutputInformation();
-  typename Superclass::OutputImagePointer     outputPtr = this->GetOutput();
-
-  // initialize the number of channels of the output image
-  outputPtr->SetNumberOfComponentsPerPixel( this->GetFunctor().GetNumberOfComponentsPerPixel() );
-
-}
-
-} // end namespace otb
-
-#endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixImageFilter.h
similarity index 69%
rename from Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h
rename to Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixImageFilter.h
index cc9c9fe283d10b4b3bf24a1f4e93157cb0209f36..02fce56c7ff121a4935cb66da28e029867e1d33e 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToCircularCovarianceMatrixImageFilter.h
@@ -18,11 +18,14 @@
  * limitations under the License.
  */
 
-#ifndef otbSinclairToCircularCovarianceMatrixFunctor_h
-#define otbSinclairToCircularCovarianceMatrixFunctor_h
+#ifndef otbSinclairToCircularCovarianceMatrixImageFilter_h
+#define otbSinclairToCircularCovarianceMatrixImageFilter_h
 
 #include <complex>
-#include "otbSinclairToCovarianceMatrixFunctor.h"
+
+#include "otbSinclairToCovarianceMatrixImageFilter.h"
+#include "otbFunctorImageFilter.h"
+#include "otbPolarimetryTags.h"
 
 namespace otb
 {
@@ -55,6 +58,8 @@ namespace Functor
  * The output pixel has 10 channels : the diagonal and the upper element of the matrix.
  * Element are stored from left to right, line by line.
  *
+ * Use otb::SinclairToCircularCovarianceMatrixImageFilter to apply it to an image.
+ *
  *  \ingroup Functor
  *  \ingroup SARPolarimetry
  *
@@ -79,22 +84,18 @@ public:
   typedef std::complex <RealType>                  ComplexType;
   typedef typename TOutput::ValueType              OutputValueType;
   typedef SinclairToCovarianceMatrixFunctor<ComplexType, ComplexType, ComplexType, ComplexType, TOutput> SinclairToCovarianceFunctorType;
-  inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv,
-                             const TInput3& Svh, const TInput4& Svv)
+  inline void operator()(TOutput& result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svh, const TInput4& Svv) const
   {
-    TOutput result;
-
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vh = static_cast<ComplexType>(Svh);
     const ComplexType S_vv = static_cast<ComplexType>(Svv);
 
-    result.SetSize(m_NumberOfComponentsPerPixel);
     const ComplexType jS_hv = S_hv * ComplexType(0., 1.);
     const ComplexType jS_vh = S_vh * ComplexType(0., 1.);
     const ComplexType jS_hh = S_hh * ComplexType(0., 1.);
     const ComplexType jS_vv = S_vv * ComplexType(0., 1.);
-    
+
     const ComplexType coef(0.5);
 
     const ComplexType Sll = coef*( S_hh+jS_hv+jS_vh-S_vv );
@@ -102,34 +103,49 @@ public:
     const ComplexType Srl = coef*( jS_hh-S_hv+S_vh+jS_vv );
     const ComplexType Srr = coef*( -S_hh+jS_hv+jS_vh+S_vv );
 
-    //const ComplexType conjSll = std::conj(Sll);
-    //const ComplexType conjSlr = std::conj(Slr);
-    //const ComplexType conjSrl = std::conj(Srl);
-    //const ComplexType conjSrr = std::conj(Srr);
-
     SinclairToCovarianceFunctorType funct;
-    return ( funct( Sll, Slr, Srl, Srr ) );
+    funct(result, Sll, Slr, Srl, Srr);
   }
 
-  unsigned int GetNumberOfComponentsPerPixel()
+  constexpr size_t OutputSize(...) const
   {
-    return m_NumberOfComponentsPerPixel;
+    // Size of circular covariance matrix
+    return 10;
   }
 
   /** Constructor */
-  SinclairToCircularCovarianceMatrixFunctor() : m_NumberOfComponentsPerPixel(10) {}
+  SinclairToCircularCovarianceMatrixFunctor()
+  {
+  }
 
   /** Destructor */
   virtual ~SinclairToCircularCovarianceMatrixFunctor() {}
-
-protected:
-
-
-private:
-    unsigned int m_NumberOfComponentsPerPixel;
 };
 
 } // namespace Functor
+
+/**
+ * \typedef SinclairToCircularCovarianceMatrixImageFilter
+ * \brief Applies otb::Functor::SinclairToCircularCovarianceMatrixFunctor
+ * \sa otb::Functor::SinclairToCircularCovarianceMatrixFunctor
+ *
+ * Set inputs with:
+ * \code
+ *
+ * SetVariadicNamedInput<polarimetry_tags::hh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::hv>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vv>(inputPtr);
+ *
+ * \endcode
+ *
+ * \ingroup OTBPolarimetry
+ */
+template <typename TInputImage, typename TOutputImage>
+using SinclairToCircularCovarianceMatrixImageFilter = FunctorImageFilter<
+    Functor::SinclairToCircularCovarianceMatrixFunctor<typename TInputImage::PixelType, typename TInputImage::PixelType, typename TInputImage::PixelType,
+                                                       typename TInputImage::PixelType, typename TOutputImage::PixelType>,
+    std::tuple<polarimetry_tags::hh, polarimetry_tags::hv, polarimetry_tags::vh, polarimetry_tags::vv>>;
 } // namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToCoherencyMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToCoherencyMatrixImageFilter.h
similarity index 73%
rename from Modules/Filtering/Polarimetry/include/otbSinclairToCoherencyMatrixFunctor.h
rename to Modules/Filtering/Polarimetry/include/otbSinclairToCoherencyMatrixImageFilter.h
index e21d9635e8a8181d45c4ed8b781a8712f6f1edb1..64e315386a21ee81292567c8224beb335a7d2173 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToCoherencyMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToCoherencyMatrixImageFilter.h
@@ -18,10 +18,12 @@
  * limitations under the License.
  */
 
-#ifndef otbSinclairToCoherencyMatrixFunctor_h
-#define otbSinclairToCoherencyMatrixFunctor_h
+#ifndef otbSinclairToCoherencyMatrixImageFilter_h
+#define otbSinclairToCoherencyMatrixImageFilter_h
 
 #include <complex>
+#include "otbFunctorImageFilter.h"
+#include "otbPolarimetryTags.h"
 
 namespace otb
 {
@@ -46,6 +48,8 @@ namespace Functor
  * The output pixel has 10 channels : the diagonal and the upper element of the matrix.
  * Element are stored from left to right, line by line.
  *
+ * Use otb::SinclairToCoherencyMatrixImageFilter to apply it to an image.
+ *
  *  \ingroup Functor
  *  \ingroup SARPolarimetry
  *
@@ -69,13 +73,8 @@ public:
   typedef double                                   RealType;
   typedef std::complex <RealType>                  ComplexType;
   typedef typename TOutput::ValueType              OutputValueType;
-  inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv,
-                             const TInput3& Svh, const TInput4& Svv)
+  inline void operator()(TOutput& result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svh, const TInput4& Svv) const
   {
-    TOutput result;
-
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vh = static_cast<ComplexType>(Svh);
@@ -98,13 +97,12 @@ public:
     result[9] = static_cast<OutputValueType>( std::norm(jHVMinusVH) );
 
     result /= 2.0;
-
-    return (result);
   }
 
-  unsigned int GetNumberOfComponentsPerPixel()
+  constexpr size_t OutputSize(...) const
   {
-    return m_NumberOfComponentsPerPixel;
+    // Size of coherency matrix
+    return 10;
   }
 
   /** Constructor */
@@ -112,16 +110,32 @@ public:
 
   /** Destructor */
   virtual ~SinclairToCoherencyMatrixFunctor() {}
-
-protected:
-
-
-private:
-  //itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 10);
-  static const  unsigned int m_NumberOfComponentsPerPixel = 10;
 };
 
 } // namespace Functor
+
+/**
+ * \typedef SinclairToCoherencyMatrixImageFilter
+ * \brief Applies otb::Functor::SinclairToCoherencyMatrixFunctor
+ * \sa otb::Functor::SinclairToCoherencyMatrixFunctor
+ *
+ * Set inputs with:
+ * \code
+ *
+ * SetVariadicNamedInput<polarimetry_tags::hh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::hv>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vv>(inputPtr);
+ *
+ * \endcode
+ *
+ * \ingroup OTBPolarimetry
+ */
+template <typename TInputImage, typename TOutputImage>
+using SinclairToCoherencyMatrixImageFilter = FunctorImageFilter<
+    Functor::SinclairToCoherencyMatrixFunctor<typename TInputImage::PixelType, typename TInputImage::PixelType, typename TInputImage::PixelType,
+                                              typename TInputImage::PixelType, typename TOutputImage::PixelType>,
+    std::tuple<polarimetry_tags::hh, polarimetry_tags::hv, polarimetry_tags::vh, polarimetry_tags::vv>>;
 } // namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToCovarianceMatrixImageFilter.h
similarity index 65%
rename from Modules/Filtering/Polarimetry/include/otbSinclairToCovarianceMatrixFunctor.h
rename to Modules/Filtering/Polarimetry/include/otbSinclairToCovarianceMatrixImageFilter.h
index 9decec618f7b9991f9c2d7800e3bc9a90c5223bf..eba84426145c3f957e20473ed73abf469d46c1fd 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToCovarianceMatrixImageFilter.h
@@ -18,10 +18,12 @@
  * limitations under the License.
  */
 
-#ifndef otbSinclairToCovarianceMatrixFunctor_h
-#define otbSinclairToCovarianceMatrixFunctor_h
+#ifndef otbSinclairToCovarianceMatrixImageFilter_h
+#define otbSinclairToCovarianceMatrixImageFilter_h
 
 #include <complex>
+#include "otbFunctorImageFilter.h"
+#include "otbPolarimetryTags.h"
 
 namespace otb
 {
@@ -43,11 +45,15 @@ namespace Functor
  *  - channel #8 : \f$ S_{vh}.S_{vv}^{*} \f$
  *  - channel #9 : \f$ S_{vv}.S_{vv}^{*} \f$
  *
- * The output pixel has 10 channels : the diagonal and the upper element of the matrix.
- * Element are stored from left to right, line by line.
+ *  The output pixel has 10 channels : the diagonal and the upper element of the matrix.
+ *  Element are stored from left to right, line by line.
+ *
+ *  Use otb::SinclairToCovarianceMatrixImageFilter to apply
+ *  it to an image.
  *
  *  \ingroup Functor
  *  \ingroup SARPolarimetry
+ *  \ingroup OTBPolarimetry
  *
  *  \sa SinclairImageFilter
  *  \sa SinclairToCircularCovarianceMatrixFunctor
@@ -57,8 +63,6 @@ namespace Functor
  *  \sa SinclairToReciprocalCoherencyFunctor
  *  \sa SinclairToReciprocalCovarianceMatrixFunctor
  *
- *
- * \ingroup OTBPolarimetry
  */
 template <class TInput1, class TInput2, class TInput3,
           class TInput4, class TOutput>
@@ -68,13 +72,8 @@ public:
   /** Some typedefs. */
   typedef typename std::complex <double>           ComplexType;
   typedef typename TOutput::ValueType              OutputValueType;
-  inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv,
-                             const TInput3& Svh, const TInput4& Svv)
+  inline void operator()(TOutput& result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svh, const TInput4& Svv) const
   {
-    TOutput result;
-
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vh = static_cast<ComplexType>(Svh);
@@ -90,31 +89,39 @@ public:
     result[7] = static_cast<OutputValueType>( std::norm(S_vh) );
     result[8] = static_cast<OutputValueType>( S_vh*std::conj(S_vv) );
     result[9] = static_cast<OutputValueType>( std::norm(S_vv) );
-
-    return (result);
   }
 
-  unsigned int GetNumberOfComponentsPerPixel()
+  constexpr size_t OutputSize(...) const
   {
-    return m_NumberOfComponentsPerPixel;
+    // Number of components in the covariance matrix
+    return 10;
   }
-
-  /** Constructor */
-  SinclairToCovarianceMatrixFunctor() {}
-
-  /** Destructor */
-  virtual ~SinclairToCovarianceMatrixFunctor() {}
-
-protected:
-
-
-private:
-  //itkStaticConstMacro(m_NumberOfComponentsPerPixel, unsigned int, 10);
-  static const  unsigned int m_NumberOfComponentsPerPixel = 10;
-
 };
-
 } // namespace Functor
+
+/**
+ * \typedef SinclairToCovarianceMatrixImageFilter
+ * \brief Applies otb::Functor::SinclairToCovarianceMatrixFunctor
+ * \sa otb::Functor::SinclairToCovarianceMatrixFunctor
+ *
+ * Set inputs with:
+ * \code
+ *
+ * SetVariadicNamedInput<polarimetry_tags::hh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::hv>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vv>(inputPtr);
+ *
+ * \endcode
+ *
+ * \ingroup OTBPolarimetry
+ */
+template <typename TInputImage, typename TOutputImage>
+using SinclairToCovarianceMatrixImageFilter = FunctorImageFilter<
+    Functor::SinclairToCovarianceMatrixFunctor<typename TInputImage::PixelType, typename TInputImage::PixelType, typename TInputImage::PixelType,
+                                               typename TInputImage::PixelType, typename TOutputImage::PixelType>,
+    std::tuple<polarimetry_tags::hh, polarimetry_tags::hv, polarimetry_tags::vh, polarimetry_tags::vv>>;
+
 } // namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixImageFilter.h
similarity index 80%
rename from Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h
rename to Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixImageFilter.h
index 893fdb2158fd0d240359b5fe72aa9000eb5383c6..87d0d639dcc4385bed416a6e1c034dfda508bd47 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToMuellerMatrixImageFilter.h
@@ -18,10 +18,12 @@
  * limitations under the License.
  */
 
-#ifndef otbSinclairToMuellerMatrixFunctor_h
-#define otbSinclairToMuellerMatrixFunctor_h
+#ifndef otbSinclairToMuellerMatrixImageFilter_h
+#define otbSinclairToMuellerMatrixImageFilter_h
 
 #include <complex>
+#include "otbFunctorImageFilter.h"
+#include "otbPolarimetryTags.h"
 
 namespace otb
 {
@@ -65,6 +67,7 @@ namespace Functor
  * {channel #12}&{channel #13}&{channel #14}&{channel #15} \\
  * \end{pmatrix}  \f$
  *
+ * Use otb::otbSinclairToMuellerMatrixImageFilter to apply it to an image.
  *  \ingroup Functor
  *  \ingroup SARPolarimetry
  *
@@ -89,13 +92,8 @@ public:
   typedef typename TOutput::ValueType              OutputValueType;
   typedef double                                   RealType;
 
-  inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv,
-                             const TInput3& Svh, const TInput4& Svv)
+  inline void operator()(TOutput& result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svh, const TInput4& Svv) const
   {
-    TOutput result;
-
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
     const ComplexType Txx = static_cast<ComplexType>(-Shh);
     const ComplexType Txy = static_cast<ComplexType>(-Shv);
     const ComplexType Tyx = static_cast<ComplexType>(Svh);
@@ -122,29 +120,48 @@ public:
     result[13] = static_cast<OutputValueType>( (conjTxx*Tyx - conjTxy*Tyy).imag()  );
     result[14] = static_cast<OutputValueType>( (conjTxx*Tyy + conjTxy*Tyx).imag()  );
     result[15] = static_cast<OutputValueType>( (Txx*conjTyy - Txy*conjTyx).real()  );
-
-    return (result);
   }
 
-  unsigned int GetNumberOfComponentsPerPixel()
+  constexpr size_t OutputSize(...) const
   {
-    return m_NumberOfComponentsPerPixel;
+    // Size of mueller matrix
+    return 16;
   }
 
   /** Constructor */
-  SinclairToMuellerMatrixFunctor() : m_NumberOfComponentsPerPixel(16) {}
+  SinclairToMuellerMatrixFunctor()
+  {
+  }
 
   /** Destructor */
   virtual ~SinclairToMuellerMatrixFunctor() {}
-
-protected:
-
-
-private:
-    unsigned int m_NumberOfComponentsPerPixel;
 };
 
 } // namespace Functor
+
+/**
+ * \typedef SinclairToMuellerMatrixImageFilter
+ * \brief Applies otb::Functor::SinclairToMuellerMatrixFunctor
+ * \sa otb::Functor::SinclairToCircularCovarianceMatrixFunctor
+ *
+ * Set inputs with:
+ * \code
+ *
+ * SetVariadicNamedInput<polarimetry_tags::hh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::hv>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vv>(inputPtr);
+ *
+ * \endcode
+ *
+ * \ingroup OTBPolarimetry
+ */
+template <typename TInputImage, typename TOutputImage>
+using SinclairToMuellerMatrixImageFilter = FunctorImageFilter<
+    Functor::SinclairToMuellerMatrixFunctor<typename TInputImage::PixelType, typename TInputImage::PixelType, typename TInputImage::PixelType,
+                                            typename TInputImage::PixelType, typename TOutputImage::PixelType>,
+    std::tuple<polarimetry_tags::hh, polarimetry_tags::hv, polarimetry_tags::vh, polarimetry_tags::vv>>;
+
 } // namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixImageFilter.h
similarity index 65%
rename from Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
rename to Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixImageFilter.h
index 02fe39e304416acd8ec6b27e829c2bdd4367f424..284547da59bafa80915a7524363c97bc47c499dc 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixImageFilter.h
@@ -18,11 +18,14 @@
  * limitations under the License.
  */
 
-#ifndef otbSinclairToReciprocalCircularCovarianceMatrixFunctor_h
-#define otbSinclairToReciprocalCircularCovarianceMatrixFunctor_h
+#ifndef otbSinclairToReciprocalCircularCovarianceMatrixImageFilter_h
+#define otbSinclairToReciprocalCircularCovarianceMatrixImageFilter_h
 
 #include <complex>
-#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
+#include "otbSinclairToReciprocalCovarianceMatrixImageFilter.h"
+
+#include "otbFunctorImageFilter.h"
+#include "otbPolarimetryTags.h"
 
 namespace otb
 {
@@ -45,6 +48,8 @@ namespace Functor
  * The output pixel has 6 channels : the diagonal and the upper element of the reciprocal matrix.
  * Element are stored from left to right, line by line.
  *
+ * Use otb::SinclairToReciprocalCircularCovarianceMatrixImageFilter to apply it to an image.
+ *
  *  \ingroup Functor
  *  \ingroup SARPolarimetry
  *
@@ -69,13 +74,8 @@ public:
   typedef typename TOutput::ValueType              OutputValueType;
   typedef SinclairToReciprocalCovarianceMatrixFunctor<ComplexType, ComplexType, ComplexType, TOutput> SinclairToReciprocalCovarianceFunctorType;
 
-  inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv, const TInput3& Svv)
+  inline void operator()(TOutput& result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svv) const
   {
-    TOutput result;
-
-    result.SetSize(m_NumberOfComponentsPerPixel);
-
-
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vv = static_cast<ComplexType>(Svv);
@@ -93,28 +93,38 @@ public:
 
 
     SinclairToReciprocalCovarianceFunctorType funct;
-    return ( funct(Sll, Slr, Srr ) );
+    funct(result, Sll, Slr, Srr);
   }
 
-  unsigned int GetNumberOfComponentsPerPixel()
+  constexpr size_t OutputSize(...) const
   {
-    return m_NumberOfComponentsPerPixel;
+    // Size of the  matrix
+    return 6;
   }
-
-  /** Constructor */
-  SinclairToReciprocalCircularCovarianceMatrixFunctor() : m_NumberOfComponentsPerPixel(6) {}
-
-  /** Destructor */
-  virtual ~SinclairToReciprocalCircularCovarianceMatrixFunctor() {}
-
-protected:
-
-
-private:
-    unsigned int m_NumberOfComponentsPerPixel;
 };
 
 } // namespace Functor
+/**
+ * \typedef SinclairToReciprocalCircularCovarianceMatrixImageFilter
+ * \brief Applies otb::Functor::SinclairToReciprocalCircularCovarianceMatrixFunctor
+ * \sa otb::Functor::SinclairToReciprocalCircularCovarianceMatrixFunctor
+ *
+ * Set inputs with:
+ * \code
+ *
+ * SetVariadicNamedInput<polarimetry_tags::hh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vv>(inputPtr);
+ *
+ * \endcode
+ *
+ * \ingroup OTBPolarimetry
+ */
+template <typename TInputImage, typename TOutputImage>
+using SinclairToReciprocalCircularCovarianceMatrixImageFilter =
+    FunctorImageFilter<Functor::SinclairToReciprocalCircularCovarianceMatrixFunctor<typename TInputImage::PixelType, typename TInputImage::PixelType,
+                                                                                    typename TInputImage::PixelType, typename TOutputImage::PixelType>,
+                       std::tuple<polarimetry_tags::hh, polarimetry_tags::hv_or_vh, polarimetry_tags::vv>>;
 } // namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixImageFilter.h
similarity index 69%
rename from Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
rename to Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixImageFilter.h
index f9a3ec46f7f7d77590fcfe6db2dd3e2bad0f565e..894b34e6bf4a0d89cc76d0a5a82b17b455ae0659 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixImageFilter.h
@@ -18,14 +18,17 @@
  * limitations under the License.
  */
 
-#ifndef otbSinclairToReciprocalCoherencyMatrixFunctor_h
-#define otbSinclairToReciprocalCoherencyMatrixFunctor_h
+#ifndef otbSinclairToReciprocalCoherencyMatrixImageFilter_h
+#define otbSinclairToReciprocalCoherencyMatrixImageFilter_h
 
 #include "itkMacro.h"
 #include <complex>
 #include "otbMath.h"
 #include "vnl/vnl_matrix.h"
 
+#include "otbFunctorImageFilter.h"
+#include "otbPolarimetryTags.h"
+
 namespace otb
 {
 namespace Functor
@@ -47,6 +50,8 @@ namespace Functor
  * The output pixel has 6 channels : the diagonal and the upper element of the reciprocal matrix.
  * Element are stored from left to right, line by line.
  *
+ * Use otb::SinclairToReciprocalCoherencyMatrixImageFilter to apply it to an image.
+ *
  *  \ingroup Functor
  *  \ingroup SARPolarimetry
  *
@@ -69,57 +74,59 @@ public:
   typedef typename std::complex <double>           ComplexType;
   typedef vnl_matrix<ComplexType>       		   VNLMatrixType;
   typedef typename TOutput::ValueType              OutputValueType;
-  
-  itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 6);
-  
-  inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv, const TInput3& Svv)
-  {
-    TOutput result;
-
-    result.SetSize(NumberOfComponentsPerPixel);
 
+  inline void operator()(TOutput& result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svv) const
+  {
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vv = static_cast<ComplexType>(Svv);
-   
-    
+
     VNLMatrixType f3p(3, 1, 0.);
     f3p[0][0]= (S_hh + S_vv) / ComplexType( std::sqrt(2.0) , 0.0);
     f3p[1][0]= (S_hh - S_vv) / ComplexType( std::sqrt(2.0) , 0.0);
     f3p[2][0]= ComplexType( std::sqrt(2.0) , 0.0) * S_hv;
 
-
     VNLMatrixType res = f3p*f3p.conjugate_transpose();
-    
+
     result[0] = static_cast<OutputValueType>( res[0][0] );
     result[1] = static_cast<OutputValueType>( res[0][1] );
     result[2] = static_cast<OutputValueType>( res[0][2] );
     result[3] = static_cast<OutputValueType>( res[1][1] );
     result[4] = static_cast<OutputValueType>( res[1][2] );
     result[5] = static_cast<OutputValueType>( res[2][2] );
-    
-
-    return (result);
   }
 
-  unsigned int GetNumberOfComponentsPerPixel()
+  constexpr size_t OutputSize(...) const
   {
-    return NumberOfComponentsPerPixel;
+    // Size of the  matrix
+    return 6;
   }
-
-  /** Constructor */
-  SinclairToReciprocalCoherencyMatrixFunctor() {}
-
-  /** Destructor */
-  virtual ~SinclairToReciprocalCoherencyMatrixFunctor() {}
-
-protected:
-
-private:
-
 };
 
 } // namespace Functor
+
+/**
+ * \typedef SinclairToReciprocalCoherencyMatrixImageFilter
+ * \brief Applies otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor
+ * \sa otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor
+ *
+ * Set inputs with:
+ * \code
+ *
+ * SetVariadicNamedInput<polarimetry_tags::hh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vv>(inputPtr);
+ *
+ * \endcode
+ *
+ * \ingroup OTBPolarimetry
+ */
+template <typename TInputImage, typename TOutputImage>
+using SinclairToReciprocalCoherencyMatrixImageFilter =
+    FunctorImageFilter<Functor::SinclairToReciprocalCoherencyMatrixFunctor<typename TInputImage::PixelType, typename TInputImage::PixelType,
+                                                                           typename TInputImage::PixelType, typename TOutputImage::PixelType>,
+                       std::tuple<polarimetry_tags::hh, polarimetry_tags::hv_or_vh, polarimetry_tags::vv>>;
+
 } // namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixImageFilter.h
similarity index 67%
rename from Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
rename to Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixImageFilter.h
index f24ee87fdbc4d89e6ce492ce35471683063ac117..cae7d645da99c02c05c9932271fc17599ca4d4f8 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixImageFilter.h
@@ -18,13 +18,16 @@
  * limitations under the License.
  */
 
-#ifndef otbSinclairToReciprocalCovarianceMatrixFunctor_h
-#define otbSinclairToReciprocalCovarianceMatrixFunctor_h
+#ifndef otbSinclairToReciprocalCovarianceMatrixImageFilter_h
+#define otbSinclairToReciprocalCovarianceMatrixImageFilter_h
 
 #include <complex>
 #include "otbMath.h"
 #include "vnl/vnl_matrix.h"
 
+#include "otbFunctorImageFilter.h"
+#include "otbPolarimetryTags.h"
+
 namespace otb
 {
 namespace Functor
@@ -46,6 +49,8 @@ namespace Functor
  * The output pixel has 6 channels : the diagonal and the upper element of the reciprocal matrix.
  * Element are stored from left to right, line by line.
  *
+ * Use otb::SinclairToReciprocalCovarianceMatrixImageFilter to apply it to an image.
+ *
  *  \ingroup Functor
  *  \ingroup SARPolarimetry
  *
@@ -68,54 +73,57 @@ public:
   typedef typename std::complex <double>           ComplexType;
   typedef vnl_matrix<ComplexType>       		   VNLMatrixType;
   typedef typename TOutput::ValueType              OutputValueType;
-  inline TOutput operator ()(const TInput1& Shh, const TInput2& Shv, const TInput3& Svv)
+  inline void                                      operator()(TOutput& result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svv) const
   {
-    TOutput result;
-
-    result.SetSize(NumberOfComponentsPerPixel);
-
     const ComplexType S_hh = static_cast<ComplexType>(Shh);
     const ComplexType S_hv = static_cast<ComplexType>(Shv);
     const ComplexType S_vv = static_cast<ComplexType>(Svv);
-    
+
     VNLMatrixType f3l(3, 1, 0.);
     f3l[0][0]=S_hh;
     f3l[1][0]=ComplexType(std::sqrt(2.0),0.0)*S_hv;
     f3l[2][0]=S_vv;
-    
+
     VNLMatrixType res = f3l*f3l.conjugate_transpose();
-    
+
     result[0] = static_cast<OutputValueType>( res[0][0] );
     result[1] = static_cast<OutputValueType>( res[0][1] );
     result[2] = static_cast<OutputValueType>( res[0][2] );
     result[3] = static_cast<OutputValueType>( res[1][1] );
     result[4] = static_cast<OutputValueType>( res[1][2] );
     result[5] = static_cast<OutputValueType>( res[2][2] );
-
-    return (result);
   }
 
-  unsigned int GetNumberOfComponentsPerPixel()
+  constexpr size_t OutputSize(...) const
   {
-    return NumberOfComponentsPerPixel;
+    // Size of the  matrix
+    return 6;
   }
-
-  /** Constructor */
-  SinclairToReciprocalCovarianceMatrixFunctor() {}
-
-  /** Destructor */
-  virtual ~SinclairToReciprocalCovarianceMatrixFunctor() {}
-
-protected:
-
-
-private:
-  //itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 6);
-  static const unsigned int NumberOfComponentsPerPixel = 6;
-
 };
 
 } // namespace Functor
+
+/**
+ * \typedef SinclairToReciprocalCovarianceMatrixImageFilter
+ * \brief Applies otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor
+ * \sa otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor
+ *
+ * Set inputs with:
+ * \code
+ *
+ * SetVariadicNamedInput<polarimetry_tags::hh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(inputPtr);
+ * SetVariadicNamedInput<polarimetry_tags::vv>(inputPtr);
+ *
+ * \endcode
+ *
+ * \ingroup OTBPolarimetry
+ */
+template <typename TInputImage, typename TOutputImage>
+using SinclairToReciprocalCovarianceMatrixImageFilter =
+    FunctorImageFilter<Functor::SinclairToReciprocalCovarianceMatrixFunctor<typename TInputImage::PixelType, typename TInputImage::PixelType,
+                                                                            typename TInputImage::PixelType, typename TOutputImage::PixelType>,
+                       std::tuple<polarimetry_tags::hh, polarimetry_tags::hv_or_vh, polarimetry_tags::vv>>;
 } // namespace otb
 
 #endif
diff --git a/Modules/Filtering/Polarimetry/otb-module.cmake b/Modules/Filtering/Polarimetry/otb-module.cmake
index 819bb964cfad2b0d711e57bde46f49d16bfddda8..5d44ff3adaba1c9857568a1bc3e1e1b5d0f2532e 100644
--- a/Modules/Filtering/Polarimetry/otb-module.cmake
+++ b/Modules/Filtering/Polarimetry/otb-module.cmake
@@ -29,6 +29,7 @@ otb_module(OTBPolarimetry
   DEPENDS
     OTBCommon
     OTBITK
+    OTBFunctor
 
   TEST_DEPENDS
     OTBImageBase
diff --git a/Modules/Filtering/Polarimetry/test/otbMuellerToPolarisationDegreeAndPowerImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbMuellerToPolarisationDegreeAndPowerImageFilter.cxx
index 694cb34e53d478cba5d600205bf1099ce94d8bf0..7ed2b3c6b03353ddfbdf7d36fe48357063a4d2ef 100644
--- a/Modules/Filtering/Polarimetry/test/otbMuellerToPolarisationDegreeAndPowerImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbMuellerToPolarisationDegreeAndPowerImageFilter.cxx
@@ -27,9 +27,6 @@
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
 #include "otbMuellerToPolarisationDegreeAndPowerImageFilter.h"
-#include "otbSinclairImageFilter.h"
-#include "otbSinclairToMuellerMatrixFunctor.h"
-
 
 int otbMuellerToPolarisationDegreeAndPowerImageFilter(int itkNotUsed(argc), char * argv[])
 {
@@ -51,7 +48,7 @@ int otbMuellerToPolarisationDegreeAndPowerImageFilter(int itkNotUsed(argc), char
   reader->SetFileName(inputFilename);
 
   FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(reader->GetOutput());
+  filter->SetVariadicInput<0>(reader->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(filter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx
index d1d9d953e8d1947970649e9096c1981d50e2560a..8ce8a91efcd9347c8fedf3d1c8c687d2a793ee85 100644
--- a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceFunctor.cxx
@@ -34,7 +34,7 @@ int otbMuellerToReciprocalCovarianceFunctor(int itkNotUsed(argc), char * itkNotU
 
   VectorDoubleType input;
   input.SetSize(16);
-  VectorComplexType outputFunct;
+  VectorComplexType outputFunct(6);
   outputFunct.SetSize(6);
   VectorComplexType result;
   result.SetSize(6);
@@ -54,7 +54,7 @@ int otbMuellerToReciprocalCovarianceFunctor(int itkNotUsed(argc), char * itkNotU
   result[5] = ComplexType(0.75,0);
 
   FunctorType funct;
-  outputFunct = funct.operator ()( input );
+  funct.      operator()(outputFunct, input);
   std::cout<<outputFunct<<std::endl;
 
   if( std::abs(result[0].real()-outputFunct[0].real()) > 1e-10 ||
diff --git a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceImageFilter.cxx
index 53991133273f9f5844192319a02b511ad2b8638a..0eefd16d05e109ecdc7f062b615c9ec2380510c1 100644
--- a/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbMuellerToReciprocalCovarianceImageFilter.cxx
@@ -24,9 +24,10 @@
 #include "otbVectorImage.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
-#include "otbMuellerToReciprocalCovarianceImageFilter.h"
 #include "otbExtractROI.h"
 
+#include "otbMuellerToReciprocalCovarianceImageFilter.h"
+
 int otbMuellerToReciprocalCovarianceImageFilter(int itkNotUsed(argc), char * argv[])
 {
   const char * inputFilename  = argv[1];
@@ -48,7 +49,7 @@ int otbMuellerToReciprocalCovarianceImageFilter(int itkNotUsed(argc), char * arg
   reader->SetFileName(inputFilename );
 
   FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(reader->GetOutput());
+  filter->SetVariadicInput<0>(reader->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(filter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx
index 989d79ca367c1f57872faae4251e282af49e8bf6..d829dab61248199d55b60d401f52d42cda092e75 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx
@@ -27,12 +27,10 @@
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
 #include "itkMeanImageFilter.h"
-#include "otbReciprocalBarnesDecompImageFilter.h"
 #include "otbPerBandVectorImageFilter.h"
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
-
 
+#include "otbReciprocalBarnesDecompImageFilter.h"
+#include "otbSinclairToReciprocalCovarianceMatrixImageFilter.h"
 
 int otbReciprocalBarnesDecompImageFilter(int itkNotUsed(argc), char * argv[])
 {
@@ -53,50 +51,43 @@ int otbReciprocalBarnesDecompImageFilter(int itkNotUsed(argc), char * argv[])
 
   typedef otb::ImageFileReader<ComplexImageType>  ReaderType;
   typedef otb::ImageFileWriter<ComplexVectorImageType> WriterType;
-  
-  
-  typedef otb::SinclairReciprocalImageFilter<ComplexImageType, ComplexImageType, ComplexImageType, ComplexVectorImageType, 
-  otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor<ComplexImageType::PixelType,
-                                    ComplexImageType::PixelType,
-                                    ComplexImageType::PixelType,
-                                    ComplexVectorImageType::PixelType> > SinclairToCovFilterType;
-  
-  
+
+  using SinclairToCovFilterType = otb::SinclairToReciprocalCovarianceMatrixImageFilter<ComplexImageType, ComplexVectorImageType>;
+
   typedef itk::MeanImageFilter<ComplexImageType, ComplexImageType>         MeanFilterType;
   typedef otb::PerBandVectorImageFilter<ComplexVectorImageType, ComplexVectorImageType, MeanFilterType> PerBandMeanFilterType;
-  
-  
+
+
   typedef otb::ReciprocalBarnesDecompImageFilter<ComplexVectorImageType, ComplexVectorImageType> FilterType;
-  
-  
+
 
   ReaderType::Pointer readerHH = ReaderType::New();
   ReaderType::Pointer readerHV = ReaderType::New();
   ReaderType::Pointer readerVV = ReaderType::New();
-  
+
   WriterType::Pointer writer = WriterType::New();
 
   SinclairToCovFilterType::Pointer sinclairtocov = SinclairToCovFilterType::New();
   PerBandMeanFilterType::Pointer perBand = PerBandMeanFilterType::New();
   FilterType::Pointer barnesfilter = FilterType::New();
-        
-  
+
+
   MeanFilterType::InputSizeType radius;
   radius.Fill( size );
   perBand->GetFilter()->SetRadius(radius);
- 
- 
+
+
   readerHH->SetFileName(inputFilenameHH);
   readerHV->SetFileName(inputFilenameHV);
   readerVV->SetFileName(inputFilenameVV);
-  
-  sinclairtocov->SetInputHH(readerHH->GetOutput());
-  sinclairtocov->SetInputHV_VH(readerHV->GetOutput());
-  sinclairtocov->SetInputVV(readerVV->GetOutput());
- 
+
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::hh{}, readerHH->GetOutput());
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::hv_or_vh{}, readerHV->GetOutput());
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::vv{}, readerVV->GetOutput());
+
   perBand->SetInput(sinclairtocov->GetOutput());
-  
-  barnesfilter->SetInput(perBand->GetOutput());
+
+  barnesfilter->SetVariadicInput<0>(perBand->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(barnesfilter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalCoherencyToReciprocalMuellerImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalCoherencyToReciprocalMuellerImageFilter.cxx
index 1e8c910a9baf20a15385608ad9ad7ab554bbdd5b..c2060cc84b08087cd38f62d413d4ef132c8050f0 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalCoherencyToReciprocalMuellerImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalCoherencyToReciprocalMuellerImageFilter.cxx
@@ -53,7 +53,7 @@ int otbReciprocalCoherencyToReciprocalMuellerImageFilter(int itkNotUsed(argc), c
   reader->SetFileName(inputFilename);
 
   FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(reader->GetOutput());
+  filter->SetVariadicInput<0>(reader->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(filter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToCoherencyDegreeImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToCoherencyDegreeImageFilter.cxx
index 1223a207d98e578889586d8e191e0d612f2deb91..afb62522139e957a41fc83cc657570d15017d2d9 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToCoherencyDegreeImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToCoherencyDegreeImageFilter.cxx
@@ -28,7 +28,6 @@
 #include "otbImageFileWriter.h"
 #include "otbReciprocalCovarianceToCoherencyDegreeImageFilter.h"
 
-
 int otbReciprocalCovarianceToCoherencyDegreeImageFilter(int itkNotUsed(argc), char * argv[])
 {
   const char * inputFilename  = argv[1];
@@ -50,7 +49,7 @@ int otbReciprocalCovarianceToCoherencyDegreeImageFilter(int itkNotUsed(argc), ch
   reader->SetFileName(inputFilename);
 
   FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(reader->GetOutput());
+  filter->SetVariadicInput<0>(reader->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(filter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.cxx
index c52d7b6c46d418492de202fdeb794182edc3eebe..d50a251a635e146feeff974c2bfb08fe352e19a8 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalCovarianceToReciprocalCoherencyImageFilter.cxx
@@ -47,7 +47,7 @@ int otbReciprocalCovarianceToReciprocalCoherencyImageFilter(int itkNotUsed(argc)
   reader->SetFileName(inputFilename);
 
   FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(reader->GetOutput());
+  filter->SetVariadicInput<0>(reader->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(filter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx
index 489b5ae6ca8b696c8f0d3fd257062bacd0688174..723f540444aa44872e8fb9b27de528511c5f36da 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx
@@ -26,12 +26,11 @@
 #include "otbVectorImage.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
-#include "otbReciprocalHAlphaImageFilter.h"
 #include "itkMeanImageFilter.h"
 #include "otbPerBandVectorImageFilter.h"
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
 
+#include "otbReciprocalHAlphaImageFilter.h"
+#include "otbSinclairToReciprocalCovarianceMatrixImageFilter.h"
 
 int otbReciprocalHAlphaImageFilter(int itkNotUsed(argc), char * argv[])
 {
@@ -54,50 +53,42 @@ int otbReciprocalHAlphaImageFilter(int itkNotUsed(argc), char * argv[])
 
   typedef otb::ImageFileReader<ComplexImageType>  ReaderType;
   typedef otb::ImageFileWriter<RealVectorImageType> WriterType;
-  
-  
-  typedef otb::SinclairReciprocalImageFilter<ComplexImageType, ComplexImageType, ComplexImageType, ComplexVectorImageType, 
-  otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor<ComplexImageType::PixelType,
-                                    ComplexImageType::PixelType,
-                                    ComplexImageType::PixelType,
-                                    ComplexVectorImageType::PixelType> > SinclairToCovFilterType;
-  
-  
+
+  using SinclairToCovFilterType = otb::SinclairToReciprocalCovarianceMatrixImageFilter<ComplexImageType, ComplexVectorImageType>;
+
   typedef itk::MeanImageFilter<ComplexImageType, ComplexImageType>         MeanFilterType;
   typedef otb::PerBandVectorImageFilter<ComplexVectorImageType, ComplexVectorImageType, MeanFilterType> PerBandMeanFilterType;
-  
-  
+
+
   typedef otb::ReciprocalHAlphaImageFilter<ComplexVectorImageType, RealVectorImageType> HAlphaFilterType;
-  
-  
 
   ReaderType::Pointer readerHH = ReaderType::New();
   ReaderType::Pointer readerHV = ReaderType::New();
   ReaderType::Pointer readerVV = ReaderType::New();
-  
+
   WriterType::Pointer writer = WriterType::New();
 
   SinclairToCovFilterType::Pointer sinclairtocov = SinclairToCovFilterType::New();
   PerBandMeanFilterType::Pointer perBand = PerBandMeanFilterType::New();
   HAlphaFilterType::Pointer haafilter = HAlphaFilterType::New();
-        
-  
+
+
   MeanFilterType::InputSizeType radius;
   radius.Fill( size );
   perBand->GetFilter()->SetRadius(radius);
- 
- 
+
+
   readerHH->SetFileName(inputFilenameHH);
   readerHV->SetFileName(inputFilenameHV);
   readerVV->SetFileName(inputFilenameVV);
-  
-  sinclairtocov->SetInputHH(readerHH->GetOutput());
-  sinclairtocov->SetInputHV_VH(readerHV->GetOutput());
-  sinclairtocov->SetInputVV(readerVV->GetOutput());
- 
+
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::hh{}, readerHH->GetOutput());
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::hv_or_vh{}, readerHV->GetOutput());
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::vv{}, readerVV->GetOutput());
+
   perBand->SetInput(sinclairtocov->GetOutput());
-  
-  haafilter->SetInput(perBand->GetOutput());
+
+  haafilter->SetVariadicInput<0>(perBand->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(haafilter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx
index 9561c7b48cc1dbe3f49568603718fd92c2ba781e..1847d859b0896e1bb30c102fff75f85e4d896e10 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx
@@ -27,12 +27,11 @@
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
 #include "itkMeanImageFilter.h"
-#include "otbReciprocalHuynenDecompImageFilter.h"
-#include "otbPerBandVectorImageFilter.h"
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
 
+#include "otbPerBandVectorImageFilter.h"
 
+#include "otbReciprocalHuynenDecompImageFilter.h"
+#include "otbSinclairToReciprocalCovarianceMatrixImageFilter.h"
 
 int otbReciprocalHuynenDecompImageFilter(int itkNotUsed(argc), char * argv[])
 {
@@ -53,50 +52,40 @@ int otbReciprocalHuynenDecompImageFilter(int itkNotUsed(argc), char * argv[])
 
   typedef otb::ImageFileReader<ComplexImageType>  ReaderType;
   typedef otb::ImageFileWriter<ComplexVectorImageType> WriterType;
-  
-  
-  typedef otb::SinclairReciprocalImageFilter<ComplexImageType, ComplexImageType, ComplexImageType, ComplexVectorImageType, 
-  otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor<ComplexImageType::PixelType,
-                                    ComplexImageType::PixelType,
-                                    ComplexImageType::PixelType,
-                                    ComplexVectorImageType::PixelType> > SinclairToCovFilterType;
-  
-  
+
+  using SinclairToCovFilterType = otb::SinclairToReciprocalCovarianceMatrixImageFilter<ComplexImageType, ComplexVectorImageType>;
+
   typedef itk::MeanImageFilter<ComplexImageType, ComplexImageType>         MeanFilterType;
   typedef otb::PerBandVectorImageFilter<ComplexVectorImageType, ComplexVectorImageType, MeanFilterType> PerBandMeanFilterType;
-  
-  
+
   typedef otb::ReciprocalHuynenDecompImageFilter<ComplexVectorImageType, ComplexVectorImageType> FilterType;
-  
-  
+
 
   ReaderType::Pointer readerHH = ReaderType::New();
   ReaderType::Pointer readerHV = ReaderType::New();
   ReaderType::Pointer readerVV = ReaderType::New();
-  
+
   WriterType::Pointer writer = WriterType::New();
 
   SinclairToCovFilterType::Pointer sinclairtocov = SinclairToCovFilterType::New();
   PerBandMeanFilterType::Pointer perBand = PerBandMeanFilterType::New();
   FilterType::Pointer huynenfilter = FilterType::New();
-        
-  
+
   MeanFilterType::InputSizeType radius;
   radius.Fill( size );
   perBand->GetFilter()->SetRadius(radius);
- 
- 
+
   readerHH->SetFileName(inputFilenameHH);
   readerHV->SetFileName(inputFilenameHV);
   readerVV->SetFileName(inputFilenameVV);
-  
-  sinclairtocov->SetInputHH(readerHH->GetOutput());
-  sinclairtocov->SetInputHV_VH(readerHV->GetOutput());
-  sinclairtocov->SetInputVV(readerVV->GetOutput());
- 
+
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::hh{}, readerHH->GetOutput());
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::hv_or_vh{}, readerHV->GetOutput());
+  sinclairtocov->SetVariadicNamedInput(otb::polarimetry_tags::vv{}, readerVV->GetOutput());
+
   perBand->SetInput(sinclairtocov->GetOutput());
-  
-  huynenfilter->SetInput(perBand->GetOutput());
+
+  huynenfilter->SetVariadicInput<0>(perBand->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(huynenfilter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.cxx
index 24d50369400a5a2c9977e088e3237c4808e3fdb7..6429dcc90b6fd01c7633ef0ca48e9423267f7d11 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter.cxx
@@ -49,7 +49,7 @@ int otbReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter(int i
   reader->SetFileName(inputFilename);
 
   FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(reader->GetOutput());
+  filter->SetVariadicInput<0>(reader->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(filter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalPauliDecomp.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalPauliDecomp.cxx
index 587a33ef650ba410fe03e669b033af6929387180..7425e1c385295bcd06e0cd7a740c4f7b50375662 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalPauliDecomp.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalPauliDecomp.cxx
@@ -26,9 +26,10 @@
 #include "otbVectorImage.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
-#include "otbReciprocalPauliDecompImageFilter.h"
+
 #include "otbNRIBandImagesToOneNComplexBandsImage.h"
 
+#include "otbReciprocalPauliDecompImageFilter.h"
 
 
 int otbReciprocalPauliDecompImageFilter(int itkNotUsed(argc), char * argv[])
@@ -50,25 +51,25 @@ int otbReciprocalPauliDecompImageFilter(int itkNotUsed(argc), char * argv[])
 
   typedef otb::ImageFileReader<RealVectorImageType>  ReaderType;
   typedef otb::ImageFileWriter<ComplexVectorImageType> WriterType;
-  
+
   typedef otb::ReciprocalPauliDecompImageFilter<ComplexVectorImageType, ComplexVectorImageType> FilterType;
-  
+
   ReaderType::Pointer readerHH = ReaderType::New();
   ReaderType::Pointer readerHV = ReaderType::New();
   ReaderType::Pointer readerVV = ReaderType::New();
   NRITOOneCFilterType::Pointer nriToOneCfilter = NRITOOneCFilterType::New();
   WriterType::Pointer writer = WriterType::New();
   FilterType::Pointer paulifilter = FilterType::New();
-        
+
   readerHH->SetFileName(inputFilenameHH);
   readerHV->SetFileName(inputFilenameHV);
   readerVV->SetFileName(inputFilenameVV);
-  
+
   nriToOneCfilter->SetInput(0,readerHH->GetOutput());
   nriToOneCfilter->SetInput(1,readerHV->GetOutput());
   nriToOneCfilter->SetInput(2,readerVV->GetOutput());
- 
-  paulifilter->SetInput(nriToOneCfilter->GetOutput());
+
+  paulifilter->SetVariadicInput<0>(nriToOneCfilter->GetOutput());
 
   writer->SetFileName(outputFilename);
   writer->SetInput(paulifilter->GetOutput());
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairImageFilter.cxx
index 2e2c24245cd6ddcd643f3727f22bde08f3210c63..0ca8de7563f245aa481bdd07f55dc5db4449843f 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairImageFilter.cxx
@@ -26,32 +26,35 @@
 #include "otbImage.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
-#include "otbSinclairImageFilter.h"
-#include "otbSinclairToCircularCovarianceMatrixFunctor.h"
-#include "otbSinclairToCoherencyMatrixFunctor.h"
-#include "otbSinclairToMuellerMatrixFunctor.h"
-#include "otbMultiChannelExtractROI.h"
 
+#include "otbSinclairToCoherencyMatrixImageFilter.h"
+#include "otbSinclairToCovarianceMatrixImageFilter.h"
+#include "otbSinclairToCircularCovarianceMatrixImageFilter.h"
+#include "otbSinclairToMuellerMatrixImageFilter.h"
+
+#include "otbMultiChannelExtractROI.h"
 
 
+using namespace otb;
 
-template<class TInputPixel, class TOutputPixel, class TFunction>
-int generic_SinclairImageFilter(int itkNotUsed(argc), char * argv[])
+template <class TFilter>
+int generic_SinclairImageFilter(int itkNotUsed(argc), char* argv[])
 {
   const char * outputFilename = argv[4];
 
-  typedef otb::VectorImage<TOutputPixel> OutputImageType;
+  using OutputImageType = typename TFilter::OutputImageType;
+  using InputImageType  = typename TFilter::Superclass::template InputImageType<0>;
+  using OutputPixelType = typename OutputImageType::InternalPixelType;
+
   typedef otb::ImageFileWriter<OutputImageType> WriterType;
 
   const char * inputFilename1  = argv[1];
   const char * inputFilename2  = argv[2];
   const char * inputFilename3  = argv[3];
 
-  typedef otb::Image<TInputPixel> InputImageType;
-  typedef otb::VectorImage<TOutputPixel> OutputImageType;
   typedef otb::ImageFileReader<InputImageType> ReaderType;
-  typedef otb::MultiChannelExtractROI<TOutputPixel, TOutputPixel > ExtractROIType;
-  typedef otb::SinclairImageFilter<InputImageType, InputImageType, InputImageType, InputImageType, OutputImageType, TFunction> FilterType;
+  typedef otb::MultiChannelExtractROI<OutputPixelType, OutputPixelType> ExtractROIType;
+  using FilterType                     = TFilter;
   typename FilterType::Pointer filter = FilterType::New();
   typename ReaderType::Pointer reader1 = ReaderType::New();
   typename ReaderType::Pointer reader2 = ReaderType::New();
@@ -60,10 +63,10 @@ int generic_SinclairImageFilter(int itkNotUsed(argc), char * argv[])
   reader1->SetFileName(inputFilename1);
   reader2->SetFileName(inputFilename2);
   reader3->SetFileName(inputFilename3);
-  filter->SetInputHH(reader1->GetOutput());
-  filter->SetInputHV(reader2->GetOutput());
-  filter->SetInputVH(reader2->GetOutput());
-  filter->SetInputVV(reader3->GetOutput());
+  filter->SetVariadicNamedInput(polarimetry_tags::hh{}, reader1->GetOutput());
+  filter->SetVariadicNamedInput(polarimetry_tags::hv{}, reader2->GetOutput());
+  filter->SetVariadicNamedInput(polarimetry_tags::vh{}, reader2->GetOutput());
+  filter->SetVariadicNamedInput(polarimetry_tags::vv{}, reader3->GetOutput());
 
   filter->UpdateOutputInformation();
 
@@ -94,41 +97,23 @@ int otbSinclairImageFilter(int argc, char * argv[])
   typedef otb::VectorImage<OutputPixelType, Dimension> OutputImageType;
   typedef otb::VectorImage<OutputRealPixelType, Dimension> OutputRealImageType;
 
+  using CohSRFilterType = SinclairToCoherencyMatrixImageFilter<InputImageType, OutputImageType>;
+  using CovSRFilterType = SinclairToCovarianceMatrixImageFilter<InputImageType, OutputImageType>;
+  using CCSRFilterType  = SinclairToCircularCovarianceMatrixImageFilter<InputImageType, OutputImageType>;
+  using MSRFilterType   = SinclairToMuellerMatrixImageFilter<InputImageType, OutputRealImageType>;
+
+
   std::string strArgv(argv[1]);
   argc--;
   argv++;
   if (strArgv == "SinclairToCovarianceMatrix")
-    return (generic_SinclairImageFilter<InputPixelType, OutputPixelType,
-                otb::Functor::SinclairToCovarianceMatrixFunctor<InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    OutputImageType::PixelType> >
-                  (argc, argv));
+    return (generic_SinclairImageFilter<CovSRFilterType>(argc, argv));
   else  if (strArgv == "SinclairToCircularCovarianceMatrix")
-    return (generic_SinclairImageFilter<InputPixelType, OutputPixelType,
-                otb::Functor::SinclairToCircularCovarianceMatrixFunctor<InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    OutputImageType::PixelType> >
-                  (argc, argv));
+    return (generic_SinclairImageFilter<CCSRFilterType>(argc, argv));
   else  if (strArgv == "SinclairToCoherencyMatrix")
-    return (generic_SinclairImageFilter<InputPixelType, OutputPixelType,
-                otb::Functor::SinclairToCoherencyMatrixFunctor<InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    OutputImageType::PixelType> >
-                  (argc, argv));
+    return (generic_SinclairImageFilter<CohSRFilterType>(argc, argv));
   else  if (strArgv == "SinclairToMuellerMatrix")
-    return (generic_SinclairImageFilter<InputPixelType, OutputRealPixelType,
-                otb::Functor::SinclairToMuellerMatrixFunctor<InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    OutputRealImageType::PixelType> >
-                  (argc, argv));
+    return (generic_SinclairImageFilter<MSRFilterType>(argc, argv));
   else return EXIT_FAILURE;
 
   return EXIT_SUCCESS;
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx
index 471c300ecf8ec0943648c9398898774b75afa45a..1769d5412780ca42a7e66dddd52204b293ad6430 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx
@@ -18,37 +18,39 @@
  * limitations under the License.
  */
 
-
-
 #include <iostream>
 #include <typeinfo>
 
 #include "otbImage.h"
 #include "otbImageFileReader.h"
 #include "otbImageFileWriter.h"
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
-#include "otbMultiChannelExtractROI.h"
 
+#include "otbMultiChannelExtractROI.h"
 
+#include "otbSinclairToReciprocalCoherencyMatrixImageFilter.h"
+#include "otbSinclairToReciprocalCovarianceMatrixImageFilter.h"
+#include "otbSinclairToReciprocalCircularCovarianceMatrixImageFilter.h"
 
+using namespace otb;
 
-template<class TInputPixel, class TOutputPixel, class TFunction>
-int generic_SinclairReciprocalImageFilter(int itkNotUsed(argc), char * argv[])
+template <class TFilter>
+int generic_SinclairReciprocalImageFilter(int itkNotUsed(argc), char* argv[])
 {
   const char * inputFilename1 = argv[1];
   const char * inputFilename2 = argv[2];
   const char * inputFilename3 = argv[3];
   const char * outputFilename = argv[4];
 
-  typedef otb::Image<TInputPixel> InputImageType;
-  typedef otb::VectorImage<TOutputPixel> OutputImageType;
+  using OutputImageType = typename TFilter::OutputImageType;
+  using InputImageType  = typename TFilter::Superclass::template InputImageType<0>;
+  using OutputPixelType = typename OutputImageType::InternalPixelType;
+
   typedef otb::ImageFileReader<InputImageType> ReaderType;
   typedef otb::ImageFileWriter<OutputImageType> WriterType;
 
-  typedef otb::MultiChannelExtractROI<TOutputPixel, TOutputPixel > ExtractROIType;
-  typedef otb::SinclairReciprocalImageFilter<InputImageType, InputImageType, InputImageType, OutputImageType, TFunction> FilterType;
+  typedef otb::MultiChannelExtractROI<OutputPixelType, OutputPixelType> ExtractROIType;
+
+  using FilterType = TFilter;
 
   typename FilterType::Pointer filter = FilterType::New();
   typename ReaderType::Pointer reader1 = ReaderType::New();
@@ -59,9 +61,9 @@ int generic_SinclairReciprocalImageFilter(int itkNotUsed(argc), char * argv[])
   reader2->SetFileName(inputFilename2);
   reader3->SetFileName(inputFilename3);
 
-  filter->SetInputHH(reader1->GetOutput());
-  filter->SetInputHV_VH(reader2->GetOutput());
-  filter->SetInputVV(reader3->GetOutput());
+  filter->SetVariadicNamedInput(polarimetry_tags::hh{}, reader1->GetOutput());
+  filter->SetVariadicNamedInput(polarimetry_tags::hv_or_vh{}, reader2->GetOutput());
+  filter->SetVariadicNamedInput(polarimetry_tags::vv{}, reader3->GetOutput());
 
   typename ExtractROIType::Pointer  extract = ExtractROIType::New();
   extract->SetStartX(10);
@@ -89,30 +91,19 @@ int otbSinclairReciprocalImageFilter(int argc, char * argv[])
   typedef otb::Image<InputPixelType,  Dimension>       InputImageType;
   typedef otb::VectorImage<OutputPixelType, Dimension> OutputImageType;
 
+  using SToRecCohFilterType     = SinclairToReciprocalCoherencyMatrixImageFilter<InputImageType, OutputImageType>;
+  using SToRecCovFilterType     = SinclairToReciprocalCovarianceMatrixImageFilter<InputImageType, OutputImageType>;
+  using SToRecCircCovFilterType = SinclairToReciprocalCircularCovarianceMatrixImageFilter<InputImageType, OutputImageType>;
+
   std::string strArgv(argv[1]);
   argc--;
   argv++;
   if (strArgv == "SinclairToReciprocalCovarianceMatrix")
-    return (generic_SinclairReciprocalImageFilter<InputPixelType, OutputPixelType,
-                otb::Functor::SinclairToReciprocalCovarianceMatrixFunctor<InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    OutputImageType::PixelType> >
-                  (argc, argv));
-  else  if (strArgv == "SinclairToReciprocalCircularCovarianceMatrix")
-    return (generic_SinclairReciprocalImageFilter<InputPixelType, OutputPixelType,
-                otb::Functor::SinclairToReciprocalCircularCovarianceMatrixFunctor<InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    OutputImageType::PixelType> >
-                  (argc, argv));
+    return generic_SinclairReciprocalImageFilter<SToRecCovFilterType>(argc, argv);
   else  if (strArgv == "SinclairToReciprocalCoherencyMatrix")
-    return (generic_SinclairReciprocalImageFilter<InputPixelType, OutputPixelType,
-                otb::Functor::SinclairToReciprocalCoherencyMatrixFunctor<InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    InputImageType::PixelType,
-                                    OutputImageType::PixelType> >
-                  (argc, argv));
+    return generic_SinclairReciprocalImageFilter<SToRecCohFilterType>(argc, argv);
+  else if (strArgv == "SinclairToReciprocalCircularCovarianceMatrix")
+    return generic_SinclairReciprocalImageFilter<SToRecCircCovFilterType>(argc, argv);
   else return EXIT_FAILURE;
 
   return EXIT_SUCCESS;
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx
index 115738e3b77335a47cd76939dff69484cab51a9a..0547cc98602282dc27927733f1a72f6488bcc3c7 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToCircularCovarianceMatrixFunctor.cxx
@@ -19,7 +19,7 @@
  */
 
 
-#include "otbSinclairToCircularCovarianceMatrixFunctor.h"
+#include "otbSinclairToCircularCovarianceMatrixImageFilter.h"
 #include "itkVariableLengthVector.h"
 
 int otbSinclairToCircularCovarianceMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
@@ -31,7 +31,7 @@ int otbSinclairToCircularCovarianceMatrixFunctor(int itkNotUsed(argc), char * it
 
   OutputType  result(10);
   FunctorType funct;
-  OutputType outputFunct;
+  OutputType  outputFunct(10);
 
   result[0] = ComplexType( 32.,  0. );
   result[1] = ComplexType(  24., 0. );
@@ -44,7 +44,7 @@ int otbSinclairToCircularCovarianceMatrixFunctor(int itkNotUsed(argc), char * it
   result[8] = ComplexType(  4.,   0. );
   result[9] = ComplexType(  2,    0. );
 
-  outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.) );
+  funct.operator()(outputFunct, ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.));
 
 
   if( std::abs(result[0]-outputFunct[0]) > 1e-10 ||
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToCoherencyMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToCoherencyMatrixFunctor.cxx
index b4c0ac4f7e1aa0899e499f1cd4afc36ab7fb7063..16f6803b2e4f81e935b1fad5c7a06579c1556e7b 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToCoherencyMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToCoherencyMatrixFunctor.cxx
@@ -19,7 +19,7 @@
  */
 
 
-#include "otbSinclairToCoherencyMatrixFunctor.h"
+#include "otbSinclairToCoherencyMatrixImageFilter.h"
 #include "itkVariableLengthVector.h"
 
 int otbSinclairToCoherencyMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
@@ -31,7 +31,7 @@ int otbSinclairToCoherencyMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(
 
   OutputType  result(10);
   FunctorType funct;
-  OutputType outputFunct;
+  OutputType  outputFunct(10);
 
   result[0] = ComplexType(25., 0.);
   result[1] = ComplexType( 0., -15.);
@@ -44,7 +44,7 @@ int otbSinclairToCoherencyMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(
   result[8] = ComplexType(-5., 0.);
   result[9] = ComplexType( 1., 0.);
 
-  outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.) );
+  funct.operator()(outputFunct, ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.));
 
   if( std::abs(result[0]-outputFunct[0]) > 1e-10 ||
       std::abs(result[1]-outputFunct[1]) > 1e-10 ||
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToCovarianceMatrixFunctor.cxx
index 9de6d61a8ade01160c0dd66f2a846baf2a32b2c9..8fa1e279f98aa6bfb10f5aa0759b181f520351ba 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToCovarianceMatrixFunctor.cxx
@@ -20,7 +20,7 @@
 
 #include "itkMacro.h"
 
-#include "otbSinclairToCovarianceMatrixFunctor.h"
+#include "otbSinclairToCovarianceMatrixImageFilter.h"
 #include "itkVariableLengthVector.h"
 
 int otbSinclairToCovarianceMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
@@ -32,7 +32,7 @@ int otbSinclairToCovarianceMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed
 
   OutputType  result(10);
   FunctorType funct;
-  OutputType outputFunct;
+  OutputType  outputFunct(16);
 
   result[0] = ComplexType(17.,  0. );
   result[1] = ComplexType(14.,  5.);
@@ -45,8 +45,7 @@ int otbSinclairToCovarianceMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed
   result[8] = ComplexType(14.,  5.);
   result[9] = ComplexType(17.,  0.);
 
-
-  outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.) );
+  funct.operator()(outputFunct, ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.));
 
   if( std::abs(result[0]-outputFunct[0]) > 1e-10 ||
       std::abs(result[1]-outputFunct[1]) > 1e-10 ||
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToMuellerMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToMuellerMatrixFunctor.cxx
index e70c4a416ef50acbfa9dd9cc3e25a7c182b9b7dc..39c5e0046abf3b18595731694dc333ce0cfca6ac 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToMuellerMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToMuellerMatrixFunctor.cxx
@@ -20,7 +20,7 @@
 
 #include "itkMacro.h"
 
-#include "otbSinclairToMuellerMatrixFunctor.h"
+#include "otbSinclairToMuellerMatrixImageFilter.h"
 #include "itkVariableLengthVector.h"
 
 int otbSinclairToMuellerMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
@@ -32,7 +32,7 @@ int otbSinclairToMuellerMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(ar
 
   OutputType  result(16);
   FunctorType funct;
-  OutputType outputFunct;
+  OutputType  outputFunct(16);
 
   result[0]  =  30.;
   result[1]  =   0.;
@@ -51,7 +51,7 @@ int otbSinclairToMuellerMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(ar
   result[14] =  20.;
   result[15] =   4.;
 
-  outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.) );
+  funct.operator()(outputFunct, ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.), ComplexType(4., 1.));
 
   if( std::abs(result[0]-outputFunct[0]) > 1e-10 ||
       std::abs(result[1]-outputFunct[1]) > 1e-10 ||
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
index 7ab3dd6b29ece24e8f4d84e934418814b12de155..9e8dde113e0c91c89b0250ab62c06d20a6e70c75 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
@@ -19,7 +19,7 @@
  */
 
 
-#include "otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h"
+#include "otbSinclairToReciprocalCircularCovarianceMatrixImageFilter.h"
 #include "itkVariableLengthVector.h"
 
 int otbSinclairToReciprocalCircularCovarianceMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
@@ -31,7 +31,7 @@ int otbSinclairToReciprocalCircularCovarianceMatrixFunctor(int itkNotUsed(argc),
 
   OutputType  result(6);
   FunctorType funct;
-  OutputType outputFunct;
+  OutputType  outputFunct(6);
 
   result[0] = ComplexType( 25.,  0.);
   result[1] = ComplexType( 25.4558441227157,-1.4142135623731);
@@ -40,7 +40,7 @@ int otbSinclairToReciprocalCircularCovarianceMatrixFunctor(int itkNotUsed(argc),
   result[4] = ComplexType( 11.3137084989848,-1.41421356237309);
   result[5] = ComplexType( 5, .0);
 
-  outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.) );
+  funct.operator()(outputFunct, ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.));
 
   if( std::abs(result[0]-outputFunct[0]) > 1e-10 ||
       std::abs(result[1]-outputFunct[1]) > 1e-10 ||
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCoherencyMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCoherencyMatrixFunctor.cxx
index 4caad27012ce9599b6514c59813c80c578722256..ee389f4a38b11999921ac0287a394402636f5f70 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCoherencyMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCoherencyMatrixFunctor.cxx
@@ -20,7 +20,7 @@
 
 #include "itkMacro.h"
 
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
+#include "otbSinclairToReciprocalCoherencyMatrixImageFilter.h"
 #include "itkVariableLengthVector.h"
 
 int otbSinclairToReciprocalCoherencyMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
@@ -32,7 +32,7 @@ int otbSinclairToReciprocalCoherencyMatrixFunctor(int itkNotUsed(argc), char * i
 
   OutputType  result(6);
   FunctorType funct;
-  OutputType outputFunct;
+  OutputType  outputFunct(6);
 
   result[0] = ComplexType(26.,  0.);
   result[1] = ComplexType( 2., -10.);
@@ -41,7 +41,7 @@ int otbSinclairToReciprocalCoherencyMatrixFunctor(int itkNotUsed(argc), char * i
   result[4] = ComplexType( 2., 10.);
   result[5] = ComplexType(26.,  0.);
 
- outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.) );
+  funct.operator()(outputFunct, ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.));
   if( std::abs(result[0]-outputFunct[0]) > 1e-10 ||
       std::abs(result[1]-outputFunct[1]) > 1e-10 ||
       std::abs(result[2]-outputFunct[2]) > 1e-10 ||
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
index 8ad32897ac9afdacb4824d928893b91d5363a4a2..537d56ea7e55f355f3b48a84d622c1025db5617a 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
@@ -20,7 +20,7 @@
 
 #include "itkMacro.h"
 
-#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
+#include "otbSinclairToReciprocalCovarianceMatrixImageFilter.h"
 #include "itkVariableLengthVector.h"
 
 int otbSinclairToReciprocalCovarianceMatrixFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
@@ -32,7 +32,7 @@ int otbSinclairToReciprocalCovarianceMatrixFunctor(int itkNotUsed(argc), char *
 
   OutputType  result(6);
   FunctorType funct;
-  OutputType outputFunct;
+  OutputType  outputFunct(6);
 
   result[0] = ComplexType(17.,  0.);
   result[1] = ComplexType(19.7989898732233,7.07106781186548);
@@ -41,7 +41,7 @@ int otbSinclairToReciprocalCovarianceMatrixFunctor(int itkNotUsed(argc), char *
   result[4] = ComplexType(16.9705627484771,7.07106781186548);
   result[5] = ComplexType(13.,  0.);
 
-  outputFunct = funct.operator ()( ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.) );
+  funct.operator()(outputFunct, ComplexType(1., 4.), ComplexType(2., 3.), ComplexType(3., 2.));
 
   if( std::abs(result[0]-outputFunct[0]) > 1e-10 ||
       std::abs(result[1]-outputFunct[1]) > 1e-10 ||