From b17043f481dbd5087825d65176c2a45b43192550 Mon Sep 17 00:00:00 2001
From: Emmanuel Christophe <emmanuel.christophe@orfeo-toolbox.org>
Date: Fri, 5 Sep 2008 14:50:05 +0000
Subject: [PATCH] ENH: refactoring road extraction filters for application

---
 .../otbGenericRoadExtractionFilter.h          | 244 ++++++++++++++++++
 .../otbGenericRoadExtractionFilter.txx        | 188 ++++++++++++++
 .../otbRoadExtractionFilter.h                 | 141 +++-------
 .../otbRoadExtractionFilter.txx               | 130 +---------
 4 files changed, 473 insertions(+), 230 deletions(-)
 create mode 100644 Code/FeatureExtraction/otbGenericRoadExtractionFilter.h
 create mode 100644 Code/FeatureExtraction/otbGenericRoadExtractionFilter.txx

diff --git a/Code/FeatureExtraction/otbGenericRoadExtractionFilter.h b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.h
new file mode 100644
index 0000000000..05cb574810
--- /dev/null
+++ b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.h
@@ -0,0 +1,244 @@
+/*=========================================================================
+
+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 __otbGenericRoadExtractionFilter_h
+#define __otbGenericRoadExtractionFilter_h
+
+#include "itkCovariantVector.h"
+#include "itkGradientRecursiveGaussianImageFilter.h"
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageToPathListFilter.h"
+#include "itkSqrtImageFilter.h"
+#include "otbNeighborhoodScalarProductFilter.h"
+#include "otbNonMaxRemovalByDirectionFilter.h"
+#include "otbVectorizationPathListFilter.h"
+#include "otbSimplifyPathListFilter.h"
+#include "otbBreakAngularPathListFilter.h"
+#include "otbRemoveTortuousPathListFilter.h"
+#include "otbLinkPathListFilter.h"
+#include "otbRemoveIsolatedByDirectionFilter.h"
+#include "otbRemoveWrongDirectionFilter.h"
+#include "otbLikehoodPathListFilter.h"
+
+namespace otb
+{
+/**
+ * \class GenericRoadExtractionFilter
+ * \brief This class performs the extraction of roads from an image.
+ * 
+ * This composite filter implements a fast and robust road extraction
+ * for high resolution satellite images. The line 
+ * detection is done using a Gaussian gradient with a scalar product to find
+ * the road directions. Finally, extracted roads are vectorized and 
+ * processed to improve the results removing some occultations and false 
+ * detections.
+ *
+ * This filter is fast, as the detection typically takes 3 seconds for a 
+ * 1000 \f$ \times \f$ 1000 images with four spectral bands. Results can be
+ * used as an initialization for more complex algorithms.
+ *
+ * \sa itk::SqrtImageFilter
+ * \sa itk::GradientRecursiveGaussianImageFilter
+ * \sa NeighborhoodScalarProductFilter
+ * \sa RemoveIsolatedByDirectionFilter
+ * \sa RemoveWrongDirectionFilter
+ * \sa NonMaxRemovalByDirectionFilter
+ * \sa VectorizationPathListFilter
+ * \sa SimplifyPathListFilter
+ * \sa BreakAngularPathListFilter
+ * \sa RemoveTortuousPathListFilter
+ * \sa LinkPathListFilter
+ * \sa LikehoodPathListFilter
+ */
+template <class TInputImage, class TOutputPath>
+  class ITK_EXPORT GenericRoadExtractionFilter
+  : public ImageToPathListFilter<TInputImage,TOutputPath>
+  {
+    public :
+    /** Standard typedefs */ 
+    typedef GenericRoadExtractionFilter                                Self;
+    typedef ImageToPathListFilter<TInputImage,TOutputPath>      Superclass;
+    typedef itk::SmartPointer<Self>                             Pointer;
+    typedef itk::SmartPointer<const Self>                       ConstPointer;
+    /** Creation through object factory macro */
+    itkNewMacro(Self);
+    /** Type macro */
+    itkTypeMacro(GenericRoadExtractionFilter,ImageToPathListFilter);
+    /** Template parameters typedefs */
+    typedef typename Superclass::InputImageType                         InputImageType;
+    typedef typename Superclass::OutputPathType                         OutputPathType;
+    typedef typename Superclass::OutputPathListType                     OutputPathListType;
+    typedef typename InputImageType::PixelType 				InputPixelType;
+    typedef double                                                      InternalPixelType;
+    
+    typedef otb::VectorImage<InternalPixelType,InputImageType::ImageDimension>  VectorImageType;
+    typedef otb::Image<InternalPixelType,InputImageType::ImageDimension>        ModulusType;
+    typedef otb::Image<InternalPixelType,InputImageType::ImageDimension>        DirectionType;
+    
+    typedef itk::CovariantVector<InternalPixelType,InputImageType::ImageDimension> 
+                                                                        VectorPixelType;
+    typedef otb::Image<VectorPixelType,InputImageType::ImageDimension>  CovariantVectorImageType;
+
+
+    typedef itk::SqrtImageFilter<
+        InputImageType,
+        InputImageType>                      SquareRootImageFilterType;
+
+    typedef itk::GradientRecursiveGaussianImageFilter<
+        InputImageType,
+                        CovariantVectorImageType>               GradientFilterType;
+
+    typedef NeighborhoodScalarProductFilter<
+                        CovariantVectorImageType,
+                        ModulusType,
+                        DirectionType>                          NeighborhoodScalarProductFilterType;
+
+    typedef RemoveIsolatedByDirectionFilter<
+                        ModulusType,
+                        DirectionType,
+                        ModulusType >                           RemoveIsolatedByDirectionFilterType;
+
+    typedef RemoveWrongDirectionFilter<
+                        ModulusType,
+                        DirectionType,
+                        ModulusType>                            RemoveWrongDirectionFilterType;
+
+    typedef NonMaxRemovalByDirectionFilter<
+                        ModulusType,
+                        DirectionType,
+                        ModulusType >                           NonMaxRemovalByDirectionFilterType;
+
+    typedef VectorizationPathListFilter<
+                        ModulusType,
+                        DirectionType,
+                        OutputPathType >                        VectorizationPathListFilterType;
+
+    typedef SimplifyPathListFilter<OutputPathType>              SimplifyPathListFilterType;
+    typedef BreakAngularPathListFilter<OutputPathType>          BreakAngularPathListFilterType;
+    typedef RemoveTortuousPathListFilter<OutputPathType>        RemoveTortuousPathListFilterType;
+    typedef LinkPathListFilter<OutputPathType>                  LinkPathListFilterType;
+    typedef LikehoodPathListFilter<OutputPathType, ModulusType>	LikehoodPathListFilterType;
+    
+    /** Template parameters typedefs for internals filters */
+    typedef typename GradientFilterType::RealType SigmaType;
+    typedef typename VectorizationPathListFilterType::InputPixelType AmplitudeThresholdType;
+    typedef typename SimplifyPathListFilterType::ToleranceType ToleranceType;
+    typedef typename BreakAngularPathListFilterType::MaxAngleType MaxAngleType;
+    typedef typename RemoveTortuousPathListFilterType::MeanDistanceThresholdType MeanDistanceThresholdType; 
+    typedef typename LinkPathListFilterType::RealType LinkRealType;
+     
+
+  /** Get/Set the alpha value */
+  itkGetConstReferenceMacro(Alpha,double);
+  itkSetMacro(Alpha,double);
+
+  /** Get/Set the amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/
+  itkSetMacro(AmplitudeThreshold,AmplitudeThresholdType);
+  itkGetMacro(AmplitudeThreshold,AmplitudeThresholdType);
+
+  /** Get/Set  the tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/
+  itkGetMacro(Tolerance,ToleranceType);
+  itkSetMacro(Tolerance,ToleranceType);
+
+  /** Set/Get the max angle (use bye the BreakAngularPathListFilter)*/
+  itkSetMacro(MaxAngle,MaxAngleType);
+  itkGetConstMacro(MaxAngle,MaxAngleType);
+
+  /** Get/Set the tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/
+  itkGetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType);
+  itkSetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType);
+  itkGetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType);
+  itkSetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType);
+ 
+  /** Get/Set the angular threshold (use by LinkPathFilter)*/
+  itkSetMacro(AngularThreshold,LinkRealType);
+  itkGetMacro(AngularThreshold,LinkRealType);
+  /** Get/Set the distance threshold (use by LinkPathFilter)*/
+  itkSetMacro(DistanceThreshold,LinkRealType);
+  itkGetMacro(DistanceThreshold,LinkRealType);
+  
+  
+  protected:
+    /** Constructor */
+    GenericRoadExtractionFilter();
+    /** Destructor */
+    ~GenericRoadExtractionFilter() {};
+
+    /** Prepare main computation method */
+    void BeforeGenerateData(void);
+
+    /** Main computation method */
+    void GenerateData(void);
+    /** PrintSelf method */
+    void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+  private :
+    
+    GenericRoadExtractionFilter(const Self&); // purposely not implemented
+    void operator=(const Self&); // purposely not implemented
+
+
+    typename SquareRootImageFilterType::Pointer                 m_SquareRootImageFilter;
+    typename GradientFilterType::Pointer                        m_GradientFilter;
+    typename NeighborhoodScalarProductFilterType::Pointer       m_NeighborhoodScalarProductFilter;
+    typename RemoveIsolatedByDirectionFilterType::Pointer       m_RemoveIsolatedByDirectionFilter;
+    typename RemoveWrongDirectionFilterType::Pointer            m_RemoveWrongDirectionFilter;
+    typename NonMaxRemovalByDirectionFilterType::Pointer        m_NonMaxRemovalByDirectionFilter;
+    typename VectorizationPathListFilterType::Pointer           m_VectorizationPathListFilter;
+    typename SimplifyPathListFilterType::Pointer                m_FirstSimplifyPathListFilter;
+    typename SimplifyPathListFilterType::Pointer                m_SecondSimplifyPathListFilter;
+    typename BreakAngularPathListFilterType::Pointer            m_BreakAngularPathListFilter;
+    typename RemoveTortuousPathListFilterType::Pointer          m_FirstRemoveTortuousPathListFilter;
+    typename RemoveTortuousPathListFilterType::Pointer          m_SecondRemoveTortuousPathListFilter;
+    typename LinkPathListFilterType::Pointer                    m_LinkPathListFilter;
+    typename LikehoodPathListFilterType::Pointer 		m_LikehoodPathListFilter;
+
+
+  /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/
+  AmplitudeThresholdType m_AmplitudeThreshold;
+  /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/
+  ToleranceType m_Tolerance;
+  /** Max angle (use bye the BreakAngularPathListFilter)*/
+  MaxAngleType m_MaxAngle;
+  /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/
+  MeanDistanceThresholdType m_FirstMeanDistanceThreshold;
+  MeanDistanceThresholdType m_SecondMeanDistanceThreshold;
+  /** The angular threshold (use by LinkPathListFilter) */
+  LinkRealType m_AngularThreshold;
+
+  /** The distance threshold (use by LinkPathListFilter) */
+  double m_DistanceThreshold;
+  
+  /** Alpha. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter */
+  double m_Alpha;
+
+  /** Resolution of the image. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter 
+  and the m_DistanceThreshold value used by the LinkPathListFilter
+  This value is set bye the image's spacing.*/
+  double m_Resolution;
+
+  };
+
+}// End namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbGenericRoadExtractionFilter.txx"
+#endif
+
+#endif
diff --git a/Code/FeatureExtraction/otbGenericRoadExtractionFilter.txx b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.txx
new file mode 100644
index 0000000000..5ad1b49f69
--- /dev/null
+++ b/Code/FeatureExtraction/otbGenericRoadExtractionFilter.txx
@@ -0,0 +1,188 @@
+/*=========================================================================
+
+  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 __otbGenericRoadExtractionFilter_txx
+#define __otbGenericRoadExtractionFilter_txx
+
+#include "otbGenericRoadExtractionFilter.h"
+#include "otbMath.h"
+
+namespace otb
+{
+/**
+ * Constructor
+ */
+template <class TInputImage,class TOutputPath>
+GenericRoadExtractionFilter<TInputImage, TOutputPath>
+::GenericRoadExtractionFilter()
+{
+        this->SetNumberOfRequiredInputs(1);
+        this->SetNumberOfRequiredOutputs(1);
+
+	m_SquareRootImageFilter = SquareRootImageFilterType::New();
+        m_GradientFilter = GradientFilterType::New();
+        m_NeighborhoodScalarProductFilter = NeighborhoodScalarProductFilterType::New();
+        m_RemoveIsolatedByDirectionFilter = RemoveIsolatedByDirectionFilterType::New();
+        m_RemoveWrongDirectionFilter = RemoveWrongDirectionFilterType::New();
+        m_NonMaxRemovalByDirectionFilter = NonMaxRemovalByDirectionFilterType::New();
+        m_VectorizationPathListFilter = VectorizationPathListFilterType::New();
+        m_FirstSimplifyPathListFilter = SimplifyPathListFilterType::New();
+        m_SecondSimplifyPathListFilter = SimplifyPathListFilterType::New();
+        m_BreakAngularPathListFilter = BreakAngularPathListFilterType::New();
+        m_FirstRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New();
+        m_SecondRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New();
+        m_LinkPathListFilter = LinkPathListFilterType::New();
+        m_LikehoodPathListFilter = LikehoodPathListFilterType::New();
+        
+        /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/
+        m_AmplitudeThreshold = static_cast<AmplitudeThresholdType>(1.);
+        /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathFilter)*/
+        m_Tolerance = static_cast<ToleranceType>(1.);
+        /** Max angle (use bye the BreakAngularPathListFilter)*/
+        m_MaxAngle = static_cast<MaxAngleType>(M_PI/8.);
+        /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathFilter)*/
+        m_FirstMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(1.);
+        m_SecondMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(10.);
+        /** The angular threshold (use by LinkPathFilter) */
+        m_AngularThreshold = static_cast<LinkRealType>(M_PI/8.);
+
+        /** The distance threshold (use by LinkPathFilter) */
+        m_DistanceThreshold = 25.;
+
+        /** Alpha value */
+        /** Use to calculate the sigma value use by the GradientRecursiveGaussianImageFilter */
+        m_Alpha = 0.;
+        
+        /** Resolution of the image */
+        m_Resolution = 1.;
+}
+/**
+ * Prepare main computation method
+ */
+template <class TInputImage,class TOutputPath>
+void
+GenericRoadExtractionFilter<TInputImage, TOutputPath>
+::BeforeGenerateData()
+{
+  /** Calculation of resolution value */
+  typename InputImageType::SpacingType spacing = this->GetInput()->GetSpacing();
+  // Getting x Spacing for the resolution
+  m_Resolution = static_cast<double>(spacing[0]);
+  if( m_Resolution == 0. )
+  {
+        itkWarningMacro(<< "The image spacing is zero. So the resolution used in the filter is forced to 1.");
+        m_Resolution = 1.;
+  }
+
+}
+
+/**
+ * Main computation method
+ */
+template <class TInputImage,class TOutputPath>
+void
+GenericRoadExtractionFilter<TInputImage, TOutputPath>
+::GenerateData()
+{
+  // // Input images pointers
+   typename InputImageType::ConstPointer inputImage     = this->GetInput();
+   typename OutputPathListType::Pointer outputPathList  = this->GetOutput();
+
+  ///////////////////////////////////////
+  //// Algorithm for road extraction ////
+  ///////////////////////////////////////
+
+  // 
+
+  m_SquareRootImageFilter->SetInput(inputImage);
+  
+  m_GradientFilter->SetInput(m_SquareRootImageFilter->GetOutput());
+  /** Sigma calculated with the alpha and image resolution parameters */
+  m_GradientFilter->SetSigma(static_cast<SigmaType>(m_Alpha * (1.2/m_Resolution + 1.) ));
+  
+  m_NeighborhoodScalarProductFilter->SetInput(m_GradientFilter->GetOutput());
+  
+  m_RemoveIsolatedByDirectionFilter->SetInput(m_NeighborhoodScalarProductFilter->GetOutput());
+  m_RemoveIsolatedByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
+  
+  m_RemoveWrongDirectionFilter->SetInput(m_RemoveIsolatedByDirectionFilter->GetOutput());
+  m_RemoveWrongDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
+
+  m_NonMaxRemovalByDirectionFilter->SetInput(m_RemoveWrongDirectionFilter->GetOutput());
+  m_NonMaxRemovalByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
+
+  m_VectorizationPathListFilter->SetInput(m_NonMaxRemovalByDirectionFilter->GetOutput());
+  m_VectorizationPathListFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
+  m_VectorizationPathListFilter->SetAmplitudeThreshold(m_AmplitudeThreshold);
+  
+  m_FirstSimplifyPathListFilter->SetInput(m_VectorizationPathListFilter->GetOutput());
+  m_FirstSimplifyPathListFilter->SetTolerance(m_Tolerance);
+  
+  m_BreakAngularPathListFilter->SetInput(m_FirstSimplifyPathListFilter->GetOutput());
+  m_BreakAngularPathListFilter->SetMaxAngle(m_MaxAngle);
+  
+  m_FirstRemoveTortuousPathListFilter->SetInput(m_BreakAngularPathListFilter->GetOutput());
+  m_FirstRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_FirstMeanDistanceThreshold);
+
+  m_LinkPathListFilter->SetInput(m_FirstRemoveTortuousPathListFilter->GetOutput());
+  m_LinkPathListFilter->SetAngularThreshold(m_AngularThreshold);
+  m_LinkPathListFilter->SetDistanceThreshold( static_cast<LinkRealType>(m_DistanceThreshold/m_Resolution) );
+
+  m_SecondSimplifyPathListFilter->SetInput(m_LinkPathListFilter->GetOutput());
+  m_SecondSimplifyPathListFilter->SetTolerance(m_Tolerance);
+ 
+  m_SecondRemoveTortuousPathListFilter->SetInput(m_SecondSimplifyPathListFilter->GetOutput());
+  m_SecondRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_SecondMeanDistanceThreshold);
+  
+  m_LikehoodPathListFilter->SetInput(m_SecondRemoveTortuousPathListFilter->GetOutput());
+  m_LikehoodPathListFilter->SetInputImage(m_NonMaxRemovalByDirectionFilter->GetOutput());
+  
+  // Graft output seems to be broken for PolylineParametricPath
+  // So we use update, and copy the path to the output path list.
+  // m_LikehoodPathListFilter->GraftOutput(this->GetOutput());
+  m_LikehoodPathListFilter->Update();
+  // outputPathList =  m_LikehoodPathListFilter->GetOutput();
+    for(typename LikehoodPathListFilterType::PathListType::ConstIterator it 
+	  = m_LikehoodPathListFilter->GetOutput()->Begin();
+      it!=m_LikehoodPathListFilter->GetOutput()->End();
+      ++it)
+    {
+      outputPathList->PushBack(it.Get());
+    }
+}
+/**
+ * PrintSelf method
+ */
+template <class TInputImage,class TOutputPath>
+void
+GenericRoadExtractionFilter<TInputImage, TOutputPath>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os,indent);
+  os << indent << "m_Alpha:"<< m_Alpha << std::endl;
+  os << indent << "m_Resolution:"<< m_Resolution << std::endl;
+  os << indent << "m_AmplitudeThreshold: "<< m_AmplitudeThreshold << std::endl;
+  os << indent << "m_Tolerance: "<< m_Tolerance << std::endl;
+  os << indent << "m_MaxAngle: "<< m_MaxAngle << std::endl;
+  os << indent << "m_FirstMeanDistanceThreshold: "<< m_FirstMeanDistanceThreshold << std::endl;
+  os << indent << "m_SecondMeanDistanceThreshold: "<< m_SecondMeanDistanceThreshold << std::endl;
+  os << indent << "m_DistanceThreshold: "<<m_DistanceThreshold<< std::endl;
+  os << indent << "m_AngularThreshold: "<<m_AngularThreshold<< std::endl;
+
+}
+} // End namespace otb
+#endif
diff --git a/Code/FeatureExtraction/otbRoadExtractionFilter.h b/Code/FeatureExtraction/otbRoadExtractionFilter.h
index 600081c3b0..f4ee3db0e1 100644
--- a/Code/FeatureExtraction/otbRoadExtractionFilter.h
+++ b/Code/FeatureExtraction/otbRoadExtractionFilter.h
@@ -25,17 +25,7 @@ PURPOSE.  See the above copyright notices for more information.
 #include "otbVectorImage.h"
 #include "otbImageToPathListFilter.h"
 #include "otbSpectralAngleDistanceImageFilter.h"
