diff --git a/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.h b/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.h
index 01f2f7867865a452ee830c52266818512f035686..5ea92e62be6f08362fb976ed713ecf12293ea505 100644
--- a/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.h
+++ b/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.h
@@ -18,8 +18,9 @@
 #ifndef __otbScalarImageToPanTexTextureFilter_h
 #define __otbScalarImageToPanTexTextureFilter_h
 
+#include "otbGreyLevelCooccurrenceIndexedList.h"
 #include "itkImageToImageFilter.h"
-#include "itkScalarImageToCooccurrenceMatrixFilter.h"
+#include "itkHistogram.h"
 
 namespace otb
 {
@@ -66,19 +67,35 @@ public:
   typedef typename InputImageType::PixelType   InputPixelType;
   typedef typename InputImageType::RegionType  InputRegionType;
   typedef typename InputRegionType::SizeType   SizeType;
+  typedef typename InputImageType::OffsetType   OffsetType;
   typedef TOutputImage                         OutputImageType;
   typedef typename OutputImageType::Pointer    OutputImagePointerType;
   typedef typename OutputImageType::RegionType OutputRegionType;
 
-  /** Co-occurence matrix and textures calculator */
-  typedef itk::Statistics::ScalarImageToCooccurrenceMatrixFilter<InputImageType> CoocurrenceMatrixGeneratorType;
-  typedef typename CoocurrenceMatrixGeneratorType::Pointer       CoocurrenceMatrixGeneratorPointerType;
-  typedef typename CoocurrenceMatrixGeneratorType::OffsetType    OffsetType;
+  typedef typename itk::NumericTraits< InputPixelType >::RealType MeasurementType;
+  typedef itk::Statistics::DenseFrequencyContainer2 THistogramFrequencyContainer;
+  typedef itk::Statistics::Histogram< MeasurementType, THistogramFrequencyContainer > HistogramType;
+  typedef typename HistogramType::Pointer                            HistogramPointer;
+  typedef typename HistogramType::ConstPointer                       HistogramConstPointer;
+  typedef typename HistogramType::MeasurementVectorType              MeasurementVectorType;
+  typedef typename HistogramType::RelativeFrequencyType              RelativeFrequencyType;
+  typedef typename HistogramType::TotalAbsoluteFrequencyType         TotalAbsoluteFrequencyType;
+  typedef typename HistogramType::SizeType                           HistogramSizeType;
+  typedef typename HistogramType::IndexType                          CooccurrenceIndexType;
+
+  typedef GreyLevelCooccurrenceIndexedList< HistogramType >   CooccurrenceIndexedListType;
+  typedef typename CooccurrenceIndexedListType::Pointer       CooccurrenceIndexedListPointerType;
+  typedef typename CooccurrenceIndexedListType::ConstPointer  CooccurrenceIndexedListConstPointerType;
+
+  typedef typename CooccurrenceIndexedListType::VectorType VectorType;
+  typedef typename VectorType::iterator                    VectorIteratorType;
+  typedef typename VectorType::const_iterator              VectorConstIteratorType;
+
   typedef typename std::vector<OffsetType>                       OffsetListType;
-  typedef typename CoocurrenceMatrixGeneratorType::HistogramType HistogramType;
-  typedef typename HistogramType::AbsoluteFrequencyType                  FrequencyType; //FIXME stat framework
-  typedef typename HistogramType::MeasurementType                MeasurementType;
-  typedef typename HistogramType::Iterator                       HistogramIterator;
+
+  void SetBinsAndMinMax(unsigned int bins, InputPixelType min, InputPixelType max);
+
+  itkStaticConstMacro(MeasurementVectorSize, int, 2 );
 
   /** Set the radius of the window on which textures will be computed */
   itkSetMacro(Radius, SizeType);
@@ -134,6 +151,12 @@ private:
 
   /** Input image maximum */
   InputPixelType m_InputImageMaximum;
+
+  /** Histogram instance used to get index for the pixel pair */
+  HistogramPointer m_Histogram;
+
+  HistogramSizeType m_HistSize;
+
 };
 } // End namespace otb
 
