From ef4a460723a47a2cabdd093ffed848e53ee4aba1 Mon Sep 17 00:00:00 2001
From: Manuel Grizonnet <manuel.grizonnet@cnes.fr>
Date: Mon, 10 Dec 2018 17:07:59 +0100
Subject: [PATCH] WIP: start refactoring of monostatic polarimetric filters
 using FunctorImageFilter

---
 .../app/otbSARDecompositions.cxx              | 110 +++++++++---------
 .../app/otbSARPolarMatrixConvert.cxx          |  74 ++++--------
 .../Polarimetry/include/otbPolarimetryTags.h  |   1 +
 .../include/otbSinclairImageFilters.h         |  30 +++++
 ...eciprocalCircularCovarianceMatrixFunctor.h |  15 +--
 ...nclairToReciprocalCoherencyMatrixFunctor.h |  25 ++--
 ...clairToReciprocalCovarianceMatrixFunctor.h |  20 ++--
 .../test/otbReciprocalBarnesDecomp.cxx        |  45 +++----
 .../test/otbReciprocalHAlphaImageFilter.cxx   |  43 +++----
 .../test/otbReciprocalHuynenDecomp.cxx        |  43 +++----
 .../test/otbSinclairReciprocalImageFilter.cxx |  55 ++++-----
 ...iprocalCircularCovarianceMatrixFunctor.cxx |   4 +-
 ...lairToReciprocalCoherencyMatrixFunctor.cxx |   4 +-
 ...airToReciprocalCovarianceMatrixFunctor.cxx |   4 +-
 14 files changed, 213 insertions(+), 260 deletions(-)

diff --git a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
index 2a6ccbcf08..5df2ba748e 100644
--- a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
+++ b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx
@@ -50,28 +50,23 @@ 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 SinclairToReciprocalCoherencyMatrixFilter<ComplexDoubleImageType::PixelType,ComplexDoubleVectorImageType> SRFilterType;
+
   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;
@@ -95,13 +90,13 @@ private:
                           "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"   
+                          "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 +106,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 +130,10 @@ 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,44 +162,44 @@ private:
 
   void DoExecute() override
   {
-	  
+
 	bool inhv = HasUserValue("inhv");
 	bool invh = HasUserValue("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"));
+		  m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
 	    else if (invh)
-		  m_SRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+		  m_SRFilter->SetVariadicNamedInput<polarimetry_tags::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_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)
@@ -214,16 +209,16 @@ private:
 
 		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
 
 		if (inhv)
@@ -233,16 +228,16 @@ private:
 
 		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_ImageList->PushBack(GetParameterComplexDoubleImage("inhh"));
@@ -253,18 +248,17 @@ private:
 		  m_ImageList->PushBack(GetParameterComplexDoubleImage("invh"));
 
 		m_ImageList->PushBack(GetParameterComplexDoubleImage("invv"));
-        
-        m_Concatener->SetInput( m_ImageList );        
+
+        m_Concatener->SetInput( m_ImageList );
         m_PauliFilter->SetInput(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 +267,8 @@ 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 a61786e249..c996bd558e 100644
--- a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
+++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx
@@ -21,13 +21,11 @@
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
-
-
 //monostatic case
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
-#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
-#include "otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h"
+//#include "otbSinclairReciprocalImageFilter.h"
+//#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
+//#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
+//#include "otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h"
 
 #include "otbReciprocalCoherencyToReciprocalMuellerImageFilter.h"
 #include "otbReciprocalCovarianceToCoherencyDegreeImageFilter.h"
@@ -58,43 +56,12 @@ public:
 
 
   //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;
-
+  using RCohSRFilterType = SinclairToReciprocalCoherencyMatrixFilter<ComplexDoubleImageType,ComplexDoubleVectorImageType>;
+  using RCovSRFilterType = SinclairToReciprocalCovarianceMatrixFilter<ComplexDoubleImageType,ComplexDoubleVectorImageType>;
+  using RCCSRFilterType = SinclairToReciprocalCircularCovarianceMatrixFilter<ComplexDoubleImageType,ComplexDoubleVectorImageType>;
 
-    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::ReciprocalCoherencyToReciprocalMuellerImageFilter<ComplexDoubleVectorImageType, DoubleVectorImageType> RCRMFilterType;
 
 	typedef otb::ReciprocalCovarianceToCoherencyDegreeImageFilter<ComplexDoubleVectorImageType, ComplexDoubleVectorImageType> RCCDFilterType;
 
@@ -110,7 +77,6 @@ public:
   using MSRFilterType   = SinclairToMuellerMatrixFilter<ComplexDoubleImageType,DoubleVectorImageType>;
 
 
-
 	typedef otb::MuellerToReciprocalCovarianceImageFilter<DoubleVectorImageType, ComplexDoubleVectorImageType>  MRCFilterType;
 
 	typedef otb::MuellerToPolarisationDegreeAndPowerImageFilter<DoubleVectorImageType, DoubleVectorImageType>   MPDPFilterType;
@@ -441,12 +407,12 @@ private:
 	  	m_RCohSRFilter = RCohSRFilterType::New();
 
 	    if (inhv)
-		  m_RCohSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
+		  m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
 	    else if (invh)
-		  m_RCohSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+		  m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
 
-		m_RCohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_RCohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		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
 
@@ -458,12 +424,12 @@ private:
 		m_RCovSRFilter = RCovSRFilterType::New();
 
 		if (inhv)
-		  m_RCovSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
+		  m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
 	    else if (invh)
-		  m_RCovSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+		  m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
 
-		m_RCovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_RCovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		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
 
@@ -476,12 +442,12 @@ private:
 		m_RCCSRFilter = RCCSRFilterType::New();
 
 		if (inhv)
-		  m_RCCSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("inhv"));
+		  m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
 	    else if (invh)
