From afb7195d1d0b8278058535abaf7ae14f44e0d88b Mon Sep 17 00:00:00 2001
From: Patrick Imbo <patrick.imbo@c-s.fr>
Date: Thu, 7 Sep 2006 15:00:07 +0000
Subject: [PATCH] =?UTF-8?q?otbLogPolarResampleImageFilter=20:=20impl=C3=A9?=
 =?UTF-8?q?mentation=20de=20la=20classe=20+=20tests?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../otbLogPolarResampleImageFilter.h          | 224 +++++++++++
 .../otbLogPolarResampleImageFilter.txx        | 357 ++++++++++++++++++
 Testing/Code/BasicFilters/CMakeLists.txt      |  12 +
 .../BasicFilters/otbBasicFiltersTests.cxx     |   2 +
 .../Code/BasicFilters/otbFrostFilterNew.cxx   |   6 +-
 .../otbLogPolarResampleImageFilter.cxx        |  79 ++++
 .../otbLogPolarResampleImageFilterNew.cxx     |  56 +++
 Testing/Code/FeatureExtraction/CMakeLists.txt |   6 +
 8 files changed, 739 insertions(+), 3 deletions(-)
 create mode 100644 Code/BasicFilters/otbLogPolarResampleImageFilter.h
 create mode 100644 Code/BasicFilters/otbLogPolarResampleImageFilter.txx
 create mode 100644 Testing/Code/BasicFilters/otbLogPolarResampleImageFilter.cxx
 create mode 100644 Testing/Code/BasicFilters/otbLogPolarResampleImageFilterNew.cxx

