diff --git a/Code/FeatureExtraction/otbLineCorrelationDetector.h b/Code/FeatureExtraction/otbLineCorrelationDetector.h
new file mode 100755
index 0000000000000000000000000000000000000000..7189964d49163a6149f562b58b81ed271b7497c7
--- /dev/null
+++ b/Code/FeatureExtraction/otbLineCorrelationDetector.h
@@ -0,0 +1,176 @@
+/*=========================================================================
+
+  Programme :   OTB (ORFEO ToolBox)
+  Auteurs   :   CS - C.Ruffel
+  Language  :   C++
+  Date      :   14 mars 2006
+  Role      :   Filter of detection of linear features 
+  $Id$ 
+
+=========================================================================*/
+#ifndef __otbLineCorrelationDetector_h
+#define __otbLineCorrelationDetector_h
+
+#include "itkBSplineInterpolateImageFunction.h"
+#include "itkImageToImageFilter.h"
+#include "itkImage.h"
+#include "itkNumericTraits.h"
+
+#define MIN(_A,_B) ((_A) < (_B) ? (_A) : (_B))
+#define MAX(_A,_B) ((_A) > (_B) ? (_A) : (_B))  
+#define ROTATION(_x,_y,_theta,_xout,_yout) \
+    (_xout) = (_x)*cos(_theta) - (_y)*sin(_theta); \
+    (_yout) = (_x)*sin(_theta) + (_y)*cos(_theta)
+
+
+namespace otb
+{
+
+/** \class LineCorrelationDetector
+ * \brief Application of the filter of detection of linear features 
+ *
+ * This class implements the Tupin's detector D2 used to detect 
+ * two parallel lines, based on a new edge detector.
+ *
+ * The region is devided in three zones to delimite two parallel lines. 
+ * The size of one zone is defined by the product of the width 
+ * of the linear feature by its length.
+ *
+ * For each vertical line, we calculate the cross correlation coefficient 
+ * \rho_{ij} between regions i and j.
+ *	\[\rho_{ij}=\fract{1}{1+(n_{i}+n_{j})\fract{n_{i}\gamma_{i}^{2}\bar{c}_{ij}^{2}}{n_{i}n_{j}(\bar{c}_{ij}-1)^{2}} \]
+ *
+ * where n_{i} is the pixel number in region i, \bar{c}_{ij} = \fract{\mu_{i}}{\mu_{j}}
+ * is the empiraical contrast between regions i and j, and \gamma_{i} is the varaition
+ * coefficient (ratio of standard deviation and mean) that measures homogeneity in
+ * radar imagery scenes.
+ *
+ * The intensity of detection in the three other directions \rho(\theta_{i})
+ * is determined by rotation of the pixels of each zone around the 
+ * pixel central of the region considered. By default, the pixel location after
+ * rotation is determined by the Spline interpolator.
+ * 
+ * Finally, the intensity of detection formed by the two parallel lines 
+ * is determined by the minimum response of a ration edge detector on both sides
+ * of the linear structure:
+ *	\[\rho = \min(\rho_{12};\rho_{13}) \]
+ * where \rho_{12} and \rho_{13} are the maximum response of the ratio edge 
+ * detector of \rho(\theta_{i}).
+ * 
+ * The exit is an image of intensity of detection.
+ *
+ * 
+ */
+
+template <class TInputImage, 
+	  class TOutputImage,
+	  class InterpolatorType = itk::BSplineInterpolateImageFunction<TInputImage> >
+class LineCorrelationDetector :  public itk::ImageToImageFilter< TInputImage, TOutputImage >
+{
+public:
+  /** 	Extract dimensions as well of the images of entry of exit. */
+  itkStaticConstMacro(		InputImageDimension,
+  				unsigned int,
+                      		TInputImage::ImageDimension);
+  itkStaticConstMacro(		OutputImageDimension, 
+  				unsigned int,
+                      		TOutputImage::ImageDimension);
+
+  typedef TInputImage InputImageType;
+  typedef TOutputImage OutputImageType;
+
+  /** typedef for the classes standards. */
+  typedef LineCorrelationDetector Self;
+  typedef itk::ImageToImageFilter< InputImageType, OutputImageType> Superclass;
+  typedef itk::SmartPointer<Self> Pointer;
+  typedef itk::SmartPointer<const Self>  ConstPointer;
+
+  /** Method for management of the "object factory". */
+  itkNewMacro(Self);
+
+  /** Return the nale of the class. */
+  itkTypeMacro(LineCorrelationDetector, ImageToImageFilter);
+
+  /** Typedefs to describe and access Interpolator */
+  typedef typename InterpolatorType::Pointer InterpolatorPointer;
+  typedef typename InterpolatorType::CoordRepType CoordRepType;
+  
+  typedef typename InputImageType::PointType TPoint;
+
+
+  /** Definition of the input and output images */
+  typedef typename InputImageType::PixelType InputPixelType;
+  typedef typename OutputImageType::PixelType OutputPixelType;
+
+  
+  typedef typename InputImageType::RegionType InputImageRegionType;
+  typedef typename OutputImageType::RegionType OutputImageRegionType;
+
+  /** Definition of the size of the images. */
+  typedef typename InputImageType::SizeType SizeType;
+  
+  /** Set the length of the linear feature. */
+  itkSetMacro(LengthLine, unsigned int);
+
+  /** Get the length of the linear feature. */
+  itkGetConstReferenceMacro(LengthLine, unsigned int);
+
+  /** Set the width of the linear feature. */
+  itkSetMacro(WidthLine, unsigned int);
+
+  /** Get the length of the linear feature. */
+  itkGetConstReferenceMacro(WidthLine, unsigned int);
+  
+  /** Set the radius of one zone. */
+  itkSetMacro(Radius, SizeType);
+
+  /** Get the radius of one zone. */
+  itkGetConstReferenceMacro(Radius, SizeType);
+ 
+
+  virtual void GenerateInputRequestedRegion() throw(itk::InvalidRequestedRegionError);
+
+protected:
+  LineCorrelationDetector();
+  virtual ~LineCorrelationDetector() {};
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+
+  /** LineCorrelationDetector can be implemented for a treatment of filter multithreaded. 
+   * Thus, the ThreadedGenerateData() method is called for each thread process. 
+   * The data image are allocated automatically by the mother class by calling the 
+   * ThreadedGenerateData() method. ThreadedGenerateData can only write the portion 
+   * of the image specified by the parameter "outputRegionForThread" 
+   *
+   * \sa ImageToImageFilter::ThreadedGenerateData(),
+   *     ImageToImageFilter::GenerateData() */
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            int threadId );
+
+private:
+  LineCorrelationDetector(const Self&); //purposely not implemented
+  void operator=(const Self&); //purposely not implemented
+ 
+  /** Length of the linear feature = 2*m_LengthLine+1 */ 
+  unsigned int m_LengthLine;
+ 
+  /** Width of the linear feature = 2*m_WidthLine+1 */ 
+  unsigned int m_WidthLine;
+     
+  /** Radius of the region*/
+  SizeType m_Radius;
+  
+  /** Size of the facelist*/
+  SizeType m_FaceList;
+  
+  InterpolatorPointer      m_Interpolator;
+
+};
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbLineCorrelationDetector.txx"
+#endif
+
+  
+#endif
diff --git a/Code/FeatureExtraction/otbLineCorrelationDetector.txx b/Code/FeatureExtraction/otbLineCorrelationDetector.txx
new file mode 100755
index 0000000000000000000000000000000000000000..a7cd1f10fcdb1b5f38f1c9b16f98452fd0513bec
--- /dev/null
+++ b/Code/FeatureExtraction/otbLineCorrelationDetector.txx
@@ -0,0 +1,367 @@
+/*=========================================================================
+
+  Programme :   OTB (ORFEO ToolBox)
+  Auteurs   :   CS - C.Ruffel
+  Language  :   C++
+  Date      :   14 mars 2006
+  Role      :   Filter of detection of linear features 
+  $Id$ 
+
+=========================================================================*/
+#ifndef __otbLineCorrelationDetector_txx
+#define __otbLineCorrelationDetector_txx
+
+#include "otbLineCorrelationDetector.h"
+
+#include "itkDataObject.h"
+#include "itkExceptionObject.h"
+#include "itkConstNeighborhoodIterator.h"
+#include "itkNeighborhoodInnerProduct.h"
+#include "itkImageRegionIterator.h"
+#include "itkNeighborhoodAlgorithm.h"
+#include "itkZeroFluxNeumannBoundaryCondition.h"
+#include "itkProgressReporter.h"
+#include <math.h>
+
+#define M_PI 3.14159265358979323846
+
+namespace otb
+{
+
+/**
+ *
+ */
+template <class TInputImage, class TOutputImage, class InterpolatorType >
+LineCorrelationDetector<TInputImage, TOutputImage, InterpolatorType>::LineCorrelationDetector()
+{
+  m_Radius.Fill(1);
+  m_LengthLine = 1;
+  m_WidthLine = 0;
+  m_FaceList.Fill(0);
+  m_Interpolator = InterpolatorType::New(); 
+}
+
+template <class TInputImage, class TOutputImage, class InterpolatorType>
+void LineCorrelationDetector<TInputImage, TOutputImage, InterpolatorType>::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();
+
+  // Define the size of the region by the radius
+  m_Radius[0] = static_cast<unsigned int>(3*m_WidthLine + 2); 
+  m_Radius[1] = m_LengthLine ;
+  
+  // Define the size of the facelist by taking into account the rotation of the region
+  m_FaceList[0] = static_cast<unsigned int>( sqrt((m_Radius[0]*m_Radius[0])+ (m_Radius[1]*m_Radius[1]))+1 );
+  m_FaceList[1] = m_FaceList[0];
+
+
+  // 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, class InterpolatorType>
+void LineCorrelationDetector< TInputImage, TOutputImage, InterpolatorType>
+::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();
+  
+  m_Interpolator->SetInputImage(input);
+   
+  // 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_FaceList);
+
+
+  // support progress methods/callbacks
+  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
+  
+  typename TInputImage::IndexType     bitIndex;
+  typename InterpolatorType::ContinuousIndexType Index;
+
+
+  // --------------------------------------------------------------------------
+  
+  // Number of direction
+  const int NB_DIR = 4;
+  // Number of zone	  
+  const int NB_ZONE = 3;  
+  // Definition of the 4 directions
+  double Theta[NB_DIR];
+  
+  Theta[0] = 0.;
+  Theta[1] = M_PI / 4. ;
+  Theta[2] = M_PI / 2. ;
+  Theta[3] = 3*M_PI / 4. ;
+
+  // Number of the zone 
+  unsigned int zone;
+  
+  // Pixel numbers in each zone
+  const int NbPixelZone = (2*m_WidthLine+1)*(2*m_LengthLine+1);
+  
+  double InvNbPixel = static_cast<double>(1. / NbPixelZone); 
+   
+  // Contains for the 4 directions the sum of the pixels belonging to each zone
+  double Sum[NB_DIR][NB_ZONE];
+  double Sum2[NB_DIR][NB_ZONE];
+  
+  // Mean of zone 1, 2 and 3
+  double M1, M2, M3;
+  
+  // Standard deviation
+  double sigma1, sigma2, sigma3;
+  
+  // Result of the filter for each direction
+  double rho12_theta[NB_DIR];
+  double rho13_theta[NB_DIR];
+  // Result in one direction
+  double rho12, rho13;
+  // Intensity of the linear feature
+  double rho;
+
+  // Pixel location in the input image
+  int X, Y;
+  // Value of the pixel
+  double ValXY = 0.;
+  
+  // Pixel location after rotation in the system axis of the region  
+  double xout, yout;
+  
+   // Pixel location in the input image after rotation
+  TPoint point;
+   
+  // location of the pixel central in the input image
+  int Xc, Yc;
+
+  // location of the pixel central between zone 1 and 2 and between zone 1 and 3
+  int Xc12, Xc13;
+  
+  //---------------------------------------------------------------------------
+ 
+  // 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() )
+      {
+//std::cout << "Xc,Yc " << bit.GetIndex() << std::endl;
+
+      // Initialisations
+      for (int dir=0; dir<NB_DIR; dir++)
+        {
+        for (int z=0; z<NB_ZONE; z++)
+          { 
+          Sum[dir][z] = 0.;
+          Sum2[dir][z] = 0.;
+          }
+        }
+        
+     
+      // Location of the central pixel of the region
+      bitIndex = bit.GetIndex();
+      
+      Xc = bitIndex[0];
+      Yc = bitIndex[1];
+      
+      // Location of the central pixel between zone 1 and zone 2
+      Xc12 = Xc - m_WidthLine - 1;
+      
+      // Location of the central pixel between zone 1 and zone 3
+      Xc13 = Xc + m_WidthLine + 1;
+          
+      // Loop on the region 
+      for (i = 0; i < neighborhoodSize; ++i)
+        {
+//std::cout << "---"<< i <<" "<< bit.GetIndex(i)<< std::endl;
+//std::cout << "val(X,Y) "<< static_cast<double>(bit.GetPixel(i)) << " " << std::endl;
+
+        bitIndex = bit.GetIndex(i);
+        X = bitIndex[0];
+        Y = bitIndex[1];
+
+      
+        // We determine in the vertical direction with which zone the pixel belongs. 
+         
+        if ( X < Xc12 )
+      	  zone = 1;
+        else if ( ( Xc12 < X ) && ( X < Xc13 ) )
+          zone = 0;
+        else if ( X < Xc13 )
+          zone = 2;
+    
+        ValXY = static_cast<double>(bit.GetPixel(i));
+        
+        Sum[0][zone] += ValXY;
+        Sum2[0][zone] += ValXY*ValXY;
+         
+        // Loop on the 3 other directions
+        for ( int dir=1; dir<NB_DIR; dir++ )
+          {      
+            ROTATION( (X-Xc), (Y-Yc), Theta[dir], xout, yout);
+            
+            Index[0] = static_cast<CoordRepType>(xout + Xc);
+            Index[1] = static_cast<CoordRepType>(yout + Yc);
+                        
+//std::cout << "X' Y' "<< (xout + Xc) << " " << (yout + Yc) << std::endl;
+//std::cout << "val(X',Y') "<< static_cast<double>(m_Interpolator->EvaluateAtContinuousIndex( Index )) << std::endl;
+           
+            ValXY = static_cast<double>(m_Interpolator->EvaluateAtContinuousIndex( Index ));
+             
+            Sum[dir][zone] += ValXY;
+            Sum2[dir][zone] += ValXY*ValXY;
+          
+          }      
+
+        } // end of the loop on the pixels of the region 
+        
+      rho12 = -1.;
+      rho13 = -1.; 
+      
+      double NbPixel = static_cast<double>(NbPixelZone);          
+           
+      // Loop on the 4 directions
+      for ( int dir=0; dir<NB_DIR; dir++ )
+        {
+        		
+        // Calculation of the mean for the 3 zones	
+        M1 = Sum[dir][0] * InvNbPixel;
+        M2 = Sum[dir][1] * InvNbPixel;
+        M3 = Sum[dir][2] * InvNbPixel;
+        
+        // Calculation of the standard deviation for the 3 zones 
+	sigma1 = sqrt( (Sum2[dir][0] - NbPixel*M1*M1) * InvNbPixel );
+	sigma2 = sqrt( (Sum2[dir][1] - NbPixel*M2*M2) * InvNbPixel );
+	sigma3 = sqrt( (Sum2[dir][2] - NbPixel*M3*M3) * InvNbPixel ); 
+     	
+        // Calculation of the cross correlation coefficient
+        
+        double d1 = 0.;
+        double d2 = 0.;
+        double d3 = 0.;
+        
+        // rho12
+        if ( M2 != 0. )
+          d1 = NbPixel*pow(sigma1,2)*pow(M1/M2,2);
+        d2 = NbPixel*pow(sigma2,2);
+        if ( M2 != 0. )
+          d3 = NbPixel*NbPixel*pow(((M1/M2)-1.),2);
+        
+        if ( ( M1 != M2 ) )
+          rho12_theta[dir] = static_cast<double>( 1. / ( 1. + ( 2.*NbPixel*(d1+d2)/d3 ) ) );
+        else
+          rho12_theta[dir] = 0.;
+	 
+	// rho13 
+	if ( M3 != 0. )
+	  d1 = NbPixel*pow(sigma1,2)*pow(M1/M3,2);
+        d2 = NbPixel*pow(sigma3,2);
+        if ( M3 != 0. )
+          d3 = NbPixel*NbPixel*pow(((M1/M3)-1.),2);
+      
+        if ( ( M1 != M3 ) )
+          rho13_theta[dir] = static_cast<double>( 1. / ( 1. + ( 2.*NbPixel*(d1+d2)/d3 ) ) );
+        else
+          rho13_theta[dir] = 0.;
+        
+         
+	// Determination of the maximum cross correlation coefficients
+	rho12 = static_cast<double>( MAX( rho12, rho12_theta[dir] ) );
+        rho13 = static_cast<double>( MAX( rho13, rho13_theta[dir] ) );  
+      		
+        } // end of the loop on the directions
+      
+      // Intensity of the linear feature
+      rho = MIN ( rho12, rho13 );	
+
+      // Assignment of this value to the output pixel
+      it.Set( static_cast<OutputPixelType>(rho) );  
+
+      ++bit;
+      ++it;
+      progress.CompletedPixel();  
+      
+      }
+      
+    }
+}
+
+/**
+ * Standard "PrintSelf" method
+ */
+template <class TInputImage, class TOutput, class InterpolatorType>
+void 
+LineCorrelationDetector<TInputImage, TOutput, InterpolatorType>::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf( os, indent );
+  os << indent << "Radius: " << m_Radius << std::endl;
+}
+
+
+} // end namespace otb
+
+
+#endif