-#include "itkSqrtImageFilter.h"
-#include "otbNeighborhoodScalarProductFilter.h"
-#include "otbNonMaxRemovalByDirectionFilter.h"
-#include "otbVectorizationPathListFilter.h"
-#include "otbSimplifyPathListFilter.h"
-#include "otbBreakAngularPathListFilter.h"
-#include "otbRemoveTortuousPathListFilter.h"
-#include "otbLinkPathListFilter.h"
-#include "otbRemoveIsolatedByDirectionFilter.h"
-#include "otbRemoveWrongDirectionFilter.h"
-#include "otbLikehoodPathListFilter.h"
+#include "otbGenericRoadExtractionFilter.h"
 
 namespace otb
 {
@@ -68,6 +58,7 @@ namespace otb
  * \sa RemoveTortuousPathListFilter
  * \sa LinkPathListFilter
  * \sa LikehoodPathListFilter
+ * \sa GenericRoadExtractionFilter
  */
 template <class TInputImage, class TOutputPath>
   class ITK_EXPORT RoadExtractionFilter
@@ -104,86 +95,50 @@ template <class TInputImage, class TOutputPath>
                         InputImageType,
                         SpectralAngleType>                      SpectralAngleDistanceImageFilterType;
 
-    typedef itk::SqrtImageFilter<
-                        SpectralAngleType,
-                        SpectralAngleType>                      SquareRootImageFilterType;
-
-    typedef itk::GradientRecursiveGaussianImageFilter<
-                        SpectralAngleType,
-                        CovariantVectorImageType>               GradientFilterType;
-
-    typedef NeighborhoodScalarProductFilter<
-                        CovariantVectorImageType,
-                        ModulusType,
-                        DirectionType>                          NeighborhoodScalarProductFilterType;
-
-    typedef RemoveIsolatedByDirectionFilter<
-                        ModulusType,
-                        DirectionType,
-                        ModulusType >                           RemoveIsolatedByDirectionFilterType;
-
-    typedef RemoveWrongDirectionFilter<
-                        ModulusType,
-                        DirectionType,
-                        ModulusType>                            RemoveWrongDirectionFilterType;
-
-    typedef NonMaxRemovalByDirectionFilter<
-                        ModulusType,
-                        DirectionType,
-                        ModulusType >                           NonMaxRemovalByDirectionFilterType;
-
-    typedef VectorizationPathListFilter<
-                        ModulusType,
-                        DirectionType,
-                        OutputPathType >                        VectorizationPathListFilterType;
-
-    typedef SimplifyPathListFilter<OutputPathType>              SimplifyPathListFilterType;
-    typedef BreakAngularPathListFilter<OutputPathType>          BreakAngularPathListFilterType;
-    typedef RemoveTortuousPathListFilter<OutputPathType>        RemoveTortuousPathListFilterType;
-    typedef LinkPathListFilter<OutputPathType>                  LinkPathListFilterType;
-    typedef LikehoodPathListFilter<OutputPathType, ModulusType>	LikehoodPathListFilterType;
+    typedef GenericRoadExtractionFilter<SpectralAngleType, OutputPathType>
+        GenericRoadExtractionFilterType;
+                        
     
     /** Template parameters typedefs for internals filters */
-    typedef typename GradientFilterType::RealType SigmaType;
-    typedef typename VectorizationPathListFilterType::InputPixelType AmplitudeThresholdType;
-    typedef typename SimplifyPathListFilterType::ToleranceType ToleranceType;
-    typedef typename BreakAngularPathListFilterType::MaxAngleType MaxAngleType;
-    typedef typename RemoveTortuousPathListFilterType::MeanDistanceThresholdType MeanDistanceThresholdType; 
-    typedef typename LinkPathListFilterType::RealType LinkRealType;
+        typedef typename GenericRoadExtractionFilterType::SigmaType SigmaType;
+        typedef typename GenericRoadExtractionFilterType::AmplitudeThresholdType AmplitudeThresholdType;
+        typedef typename GenericRoadExtractionFilterType::ToleranceType ToleranceType;
+        typedef typename GenericRoadExtractionFilterType::MaxAngleType MaxAngleType;
+        typedef typename GenericRoadExtractionFilterType::MeanDistanceThresholdType MeanDistanceThresholdType; 
+        typedef typename GenericRoadExtractionFilterType::LinkRealType LinkRealType;
      
   /** Get/Set the reference pixel (use by the SpectralAngleDistanceImageFilter)*/
-  itkGetConstReferenceMacro(ReferencePixel,InputPixelType);
-  itkSetMacro(ReferencePixel,InputPixelType);
+  otbGetObjectMemberConstReferenceMacro(SpectralAngleDistanceImageFilter,ReferencePixel,InputPixelType);
+  otbSetObjectMemberMacro(SpectralAngleDistanceImageFilter,ReferencePixel,InputPixelType);
 
   /** Get/Set the alpha value */
-  itkGetConstReferenceMacro(Alpha,double);
-  itkSetMacro(Alpha,double);
+  otbGetObjectMemberConstReferenceMacro(GenericRoadExtractionFilter,Alpha,double);
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,Alpha,double);
 
   /** Get/Set the amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/
-  itkSetMacro(AmplitudeThreshold,AmplitudeThresholdType);
-  itkGetMacro(AmplitudeThreshold,AmplitudeThresholdType);
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,AmplitudeThreshold,AmplitudeThresholdType);
+  otbGetObjectMemberMacro(GenericRoadExtractionFilter,AmplitudeThreshold,AmplitudeThresholdType);
 
   /** Get/Set  the tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/
-  itkGetMacro(Tolerance,ToleranceType);
-  itkSetMacro(Tolerance,ToleranceType);
+  otbGetObjectMemberMacro(GenericRoadExtractionFilter,Tolerance,ToleranceType);
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,Tolerance,ToleranceType);
 
   /** Set/Get the max angle (use bye the BreakAngularPathListFilter)*/
