diff --git a/Code/OBIA/otbKMeansAttributesLabelMapFilter.h b/Code/OBIA/otbKMeansAttributesLabelMapFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ea57c5a6283e46de97e4d4d75238738d25c9512
--- /dev/null
+++ b/Code/OBIA/otbKMeansAttributesLabelMapFilter.h
@@ -0,0 +1,151 @@
+/*=========================================================================
+
+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 __otbKMeansAttributesLabelMapFilter_h
+#define __otbKMeansAttributesLabelMapFilter_h
+
+#include "itkLabelMapFilter.h"
+#include "itkSimpleDataObjectDecorator.h"
+#include "otbLabelMapWithClassLabelToLabeledSampleListFilter.h"
+#include "itkListSample.h"
+#include "itkEuclideanDistance.h"
+#include "itkWeightedCentroidKdTreeGenerator.h"
+#include "itkKdTreeBasedKmeansEstimator.h"
+
+namespace otb {
+
+/** \class KMeansAttributesLabelMapFilter
+ * \brief Execute a KMeans on the attributes of a itk::LabelMap<otb::AttributesMapLabelObject>
+ */
+template<class TInputImage>
+class ITK_EXPORT KMeansAttributesLabelMapFilter :
+    public itk::Object
+{
+public:
+  /** Standard class typedefs. */
+  typedef KMeansAttributesLabelMapFilter                Self;
+  typedef itk::LabelMapFilter<TInputImage, TInputImage> Superclass;
+  typedef itk::SmartPointer<Self>                       Pointer;
+  typedef itk::SmartPointer<const Self>                 ConstPointer;
+
+  /** Some convenient typedefs. */
+  typedef TInputImage                              InputImageType;
+  typedef typename InputImageType::Pointer         InputImagePointer;
+  typedef typename InputImageType::ConstPointer    InputImageConstPointer;
+  typedef typename InputImageType::RegionType      InputImageRegionType;
+  typedef typename InputImageType::PixelType       InputImagePixelType;
+  typedef typename InputImageType::LabelObjectType LabelObjectType;
+  typedef itk::DataObject                          DataObjectType;
+  typedef DataObjectType::Pointer                  DataObjectPointerType;
+
+  // LabelObject attributes
+  typedef typename LabelObjectType::AttributesValueType     AttributesValueType;
+  typedef typename LabelObjectType::AttributesMapType       AttributesMapType;
+  typedef itk::SimpleDataObjectDecorator<AttributesMapType> AttributesMapObjectType;
+  typedef typename InputImageType::LabelObjectContainerType LabelObjectContainerType;
+  typedef typename LabelObjectContainerType::const_iterator LabelObjectContainerConstIterator;
+  typedef typename LabelObjectType::ClassLabelType          ClassLabelType;
+
+  // LabelMapToSampleList
+  typedef itk::VariableLengthVector<AttributesValueType>    VectorType;
+  typedef itk::FixedArray<ClassLabelType,1>                 ClassLabelVectorType;
+
+  typedef itk::Statistics::ListSample<VectorType>           ListSampleType;
+  typedef itk::Statistics::ListSample<ClassLabelVectorType> TrainingListSampleType;
+  typedef otb::LabelMapWithClassLabelToLabeledSampleListFilter<
+            InputImageType,
+            ListSampleType,
+            TrainingListSampleType>                         LabelMapToSampleListFilterType;
+  typedef typename LabelMapToSampleListFilterType::MeasurementFunctorType MeasurementFunctorType;
+
+  // KMeans
+  typedef itk::Statistics::WeightedCentroidKdTreeGenerator<ListSampleType>         TreeGeneratorType;
+  typedef typename TreeGeneratorType::KdTreeType                                   TreeType;
+  typedef itk::Statistics::KdTreeBasedKmeansEstimator<TreeType>                    EstimatorType;
+  typedef itk::Statistics::EuclideanDistance<VectorType>                           DistanceType;
+  typedef std::vector<VectorType>                                                  CentroidsVectorType;
+  typedef itk::SimpleDataObjectDecorator<CentroidsVectorType>                      CentroidsVectorObjectType;
+
+  /** ImageDimension constants */
+  itkStaticConstMacro(InputImageDimension, unsigned int,
+                      TInputImage::ImageDimension);
+
+  /** Standard New method. */
+  itkNewMacro(Self);  
+
+  /** Runtime information support. */
+  itkTypeMacro(KMeansAttributesLabelMapFilter,
+               LabelMapFilter);
+
+  /** Return the centroids resulting from the KMeans */
+  CentroidsVectorType& GetCentroids()
+  {
+    return m_Centroids;
+  }
+  const CentroidsVectorType& GetCentroids() const
+  {
+    return m_Centroids;
+  }
+
+  itkSetObjectMacro(InputLabelMap,InputImageType);
+  itkGetObjectMacro(InputLabelMap,InputImageType);
+
+  /** Set the number of classes of the input sample list.
+   *  It will be used to choose the number of centroids.
+   *  In the one-class case, 10 centroids is chosen. Otherwise,
+   *  a number of centroids equal to the number of classes */
+  itkSetMacro(NumberOfClasses, unsigned int);
+  itkGetMacro(NumberOfClasses, unsigned int);
+
+  MeasurementFunctorType& GetMeasurementFunctor()
+  {
+    return m_LabelMapToSampleListFilter->GetMeasurementFunctor();
+  }
+
+  void SetMeasurementFunctor(MeasurementFunctorType& functor)
+  {
+    m_LabelMapToSampleListFilter->SetMeasurementFunctor(functor);
+  }
+
+  void Compute();
+
+protected:
+  KMeansAttributesLabelMapFilter();
+  ~KMeansAttributesLabelMapFilter() {};
+
+
+private:
+  KMeansAttributesLabelMapFilter(const Self&); //purposely not implemented
+  void operator=(const Self&); //purposely not implemented
+
+  InputImagePointer m_InputLabelMap;
+  CentroidsVectorType m_Centroids;
+
+  typename LabelMapToSampleListFilterType::Pointer m_LabelMapToSampleListFilter;
+  unsigned int m_NumberOfClasses;
+
+}; // end of class
+
+} // end namespace otb
+  
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbKMeansAttributesLabelMapFilter.txx"
+#endif
+
+#endif
+
+
diff --git a/Code/OBIA/otbKMeansAttributesLabelMapFilter.txx b/Code/OBIA/otbKMeansAttributesLabelMapFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..b94b82dc5c6a466da8a9144079bd0d401be5e60a
--- /dev/null
+++ b/Code/OBIA/otbKMeansAttributesLabelMapFilter.txx
@@ -0,0 +1,126 @@
+/*=========================================================================
+
+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 __otbKMeansAttributesLabelMapFilter_txx
+#define __otbKMeansAttributesLabelMapFilter_txx
+
+#include "otbKMeansAttributesLabelMapFilter.h"
+#include "itkNumericTraits.h"
+#include "itkMersenneTwisterRandomVariateGenerator.h"
+
+namespace otb {
+
+template <class TInputImage>
+KMeansAttributesLabelMapFilter<TInputImage>
+::KMeansAttributesLabelMapFilter()
+ : m_LabelMapToSampleListFilter(LabelMapToSampleListFilterType::New()),
+   m_NumberOfClasses(1)
+{
+}
+
+template<class TInputImage>
+void
+KMeansAttributesLabelMapFilter<TInputImage>
+::Compute()
+{
+  m_LabelMapToSampleListFilter->SetInputLabelMap(m_InputLabelMap);
+  m_LabelMapToSampleListFilter->Update();
+
+  typename ListSampleType::Pointer listSamples = m_LabelMapToSampleListFilter->GetOutputSampleList();
+  typename TrainingListSampleType::Pointer trainingSamples = m_LabelMapToSampleListFilter->GetOutputTrainingSampleList();
+
+  // Build the Kd Tree
+  typename TreeGeneratorType::Pointer kdTreeGenerator = TreeGeneratorType::New();
+  kdTreeGenerator->SetSample(listSamples);
+  kdTreeGenerator->SetBucketSize(100);
+  kdTreeGenerator->Update();
+  // Randomly pick the initial means among the classes
+  unsigned int sampleSize = listSamples->GetMeasurementVector(0).Size();
+  const unsigned int OneClassNbCentroids = 10;
+  unsigned int numberOfCentroids = (m_NumberOfClasses == 1 ? OneClassNbCentroids : m_NumberOfClasses);
+  typename EstimatorType::ParametersType initialMeans(sampleSize * m_NumberOfClasses);
+  initialMeans.Fill(0.);
+
+  if (m_NumberOfClasses > 1)
+    {
+    // For each class, choose a centroid as the first sample of this class encountered
+    for (ClassLabelType classLabel = 0; classLabel < m_NumberOfClasses; ++classLabel)
+      {
+      typename TrainingListSampleType::ConstIterator it;
+      // Iterate on the label list and stop when classLabel is found
+      // TODO: add random initialization ?
+      for (it = trainingSamples->Begin(); it != trainingSamples->End(); ++it)
+        {
+        if (it.GetMeasurementVector()[0] == classLabel)
+          break;
+        }
+      if (it == trainingSamples->End())
+        {
+        itkExceptionMacro(<<"Unable to find a sample with class label "<< classLabel);
+        }
+
+      typename ListSampleType::InstanceIdentifier identifier = it.GetInstanceIdentifier();
+      const typename ListSampleType::MeasurementVectorType& centroid = listSamples->GetMeasurementVector(identifier);
+      for (unsigned int i = 0; i < centroid.Size(); ++i)
+        {
+        initialMeans[classLabel * sampleSize + i] = centroid[i];
+        }
+      }
+    }
+  else
+    {
+    typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType;
+    RandomGeneratorType::Pointer randomGenerator = RandomGeneratorType::New();
+    unsigned int nbLabelObjects = listSamples->Size();
+
+    // Choose arbitrarily OneClassNbCentroids centroids among all available LabelObject
+    for (unsigned int centroidId = 0; centroidId < numberOfCentroids; ++centroidId)
+      {
+      typename ListSampleType::InstanceIdentifier identifier = randomGenerator->GetIntegerVariate(nbLabelObjects - 1);
+      const typename ListSampleType::MeasurementVectorType& centroid = listSamples->GetMeasurementVector(identifier);
+      for (unsigned int i = 0; i < centroid.Size(); ++i)
+        {
+        initialMeans[centroidId * sampleSize + i] = centroid[i];
+        }
+      }
+    }
+
+  // Run the KMeans algorithm
+  // Do KMeans estimation
+  typename EstimatorType::Pointer estimator = EstimatorType::New();
+  estimator->SetParameters(initialMeans);
+  estimator->SetKdTree(kdTreeGenerator->GetOutput());
+  estimator->SetMaximumIteration(10000);
+  estimator->SetCentroidPositionChangesThreshold(0.00001);
+  estimator->StartOptimization();
+
+  // Retrieve final centroids
+  m_Centroids.clear();
+
+  for(unsigned int cId = 0; cId < numberOfCentroids; ++cId)
+    {
+    VectorType newCenter(sampleSize);
+    for(unsigned int i = 0; i < sampleSize; ++i)
+      {
+      newCenter[i] = estimator->GetParameters()[cId * sampleSize + i];
+      }
+    m_Centroids.push_back(newCenter);
+    }
+}
+
+}// end namespace otb
+#endif
diff --git a/Code/OBIA/otbLabelMapToSampleListFilter.h b/Code/OBIA/otbLabelMapToSampleListFilter.h
index 3853b2856c25808e362f1bccc3ee264395a797dd..b423210f566c27e1706bf282f79a1c0eb661b67b 100644
--- a/Code/OBIA/otbLabelMapToSampleListFilter.h
+++ b/Code/OBIA/otbLabelMapToSampleListFilter.h
@@ -127,7 +127,7 @@ public:
   typedef TMeasurementFunctor                         MeasurementFunctorType;
 
   /** Set/Get the input label map  */