-		  m_RCCSRFilter->SetInputHV_VH(GetParameterComplexDoubleImage("invh"));
+		  m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
 
-		m_RCCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh"));
-		m_RCCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv"));
+		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
 
diff --git a/Modules/Filtering/Polarimetry/include/otbPolarimetryTags.h b/Modules/Filtering/Polarimetry/include/otbPolarimetryTags.h
index d38ca71ffa..80f0b26716 100644
--- a/Modules/Filtering/Polarimetry/include/otbPolarimetryTags.h
+++ b/Modules/Filtering/Polarimetry/include/otbPolarimetryTags.h
@@ -29,6 +29,7 @@ namespace otb
     struct hv {};
     struct vh {};
     struct vv {};
+    struct hv_or_vh{};
   } // end namespace polarimetry_tags
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairImageFilters.h b/Modules/Filtering/Polarimetry/include/otbSinclairImageFilters.h
index 3a9994eddc..8fbf37d0b9 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairImageFilters.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairImageFilters.h
@@ -21,13 +21,21 @@
 #ifndef otbSinclairImageFilters_h
 #define otbSinclairImageFilters_h
 
+// Generic polarimetry functors
 #include "otbPolarimetryTags.h"
 #include "otbFunctorImageFilter.h"
+
+// Bistatic functors
 #include "otbSinclairToCovarianceMatrixFunctor.h"
 #include "otbSinclairToCircularCovarianceMatrixFunctor.h"
 #include "otbSinclairToCoherencyMatrixFunctor.h"
 #include "otbSinclairToMuellerMatrixFunctor.h"
 
+// Monostatic functors
+#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
+#include "otbSinclairToReciprocalCovarianceMatrixFunctor.h"
+#include "otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h"
+
 namespace otb
 {
 // This is the entire declaration of SinclairToCovarianceMatrixFilter
@@ -58,6 +66,28 @@ using SinclairToMuellerMatrixFilter = FunctorImageFilter<
                                                typename TInputImage::PixelType, typename TOutputImage::PixelType>,
     std::tuple<polarimetry_tags::hh, polarimetry_tags::hv, polarimetry_tags::vh, polarimetry_tags::vv>>;
 
+// Monostatic filters
+// Convert the Sinclair reciprocal matrix
+
+// SinclairToReciprocalCoherencyMatrixFilter
+template <typename TInputImage, typename TOutputImage>
+using SinclairToReciprocalCoherencyMatrixFilter = 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>>;
+
+// SinclairToReciprocalCoherencyMatrixFilter
+template <typename TInputImage, typename TOutputImage>
+using SinclairToReciprocalCovarianceMatrixFilter = 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>>;
+
+// SinclairToReciprocalCircularCovarianceMatrixFilter
+template <typename TInputImage, typename TOutputImage>
+using SinclairToReciprocalCircularCovarianceMatrixFilter = 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>>;
+
+
 
 } // end namespace otb
 
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
index 02fe39e304..85e33689c0 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.h
@@ -69,13 +69,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)
   {
-    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,7 +88,7 @@ public:
 
 
     SinclairToReciprocalCovarianceFunctorType funct;
-    return ( funct(Sll, Slr, Srr ) );
+    funct(result, Sll, Slr, Srr);
   }
 
   unsigned int GetNumberOfComponentsPerPixel()
@@ -101,6 +96,12 @@ public:
     return m_NumberOfComponentsPerPixel;
   }
 
+  constexpr size_t OutputSize(...) const
+  {
+    // Size of the  matrix
+    return 6;
+  }
+
   /** Constructor */
   SinclairToReciprocalCircularCovarianceMatrixFunctor() : m_NumberOfComponentsPerPixel(6) {}
 
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
index f9a3ec46f7..dd61ee5c4b 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCoherencyMatrixFunctor.h
@@ -69,20 +69,16 @@ 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);
+  itkStaticConstMacro(NumberOfComponentsPerPixel, unsigned int, 6);
 
+  inline void operator ()(TOutput & result, const TInput1& Shh, const TInput2& Shv, const TInput3& Svv)
+  {
     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);