-  itkSetMacro(MaxAngle,MaxAngleType);
-  itkGetConstMacro(MaxAngle,MaxAngleType);
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,MaxAngle,MaxAngleType);
+  otbGetObjectMemberConstMacro(GenericRoadExtractionFilter,MaxAngle,MaxAngleType);
 
   /** Get/Set the tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/
-  itkGetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType);
-  itkSetMacro(FirstMeanDistanceThreshold,MeanDistanceThresholdType);
-  itkGetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType);
-  itkSetMacro(SecondMeanDistanceThreshold,MeanDistanceThresholdType);
+  otbGetObjectMemberMacro(GenericRoadExtractionFilter,FirstMeanDistanceThreshold,MeanDistanceThresholdType);
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,FirstMeanDistanceThreshold,MeanDistanceThresholdType);
+  otbGetObjectMemberMacro(GenericRoadExtractionFilter,SecondMeanDistanceThreshold,MeanDistanceThresholdType);
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,SecondMeanDistanceThreshold,MeanDistanceThresholdType);
  
   /** Get/Set the angular threshold (use by LinkPathFilter)*/
-  itkSetMacro(AngularThreshold,LinkRealType);
-  itkGetMacro(AngularThreshold,LinkRealType);
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,AngularThreshold,LinkRealType);
+  otbGetObjectMemberMacro(GenericRoadExtractionFilter,AngularThreshold,LinkRealType);
   /** Get/Set the distance threshold (use by LinkPathFilter)*/
