diff --git a/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.h b/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7564bd125ef89148d7a2dc73f4b8dade17d9950
--- /dev/null
+++ b/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.h
@@ -0,0 +1,209 @@
+/*=========================================================================
+
+  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 __otbBandsStatisticsAttributesLabelMapFilter_h
+#define __otbBandsStatisticsAttributesLabelMapFilter_h
+
+#include "otbStatisticsAttributesLabelMapFilter.h"
+#include "otbMultiToMonoChannelExtractROI.h"
+
+namespace otb
+{
+namespace Functor
+{
+/** \class BandStatsAttributesLabelObjectFunctor
+*   \brief Functor to compute multiple statistics attributes.
+*
+* For one label object, this functors applies the
+* StatisticsAttributesLabelObjectFunctor for each feature
+*
+* As such, it allows to compute in one pass statistics related to
+* multiple features. It is used in the
+* BandsStatisticsAttributesLabelMapFilter.
+*
+* Features can be added, removed or cleared via the appropriate
+* methods.
+*
+*   \sa BandsStatisticsAttributesLabelMapFilter
+*   \sa StatisticsAttributesLabelObjectFunctor
+*/
+template <class TLabelObject, class TFeatureImage>
+class BandStatsAttributesLabelObjectFunctor
+{
+public:
+  // Self typedef
+  typedef BandStatsAttributesLabelObjectFunctor Self;
+
+  /// Typedef of the feature image type
+  typedef typename TFeatureImage::PixelType FeatureType;
+
+  /// Typedef of the label object
+  typedef TLabelObject LabelObjectType;
+
+  /// Feature image const pointer
+  typedef typename TFeatureImage::ConstPointer FeatureImageConstPointer;
+
+  /// Statistics functor
+  typedef StatisticsAttributesLabelObjectFunctor
+  <TLabelObject, TFeatureImage>                           StatsFunctorType;
+
+  /// Map to store the functors
+  typedef std::map<std::string, StatsFunctorType> StatsFunctorsMapType;
+
+  /** Constructor */
+  BandStatsAttributesLabelObjectFunctor();
+
+  /** Destructor */
+  virtual ~BandStatsAttributesLabelObjectFunctor();
+
+  /** The comparators */
+  bool operator !=(const Self& self);
+  bool operator ==(const Self& self);
+
+  /** This is the functor implementation
+   *  Calling the functor on a label object
+   *  will update its statistics attributes */
+  inline void operator ()(LabelObjectType * lo) const;
+
+  /** Add a feature with the given name */
+  void AddFeature(const std::string& name, const TFeatureImage * img);
+
+  /** Remove the feature with this name if it exists */
+  bool RemoveFeature(const std::string& name);
+
+  /** Get the feature image with this name */
+  const TFeatureImage * GetFeatureImage(const std::string& name) const;
+
+  /** Clear all the features */
+  void ClearAllFeatures();
+
+  /** Get the number of features */
+  unsigned int GetNumberOfFeatures() const;
+
+  /** Set the reduced attribute set */
+  void SetReducedAttributeSet(bool flag);
+
+  /** Get the reduced attribute set */
+  bool GetReducedAttributeSet() const;
+
+private:
+  /// True to compute only a reduced attribute set
+  bool m_ReducedAttributeSet;
+
+  /// The Stat functors map
+  StatsFunctorsMapType m_StatsFunctorsMap;
+};
+} // End namespace Functor
+
+/** \class BandsStatisticsAttributesLabelMapFilter
+ *  \brief This filter computes band statistics attributes for each object.
+ *
+ * Images are supposed to be compatible with otb::VectorImage
+ *
+ * This filter internally applies the
+ * StatisticsAttributesLabelMapFilter each channel independently
+ *
+ * The feature name is constructed as:
+ * 'STATS' + '::' + 'Band' + #BandIndex + '::' + StatisticName
+ *
+ * The ReducedAttributesSet flag allows to tell the internal
+ * statistics filter to compute only the main attributes (mean, variance, skewness and kurtosis).
+ *
+ * \sa MultiStatsAttributesLabelObjectFunctor AttributesMapLabelObject
+ *
+ * \ingroup ImageEnhancement MathematicalMorphologyImageFilters
+ */
+template<class TImage, class TFeatureImage>
+class ITK_EXPORT BandsStatisticsAttributesLabelMapFilter
+  : public LabelMapFeaturesFunctorImageFilter
+  <TImage,
+      typename Functor::BandStatsAttributesLabelObjectFunctor
+      <typename TImage::LabelObjectType, otb::Image<double, 2> > >
+{
+public:
+  /** Some convenient typedefs. */
+  typedef TImage                                       ImageType;
+  typedef typename ImageType::LabelObjectType          LabelObjectType;
+  typedef TFeatureImage                                FeatureImageType;
+  typedef typename FeatureImageType::InternalPixelType FeatureInternalPixelType;
+  typedef double                                       InternalPrecisionType;
+  typedef Image<InternalPrecisionType, 2>              InternalImageType;
+
+  /** Functor typedef */
+  typedef Functor::BandStatsAttributesLabelObjectFunctor
+  <LabelObjectType, InternalImageType>                    FunctorType;
+
+  /** Standard class typedefs. */
+  typedef BandsStatisticsAttributesLabelMapFilter Self;
+  typedef LabelMapFeaturesFunctorImageFilter
+  <ImageType, FunctorType>                                Superclass;
+  typedef itk::SmartPointer<Self>       Pointer;
+  typedef itk::SmartPointer<const Self> ConstPointer;
+
+  /** ImageDimension constants */
+  itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension);
+
+  /** Standard New method. */
+  itkNewMacro(Self);
+
+  /** Runtime information support. */
+  itkTypeMacro(BandsStatisticsAttributesLabelMapFilter, LabelMapFeaturesFunctorImageFilter);
+
+  // Channels
+  typedef MultiToMonoChannelExtractROI
+  <FeatureInternalPixelType, InternalPrecisionType>       ChannelFilterType;
+  typedef typename ChannelFilterType::Pointer ChannelFilterPointerType;
+
+  /** Set the feature image */
+  void SetFeatureImage(const TFeatureImage *input);
+
+  /** Get the feature image */
+  const FeatureImageType * GetFeatureImage() const;
+
+  /** Set the reduced attribute set */
+  void SetReducedAttributeSet(bool flag);
+
+  /** Get the reduced attribute set */
+  bool GetReducedAttributeSet() const;
+
+  itkBooleanMacro(ReducedAttributeSet);
+
+protected:
+  /** Constructor */
+  BandsStatisticsAttributesLabelMapFilter();
+  /** Destructor */
+  ~BandsStatisticsAttributesLabelMapFilter() {}
+
+  /** Before threaded data generation */
+  virtual void BeforeThreadedGenerateData();
+
+  /** PrintSelf method */
+  void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+private:
+  BandsStatisticsAttributesLabelMapFilter(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+}; // end of class
+
+} // end namespace itk
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbBandsStatisticsAttributesLabelMapFilter.txx"
+#endif
+
+#endif
diff --git a/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.txx b/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.txx
new file mode 100644
index 0000000000000000000000000000000000000000..224bbd7f904177924ddb1a121b9a885389309117
--- /dev/null
+++ b/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.txx
@@ -0,0 +1,249 @@
+/*=========================================================================
+
+  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 __otbBandsStatisticsAttributesLabelMapFilter_txx
+#define __otbBandsStatisticsAttributesLabelMapFilter_txx
+
+#include "otbBandsStatisticsAttributesLabelMapFilter.h"
+
+namespace otb
+{
+namespace Functor
+{
+/** Constructor */
+template <class TLabelObject, class TFeatureImage>
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::BandStatsAttributesLabelObjectFunctor() : m_ReducedAttributeSet(true),
+  m_StatsFunctorsMap()
+{}
+
+/** Destructor */
+template <class TLabelObject, class TFeatureImage>
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::~BandStatsAttributesLabelObjectFunctor(){}
+
+/** The comparators */
+template <class TLabelObject, class TFeatureImage>
+bool
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::operator != (const Self &self)
+  {
+  bool resp = true;
+  resp = resp && (m_ReducedAttributeSet != self.m_ReducedAttributeSet);
+  resp = resp && (m_StatsFunctorsMap != self.m_StatsFunctorsMap);
+  return resp;
+  }
+
+template <class TLabelObject, class TFeatureImage>
+bool
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::operator == (const Self &self)
+  {
+  return !(this != self);
+  }
+
+/** This is the functor implementation
+ *  Calling the functor on a label object
+ *  will update its statistics attributes */
+template <class TLabelObject, class TFeatureImage>
+void
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::operator() (LabelObjectType * lo) const
+{
+  // Walk every registered functors
+  for (typename StatsFunctorsMapType::const_iterator it = m_StatsFunctorsMap.begin();
+       it != m_StatsFunctorsMap.end(); ++it)
+    {
+    (it->second)(lo);
+    }
+}
+
+/** Add a feature with the given name */
+template <class TLabelObject, class TFeatureImage>
+void
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::AddFeature(const std::string& name, const TFeatureImage * img)
+{
+  // Create a new functor
+  StatsFunctorType newFunctor;
+
+  // Set the reduced attribute set option
+  newFunctor.SetReducedAttributeSet(m_ReducedAttributeSet);
+
+  // Set the feature and its name
+  newFunctor.SetFeatureName(name);
+
+  // Set the feature image
+  newFunctor.SetFeatureImage(img);
+
+  // Add it to the map
+  m_StatsFunctorsMap[name] = newFunctor;
+}
+
+/** Remove the feature with this name if it exists */
+template <class TLabelObject, class TFeatureImage>
+bool
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::RemoveFeature(const std::string& name)
+{
+  return (m_StatsFunctorsMap.erase(name) == 1);
+}
+
+/** Get the feature image with this name */
+template <class TLabelObject, class TFeatureImage>
+const TFeatureImage *
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::GetFeatureImage(const std::string& name) const
+{
+  if (m_StatsFunctorsMap.count(name) == 0)
+    {
+    itkGenericExceptionMacro(<< "No feature named " << name << " in map.");
+    }
+  return m_StatsFunctorsMap[name].GetFeatureImage();
+}
+
+/** Clear all the features */
+template <class TLabelObject, class TFeatureImage>
+void
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::ClearAllFeatures()
+{
+  m_StatsFunctorsMap.clear();
+}
+
+/** Get the number of features */
+template <class TLabelObject, class TFeatureImage>
+unsigned int
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::GetNumberOfFeatures() const
+{
+  return m_StatsFunctorsMap.size();
+}
+
+/** Set the reduced attribute set */
+template <class TLabelObject, class TFeatureImage>
+void
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::SetReducedAttributeSet(bool flag)
+{
+  // Set the flag
+  m_ReducedAttributeSet = flag;
+
+  // Set the flag to all the already existing functors
+  for (typename StatsFunctorsMapType::iterator it = m_StatsFunctorsMap.begin();
+       it != m_StatsFunctorsMap.end(); ++it)
+    {
+    it->second.SetReducedAttributeSet(m_ReducedAttributeSet);
+    }
+}
+/** Get the reduced attribute set */
+template <class TLabelObject, class TFeatureImage>
+bool
+BandStatsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
+::GetReducedAttributeSet() const
+{
+  return m_ReducedAttributeSet;
+}
+} // End namespace Functor
+
+template <class TImage, class TFeatureImage>
+BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::BandsStatisticsAttributesLabelMapFilter()
+{
+  this->SetNumberOfRequiredInputs(2);
+}
+
+/** Set the feature image */
+template <class TImage, class TFeatureImage>
+void
+BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::SetFeatureImage(const TFeatureImage *input)
+{
+  // Set the Nth input
+  this->SetNthInput(1, const_cast<TFeatureImage*>(input));
+}
+
+/** Get the feature image */
+template <class TImage, class TFeatureImage>
+const typename BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::FeatureImageType *
+BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::GetFeatureImage() const
+{
+  return static_cast<const TFeatureImage *>(this->itk::ProcessObject::GetInput(1));
+}
+
+/** Set the reduced attribute set */
+template <class TImage, class TFeatureImage>
+void
+BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::SetReducedAttributeSet(bool flag)
+{
+  if (this->GetFunctor().GetReducedAttributeSet() != flag)
+    {
+    this->GetFunctor().SetReducedAttributeSet(flag);
+    this->Modified();
+    }
+}
+
+/** Get the reduced attribute set */
+template <class TImage, class TFeatureImage>
+bool
+BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::GetReducedAttributeSet() const
+{
+  return this->GetFunctor().GetReducedAttributeSet();
+}
+
+template <class TImage, class TFeatureImage>
+void
+BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::BeforeThreadedGenerateData()
+{
+  // First call superclass implementation
+  Superclass::BeforeThreadedGenerateData();
+
+  unsigned long nbComponents = this->GetFeatureImage()->GetNumberOfComponentsPerPixel();
+
+  // Clear any previous feature
+  this->GetFunctor().ClearAllFeatures();
+
+  // Add each band of the feature image to the statistics functor
+  for (unsigned int i = 0; i < nbComponents; ++i)
+    {
+    ChannelFilterPointerType band = ChannelFilterType::New();
+    band->SetChannel(i + 1);
+    band->SetInput(this->GetFeatureImage());
+    band->GetOutput()->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
+    band->Update();
+    std::ostringstream oss;
+    oss << "Band" << i + 1; // [1..N] convention in feature naming
+    this->GetFunctor().AddFeature(oss.str(), band->GetOutput());
+    }
+
+}
+
+template <class TImage, class TFeatureImage>
+void
+BandsStatisticsAttributesLabelMapFilter<TImage, TFeatureImage>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+} // end namespace itk
+#endif
diff --git a/Code/OBIA/otbStatisticsAttributesLabelMapFilter.txx b/Code/OBIA/otbStatisticsAttributesLabelMapFilter.txx
index b3169c545a5799b0eb29f6c860eb8549f10ffce7..45d0973fe353856f0b4df6bdea3f26764834bd9c 100644
--- a/Code/OBIA/otbStatisticsAttributesLabelMapFilter.txx
+++ b/Code/OBIA/otbStatisticsAttributesLabelMapFilter.txx
@@ -78,15 +78,17 @@ StatisticsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
 ::operator() (LabelObjectType * lo) const
 {
   typename LabelObjectType::LineContainerType::const_iterator lit;
-  typename LabelObjectType::LineContainerType&                lineContainer = lo->GetLineContainer();
-
-  FeatureType                       min = itk::NumericTraits<FeatureType>::max();
-  FeatureType                       max = itk::NumericTraits<FeatureType>::NonpositiveMin();
-  double                            sum = 0;
-  double                            sum2 = 0;
-  double                            sum3 = 0;
-  double                            sum4 = 0;
-  unsigned int                      totalFreq = 0;
+  typename LabelObjectType::LineContainerType& lineContainer = lo->GetLineContainer();
+
+  itk::OStringStream oss;
+
+  FeatureType min = itk::NumericTraits<FeatureType>::max();
+  FeatureType max = itk::NumericTraits<FeatureType>::NonpositiveMin();
+  double sum = 0;
+  double sum2 = 0;
+  double sum3 = 0;
+  double sum4 = 0;
+  unsigned int totalFreq = 0;
   typename TFeatureImage::IndexType minIdx;
   minIdx.Fill(0);
   typename TFeatureImage::IndexType maxIdx;
@@ -104,7 +106,7 @@ StatisticsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
   for (lit = lineContainer.begin(); lit != lineContainer.end(); lit++)
     {
     const typename TFeatureImage::IndexType& firstIdx = lit->GetIndex();
-    unsigned long                            length = lit->GetLength();
+    unsigned long length = lit->GetLength();
 
     long endIdx0 = firstIdx[0] + length;
     for (typename TFeatureImage::IndexType idx = firstIdx; idx[0] < endIdx0; idx[0]++)
@@ -125,34 +127,38 @@ StatisticsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
         }
 
       //increase the sums
+      const double v2 = v * v;
+
       sum += v;
-      sum2 += vcl_pow((double) v, 2);
-      sum3 += vcl_pow((double) v, 3);
-      sum4 += vcl_pow((double) v, 4);
+      sum2 += v2;
+      sum3 += v2 * v;
+      sum4 += v2 * v2;
 
-      // moments
-      typename TFeatureImage::PointType physicalPosition;
-      m_FeatureImage->TransformIndexToPhysicalPoint(idx, physicalPosition);
-      for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
+      if (!m_ReducedAttributeSet)
         {
-        centerOfGravity[i] += physicalPosition[i] * v;
-        centralMoments[i][i] += v * physicalPosition[i] * physicalPosition[i];
-        for (unsigned int j = i + 1; j < TFeatureImage::ImageDimension; j++)
+        // moments
+        typename TFeatureImage::PointType physicalPosition;
+        m_FeatureImage->TransformIndexToPhysicalPoint(idx, physicalPosition);
+        for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
           {
-          double weight = v * physicalPosition[i] * physicalPosition[j];
-          centralMoments[i][j] += weight;
-          centralMoments[j][i] += weight;
+          centerOfGravity[i] += physicalPosition[i] * v;
+          centralMoments[i][i] += v * physicalPosition[i] * physicalPosition[i];
+          for (unsigned int j = i + 1; j < TFeatureImage::ImageDimension; j++)
+            {
+            const double weight = v * physicalPosition[i] * physicalPosition[j];
+            centralMoments[i][j] += weight;
+            centralMoments[j][i] += weight;
+            }
           }
         }
-
       }
     }
 
   // final computations