@@ -90,16 +86,13 @@ public:
 
 
     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()
@@ -107,6 +100,12 @@ public:
     return NumberOfComponentsPerPixel;
   }
 
+  constexpr size_t OutputSize(...) const
+  {
+    // Size of the  matrix
+    return 6;
+  }
+
   /** Constructor */
   SinclairToReciprocalCoherencyMatrixFunctor() {}
 
diff --git a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
index f24ee87fdb..2e7275a5f5 100644
--- a/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
+++ b/Modules/Filtering/Polarimetry/include/otbSinclairToReciprocalCovarianceMatrixFunctor.h
@@ -68,31 +68,25 @@ 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)
   {
-    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()
@@ -100,6 +94,12 @@ public:
     return NumberOfComponentsPerPixel;
   }
 
+  constexpr size_t OutputSize(...) const
+  {
+    // Size of the  matrix
+    return 6;
+  }
+
   /** Constructor */
   SinclairToReciprocalCovarianceMatrixFunctor() {}
 
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx
index 989d79ca36..c18bd11ed3 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalBarnesDecomp.cxx
@@ -29,9 +29,8 @@
 #include "itkMeanImageFilter.h"
 #include "otbReciprocalBarnesDecompImageFilter.h"
 #include "otbPerBandVectorImageFilter.h"
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
 
+#include "otbSinclairImageFilters.h"
 
 
 int otbReciprocalBarnesDecompImageFilter(int itkNotUsed(argc), char * argv[])
@@ -53,49 +52,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::SinclairToReciprocalCovarianceMatrixFilter<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());
 
   writer->SetFileName(outputFilename);
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx
index 489b5ae6ca..bfb6dc9696 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalHAlphaImageFilter.cxx
@@ -29,9 +29,8 @@
 #include "otbReciprocalHAlphaImageFilter.h"
 #include "itkMeanImageFilter.h"
 #include "otbPerBandVectorImageFilter.h"
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
 
+#include "otbSinclairImageFilters.h"
 
 int otbReciprocalHAlphaImageFilter(int itkNotUsed(argc), char * argv[])
 {
@@ -54,49 +53,41 @@ 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::SinclairToReciprocalCovarianceMatrixFilter<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());
 
   writer->SetFileName(outputFilename);
diff --git a/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx b/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx
index 9561c7b48c..31bf2e5674 100644
--- a/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbReciprocalHuynenDecomp.cxx
@@ -29,10 +29,8 @@
 #include "itkMeanImageFilter.h"
 #include "otbReciprocalHuynenDecompImageFilter.h"
 #include "otbPerBandVectorImageFilter.h"
-#include "otbSinclairReciprocalImageFilter.h"
-#include "otbSinclairToReciprocalCoherencyMatrixFunctor.h"
-
 
+#include "otbSinclairImageFilters.h"
 
 int otbReciprocalHuynenDecompImageFilter(int itkNotUsed(argc), char * argv[])
 {
@@ -53,49 +51,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::SinclairToReciprocalCovarianceMatrixFilter<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());
 
   writer->SetFileName(outputFilename);
diff --git a/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx
index 471c300ecf..f52ef63d5a 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairReciprocalImageFilter.cxx
@@ -18,23 +18,20 @@
  * 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 "otbSinclairImageFilters.h"
 
+#include "otbMultiChannelExtractROI.h"
 
+using namespace otb;
 
-template<class TInputPixel, class TOutputPixel, class TFunction>
+template<class TFilter>
 int generic_SinclairReciprocalImageFilter(int itkNotUsed(argc), char * argv[])
 {
   const char * inputFilename1 = argv[1];
@@ -42,13 +39,16 @@ int generic_SinclairReciprocalImageFilter(int itkNotUsed(argc), char * argv[])
   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 +59,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 +89,19 @@ int otbSinclairReciprocalImageFilter(int argc, char * argv[])
   typedef otb::Image<InputPixelType,  Dimension>       InputImageType;
   typedef otb::VectorImage<OutputPixelType, Dimension> OutputImageType;
 
+  using SToRecCohFilterType = SinclairToReciprocalCoherencyMatrixFilter<InputImageType, OutputImageType>;
+  using SToRecCovFilterType = SinclairToReciprocalCovarianceMatrixFilter<InputImageType, OutputImageType>;
+  using SToRecCircCovFilterType = SinclairToReciprocalCircularCovarianceMatrixFilter<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/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
index 7ab3dd6b29..77b557682e 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCircularCovarianceMatrixFunctor.cxx
@@ -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 4caad27012..7c7d193947 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCoherencyMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCoherencyMatrixFunctor.cxx
@@ -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 8ad32897ac..32a3d1a3c6 100644
--- a/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
+++ b/Modules/Filtering/Polarimetry/test/otbSinclairToReciprocalCovarianceMatrixFunctor.cxx
@@ -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 ||
-- 
GitLab