From 01cc2e688f8eb7679bbf9f6f194d49c68bd8828e Mon Sep 17 00:00:00 2001
From: Thomas Feuvrier <thomas.feuvrier@c-s.fr>
Date: Tue, 21 Mar 2006 08:01:06 +0000
Subject: [PATCH] nomsg

---
 Code/BasicFilters/otbFrostImageFilter.txx | 206 ++++++++++++++++++++++
 Code/BasicFilters/otbLeeImageFilter.h     | 131 ++++++++++++++
 Code/BasicFilters/otbLeeImageFilter.txx   | 181 +++++++++++++++++++
 3 files changed, 518 insertions(+)
 create mode 100644 Code/BasicFilters/otbFrostImageFilter.txx
 create mode 100644 Code/BasicFilters/otbLeeImageFilter.h
 create mode 100644 Code/BasicFilters/otbLeeImageFilter.txx

diff --git a/Code/BasicFilters/otbFrostImageFilter.txx b/Code/BasicFilters/otbFrostImageFilter.txx
new file mode 100644
index 0000000000..a38ad1de60
--- /dev/null
+++ b/Code/BasicFilters/otbFrostImageFilter.txx
@@ -0,0 +1,206 @@
+/*=========================================================================
+
+  Programme :   OTB (ORFEO ToolBox)
+  Auteurs   :   CS - P.Imbo
+  Language  :   C++
+  Date      :   24 janvier 2006
+  Role      :   Filtre de débruitage de FROST sur une image 
+  $Id$ 
+
+=========================================================================*/
+#ifndef __otbFrostImageFilter_txx
+#define __otbFrostImageFilter_txx
+
+#include "otbFrostImageFilter.h"
+
+#include "itkDataObject.h"
+#include "itkExceptionObject.h"
+#include "itkConstNeighborhoodIterator.h"
+#include "itkNeighborhoodInnerProduct.h"
+#include "itkImageRegionIterator.h"
+#include "itkNeighborhoodAlgorithm.h"
+#include "itkZeroFluxNeumannBoundaryCondition.h"
+#include "itkOffset.h"
+#include "itkProgressReporter.h"
+#include <math.h>
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+FrostImageFilter<TInputImage, TOutputImage>::FrostImageFilter()
+{
+  m_Radius.Fill(1);
+}
+
+template <class TInputImage, class TOutputImage>
+void FrostImageFilter<TInputImage, TOutputImage>::GenerateInputRequestedRegion() throw (itk::InvalidRequestedRegionError)
+{
+  // call the superclass' implementation of this method
+  Superclass::GenerateInputRequestedRegion();
+  
+  // get pointers to the input and output
+  typename Superclass::InputImagePointer inputPtr   =  const_cast< TInputImage * >( this->GetInput() );
+  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
+  
+  if ( !inputPtr || !outputPtr )
+    {
+    return;
+    }
+
+  // get a copy of the input requested region (should equal the output
+  // requested region)
+  typename TInputImage::RegionType inputRequestedRegion;
+  inputRequestedRegion = inputPtr->GetRequestedRegion();
+
+  // pad the input requested region by the operator radius
+  inputRequestedRegion.PadByRadius( m_Radius );
+
+  // crop the input requested region at the input's largest possible region
+  if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
+    {
+    inputPtr->SetRequestedRegion( inputRequestedRegion );
+    return;
+    }
+  else
+    {
+    // Couldn't crop the region (requested region is outside the largest
+    // possible region).  Throw an exception.
+
+    // store what we tried to request (prior to trying to crop)
+    inputPtr->SetRequestedRegion( inputRequestedRegion );
+    
+    // build an exception
+    itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
+    itk::OStringStream msg;
+    msg << static_cast<const char *>(this->GetNameOfClass())
+        << "::GenerateInputRequestedRegion()";
+    e.SetLocation(msg.str().c_str());
+    e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
+    e.SetDataObject(inputPtr);
+    throw e;
+    }
+}
+
+
+template< class TInputImage, class TOutputImage>
+void FrostImageFilter< TInputImage, TOutputImage>::ThreadedGenerateData(	
+			const 	OutputImageRegionType& 		outputRegionForThread,
+                       	int 	threadId
+				)
+{
+  unsigned int i;
+  itk::ZeroFluxNeumannBoundaryCondition<InputImageType> 	nbc;
+  itk::ConstNeighborhoodIterator<InputImageType> 		bit;
+  typename itk::ConstNeighborhoodIterator<InputImageType>::OffsetType	off;
+  itk::ImageRegionIterator<OutputImageType> 			it;
+  
+  
+  // Allocate output
+  typename OutputImageType::Pointer     output = this->GetOutput();
+  typename InputImageType::ConstPointer input  = this->GetInput();
+  
+  // Find the data-set boundary "faces"
+  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType 		faceList;
+  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType::iterator 	fit;
+
+  itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType> bC;
+  faceList = bC(input, outputRegionForThread, m_Radius);
+
+
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
+  
+//  InputRealType pixel;
+  InputRealType sum;
+  InputRealType sum2;
+
+  double 	Moyenne, Variance; 
+  double	Alpha;   	 
+  double    	NormFiltre;
+  double	FrostFiltre;
+  double	CoefFiltre;
+  double	dPixel;
+  
+    
+  // Process each of the boundary faces.  These are N-d regions which border
+  // the edge of the buffer.
+  for (fit=faceList.begin(); fit != faceList.end(); ++fit)
+    { 
+    bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
+    unsigned int neighborhoodSize = bit.Size();
+    unsigned int CenterPos        = bit.GetCenterNeighborhoodIndex(); 
+    it = itk::ImageRegionIterator<OutputImageType>(output, *fit);
+    bit.OverrideBoundaryCondition(&nbc);
+    bit.GoToBegin();
+
+    while ( ! bit.IsAtEnd() )
+      {
+      sum  = itk::NumericTraits<InputRealType>::Zero;
+      sum2 = itk::NumericTraits<InputRealType>::Zero;
+      for (i = 0; i < neighborhoodSize; ++i)
+        {
+        	dPixel = static_cast<double>( bit.GetPixel(i) );
+		sum += dPixel;
+		sum2 += dPixel * dPixel;
+        }
+      Moyenne   = sum  / double(neighborhoodSize);
+      Variance  = sum2 / double(neighborhoodSize) - Moyenne * Moyenne ;
+     
+      Alpha = m_Deramp * Variance / (Moyenne * Moyenne) ;
+      
+      NormFiltre  = 0.0;
+      FrostFiltre = 0.0;
+ 
+      const double rad_x = static_cast<double>(m_Radius[0]);
+      const double rad_y = static_cast<double>(m_Radius[1]);
+                 
+      for (double x = -rad_x; x<= rad_x; x++)      
+      	{	
+       	for (double y = -rad_y; y <= rad_y; y++)
+		{
+		double Dist = double(sqrt(x*x+y*y));
+		off[0]= static_cast<int>(x);
+		off[1]= static_cast<int>(y);
+//		i = (unsigned int)((y+rad_y)*(2*rad_y+1)+(x+rad_x));
+		dPixel= static_cast<double>( bit.GetPixel(off));
+//		dPixel= static_cast<double>( bit.GetPixel(i));
+		CoefFiltre = Alpha * exp(-Alpha *Dist);
+		NormFiltre  = NormFiltre  + CoefFiltre;
+		FrostFiltre = FrostFiltre + (CoefFiltre * dPixel);
+		}
+        }	      
+      dPixel = (FrostFiltre/NormFiltre);      
+      if (finite(dPixel)==0){
+      	dPixel = 0.;
+      }
+                  
+      it.Set( static_cast<OutputPixelType>( dPixel ) );
+      
+      ++bit;
+      ++it;
+      progress.CompletedPixel();
+      
+      }
+    }
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void 
+FrostImageFilter<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf( os, indent );
+  os << indent << "Radius: " << m_Radius << std::endl;
+}
+
+
+} // end namespace otb
+
+
+#endif
diff --git a/Code/BasicFilters/otbLeeImageFilter.h b/Code/BasicFilters/otbLeeImageFilter.h
new file mode 100644
index 0000000000..252d9043ea
--- /dev/null
+++ b/Code/BasicFilters/otbLeeImageFilter.h
@@ -0,0 +1,131 @@
+/*=========================================================================
+
+  Programme :   OTB (ORFEO ToolBox)
+  Auteurs   :   CS - P.Imbo
+  Language  :   C++
+  Date      :   23 janvier 2006
+  Role      :  Filtre de débruitage de LEE sur une image 
+  $Id$ 
+
+=========================================================================*/
+#ifndef __otbLeeImageFilter_h
+#define __otbLeeImageFilter_h
+
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+namespace otb
+{
+
+/** \class LeeImageFilter
+ * \brief Applique un filtre de débruitage sur une image.
+ *
+ * Ce filtre correspond au filtre Anti-Speckle de LEE :
+ *
+ *	R = E[I] + b(I-E[I]) avec 	b  = C²r / ( C²r + C²v )
+ *					Cv = 1 / sqrt(L)  avec L le nombre de vues
+ *					Cr = sqrt(Var(I)) / E[I] avec Var(I) = E[I²] - E[I]²
+ *
+ */
+
+template <class TInputImage, class TOutputImage>
+class LeeImageFilter :  public itk::ImageToImageFilter< TInputImage, TOutputImage >
+{
+public:
+  /** 	Extrait les dimensions aussi bien des images 
+  	d'entrée (Input) que de sortie (Output). */
+  itkStaticConstMacro(		InputImageDimension,
+  				unsigned int,
+                      		TInputImage::ImageDimension);
+  itkStaticConstMacro(		OutputImageDimension, 
+  				unsigned int,
+                      		TOutputImage::ImageDimension);
+
+  /** "typedef" pour simplifier la définition et la déclaration de variables. */
+  typedef TInputImage InputImageType;
+  /** "typedef" pour simplifier la définition et la déclaration de variables. */
+  typedef TOutputImage OutputImageType;
+
+  /** "typedef" pour les classes standards. */
+  typedef LeeImageFilter Self;
+  typedef itk::ImageToImageFilter< InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self> Pointer;
+  typedef itk::SmartPointer<const Self>  ConstPointer;
+
+  /** Methode pour la gestion "object factory". */
+  itkNewMacro(Self);
+
+  /** Retourne le nom de la classe. */
+  itkTypeMacro(LeeImageFilter, ImageToImageFilter);
+  
+  /** Définition des images supportées. */
+  typedef typename InputImageType::PixelType InputPixelType;
+  typedef typename OutputImageType::PixelType OutputPixelType;
+  /** "typedef" définissant un réel dans cette classe. */
+  typedef typename itk::NumericTraits<InputPixelType>::RealType InputRealType;
+  
+  typedef typename InputImageType::RegionType InputImageRegionType;
+  typedef typename OutputImageType::RegionType OutputImageRegionType;
+
+  /** "typedef" définissant la taille d'une image. */
+  typedef typename InputImageType::SizeType SizeType;
+
+  /** Positionne le rayon définissant le voisinage utilisé pour le calcul du filtre. */
+  itkSetMacro(Radius, SizeType);
+
+  /** Récupère le rayon définissant le voisinage utilisé pour le calcul du filtre. */
+  itkGetConstReferenceMacro(Radius, SizeType);
+  
+  /** Positionne le nombre de vues utilisé pour le calcul du filtre. */
+  itkSetMacro(NbVues, double);
+  /** Récupère le nombre de vues (référencé constant) utilisé pour le calcul du filtre. */
+  itkGetConstReferenceMacro(NbVues, double);
+
+  /** LeeImageFilter a besoin d'une zone de traitement plus large en entrée qu'en sortie 
+   * pemettant une utilisation needs a larger input requested region than
+   * the output requested region.  As such, LeeImageFilter needs
+   * to provide an implementation for GenerateInputRequestedRegion()
+   * in order to inform the pipeline execution model.
+   *
+   * \sa ImageToImageFilter::GenerateInputRequestedRegion() */
+  virtual void GenerateInputRequestedRegion() throw(itk::InvalidRequestedRegionError);
+
+protected:
+  LeeImageFilter();
+  virtual ~LeeImageFilter() {};
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  /** LeeImageFilter peut etre implémentée pour un traitement de filtre multithreaded.
+   * Ainsi, cette implémentation fournit la méthode ThreadedGenerateData()
+   * qui est appelée pour chaque thread du process. Les données image sont allouées automatiquement 
+   * par la classe "mère" en appelant la méthode ThreadedGenerateData(). ThreadedGenerateData peut seulement 
+   * écrire la portion de l'image spécifiée par le paramètre "outputRegionForThread"
+   *
+   *	Filtre de LEE : 
+   *	R = E[I] + b(I-E[I]) avec 	b  = C²r / ( C²r + C²v )
+   *					Cv = 1 / sqrt(L)  avec L le nombre de vues
+   *					Cr = sqrt(Var(I)) / E[I] avec Var(I) = E[I²] - E[I]²
+   *
+   * \sa ImageToImageFilter::ThreadedGenerateData(),
+   *     ImageToImageFilter::GenerateData() */
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            int threadId );
+
+private:
+  LeeImageFilter(const Self&); //purposely not implemented
+  void operator=(const Self&); //purposely not implemented
+
+  /** Déclaration du rayon */
+  SizeType m_Radius;
+  /** Déclaration du nombre de vues du filtre */
+  double m_NbVues;
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbLeeImageFilter.txx"
+#endif
+
+  
+#endif
diff --git a/Code/BasicFilters/otbLeeImageFilter.txx b/Code/BasicFilters/otbLeeImageFilter.txx
new file mode 100644
index 0000000000..ad8edc4bde
--- /dev/null
+++ b/Code/BasicFilters/otbLeeImageFilter.txx
@@ -0,0 +1,181 @@
+/*=========================================================================
+
+  Programme :   OTB (ORFEO ToolBox)
+  Auteurs   :   CS - P.Imbo
+  Language  :   C++
+  Date      :   23 janvier 2006
+  Role      :  Filtre de débruitage de LEE sur une image 
+  $Id$ 
+
+=========================================================================*/
+#ifndef __otbLeeImageFilter_txx
+#define __otbLeeImageFilter_txx
+
+#include "otbLeeImageFilter.h"
+
+#include "itkDataObject.h"
+#include "itkExceptionObject.h"
+#include "itkConstNeighborhoodIterator.h"
+#include "itkNeighborhoodInnerProduct.h"
+#include "itkImageRegionIterator.h"
+#include "itkNeighborhoodAlgorithm.h"
+#include "itkZeroFluxNeumannBoundaryCondition.h"
+#include "itkOffset.h"
+#include "itkProgressReporter.h"
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage>
+LeeImageFilter<TInputImage, TOutputImage>::LeeImageFilter()
+{
+  m_Radius.Fill(1);
+}
+
+template <class TInputImage, class TOutputImage>
+void LeeImageFilter<TInputImage, TOutputImage>::GenerateInputRequestedRegion() throw (itk::InvalidRequestedRegionError)
+{
+  // call the superclass' implementation of this method
+  Superclass::GenerateInputRequestedRegion();
+  
+  // get pointers to the input and output
+  typename Superclass::InputImagePointer inputPtr   =  const_cast< TInputImage * >( this->GetInput() );
+  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
+  
+  if ( !inputPtr || !outputPtr )
+    {
+    return;
+    }
+
+  // get a copy of the input requested region (should equal the output
+  // requested region)
+  typename TInputImage::RegionType inputRequestedRegion;
+  inputRequestedRegion = inputPtr->GetRequestedRegion();
+
+  // pad the input requested region by the operator radius
+  inputRequestedRegion.PadByRadius( m_Radius );
+
+  // crop the input requested region at the input's largest possible region
+  if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
+    {
+    inputPtr->SetRequestedRegion( inputRequestedRegion );
+    return;
+    }
+  else
+    {
+    // Couldn't crop the region (requested region is outside the largest
+    // possible region).  Throw an exception.
+
+    // store what we tried to request (prior to trying to crop)
+    inputPtr->SetRequestedRegion( inputRequestedRegion );
+    
+    // build an exception
+    itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
+    itk::OStringStream msg;
+    msg << static_cast<const char *>(this->GetNameOfClass())
+        << "::GenerateInputRequestedRegion()";
+    e.SetLocation(msg.str().c_str());
+    e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
+    e.SetDataObject(inputPtr);
+    throw e;
+    }
+}
+
+
+template< class TInputImage, class TOutputImage>
+void LeeImageFilter< TInputImage, TOutputImage>::ThreadedGenerateData(	
+			const 	OutputImageRegionType& 		outputRegionForThread,
+                       	int 	threadId
+				)
+{
+  unsigned int i;
+  itk::ZeroFluxNeumannBoundaryCondition<InputImageType> nbc;
+
+  itk::ConstNeighborhoodIterator<InputImageType> bit;
+  itk::ImageRegionIterator<OutputImageType> it;
+  
+  // Allocate output
+  typename OutputImageType::Pointer     output = this->GetOutput();
+  typename InputImageType::ConstPointer input  = this->GetInput();
+  
+  // Find the data-set boundary "faces"
+  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType 		faceList;
+  typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType::iterator 	fit;
+
+  itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType> bC;
+  faceList = bC(input, outputRegionForThread, m_Radius);
+
+
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
+  
+//  InputRealType pixel;
+  InputRealType sum;
+  InputRealType sum2;
+
+  double Cr2, Cv2, E_I, I, Var_I, dPixel;
+  
+  
+//  dPixel = this->getNbVues();
+  dPixel = m_NbVues;
+  //Calcul du rapport
+  Cv2 = 1./(sqrt(dPixel));
+  Cv2 = Cv2*Cv2;
+
+  // Process each of the boundary faces.  These are N-d regions which border
+  // the edge of the buffer.
+  for (fit=faceList.begin(); fit != faceList.end(); ++fit)
+    { 
+    bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
+    unsigned int neighborhoodSize = bit.Size();
+    it = itk::ImageRegionIterator<OutputImageType>(output, *fit);
+    bit.OverrideBoundaryCondition(&nbc);
+    bit.GoToBegin();
+
+    while ( ! bit.IsAtEnd() )
+      {
+      sum = itk::NumericTraits<InputRealType>::Zero;
+      sum2 = itk::NumericTraits<InputRealType>::Zero;
+      //Parcours du voisinage
+      for (i = 0; i < neighborhoodSize; ++i)
+        {
+        	dPixel = static_cast<double>( bit.GetPixel(i) );
+		sum += dPixel;
+		sum2 += dPixel * dPixel;
+        }
+      
+      E_I   = sum / double(neighborhoodSize);
+      Var_I = sum2 / double(neighborhoodSize) - E_I*E_I ;
+      I = static_cast<double>( bit.GetCenterPixel() );
+      Cr2    = Var_I / (E_I*E_I);
+      
+      dPixel = E_I + ((I-E_I)*(Cr2))/(Cr2 + Cv2);
+      // get the mean value
+      it.Set( static_cast<OutputPixelType>( dPixel ) );
+      
+      ++bit;
+      ++it;
+      progress.CompletedPixel();
+      }
+    }
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput>
+void 
+LeeImageFilter<TInputImage, TOutput>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf( os, indent );
+  os << indent << "Radius: " << m_Radius << std::endl;
+}
+
+
+} // end namespace otb
+
+
+#endif
-- 
GitLab