-  double mean = sum / totalFreq;
-  double variance = (sum2 - (vcl_pow(sum, 2) / totalFreq)) / (totalFreq - 1);
-  double sigma = vcl_sqrt(variance);
-  double mean2 = mean * mean;
+  const double mean = sum / totalFreq;
+  const double variance = (sum2 - (sum * sum / totalFreq)) / (totalFreq - 1);
+  const double sigma = vcl_sqrt(variance);
+  const double mean2 = mean * mean;
   double skewness = 0;
   double kurtosis = 0;
 
@@ -160,82 +166,10 @@ StatisticsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
   if (vcl_abs(variance) > epsilon)
     {
     skewness = ((sum3 - 3.0 * mean * sum2) / totalFreq + 2.0 * mean * mean2) / (variance * sigma);
-    kurtosis =
-      ((sum4 - 4.0 * mean * sum3 + 6.0 * mean2 *
-        sum2) / totalFreq - 3.0 * mean2 * mean2) / (variance * variance) - 3.0;
+    kurtosis = ((sum4 - 4.0 * mean * sum3 + 6.0 * mean2 * sum2) / totalFreq - 3.0 * mean2 * mean2) / (variance
+        * variance) - 3.0;
     }
 
-  double elongation = 0;
-  if (sum != 0)
-    {
-    // Normalize using the total mass
-    for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
-      {
-      centerOfGravity[i] /= sum;
-      for (unsigned int j = 0; j < TFeatureImage::ImageDimension; j++)
-        {
-        centralMoments[i][j] /= sum;
-        }
-      }
-
-    // Center the second order moments
-    for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
-      {
-      for (unsigned int j = 0; j < TFeatureImage::ImageDimension; j++)
-        {
-        centralMoments[i][j] -= centerOfGravity[i] * centerOfGravity[j];
-        }
-      }
-
-    // Compute principal moments and axes
-    vnl_symmetric_eigensystem<double> eigen(centralMoments.GetVnlMatrix());
-    vnl_diag_matrix<double> pm = eigen.D;
-    for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
-      {
-      //    principalMoments[i] = 4 * vcl_sqrt( pm(i,i) );
-      principalMoments[i] = pm(i, i);
-      }
-    principalAxes = eigen.V.transpose();
-
-    // Add a final reflection if needed for a proper rotation,
-    // by multiplying the last row by the determinant
-    vnl_real_eigensystem eigenrot(principalAxes.GetVnlMatrix());
-    vnl_diag_matrix<vcl_complex<double> > eigenval = eigenrot.D;
-    vcl_complex<double> det(1.0, 0.0);
-
-    for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
-      {
-      det *= eigenval(i, i);
-      }
-
-    for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
-      {
-      principalAxes[TFeatureImage::ImageDimension - 1][i] *= std::real(det);
-      }
-
-    if (principalMoments[0] != 0)
-      {
-      //    elongation = principalMoments[TFeatureImage::ImageDimension-1] / principalMoments[0];
-      elongation = vcl_sqrt(principalMoments[TFeatureImage::ImageDimension - 1] / principalMoments[0]);
-      }
-    }
-  else
-    {
-    // can't compute anything in that case - just set everything to a default value
-    // Normalize using the total mass
-    for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
-      {
-      centerOfGravity[i] = 0;
-      principalMoments[i] = 0;
-      for (unsigned int j = 0; j < TFeatureImage::ImageDimension; j++)
-        {
-        principalAxes[i][j] = 0;
-        }
-      }
-    }
-  itk::OStringStream oss;
-
-  // finally put the values in the label object
   oss.str("");
   oss << "STATS::" << m_FeatureName << "::Mean";
   lo->SetAttribute(oss.str().c_str(), mean);