diff --git a/Code/BasicFilters/otbLogPolarResampleImageFilter.h b/Code/BasicFilters/otbLogPolarResampleImageFilter.h
new file mode 100644
index 0000000000..50edad741c
--- /dev/null
+++ b/Code/BasicFilters/otbLogPolarResampleImageFilter.h
@@ -0,0 +1,224 @@
+/*=========================================================================
+
+  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 __otbLogPolarResampleImageFilter_h
+#define __otbLogPolarResampleImageFilter_h
+
+//#include "itkImageFunction.h"
+//#include "itkImageRegionIterator.h"
+#include "otbImage.h"
+#include "itkImageToImageFilter.h"
+#include "itkLinearInterpolateImageFunction.h"
+#include "itkSize.h"
+
+namespace otb
+{
+
+/** \class LogPolarResampleImageFilter
+ * \brief Resample an image onto a log-polar coordinate transform
+ *
+ * LogPolarResampleImageFilter resamples an existing image to a log-polar coordinate
+ * system and interpolate via some image function.  The class is templated
+ * over the types of the input and output images.
+ *
+ * Note that the choice of interpolator function can be important.
+ * This function is set via SetInterpolator().  The default is
+ * itk::LinearInterpolateImageFunction<InputImageType, TInterpolatorPrecisionType>, which
+ *
+ * Output information (spacing, size and direction) for the output
+ * image should be set. This information has the normal defaults of
+ * unit spacing, zero origin and identity direction. Optionally, the
+ * output information can be obtained from a reference image. If the
+ * reference image is provided and UseReferenceImage is On, then the
+ * spacing, origin and direction of the reference image will be used.
+ *
+ * Since this filter produces an image which is a different size than
+ * its input, it needs to override several of the methods defined
+ * in ProcessObject in order to properly manage the pipeline execution model.
+ * In particular, this filter overrides
+ * ProcessObject::GenerateInputRequestedRegion() and
+ * ProcessObject::GenerateOutputInformation().
+ *
+ * This filter is implemented as a multithreaded filter.  It provides a 
+ * ThreadedGenerateData() method for its implementation.
+ *
+ * \ingroup GeometricTransforms
+ */
+template <class TInputImage, 
+	  class TInterpolator = itk::LinearInterpolateImageFunction<TInputImage> >
+class ITK_EXPORT LogPolarResampleImageFilter:
+    public itk::ImageToImageFilter<TInputImage, TInputImage>
+{
+public:
+
+  /** Standard class typedefs. */
+  typedef LogPolarResampleImageFilter                 	 	Self;
+  typedef itk::ImageToImageFilter<TInputImage,TInputImage>  	Superclass;
+  typedef itk::SmartPointer<Self>        			Pointer;
+  typedef itk::SmartPointer<const Self>  			ConstPointer;
+
+  typedef TInputImage 						InputImageType;
+  typedef typename InputImageType::Pointer 			InputImagePointer;
+  typedef typename InputImageType::ConstPointer 		InputImageConstPointer;
+  typedef typename InputImageType::PixelType 			InputPixelType;
+  typedef typename InputImageType::RegionType 			InputImageRegionType;
+  typedef typename InputImageType::SizeType 			SizeType;
+  
+  typedef TInputImage 						OutputImageType;
+  typedef typename OutputImageType::Pointer 			OutputImagePointer;
+  typedef typename OutputImageType::PixelType 			OutputPixelType;
+  typedef typename OutputImageType::RegionType 			OutputImageRegionType;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);  
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(LogPolarResampleImageFilter, itk::ImageToImageFilter);
+
+  /** Number of dimensions. */
+  itkStaticConstMacro(InputImageDimension, unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension, unsigned int,
+                      TInputImage::ImageDimension);
+
+  /** Typedefs to describe and access Interpolator */
+  typedef TInterpolator 					InterpolatorType;
+  typedef typename InterpolatorType::Pointer 			InterpolatorPointer;
+  typedef typename InterpolatorType::CoordRepType 		CoordRepType;
+  typedef typename InterpolatorType::PointType   		PointType;
+  typedef typename InterpolatorType::CoordRepType   		CoordRepType;
+
+  /** Image size typedef. */
+  typedef itk::Size<itkGetStaticConstMacro(OutputImageDimension)> SizeType;
+  typedef typename SizeType::SizeValueType			  SizeValueType;
+
+  /** Image index typedef. */
+  typedef typename OutputImageType::IndexType 		IndexType;
+
+
+   /** Image spacing,origin and direction typedef */
+  typedef typename OutputImageType::SpacingType 		SpacingType;
+  typedef typename OutputImageType::PointType   		OriginPointType;
+  typedef typename OutputImageType::DirectionType 		DirectionType;
+  
+      
+
+  /** Set the pixel value when a transformed pixel is outside of the
+   * image.  The default default pixel value is 0. */
+  itkSetMacro(DefaultPixelValue,OutputPixelType);
+
+  /** Get the pixel value when a transformed pixel is outside of the image */
+  itkGetMacro(DefaultPixelValue,OutputPixelType);
+
+  /** Set the Angular spacing. */
+  itkSetMacro(AngularStep, double);
+  /** Get the Angular spacing. */
+  itkGetConstReferenceMacro(AngularStep, double);
+
+  /** Set the Radial number of samples. */
+  itkSetMacro(RadialNumberOfSamples, double);
+  /** Get the Radial number of samples. */
+  itkGetConstReferenceMacro(RadialNumberOfSamples, double);
+
+  /** Set the Sigma value. */
+  itkSetMacro(Sigma, double);
+  /** Get the Sigma value. */
+  itkGetConstReferenceMacro(Sigma, double);
+
+  /** LogPolarResampleImageFilter produces an image which is a different size
+   * than its input.  As such, it needs to provide an implementation
+   * for GenerateOutputInformation() in order to inform the pipeline
+   * execution model.  The original documentation of this method is
+   * below. \sa ProcessObject::GenerateOutputInformaton() */
+  virtual void GenerateOutputInformation();
+
+  /** LogPolarResampleImageFilter needs a different input requested region than
+   * the output requested region.  As such, LogPolarResampleImageFilter needs
+   * to provide an implementation for GenerateInputRequestedRegion()
+   * in order to inform the pipeline execution model.
+   * \sa ProcessObject::GenerateInputRequestedRegion() */
+  virtual void GenerateInputRequestedRegion();
+
+  /** This method is used to set the state of the filter before 
+   * multi-threading. */
+  virtual void BeforeThreadedGenerateData();
+
+  /** This method is used to set the state of the filter after 
+   * multi-threading. */
+  virtual void AfterThreadedGenerateData();
+
+  /** Method Compute the Modified Time based on changed to the components. */
+  unsigned long GetMTime( void ) const;
+
+
+  itkSetMacro(IsOriginAtCenter, bool);
+  itkBooleanMacro(IsOriginAtCenter);
+  itkGetMacro(IsOriginAtCenter, bool);
+
+#ifdef ITK_USE_CONCEPT_CHECKING
+  /** Begin concept checking */
+  itkConceptMacro(OutputHasNumericTraitsCheck,
+                  (Concept::HasNumericTraits<OutputPixelType>));
+  /** End concept checking */
+#endif
+
+protected:
+  LogPolarResampleImageFilter();
+  ~LogPolarResampleImageFilter() {};
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  /** LogPolarResampleImageFilter can be implemented as a multithreaded filter.  Therefore,
+   * this implementation provides a ThreadedGenerateData() routine which
+   * is called for each processing thread. The output image data is allocated
+   * automatically by the superclass prior to calling ThreadedGenerateData().
+   * ThreadedGenerateData can only write to the portion of the output image
+   * specified by the parameter "outputRegionForThread"
+   * \sa ImageToImageFilter::ThreadedGenerateData(),
+   *     ImageToImageFilter::GenerateData() */
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            int threadId );
+  
+
+private:
+  LogPolarResampleImageFilter(const Self&); //purposely not implemented
+  void operator=(const Self&); //purposely not implemented
+
+  OutputImagePointer      m_OutputImage;
+
+  InterpolatorPointer     m_Interpolator;        // Image function for interpolation
+  OutputPixelType         m_DefaultPixelValue;   // default pixel value if the point 
+                                                 // is outside the image
+         // output image spacing
+  OriginPointType         m_OutputOrigin;        // output image origin
+  IndexType               m_OutputStartIndex;    // output image start index
+  bool			  m_IsOriginAtCenter;     // true if input image origin is at center of the image
+  double		  m_AngularStep;
+  double		  m_RadialStep;
+  double		  m_RadialNumberOfSamples;
+  double		  m_AngularNumberOfSamples;
+  double 		  m_Sigma;
+};
+
+  
+} // end namespace otb
+  
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbLogPolarResampleImageFilter.txx"
+#endif
+  
+#endif
diff --git a/Code/BasicFilters/otbLogPolarResampleImageFilter.txx b/Code/BasicFilters/otbLogPolarResampleImageFilter.txx
new file mode 100644
index 0000000000..db91fd29c0
--- /dev/null
+++ b/Code/BasicFilters/otbLogPolarResampleImageFilter.txx
@@ -0,0 +1,357 @@
+/*=========================================================================
+
+  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 _otbLogPolarResampleImageFilter_txx
+#define _otbLogPolarResampleImageFilter_txx
+
+#include "otbLogPolarResampleImageFilter.h"
+#include "itkObjectFactory.h"
+#include "itkIdentityTransform.h"
+#include "itkLinearInterpolateImageFunction.h"
+#include "itkProgressReporter.h"
+#include "itkImageRegionIteratorWithIndex.h"
+#include "itkImageLinearIteratorWithIndex.h"
+#include "itkSpecialCoordinatesImage.h"
+
+namespace otb
+{
+
+/**
+ * Initialize new instance
+ */
+template <class TInputImage,  class TInterpolator>
+LogPolarResampleImageFilter<TInputImage, TInterpolator>
+::LogPolarResampleImageFilter()
+{
+  m_RadialStep  = 1.0;
+  m_AngularStep = 1.0;
+  m_RadialNumberOfSamples  = 128;
+  m_AngularNumberOfSamples = 128;
+  m_IsOriginAtCenter = true;
+  m_DefaultPixelValue = 0;
+  m_Interpolator = itk::LinearInterpolateImageFunction<InputImageType, CoordRepType>::New();
+  
+}
+
+/**
+ * Print out a description of self
+ *
+ */
+template <class TInputImage, class TInterpolator>
+void 
+LogPolarResampleImageFilter<TInputImage, TInterpolator>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os,indent);
+  os << indent << "m_RadialStep: " << m_RadialStep << std::endl;
+  os << indent << "m_AngularStep: " << m_AngularStep << std::endl;
+  os << indent << "m_RadialNumberOfSamples: " << m_RadialNumberOfSamples << std::endl;
+  os << indent << "m_AngularNumberOfSamples: " << m_AngularNumberOfSamples << std::endl;
+  os << indent << "m_IsOriginAtCenter: " << (m_IsOriginAtCenter ? "On" : "Off") << std::endl;
+  os << indent << "m_DefaultPixelValue: " << m_DefaultPixelValue << std::endl;
+  os << indent << "m_Interpolator: " << m_Interpolator.GetPointer() << std::endl;
+ 
+  return;
+}
+
+
+
+/**
+ * Set up state of filter before multi-threading.
+ * InterpolatorType::SetInputImage is not thread-safe and hence
+ * has to be set up before ThreadedGenerateData
+ */
+template <class TInputImage, class TInterpolator>
+void 
+LogPolarResampleImageFilter<TInputImage,TInterpolator>
+::BeforeThreadedGenerateData()
+{
+
+  if( !m_Interpolator )
+    {
+    itkExceptionMacro(<< "Interpolator not set"<<std::endl);
+    }
+
+  // Connect input image to interpolator
+  m_Interpolator->SetInputImage( this->GetInput() );
+
+}
+
+
+/**
+ * Set up state of filter after multi-threading.
+ */
+template <class TInputImage, class TInterpolator>
+void 
+LogPolarResampleImageFilter<TInputImage,TInterpolator>
+::AfterThreadedGenerateData()
+{
+  // Disconnect input image from the interpolator
+  m_Interpolator->SetInputImage( NULL );
+
+}
+
+/**
+ * ThreadedGenerateData
+ */
+template <class TInputImage, class TInterpolator>
+void 
+LogPolarResampleImageFilter<TInputImage,TInterpolator>
+::ThreadedGenerateData(
+  const OutputImageRegionType& outputRegionForThread,
+  int threadId)
+{
+  // Get the output pointers
+  OutputImagePointer      outputPtr = this->GetOutput();
+
+  // Get ths input pointers
+  InputImageConstPointer inputPtr=this->GetInput();
+
+  // Create an iterator that will walk the output region for this thread.
+  typedef itk::ImageRegionIteratorWithIndex<TInputImage> OutputIterator;
+
+  OutputIterator outIt(outputPtr, outputRegionForThread);
+
+  // Define a few indices that will be used to translate from an input pixel
+  // to an output pixel
+  PointType outputPoint;         // Coordinates of current output pixel
+  PointType inputPoint;          // Coordinates of current input pixel
+
+  typedef itk::ContinuousIndex<CoordRepType, OutputImageDimension> ContinuousIndexType;
+  ContinuousIndexType inputIndex;
+
+  // Support for progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
+        
+  typedef typename InterpolatorType::OutputType OutputType;
+
+  // Min/max values of the output pixel type AND these values
+  // represented as the output type of the interpolator
+  const OutputPixelType minOutputValue =  itk::NumericTraits<OutputPixelType >::NonpositiveMin();
+  const OutputPixelType maxOutputValue =  itk::NumericTraits<OutputPixelType >::max();
+
+  // Walk the output region
+  outIt.GoToBegin();
+
+  while ( !outIt.IsAtEnd() )
+    {
+    // Determine the index of the current output pixel
+    outputPtr->TransformIndexToPhysicalPoint( outIt.GetIndex(), outputPoint );
+
+    // Compute corresponding input pixel position
+    double Theta = outputPoint[0]*m_AngularStep*acos(-1.0)/180.0;
+    double Rho   = outputPoint[1]*m_RadialStep;
+
+    inputPoint[0] = exp(Rho) * cos(Theta);
+    inputPoint[1] = exp(Rho) * sin(Theta);
+  
+    if(m_IsOriginAtCenter == true)
+      {
+      inputPoint[0] += inputPtr->GetLargestPossibleRegion().GetSize()[0]/2.;
+      inputPoint[1] += inputPtr->GetLargestPossibleRegion().GetSize()[1]/2.;
+      }
+    
+     
+    inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, inputIndex);
+
+    
+    // Evaluate input at right position and copy to the output
+    if( m_Interpolator->IsInsideBuffer(inputIndex) )
+      {
+      OutputPixelType pixval;
+      double valueTemp = static_cast<double>(m_Interpolator->EvaluateAtContinuousIndex(inputIndex) );
+      valueTemp *= exp(m_Sigma * Rho);
+      valueTemp *= m_RadialStep; 
+      OutputPixelType value = static_cast<OutputPixelType>(valueTemp);
+      
+      if( value < minOutputValue )
+        {
+        pixval = minOutputValue;
+        }
+      else if( value > maxOutputValue )
+        {
+        pixval = maxOutputValue;
+        }
+      else 
+        {
+        pixval = static_cast<OutputPixelType>( value );
+        }
+      outIt.Set( pixval );      
+      }
+    else
+      {
+      outIt.Set(m_DefaultPixelValue); // default background value
+      }
+
+    progress.CompletedPixel();
+    ++outIt;
+    }
+
+  return;
+  
+}
+
+
+
+
+/** 
+ * Inform pipeline of necessary input image region
+ *
+ * Determining the actual input region is non-trivial, especially
+ * when we cannot assume anything about the transform being used.
+ * So we do the easy thing and request the entire input image.
+ */
+template <class TInputImage, class TInterpolator>
+void 
+LogPolarResampleImageFilter<TInputImage,TInterpolator>
+::GenerateInputRequestedRegion()
+{
+  // call the superclass's implementation of this method
+  Superclass::GenerateInputRequestedRegion();
+
+  if ( !this->GetInput() )
+    {
+    return;
+    }
+
+  // get pointers to the input and output
+  InputImagePointer  inputPtr  = 
+    const_cast< TInputImage *>( this->GetInput() );
+
+  // Request the entire input image
+  InputImageRegionType inputRegion;
+  inputRegion = inputPtr->GetLargestPossibleRegion();
+  inputPtr->SetLargestPossibleRegion(inputRegion);
+  inputPtr->SetRequestedRegion(inputRegion);
+
+  return;
+}
+
+
+/** 
+ * Inform pipeline of required output region
+ */
+template <class TInputImage, class TInterpolator>
+void 
+LogPolarResampleImageFilter<TInputImage,TInterpolator>
+::GenerateOutputInformation()
+{
+  // call the superclass' implementation of this method
+  Superclass::GenerateOutputInformation();
+
+
+  // get pointers to the input and output
+  InputImagePointer  inputPtr  = const_cast< TInputImage *>( this->GetInput() );
+  OutputImagePointer outputPtr = this->GetOutput();
+  if ( !inputPtr )
+    {
+    return;
+    }
+  SizeType                Size;                // Size of the output image
+  Size = inputPtr->GetLargestPossibleRegion().GetSize();
+    
+  SpacingType             OutputSpacing;
+  OutputSpacing[0] = m_AngularStep;
+  OutputSpacing[1] = m_RadialStep;
+  
+
+  double Radial_max;
+  double Angular_max;
+  Radial_max  = sqrt(Size[0]*Size[0]+Size[1]*Size[1]);
+  Angular_max = 90.0; 
+  if(m_IsOriginAtCenter == true)
+    {
+    Radial_max /= 2.0;
+    Angular_max = 360.0;
+    }
+  
+  
+  if( Radial_max == 0. || m_RadialNumberOfSamples ==0 )
+    {
+    itkExceptionMacro(<< "LogPolarResampleImageFilter::GenerateOutputInformation() Image size msut be greater than zero for the Radial part"<< std::endl);
+    }
+
+  m_RadialStep = log(Radial_max) / m_RadialNumberOfSamples;
+
+  double bx = log(m_RadialNumberOfSamples) / log(2.0);
+  if(int(bx)!=bx)
+    {
+     m_RadialNumberOfSamples = pow(2,int(bx)+1);
+    }
+  
+  if( m_AngularNumberOfSamples ==0 )
+    {
+    itkExceptionMacro(<< "LogPolarResampleImageFilter::GenerateOutputInformation() Image size msut be greater than zero for the Angular part");
+    }
+
+  m_AngularStep = Angular_max / m_AngularNumberOfSamples;
+  double by = log(m_AngularNumberOfSamples) / log(2.0);
+  if(int(by)!=by)
+    {
+     m_AngularNumberOfSamples = pow(2,int(by)+1);
+    }
+  
+  Size[0] = static_cast<SizeValueType>(m_AngularNumberOfSamples);
+  Size[1] = static_cast<SizeValueType>(m_RadialNumberOfSamples);
+
+  OriginPointType         OutputOrigin;        // output image origin
+  IndexType               OutputStartIndex;    // output image start index
+  OutputOrigin.Fill(0.0);
+  OutputStartIndex.Fill( 0 );
+
+  OutputImageRegionType    outputLargestPossibleRegion;
+  outputLargestPossibleRegion.SetSize( Size );
+  outputLargestPossibleRegion.SetIndex( OutputStartIndex );
+  outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
+
+  outputPtr->SetSpacing( OutputSpacing );
+  outputPtr->SetOrigin( OutputOrigin );
+
+  return;
+}
+
+
+
+/** 
+ * Verify if any of the components has been modified.
+ */
+template <class TInputImage, class TInterpolator>
+unsigned long 
+LogPolarResampleImageFilter<TInputImage,TInterpolator>
+::GetMTime( void ) const
+{
+  unsigned long latestTime = itk::Object::GetMTime(); 
+
+
+  if( m_Interpolator )
+    {
+    if( latestTime < m_Interpolator->GetMTime() )
+      {
+      latestTime = m_Interpolator->GetMTime();
+      }
+    }
+
+  return latestTime;
+}
+
+
+} // end namespace otb
+
+#endif
diff --git a/Testing/Code/BasicFilters/CMakeLists.txt b/Testing/Code/BasicFilters/CMakeLists.txt
index 80376d6de1..652f3119ee 100755
--- a/Testing/Code/BasicFilters/CMakeLists.txt
+++ b/Testing/Code/BasicFilters/CMakeLists.txt
@@ -43,6 +43,16 @@ ADD_TEST(bfTvFiltreFrost ${BASICFILTERS_TESTS}
 	${TEMP}/bfFiltreFrost_poupees_05_05_01.png
 	05 05 0.1)
 
