From 27f75a1f93c76ec60e864152549446253ccaa784 Mon Sep 17 00:00:00 2001
From: Christophe Palmann <christophe.palmann@c-s.fr>
Date: Wed, 29 Jul 2015 18:17:35 +0200
Subject: [PATCH] ENH: Im manipulation, complex band vs RI band conversion
 filters (SAR)

---
 .../otbNRIBandImagesToOneNComplexBandsImage.h |  92 +++++++++++
 ...tbNRIBandImagesToOneNComplexBandsImage.txx | 139 +++++++++++++++++
 .../otbOneRIBandImageToOneComplexBandImage.h  |  91 +++++++++++
 ...otbOneRIBandImageToOneComplexBandImage.txx | 100 ++++++++++++
 .../otbTwoNRIBandsImageToNComplexBandsImage.h |  92 +++++++++++
 ...tbTwoNRIBandsImageToNComplexBandsImage.txx | 143 ++++++++++++++++++
 .../ImageManipulation/test/CMakeLists.txt     |  35 +++++
 .../test/otbImageManipulationTestDriver.cxx   |   3 +
 ...tbNRIBandImagesToOneNComplexBandsImage.cxx |  62 ++++++++
 ...otbOneRIBandImageToOneComplexBandImage.cxx |  56 +++++++
 ...tbTwoNRIBandsImageToNComplexBandsImage.cxx |  56 +++++++
 11 files changed, 869 insertions(+)
 create mode 100644 Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h
 create mode 100644 Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx
 create mode 100644 Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
 create mode 100644 Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx
 create mode 100644 Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
 create mode 100644 Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
 create mode 100644 Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx
 create mode 100644 Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
 create mode 100644 Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx

diff --git a/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h
new file mode 100644
index 0000000000..18f1465b09
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.h
@@ -0,0 +1,92 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbNRIBandImagesToOneNComplexBandsImage_h
+#define __otbNRIBandImagesToOneNComplexBandsImage_h
+
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+/*
+ * Inputs : N images made of two real bands 
+ * Output : one single image made of N complex bands
+ * 
+ * */
+
+
+namespace otb
+{
+
+
+template <class TInputImage, class TOutputImage>
+class ITK_EXPORT NRIBandImagesToOneNComplexBandsImage :  public itk::ImageToImageFilter<TInputImage, TOutputImage>
+{
+public:
+  /**   Extract input and output image dimension */
+  itkStaticConstMacro(InputImageDimension,
+                      unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension,
+                      unsigned int,
+                      TOutputImage::ImageDimension);
+
+  typedef TInputImage  InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  /** standard class typedefs */
+  typedef NRIBandImagesToOneNComplexBandsImage                                           Self;
+  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self>                                  Pointer;
+  typedef itk::SmartPointer<const Self>                            ConstPointer;
+
+  /** Object factory management */
+  itkNewMacro(Self);
+
+  /** typemacro */
+  itkTypeMacro(NRIBandImagesToOneNComplexBandsImage, ImageToImageFilter);
+
+  typedef typename InputImageType::PixelType                    InputPixelType;
+  typedef typename OutputImageType::PixelType                   OutputPixelType;
+  typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+  typedef typename InputImageType::RegionType                   InputImageRegionType;
+  typedef typename OutputImageType::RegionType                  OutputImageRegionType;
+
+
+protected:
+  NRIBandImagesToOneNComplexBandsImage();
+  virtual ~NRIBandImagesToOneNComplexBandsImage() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  void GenerateOutputInformation(void);
+  void BeforeThreadedGenerateData(void);
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            itk::ThreadIdType threadId);
+
+private:
+  NRIBandImagesToOneNComplexBandsImage(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbNRIBandImagesToOneNComplexBandsImage.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx
new file mode 100644
index 0000000000..46abbf79ef
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbNRIBandImagesToOneNComplexBandsImage.txx
@@ -0,0 +1,139 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbNRIBandImagesToOneNComplexBandsImage_txx
+#define __otbNRIBandImagesToOneNComplexBandsImage_txx
+
+#include "otbNRIBandImagesToOneNComplexBandsImage.h"
+
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkProgressReporter.h"
+#include "itkVariableLengthVector.h"
+
+
+
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>::NRIBandImagesToOneNComplexBandsImage()
+{
+	//this->SetNumberOfThreads(1);
+}
+
+/**
+ * GenerateOutputInformation
+ */
+template<class TInputImage, class TOutputImage>
+void
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>
+::GenerateOutputInformation(void)
+{
+  Superclass::GenerateOutputInformation();
+  
+  unsigned int nbInputs = this->GetNumberOfInputs();
+  this->GetOutput()->SetNumberOfComponentsPerPixel(nbInputs);
+  
+}
+
+/**
+ * BeforeThreadedGenerateData
+ */
+template <class TInputImage, class TOutputImage>
+void
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>
+::BeforeThreadedGenerateData(void)
+{
+	unsigned int nbInputs = this->GetNumberOfInputs();
+	
+	for (unsigned int i=0; i<nbInputs; i++)
+		if (this->GetInput(i)->GetNumberOfComponentsPerPixel() != 2 )
+			itkExceptionMacro("Input images must be made of two bands and only two (see input #" << i << ").");
+		
+}
+
+/**
+ * ThreadedGenerateData
+ */
+template<class TInputImage, class TOutputImage>
+void NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutputImage>::ThreadedGenerateData(
+  const OutputImageRegionType&     outputRegionForThread,
+  itk::ThreadIdType threadId
+  )
+{
+ 
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());	
+	
+  unsigned int nbInputs = this->GetNumberOfInputs();	  
+  
+  itk::VariableLengthVector< std::complex< typename InputPixelType::ValueType > > vlv(nbInputs);
+
+  std::vector< typename itk::ImageRegionConstIterator<TInputImage> > vInIt;
+  for (unsigned int i=0; i<nbInputs; i++)
+	vInIt.push_back( itk::ImageRegionConstIterator<TInputImage>(this->GetInput(i), outputRegionForThread) );
+
+	
+  itk::ImageRegionIterator<OutputImageType>      outIt;
+  outIt = itk::ImageRegionIterator<OutputImageType>(this->GetOutput(), outputRegionForThread);
+  
+  for (unsigned int i=0; i<nbInputs; i++)
+	vInIt[i].GoToBegin();
+  outIt.GoToBegin();
+
+  while (!outIt.IsAtEnd())
+  {
+	  
+	  
+	  for (unsigned int i=0; i<nbInputs; i++)
+	  {
+		  vlv[i] = std::complex< typename InputPixelType::ValueType >(vInIt[i].Get()[0],vInIt[i].Get()[1]);
+		//std::cout << "i = " << i << " " << vInIt[i].Get()[0] << " " << vInIt[i].Get()[1] << std::endl;
+	  }
+
+	  
+	  outIt.Set(vlv);
+	  
+	  //std::cout << "outIt.Get() = " << outIt.Get() << std::endl;
+	  
+	  for (unsigned int i=0; i<nbInputs; i++)
+		++vInIt[i];
+	  ++outIt;
+	  
+	  progress.CompletedPixel();
+  }
+  
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void
+NRIBandImagesToOneNComplexBandsImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
new file mode 100644
index 0000000000..7451997214
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h
@@ -0,0 +1,91 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbOneRIBandImageToOneComplexBandImage_h
+#define __otbOneRIBandImageToOneComplexBandImage_h
+
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+
+/*
+ * Inputs : one image made of two real bands 
+ * Output : one image made of one complex band
+ * 
+ * */
+
+namespace otb
+{
+
+
+template <class TInputImage, class TOutputImage>
+class ITK_EXPORT OneRIBandImageToOneComplexBandImage :  public itk::ImageToImageFilter<TInputImage, TOutputImage>
+{
+public:
+  /**   Extract input and output image dimension */
+  itkStaticConstMacro(InputImageDimension,
+                      unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension,
+                      unsigned int,
+                      TOutputImage::ImageDimension);
+
+  typedef TInputImage  InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  /** standard class typedefs */
+  typedef OneRIBandImageToOneComplexBandImage                                           Self;
+  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self>                                  Pointer;
+  typedef itk::SmartPointer<const Self>                            ConstPointer;
+
+  /** Object factory management */
+  itkNewMacro(Self);
+
+  /** typemacro */
+  itkTypeMacro(OneRIBandImageToOneComplexBandImage, ImageToImageFilter);
+
+  typedef typename InputImageType::PixelType                    InputPixelType;
+  typedef typename OutputImageType::PixelType                   OutputPixelType;
+  typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+  typedef typename InputImageType::RegionType                   InputImageRegionType;
+  typedef typename OutputImageType::RegionType                  OutputImageRegionType;
+
+
+protected:
+  OneRIBandImageToOneComplexBandImage();
+  virtual ~OneRIBandImageToOneComplexBandImage() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  void BeforeThreadedGenerateData(void);
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            itk::ThreadIdType threadId);
+
+private:
+  OneRIBandImageToOneComplexBandImage(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbOneRIBandImageToOneComplexBandImage.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx
new file mode 100644
index 0000000000..8a7003a8ee
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.txx
@@ -0,0 +1,100 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbOneRIBandImageToOneComplexBandImage_txx
+#define __otbOneRIBandImageToOneComplexBandImage_txx
+
+#include "otbOneRIBandImageToOneComplexBandImage.h"
+
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkProgressReporter.h"
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>::OneRIBandImageToOneComplexBandImage()
+{
+  //this->SetNumberOfThreads(1);
+}
+
+/**
+ * BeforeThreadedGenerateData
+ */
+template <class TInputImage, class TOutputImage>
+void
+OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>
+::BeforeThreadedGenerateData(void)
+{
+	if (this->GetInput()->GetNumberOfComponentsPerPixel() != 2 )
+			itkExceptionMacro("Input image must be made of two bands and only two.");
+		
+}
+
+/**
+ * ThreadedGenerateData
+ */
+template<class TInputImage, class TOutputImage>
+void OneRIBandImageToOneComplexBandImage<TInputImage, TOutputImage>::ThreadedGenerateData(
+  const OutputImageRegionType&     outputRegionForThread,
+  itk::ThreadIdType threadId
+  )
+{
+	
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());	
+	
+  typename OutputImageType::Pointer     output = this->GetOutput();
+  typename InputImageType::ConstPointer input  = this->GetInput();
+  
+  itk::ImageRegionIterator<OutputImageType>      it;
+   itk::ImageRegionConstIterator<TInputImage>      itIn;
+  
+  itIn = itk::ImageRegionConstIterator<TInputImage>(input, outputRegionForThread);
+  it = itk::ImageRegionIterator<OutputImageType>(output, outputRegionForThread);
+  
+  it.GoToBegin();
+  itIn.GoToBegin();
+  while (!it.IsAtEnd())
+  {
+	  
+	  it.Set(static_cast<OutputPixelType>(   std::complex< typename InputPixelType::ValueType >(itIn.Get()[0],itIn.Get()[1])   ));
+	  
+	  ++it;
+	  ++itIn;
+	  progress.CompletedPixel();
+  }
+  
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void
+OneRIBandImageToOneComplexBandImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
new file mode 100644
index 0000000000..e60a091176
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h
@@ -0,0 +1,92 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbTwoNRIBandsImageToNComplexBandsImage_h
+#define __otbTwoNRIBandsImageToNComplexBandsImage_h
+
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+/*
+ * Inputs : one single image made of 2N real bands 
+ * Output : one single image made of N complex bands
+ * 
+ * */
+
+
+namespace otb
+{
+
+
+template <class TInputImage, class TOutputImage>
+class ITK_EXPORT TwoNRIBandsImageToNComplexBandsImage :  public itk::ImageToImageFilter<TInputImage, TOutputImage>
+{
+public:
+  /**   Extract input and output image dimension */
+  itkStaticConstMacro(InputImageDimension,
+                      unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension,
+                      unsigned int,
+                      TOutputImage::ImageDimension);
+
+  typedef TInputImage  InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  /** standard class typedefs */
+  typedef TwoNRIBandsImageToNComplexBandsImage                                           Self;
+  typedef itk::ImageToImageFilter<InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self>                                  Pointer;
+  typedef itk::SmartPointer<const Self>                            ConstPointer;
+
+  /** Object factory management */
+  itkNewMacro(Self);
+
+  /** typemacro */
+  itkTypeMacro(TwoNRIBandsImageToNComplexBandsImage, ImageToImageFilter);
+
+  typedef typename InputImageType::PixelType                    InputPixelType;
+  typedef typename OutputImageType::PixelType                   OutputPixelType;
+  typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+  typedef typename InputImageType::RegionType                   InputImageRegionType;
+  typedef typename OutputImageType::RegionType                  OutputImageRegionType;
+
+
+protected:
+  TwoNRIBandsImageToNComplexBandsImage();
+  virtual ~TwoNRIBandsImageToNComplexBandsImage() {}
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  void GenerateOutputInformation(void);
+  void BeforeThreadedGenerateData(void);
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            itk::ThreadIdType threadId);
+
+private:
+  TwoNRIBandsImageToNComplexBandsImage(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbTwoNRIBandsImageToNComplexBandsImage.txx"
+#endif
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
new file mode 100644
index 0000000000..c61f07a900
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.txx
@@ -0,0 +1,143 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef __otbTwoNRIBandsImageToNComplexBandsImage_txx
+#define __otbTwoNRIBandsImageToNComplexBandsImage_txx
+
+#include "otbTwoNRIBandsImageToNComplexBandsImage.h"
+
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkProgressReporter.h"
+#include "itkVariableLengthVector.h"
+
+
+
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>::TwoNRIBandsImageToNComplexBandsImage()
+{
+	//this->SetNumberOfThreads(1);
+}
+
+/**
+ * GenerateOutputInformation
+ */
+template<class TInputImage, class TOutputImage>
+void
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>
+::GenerateOutputInformation(void)
+{
+  Superclass::GenerateOutputInformation();
+  
+  unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
+  
+  if ( (nbCompo % 2) != 0 )
+  {
+	itkExceptionMacro("Number of bands of the input images must be an even number");
+  }
+  else
+	this->GetOutput()->SetNumberOfComponentsPerPixel(nbCompo/2);
+	
+	std::cout << "GenerateOutputInformation : " << this->GetOutput()->GetNumberOfComponentsPerPixel() << std::endl;
+  
+}
+
+/**
+ * BeforeThreadedGenerateData
+ */
+template <class TInputImage, class TOutputImage>
+void
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>
+::BeforeThreadedGenerateData(void)
+{
+	unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
+			
+	if ( (nbCompo % 2) != 0 )
+	  itkExceptionMacro("Number of bands of the input images must be an even number");
+		
+}
+
+/**
+ * ThreadedGenerateData
+ */
+template<class TInputImage, class TOutputImage>
+void TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutputImage>::ThreadedGenerateData(
+  const OutputImageRegionType&     outputRegionForThread,
+  itk::ThreadIdType threadId
+  )
+{
+ 
+  unsigned int nbCompo = this->GetInput()->GetNumberOfComponentsPerPixel();
+  
+  itk::VariableLengthVector< std::complex< typename InputPixelType::ValueType > > vlv(nbCompo/2);
+  
+ 
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());	
+
+  itk::ImageRegionConstIterator<TInputImage>  inIt;
+  inIt = itk::ImageRegionConstIterator<TInputImage>(this->GetInput(), outputRegionForThread);	
+	
+  itk::ImageRegionIterator<OutputImageType>      outIt;
+  outIt = itk::ImageRegionIterator<OutputImageType>(this->GetOutput(), outputRegionForThread);
+  
+
+  inIt.GoToBegin();
+  outIt.GoToBegin();
+
+  while (!outIt.IsAtEnd())
+  {
+	  
+	  unsigned int k=0;
+	  for (unsigned int i=0; i<nbCompo-1; i=i+2)
+	  {
+		  vlv[k] = std::complex< typename InputPixelType::ValueType >(inIt.Get()[i],inIt.Get()[i+1]);
+		  k++;
+	  }
+
+	  
+	  outIt.Set(vlv);
+	  
+
+	  ++inIt;
+	  ++outIt;
+	  
+	  progress.CompletedPixel();
+  }
+  
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void
+TwoNRIBandsImageToNComplexBandsImage<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+} // end namespace otb
+
+#endif
diff --git a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
index a167f9c62b..ad89f0e964 100644
--- a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
+++ b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt
@@ -70,6 +70,9 @@ otbSpectralAngleDistanceImageFilter.cxx
 otbFunctionWithNeighborhoodToImageFilterNew.cxx
 otbEuclideanDistanceMetricWithMissingValue.cxx
 otbEuclideanDistanceMetricWithMissingValueNew.cxx
+otbNRIBandImagesToOneNComplexBandsImage.cxx
+otbOneRIBandImageToOneComplexBandImage.cxx
+otbTwoNRIBandsImageToNComplexBandsImage.cxx
 )
 
 add_executable(otbImageManipulationTestDriver ${OTBImageManipulationTests})
@@ -669,3 +672,35 @@ otb_add_test(NAME bfTvEuclideanDistanceMetricWithMissingValue COMMAND otbImageMa
   otbEuclideanDistanceMetricWithMissingValue)
 otb_add_test(NAME bfTuEuclideanDistanceMetricWithMissingValueNew COMMAND otbImageManipulationTestDriver
   otbEuclideanDistanceMetricWithMissingValueNew)
+  
+  
+otb_add_test(NAME bfTvTwoNRIBandsImageToNComplexBandsImage COMMAND otbImageManipulationTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  ${TEMP}/bfTvTwoNRIBandsImageToNComplexBandsImage.tif
+  otbTwoNRIBandsImageToNComplexBandsImage
+  ${INPUTDATA}/RSAT_imagery_HH_HV_VV.tif
+  ${TEMP}/bfTvTwoNRIBandsImageToNComplexBandsImage.tif
+  )
+  
+  
+otb_add_test(NAME bfTvNRIBandImagesToOneNComplexBandsImage COMMAND otbImageManipulationTestDriver
+  --compare-image ${EPSILON_7}
+  ${BASELINE}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  ${TEMP}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  otbNRIBandImagesToOneNComplexBandsImage 
+  ${INPUTDATA}/RSAT_imagery_HH.tif
+  ${INPUTDATA}/RSAT_imagery_HV.tif
+  ${INPUTDATA}/RSAT_imagery_VV.tif
+  ${TEMP}/bfTvNRIBandImagesToOneNComplexBandsImage.tif
+  )
+  
+otb_add_test(NAME bfTvOneRIBandImageToOneComplexBandImage COMMAND otbImageManipulationTestDriver
+  --compare-image ${EPSILON_3}
+  ${INPUTDATA}/RSAT_imageryC_HH.tif
+  ${TEMP}/bfTvOneRIBandImageToOneComplexBandImage.tif
+  otbOneRIBandImageToOneComplexBandImage
+  ${INPUTDATA}/RSAT_imagery_HH.tif
+  ${TEMP}/bfTvOneRIBandImageToOneComplexBandImage.tif
+  )
+
diff --git a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
index 361248a4fc..af6198611d 100644
--- a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
+++ b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx
@@ -76,4 +76,7 @@ void RegisterTests()
   REGISTER_TEST(otbFunctionWithNeighborhoodToImageFilterNew);
   REGISTER_TEST(otbEuclideanDistanceMetricWithMissingValue);
   REGISTER_TEST(otbEuclideanDistanceMetricWithMissingValueNew);
+  REGISTER_TEST(otbNRIBandImagesToOneNComplexBandsImage);
+  REGISTER_TEST(otbOneRIBandImageToOneComplexBandImage);
+  REGISTER_TEST(otbTwoNRIBandsImageToNComplexBandsImage);
 }
diff --git a/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx b/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx
new file mode 100644
index 0000000000..778f42146e
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbNRIBandImagesToOneNComplexBandsImage.cxx
@@ -0,0 +1,62 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "itkMacro.h"
+
+#include "otbNRIBandImagesToOneNComplexBandsImage.h"
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+int otbNRIBandImagesToOneNComplexBandsImage(int itkNotUsed(argc), char * argv[])
+{
+
+  typedef double PixelType;
+  typedef otb::VectorImage<PixelType,  2> InputImageType;
+    
+  typedef std::complex<double> OutputPixelType;
+  typedef otb::VectorImage<OutputPixelType, 2> OutputImageType;
+ 
+ 
+  typedef otb::NRIBandImagesToOneNComplexBandsImage<InputImageType, OutputImageType> FilterType;
+  typedef otb::ImageFileReader<InputImageType> ReaderType;
+  typedef otb::ImageFileWriter<OutputImageType> WriterType;
+
+  ReaderType::Pointer readerA = ReaderType::New();
+  ReaderType::Pointer readerB = ReaderType::New();
+  ReaderType::Pointer readerC = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  WriterType::Pointer writer = WriterType::New();
+  
+  
+  readerA->SetFileName(argv[1]);
+  readerB->SetFileName(argv[2]);
+  readerC->SetFileName(argv[3]);
+  writer->SetFileName(argv[4]);
+
+  filter->SetInput(0,readerA->GetOutput());
+  filter->SetInput(1,readerB->GetOutput());
+  filter->SetInput(2,readerC->GetOutput());
+  writer->SetInput(filter->GetOutput());
+  writer->Update();
+
+
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
new file mode 100644
index 0000000000..bbc4682269
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx
@@ -0,0 +1,56 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "itkMacro.h"
+
+#include "otbOneRIBandImageToOneComplexBandImage.h"
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+int otbOneRIBandImageToOneComplexBandImage(int itkNotUsed(argc), char * argv[])
+{
+
+  typedef double PixelType;
+  typedef otb::VectorImage<PixelType,  2> InputImageType;
+    
+  typedef std::complex<double> OutputPixelType;
+  typedef otb::Image<OutputPixelType, 2> OutputImageType;
+ 
+ 
+  typedef otb::OneRIBandImageToOneComplexBandImage<InputImageType, OutputImageType> FilterType;
+  typedef otb::ImageFileReader<InputImageType> ReaderType;
+  typedef otb::ImageFileWriter<OutputImageType> WriterType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  WriterType::Pointer writer = WriterType::New();
+  
+  
+  reader->SetFileName(argv[1]);
+  writer->SetFileName(argv[2]);
+
+  filter->SetInput(reader->GetOutput());
+  writer->SetInput(filter->GetOutput());
+  writer->Update();
+
+
+
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx b/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx
new file mode 100644
index 0000000000..b4fed19631
--- /dev/null
+++ b/Modules/Filtering/ImageManipulation/test/otbTwoNRIBandsImageToNComplexBandsImage.cxx
@@ -0,0 +1,56 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "itkMacro.h"
+
+#include "otbTwoNRIBandsImageToNComplexBandsImage.h"
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+
+int otbTwoNRIBandsImageToNComplexBandsImage(int itkNotUsed(argc), char * argv[])
+{
+
+  typedef double PixelType;
+  typedef otb::VectorImage<PixelType,  2> InputImageType;
+    
+  typedef std::complex<double> OutputPixelType;
+  typedef otb::VectorImage<OutputPixelType, 2> OutputImageType;
+ 
+ 
+  typedef otb::TwoNRIBandsImageToNComplexBandsImage<InputImageType, OutputImageType> FilterType;
+  typedef otb::ImageFileReader<InputImageType> ReaderType;
+  typedef otb::ImageFileWriter<OutputImageType> WriterType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  FilterType::Pointer filter = FilterType::New();
+  WriterType::Pointer writer = WriterType::New();
+  
+  
+  reader->SetFileName(argv[1]);
+  writer->SetFileName(argv[2]);
+
+  filter->SetInput(0,reader->GetOutput());
+  writer->SetInput(filter->GetOutput());
+  writer->Update();
+
+
+
+  return EXIT_SUCCESS;
+}
-- 
GitLab