@@ -250,55 +184,124 @@ StatisticsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
 
   oss.str("");
   oss << "STATS::" << m_FeatureName << "::Kurtosis";
-  lo->SetAttribute(oss.str().c_str(),  kurtosis);
+  lo->SetAttribute(oss.str().c_str(), kurtosis);
 
-  // If we want all the features
   if (!m_ReducedAttributeSet)
     {
-    oss.str("");
-    oss << "STATS::" << m_FeatureName << "::Minimum";
-    lo->SetAttribute(oss.str().c_str(), (double) min);
+    double elongation = 0;
+    if (sum != 0)
+      {
+      // Normalize using the total mass
+      for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
+        {
+        centerOfGravity[i] /= sum;
+        for (unsigned int j = 0; j < TFeatureImage::ImageDimension; j++)
+          {
+          centralMoments[i][j] /= sum;
+          }
+        }
+
+      // Center the second order moments
+      for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
+        {
+        for (unsigned int j = 0; j < TFeatureImage::ImageDimension; j++)
+          {
+          centralMoments[i][j] -= centerOfGravity[i] * centerOfGravity[j];
+          }
+        }
+
+      // Compute principal moments and axes
+      vnl_symmetric_eigensystem<double> eigen(centralMoments.GetVnlMatrix());
+      vnl_diag_matrix<double> pm = eigen.D;
+      for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
+        {
+        //    principalMoments[i] = 4 * vcl_sqrt( pm(i,i) );
+        principalMoments[i] = pm(i, i);
+        }
+      principalAxes = eigen.V.transpose();
 
-    oss.str("");
-    oss << "STATS::" << m_FeatureName << "::Maximum";
-    lo->SetAttribute(oss.str().c_str(), (double) max);
+      // Add a final reflection if needed for a proper rotation,
+      // by multiplying the last row by the determinant
+      vnl_real_eigensystem eigenrot(principalAxes.GetVnlMatrix());
+      vnl_diag_matrix<vcl_complex<double> > eigenval = eigenrot.D;
+      vcl_complex<double> det(1.0, 0.0);
 
-    oss.str("");
-    oss << "STATS::" << m_FeatureName << "::Sum";
-    lo->SetAttribute(oss.str().c_str(), sum);
+      for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
+        {
+        det *= eigenval(i, i);
+        }
 
-    oss.str("");
-    oss << "STATS::" << m_FeatureName << "::Sigma";
-    lo->SetAttribute(oss.str().c_str(), sigma);
+      for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
+        {
+        principalAxes[TFeatureImage::ImageDimension - 1][i] *= std::real(det);
+        }
+
+      if (principalMoments[0] != 0)
+        {
+        //    elongation = principalMoments[TFeatureImage::ImageDimension-1] / principalMoments[0];
+          elongation = vcl_sqrt(principalMoments[TFeatureImage::ImageDimension - 1] / principalMoments[0]);
+          }
+        }
+      else
+        {
+        // can't compute anything in that case - just set everything to a default value
+        // Normalize using the total mass
+        for (unsigned int i = 0; i < TFeatureImage::ImageDimension; i++)
+          {
+          centerOfGravity[i] = 0;
+          principalMoments[i] = 0;
+          for (unsigned int j = 0; j < TFeatureImage::ImageDimension; j++)
+            {
+            principalAxes[i][j] = 0;
+            }
+          }
+        }
 
-    for (unsigned int dim = 0; dim < TFeatureImage::ImageDimension; ++dim)
-      {
       oss.str("");
-      oss << "STATS::" << m_FeatureName << "::CenterOfGravity" << dim;
-      lo->SetAttribute(oss.str().c_str(), centerOfGravity[dim]);
+      oss << "STATS::" << m_FeatureName << "::Minimum";
+      lo->SetAttribute(oss.str().c_str(), (double) min);
 
       oss.str("");
-      oss << "STATS::" << m_FeatureName << "::PrincipalMoments" << dim;
-      lo->SetAttribute(oss.str().c_str(), principalMoments[dim]);
+      oss << "STATS::" << m_FeatureName << "::Maximum";
+      lo->SetAttribute(oss.str().c_str(), (double) max);
 
       oss.str("");
-      oss << "STATS::" << m_FeatureName << "::FirstMinimumIndex" << dim;
-      lo->SetAttribute(oss.str().c_str(), minIdx[dim]);
+      oss << "STATS::" << m_FeatureName << "::Sum";
+      lo->SetAttribute(oss.str().c_str(), sum);
 
       oss.str("");
-      oss << "STATS::" << m_FeatureName << "::FirstMaximumIndex" << dim;
-      lo->SetAttribute(oss.str().c_str(), maxIdx[dim]);
+      oss << "STATS::" << m_FeatureName << "::Sigma";
+      lo->SetAttribute(oss.str().c_str(), sigma);
 
-      for (unsigned int dim2 = 0; dim2 < TFeatureImage::ImageDimension; ++dim2)
+      for (unsigned int dim = 0; dim < TFeatureImage::ImageDimension; ++dim)
         {
         oss.str("");
-        oss << "STATS::" << m_FeatureName << "::PrincipalAxis" << dim << dim2;
-        lo->SetAttribute(oss.str().c_str(), principalAxes(dim, dim2));
+        oss << "STATS::" << m_FeatureName << "::CenterOfGravity" << dim;
+        lo->SetAttribute(oss.str().c_str(), centerOfGravity[dim]);
+
+        oss.str("");
+        oss << "STATS::" << m_FeatureName << "::PrincipalMoments" << dim;
+        lo->SetAttribute(oss.str().c_str(), principalMoments[dim]);
+
+        oss.str("");
+        oss << "STATS::" << m_FeatureName << "::FirstMinimumIndex" << dim;
+        lo->SetAttribute(oss.str().c_str(), minIdx[dim]);
+
+        oss.str("");
+        oss << "STATS::" << m_FeatureName << "::FirstMaximumIndex" << dim;
+        lo->SetAttribute(oss.str().c_str(), maxIdx[dim]);
+
+        for (unsigned int dim2 = 0; dim2 < TFeatureImage::ImageDimension; ++dim2)
+          {
+          oss.str("");
+          oss << "STATS::" << m_FeatureName << "::PrincipalAxis" << dim << dim2;
+          lo->SetAttribute(oss.str().c_str(), principalAxes(dim, dim2));
+          }
         }
       }
-    }
 }
 