-  itkSetMacro(DistanceThreshold,LinkRealType);
-  itkGetMacro(DistanceThreshold,LinkRealType);
-  
+  otbSetObjectMemberMacro(GenericRoadExtractionFilter,DistanceThreshold,LinkRealType);
+  otbGetObjectMemberMacro(GenericRoadExtractionFilter,DistanceThreshold,LinkRealType);
   
   protected:
     /** Constructor */
@@ -206,45 +161,11 @@ template <class TInputImage, class TOutputPath>
 
     /** SpectralAngleDistanceImageFilter use by the composite filter */
     typename SpectralAngleDistanceImageFilterType::Pointer      m_SpectralAngleDistanceImageFilter;
-    typename SquareRootImageFilterType::Pointer                 m_SquareRootImageFilter;
-    typename GradientFilterType::Pointer                        m_GradientFilter;
-    typename NeighborhoodScalarProductFilterType::Pointer       m_NeighborhoodScalarProductFilter;
-    typename RemoveIsolatedByDirectionFilterType::Pointer       m_RemoveIsolatedByDirectionFilter;
-    typename RemoveWrongDirectionFilterType::Pointer            m_RemoveWrongDirectionFilter;
-    typename NonMaxRemovalByDirectionFilterType::Pointer        m_NonMaxRemovalByDirectionFilter;
-    typename VectorizationPathListFilterType::Pointer           m_VectorizationPathListFilter;
-    typename SimplifyPathListFilterType::Pointer                m_FirstSimplifyPathListFilter;
-    typename SimplifyPathListFilterType::Pointer                m_SecondSimplifyPathListFilter;
-    typename BreakAngularPathListFilterType::Pointer            m_BreakAngularPathListFilter;
-    typename RemoveTortuousPathListFilterType::Pointer          m_FirstRemoveTortuousPathListFilter;
-    typename RemoveTortuousPathListFilterType::Pointer          m_SecondRemoveTortuousPathListFilter;
-    typename LinkPathListFilterType::Pointer                    m_LinkPathListFilter;
-    typename LikehoodPathListFilterType::Pointer 		m_LikehoodPathListFilter;
+    typename GenericRoadExtractionFilterType::Pointer m_GenericRoadExtractionFilter;
 
   /** The reference pixel (use by the SpectralAngleDistanceImageFilter)*/