-  itkSetObjectMacro(InputLabelMap,InputLabelMapType);
+  itkSetConstObjectMacro(InputLabelMap,InputLabelMapType);
   itkGetConstObjectMacro(InputLabelMap,InputLabelMapType);
   itkGetObjectMacro(OutputSampleList,OutputSampleListType);
 
diff --git a/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.h b/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.h
index 406ec741f143d11673283f06cee478207a49d320..a8f3c4303daa7116262f1e18eb9272bc8b574d7d 100644
--- a/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.h
+++ b/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.h
@@ -61,16 +61,16 @@ public:
   ::MeasurementVectorType                             MeasurementVectorType;
   
   /** Output training sample list */
-  typedef TOutputTrainingSampleList                   OutputTrainingSampleListType;
+  typedef TOutputTrainingSampleList                      OutputTrainingSampleListType;
   typedef typename OutputTrainingSampleListType::Pointer OutputTrainingSampleListPointerType;
   typedef typename OutputTrainingSampleListType
-  ::MeasurementVectorType                             TraningVectorType;
+  ::MeasurementVectorType                                TraningVectorType;
 
   /** Measurement functor */
   typedef TMeasurementFunctor                         MeasurementFunctorType;
 
   /** Set/Get the input label map  */
-  itkSetObjectMacro(InputLabelMap,InputLabelMapType);
+  itkSetConstObjectMacro(InputLabelMap,InputLabelMapType);
   itkGetConstObjectMacro(InputLabelMap,InputLabelMapType);
   itkGetObjectMacro(OutputSampleList,OutputSampleListType);
   itkGetObjectMacro(OutputTrainingSampleList,OutputTrainingSampleListType);