+# -------            otb::LogPolarResampleImageFilter   ------------------------------
+
+ADD_TEST(bfTuLogPolarResampleImageFilterNew ${BASICFILTERS_TESTS}  
+        otbLogPolarResampleImageFilterNew )
+
+ADD_TEST(bfTuLogPolarResampleImageFilter ${BASICFILTERS_TESTS}  
+        otbLogPolarResampleImageFilter
+        ${INPUTDATA}/DeuxCercles.hdr
+	${TEMP}/bfLogPolarResampleImageFilter.hdr)
+
 # -------            otb::PointSetSource   ------------------------------
 
 ADD_TEST(bfTuImageToPointSetFilterTest ${BASICFILTERS_TESTS} 
@@ -55,6 +65,8 @@ otbFrostFilterTest.cxx
 otbFrostFilterNew.cxx
 otbFrostFilter.cxx
 otbImageToPointSetFilterTest.cxx
+otbLogPolarResampleImageFilterNew.cxx
+otbLogPolarResampleImageFilter.cxx
 )
 
 
diff --git a/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx b/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx
index 2bef373d7e..51d3ffce26 100755
--- a/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx
+++ b/Testing/Code/BasicFilters/otbBasicFiltersTests.cxx
@@ -32,4 +32,6 @@ REGISTER_TEST(otbFrostFilterNew);
 REGISTER_TEST(otbFrostFilterTest);
 REGISTER_TEST(otbFrostFilter);
 REGISTER_TEST(otbImageToPointSetFilterTest);