+
 /** Set the name of the feature */
 template <class TLabelObject, class TFeatureImage>
 void
@@ -352,6 +355,7 @@ StatisticsAttributesLabelObjectFunctor<TLabelObject, TFeatureImage>
 {
   return m_ReducedAttributeSet;
 }
+
 } // End namespace Functor
 
 template <class TImage, class TFeatureImage>
diff --git a/Testing/Code/OBIA/CMakeLists.txt b/Testing/Code/OBIA/CMakeLists.txt
index 46bd283112a8f1b0ce60ee9df1eaaf164bd9a1ba..8492d043e6b727a63223dc835d19d3eb9d722d6b 100644
--- a/Testing/Code/OBIA/CMakeLists.txt
+++ b/Testing/Code/OBIA/CMakeLists.txt
@@ -1,9 +1,9 @@
 IF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
 
-SET(BASELINE ${OTB_DATA_ROOT}/Baseline/OTB/Images)
+SET(BASELINE       ${OTB_DATA_ROOT}/Baseline/OTB/Images)
 SET(BASELINE_FILES ${OTB_DATA_ROOT}/Baseline/OTB/Files)
-SET(INPUTDATA ${OTB_DATA_ROOT}/Input)
-SET(TEMP ${OTBTesting_BINARY_DIR}/Temporary)
+SET(INPUTDATA      ${OTB_DATA_ROOT}/Input)
+SET(TEMP           ${OTBTesting_BINARY_DIR}/Temporary)
 
 #Remote sensing images (large images )
 IF(OTB_DATA_USE_LARGEINPUT)