-  InputPixelType m_ReferencePixel;
-  /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/
-  AmplitudeThresholdType m_AmplitudeThreshold;
-  /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathListFilter)*/
-  ToleranceType m_Tolerance;
-  /** Max angle (use bye the BreakAngularPathListFilter)*/
-  MaxAngleType m_MaxAngle;
-  /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathListFilter)*/
-  MeanDistanceThresholdType m_FirstMeanDistanceThreshold;
-  MeanDistanceThresholdType m_SecondMeanDistanceThreshold;
-  /** The angular threshold (use by LinkPathListFilter) */
-  LinkRealType m_AngularThreshold;
-
-  /** The distance threshold (use by LinkPathListFilter) */
-  double m_DistanceThreshold;
-  
-  /** Alpha. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter */
-  double m_Alpha;
+//   InputPixelType m_ReferencePixel;
 
-  /** Resolution of the image. Use to calculate the sigma value used by the GradientRecursiveGaussianImageFilter 
-  and the m_DistanceThreshold value used by the LinkPathListFilter
-  This value is set bye the image's spacing.*/
-  double m_Resolution;
 
   };
 
diff --git a/Code/FeatureExtraction/otbRoadExtractionFilter.txx b/Code/FeatureExtraction/otbRoadExtractionFilter.txx
index 037e46ec29..7a7f572867 100644
--- a/Code/FeatureExtraction/otbRoadExtractionFilter.txx
+++ b/Code/FeatureExtraction/otbRoadExtractionFilter.txx
@@ -34,62 +34,10 @@ RoadExtractionFilter<TInputImage, TOutputPath>
         this->SetNumberOfRequiredOutputs(1);
 
         m_SpectralAngleDistanceImageFilter = SpectralAngleDistanceImageFilterType::New();