+REGISTER_TEST(otbLogPolarResampleImageFilterNew);
+REGISTER_TEST(otbLogPolarResampleImageFilter);
 }
diff --git a/Testing/Code/BasicFilters/otbFrostFilterNew.cxx b/Testing/Code/BasicFilters/otbFrostFilterNew.cxx
index b1f3338605..363e2fefb3 100644
--- a/Testing/Code/BasicFilters/otbFrostFilterNew.cxx
+++ b/Testing/Code/BasicFilters/otbFrostFilterNew.cxx
@@ -24,7 +24,7 @@
 
 #include "itkExceptionObject.h"
 #include "itkImageFileWriter.h"
-#include "itkImage.h"
+#include "otbImage.h"
 #include "itkRandomImageSource.h"
 #include "itkMeanImageFilter.h"
 
@@ -37,8 +37,8 @@ int otbFrostFilterNew( int argc, char * argv[] )
         typedef unsigned char   	                        OutputPixelType;
         const   unsigned int        	                        Dimension = 2;
 
-        typedef itk::Image< InputPixelType,  Dimension >        InputImageType;
-        typedef itk::Image< OutputPixelType, Dimension >        OutputImageType;
+        typedef otb::Image< InputPixelType,  Dimension >        InputImageType;
+        typedef otb::Image< OutputPixelType, Dimension >        OutputImageType;
 
         typedef otb::FrostImageFilter< InputImageType,OutputImageType >   FilterType;
 