@@ -39,21 +39,21 @@ ADD_TEST(obTuImageToLabelMapWithAttributesFilterNew ${OBIA_TESTS1}
 
 ADD_TEST(obTvImageToLabelMapWithAttributesFilter ${OBIA_TESTS1} 
     otbImageToLabelMapWithAttributesFilter
-        ${INPUTDATA}/calanques.tif
-        ${INPUTDATA}/cala_labelled.tif)
+    ${INPUTDATA}/maur.tif
+    ${INPUTDATA}/maur_labelled.tif)
 
 ADD_TEST(obTuLabelMapSourceNew ${OBIA_TESTS1}
-         otbLabelMapSourceNew)
+    otbLabelMapSourceNew)
 
 ADD_TEST(obTvLabelMapToVectorDataFilter ${OBIA_TESTS1}
     otbLabelMapToVectorDataFilter
-        ${INPUTDATA}/rcc8_mire1.png
-        ${TEMP}/rcc8_mire2_vectorizer.shp)
+    ${INPUTDATA}/rcc8_mire1.png
+    ${TEMP}/rcc8_mire2_vectorizer.shp)
 
 ADD_TEST(obTvVectorDataToLabelMapFilter ${OBIA_TESTS1}
     otbVectorDataToLabelMapFilter
-        ${INPUTDATA}/vectorIOexample_gis_to_vec.shp
-        ${TEMP}/vectordataToLabelMap.png)
+    ${INPUTDATA}/vectorIOexample_gis_to_vec.shp
+    ${TEMP}/vectordataToLabelMap.png)
 
 ADD_TEST(obTuLabelMapToSampleListFilterNew ${OBIA_TESTS1}
     otbLabelMapToSampleListFilterNew)
@@ -66,14 +66,12 @@ ADD_TEST(obTvLabelMapToSampleListFilter ${OBIA_TESTS1}
     SHAPE::Flusser09 SHAPE::Flusser10 SHAPE::Flusser11)
 
 ADD_TEST(obTuLabelMapToVectorDataFilterNew ${OBIA_TESTS1}
-otbLabelMapToVectorDataFilterNew
-)
+    otbLabelMapToVectorDataFilterNew)
 
 ADD_TEST(obTvLabelMapToVectorDataFilter ${OBIA_TESTS1}
-otbLabelMapToVectorDataFilter
-        ${INPUTDATA}/rcc8_mire1.png
-        ${TEMP}/rcc8_mire2_vectorizer.shp
-)
+    otbLabelMapToVectorDataFilter
+    ${INPUTDATA}/rcc8_mire1.png
+    ${TEMP}/rcc8_mire2_vectorizer.shp)
 
 ADD_TEST(obTuLabelMapWithClassLabelToLabeledSampleListFilterNew ${OBIA_TESTS1}
     otbLabelMapWithClassLabelToLabeledSampleListFilterNew)