-	m_SquareRootImageFilter = SquareRootImageFilterType::New();
-        m_GradientFilter = GradientFilterType::New();
-        m_NeighborhoodScalarProductFilter = NeighborhoodScalarProductFilterType::New();
-        m_RemoveIsolatedByDirectionFilter = RemoveIsolatedByDirectionFilterType::New();
-        m_RemoveWrongDirectionFilter = RemoveWrongDirectionFilterType::New();
-        m_NonMaxRemovalByDirectionFilter = NonMaxRemovalByDirectionFilterType::New();
-        m_VectorizationPathListFilter = VectorizationPathListFilterType::New();
-        m_FirstSimplifyPathListFilter = SimplifyPathListFilterType::New();
-        m_SecondSimplifyPathListFilter = SimplifyPathListFilterType::New();
-        m_BreakAngularPathListFilter = BreakAngularPathListFilterType::New();
-        m_FirstRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New();
-        m_SecondRemoveTortuousPathListFilter = RemoveTortuousPathListFilterType::New();
-        m_LinkPathListFilter = LinkPathListFilterType::New();
-        m_LikehoodPathListFilter = LikehoodPathListFilterType::New();
+        m_GenericRoadExtractionFilter = GenericRoadExtractionFilterType::New();
         
-        /** Amplitude threshold to start following a path (use by the VectorizationPathListFilter)*/
-        m_AmplitudeThreshold = static_cast<AmplitudeThresholdType>(1.);
-        /** Tolerance for segment consistency (tolerance in terms of distance) (use by the SimplifyPathFilter)*/
-        m_Tolerance = static_cast<ToleranceType>(1.);
-        /** Max angle (use bye the BreakAngularPathListFilter)*/
-        m_MaxAngle = static_cast<MaxAngleType>(M_PI/8.);
-        /** Tolerance for segment consistency (tolerance in terms of distance) (use by RemoveTortuousPathFilter)*/
-        m_FirstMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(1.);
-        m_SecondMeanDistanceThreshold = static_cast<MeanDistanceThresholdType>(10.);
-        /** The angular threshold (use by LinkPathFilter) */
-        m_AngularThreshold = static_cast<LinkRealType>(M_PI/8.);
-
-        /** The distance threshold (use by LinkPathFilter) */
-        m_DistanceThreshold = 25.;
-
-        /** Alpha value */
-        /** Use to calculate the sigma value use by the GradientRecursiveGaussianImageFilter */
-        m_Alpha = 0.;
-        
-        /** Resolution of the image */
-        m_Resolution = 1.;
 }