diff --git a/Testing/Code/BasicFilters/otbLogPolarResampleImageFilter.cxx b/Testing/Code/BasicFilters/otbLogPolarResampleImageFilter.cxx
new file mode 100644
index 0000000000..6ddcc8fa97
--- /dev/null
+++ b/Testing/Code/BasicFilters/otbLogPolarResampleImageFilter.cxx
@@ -0,0 +1,79 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4786 )
+#endif
+
+#define MAIN
+
+#include "otbImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+#include "otbLogPolarResampleImageFilter.h"
+
+#include "itkLinearInterpolateImageFunction.h"
+#include "itkExceptionObject.h"
+
+int otbLogPolarResampleImageFilter(int argc, char* argv[])
+{
+  try 
+    {
+
+        const char * inputFilename  = argv[1];
+        const char * outputFilename = argv[2];
+        typedef double                                          InputPixelType;
+        typedef double                                          OutputPixelType;
+  	const   unsigned int        	                        Dimension = 2;
+
+  	typedef otb::Image< InputPixelType, Dimension >         InputImageType;
+  	typedef otb::Image< OutputPixelType, Dimension >        OutputImageType;
+
+        typedef otb::ImageFileReader< InputImageType  >         ReaderType;
+        typedef otb::ImageFileWriter< OutputImageType >         WriterType;
+   
+  	typedef itk::LinearInterpolateImageFunction< InputImageType, double >	InterpolatorType;
+  	typedef otb::LogPolarResampleImageFilter<InputImageType,InterpolatorType> LogPolarResampleImageType;
+     
+     	LogPolarResampleImageType::Pointer LogPolarImage = LogPolarResampleImageType::New();
+
+        ReaderType::Pointer reader = ReaderType::New();
+        WriterType::Pointer writer = WriterType::New();
+
+        reader->SetFileName( inputFilename  );
+        writer->SetFileName( outputFilename );
+
+	LogPolarImage->SetInput( reader->GetOutput() );
+        writer->SetInput( LogPolarImage->GetOutput() );
+        
+        writer->Update(); 
+	
+    } 
+  catch( itk::ExceptionObject & err ) 
+    { 
+    std::cerr << "itk::Exception detected: "  << err.GetDescription();
+    return EXIT_FAILURE;
+    } 
+  catch( ... ) 
+    { 
+    std::cout << "unknown exception detected !" << std::endl; 
+    return EXIT_FAILURE;
+    } 
+  
+  return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/BasicFilters/otbLogPolarResampleImageFilterNew.cxx b/Testing/Code/BasicFilters/otbLogPolarResampleImageFilterNew.cxx
new file mode 100644
index 0000000000..8811a08239
--- /dev/null
+++ b/Testing/Code/BasicFilters/otbLogPolarResampleImageFilterNew.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.
+
+=========================================================================*/
+
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4786 )
+#endif
+
+#define MAIN
+
+#include "otbImage.h"
+#include "otbLogPolarResampleImageFilter.h"
+#include "itkLinearInterpolateImageFunction.h"
+
+int otbLogPolarResampleImageFilterNew(int argc, char* argv[])
+{
+
+  typedef double                                          PixelType;
+  const   unsigned int        	                          Dimension = 2;
+
+  typedef otb::Image< PixelType, Dimension >        InputImageType;
+  typedef otb::Image< PixelType, Dimension >        OutputImageType;
+   
+  typedef itk::LinearInterpolateImageFunction< InputImageType, double >	InterpolatorType;
+  typedef otb::LogPolarResampleImageFilter<InputImageType,InterpolatorType> LogPolarResampleImageType;
+  try 
+    { 
+     LogPolarResampleImageType::Pointer LogPolarImage = LogPolarResampleImageType::New();
+    } 
+  catch( itk::ExceptionObject & err ) 
+    { 
+    std::cerr << "itk::Exception detected: "  << err.GetDescription();
+    return EXIT_FAILURE;
+    } 
+  catch( ... ) 
+    { 
+    std::cout << "unknown exception detected !" << std::endl; 
+    return EXIT_FAILURE;
+    } 
+  
+  return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/FeatureExtraction/CMakeLists.txt b/Testing/Code/FeatureExtraction/CMakeLists.txt
index 9acb0c6118..4f2cb50355 100755
--- a/Testing/Code/FeatureExtraction/CMakeLists.txt
+++ b/Testing/Code/FeatureExtraction/CMakeLists.txt
@@ -380,6 +380,11 @@ ADD_TEST(feTvExtractSegments ${FEATUREEXTRACTION_TESTS}
 	${TEMP}/feFiltreExtractSegments_ImageLine.png
 	2 0.3 20 20 2 10 0.5)                
 
+# -------            otb::ForwardFourierMellinTransformImageFilter   -------------
+
+ADD_TEST(feTuForwardFourierMellinTransformImageFilterNew ${COMMON_TESTS} 
+         otbForwardFourierMellinTransformImageFilterNew)  
+
 # -----------------------------------------------------------------------
 			        
 
@@ -435,6 +440,7 @@ otbLocalHough.cxx
 otbLocalHoughDraw.cxx
 otbExtractSegmentsNew.cxx
 otbExtractSegments.cxx
+otbForwardFourierMellinTransformImageFilterNew.cxx
 )
 
 
-- 
GitLab