@@ -86,47 +84,52 @@ ADD_TEST(obTvLabelMapWithClassLabelToLabeledSampleListFilter ${OBIA_TESTS1}
     SHAPE::Flusser09 SHAPE::Flusser10  SHAPE::Flusser11)
 
 ADD_TEST(otbLabelObjectMapVectorizer ${OBIA_TESTS1}
-        otbLabelObjectMapVectorizer
-        ${INPUTDATA}/rcc8_mire1.png
-        rcc8_mire1_label_vectorizer.gml)
+    otbLabelObjectMapVectorizer
+    ${INPUTDATA}/rcc8_mire1.png
+    rcc8_mire1_label_vectorizer.gml)
 
 ADD_TEST(obTuLabelObjectToPolygonFunctorNew ${OBIA_TESTS1}
-otbLabelObjectToPolygonFunctorNew
-)
+    otbLabelObjectToPolygonFunctorNew)
 
 ADD_TEST(obTuMinMaxAttributesLabelMapFilterNew ${OBIA_TESTS1}
-otbMinMaxAttributesLabelMapFilterNew
-)
+    otbMinMaxAttributesLabelMapFilterNew)
 
 ADD_TEST(obTvMinMaxAttributesLabelMapFilter ${OBIA_TESTS1}
-         otbMinMaxAttributesLabelMapFilter
-         ${INPUTDATA}/calanques.tif
-         ${INPUTDATA}/cala_labelled.tif
-         ${TEMP}/obTvMinMaxAttributesLabelMapFilter.txt)
+    otbMinMaxAttributesLabelMapFilter
+    ${INPUTDATA}/maur.tif
+    ${INPUTDATA}/maur_labelled.tif
+    ${TEMP}/obTvMinMaxAttributesLabelMapFilter.txt)
 
 ADD_TEST(obTuNormalizeAttributesLabelMapFilterNew ${OBIA_TESTS1}
-         otbNormalizeAttributesLabelMapFilterNew
-)
+    otbNormalizeAttributesLabelMapFilterNew)
 
 ADD_TEST(obTvNormalizeAttributesLabelMapFilter ${OBIA_TESTS1}
-         otbNormalizeAttributesLabelMapFilter
-         ${INPUTDATA}/calanques.tif
-         ${INPUTDATA}/cala_labelled.tif
-         ${TEMP}/obTvNormalizeAttributesLabelMapFilter.txt)
+    otbNormalizeAttributesLabelMapFilter
+    ${INPUTDATA}/maur.tif
+    ${INPUTDATA}/maur_labelled.tif
+    ${TEMP}/obTvNormalizeAttributesLabelMapFilter.txt)
 
 ADD_TEST(obTuKMeansAttributesLabelMapFilterNew ${OBIA_TESTS1}
-         otbKMeansAttributesLabelMapFilterNew)
+    otbKMeansAttributesLabelMapFilterNew)
 
 ADD_TEST(obTvKMeansAttributesLabelMapFilter ${OBIA_TESTS1}
-         otbKMeansAttributesLabelMapFilter
-         ${INPUTDATA}/calanques.tif
-         ${INPUTDATA}/cala_labelled.tif
-         ${TEMP}/obTvKMeansAttributesLabelMapFilter.txt)
+    otbKMeansAttributesLabelMapFilter
+    ${INPUTDATA}/maur.tif
+    ${INPUTDATA}/maur_labelled.tif
+    ${TEMP}/obTvKMeansAttributesLabelMapFilter.txt)
 
 ADD_TEST(obTuRadiometricAttributesLabelMapFilterNew ${OBIA_TESTS1}
-otbRadiometricAttributesLabelMapFilterNew
-)
+    otbRadiometricAttributesLabelMapFilterNew)
 
+ADD_TEST(obTuBandsStatisticsAttributesLabelMapFilterNew ${OBIA_TESTS1}
+    otbBandsStatisticsAttributesLabelMapFilterNew)
+    
+ADD_TEST(obTvBandsStatisticsAttributesLabelMapFilter ${OBIA_TESTS1}
+    otbBandsStatisticsAttributesLabelMapFilter
+    ${INPUTDATA}/maur.tif
+    ${INPUTDATA}/maur_labelled.tif
+    ${TEMP}/obTvBandsStatisticsAttributesLabelMapFilter.txt)
+    
 ADD_TEST(obTuShapeAttributesLabelMapFilterNew ${OBIA_TESTS1}
 	otbShapeAttributesLabelMapFilterNew)
 