-/**
- * Prepare main computation method
- */
-template <class TInputImage,class TOutputPath>
-void
-RoadExtractionFilter<TInputImage, TOutputPath>
-::BeforeGenerateData()
-{
-  /** Calculation of resolution value */
-  typename InputImageType::SpacingType spacing = this->GetInput()->GetSpacing();
-  // Getting x Spacing for the resolution
-  m_Resolution = static_cast<double>(spacing[0]);
-  if( m_Resolution == 0. )
-  {
-        itkWarningMacro(<< "The image spacing is zero. So the resolution used in the filter is forced to 1.");
-        m_Resolution = 1.;
-  }
 
-}
 
 /**
  * Main computation method
@@ -99,69 +47,20 @@ void
 RoadExtractionFilter<TInputImage, TOutputPath>
 ::GenerateData()
 {
-  // // Input images pointers
+  // Input images pointers
    typename InputImageType::ConstPointer inputImage     = this->GetInput();
    typename OutputPathListType::Pointer outputPathList  = this->GetOutput();
 
-  ///////////////////////////////////////
-  //// Algorithm for road extraction ////
-  ///////////////////////////////////////
-
   // 
   m_SpectralAngleDistanceImageFilter->SetInput(inputImage);
-  m_SpectralAngleDistanceImageFilter->SetReferencePixel(m_ReferencePixel);
+//   m_SpectralAngleDistanceImageFilter->SetReferencePixel(m_ReferencePixel);
 
-  m_SquareRootImageFilter->SetInput(m_SpectralAngleDistanceImageFilter->GetOutput());
-  
-  m_GradientFilter->SetInput(m_SquareRootImageFilter->GetOutput());
-  /** Sigma calculated with the alpha and image resolution parameters */
-  m_GradientFilter->SetSigma(static_cast<SigmaType>(m_Alpha * (1.2/m_Resolution + 1.) ));
-  
-  m_NeighborhoodScalarProductFilter->SetInput(m_GradientFilter->GetOutput());
+  m_GenericRoadExtractionFilter->SetInput(m_SpectralAngleDistanceImageFilter->GetOutput());
   