diff --git a/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.txx b/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.txx
index 5adb3a3d3eae82ce71d913d508da65cd639f87f7..e69fbc7bebee6b0678a84cac74c888d0fb988ece 100644
--- a/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.txx
+++ b/Code/OBIA/otbLabelMapWithClassLabelToLabeledSampleListFilter.txx
@@ -55,7 +55,6 @@ LabelMapWithClassLabelToLabeledSampleListFilter<TInputLabelMap,TOutputListSample
     if(it->second->HasClassLabel())
       {
       label[0]=static_cast<typename TraningVectorType::ValueType>(it->second->GetClassLabel());
-
       }
     else
       {
diff --git a/Code/OBIA/otbMinMaxAttributesLabelMapFilter.h b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.h
index 5c80093cc64db25362cbe8dcd79bb9f41f18c99f..59cca650ae8822c74f9e1f139b682d2d763fc2df 100644
--- a/Code/OBIA/otbMinMaxAttributesLabelMapFilter.h
+++ b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.h
@@ -26,42 +26,35 @@ namespace otb {
 /** \class MinMaxAttributesLabelMapFilter
  * \brief Computes the min/max of all attributes of a itk::LabelMap<otb::AttributesMapLabelObject>
  */
-template<class TInputImage, class TOutputImage>
+template<class TInputImage>
 class ITK_EXPORT MinMaxAttributesLabelMapFilter :
-    public itk::LabelMapFilter<TInputImage, TOutputImage>
+    public itk::LabelMapFilter<TInputImage,TInputImage>
 {
 public:
   /** Standard class typedefs. */
-  typedef MinMaxAttributesLabelMapFilter Self;
-  typedef itk::LabelMapFilter<TInputImage, TOutputImage>
-  Superclass;
-  typedef itk::SmartPointer<Self>        Pointer;
-  typedef itk::SmartPointer<const Self>  ConstPointer;
+  typedef MinMaxAttributesLabelMapFilter               Self;
+  typedef itk::LabelMapFilter<TInputImage,TInputImage> Superclass;
+  typedef itk::SmartPointer<Self>                      Pointer;
+  typedef itk::SmartPointer<const Self>                ConstPointer;
 
   /** Some convenient typedefs. */
   typedef TInputImage InputImageType;
-  typedef TOutputImage OutputImageType;
-  typedef typename InputImageType::Pointer         InputImagePointer;
-  typedef typename InputImageType::ConstPointer    InputImageConstPointer;
-  typedef typename InputImageType::RegionType      InputImageRegionType;
-  typedef typename InputImageType::PixelType       InputImagePixelType;
-  typedef typename InputImageType::LabelObjectType LabelObjectType;
-  
-  typedef typename OutputImageType::Pointer        OutputImagePointer;
-  typedef typename OutputImageType::ConstPointer   OutputImageConstPointer;
-  typedef typename OutputImageType::RegionType     OutputImageRegionType;
-  typedef typename OutputImageType::PixelType      OutputImagePixelType;
-  typedef typename OutputImageType::IndexType      IndexType;
+  typedef typename InputImageType::Pointer             InputImagePointer;
+  typedef typename InputImageType::ConstPointer        InputImageConstPointer;
+  typedef typename InputImageType::RegionType          InputImageRegionType;
+  typedef typename InputImageType::PixelType           InputImagePixelType;
+  typedef typename InputImageType::LabelObjectType     LabelObjectType;
   
   typedef typename LabelObjectType::AttributesValueType     AttributesValueType;
   typedef typename LabelObjectType::AttributesMapType       AttributesMapType;
   typedef itk::SimpleDataObjectDecorator<AttributesMapType> AttributesMapObjectType;
 
+  typedef itk::DataObject         DataObjectType;
+  typedef DataObjectType::Pointer DataObjectPointerType;
+
   /** ImageDimension constants */
   itkStaticConstMacro(InputImageDimension, unsigned int,
                       TInputImage::ImageDimension);
-  itkStaticConstMacro(OutputImageDimension, unsigned int,
-                      TOutputImage::ImageDimension);
 
   /** Standard New method. */
   itkNewMacro(Self);  
@@ -87,6 +80,7 @@ public:
   AttributesMapObjectType* GetMaximumOutput();
   const AttributesMapObjectType* GetMaximumOutput() const;
 
+  virtual DataObjectPointerType MakeOutput(unsigned int idx);
 
 protected:
   MinMaxAttributesLabelMapFilter();
diff --git a/Code/OBIA/otbMinMaxAttributesLabelMapFilter.txx b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.txx
index f992ebd520fdf72c5fedf4bb67084559b59458ba..55bd1205287e97f0836c8b741de17a4593b3f4e3 100644
--- a/Code/OBIA/otbMinMaxAttributesLabelMapFilter.txx
+++ b/Code/OBIA/otbMinMaxAttributesLabelMapFilter.txx
@@ -23,52 +23,70 @@ PURPOSE.  See the above copyright notices for more information.
 
 namespace otb {
 
-template <class TInputImage, class TOutputImage>
-MinMaxAttributesLabelMapFilter<TInputImage, TOutputImage>
+template <class TInputImage>
+MinMaxAttributesLabelMapFilter<TInputImage>
 ::MinMaxAttributesLabelMapFilter()
 {
-  typename AttributesMapObjectType::Pointer min = AttributesMapObjectType::New();
-  typename AttributesMapObjectType::Pointer max = AttributesMapObjectType::New();
+  this->Superclass::SetNumberOfRequiredOutputs(3);
+  this->itk::ProcessObject::SetNthOutput(1, this->MakeOutput(1).GetPointer());
+  this->itk::ProcessObject::SetNthOutput(2, this->MakeOutput(2).GetPointer());
+}
 
-  this->itk::ProcessObject::SetNthOutput(1, min.GetPointer());
-  this->itk::ProcessObject::SetNthOutput(2, max.GetPointer());
+template<class TInputImage>
+typename MinMaxAttributesLabelMapFilter<TInputImage>::DataObjectPointerType
+MinMaxAttributesLabelMapFilter<TInputImage>
+::MakeOutput(unsigned int i)
+{
+  DataObjectPointerType ret;
+  switch (i)
+  {
+    case 0:
+      ret = InputImageType::New();
+      break;
+    case 1:
+    case 2:
+      ret = AttributesMapObjectType::New();
+      break;
+  }
+  return ret;
 }
 
-template<class TInputImage, class TOutputImage>
-typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesMapObjectType*
-MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>
+
+template<class TInputImage>
+typename MinMaxAttributesLabelMapFilter<TInputImage>::AttributesMapObjectType*
+MinMaxAttributesLabelMapFilter<TInputImage>
 ::GetMinimumOutput()
 {
   return static_cast<AttributesMapObjectType*>(this->itk::ProcessObject::GetOutput(1));
 }
 
-template<class TInputImage, class TOutputImage>
-const typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesMapObjectType*
-MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>
+template<class TInputImage>
+const typename MinMaxAttributesLabelMapFilter<TInputImage>::AttributesMapObjectType*
+MinMaxAttributesLabelMapFilter<TInputImage>
 ::GetMinimumOutput() const
 {
   return static_cast<const AttributesMapObjectType*>(this->itk::ProcessObject::GetOutput(1));
 }
 
-template<class TInputImage, class TOutputImage>
-typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesMapObjectType*
-MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>
+template<class TInputImage>
+typename MinMaxAttributesLabelMapFilter<TInputImage>::AttributesMapObjectType*
+MinMaxAttributesLabelMapFilter<TInputImage>
 ::GetMaximumOutput()
 {
   return static_cast<AttributesMapObjectType*>(this->itk::ProcessObject::GetOutput(2));
 }
 
-template<class TInputImage, class TOutputImage>
-const typename MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>::AttributesMapObjectType*
-MinMaxAttributesLabelMapFilter<TInputImage,TOutputImage>
+template<class TInputImage>
+const typename MinMaxAttributesLabelMapFilter<TInputImage>::AttributesMapObjectType*
+MinMaxAttributesLabelMapFilter<TInputImage>
 ::GetMaximumOutput() const
 {
   return static_cast<const AttributesMapObjectType*>(this->itk::ProcessObject::GetOutput(2));
 }
 
-template<class TInputImage, class TOutputImage>
+template<class TInputImage>
 void
-MinMaxAttributesLabelMapFilter<TInputImage, TOutputImage>
+MinMaxAttributesLabelMapFilter<TInputImage>
 ::GenerateData()
 {
   unsigned int nbAttr = this->GetLabelMap()->GetLabelObject(0)->GetNumberOfAttributes();
diff --git a/Code/OBIA/otbRadiometricAttributesLabelMapFilter.h b/Code/OBIA/otbRadiometricAttributesLabelMapFilter.h
index eee0b31cdb5ae33486e61e99d648545b01882256..8ab0b8f5918121562fccccd85b34a2b4d81afe96 100644
--- a/Code/OBIA/otbRadiometricAttributesLabelMapFilter.h
+++ b/Code/OBIA/otbRadiometricAttributesLabelMapFilter.h
@@ -25,7 +25,6 @@
 #include "otbWaterIndicesFunctor.h"
 #include "otbMultiChannelRAndNIRIndexImageFilter.h"
 #include "otbMultiChannelGAndRIndexImageFilter.h"
-#include "otbMultiChannelRAndGAndNIRVegetationIndexImageFilter.h"
 #include "otbVectorImageToIntensityImageFilter.h"
 #include "otbMultiToMonoChannelExtractROI.h"
 
diff --git a/Testing/Code/OBIA/CMakeLists.txt b/Testing/Code/OBIA/CMakeLists.txt
index c4ecc21a0e9a2bd19c65ee94637ce1bd52a1fbfb..4920059a0711b5a5b3e907d21a92978ac1216f73 100644
--- a/Testing/Code/OBIA/CMakeLists.txt
+++ b/Testing/Code/OBIA/CMakeLists.txt
@@ -42,7 +42,7 @@ ADD_TEST(obTvImageToLabelMapWithAttributesFilter ${OBIA_TESTS1}
         ${INPUTDATA}/cala_labelled.tif)
 
 ADD_TEST(obTuLabelMapSourceNew ${OBIA_TESTS1}
-    otbLabelMapSourceNew)
+         otbLabelMapSourceNew)
 
 ADD_TEST(obTvLabelMapToVectorDataFilter ${OBIA_TESTS1}
     otbLabelMapToVectorDataFilter
@@ -54,7 +54,6 @@ ADD_TEST(obTvVectorDataToLabelMapFilter ${OBIA_TESTS1}
         ${INPUTDATA}/vectorIOexample_gis_to_vec.shp
         ${TEMP}/vectordataToLabelMap.png)
 
-
 ADD_TEST(obTuLabelMapToSampleListFilterNew ${OBIA_TESTS1}
     otbLabelMapToSampleListFilterNew)
     
@@ -114,6 +113,14 @@ ADD_TEST(obTvNormalizeAttributesLabelMapFilter ${OBIA_TESTS1}
          ${INPUTDATA}/cala_labelled.tif
          ${TEMP}/obTvNormalizeAttributesLabelMapFilter.txt)
 
+ADD_TEST(obTuKMeansAttributesLabelMapFilterNew ${OBIA_TESTS1}
+         otbKMeansAttributesLabelMapFilterNew)
+
+ADD_TEST(obTvKMeansAttributesLabelMapFilter ${OBIA_TESTS1}
+         otbKMeansAttributesLabelMapFilter
+         ${INPUTDATA}/calanques.tif
+         ${INPUTDATA}/cala_labelled.tif
+         ${TEMP}/obTvKMeansAttributesLabelMapFilter.txt)
 
 ADD_TEST(obTuRadiometricAttributesLabelMapFilterNew ${OBIA_TESTS1}
 otbRadiometricAttributesLabelMapFilterNew
@@ -170,6 +177,7 @@ otbLabelObjectMapVectorizer.cxx
 otbLabelObjectToPolygonFunctorNew.cxx
 otbMinMaxAttributesLabelMapFilter.cxx
 otbNormalizeAttributesLabelMapFilter.cxx
+otbKMeansAttributesLabelMapFilter.cxx
 otbRadiometricAttributesLabelMapFilterNew.cxx
 otbShapeAttributesLabelMapFilterNew.cxx
 otbStatisticsAttributesLabelMapFilterNew.cxx
diff --git a/Testing/Code/OBIA/otbKMeansAttributesLabelMapFilter.cxx b/Testing/Code/OBIA/otbKMeansAttributesLabelMapFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b1bc8f6fcc4a21de1d102207a06ec0b8a56dd5d2
--- /dev/null
+++ b/Testing/Code/OBIA/otbKMeansAttributesLabelMapFilter.cxx
@@ -0,0 +1,113 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+
+#include "otbImageFileReader.h"
+
+#include <fstream>
+#include <iostream>
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbAttributesMapLabelObjectWithClassLabel.h"
+#include "itkLabelMap.h"
+#include "itkLabelImageToLabelMapFilter.h"
+#include "otbImageToLabelMapWithAttributesFilter.h"
+#include "otbKMeansAttributesLabelMapFilter.h"
+
+const unsigned int Dimension = 2;
+typedef unsigned short LabelType;
+typedef double         PixelType;
+
+typedef otb::AttributesMapLabelObjectWithClassLabel<LabelType, Dimension, double, LabelType>
+                                                                                    LabelObjectType;
+typedef itk::LabelMap<LabelObjectType>                                              LabelMapType;
+typedef otb::VectorImage<PixelType, Dimension>                                      VectorImageType;
+typedef otb::Image<unsigned int,2>                                                  LabeledImageType;
+
+typedef otb::ImageFileReader<VectorImageType>                                       ReaderType;
+typedef otb::ImageFileReader<LabeledImageType>                                      LabeledReaderType;
+typedef itk::LabelImageToLabelMapFilter<LabeledImageType,LabelMapType>              LabelMapFilterType;
+typedef otb::ShapeAttributesLabelMapFilter<LabelMapType>                            ShapeFilterType;
+typedef otb::KMeansAttributesLabelMapFilter<LabelMapType>                           KMeansAttributesLabelMapFilterType;
+
+int otbKMeansAttributesLabelMapFilterNew(int argc, char * argv[])
+{
+  KMeansAttributesLabelMapFilterType::Pointer radiometricLabelMapFilter = KMeansAttributesLabelMapFilterType::New();
+  return EXIT_SUCCESS;
+}
+
+int otbKMeansAttributesLabelMapFilter(int argc, char * argv[])
+{
+  const char * infname = argv[1];
+  const char * lfname  = argv[2];
+  const char * outfname = argv[3];
+
+  // SmartPointer instanciation
+  ReaderType::Pointer         reader = ReaderType::New();
+  LabeledReaderType::Pointer  labeledReader = LabeledReaderType::New();
+  LabelMapFilterType::Pointer filter = LabelMapFilterType::New();
+  ShapeFilterType::Pointer    shapeFilter = ShapeFilterType::New();
+  KMeansAttributesLabelMapFilterType::Pointer kmeansLabelMapFilter = KMeansAttributesLabelMapFilterType::New();
+
+  // Inputs
+  reader->SetFileName(infname);
+  reader->UpdateOutputInformation();
+  labeledReader->SetFileName(lfname);
+  labeledReader->UpdateOutputInformation();
+
+  // Filter
+  filter->SetInput(labeledReader->GetOutput());
+  filter->SetBackgroundValue(itk::NumericTraits<LabelType>::max());
+
+  shapeFilter->SetInput(filter->GetOutput());
+  shapeFilter->Update();
+
+  // Labelize the objects
+  LabelMapType::Pointer labelMap = shapeFilter->GetOutput();
+
+  LabelMapType::LabelObjectContainerType& container = labelMap->GetLabelObjectContainer();
+  LabelMapType::LabelObjectContainerType::const_iterator loIt = container.begin();
+  unsigned int labelObjectID = 0;
+  for(loIt = container.begin(); loIt != container.end(); ++loIt )
+    {
+    unsigned int classLabel = labelObjectID % 3;
+    loIt->second->SetClassLabel(classLabel);
+    ++labelObjectID;
+    }
+
+  kmeansLabelMapFilter->SetInputLabelMap(labelMap);
+  std::vector<std::string> attributes = labelMap->GetLabelObject(0)->GetAvailableAttributes();
+  std::vector<std::string>::const_iterator attrIt;
+  for (attrIt = attributes.begin(); attrIt != attributes.end(); ++attrIt)
+    {
+    kmeansLabelMapFilter->GetMeasurementFunctor().AddAttribute((*attrIt).c_str());
+    }
+
+  kmeansLabelMapFilter->SetNumberOfClasses(3);
+  kmeansLabelMapFilter->Compute();
+
+  std::ofstream outfile(outfname);
+  const KMeansAttributesLabelMapFilterType::CentroidsVectorType& centroids = kmeansLabelMapFilter->GetCentroids();
+  for (unsigned int i = 0; i < centroids.size(); ++i)
+    {
+    outfile << "Centroid " << i << " : " << centroids[i] << std::endl;
+    }
+  outfile.close();
+
+  return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/OBIA/otbMinMaxAttributesLabelMapFilter.cxx b/Testing/Code/OBIA/otbMinMaxAttributesLabelMapFilter.cxx
index e70fc13e0b4a3a126b91696304dd27b0c7e912a6..40384f762776b2d85ebb373a4c4229720260ca62 100644
--- a/Testing/Code/OBIA/otbMinMaxAttributesLabelMapFilter.cxx
+++ b/Testing/Code/OBIA/otbMinMaxAttributesLabelMapFilter.cxx
@@ -41,7 +41,7 @@ typedef otb::ImageFileReader<VectorImageType>
 typedef otb::ImageFileReader<LabeledImageType>                                  LabeledReaderType;
 typedef otb::LabelImageToLabelMapWithAdjacencyFilter<LabeledImageType,LabelMapType> LabelMapFilterType;
 typedef otb::ShapeAttributesLabelMapFilter<LabelMapType>                        ShapeFilterType;
-typedef otb::MinMaxAttributesLabelMapFilter<LabelMapType, VectorImageType>      MinMaxAttributesLabelMapFilterType;
+typedef otb::MinMaxAttributesLabelMapFilter<LabelMapType>                       MinMaxAttributesLabelMapFilterType;
 
 int otbMinMaxAttributesLabelMapFilterNew(int argc, char * argv[])
 {
@@ -95,6 +95,7 @@ int otbMinMaxAttributesLabelMapFilter(int argc, char * argv[])
     outfile << "  " << (*it).first << " : " << (*it).second << std::endl;
     }
   outfile << std::endl;
+  outfile.close();
 
   return EXIT_SUCCESS;
 }
diff --git a/Testing/Code/OBIA/otbNormalizeAttributesLabelMapFilter.cxx b/Testing/Code/OBIA/otbNormalizeAttributesLabelMapFilter.cxx
index d15ef8f6cca2e4f578c21683a0866521b8b5369d..39279e3f3d907542092b124f60f48af19a6ac0a5 100644
--- a/Testing/Code/OBIA/otbNormalizeAttributesLabelMapFilter.cxx
+++ b/Testing/Code/OBIA/otbNormalizeAttributesLabelMapFilter.cxx
@@ -42,7 +42,7 @@ typedef otb::ImageFileReader<VectorImageType>
 typedef otb::ImageFileReader<LabeledImageType>                                  LabeledReaderType;
 typedef otb::LabelImageToLabelMapWithAdjacencyFilter<LabeledImageType,LabelMapType> LabelMapFilterType;
 typedef otb::ShapeAttributesLabelMapFilter<LabelMapType>                        ShapeFilterType;
-typedef otb::MinMaxAttributesLabelMapFilter<LabelMapType, VectorImageType>      MinMaxAttributesLabelMapFilterType;
+typedef otb::MinMaxAttributesLabelMapFilter<LabelMapType>                       MinMaxAttributesLabelMapFilterType;
 typedef otb::NormalizeAttributesLabelMapFilter<LabelMapType>                    NormalizeAttributesLabelMapFilterType;
 
 int otbNormalizeAttributesLabelMapFilterNew(int argc, char * argv[])
@@ -128,6 +128,7 @@ int otbNormalizeAttributesLabelMapFilter(int argc, char * argv[])
     }
   outfile << std::endl;
   }
+  outfile.close();
 
   return EXIT_SUCCESS;
 }
diff --git a/Testing/Code/OBIA/otbOBIATests1.cxx b/Testing/Code/OBIA/otbOBIATests1.cxx
index fdae20c10c43205a281fac507f849d45431d04e6..993822ec7868a47ad06b4b2f007179e8c0ccabfd 100644
--- a/Testing/Code/OBIA/otbOBIATests1.cxx
+++ b/Testing/Code/OBIA/otbOBIATests1.cxx
@@ -45,6 +45,8 @@ REGISTER_TEST(otbMinMaxAttributesLabelMapFilterNew);
 REGISTER_TEST(otbMinMaxAttributesLabelMapFilter);
 REGISTER_TEST(otbNormalizeAttributesLabelMapFilterNew);
 REGISTER_TEST(otbNormalizeAttributesLabelMapFilter);
+REGISTER_TEST(otbKMeansAttributesLabelMapFilterNew);
+REGISTER_TEST(otbKMeansAttributesLabelMapFilter);
 REGISTER_TEST(otbRadiometricAttributesLabelMapFilterNew);
 REGISTER_TEST(otbShapeAttributesLabelMapFilterNew);
 REGISTER_TEST(otbStatisticsAttributesLabelMapFilterNew);