diff --git a/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.txx b/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.txx
index da5e6856e9506a0732456300ad221b559ab4692d..b3515e841e2ce86e4e905335e7c236128038425d 100644
--- a/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.txx
+++ b/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.txx
@@ -20,8 +20,10 @@
 
 #include "otbScalarImageToPanTexTextureFilter.h"
 #include "itkImageRegionIteratorWithIndex.h"
+#include "itkConstNeighborhoodIterator.h"
 #include "itkImageRegionIterator.h"
 #include "itkProgressReporter.h"
+#include "itkNumericTraits.h"
 
 namespace otb
 {
@@ -29,8 +31,9 @@ template <class TInputImage, class TOutputImage>
 ScalarImageToPanTexTextureFilter<TInputImage, TOutputImage>
 ::ScalarImageToPanTexTextureFilter() : m_Radius(),
   m_NumberOfBinsPerAxis(8),
+  m_HistSize(2),
   m_InputImageMinimum(0),
-  m_InputImageMaximum(256)
+  m_InputImageMaximum(255)
 {
   // There are 1 output corresponding to the Pan Tex texture indice
   this->SetNumberOfRequiredOutputs(1);
@@ -67,6 +70,29 @@ ScalarImageToPanTexTextureFilter<TInputImage, TOutputImage>
 ::~ScalarImageToPanTexTextureFilter()
 {}
 
+template <class TInputImage, class TOutputImage>
+void
+ScalarImageToPanTexTextureFilter<TInputImage, TOutputImage>
+::SetBinsAndMinMax(unsigned int numberOfBinsPerAxis,
+                   InputPixelType inputImageMinimum,
+                   InputPixelType inputImageMaximum)
+{
+  /** Initalize m_Histogram with given min, max and number of bins  **/
+  MeasurementVectorType lowerBound;
+  MeasurementVectorType upperBound;
+  m_InputImageMinimum = inputImageMinimum;
+  m_InputImageMaximum = inputImageMaximum;
+  m_NumberOfBinsPerAxis = numberOfBinsPerAxis;
+  m_Histogram = HistogramType::New();
+  m_Histogram->SetMeasurementVectorSize( MeasurementVectorSize );
+  lowerBound.SetSize( MeasurementVectorSize );
+  upperBound.SetSize( MeasurementVectorSize );
+  lowerBound.Fill(m_InputImageMinimum);
+  upperBound.Fill(m_InputImageMaximum+1);
+  m_HistSize.Fill(m_NumberOfBinsPerAxis);
+  m_Histogram->Initialize(m_HistSize, lowerBound, upperBound);
+}
+
 template <class TInputImage, class TOutputImage>
 void
 ScalarImageToPanTexTextureFilter<TInputImage, TOutputImage>
@@ -144,86 +170,90 @@ ScalarImageToPanTexTextureFilter<TInputImage, TOutputImage>
       OffsetType currentOffset = *offIt;
 
       // Compute the region on which co-occurence will be estimated
-      typename InputRegionType::IndexType inputIndex, inputIndexWithTwiceOffset;
-      typename InputRegionType::SizeType inputSize, inputSizeWithTwiceOffset;
+      typename InputRegionType::IndexType inputIndex;
+      typename InputRegionType::SizeType inputSize;
 
-      // First, apply offset
+      // First, create an window for neighborhood iterator based on m_Radius
+      // For example, if xradius and yradius is 2. window size is 5x5 (2 *
+      // radius + 1).
       for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
         {
-        inputIndex[dim] = std::min(
-                                  static_cast<int>(outputIt.GetIndex()[dim] - m_Radius[dim]),
-                                  static_cast<int>(outputIt.GetIndex()[dim] - m_Radius[dim] + currentOffset[dim])
-                                  );
-        inputSize[dim] = 2 * m_Radius[dim] + 1 + std::abs(currentOffset[dim]);
-
-        inputIndexWithTwiceOffset[dim] = static_cast<int>(outputIt.GetIndex()[dim] - m_Radius[dim] - std::abs(currentOffset[dim]));
-        inputSizeWithTwiceOffset[dim] = inputSize[dim] + std::abs(currentOffset[dim]);
+        inputIndex[dim] = outputIt.GetIndex()[dim] - m_Radius[dim];
+        inputSize[dim] = 2 * m_Radius[dim] + 1;
         }
-
       // Build the input  region
       InputRegionType inputRegion;
       inputRegion.SetIndex(inputIndex);
       inputRegion.SetSize(inputSize);
       inputRegion.Crop(inputPtr->GetRequestedRegion());
 
-      InputRegionType inputRegionWithTwiceOffset;
-      inputRegionWithTwiceOffset.SetIndex(inputIndexWithTwiceOffset);
-      inputRegionWithTwiceOffset.SetSize(inputSizeWithTwiceOffset);
-      inputRegionWithTwiceOffset.Crop(inputPtr->GetRequestedRegion());
-
-      /*********************************************************************************/
-      //Local copy of the input image around the processed pixel *outputIt
-      InputImagePointerType localInputImage = InputImageType::New();
-      localInputImage->SetRegions(inputRegionWithTwiceOffset);
-      localInputImage->Allocate();
-      typedef itk::ImageRegionIteratorWithIndex<InputImageType> ImageRegionIteratorType;
-      ImageRegionIteratorType itInputPtr(inputPtr, inputRegionWithTwiceOffset);
-      ImageRegionIteratorType itLocalInputImage(localInputImage, inputRegionWithTwiceOffset);
-      for (itInputPtr.GoToBegin(), itLocalInputImage.GoToBegin(); !itInputPtr.IsAtEnd(); ++itInputPtr, ++itLocalInputImage)
+      CooccurrenceIndexedListPointerType m_GLCIList = CooccurrenceIndexedListType::New();
+      m_GLCIList->Initialize(m_HistSize);
+
+      SizeType neighborhoodRadius;
+      /** calulate minimum offset and set it as neigborhood radius **/
+      unsigned int minRadius = 0;
+      for ( unsigned int i = 0; i < currentOffset.GetOffsetDimension(); i++ )
         {
-        itLocalInputImage.Set(itInputPtr.Get());
+        unsigned int distance = vcl_abs(currentOffset[i]);
+        if ( distance > minRadius )
+          {
+          minRadius = distance;
+          }
         }
-      /*********************************************************************************/
-
-      InputImagePointerType maskImage = InputImageType::New();
-      maskImage->SetRegions(inputRegionWithTwiceOffset);
-      maskImage->Allocate();
-      maskImage->FillBuffer(0);
+      neighborhoodRadius.Fill(minRadius);
 
-      ImageRegionIteratorType itMask(maskImage, inputRegion);
-      for (itMask.GoToBegin(); !itMask.IsAtEnd(); ++itMask)
+      typedef itk::ConstNeighborhoodIterator< InputImageType > NeighborhoodIteratorType;
+      NeighborhoodIteratorType neighborIt;
+      neighborIt = NeighborhoodIteratorType(neighborhoodRadius, inputPtr, inputRegion);
+      for ( neighborIt.GoToBegin(); !neighborIt.IsAtEnd(); ++neighborIt )
         {
-        itMask.Set(1);
-        }
+        const InputPixelType centerPixelIntensity = neighborIt.GetCenterPixel();
+        if ( centerPixelIntensity < m_InputImageMinimum
+             || centerPixelIntensity > m_InputImageMaximum )
+          {
+          continue; // don't put a pixel in the histogram if the value
+          // is out-of-bounds.
+          }
 
+        bool            pixelInBounds;
+        const InputPixelType pixelIntensity =
+          neighborIt.GetPixel(currentOffset, pixelInBounds);
 
-      // Build the co-occurence matrix generator
-      CoocurrenceMatrixGeneratorPointerType coOccurenceMatrixGenerator = CoocurrenceMatrixGeneratorType::New();
-      coOccurenceMatrixGenerator->SetInput(localInputImage);
-      coOccurenceMatrixGenerator->SetOffset(currentOffset);
-      coOccurenceMatrixGenerator->SetNumberOfBinsPerAxis(m_NumberOfBinsPerAxis);
-      coOccurenceMatrixGenerator->SetPixelValueMinMax(m_InputImageMinimum, m_InputImageMaximum);
+        if ( !pixelInBounds )
+          {
+          continue; // don't put a pixel in the histogram if it's out-of-bounds.
+          }
 
-      // Compute the co-occurence matrix
-      coOccurenceMatrixGenerator->SetMaskImage(maskImage);
-      coOccurenceMatrixGenerator->SetInsidePixelValue(1);
-      coOccurenceMatrixGenerator->Update();
+        if ( pixelIntensity < m_InputImageMinimum
+             || pixelIntensity > m_InputImageMaximum )
+          {
+          continue; // don't put a pixel in the histogram if the value
+          // is out-of-bounds.
+          }
+
+        CooccurrenceIndexType instanceIndex;
+        MeasurementVectorType measurement( MeasurementVectorSize );
+        measurement[0] = centerPixelIntensity;
+        measurement[1] = pixelIntensity;
+        //Get Index of the histogram for the given pixel pair;
+        m_Histogram->GetIndex(measurement, instanceIndex);
+        m_GLCIList->AddPairToList(instanceIndex);
+        }
 
-      typename HistogramType::ConstPointer histo = coOccurenceMatrixGenerator->GetOutput();
+      m_GLCIList->Normalize();
+      VectorConstIteratorType constVectorIt;
+      VectorType glcList = m_GLCIList->GetVector();
 
+      //Compute inertia aka contrast
       double inertia = 0;
-      typename HistogramType::TotalAbsoluteFrequencyType  totalFrequency = histo->GetTotalFrequency();
-      typename HistogramType::ConstIterator itr = histo->Begin();
-      typename HistogramType::ConstIterator end = histo->End();
-      for(; itr != end; ++itr )
+      constVectorIt = glcList.begin();
+      while( constVectorIt != glcList.end())
         {
-        MeasurementType frequency = itr.GetFrequency();
-        if (frequency == 0)
-          {
-          continue; // no use doing these calculations if we're just multiplying by zero.
-          }
-        typename HistogramType::IndexType index = histo->GetIndex(itr.GetInstanceIdentifier());
-        inertia += (index[0] - index[1]) * (index[0] - index[1]) * frequency / totalFrequency;
+        CooccurrenceIndexType index = (*constVectorIt).index;
+        RelativeFrequencyType frequency = (*constVectorIt).frequency;
+        inertia += ( index[0] - index[1] ) * ( index[0] - index[1] ) * frequency;
+        ++constVectorIt;
         }
 
       if (inertia < out)
diff --git a/Testing/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.cxx b/Testing/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.cxx
index 1535a2a2ac221b8f2d58ecb6a3f76de974ed48c6..2f5460b3a539d957fd5add9328050e9c58afa606 100644
--- a/Testing/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.cxx
+++ b/Testing/Code/FeatureExtraction/otbScalarImageToPanTexTextureFilter.cxx
@@ -55,13 +55,11 @@ int otbScalarImageToPanTexTextureFilter(int argc, char * argv[])
   sradius.Fill(radius);
 
   filter->SetInput(reader->GetOutput());
-  filter->SetNumberOfBinsPerAxis(nbBins);
   filter->SetRadius(sradius);
 
   otb::StandardFilterWatcher watcher(filter, "Textures filter");
 
-  filter->SetInputImageMinimum(0);
-  filter->SetInputImageMaximum(255);
+  filter->SetBinsAndMinMax(nbBins, 0, 255);
 
   // Write outputs
   std::ostringstream oss;