-  m_RemoveIsolatedByDirectionFilter->SetInput(m_NeighborhoodScalarProductFilter->GetOutput());
-  m_RemoveIsolatedByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
-  
-  m_RemoveWrongDirectionFilter->SetInput(m_RemoveIsolatedByDirectionFilter->GetOutput());
-  m_RemoveWrongDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
-
-  m_NonMaxRemovalByDirectionFilter->SetInput(m_RemoveWrongDirectionFilter->GetOutput());
-  m_NonMaxRemovalByDirectionFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
-
-  m_VectorizationPathListFilter->SetInput(m_NonMaxRemovalByDirectionFilter->GetOutput());
-  m_VectorizationPathListFilter->SetInputDirection(m_NeighborhoodScalarProductFilter->GetOutputDirection());
-  m_VectorizationPathListFilter->SetAmplitudeThreshold(m_AmplitudeThreshold);
-  
-  m_FirstSimplifyPathListFilter->SetInput(m_VectorizationPathListFilter->GetOutput());
-  m_FirstSimplifyPathListFilter->SetTolerance(m_Tolerance);
-  
-  m_BreakAngularPathListFilter->SetInput(m_FirstSimplifyPathListFilter->GetOutput());
-  m_BreakAngularPathListFilter->SetMaxAngle(m_MaxAngle);
-  
-  m_FirstRemoveTortuousPathListFilter->SetInput(m_BreakAngularPathListFilter->GetOutput());
-  m_FirstRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_FirstMeanDistanceThreshold);
-
-  m_LinkPathListFilter->SetInput(m_FirstRemoveTortuousPathListFilter->GetOutput());
-  m_LinkPathListFilter->SetAngularThreshold(m_AngularThreshold);
-  m_LinkPathListFilter->SetDistanceThreshold( static_cast<LinkRealType>(m_DistanceThreshold/m_Resolution) );
-
-  m_SecondSimplifyPathListFilter->SetInput(m_LinkPathListFilter->GetOutput());
-  m_SecondSimplifyPathListFilter->SetTolerance(m_Tolerance);
- 
-  m_SecondRemoveTortuousPathListFilter->SetInput(m_SecondSimplifyPathListFilter->GetOutput());
-  m_SecondRemoveTortuousPathListFilter->SetMeanDistanceThreshold(m_SecondMeanDistanceThreshold);
-  
-  m_LikehoodPathListFilter->SetInput(m_SecondRemoveTortuousPathListFilter->GetOutput());
-  m_LikehoodPathListFilter->SetInputImage(m_NonMaxRemovalByDirectionFilter->GetOutput());
-  
-  // Graft output seems to be broken for PolylineParametricPath
-  // So we use update, and copy the path to the output path list.
-  // m_LikehoodPathListFilter->GraftOutput(this->GetOutput());
-  m_LikehoodPathListFilter->Update();
-  // outputPathList =  m_LikehoodPathListFilter->GetOutput();
-    for(typename LikehoodPathListFilterType::PathListType::ConstIterator it 
-	  = m_LikehoodPathListFilter->GetOutput()->Begin();
-      it!=m_LikehoodPathListFilter->GetOutput()->End();
+  m_GenericRoadExtractionFilter->Update();
+  for(typename GenericRoadExtractionFilterType::OutputPathListType::ConstIterator it 
+        = m_GenericRoadExtractionFilter->GetOutput()->Begin();
+        it!=m_GenericRoadExtractionFilter->GetOutput()->End();
       ++it)
     {
       outputPathList->PushBack(it.Get());
@@ -176,17 +75,8 @@ RoadExtractionFilter<TInputImage, TOutputPath>
 ::PrintSelf(std::ostream& os, itk::Indent indent) const
 {
   Superclass::PrintSelf(os,indent);
-  os << indent << "m_Alpha:"<< m_Alpha << std::endl;
-  os << indent << "m_Resolution:"<< m_Resolution << std::endl;
-  os << indent << "m_ReferencePixel: "<< m_ReferencePixel << std::endl;
-  os << indent << "m_AmplitudeThreshold: "<< m_AmplitudeThreshold << std::endl;
-  os << indent << "m_Tolerance: "<< m_Tolerance << std::endl;
-  os << indent << "m_MaxAngle: "<< m_MaxAngle << std::endl;
-  os << indent << "m_FirstMeanDistanceThreshold: "<< m_FirstMeanDistanceThreshold << std::endl;
-  os << indent << "m_SecondMeanDistanceThreshold: "<< m_SecondMeanDistanceThreshold << std::endl;
-  os << indent << "m_DistanceThreshold: "<<m_DistanceThreshold<< std::endl;
-  os << indent << "m_AngularThreshold: "<<m_AngularThreshold<< std::endl;
-
+  os << indent << "m_ReferencePixel: "<< m_SpectralAngleDistanceImageFilter->GetReferencePixel() << std::endl;
 }
+
 } // End namespace otb
 #endif
-- 
GitLab