From a40dc8d6f265416ddd8041a1de5c136244e956a3 Mon Sep 17 00:00:00 2001
From: Emmanuel Christophe <emmanuel.christophe@orfeo-toolbox.org>
Date: Thu, 6 Dec 2007 17:54:33 +0000
Subject: [PATCH] Pan sharpening

---
 .../BasicFilters/otbDivideVectorImageFilter.h | 122 ++++++++++++++++
 ...bSimpleRcsPanSharpeningFusionImageFilter.h | 117 ++++++++++++++++
 ...impleRcsPanSharpeningFusionImageFilter.txx | 131 ++++++++++++++++++
 Examples/Fusion/PanSharpeningExample.cxx      |  44 ++++++
 4 files changed, 414 insertions(+)
 create mode 100644 Code/BasicFilters/otbDivideVectorImageFilter.h
 create mode 100644 Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h
 create mode 100644 Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx
 create mode 100644 Examples/Fusion/PanSharpeningExample.cxx

diff --git a/Code/BasicFilters/otbDivideVectorImageFilter.h b/Code/BasicFilters/otbDivideVectorImageFilter.h
new file mode 100644
index 0000000000..0bca78aa10
--- /dev/null
+++ b/Code/BasicFilters/otbDivideVectorImageFilter.h
@@ -0,0 +1,122 @@
+/*=========================================================================
+	
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Some parts of this code are derived from ITK. See ITKCopyright.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 __otbDivideVectorImageFilter_h
+#define __otbDivideVectorImageFilter_h
+
+#include "itkBinaryFunctorImageFilter.h"
+#include "itkNumericTraits.h"
+
+namespace otb
+{
+  
+/** \class DivideVectorImageFilter
+ * \brief Implements an operator for pixel-wise division of two images.
+ *
+ * This class is only a temporary fix to use in otbSimpleRcsPanSharpeningFusionImageFilter. Should be useless after 2007-12-11
+ * 
+ * \ingroup IntensityImageFilters  Multithreaded
+ */
+
+namespace Function {  
+  
+template< class TInput1, class TInput2, class TOutput>
+class Div
+{
+public:
+  Div() {};
+  ~Div() {};
+  bool operator!=( const Div & ) const
+  {
+    return false;
+  }
+  bool operator==( const Div & other ) const
+  {
+    return !(*this != other);
+  }
+  inline TOutput operator()( const TInput1 & A, const TInput2 & B)
+  {
+//     if(B != (TInput2) 0)
+      return (TOutput)(A / B);
+//     else
+//       return NumericTraits<TOutput>::max();
+  }
+}; 
+}
+
+template <class TInputImage1, class TInputImage2, class TOutputImage>
+class ITK_EXPORT DivideVectorImageFilter :
+    public
+itk::BinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage, 
+                         Function::Div< 
+  typename TInputImage1::PixelType, 
+  typename TInputImage2::PixelType,
+  typename TOutputImage::PixelType>   >
+{
+public:
+  /**
+   * Standard "Self" typedef.
+   */
+  typedef DivideVectorImageFilter  Self;
+
+  /**
+   * Standard "Superclass" typedef.
+   */
+  typedef itk::BinaryFunctorImageFilter<TInputImage1,TInputImage2,TOutputImage, 
+                                   Function::Div< 
+    typename TInputImage1::PixelType, 
+    typename TInputImage2::PixelType,
+    typename TOutputImage::PixelType>   
+  > Superclass;
+
+  /** 
+   * Smart pointer typedef support 
+   */
+  typedef itk::SmartPointer<Self>   Pointer;
+  typedef itk::SmartPointer<const Self>  ConstPointer;
+
+  /**
+   * Method for creation through the object factory.
+   */
+  itkNewMacro(Self);
+
+#ifdef ITK_USE_CONCEPT_CHECKING
+  /** Begin concept checking */
+  itkConceptMacro(IntConvertibleToInput2Check,
+    (Concept::Convertible<int, typename TInputImage2::PixelType>));
+  itkConceptMacro(Input1Input2OutputDivisionOperatorsCheck,
+    (Concept::DivisionOperators<typename TInputImage1::PixelType,
+                                typename TInputImage2::PixelType,
+                                typename TOutputImage::PixelType>));
+  /** End concept checking */
+#endif
+
+protected:
+  DivideVectorImageFilter() {}
+  virtual ~DivideVectorImageFilter() {}
+  DivideVectorImageFilter(const Self&) {}
+  void operator=(const Self&) {}
+
+};
+
+} // end namespace otb
+
+
+#endif
diff --git a/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h
new file mode 100644
index 0000000000..60ccfce77f
--- /dev/null
+++ b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.h
@@ -0,0 +1,117 @@
+/*=========================================================================
+	
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Some parts of this code are derived from ITK. See ITKCopyright.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 __otbSimpleRcsPanSharpeningFusionImageFilter_h
+#define __otbSimpleRcsPanSharpeningFusionImageFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "itkMeanImageFilter.h"
+// #include "itkDivideImageFilter.h"
+#include "otbDivideVectorImageFilter.h"//TODO to correct after the fix from ITK
+#include "itkMultiplyImageFilter.h"
+    
+namespace otb {
+  /**
+   * \class SimpleRcsPanSharpeningFusionImageFilter
+   * \brief This class performs a simple Pan sharpening operation
+   * 
+   * Given a Pan image and the corresponding Xs image (oversampled to have the
+   * same number of pixels), this filter realizes a simple Pan sharpening 
+   * operation:
+   * 
+   * \f[ \frac{XS}{\mathrm{Filtered}(PAN)} PAN  \f]
+   *
+   * 
+   * 
+   **/
+
+  template <class TPanImageType,class TXsImageType,class TOutputImageType>
+class ITK_EXPORT SimpleRcsPanSharpeningFusionImageFilter :
+    public itk::ImageToImageFilter<TPanImageType, TOutputImageType>
+      {
+        public:
+          typedef SimpleRcsPanSharpeningFusionImageFilter   Self;
+          typedef itk::ImageToImageFilter
+              <TPanImageType, TOutputImageType> Superclass;
+          typedef itk::SmartPointer<Self>             Pointer;
+          typedef itk::SmartPointer<const Self>       ConstPointer;
+          typedef otb::Image<double,2>                InternalImageType;
+          typedef otb::VectorImage<double>            InternalVectorImageType;
+          
+          
+          /** Method for creation through object factory */
+          itkNewMacro(Self);
+
+          /** Run-time type information */
+          itkTypeMacro(SimpleRcsPanSharpeningFusionImageFilter, 
+                       itk::ImageToImageFilter);
+
+          /** Display */
+          void PrintSelf( std::ostream& os, itk::Indent indent ) const;
+          
+          typedef typename InternalImageType::SizeType RadiusType;
+
+          itkGetMacro( Radius, RadiusType);
+          itkSetMacro( Radius, RadiusType);
+          
+          virtual void SetPanInput( const TPanImageType * image);
+          const TPanImageType * GetPanInput(void);
+             
+          virtual void SetXsInput( const TXsImageType * path);
+          const TXsImageType * GetXsInput(void);
+          
+        protected:
+
+          SimpleRcsPanSharpeningFusionImageFilter();
+
+          typedef itk::MeanImageFilter
+              <TPanImageType, InternalImageType> MeanFilterType;
+          typedef otb::DivideVectorImageFilter
+              <InternalVectorImageType,InternalImageType,
+              InternalVectorImageType> DivideFilterType;
+          typedef itk::MultiplyImageFilter
+              <InternalVectorImageType,TPanImageType,TOutputImageType> MultiplyFilterType;
+              
+
+//  Software Guide : EndCodeSnippet
+
+                  void GenerateData();
+
+        private:
+
+          SimpleRcsPanSharpeningFusionImageFilter(Self&);   // intentionally not implemented
+          void operator=(const Self&);          // intentionally not implemented
+
+          typename MeanFilterType::Pointer     m_MeanFilter;
+          typename DivideFilterType::Pointer    m_DivideFilter;
+          typename MultiplyFilterType::Pointer     m_MultiplyFilter;
+
+          RadiusType m_Radius;
+
+      };
+      
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbSimpleRcsPanSharpeningFusionImageFilter.txx"
+#endif
+
+#endif
+
diff --git a/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx
new file mode 100644
index 0000000000..a0cba29c98
--- /dev/null
+++ b/Code/Fusion/otbSimpleRcsPanSharpeningFusionImageFilter.txx
@@ -0,0 +1,131 @@
+/*=========================================================================
+	
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+  Some parts of this code are derived from ITK. See ITKCopyright.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 __otbSimpleRcsPanSharpeningFusionImageFilter_txx
+#define __otbSimpleRcsPanSharpeningFusionImageFilter_txx
+
+#include "otbSimpleRcsPanSharpeningFusionImageFilter.h"
+
+
+namespace otb
+{
+  template <class TPanImageType, class TXsImageType, class TOutputImageType>
+      SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType>
+  ::SimpleRcsPanSharpeningFusionImageFilter()
+  {
+    this->SetNumberOfRequiredInputs(2);
+    m_MeanFilter = MeanFilterType::New();
+    m_DivideFilter = DivideFilterType::New();
+    m_MultiplyFilter = MultiplyFilterType::New();
+    
+    m_Radius[0]=3;
+    m_Radius[1]=3;
+    m_MeanFilter->SetRadius(m_Radius);
+    
+    m_DivideFilter->SetInput2(m_MeanFilter->GetOutput());
+    m_MultiplyFilter->SetInput1(m_DivideFilter->GetOutput());
+    
+  }
+  
+  template <class TPanImageType, class TXsImageType, class TOutputImageType>
+      void
+          SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType>
+  ::SetPanInput(const TPanImageType *image)
+  {
+  // We have 2 inputs:  an image and a vector image
+
+  // Process object is not const-correct so the const_cast is required here
+    this->itk::ProcessObject::SetNthInput(0, 
+                                     const_cast<  TPanImageType* >( image ) );
+    this->Modified();
+  }
+
+  template <class TPanImageType, class TXsImageType, class TOutputImageType>
+      const TPanImageType *
+          SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType>
+  ::GetPanInput(void) 
+  {
+    if (this->GetNumberOfInputs() < 1)
+    {
+      return 0;
+    }
+  
+    return static_cast<const TPanImageType * >
+        (this->itk::ProcessObject::GetInput(0) );
+  }
+  
+  template <class TPanImageType, class TXsImageType, class TOutputImageType>
+      void
+          SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType>
+  ::SetXsInput(const TXsImageType *image)
+  {
+  // We have 2 inputs:  an image and a vector image
+
+  // Process object is not const-correct so the const_cast is required here
+    this->itk::ProcessObject::SetNthInput(1, 
+                         const_cast<  TXsImageType* >( image ) );
+    this->Modified();
+  }
+
+  template <class TPanImageType, class TXsImageType, class TOutputImageType>
+      const TXsImageType *
+          SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType>
+  ::GetXsInput(void) 
+  {
+    if (this->GetNumberOfInputs() < 2)
+    {
+      return 0;
+    }
+  
+    return static_cast<const TXsImageType * >
+        (this->itk::ProcessObject::GetInput(1) );
+  }
+  
+  
+  template <class TPanImageType,class TXsImageType,class TOutputImageType>
+      void
+      SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType>
+  ::GenerateData()
+      {
+        m_MeanFilter->SetInput( this->GetPanInput() );
+        m_DivideFilter->SetInput1(this->GetXsInput());
+
+        m_MultiplyFilter->SetInput2(this->GetPanInput());
+
+        m_MultiplyFilter->GraftOutput( this->GetOutput() );
+        m_MultiplyFilter->Update();
+        this->GraftOutput( m_MultiplyFilter->GetOutput() );
+      }
+      
+  template <class TPanImageType,class TXsImageType,class TOutputImageType>
+          void
+      SimpleRcsPanSharpeningFusionImageFilter<TPanImageType, TXsImageType, TOutputImageType>
+  ::PrintSelf( std::ostream& os, itk::Indent indent ) const
+          {
+            Superclass::PrintSelf(os,indent);
+
+            os
+                << indent << "Radius:" << this->m_Radius
+                << std::endl;
+          }
+          
+} // end namespace otb
+
+#endif
diff --git a/Examples/Fusion/PanSharpeningExample.cxx b/Examples/Fusion/PanSharpeningExample.cxx
new file mode 100644
index 0000000000..2deca33348
--- /dev/null
+++ b/Examples/Fusion/PanSharpeningExample.cxx
@@ -0,0 +1,44 @@
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbStreamingImageFileWriter.h"
+#include "otbSimpleRcsPanSharpeningFusionImageFilter.h"
+
+
+int main( int argc, char* argv[] )
+{
+  typedef otb::Image<double, 2>     ImageType;
+  typedef otb::VectorImage<double, 2>     VectorImageType;
+  typedef otb::ImageFileReader<ImageType>  ReaderType;
+  typedef otb::ImageFileReader<VectorImageType>  ReaderVectorType;
+  
+  typedef otb::VectorImage<unsigned int, 2>     VectorIntImageType;
+
+
+					
+  ReaderVectorType::Pointer     	readerXS=ReaderVectorType::New();
+  ReaderType::Pointer     	readerPAN=ReaderType::New();
+
+  
+  readerPAN->SetFileName(argv[1]);
+  readerXS->SetFileName(argv[2]);
+  
+  typedef otb::SimpleRcsPanSharpeningFusionImageFilter
+      <ImageType,VectorImageType,VectorIntImageType> FusionFilterType;
+  FusionFilterType::Pointer fusion = FusionFilterType::New();
+  fusion->SetPanInput(readerPAN->GetOutput());
+  fusion->SetXsInput(readerXS->GetOutput());
+      
+      
+  typedef otb::StreamingImageFileWriter<VectorIntImageType>  WriterType;
+  WriterType::Pointer	    	writer=WriterType::New();
+  writer->SetFileName(argv[3]);
+  writer->SetInput(fusion->GetOutput());
+  writer->Update();
+
+  return 0;
+  
+}
+
+
-- 
GitLab