@@ -134,26 +137,24 @@ ADD_TEST(obTuStatisticsAttributesLabelMapFilterNew ${OBIA_TESTS1}
 	otbStatisticsAttributesLabelMapFilterNew)
 
 ADD_TEST(obTuVectorDataToLabelMapFilterNew ${OBIA_TESTS1}
-otbVectorDataToLabelMapFilterNew
-)
+    otbVectorDataToLabelMapFilterNew)
 
 ADD_TEST(obTvVectorDataToLabelMapFilter ${OBIA_TESTS1}
-otbVectorDataToLabelMapFilter
-        ${INPUTDATA}/vectorIOexample_gis_to_vec.shp
-        ${TEMP}/vectordataToLabelMap.png
-)
+    otbVectorDataToLabelMapFilter
+    ${INPUTDATA}/vectorIOexample_gis_to_vec.shp
+    ${TEMP}/vectordataToLabelMap.png)
 
 
 # OBIATests2 (need PQXX)
 IF(OTB_USE_PQXX)
 ADD_TEST(obTuLabelMapToGISTableFilterNew ${OBIA_TESTS2}
-  otbLabelMapToGISTableFilterNew)
+    otbLabelMapToGISTableFilterNew)
 
 ADD_TEST(obTuGISTableToLabelMapFilterNew ${OBIA_TESTS2}
-  otbGISTableToLabelMapFilterNew)
+    otbGISTableToLabelMapFilterNew)
 
 ADD_TEST(obTvLabelMapToGISTableFilter ${OBIA_TESTS2}
-  otbLabelMapToGISTableFilter
+    otbLabelMapToGISTableFilter
     ${INPUTDATA}/rcc8_mire1.png
     orfeotoolbox_test
     labelmaptogis_test_table
@@ -192,6 +193,7 @@ otbMinMaxAttributesLabelMapFilter.cxx
 otbNormalizeAttributesLabelMapFilter.cxx
 otbKMeansAttributesLabelMapFilter.cxx
 otbRadiometricAttributesLabelMapFilterNew.cxx
+otbBandsStatisticsAttributesLabelMapFilter.cxx
 otbShapeAttributesLabelMapFilterNew.cxx
 otbStatisticsAttributesLabelMapFilterNew.cxx
 otbVectorDataToLabelMapFilter.cxx
diff --git a/Testing/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.cxx b/Testing/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..69a5037a1741adb609b24e926bdfa0408411f3e0
--- /dev/null
+++ b/Testing/Code/OBIA/otbBandsStatisticsAttributesLabelMapFilter.cxx
@@ -0,0 +1,112 @@
+/*=========================================================================
+
+  Program:   ORFEO Toolbox
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+  See OTBCopyright.txt for details.
+
+
+  This software is distributed WITHOUT ANY WARRANTY; without even 
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+  PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#if defined(_MSC_VER)
+#pragma warning ( disable : 4786 )
+#endif
+
+#include <fstream>
+#include <iostream>
+
+#include "otbImage.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+#include "otbImageFileWriter.h"
+#include "otbAttributesMapLabelObject.h"
+#include "itkLabelImageToLabelMapFilter.h"
+#include "otbBandsStatisticsAttributesLabelMapFilter.h"
+
+const unsigned int Dimension = 2;
+typedef unsigned short LabelType;
+typedef double         PixelType;
+
+typedef otb::AttributesMapLabelObject<LabelType, Dimension, double>                LabelObjectType;
+typedef itk::LabelMap<LabelObjectType>                                             LabelMapType;
+typedef otb::VectorImage<PixelType, Dimension>                                     VectorImageType;
+typedef otb::Image<unsigned int,2>                                                 LabeledImageType;
+
+typedef LabelMapType::LabelObjectContainerType   LabelObjectContainerType;
+typedef LabelObjectContainerType::const_iterator LabelObjectIterator;
+
+typedef otb::ImageFileReader<VectorImageType>                                      ReaderType;
+typedef otb::ImageFileReader<LabeledImageType>                                     LabeledReaderType;
+typedef otb::ImageFileWriter<VectorImageType>                                      WriterType;
+typedef otb::ImageFileWriter<LabeledImageType>                                     LabeledWriterType;
+
+typedef itk::LabelImageToLabelMapFilter<LabeledImageType,LabelMapType>             LabelMapFilterType;
+typedef otb::BandsStatisticsAttributesLabelMapFilter<LabelMapType,VectorImageType> BandsStatisticsFilterType;
+
+
+int otbBandsStatisticsAttributesLabelMapFilterNew(int argc, char* argv[])
+{
+  BandsStatisticsFilterType::Pointer object = BandsStatisticsFilterType::New();
+  return EXIT_SUCCESS;
+}
+
+int otbBandsStatisticsAttributesLabelMapFilter(int argc, char* argv[])
+{
+  const char * infname  = argv[1];
+  const char * lfname   = argv[2];
+  const char * outfname = argv[3];
+
+  // Filters instanciation
+  ReaderType::Pointer                reader              = ReaderType::New();
+  LabeledReaderType::Pointer         labeledReader       = LabeledReaderType::New();
+  LabelMapFilterType::Pointer        filter              = LabelMapFilterType::New();
+  BandsStatisticsFilterType::Pointer stats               = BandsStatisticsFilterType::New();
+
+  // Read inputs
+  reader->SetFileName(infname);
+  labeledReader->SetFileName(lfname);
+
+  // Make a LabelMap out of it
+  filter->SetInput(labeledReader->GetOutput());
+  filter->SetBackgroundValue(itk::NumericTraits<LabelType>::max());
+
+  //Compute band statistics attributes
+  stats->SetInput(filter->GetOutput());
+  stats->SetFeatureImage(reader->GetOutput());
+
+  stats->Update();
+
+  LabelMapType::Pointer labelMap = stats->GetOutput();
+
+  // Dump all results in the output file
+  std::ofstream outfile(outfname);
+  LabelObjectIterator it = labelMap->GetLabelObjectContainer().begin();
+  LabelObjectIterator end = labelMap->GetLabelObjectContainer().end();
+  for (; it != end; ++it)
+    {
+    LabelType label = it->first;
+    LabelObjectType::Pointer labelObject = it->second;
+
+    outfile << "Label " << label << " : " << std::endl;
+
+    std::vector<std::string> attributes = labelObject->GetAvailableAttributes();
+    std::vector<std::string>::const_iterator attrIt = attributes.begin();
+    std::vector<std::string>::const_iterator attrEnd = attributes.end();
+    for (; attrIt != attrEnd; ++attrIt)
+      {
+      LabelObjectType::AttributesValueType value = labelObject->GetAttribute(attrIt->c_str());
+      outfile << "  " << *attrIt << " : "<< std::fixed << std::setprecision(6) << value << std::endl;
+      }
+    outfile << std::endl;
+    }
+
+  return EXIT_SUCCESS;
+}
+
diff --git a/Testing/Code/OBIA/otbLabelMapSVMClassifier.cxx b/Testing/Code/OBIA/otbLabelMapSVMClassifier.cxx
index 1c7ecafcec3535c200ce8f5f40b3dbefa9541557..66af9c2dc7022f008b9124f52427a8d21876ddc2 100644
--- a/Testing/Code/OBIA/otbLabelMapSVMClassifier.cxx
+++ b/Testing/Code/OBIA/otbLabelMapSVMClassifier.cxx
@@ -57,14 +57,16 @@ typedef itk::FixedArray<LabelType,1>                           TrainingVectorTyp
 typedef itk::Statistics::ListSample<VectorType>                ListSampleType;
 typedef itk::Statistics::ListSample<TrainingVectorType>        TrainingListSampleType;
 typedef otb::LabelMapWithClassLabelToLabeledSampleListFilter<LabelMapType,ListSampleType,TrainingListSampleType>
-                                                               LabelMap2ListSampleFilterType;
+                                                               ListSampleFilterType;
 
 typedef otb::Functor::VariableLengthVectorToMeasurementVectorFunctor<VectorType> MeasurementVectorFunctorType;
 typedef otb::SVMSampleListModelEstimator<ListSampleType,TrainingListSampleType,
   MeasurementVectorFunctorType>                                                  SVMEstimatorType;
 
 typedef otb::LabelMapSVMClassifier<LabelMapType>                                ClassifierType;
-typedef otb::LabelMapWithClassLabelToClassLabelImageFilter<LabelMapType,LabeledImageType> LabelMapWithClassLabelToClassLabelImageFilterType;
+typedef otb::LabelMapWithClassLabelToClassLabelImageFilter
+          <LabelMapType,LabeledImageType>                                       ClassifImageGeneratorType;
+
 
 LabelObjectType::Pointer makeTrainingSample(LabelMapType* labelMap, LabelType labelObjectId, LabelType classLabel)
 {
@@ -86,33 +88,37 @@ int otbLabelMapSVMClassifier(int argc, char * argv[])
   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();
-  RadiometricFilterType::Pointer radiometricFilter = RadiometricFilterType::New();
-  ClassifierType::Pointer     classifier = ClassifierType::New();
-
-  // Inputs
+  // Filters instanciation
+  ReaderType::Pointer                reader              = ReaderType::New();
+  LabeledReaderType::Pointer         labeledReader       = LabeledReaderType::New();
+  LabelMapFilterType::Pointer        filter              = LabelMapFilterType::New();
+  ShapeFilterType::Pointer           shapeFilter         = ShapeFilterType::New();
+  RadiometricFilterType::Pointer     radiometricFilter   = RadiometricFilterType::New();
+  LabelMapType::Pointer              trainingLabelMap    = LabelMapType::New();
+  ListSampleFilterType::Pointer      labelMap2SampleList = ListSampleFilterType::New();
+  SVMEstimatorType::Pointer          svmEstim            = SVMEstimatorType::New();
+  ClassifierType::Pointer            classifier          = ClassifierType::New();
+  ClassifImageGeneratorType::Pointer imGenerator         = ClassifImageGeneratorType::New();
+  LabeledWriterType::Pointer         writer              = LabeledWriterType::New();
+
+  // Read inputs
   reader->SetFileName(infname);
   labeledReader->SetFileName(lfname);
 
-  // Filter
+  // Make a LabelMap out of it
   filter->SetInput(labeledReader->GetOutput());
   filter->SetBackgroundValue(itk::NumericTraits<LabelType>::max());
 
+  //Compute shape and radimometric attributes
   shapeFilter->SetInput(filter->GetOutput());
-
   radiometricFilter->SetInput(shapeFilter->GetOutput());
   radiometricFilter->SetFeatureImage(reader->GetOutput());
   radiometricFilter->Update();
 
-  // Build training samples
+  // Build a sub-LabelMap with class-labeled LabelObject
   LabelMapType::Pointer labelMap = radiometricFilter->GetOutput();
-  LabelMapType::Pointer trainingLabelMap = LabelMapType::New();
 
-  // The following is specific to the input specified in CMakeLists
+  // The following is very specific to the input specified in CMakeLists
   // water
   trainingLabelMap->PushLabelObject(makeTrainingSample(labelMap, 13, 0));
   // road
@@ -132,7 +138,7 @@ int otbLabelMapSVMClassifier(int argc, char * argv[])
   trainingLabelMap->PushLabelObject(makeTrainingSample(labelMap, 161, 4));
   trainingLabelMap->PushLabelObject(makeTrainingSample(labelMap, 46, 4));
 
-  LabelMap2ListSampleFilterType::Pointer labelMap2SampleList = LabelMap2ListSampleFilterType::New();
+  // Make a ListSample out of trainingLabelMap
   labelMap2SampleList->SetInputLabelMap(trainingLabelMap);
 
   std::vector<std::string> attributes = labelMap->GetLabelObject(0)->GetAvailableAttributes();
@@ -144,13 +150,14 @@ int otbLabelMapSVMClassifier(int argc, char * argv[])
 
   labelMap2SampleList->Update();
 
-  SVMEstimatorType::Pointer svmEstim = SVMEstimatorType::New();
+  // Estimate SVM model
   svmEstim->SetInputSampleList(labelMap2SampleList->GetOutputSampleList());
   svmEstim->SetTrainingSampleList(labelMap2SampleList->GetOutputTrainingSampleList());
   svmEstim->SetNumberOfClasses(5);
   svmEstim->Modified();
   svmEstim->Update();
 
+  // Classify using the whole LabelMap with estimated model
   classifier->SetInput(labelMap);
   classifier->SetModel(svmEstim->GetModel());
 
@@ -161,10 +168,9 @@ int otbLabelMapSVMClassifier(int argc, char * argv[])
 
   classifier->Update();
 
-  LabelMapWithClassLabelToClassLabelImageFilterType::Pointer imGenerator = LabelMapWithClassLabelToClassLabelImageFilterType::New();
+  // Make a labeled image with the classification result
   imGenerator->SetInput(classifier->GetOutput());
 
-  LabeledWriterType::Pointer writer = LabeledWriterType::New();
   writer->SetInput(imGenerator->GetOutput());
   writer->SetFileName(outfname);
   writer->Update();
diff --git a/Testing/Code/OBIA/otbOBIATests1.cxx b/Testing/Code/OBIA/otbOBIATests1.cxx
index 993822ec7868a47ad06b4b2f007179e8c0ccabfd..7ecc330f96653b1f40bf5a2d5b516988b5aee1e3 100644
--- a/Testing/Code/OBIA/otbOBIATests1.cxx
+++ b/Testing/Code/OBIA/otbOBIATests1.cxx
@@ -48,6 +48,8 @@ REGISTER_TEST(otbNormalizeAttributesLabelMapFilter);
 REGISTER_TEST(otbKMeansAttributesLabelMapFilterNew);
 REGISTER_TEST(otbKMeansAttributesLabelMapFilter);
 REGISTER_TEST(otbRadiometricAttributesLabelMapFilterNew);
+REGISTER_TEST(otbBandsStatisticsAttributesLabelMapFilterNew);
+REGISTER_TEST(otbBandsStatisticsAttributesLabelMapFilter);
 REGISTER_TEST(otbShapeAttributesLabelMapFilterNew);
 REGISTER_TEST(otbStatisticsAttributesLabelMapFilterNew);
 REGISTER_TEST(otbVectorDataToLabelMapFilterNew);