Olena-patches
  Threads by month 
                
            - ----- 2025 -----
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2024 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2023 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2022 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2021 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2020 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2019 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2018 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2017 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2016 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2015 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2014 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2013 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2012 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2011 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2010 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2009 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2008 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2007 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2006 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2005 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 - February
 - January
 - ----- 2004 -----
 - December
 - November
 - October
 - September
 - August
 - July
 - June
 - May
 - April
 - March
 
- 9625 discussions
 
                    
                        Frédéric,
Il semble que tes patches n'apparaissent pas dans olena-patches.  Peux- 
tu vérifier que ta configuration Sendmail ou les variables  
d'environnement utilisées par svn-wrapper sont correctes ?
Par ailleurs, ne pas préfixer tes titre de ChangeLog avec « [sandbox] 
[bour] » ou autre : ça rajoute du garbage dans le ChangeLog :
2009-02-10  Frederic Bour  <bour(a)lrde.epita.fr>
	[sandbox][bour] Leveling filter with test.
	* fred/Makefile: Modified to test leveling.
	* fred/leveling.cc: Working leveling filter.
	* fred/mean.hh: Corrected bugs.
Un dernier mot sur le style des entrées correspondant à chaque  
fichier : elles doivent être écrites à l'infinitif.
   http://www.gnu.org/prep/standards/html_node/Change-Logs.html
Merci d'avance !
Roland
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                        
                            
                                
                            
                            3333: Fix missing specialization for bkd_pixter in	image1d and image3d.
                        
                        
by Thierry Geraud 10 Feb '09
                    by Thierry Geraud 10 Feb '09
10 Feb '09
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Fix missing specialization for bkd_pixter in image1d and image3d.
	* mln/core/image/image1d.hh
	(bkd_pixter): Fix missing specialization.
	* mln/core/image/image3d.hh
	(bkd_pixter): Fix missing specialization.
	* mln/morpho/attribute/card.hh: Fix missing using.
	* mln/canvas/morpho/algebraic_filter.hh: Layout.
	* tests/morpho/closing_algebraic.cc: Remove dead code.
 mln/core/image/image1d.hh         |   10 ++++++++--
 mln/core/image/image3d.hh         |   10 ++++++++--
 mln/morpho/attribute/card.hh      |    9 ++++++---
 tests/morpho/closing_algebraic.cc |    2 +-
 4 files changed, 23 insertions(+), 8 deletions(-)
Index: mln/core/image/image1d.hh
--- mln/core/image/image1d.hh	(revision 3332)
+++ mln/core/image/image1d.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -543,6 +543,12 @@
     template <typename T>
     struct bkd_pixter< image1d<T> >
     {
+      typedef bkd_pixter1d< image1d<T> > ret;
+    };
+
+    template <typename T>
+    struct bkd_pixter< const image1d<T> >
+    {
       typedef bkd_pixter1d< const image1d<T> > ret;
     };
 
Index: mln/core/image/image3d.hh
--- mln/core/image/image3d.hh	(revision 3332)
+++ mln/core/image/image3d.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -623,6 +623,12 @@
     template <typename T>
     struct bkd_pixter< image3d<T> >
     {
+      typedef bkd_pixter3d< image3d<T> > ret;
+    };
+
+    template <typename T>
+    struct bkd_pixter< const image3d<T> >
+    {
       typedef bkd_pixter3d< const image3d<T> > ret;
     };
 
Index: mln/morpho/attribute/card.hh
--- mln/morpho/attribute/card.hh	(revision 3332)
+++ mln/morpho/attribute/card.hh	(working copy)
@@ -44,7 +44,7 @@
 
   namespace morpho {
     namespace attribute {
-      template <typename I> struct card;
+      template <typename I> class card;
     }
   }
 
@@ -61,7 +61,6 @@
       typedef accumulator::has_set_value::no  has_set_value;
       typedef accumulator::has_stop::no       has_stop;
       typedef accumulator::when_pix::use_none when_pix;
-      
     };
 
   } // end of namespace mln::trait
@@ -76,8 +75,11 @@
       /// Cardinality accumulator class.
 
       template <typename I>
-      struct card : public mln::accu::internal::base< unsigned, card<I> >
+      class card : public mln::accu::internal::base< unsigned, card<I> >
       {
+	typedef mln::accu::internal::base< unsigned, card<I> > super_;
+      public:
+
 	typedef mln_psite(I) argument;
 
 	card();
@@ -93,6 +95,7 @@
 
 	void take();
 	void take_as_init();
+	using super_::take_as_init;
 	/// \}
 
 	/// Get the value of the accumulator.
Index: mln/canvas/morpho/algebraic_filter.hh
Index: tests/morpho/closing_algebraic.cc
--- tests/morpho/closing_algebraic.cc	(revision 3332)
+++ tests/morpho/closing_algebraic.cc	(working copy)
@@ -53,7 +53,7 @@
 
   typedef image2d<int_u8> I;
   I lena;
-  io::pgm::load(lena, MLN_IMG_DIR "/tiny.pgm");//lena.pgm");
+  io::pgm::load(lena, MLN_IMG_DIR "/tiny.pgm");
   {
     accu::count<point2d> a;
     io::pgm::save(morpho::closing_algebraic(lena, c4(), a, 10),
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    10 Feb '09
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Fetch card and algebraic_union_find.hh from Edwin's sandbox.
	* mln/trait/accumulator/props.hh (use_none): New.
	* mln/trait/accumulators.hh
	(mln_trait_accumulator_has_setvalue): Rename as...
	(mln_trait_accumulator_has_set_value): ...this.
	* mln/morpho/attribute: New directory.
	* mln/morpho/attribute/all.hh: New.
	* sandbox/edwin/card.hh: Copy to...
	* mln/morpho/attribute/card.hh: ...this new file.
	Update.
	* mln/morpho/all.hh: Update.
	* sandbox/edwin/algebraic_union_find.hh: Copy to...
	* mln/canvas/morpho/algebraic_filter.hh: ...this new file.
	(algebraic_union_find): Rename as...
	(algebraic_filter): ...this.
	Fix.
	* mln/morpho/closing_algebraic.hh: New.
	* mln/canvas/morpho/all.hh: Update.
	* tests/morpho/attribute: New directory.
	* tests/morpho/attribute/Makefile.am: New.
	* tests/morpho/attribute/card.cc: New.
	* tests/morpho/Makefile.am: Update.
	* tests/morpho/closing_algebraic.cc: New.
 mln/canvas/morpho/algebraic_filter.hh |  174 ++++++++++++------------
 mln/canvas/morpho/all.hh              |    5 
 mln/morpho/all.hh                     |    5 
 mln/morpho/attribute/all.hh           |   51 +++++++
 mln/morpho/attribute/card.hh          |  146 +++++++++++++++-----
 mln/morpho/closing_algebraic.hh       |  240 ++--------------------------------
 mln/trait/accumulator/props.hh        |    1 
 mln/trait/accumulators.hh             |    2 
 tests/morpho/Makefile.am              |    3 
 tests/morpho/attribute/Makefile.am    |   10 +
 tests/morpho/attribute/card.cc        |   50 +++++++
 tests/morpho/closing_algebraic.cc     |   29 ++--
 12 files changed, 360 insertions(+), 356 deletions(-)
Index: mln/trait/accumulator/props.hh
--- mln/trait/accumulator/props.hh	(revision 3331)
+++ mln/trait/accumulator/props.hh	(working copy)
@@ -74,6 +74,7 @@
         struct use_v : any { std::string name() const { return "when_pix::use_v"; } };
         struct use_p : any { std::string name() const { return "when_pix::use_p"; } };
         struct use_pix : any { std::string name() const { return "when_pix::use_pix"; } };
+        struct use_none : any { std::string name() const { return "when_pix::use_none"; } };
         struct not_ok : any { std::string name() const { return "when_pix::not_ok"; } };
       };
 
Index: mln/trait/accumulators.hh
--- mln/trait/accumulators.hh	(revision 3331)
+++ mln/trait/accumulators.hh	(working copy)
@@ -40,7 +40,7 @@
 # define mln_trait_accumulator_has_untake(A) typename mln::trait::accumulator_< A >::has_untake
 
 /// Shortcut to the accumulator property about setvalue method disponibility
-# define mln_trait_accumulator_has_setvalue(A) typename mln::trait::accumulator_< A >::has_setvalue
+# define mln_trait_accumulator_has_set_value(A) typename mln::trait::accumulator_< A >::has_set_value
 
 /// Shortcut to the accumulator property about stop method disponibility
 # define mln_trait_accumulator_has_stop(A) typename mln::trait::accumulator_< A >::has_stop
Index: mln/morpho/attribute/all.hh
--- mln/morpho/attribute/all.hh	(revision 0)
+++ mln/morpho/attribute/all.hh	(revision 0)
@@ -0,0 +1,51 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_ATTRIBUTE_ALL_HH
+# define MLN_MORPHO_ATTRIBUTE_ALL_HH
+
+/// \file mln/morpho/attribute/all.hh
+///
+/// File that includes all attributes used in mathematical morphology.
+
+
+namespace mln
+{
+  namespace morpho
+  {
+
+    /// Namespace of attributes used in mathematical morphology.
+    namespace attribute {}
+
+  }
+}
+
+
+# include <mln/morpho/attribute/card.hh>
+
+
+#endif // ! MLN_MORPHO_ATTRIBUTE_ALL_HH
Index: mln/morpho/attribute/card.hh
--- mln/morpho/attribute/card.hh	(revision 0)
+++ mln/morpho/attribute/card.hh	(working copy)
@@ -1,44 +1,121 @@
-#ifndef CARD_HH_
-# define CARD_HH_
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_ATTRIBUTE_CARD_HH
+# define MLN_MORPHO_ATTRIBUTE_CARD_HH
+
+/// \file mln/morpho/attribute/card.hh
+///
+/// Define an accumulator that computes the cardinality of a
+/// component.
+
+# include <mln/accu/internal/base.hh>
 
-# include <mln/accu/all.hh>
-# include <mln/util/pix.hh>
 
 namespace mln
 {
+
+
+  // Forward declaration.
+
+  namespace morpho {
+    namespace attribute {
+      template <typename I> struct card;
+    }
+  }
+
+
+  // Traits.
+
+  namespace trait
+  {
+
+    template <typename I>
+    struct accumulator_< morpho::attribute::card<I> >
+    {
+      typedef accumulator::has_untake::no     has_untake;
+      typedef accumulator::has_set_value::no  has_set_value;
+      typedef accumulator::has_stop::no       has_stop;
+      typedef accumulator::when_pix::use_none when_pix;
+      
+    };
+
+  } // end of namespace mln::trait
+
+
   namespace morpho
   {
-    namespace accu
+
+    namespace attribute
     {
+
+      /// Cardinality accumulator class.
+
       template <typename I>
       struct card : public mln::accu::internal::base< unsigned, card<I> >
       {
 	typedef mln_psite(I) argument;
 
 	card ();
+
+	/// Manipulators.
+	/// \{
 	void init ();
 
-	void take (const card<I>& accu);
+	void take(const argument& s);
+	void take(const card<I>& other);
+
+	void take(const util::pix<I>& px);
 
 	void take ();
-	void take (const mln_psite(I)& elt);
-	void take (const mln_value(I)& elt);
-	void take (const util::pix<I>& pix);
+	void take_as_init();
+	/// \}
 
+	/// Get the value of the accumulator.
 	unsigned to_result() const;
 
+	/// Check whether this accu is able to return a result.
+	/// Always true here.
 	bool is_valid () const;
 
-      private:
+      protected:
+	/// The value.
 	unsigned c_;
       };
 
+
+
 # ifndef MLN_INCLUDE_ONLY
+
       template <typename I>
       inline
-      card<I>::card () :
-	c_ (0)
+      card<I>::card()
       {
+	init();
       }
 
       template <typename I>
@@ -52,45 +129,43 @@
       template <typename I>
       inline
       void
-      card<I>::take (const card<I>& accu)
+      card<I>::take(const argument&)
       {
-	c_ += accu.c_;
+	take();
       }
 
-
       template <typename I>
       inline
       void
-      card<I>::take ()
+      card<I>::take(const card<I>& other)
       {
-	++c_;
-      };
+	c_ += other.c_;
+      }
 
       template <typename I>
       inline
       void
-      card<I>::take (const mln_psite(I)& elt)
+      card<I>::take(const util::pix<I>&)
       {
-	++c_;
-      };
-
+	take();
+      }
 
       template <typename I>
       inline
       void
-      card<I>::take (const mln_value(I)& elt)
+      card<I>::take()
       {
 	++c_;
-      };
-
+      }
 
       template <typename I>
       inline
       void
-      card<I>::take (const util::pix<I>& pix)
+      card<I>::take_as_init()
       {
-	++c_;
-      };
+	init();
+	take();
+      }
 
       template <typename I>
       inline
@@ -98,7 +173,7 @@
       card<I>::to_result() const
       {
 	return c_;
-      };
+      }
 
       template <typename I>
       inline
@@ -106,14 +181,15 @@
       card<I>::is_valid () const
       {
 	return true;
-      };
-# endif
+      }
+
+# endif // ! MLN_INCLUDE_ONLY
 
+    } // end of namespace mln::morpho::attribute
 
-    } // mln::morpho::accu
-  } // mln::morpho
-} // mln
+  } // end of namespace mln::morpho
 
-#endif /* !CARD_HH_ */
+} // end of namespace mln
 
 
+#endif // ! MLN_MORPHO_ATTRIBUTE_CARD_HH
Property changes on: mln/morpho/attribute/card.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/morpho/all.hh
--- mln/morpho/all.hh	(revision 3331)
+++ mln/morpho/all.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -84,6 +84,7 @@
 
 // Sub-directories.
 
+# include <mln/morpho/attribute/all.hh>
 # include <mln/morpho/elementary/all.hh>
 # include <mln/morpho/tree/all.hh>
 # include <mln/morpho/watershed/all.hh>
Index: mln/morpho/closing_algebraic.hh
--- mln/morpho/closing_algebraic.hh	(revision 3330)
+++ mln/morpho/closing_algebraic.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -26,25 +26,15 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_MORPHO_CLOSING_ATTRIBUTE_HH
-# define MLN_MORPHO_CLOSING_ATTRIBUTE_HH
+#ifndef MLN_MORPHO_CLOSING_ALGEBRAIC_HH
+# define MLN_MORPHO_CLOSING_ALGEBRAIC_HH
 
-/// \file mln/morpho/closing_attribute.hh
+/// \file mln/morpho/closing_algebraic.hh
 ///
-/// Morphological attribute closing.
-///
-/// \todo How to pass dynamic data (e.g., k of accu::rank) to the routine?
-///
-/// \todo Add extension::adjust_fill.
-///
-/// \todo Re-activate the fastest version when accumulators are
-/// cleaned-up.
+/// Morphological algebraic closing.
 
 # include <mln/morpho/includes.hh>
-# include <mln/canvas/morpho/algebraic_union_find.hh>
-# include <mln/level/sort_psites.hh>
-# include <mln/level/sort_offsets.hh>
-# include <mln/util/pix.hh>
+# include <mln/canvas/morpho/algebraic_filter.hh>
 
 
 namespace mln
@@ -53,227 +43,39 @@
   namespace morpho
   {
 
-    /// Morphological attribute closing.
-    template <typename A, typename I, typename N>
-    mln_concrete(I)
-    closing_attribute(const Image<I>& input, const Neighborhood<N>& nbh,
-		      mln_result(A) lambda);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-
-    // Implementations.
-
-    namespace impl
-    {
-
-
-      // Generic version.
-
-      namespace generic
-      {
-
-	template <typename I, typename A_>
-	struct closing_attribute_functor_t
-	{
-	  // requirements from mln::canvas::morpho::algebraic_union_find
-
-	  typedef A_ A;
-	  typedef mln_psite(I) P;
-	  typedef p_array<P> S;
-
-	  mln_result(A) lambda;
-	  const S s;
-
-	  void init()
-	  {
-	    // FIXME: border::fill(input, mln_max(mln_value(I)));
-	  }
-
-	  bool is_active(const A& attr) const
-	  {
-	    return attr.to_result() < lambda;
-	  }
-
-	  void inactivate(A& attr)
-	  {
-	    attr.set_value(lambda);
-	  }
-
-	  // end of requirements
-
-	  closing_attribute_functor_t(const Image<I>& input, mln_result(A) lambda)
-	    : lambda(lambda),
-	      s(level::sort_psites_increasing(exact(input)))
-	  {
-	  }
-
-	};
-
-
-	template <typename A, typename I, typename N>
-	inline
+    /// Morphological algebraic closing.
+    template <typename I, typename N, typename A>
 	mln_concrete(I)
-	closing_attribute(const Image<I>& input, const Neighborhood<N>& nbh,
-			  mln_result(A) lambda)
-	{
-	  trace::entering("morpho::impl::generic::closing_attribute");
+    closing_algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
+		      const Accumulator<A>& accu, const mln_result(A)& lambda);
 	
-	  mln_precondition(exact(input).is_valid());
 	
-	  typedef closing_attribute_functor_t<I, A> F;
-	  F f(input, lambda);
-	  mln_concrete(I) output = canvas::morpho::impl::generic::algebraic_union_find(input, nbh, f);
-	
-	  mln_postcondition(output >= input);
-	
-	  trace::exiting("morpho::impl::generic::closing_attribute");
-	  return output;
-	}
-
-
-      } // end of namespace mln::morpho::impl::generic
-
-
-
-      // "Fastest" version.
-
-
-      template <typename I, typename A_>
-      struct closing_attribute_fastest_functor_t
-      {
-	// requirements from mln::canvas::morpho::algebraic_union_find
-
-	typedef A_ A;
-	typedef mln_psite(I) P;
-	typedef util::array<unsigned> S;
-
-	mln_result(A) lambda;
-	const S s;
-
-	void init()
-	{
-	  // FIXME: border::fill(input, mln_max(mln_value(I)));
-	}
-
-	bool is_active(const A& attr) const
-	{
-	  return attr.to_result() < lambda;
-	}
-
-	void inactivate(A& attr)
-	{
-	  attr.set_value(lambda);
-	}
-
-	// end of requirements
-
-	closing_attribute_fastest_functor_t(const Image<I>& input, mln_result(A) lambda)
-	  : lambda(lambda),
-	    s(level::sort_offsets_increasing(exact(input)))
-	{
-	}
-
-      };
-
-
-      template <typename A, typename I, typename N>
-      inline
-      mln_concrete(I)
-      closing_attribute_fastest(const Image<I>& input, const Neighborhood<N>& nbh,
-				mln_result(A) lambda)
-      {
-	trace::entering("morpho::impl::closing_attribute_fastest");
-	
-	mln_precondition(exact(input).is_valid());
-	
-	typedef impl::closing_attribute_fastest_functor_t<I, A> F;
-	F f(input, lambda);
-	mln_concrete(I) output = canvas::morpho::impl::algebraic_union_find_fastest(input, nbh, f);
-	
-	mln_postcondition(output >= input);
-	
-	trace::exiting("morpho::impl::closing_attribute_fastest");
-	return output;
-      }
-
-
-    } // end of namespace mln::morpho::impl
-
-
-
-    // Dispatch.
-
-    namespace internal
-    {
-
-      template <typename A, typename I, typename N>
-      inline
-      mln_concrete(I)
-      closing_attribute_dispatch(metal::false_,
-				 const Image<I>& input, const Neighborhood<N>& nbh,
-				 mln_result(A) lambda)
-      {
-	return impl::generic::closing_attribute<A>(input, nbh, lambda);
-      }
-
-      template <typename A, typename I, typename N>
-      inline
-      mln_concrete(I)
-      closing_attribute_dispatch(metal::true_,
-				 const Image<I>& input, const Neighborhood<N>& nbh,
-				 mln_result(A) lambda)
-      {
-	return impl::generic::closing_attribute<A>(input, nbh, lambda);
-// 	return impl::closing_attribute_fastest<A>(input, nbh, lambda);
-      }
-
-      template <typename A, typename I, typename N>
-      inline
-      mln_concrete(I)
-      closing_attribute_dispatch(const Image<I>& input, const Neighborhood<N>& nbh,
-				 mln_result(A) lambda)
-      {
-	  enum {
-	    test = mlc_equal(mln_trait_image_speed(I),
-			     trait::image::speed::fastest)::value
-	    &&
-	    mln_is_simple_neighborhood(N)::value
-	  };
-	  return closing_attribute_dispatch<A>(metal::bool_<test>(),
-					     input, nbh, lambda);
-      }
-
-    } // end of namespace internal
 
 
+# ifndef MLN_INCLUDE_ONLY
 
-    // Facade.
 
-    template <typename A, typename I, typename N>
+    template <typename I, typename N, typename A>
     inline
     mln_concrete(I)
-    closing_attribute(const Image<I>& input, const Neighborhood<N>& nbh,
-		      mln_result(A) lambda)
+    closing_algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
+		      const Accumulator<A>& accu, const mln_result(A)& lambda)
     {
-      trace::entering("morpho::closing_attribute");
+      trace::entering("morpho::closing_algebraic");
 
       mln_precondition(exact(input).is_valid());
 
-      mln_concrete(I) output = internal::closing_attribute_dispatch<A>(input, nbh, lambda);
+      mln_concrete(I) output;
+      output = canvas::morpho::algebraic_filter(input, nbh, accu, lambda,
+						/* increasing = */ true);
 
       mln_postcondition(output >= input);
 
-      trace::exiting("morpho::closing_attribute");
+      trace::exiting("morpho::closing_algebraic");
       return output;
     }
 
 
-    // Facade.
-
-
 # endif // ! MLN_INCLUDE_ONLY
 
   } // end of namespace mln::morpho
@@ -281,4 +83,4 @@
 } // end of namespace mln
 
 
-#endif // ! MLN_MORPHO_CLOSING_ATTRIBUTE_HH
+#endif // ! MLN_MORPHO_CLOSING_ALGEBRAIC_HH
Property changes on: mln/morpho/closing_algebraic.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/canvas/morpho/all.hh
--- mln/canvas/morpho/all.hh	(revision 3331)
+++ mln/canvas/morpho/all.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -46,6 +46,7 @@
 }
 
 
+# include <mln/canvas/morpho/algebraic_filter.hh>
 # include <mln/canvas/morpho/algebraic_union_find.hh>
 
 
Index: mln/canvas/morpho/algebraic_filter.hh
--- mln/canvas/morpho/algebraic_filter.hh	(revision 3330)
+++ mln/canvas/morpho/algebraic_filter.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -26,27 +26,24 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH
-# define MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH
+#ifndef MLN_CANVAS_MORPHO_ALGEBRAIC_FILTER_HH
+# define MLN_CANVAS_MORPHO_ALGEBRAIC_FILTER_HH
 
+/// \file mln/canvas/morpho/algebraic_filter.hh
 ///
-///
-/// \todo: Doc!
-///
-/// \todo Re-activate the fastest version when accumulators are
-/// cleaned-up.
+/// Canvas for morphological algebraic filters.
 
 # include <mln/core/concept/image.hh>
 # include <mln/core/concept/neighborhood.hh>
 # include <mln/core/concept/accumulator.hh>
-# include <mln/data/fill.hh>
-# include <mln/util/pix.hh>
 
+# include <mln/data/fill.hh>
+# include <mln/extension/adjust_fill.hh>
 
 # include <mln/level/sort_psites.hh>
 # include <mln/level/sort_offsets.hh>
 
-# include "accu_trait.hh"
+
 
 namespace mln
 {
@@ -57,6 +54,23 @@
     namespace morpho
     {
 
+
+      template <typename I, typename N, typename A>
+      mln_concrete(I)
+      algebraic_filter(const Image<I>& input,
+		       const Neighborhood<N>& nbh,
+		       const Accumulator<A>& accu,
+		       const mln_result(A)& lambda,
+		       bool increasing);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+      // Implementations.
+
+
       namespace impl
       {
 
@@ -79,18 +93,19 @@
 	  template <typename I, typename N, typename S, typename A>
 	  inline
 	  mln_concrete(I)
-	  algebraic_union_find(const Image<I>& input_,
+	  algebraic_filter(const Image<I>& input_,
 			       const Neighborhood<N>& nbh_,
-			       const Site_Set<S>& s_,
 			       const Accumulator<A>& accu_,
-			       mln_result(A) lambda)
+			   const mln_result(A)& lambda,
+			   const Site_Set<S>& s_)
 	  {
-	    trace::entering("canvas::morpho::impl::generic::algebraic_union_find");
+	    trace::entering("canvas::morpho::impl::generic::algebraic_filter");
 
 	    // FIXME: Tests?
 
 	    const I& input = exact(input_);
 	    const N& nbh = exact(nbh_);
+	    const S& s     = exact(s_);
 
 	    mln_concrete(I) output;
 	    initialize(output, input);
@@ -117,42 +132,18 @@
 
 	    // First pass.
 	    {
-	      mln_fwd_piter(S) p(s_);
+	      mln_fwd_piter(S) p(s);
 	      mln_niter(N) n(nbh, p);
 	      for_all(p)
 	      {
-		// Make set.
-		{
+		// Make-Set.
 		  parent(p) = p;
-		  /* FIXME: What if the value_type of DATA (i.e., A) were not
-		     based on a accu::count<mln::pix>?  Currently, nothing
-		     enforces this, but the code below expects this line to be
-		     valid:
-
-		     data(p).take_as_init(make::pix(f.input, p))
-
-		     which probably restricts the kind of input images.
-
-		     If we want to be more generic, the initialization should
-		     read something like:
-
-		     init_data(p);
-
-		     i.e., the functor for the initialization of data should
-		     be passed as an argument to the canvas' ctor.
-
-		     Of course, we might want to restrict attributes to the
-		     accumulator accu::count<mln::pix> (which is perfectly
-		     acceptable), but then this class should statically check
-		     the conformance of the template parameter A to this
-		     constraint.  */
-		  data(p).take_as_init(p); // FIXME: algebraic so p!
-		}
+		data(p).take_as_init(p);
 
 		for_all(n)
 		  if (input.domain().has(n) && deja_vu(n))
 		    {
-		      //do_union(n, p);
+		      // Do-Union.
 		      P r = find_root(parent, n);
 		      if (r != p)
 			{
@@ -177,18 +168,16 @@
 				activity(p) = false;
 			    }
 			  else
-			    {
 			      activity(p) = false;
 			    }
 			}
-		    }
 		deja_vu(p) = true;
 	      }
 	    }
 
 	    // Second pass.
 	    {
-	      mln_bkd_piter(S) p(s_);
+	      mln_bkd_piter(S) p(s);
 	      for_all(p)
 		if (parent(p) == p) // p is root.
 		  output(p) = input(p);
@@ -202,7 +191,7 @@
 	      and add in init:
 	      mln::data::fill(output, input);
 	    */
-	    trace::exiting("canvas::morpho::impl::generic::algebraic_union_find");
+	    trace::exiting("canvas::morpho::impl::generic::algebraic_filter");
 
 	    return output;
 	  }
@@ -213,34 +202,36 @@
 
 	// Fastest version.
 
+
 	template <typename I>
 	inline
 	unsigned
 	find_root_fastest(I& parent, unsigned x)
 	{
-	  if (parent.element(x) == x)
+	  if (parent.element(x) == 0)
 	    return x;
 	  else
 	    return parent.element(x) = find_root_fastest(parent, parent.element(x));
 	}
 
-
-	template <typename I, typename N, typename S, typename A>
+	template <typename I, typename N, typename A>
 	inline
 	mln_concrete(I)
-	algebraic_union_find_fastest(const Image<I>& input_,
+	algebraic_filter_fastest(const Image<I>& input_,
 				     const Neighborhood<N>& nbh_,
-				     const Site_Set<S>& s_,
 				     const Accumulator<A>& accu_,
-				     mln_result(A) lambda)
+				 const mln_result(A)& lambda,
+				 const util::array<unsigned>& s)
 	{
-	  trace::entering("canvas::morpho::impl::algebraic_union_find_fastest");
+	  trace::entering("canvas::morpho::impl::algebraic_filter_fastest");
 
 	  // FIXME: Tests?
 
 	  const I& input = exact(input_);
 	  const N& nbh = exact(nbh_);
 
+	  extension::adjust(input, nbh);
+
 	  mln_concrete(I) output;
 	  initialize(output, input);
 
@@ -257,6 +248,7 @@
 	  {
 	    initialize(deja_vu, input);
 	    mln::data::fill(deja_vu, false);
+	    extension::fill(deja_vu, false); // So that the extension is ignored.
 	    initialize(activity, input);
 	    mln::data::fill(activity, true);
 	    initialize(parent, input);
@@ -267,18 +259,17 @@
 	  util::array<int> dp = offsets_wrt(input, nbh);
 	  const unsigned n_nbhs = dp.nelements();
 
-	  const unsigned n_points = s_.nelements();
+	  const unsigned n = s.nelements();
 
 	  // First pass.
 	  {
 
-	    for (unsigned i = 0; i < n_points; ++i)
+	    for (unsigned i = 0; i < n; ++i)
 	      {
-		unsigned p = s_[i]; // An offset.
+		unsigned p = s[i]; // An offset.
 
 		// Make set.
-		parent.element(p) = p;
-		data.element(p).take_as_init(); // FIXME: Very bad et SEULEMENT POUR CARD !!! C CON!!!
+		data.element(p).take_as_init(); // FIXME: Very bad!
 
 		for (unsigned j = 0; j < n_nbhs; ++j)
 		  {
@@ -290,20 +281,17 @@
 		    if (r != p)
 		      {
 			if (input.element(r) == input.element(p)
-			    || (activity.element(r)
-				&& data.element(r) < lambda))
+			    || (activity.element(r) && data.element(r) < lambda))
 			  {
-			    data.element(p).take();
+			    data.element(p).take(data.element(r));
 			    parent.element(r) = p;
 			    if (activity.element(r) == false)
 			      activity.element(p) = false;
 			  }
 			else
-			  {
 			    activity.element(p) = false;
 			  }
 		      }
-		  }
 
 		deja_vu.element(p) = true;
 	      }
@@ -312,16 +300,16 @@
 
 	  // Second pass.
 	  {
-	    for (int i = n_points - 1; i >= 0 ; --i)
+	    for (int i = n - 1; i >= 0 ; --i)
 	      {
-		unsigned p = s_[i];
-		if (parent.element(p) == p) // p is root.
+		unsigned p = s[i];
+		if (parent.element(p) == 0) // p is root.
 		  output.element(p) = input.element(p);
 		else
 		  output.element(p) = output.element(parent.element(p));
 	      }
 	  }
-	  trace::exiting("canvas::morpho::impl::algebraic_union_find_fastest");
+	  trace::exiting("canvas::morpho::impl::algebraic_filter_fastest");
 	  return output;
 	}
 
@@ -332,59 +320,64 @@
 
       // Dispatch.
 
+
       namespace internal
       {
 	template <typename I, typename N, typename A>
 	inline
 	mln_concrete(I)
-	algebraic_union_find_dispatch(metal::false_,
+	algebraic_filter_dispatch(metal::false_,
 				      const Image<I>& input,
 				      const Neighborhood<N>& nbh,
 				      const Accumulator<A>& accu,
-				      mln_result(A) lambda,
+				  const mln_result(A)& lambda,
 				      bool increasing)
 	{
 	  p_array<mln_psite(I)> s = increasing ?
 	    level::sort_psites_increasing(input) :
 	    level::sort_psites_decreasing(input);
-	  return impl::generic::algebraic_union_find(input, nbh, s, accu,
-						     lambda);
+	  return impl::generic::algebraic_filter(input, nbh, accu, lambda,
+						 s);
 	}
 
 	template <typename I, typename N, typename A>
 	inline
 	mln_concrete(I)
-	algebraic_union_find_dispatch(metal::true_,
+	algebraic_filter_dispatch(metal::true_,
 				      const Image<I>& input,
 				      const Neighborhood<N>& nbh,
 				      const Accumulator<A>& accu,
-				      mln_result(A) lambda,
+				  const mln_result(A)& lambda,
 				      bool increasing)
 	{
 	  util::array<unsigned> s = increasing ?
 	    level::sort_offsets_increasing(input) :
 	    level::sort_offsets_decreasing(input);
-	  return impl::algebraic_union_find_fastest(input, nbh, s, accu, lambda);
+	  return impl::algebraic_filter_fastest(input, nbh, accu, lambda,
+						s);
 	}
 
 	template <typename I, typename N, typename A>
 	inline
 	mln_concrete(I)
-	algebraic_union_find_dispatch(const Image<I>& input,
+	algebraic_filter_dispatch(const Image<I>& input,
 				      const Neighborhood<N>& nbh,
 				      const Accumulator<A>& accu,
-				      mln_result(A) lambda,
+				  const mln_result(A)& lambda,
 				      bool increasing)
 	{
 	  enum {
 	    test = (mlc_equal(mln_trait_image_speed(I),
-			      trait::image::speed::fastest)::value &&
-		    mln_is_simple_neighborhood(N)::value &&
-		    mlc_equal(mln_trait_accu_when_pix(A),
-			      trait::accu::when_pix::use_whatever)::value)
+			      trait::image::speed::fastest)::value
+		    &&
+		    mln_is_simple_neighborhood(N)::value
+		    &&
+		    mlc_equal(mln_trait_accumulator_when_pix(A),
+			      trait::accumulator::when_pix::use_none)::value)
 	  };
-	  return algebraic_union_find_dispatch(metal::bool_<test>(), input, nbh,
-					       accu, lambda, increasing);
+	  return algebraic_filter_dispatch(metal::bool_<test>(),
+					   input, nbh, accu, lambda,
+					   increasing);
 	}
 
       } // end of namespace mln::canvas::morpho::internal
@@ -393,20 +386,23 @@
 
       // Facade.
 
+
       template <typename I, typename N, typename A>
       inline
       mln_concrete(I)
-      algebraic_union_find(const Image<I>& input,
+      algebraic_filter(const Image<I>& input,
 			   const Neighborhood<N>& nbh,
 			   const Accumulator<A>& accu,
-			   mln_result(A) lambda,
+		       const mln_result(A)& lambda,
 			   bool increasing)
       {
-	return internal::algebraic_union_find_dispatch(input, nbh, accu,
-						       lambda, increasing);
+	return internal::algebraic_filter_dispatch(input, nbh, accu, lambda,
+						   increasing);
       }
 
 
+# endif // ! MLN_INCLUDE_ONLY
+
     } // end of namespace mln::canvas::morpho
 
   } // end of namespace mln::canvas
@@ -414,4 +410,4 @@
 } // end of namespace mln
 
 
-#endif // ! MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH
+#endif // ! MLN_CANVAS_MORPHO_ALGEBRAIC_FILTER_HH
Property changes on: mln/canvas/morpho/algebraic_filter.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: tests/morpho/attribute/Makefile.am
--- tests/morpho/attribute/Makefile.am	(revision 0)
+++ tests/morpho/attribute/Makefile.am	(revision 0)
@@ -0,0 +1,10 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+include $(top_srcdir)/milena/tests/tests.mk
+
+check_PROGRAMS =				\
+  card
+
+card_SOURCES = card.cc
+
+TESTS = $(check_PROGRAMS)
Index: tests/morpho/attribute/card.cc
--- tests/morpho/attribute/card.cc	(revision 0)
+++ tests/morpho/attribute/card.cc	(revision 0)
@@ -0,0 +1,50 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/morpho/attribute/card.cc
+///
+/// Test on mln::morpho::attribute::card.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/morpho/attribute/card.hh>
+
+
+int main()
+{
+  using namespace mln;
+
+  typedef image2d<int> I;
+  I ima(3, 3);
+  point2d p(0, 0);
+  util::pix<I> px(ima, p);
+
+  morpho::attribute::card<I> c;
+  c.take();
+  c.take(p);
+  c.take(px);
+  mln_assertion(c == 3);
+}
Index: tests/morpho/Makefile.am
--- tests/morpho/Makefile.am	(revision 3331)
+++ tests/morpho/Makefile.am	(working copy)
@@ -3,12 +3,14 @@
 include $(top_srcdir)/milena/tests/tests.mk
 
 SUBDIRS =					\
+  attribute					\
   elementary					\
   tree						\
   watershed
 
 check_PROGRAMS =				\
   artificial_line_graph_image_wst		\
+  closing_algebraic				\
   closing_area					\
   closing_height				\
   closing_volume				\
@@ -45,6 +47,7 @@
 erosion_SOURCES = erosion.cc
 
 opening_area_SOURCES = opening_area.cc
+closing_algebraic_SOURCES = closing_algebraic.cc
 closing_area_SOURCES = closing_area.cc
 closing_height_SOURCES = closing_height.cc
 opening_height_SOURCES = opening_height.cc
Index: tests/morpho/closing_algebraic.cc
--- tests/morpho/closing_algebraic.cc	(revision 3330)
+++ tests/morpho/closing_algebraic.cc	(working copy)
@@ -1,5 +1,4 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -26,9 +25,9 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/// \file tests/morpho/closing_area.cc
+/// \file tests/morpho/closing_algebraic.cc
 ///
-/// Test on mln::morpho::closing_area.
+/// Test on mln::morpho::closing_algebraic.
 
 #include <mln/core/image/image2d.hh>
 #include <mln/value/int_u8.hh>
@@ -37,7 +36,9 @@
 #include <mln/io/pgm/load.hh>
 #include <mln/io/pgm/save.hh>
 
-#include <mln/morpho/closing_area.hh>
+#include <mln/morpho/closing_algebraic.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/accu/count.hh>
 
 #include "tests/data.hh"
 
@@ -48,7 +49,19 @@
   using namespace mln;
   using value::int_u8;
 
-  image2d<int_u8> lena;
-  io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
-  io::pgm::save(morpho::closing_area(lena, c4(), 510), "out.pgm");
+  trace::quiet = false;
+
+  typedef image2d<int_u8> I;
+  I lena;
+  io::pgm::load(lena, MLN_IMG_DIR "/tiny.pgm");//lena.pgm");
+  {
+    accu::count<point2d> a;
+    io::pgm::save(morpho::closing_algebraic(lena, c4(), a, 10),
+		  "ref.pgm");
+  }
+  {
+    morpho::attribute::card<I> a;
+    io::pgm::save(morpho::closing_algebraic(lena, c4(), a, 10),
+		  "out.pgm");
+  }
 }
Property changes on: tests/morpho/closing_algebraic.cc
___________________________________________________________________
Added: svn:mergeinfo
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Fetch accumulator properties from Fred's sandbox.
	* mln/trait/accumulator: New directory.
	* sandbox/fred/accuprops.cc: Copy to...
	* mln/trait/accumulator/props.hh,
	* mln/trait/accumulators.hh: ...these new files.
	Rename entities to enforce consistency.
	Remove leveling related code.
	* mln/trait/accumulator/print.hh: New.
	* mln/core/concept/accumulator.hh: Include props.
	* tests/accu/max.cc: Upgrade file doc style.
 mln/core/concept/accumulator.hh |    5 
 mln/trait/accumulator/print.hh  |   92 ++++++++++
 mln/trait/accumulator/props.hh  |  338 +++++----------------------------------
 mln/trait/accumulators.hh       |  340 +++++-----------------------------------
 tests/accu/max.cc               |   12 -
 5 files changed, 195 insertions(+), 592 deletions(-)
Index: mln/trait/accumulator/props.hh
--- mln/trait/accumulator/props.hh	(revision 0)
+++ mln/trait/accumulator/props.hh	(working copy)
@@ -1,331 +1,87 @@
-# include <iostream>
-# include <string>
-
-# include <mln/trait/undef.hh>
-# include <mln/trait/image/props.hh>
-# include <mln/trait/value_.hh>
-
-# include <mln/metal/bexpr.hh>
-# include <mln/metal/equal.hh>
-# include <mln/metal/if.hh>
-# include <mln/metal/is_const.hh>
-
-# include <mln/core/concept/image.hh>
-# include <mln/accu/all.hh>
-# include <mln/util/pix.hh>
-# include <mln/make/pix.hh>
-
-/// Shortcut to the accumulator property about untake method disponibility
-# define mln_trait_accu_has_untake(A) typename mln::trait::accu_< A >::has_untake
-
-/// Shortcut to the accumulator property about setvalue method disponibility
-# define mln_trait_accu_has_setvalue(A) typename mln::trait::accu_< A >::has_setvalue
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_TRAIT_ACCUMULATOR_PROPS_HH
+# define MLN_TRAIT_ACCUMULATOR_PROPS_HH
+
+/// \file mln/trait/accumulator/props.hh
+///
+/// Properties of accumulator classes.
 
-/// Shortcut to the accumulator property about stop method disponibility
-# define mln_trait_accu_has_stop(A) typename mln::trait::accu_< A >::has_stop
+# include <string>
 
-/// Shortcut to the accumulator property about behavior when pixel is given as take() value
-/// Used for instance in mln::canvas::morpho::leveling
-# define mln_trait_accu_when_pix(A) typename mln::trait::accu_< A >::when_pix
 
-namespace mln {
+namespace mln
+{
 
-  namespace trait {
+  namespace trait 
+  {
 
-    namespace accu {
+    namespace accumulator
+    {
 
-      // Basic accumulators properties
+      // Basic accumulators properties.
 
       struct has_untake
       {
         struct any { protected: any() {}; };
-
         struct no : any { std::string name() const { return "has_untake::no"; } };
-
         struct yes : any { std::string name() const { return "has_untake::yes"; } };
       };
 
       struct has_stop
       {
         struct any { protected: any() {}; };
-
-        struct no : any { std::string name() const { return "has_setvalue::no"; } };
-
+        struct no : any { std::string name() const { return "has_stop::no"; } };
         struct yes : any { std::string name() const { return "has_stop::yes"; } };
       };
 
-      struct has_setvalue
+      struct has_set_value
       {
         struct any { protected: any() {}; };
-
-        struct no : any { std::string name() const { return "has_setvalue::no"; } };
-
-        struct yes : any { std::string name() const { return "has_setvalue::yes"; } };
+        struct no : any { std::string name() const { return "has_set_value::no"; } };
+        struct yes : any { std::string name() const { return "has_set_value::yes"; } };
       };
 
       // Morphological accumulators properties
       struct when_pix
       {
         struct any { protected: any() {}; };
-
         struct use_v : any { std::string name() const { return "when_pix::use_v"; } };
-
         struct use_p : any { std::string name() const { return "when_pix::use_p"; } };
-
         struct use_pix : any { std::string name() const { return "when_pix::use_pix"; } };
-
         struct not_ok : any { std::string name() const { return "when_pix::not_ok"; } };
       };
 
-    }  // end of namespace mln::trait::accu
-
-    template <typename A>
-    struct undefined_accu_
-    {
-      // general
-      typedef undef has_untake;
-      typedef undef has_stop;
-      typedef undef has_setvalue;
-
-      // morpho
-      typedef accu::when_pix::not_ok when_pix;
-      // FIXME: should default be undef ?
-    };
-
-    template <typename A>
-    struct accu_ : undefined_accu_<A>
-    {
-    };
-
-  }  // end of namespace mln::trait
-
-  namespace canvas {
-
-    namespace morpho {
-
-      namespace impl {
-
-        namespace generic {
-
-          template <typename I, template <typename P> class A>
-          inline
-          void
-          leveling(const Image<I>& input,
-              Accumulator< A< util::pix<I> > >& acc)
-          {
-            const I& ima = exact(input);
-            A< util::pix<I> >& a = exact(acc);
-
-            mln_piter(I) p(ima.domain());
-
-            for_all(p)
-              a.take(mln::make::pix(ima, p));
-          }
-
-        } // end of namespace mln::canvas::morpho::impl::generic
-
-        // fast implementation (only on values from pixter)
-        template <typename I, template <typename P> class A>
-        inline
-        void
-        leveling_fastest(const Image<I>& input,
-            Accumulator< A< util::pix<I> > >& acc)
-        {
-          const I& ima = exact(input);
-          A< util::pix<I> >& a = exact(acc);
-
-          mln_pixter(const I) px(ima);
-
-          for_all(px)
-            a.take(px.val());
-        }
-
-      }  // end of namespace mln::canvas::morpho::impl
-
-      namespace internal {
-
-        template <typename I, typename A>
-        inline
-        void
-        leveling_dispatch(metal::false_,
-            const Image<I>& input,
-            Accumulator<A>& acc)
-        {
-          impl::generic::leveling(input, acc);
-        }
-
-        template <typename I, typename A>
-        inline
-        void
-        leveling_dispatch(metal::true_,
-            const Image<I>& input,
-            Accumulator<A>& acc)
-        {
-          impl::leveling_fastest(input, acc);
-        }
-
-        template <typename I, typename A>
-        inline
-        void
-        leveling_dispatch(const Image<I>& input,
-            Accumulator<A>& acc)
-        {
-          enum {
-            test = mlc_equal(mln_trait_image_speed(I),
-                trait::image::speed::fastest)::value
-                &&
-                mlc_equal(mln_trait_accu_when_pix(A),
-                    trait::accu::when_pix::use_v)::value
-          };
-          internal::leveling_dispatch(metal::bool_<test>(),
-              input, acc);
-        }
-
-      }  // end of namespace mln::canvas::morpho::internal
-
-      // Facade.
-      template <typename I, template <typename P> class A>
-      inline
-      void
-      leveling(const Image<I>& input,
-          Accumulator< A< util::pix<I> > >& acc)
-      {
-        internal::leveling_dispatch(input, acc);
-      }
-
-    }  // end of namespace mln::canvas::morpho
-
-  }  // end of namespace mln::canvas
-
-  namespace morpho {
-
-    namespace accu {
-
-      namespace internal {
-
-        template <typename V>
-        struct sum_handling_pixels
-        { typedef mln_sum(V) ret; };
-
-        template <typename I>
-        struct sum_handling_pixels< util::pix<I> >
-        { typedef mln_sum(mln_value(I)) ret; };
-
-      } // end of namespace mln::morpho::accu::internal
-
-      template <typename T>
-      /// Morphological (i.e. for pixel and pixel values) accumulator calculating mean.
-      /// FIXME: is inclusion polyphormism really appliable ?
-      struct mean : public mln::accu::mean<T, typename internal::sum_handling_pixels<T>::ret>,
-                    public Accumulator< mean<T> >
-      {
-        typedef mln::accu::mean<T, typename internal::sum_handling_pixels<T>::ret> super;
-	typedef typename super::result result;
-
-        using super::operator result;
-        using super::take;
-
-        void take(const mean<T>& m);
-      };
-
-      template <typename I>
-      struct mean< util::pix<I> > : public mean< mln_value(I) >,
-                                    public Accumulator< mean< util::pix<I> > >
-      {
-        typedef mean< mln_value(I) > super;
-        typedef util::pix<I> argument;
-	typedef typename super::result result;
-
-        using super::operator result;
-        using super::take;
-
-        void take(const argument& t);
-        void take(const mean< util::pix<I> >& m);
-      };
-
-# ifndef MLN_INCLUDE_ONLY
-
-      template <typename T>
-      inline
-      void mean<T>::take(const mean<T>& m)
-      {
-        this->super::take(m);
-      }
-
-      template <typename I>
-      inline
-      void mean< util::pix<I> >::take(const mean< util::pix<I> >::argument& t)
-      {
-        this->mean< mln_value(I) >::take(t.v());
-      }
-
-      template <typename I>
-      inline
-      void mean< util::pix<I> >::take(const mean< util::pix<I> >& m)
-      {
-        this->super::take(m);
-      }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-    } // end of namespace mln::morpho::accu
-
-  } // end of namespace mln::morpho
-
-  namespace trait {
-
-    template <typename I>
-    struct accu_< morpho::accu::mean< util::pix<I> > > :
-      public undefined_accu_ < morpho::accu::mean< util::pix<I> > >
-    {
-      typedef accu::when_pix::use_v when_pix;
-    };
+    } // end of namespace mln::trait::accumulator
 
   } // end of namespace mln::trait
 
 } // end of namespace mln
 
-# include <mln/accu/all.hh>
-# include <mln/core/image/image2d.hh>
-
-# include <mln/debug/iota.hh>
-# include <mln/debug/println.hh>
-# include <mln/core/var.hh>
-# include <mln/util/timer.hh>
-int main()
-{
-  typedef mln::image2d<int> I;
-
-  I ima(1000, 1000);
-  mln::morpho::accu::mean< mln::util::pix<I> > acc;
-
-  float elapsed;
-  mln::util::timer chrono;
-
-  mln::debug::iota(ima);
-  std::cout << "50 mean of a 1000x1000 image2d<int>" << std::endl;
-
-  acc.init();
-  chrono.start();
-  for (int i = 0; i < 50; i++)
-    mln::canvas::morpho::leveling(ima, acc);
-  elapsed = chrono.stop();
-
-  std::cout << "(auto) " << elapsed << "s : " << acc.to_result() << std::endl;
-
-  acc.init();
-  chrono.start();
-  for (int i = 0; i < 50; i++)
-    mln::canvas::morpho::impl::generic::leveling(ima, acc);
-  elapsed = chrono.stop();
-
-  std::cout << "(generic) " << elapsed << "s : " << acc.to_result() << std::endl;
-
-  acc.init();
-  chrono.start();
-  for (int i = 0; i < 50; i++)
-    mln::canvas::morpho::impl::leveling_fastest(ima, acc);
-  elapsed = chrono.stop();
 
-  std::cout << "(fast) " << elapsed << "s : " << acc.to_result() << std::endl;
-}
+#endif // ! MLN_TRAIT_ACCUMULATOR_PROPS_HH
Property changes on: mln/trait/accumulator/props.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/trait/accumulator/print.hh
--- mln/trait/accumulator/print.hh	(revision 0)
+++ mln/trait/accumulator/print.hh	(revision 0)
@@ -0,0 +1,92 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_TRAIT_ACCUMULATOR_PRINT_HH
+# define MLN_TRAIT_ACCUMULATOR_PRINT_HH
+
+/// \file mln/trait/accumulator/print.hh
+///
+/// Print the collection of traits for an accumulator type.
+
+# include <iostream>
+# include <mln/trait/accumulators.hh>
+# include <mln/metal/is_a.hh>
+
+
+
+namespace mln
+{
+
+  // Forward declaration.
+  template <typename E> struct Accumulator;
+
+
+  namespace trait
+  {
+
+    namespace accumulator
+    {
+
+      template <typename A>
+      void print(std::ostream& ostr = std::cout);
+
+      template <typename A>
+      void print(const Accumulator<A>& ima, std::ostream& ostr = std::cout);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+      template <typename A>
+      inline
+      void print(std::ostream& ostr)
+      {
+	mlc_is_a(A, Accumulator)::check();
+	typedef mln::trait::accumulator_<A> the;
+	ostr << "{ "
+	     << typename the::has_untake().name() << ", "
+	     << typename the::has_stop().name() << ", "
+	     << typename the::has_set_value().name() << ", "
+	     << typename the::when_pix().name() << " }" << std::endl;
+      }
+
+      template <typename A>
+      inline
+      void print(const Accumulator<A>&, std::ostream& ostr)
+      {
+	print<A>(ostr);
+      }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+    } // end of namespace mln::trait::accumulator
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRAIT_ACCUMULATOR_PRINT_HH
Index: mln/trait/accumulators.hh
--- mln/trait/accumulators.hh	(revision 3329)
+++ mln/trait/accumulators.hh	(working copy)
@@ -1,331 +1,83 @@
-# include <iostream>
-# include <string>
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_TRAIT_ACCUMULATORS_HH
+# define MLN_TRAIT_ACCUMULATORS_HH
+
+/// \file mln/trait/accumulators.hh
+///
+/// Some base trait types for accumulators.
 
+# include <mln/trait/accumulator/props.hh>
 # include <mln/trait/undef.hh>
-# include <mln/trait/image/props.hh>
-# include <mln/trait/value_.hh>
 
-# include <mln/metal/bexpr.hh>
-# include <mln/metal/equal.hh>
-# include <mln/metal/if.hh>
-# include <mln/metal/is_const.hh>
-
-# include <mln/core/concept/image.hh>
-# include <mln/accu/all.hh>
-# include <mln/util/pix.hh>
-# include <mln/make/pix.hh>
 
 /// Shortcut to the accumulator property about untake method disponibility
-# define mln_trait_accu_has_untake(A) typename mln::trait::accu_< A >::has_untake
+# define mln_trait_accumulator_has_untake(A) typename mln::trait::accumulator_< A >::has_untake
 
 /// Shortcut to the accumulator property about setvalue method disponibility
-# define mln_trait_accu_has_setvalue(A) typename mln::trait::accu_< A >::has_setvalue
+# define mln_trait_accumulator_has_setvalue(A) typename mln::trait::accumulator_< A >::has_setvalue
 
 /// Shortcut to the accumulator property about stop method disponibility
-# define mln_trait_accu_has_stop(A) typename mln::trait::accu_< A >::has_stop
+# define mln_trait_accumulator_has_stop(A) typename mln::trait::accumulator_< A >::has_stop
 
 /// Shortcut to the accumulator property about behavior when pixel is given as take() value
 /// Used for instance in mln::canvas::morpho::leveling
-# define mln_trait_accu_when_pix(A) typename mln::trait::accu_< A >::when_pix
+# define mln_trait_accumulator_when_pix(A) typename mln::trait::accumulator_< A >::when_pix
 
-namespace mln {
 
-  namespace trait {
 
-    namespace accu {
-
-      // Basic accumulators properties
-
-      struct has_untake
+namespace mln
       {
-        struct any { protected: any() {}; };
-
-        struct no : any { std::string name() const { return "has_untake::no"; } };
 
-        struct yes : any { std::string name() const { return "has_untake::yes"; } };
-      };
-
-      struct has_stop
+  namespace trait
       {
-        struct any { protected: any() {}; };
-
-        struct no : any { std::string name() const { return "has_setvalue::no"; } };
-
-        struct yes : any { std::string name() const { return "has_stop::yes"; } };
-      };
-
-      struct has_setvalue
-      {
-        struct any { protected: any() {}; };
-
-        struct no : any { std::string name() const { return "has_setvalue::no"; } };
-
-        struct yes : any { std::string name() const { return "has_setvalue::yes"; } };
-      };
-
-      // Morphological accumulators properties
-      struct when_pix
-      {
-        struct any { protected: any() {}; };
-
-        struct use_v : any { std::string name() const { return "when_pix::use_v"; } };
-
-        struct use_p : any { std::string name() const { return "when_pix::use_p"; } };
-
-        struct use_pix : any { std::string name() const { return "when_pix::use_pix"; } };
-
-        struct not_ok : any { std::string name() const { return "when_pix::not_ok"; } };
-      };
-
-    }  // end of namespace mln::trait::accu
 
     template <typename A>
-    struct undefined_accu_
+    struct undefined_accumulator_
     {
-      // general
       typedef undef has_untake;
       typedef undef has_stop;
-      typedef undef has_setvalue;
-
-      // morpho
-      typedef accu::when_pix::not_ok when_pix;
-      // FIXME: should default be undef ?
+      typedef undef has_set_value;
+      typedef accumulator::when_pix::not_ok when_pix;
     };
 
     template <typename A>
-    struct accu_ : undefined_accu_<A>
-    {
-    };
-
-  }  // end of namespace mln::trait
-
-  namespace canvas {
-
-    namespace morpho {
-
-      namespace impl {
-
-        namespace generic {
-
-          template <typename I, template <typename P> class A>
-          inline
-          void
-          leveling(const Image<I>& input,
-              Accumulator< A< util::pix<I> > >& acc)
-          {
-            const I& ima = exact(input);
-            A< util::pix<I> >& a = exact(acc);
-
-            mln_piter(I) p(ima.domain());
-
-            for_all(p)
-              a.take(mln::make::pix(ima, p));
-          }
-
-        } // end of namespace mln::canvas::morpho::impl::generic
-
-        // fast implementation (only on values from pixter)
-        template <typename I, template <typename P> class A>
-        inline
-        void
-        leveling_fastest(const Image<I>& input,
-            Accumulator< A< util::pix<I> > >& acc)
-        {
-          const I& ima = exact(input);
-          A< util::pix<I> >& a = exact(acc);
-
-          mln_pixter(const I) px(ima);
-
-          for_all(px)
-            a.take(px.val());
-        }
-
-      }  // end of namespace mln::canvas::morpho::impl
-
-      namespace internal {
-
-        template <typename I, typename A>
-        inline
-        void
-        leveling_dispatch(metal::false_,
-            const Image<I>& input,
-            Accumulator<A>& acc)
-        {
-          impl::generic::leveling(input, acc);
-        }
-
-        template <typename I, typename A>
-        inline
-        void
-        leveling_dispatch(metal::true_,
-            const Image<I>& input,
-            Accumulator<A>& acc)
+    struct accumulator_ : undefined_accumulator_<A>
         {
-          impl::leveling_fastest(input, acc);
-        }
-
-        template <typename I, typename A>
-        inline
-        void
-        leveling_dispatch(const Image<I>& input,
-            Accumulator<A>& acc)
-        {
-          enum {
-            test = mlc_equal(mln_trait_image_speed(I),
-                trait::image::speed::fastest)::value
-                &&
-                mlc_equal(mln_trait_accu_when_pix(A),
-                    trait::accu::when_pix::use_v)::value
-          };
-          internal::leveling_dispatch(metal::bool_<test>(),
-              input, acc);
-        }
-
-      }  // end of namespace mln::canvas::morpho::internal
-
-      // Facade.
-      template <typename I, template <typename P> class A>
-      inline
-      void
-      leveling(const Image<I>& input,
-          Accumulator< A< util::pix<I> > >& acc)
-      {
-        internal::leveling_dispatch(input, acc);
-      }
-
-    }  // end of namespace mln::canvas::morpho
-
-  }  // end of namespace mln::canvas
-
-  namespace morpho {
-
-    namespace accu {
-
-      namespace internal {
-
-        template <typename V>
-        struct sum_handling_pixels
-        { typedef mln_sum(V) ret; };
-
-        template <typename I>
-        struct sum_handling_pixels< util::pix<I> >
-        { typedef mln_sum(mln_value(I)) ret; };
-
-      } // end of namespace mln::morpho::accu::internal
-
-      template <typename T>
-      /// Morphological (i.e. for pixel and pixel values) accumulator calculating mean.
-      /// FIXME: is inclusion polyphormism really appliable ?
-      struct mean : public mln::accu::mean<T, typename internal::sum_handling_pixels<T>::ret>,
-                    public Accumulator< mean<T> >
-      {
-        typedef mln::accu::mean<T, typename internal::sum_handling_pixels<T>::ret> super;
-	typedef typename super::result result;
-
-        using super::operator result;
-        using super::take;
-
-        void take(const mean<T>& m);
-      };
-
-      template <typename I>
-      struct mean< util::pix<I> > : public mean< mln_value(I) >,
-                                    public Accumulator< mean< util::pix<I> > >
-      {
-        typedef mean< mln_value(I) > super;
-        typedef util::pix<I> argument;
-	typedef typename super::result result;
-
-        using super::operator result;
-        using super::take;
-
-        void take(const argument& t);
-        void take(const mean< util::pix<I> >& m);
       };
 
-# ifndef MLN_INCLUDE_ONLY
-
-      template <typename T>
-      inline
-      void mean<T>::take(const mean<T>& m)
-      {
-        this->super::take(m);
-      }
-
-      template <typename I>
-      inline
-      void mean< util::pix<I> >::take(const mean< util::pix<I> >::argument& t)
-      {
-        this->mean< mln_value(I) >::take(t.v());
-      }
-
-      template <typename I>
-      inline
-      void mean< util::pix<I> >::take(const mean< util::pix<I> >& m)
-      {
-        this->super::take(m);
-      }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-    } // end of namespace mln::morpho::accu
-
-  } // end of namespace mln::morpho
-
-  namespace trait {
-
-    template <typename I>
-    struct accu_< morpho::accu::mean< util::pix<I> > > :
-      public undefined_accu_ < morpho::accu::mean< util::pix<I> > >
-    {
-      typedef accu::when_pix::use_v when_pix;
-    };
 
   } // end of namespace mln::trait
 
 } // end of namespace mln
 
-# include <mln/accu/all.hh>
-# include <mln/core/image/image2d.hh>
-
-# include <mln/debug/iota.hh>
-# include <mln/debug/println.hh>
-# include <mln/core/var.hh>
-# include <mln/util/timer.hh>
-int main()
-{
-  typedef mln::image2d<int> I;
-
-  I ima(1000, 1000);
-  mln::morpho::accu::mean< mln::util::pix<I> > acc;
-
-  float elapsed;
-  mln::util::timer chrono;
-
-  mln::debug::iota(ima);
-  std::cout << "50 mean of a 1000x1000 image2d<int>" << std::endl;
-
-  acc.init();
-  chrono.start();
-  for (int i = 0; i < 50; i++)
-    mln::canvas::morpho::leveling(ima, acc);
-  elapsed = chrono.stop();
-
-  std::cout << "(auto) " << elapsed << "s : " << acc.to_result() << std::endl;
-
-  acc.init();
-  chrono.start();
-  for (int i = 0; i < 50; i++)
-    mln::canvas::morpho::impl::generic::leveling(ima, acc);
-  elapsed = chrono.stop();
 
-  std::cout << "(generic) " << elapsed << "s : " << acc.to_result() << std::endl;
+# include <mln/trait/accumulator/print.hh>
 
-  acc.init();
-  chrono.start();
-  for (int i = 0; i < 50; i++)
-    mln::canvas::morpho::impl::leveling_fastest(ima, acc);
-  elapsed = chrono.stop();
 
-  std::cout << "(fast) " << elapsed << "s : " << acc.to_result() << std::endl;
-}
+#endif // ! MLN_TRAIT_ACCUMULATORS_HH
Property changes on: mln/trait/accumulators.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/core/concept/accumulator.hh
--- mln/core/concept/accumulator.hh	(revision 3329)
+++ mln/core/concept/accumulator.hh	(working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -36,6 +36,7 @@
 # include <mln/core/concept/proxy.hh>
 # include <mln/metal/fix_return.hh>
 # include <mln/metal/const.hh>
+# include <mln/trait/accumulators.hh>
 
 
 namespace mln
Index: tests/accu/max.cc
--- tests/accu/max.cc	(revision 3329)
+++ tests/accu/max.cc	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -25,10 +26,9 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/*! \file tests/accu/max.cc
- *
- * \brief Tests on mln::accu::max.
- */
+/// \file tests/accu/max.cc
+///
+/// Tests on mln::accu::max.
 
 #include <mln/core/image/image2d.hh>
 #include <mln/debug/iota.hh>
@@ -50,4 +50,6 @@
   mln_assertion(level::compute(accu::meta::max(), ima) == 9);
   accu::max<int> M;
   mln_assertion(level::compute(M, ima) == 9);
+
+  // mln::trait::accumulator::print(M);
 }
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* mln/accu/center.hh: use a vector of type mln_sum(P::coord) instead
	of P::vec. Avoid an overflow.
---
 milena/ChangeLog          |    7 +++++++
 milena/mln/accu/center.hh |    4 ++--
 2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 3d3cca5..933a495 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,10 @@
+2009-02-10  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Fix accu::center.
+
+	* mln/accu/center.hh: use a vector of type mln_sum(P::coord) instead
+	of P::vec. Avoid an overflow.
+
 2009-02-09  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
 	Update ICP.
diff --git a/milena/mln/accu/center.hh b/milena/mln/accu/center.hh
index aba9a80..f7caff3 100644
--- a/milena/mln/accu/center.hh
+++ b/milena/mln/accu/center.hh
@@ -73,7 +73,7 @@ namespace mln
       bool is_valid() const;
 
     protected:
-      V center_;
+      algebra::vec<P::dim, mln_sum(mln_coord(P))> center_;
       unsigned nsites_;
     };
 
@@ -87,7 +87,7 @@ namespace mln
 	template <typename P, typename V>
 	struct with
 	{
-	  typedef accu::center<P,V> ret;
+	  typedef accu::center<P, V> ret;
 	};
 
       };
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    09 Feb '09
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-02-09  Edwin Carlinet  <carlinet(a)lrde.epita.fr>
	Try to make algebraic_union_find filter work with new accus.
	* edwin/algebraic_union_find.hh: First version of algebraic
	filter according to new accus.
	* edwin/card.hh: Make card cleaner with MLN_INCLUDE_ONLY.
---
 algebraic_union_find.hh |  417 ++++++++++++++++++++++++++++++++++++++++++++++++
 card.hh                 |   96 ++++++++++-
 2 files changed, 504 insertions(+), 9 deletions(-)
Index: trunk/milena/sandbox/edwin/algebraic_union_find.hh
===================================================================
--- trunk/milena/sandbox/edwin/algebraic_union_find.hh	(revision 0)
+++ trunk/milena/sandbox/edwin/algebraic_union_find.hh	(revision 3328)
@@ -0,0 +1,417 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH
+# define MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH
+
+///
+///
+/// \todo: Doc!
+///
+/// \todo Re-activate the fastest version when accumulators are
+/// cleaned-up.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/accumulator.hh>
+# include <mln/data/fill.hh>
+# include <mln/util/pix.hh>
+
+
+# include <mln/level/sort_psites.hh>
+# include <mln/level/sort_offsets.hh>
+
+# include "accu_trait.hh"
+
+namespace mln
+{
+
+  namespace canvas
+  {
+
+    namespace morpho
+    {
+
+      namespace impl
+      {
+
+	// Generic version.
+
+	namespace generic
+	{
+
+	  template <typename I>
+	  inline
+	  mln_psite(I)
+	  find_root(I& parent, const mln_psite(I)& x)
+	  {
+	    if (parent(x) == x)
+	      return x;
+	    else
+	      return parent(x) = find_root(parent, parent(x));
+	  }
+
+	  template <typename I, typename N, typename S, typename A>
+	  inline
+	  mln_concrete(I)
+	  algebraic_union_find(const Image<I>& input_,
+			       const Neighborhood<N>& nbh_,
+			       const Site_Set<S>& s_,
+			       const Accumulator<A>& accu_,
+			       mln_result(A) lambda)
+	  {
+	    trace::entering("canvas::morpho::impl::generic::algebraic_union_find");
+
+	    // FIXME: Tests?
+
+	    const I& input = exact(input_);
+	    const N& nbh = exact(nbh_);
+
+	    mln_concrete(I) output;
+	    initialize(output, input);
+
+	    // Local type.
+	    typedef mln_psite(I) P;
+
+	    // Auxiliary data.
+	    mln_ch_value(I, bool)  deja_vu;
+	    mln_ch_value(I, bool)  activity;
+	    mln_ch_value(I, P)     parent;
+	    mln_ch_value(I, A)     data;
+
+
+	    // Initialization.
+	    {
+	      initialize(deja_vu, input);
+	      mln::data::fill(deja_vu, false);
+	      initialize(activity, input);
+	      mln::data::fill(activity, true);
+	      initialize(parent, input);
+	      initialize(data, input);
+	    }
+
+	    // First pass.
+	    {
+	      mln_fwd_piter(S) p(s_);
+	      mln_niter(N) n(nbh, p);
+	      for_all(p)
+	      {
+		// Make set.
+		{
+		  parent(p) = p;
+		  /* FIXME: What if the value_type of DATA (i.e., A) were not
+		     based on a accu::count<mln::pix>?  Currently, nothing
+		     enforces this, but the code below expects this line to be
+		     valid:
+
+		     data(p).take_as_init(make::pix(f.input, p))
+
+		     which probably restricts the kind of input images.
+
+		     If we want to be more generic, the initialization should
+		     read something like:
+
+		     init_data(p);
+
+		     i.e., the functor for the initialization of data should
+		     be passed as an argument to the canvas' ctor.
+
+		     Of course, we might want to restrict attributes to the
+		     accumulator accu::count<mln::pix> (which is perfectly
+		     acceptable), but then this class should statically check
+		     the conformance of the template parameter A to this
+		     constraint.  */
+		  data(p).take_as_init(p); // FIXME: algebraic so p!
+		}
+
+		for_all(n)
+		  if (input.domain().has(n) && deja_vu(n))
+		    {
+		      //do_union(n, p);
+		      P r = find_root(parent, n);
+		      if (r != p)
+			{
+			  if (input(r) == input(p) || (activity(r) && data(r) < lambda)) // Equiv(r, p)
+			    // Either a flat zone or the component of r is still growing.
+			    {
+			      /* FIXME: Same remark as above concerning the
+				 initialization of data(p); instead of
+
+				 data(p).take(data(r));
+
+				 we should (or could) have
+
+				 unite_data(p, r);
+
+				 so as to keep the generic aspect of this canvas
+				 (as long as the set of acceptable types for the
+				 template parameter A is not bound).  */
+			      data(p).take(data(r));
+			      parent(r) = p;
+			      if (activity(r) == false)
+				activity(p) = false;
+			    }
+			  else
+			    {
+			      activity(p) = false;
+			    }
+			}
+		    }
+		deja_vu(p) = true;
+	      }
+	    }
+
+	    // Second pass.
+	    {
+	      mln_bkd_piter(S) p(s_);
+	      for_all(p)
+		if (parent(p) == p) // p is root.
+		  output(p) = input(p);
+		else
+		  output(p) = output(parent(p));
+	    }
+
+	    /*
+	      Change 2nd pass into:
+	      for_all(p) if (not is_root(p)) output(p) = output(parent(p));
+	      and add in init:
+	      mln::data::fill(output, input);
+	    */
+	    trace::exiting("canvas::morpho::impl::generic::algebraic_union_find");
+
+	    return output;
+	  }
+
+	} // end of namespace mln::canvas::morpho::impl::generic
+
+
+
+	// Fastest version.
+
+	template <typename I>
+	inline
+	unsigned
+	find_root_fastest(I& parent, unsigned x)
+	{
+	  if (parent.element(x) == x)
+	    return x;
+	  else
+	    return parent.element(x) = find_root_fastest(parent, parent.element(x));
+	}
+
+
+	template <typename I, typename N, typename S, typename A>
+	inline
+	mln_concrete(I)
+	algebraic_union_find_fastest(const Image<I>& input_,
+				     const Neighborhood<N>& nbh_,
+				     const Site_Set<S>& s_,
+				     const Accumulator<A>& accu_,
+				     mln_result(A) lambda)
+	{
+	  trace::entering("canvas::morpho::impl::algebraic_union_find_fastest");
+
+	  // FIXME: Tests?
+
+	  const I& input = exact(input_);
+	  const N& nbh = exact(nbh_);
+
+	  mln_concrete(I) output;
+	  initialize(output, input);
+
+	  // Local type.
+	  typedef mln_psite(I) P;
+
+	  // Auxiliary data.
+	  mln_ch_value(I, bool)  deja_vu;
+	  mln_ch_value(I, bool)  activity;
+	  mln_ch_value(I, unsigned) parent;
+	  mln_ch_value(I, A)     data;
+
+	  // Initialization.
+	  {
+	    initialize(deja_vu, input);
+	    mln::data::fill(deja_vu, false);
+	    initialize(activity, input);
+	    mln::data::fill(activity, true);
+	    initialize(parent, input);
+	    mln::data::fill(parent, 0);
+	    initialize(data, input);
+	  }
+
+	  util::array<int> dp = offsets_wrt(input, nbh);
+	  const unsigned n_nbhs = dp.nelements();
+
+	  const unsigned n_points = s_.nelements();
+
+	  // First pass.
+	  {
+
+	    for (unsigned i = 0; i < n_points; ++i)
+	      {
+		unsigned p = s_[i]; // An offset.
+
+		// Make set.
+		parent.element(p) = p;
+		data.element(p).take_as_init(); // FIXME: Very bad et SEULEMENT POUR CARD !!! C CON!!!
+
+		for (unsigned j = 0; j < n_nbhs; ++j)
+		  {
+		    unsigned n = p + dp[j];
+		    if (! deja_vu.element(n))
+		      continue;
+
+		    unsigned r = find_root_fastest(parent, n);
+		    if (r != p)
+		      {
+			if (input.element(r) == input.element(p)
+			    || (activity.element(r)
+				&& data.element(r) < lambda))
+			  {
+			    data.element(p).take();
+			    parent.element(r) = p;
+			    if (activity.element(r) == false)
+			      activity.element(p) = false;
+			  }
+			else
+			  {
+			    activity.element(p) = false;
+			  }
+		      }
+		  }
+
+		deja_vu.element(p) = true;
+	      }
+
+	  }
+
+	  // Second pass.
+	  {
+	    for (int i = n_points - 1; i >= 0 ; --i)
+	      {
+		unsigned p = s_[i];
+		if (parent.element(p) == p) // p is root.
+		  output.element(p) = input.element(p);
+		else
+		  output.element(p) = output.element(parent.element(p));
+	      }
+	  }
+	  trace::exiting("canvas::morpho::impl::algebraic_union_find_fastest");
+	  return output;
+	}
+
+
+      } // end of namespace mln::canvas::morpho::impl
+
+
+
+      // Dispatch.
+
+      namespace internal
+      {
+	template <typename I, typename N, typename A>
+	inline
+	mln_concrete(I)
+	algebraic_union_find_dispatch(metal::false_,
+				      const Image<I>& input,
+				      const Neighborhood<N>& nbh,
+				      const Accumulator<A>& accu,
+				      mln_result(A) lambda,
+				      bool increasing)
+	{
+	  p_array<mln_psite(I)> s = increasing ?
+	    level::sort_psites_increasing(input) :
+	    level::sort_psites_decreasing(input);
+	  return impl::generic::algebraic_union_find(input, nbh, s, accu,
+						     lambda);
+	}
+
+	template <typename I, typename N, typename A>
+	inline
+	mln_concrete(I)
+	algebraic_union_find_dispatch(metal::true_,
+				      const Image<I>& input,
+				      const Neighborhood<N>& nbh,
+				      const Accumulator<A>& accu,
+				      mln_result(A) lambda,
+				      bool increasing)
+	{
+	  util::array<unsigned> s = increasing ?
+	    level::sort_offsets_increasing(input) :
+	    level::sort_offsets_decreasing(input);
+	  return impl::algebraic_union_find_fastest(input, nbh, s, accu, lambda);
+	}
+
+	template <typename I, typename N, typename A>
+	inline
+	mln_concrete(I)
+	algebraic_union_find_dispatch(const Image<I>& input,
+				      const Neighborhood<N>& nbh,
+				      const Accumulator<A>& accu,
+				      mln_result(A) lambda,
+				      bool increasing)
+	{
+	  enum {
+	    test = (mlc_equal(mln_trait_image_speed(I),
+			      trait::image::speed::fastest)::value &&
+		    mln_is_simple_neighborhood(N)::value &&
+		    mlc_equal(mln_trait_accu_when_pix(A),
+			      trait::accu::when_pix::use_whatever)::value)
+	  };
+	  return algebraic_union_find_dispatch(metal::bool_<test>(), input, nbh,
+					       accu, lambda, increasing);
+	}
+
+      } // end of namespace mln::canvas::morpho::internal
+
+
+
+      // Facade.
+
+      template <typename I, typename N, typename A>
+      inline
+      mln_concrete(I)
+      algebraic_union_find(const Image<I>& input,
+			   const Neighborhood<N>& nbh,
+			   const Accumulator<A>& accu,
+			   mln_result(A) lambda,
+			   bool increasing)
+      {
+	return internal::algebraic_union_find_dispatch(input, nbh, accu,
+						       lambda, increasing);
+      }
+
+
+    } // end of namespace mln::canvas::morpho
+
+  } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH
Index: trunk/milena/sandbox/edwin/card.hh
===================================================================
--- trunk/milena/sandbox/edwin/card.hh	(revision 3327)
+++ trunk/milena/sandbox/edwin/card.hh	(revision 3328)
@@ -15,23 +15,101 @@
       {
 	typedef mln_psite(I) argument;
 
-	card () { init(); };
-	void init () { c_ = 0; };
+	card ();
+	void init ();
 
-	void take (const card<I>& accu) { c_ += accu.c_; };
+	void take (const card<I>& accu);
 
-	void take () { ++c_; };
-	void take (const mln_psite(I)& elt) { ++c_; };
-	void take (const mln_value(I)& elt) { ++c_; };
-	void take (const util::pix<I>& pix) { ++c_; };
+	void take ();
+	void take (const mln_psite(I)& elt);
+	void take (const mln_value(I)& elt);
+	void take (const util::pix<I>& pix);
 
-	unsigned to_result() const { return c_; };
+	unsigned to_result() const;
 
-	bool is_valid () const { return true; };
+	bool is_valid () const;
 
       private:
 	unsigned c_;
       };
+
+# ifndef MLN_INCLUDE_ONLY
+      template <typename I>
+      inline
+      card<I>::card () :
+	c_ (0)
+      {
+      }
+
+      template <typename I>
+      inline
+      void
+      card<I>::init ()
+      {
+	c_ = 0;
+      }
+
+      template <typename I>
+      inline
+      void
+      card<I>::take (const card<I>& accu)
+      {
+	c_ += accu.c_;
+      }
+
+
+      template <typename I>
+      inline
+      void
+      card<I>::take ()
+      {
+	++c_;
+      };
+
+      template <typename I>
+      inline
+      void
+      card<I>::take (const mln_psite(I)& elt)
+      {
+	++c_;
+      };
+
+
+      template <typename I>
+      inline
+      void
+      card<I>::take (const mln_value(I)& elt)
+      {
+	++c_;
+      };
+
+
+      template <typename I>
+      inline
+      void
+      card<I>::take (const util::pix<I>& pix)
+      {
+	++c_;
+      };
+
+      template <typename I>
+      inline
+      unsigned
+      card<I>::to_result() const
+      {
+	return c_;
+      };
+
+      template <typename I>
+      inline
+      bool
+      card<I>::is_valid () const
+      {
+	return true;
+      };
+# endif
+
+
     } // mln::morpho::accu
   } // mln::morpho
 } // mln
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                          URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-02-09  Fabien Freling  <freling(a)lrde.epita.fr>
	New IGR test files.
	* fabien/igr/igr.cc: New test file.
	* fabien/igr/img/slice_7.pgm: New test picture.
---
 igr.cc |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
Index: trunk/milena/sandbox/fabien/igr/igr.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/igr.cc	(revision 0)
+++ trunk/milena/sandbox/fabien/igr/igr.cc	(revision 3326)
@@ -0,0 +1,102 @@
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/labeling/flat_zones.hh>
+
+#include <mln/labeling/blobs.hh>
+#include <mln/labeling/compute.hh>
+#include <mln/level/compare.hh>
+#include <mln/fun/v2b/threshold.hh>
+#include <mln/level/transform.hh>
+#include <mln/accu/count.hh>
+#include <mln/value/label_8.hh>
+#include <mln/data/fill.hh>
+#include <mln/pw/all.hh>
+
+//FIXME: remove
+#include <mln/essential/2d.hh>
+
+//struct threshold : Function_v2v<threshold>
+//{
+//  typedef bool result;
+//  bool operator() (int_u8 val) const {if (val < 25) return false; return true;}
+//};
+
+int main()
+{
+  using namespace mln;
+  using value::int_u8;
+  using value::label_8;
+
+  trace::quiet = false;
+
+  image2d<int_u8> src;
+  io::pgm::load(src, "img/slice_7.pgm");
+
+  image2d<bool> threshold = level::transform(src, fun::v2b::threshold<int_u8>(25));
+
+  label_8 n;
+  image2d<label_8> labels = labeling::flat_zones(threshold, c4(), n);
+  accu::count<int_u8> a_;
+  util::array<unsigned> a = labeling::compute(a_, src, labels, n);
+
+  mln_ch_value_(image2d<int_u8>, bool) biggest;
+  initialize(biggest, src);
+  data::fill(biggest, false);
+  unsigned x = 0;
+  unsigned y = 0;
+  unsigned z = 0;
+  for (int i = 0; i < a.nelements(); ++i)
+  {
+    if (a[i] > x)
+      x = a[i];
+    if (x > y)
+    {
+      int swap = y;
+      y = x;
+      x = swap;
+    }
+    if (y > z)
+    {
+      int swap = z;
+      z = y;
+      y = swap;
+    }
+  }
+  data::fill((biggest | pw::value(labels) == x).rw(), true);
+  data::fill((biggest | pw::value(labels) == y).rw(), true);
+
+  // gradient_internal, center
+
+  io::pbm::save(biggest, "out.pgm");
+}
Index: trunk/milena/sandbox/fabien/igr/img/slice_7.pgm
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/milena/sandbox/fabien/igr/img/slice_7.pgm
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* mln/registration/icp2.hh: add a better debug. Revamp and remove
	useless overloads.
---
 milena/ChangeLog                |    7 +
 milena/mln/registration/icp2.hh |  269 +++++++++++++++++++--------------------
 2 files changed, 138 insertions(+), 138 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 9d32600..3d3cca5 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,10 @@
+2009-02-09  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Update ICP.
+
+	* mln/registration/icp2.hh: add a better debug. Revamp and remove
+	useless overloads.
+
 2009-02-09  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
 
 	Optimize the video labeling canvas.
diff --git a/milena/mln/registration/icp2.hh b/milena/mln/registration/icp2.hh
index 1c83c25..1a6f331 100644
--- a/milena/mln/registration/icp2.hh
+++ b/milena/mln/registration/icp2.hh
@@ -31,6 +31,8 @@
 /// \file mln/registration/icp.hh
 ///
 /// Register an image over an another using the ICP algorithm.
+///
+/// \todo encode distances on 12 bits.
 
 # include <cmath>
 # include <algorithm>
@@ -61,7 +63,6 @@
 # include <mln/literal/colors.hh>
 
 # include <mln/core/image/slice_image.hh>
-# include <mln/util/timer.hh>
 
 #include <mln/core/image/tr_image.hh>
 #include <mln/core/image/extension_fun.hh>
@@ -70,6 +71,7 @@
 #include <mln/accu/sum.hh>
 #include <mln/debug/histo.hh>
 
+# include <mln/util/timer.hh>
 
 namespace mln
 {
@@ -77,7 +79,8 @@ namespace mln
 
   namespace registration
   {
-
+        //  std::string method = "compute_on_subsets";
+    std::string method = "compute_on_subset_and_p";
     using namespace fun::x2x;
 
     /*! Register point in \p c using a function of closest points
@@ -127,15 +130,15 @@ namespace mln
     {
       typedef mln_image_from_grid(mln_grid(P), P) I;
       typedef mln_ch_value(I, P) cp_ima_t;
-      typedef mln_ch_value(I,value::int_u8) dmap_t;
+      typedef mln_ch_value(I,value::int_u16) dmap_t;
 
     public:
 
       closest_point_with_map(const p_array<P>& X)
       {
 	box3d box = geom::bbox(X);
-	box.enlarge(1, box.nrows() / 2);
-	box.enlarge(2, box.ncols() / 2);
+	box.enlarge(1, box.nrows());
+	box.enlarge(2, box.ncols());
 	std::cout << "Map image defined on " << box << std::endl;
 
 	typedef mln_ch_value(I, bool) model_t;
@@ -147,13 +150,13 @@ namespace mln
 	util::timer t;
 	t.start();
 	dmap_X_ = canvas::distance_geodesic(model, c6(),
-					    mln_max(value::int_u8),
+					    mln_max(value::int_u16),
 					    f);
 	std::cout << "canvas::distance_geodesic - " << t << "s" << std::endl;
 
 	cp_ima_ = f.cp_ima;
 
-#ifndef NDEBUG
+//#ifndef NDEBUG
 	mln_ch_value(I, bool) debug2(box);
 	data::fill(debug2, false);
 	mln_ch_value(I, value::rgb8) debug(box);
@@ -175,7 +178,7 @@ namespace mln
 	io::pbm::save(slice(debug2,0), "debug2-b.ppm");
 	io::ppm::save(slice(debug,0), "debug.ppm");
 	std::cout << "map saved" << std::endl;
-#endif
+//#endif
       }
 
       mln_site(I) operator()(const mln_site(I)& p) const
@@ -278,19 +281,58 @@ namespace mln
 
 
     template <typename P, typename F>
-    p_array<P>
-    remove_too_far_sites(image3d<value::rgb8>& out, const p_array<P>& P_,
+    void
+    remove_too_far_sites_debug(image3d<value::rgb8>& out, const p_array<P>& P_,
 			 const F& closest_point,
 			 const std::pair<algebra::quat,mln_vec(P)>& pair,
-			 const p_array<P>& X, p_array<P>& removed_set,
-			 unsigned r)
+			 const p_array<P>& X,
+			 unsigned r, int d_min, int d_max, unsigned prefix)
+    {
+      unsigned removed = 0;
+      accu::histo<value::int_u8> h;
+      mln_piter(p_array<P>) p(P_);
+      data::fill(out, literal::black);
+      data::fill((out | X).rw(), literal::white);
+
+      for_all(p)
+      {
+	vec3d_f Pk_i = pair.first.rotate(p.to_vec()) + pair.second;
+	vec3d_f Yk_i = closest_point(Pk_i).to_vec();
+
+	int d_i = closest_point.dmap_X_(Pk_i);
+	if (d_i >= d_min && d_i <= d_max)
+	  out(Pk_i) = literal::green;
+	else
+	{
+	  ++removed;
+	  out(Pk_i) = literal::red;
+	}
+      }
+
+      std::ostringstream ss1;
+      ss1 << "histo_" << prefix << r << ".dat";
+//      debug::histo_plot(h, ss1.str());
+      std::cout << h << std::endl;
+
+      std::ostringstream ss2;
+      ss2 << "out_" << prefix << r << ".ppm";
+      io::ppm::save(mln::slice(out,0), ss2.str());
+
+      std::cout << "Points removed with the whole set and current d_min/d_max: " << removed << std::endl;
+
+    }
+
+    template <typename P, typename F>
+    void
+    compute_distance_criteria(const p_array<P>& P_,
+			 const F& closest_point,
+			 const std::pair<algebra::quat,mln_vec(P)>& pair,
+			 unsigned r, int& d_min, int& d_max)
     {
       mln_piter(p_array<P>) p(P_);
       accu::histo<value::int_u8> h;
-//       float sd = compute_standard_deviation(P_, pair, closest_point);
 
       float sd;
-      int d_min, d_max;
       {
 	accu::sum<float> s, s2;
 	for_all(p)
@@ -306,17 +348,31 @@ namespace mln
 	d_min = int(mean - sd);
 	d_max = int(mean + sd);
       }
-      
 
       std::cout << "Standard deviation = " << sd << std::endl;
+      std::ostringstream ss1;
+      ss1 << "histo_" << r << ".dat";
+      debug::histo_plot(h, ss1.str());
+      std::cout << h << std::endl;
       std::cout << "d thresholds = " << d_min << ' ' << d_max << std::endl;
+    }
 
+    template <typename P, typename F>
+    p_array<P>
+    remove_too_far_sites(image3d<value::rgb8>& out, const p_array<P>& P_,
+			 const F& closest_point,
+			 const std::pair<algebra::quat,mln_vec(P)>& pair,
+			 const p_array<P>& X, p_array<P>& removed_set,
+			 unsigned r, int d_min, int d_max,
+			 const std::string& method)
+    {
       p_array<P> tmp;
       unsigned removed = 0;
 
-      data::fill(out, literal::white);
-      data::fill((out | X).rw(), literal::black);
+      data::fill(out, literal::black);
+      data::fill((out | X).rw(), literal::white);
 
+      mln_piter(p_array<P>) p(P_);
       for_all(p)
       {
 	vec3d_f Pk_i = pair.first.rotate(p.to_vec()) + pair.second;
@@ -336,13 +392,8 @@ namespace mln
 	}
       }
 
-      std::ostringstream ss1;
-      ss1 << "histo_" << r << ".dat";
-      debug::histo_plot(h, ss1.str());
-      std::cout << h << std::endl;
-
       std::ostringstream ss2;
-      ss2 << "out_0" << r << ".ppm";
+      ss2 << method << "_" << r << "_removed_sites" << ".ppm";
       io::ppm::save(mln::slice(out,0), ss2.str());
 
       std::cout << "Points removed: " << removed << std::endl;
@@ -350,6 +401,37 @@ namespace mln
       return tmp;
     }
 
+    template <typename P>
+    void
+    display_sites_used_in_icp(image3d<value::rgb8>& out, const p_array<P>& P_sub,
+			      const p_array<P>& P_, const p_array<P>& X,
+			      unsigned r, const std::string& prefix,
+			      const std::pair<algebra::quat,mln_vec(P)>& pair,
+			      const std::string& period, const value::rgb8& c)
+    {
+      data::fill(out, literal::black);
+      data::fill((out | X).rw(), literal::white);
+
+      mln_piter(p_array<P>) p1(P_);
+      for_all(p1)
+      {
+	vec3d_f Pk_i = pair.first.rotate(p1.to_vec()) + pair.second;
+	out(Pk_i) = literal::red;
+      }
+
+      mln_piter(p_array<P>) p2(P_sub);
+      for_all(p2)
+      {
+	vec3d_f Pk_i = pair.first.rotate(p2.to_vec()) + pair.second;
+	out(Pk_i) = c;
+      }
+
+      std::ostringstream ss;
+      ss << prefix << "_" << r << "_" << period << ".ppm";
+
+      io::ppm::save(slice(out,0), ss.str());
+    }
+
 
     template <typename P, typename F>
     inline
@@ -591,85 +673,18 @@ namespace mln
       return result;
     }
 
-
-    /// Shuffle the sites in P_.
-    /// Use one third of P_'s sites for each run.
-    /// For each run, it removes sites which are too close or too far.
-    template <typename P, typename F>
-    inline
-    composed< translation<P::dim,float>,rotation<P::dim,float> >
-    icp_clean(const p_array<P>& P_,
-	      const p_array<P>& X,
-	      const F& closest_point)
-    {
-      util::timer t;
-      t.start();
-
-      // P_bak is shuffled.
-      p_array<P> P_bak = P_;
-      std::vector<mln_element(p_array<P>)>& v = P_bak.hook_std_vector_();
-      std::random_shuffle(v.begin(), v.end());
-
-      // P_sub = 1/3 * P_bak;
-      p_array<P> P_sub = P_bak;
-      P_sub.hook_std_vector_().resize(P_bak.nsites() / 3);
-
-      unsigned r = 0;
-      std::pair<algebra::quat,mln_vec(P)> pair;
-      pair.first = algebra::quat(1,0,0,0);
-      pair.second = literal::zero;
-      box3d box = geom::bbox(X);
-      box.enlarge(40);
-      image3d<value::rgb8> out(box);
-      p_array<P> removed_set;
-      do
-      {
-	/// Compute transformation.
-	pair = icp(P_sub, X, closest_point,
-		   pair.first,
-		   pair.second);
-
-	pair = icp(P_sub, X, closest_point,
-		   pair.first,
-		   pair.second);
-
-	P_sub = remove_too_far_sites(out, P_sub,
-				     closest_point, pair, X, removed_set, r);
-
-
-	++r;
-
-	//Add more data
-	if (r < 3)
-	  for (unsigned i = (P_bak.nsites() / 3) * r;
-	      i < (P_bak.nsites() / 3) * (r + 1); ++i)
-	  {
-	    P_sub.append(P_bak[i]);
-	  }
-
-      } while (r < 4);
-      std::cout << "icp = " << t << std::endl;
-
-      typedef rotation<3u,float> rot_t;
-      rot_t tqR(pair.first);
-      typedef translation<3u,float> trans_t;
-      trans_t tqT(pair.second);
-      composed<trans_t,rot_t> result(tqT, tqR);
-
-      return result;
-    }
-
-
     /// Shuffle sites in P_.
     /// Do the first run with all sites.
     /// For each run, remove sites which are too far or too close.
-    template <typename P, typename F>
+    template <typename P>
     inline
     composed< translation<P::dim,float>,rotation<P::dim,float> >
-    icp_clean2(const p_array<P>& P_,
-	      const p_array<P>& X,
-	      const F& closest_point)
+    registration(const p_array<P>& P_,
+		 const p_array<P>& X)
     {
+      registration::closest_point_with_map<P> closest_point(X);
+//  registration::closest_point_basic<point3d> closest_point(X);
+
       util::timer t;
       t.start();
 
@@ -681,21 +696,38 @@ namespace mln
       pair.first = algebra::quat(1,0,0,0);
       pair.second = literal::zero;
       box3d box = geom::bbox(X);
-      box.enlarge(40);
+      box.enlarge(1, 60);
+      box.enlarge(2, 60);
       image3d<value::rgb8> out(box);
       p_array<P> removed_set;
+
       do
       {
+	std::cout << std::endl << std::endl << "==== New run - " << r << std::endl;
 	pair = icp(P_bak, X, closest_point,
 		   pair.first,
 		   pair.second);
 
+	display_sites_used_in_icp(out, P_bak, P_, X, r, method, pair, "final", literal::blue);
+
+	int d_min, d_max;
+	compute_distance_criteria(P_bak, closest_point, pair, r, d_min, d_max);
+
 	P_bak = remove_too_far_sites(out, P_bak,
-				     closest_point, pair, X, removed_set, r);
+				     closest_point, pair, X, removed_set,
+				     r, d_min, d_max, method);
+
+//	P_bak = remove_too_far_sites(out, P_,
+//				     closest_point, pair, X, removed_set,
+//				     r, d_min, d_max, method);
+
+
+	display_sites_used_in_icp(out, P_bak, P_, X, r, method, pair, "schanges", literal::green);
 
 	++r;
 
-      } while (r < 4);
+	std::cout << "==== End of run" << std::endl;
+      } while (r < 10);
       std::cout << "icp = " << t << std::endl;
 
       draw_last_run(box, P_bak, removed_set, X, pair.first, pair.second);
@@ -710,45 +742,6 @@ namespace mln
     }
 
 
-
-    /// Run icp once with 1/10 of the sites and run it once again with the
-    /// resulting tranformation and all the sites.
-    template <typename P, typename F>
-    inline
-    composed< translation<P::dim,float>,rotation<P::dim,float> >
-    icp_fast(const p_array<P>& P_,
-	     const p_array<P>& X,
-	     const F& closest_point)
-    {
-      typedef std::pair<algebra::quat,mln_vec(P)> pair_t;
-
-      p_array<P> P_sub = P_;
-      std::vector<mln_element(p_array<P>)>& v = P_sub.hook_std_vector_();
-      std::random_shuffle(v.begin(), v.end());
-      v.resize(P_.nsites() / 10);
-
-      util::timer t;
-      t.start();
-      pair_t tmp = icp(P_sub, X, closest_point,
-		     algebra::quat(1,0,0,0), literal::zero);
-
-      std::cout << "icp_1 - " << t << "s" << std::endl;
-      t.restart();
-
-      pair_t tmp2 = icp(P_, X, closest_point,
-			tmp.first, tmp.second);
-
-      std::cout << "icp_2 - " << t << "s" << std::endl;
-
-      typedef rotation<3u,float> rot_t;
-      rot_t tqR(tmp2.first);
-      typedef translation<3u,float> trans_t;
-      trans_t tqT(tmp2.second);
-      composed<rot_t,trans_t> result(tqR, tqT);
-
-      return result;
-    }
-
 # endif // ! MLN_INCLUDE_ONLY
 
   } // end of namespace mln::registration
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* lazzara/igr.cc: update code. More debug.
	* lazzara/igr-cloud.cc: new. Register clouds of points.
	* lazzara/irm_seg_with_mm_and_rag.mine.cc: new. Segment using
	meyer_wst and register clouds of points.
---
 milena/sandbox/ChangeLog                           |   11 +
 milena/sandbox/lazzara/igr-cloud.cc                |   61 ++++
 milena/sandbox/lazzara/igr.cc                      |  297 ++++++++----------
 .../lazzara/irm_seg_with_mm_and_rag.mine.cc        |  331 ++++++++++++++++++++
 4 files changed, 533 insertions(+), 167 deletions(-)
 create mode 100644 milena/sandbox/lazzara/igr-cloud.cc
 create mode 100644 milena/sandbox/lazzara/irm_seg_with_mm_and_rag.mine.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index f82dab8..0e61ceb 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,14 @@
+2009-02-09  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Update igr's code.
+
+      	* lazzara/igr.cc: update code. More debug.
+
+	* lazzara/igr-cloud.cc: new. Register clouds of points.
+
+	* lazzara/irm_seg_with_mm_and_rag.mine.cc: new. Segment using
+	meyer_wst and register clouds of points.
+
 2009-02-09  Fabien Freling  <freling(a)lrde.epita.fr>
 
 	Implement fastest versions of labeling.
diff --git a/milena/sandbox/lazzara/igr-cloud.cc b/milena/sandbox/lazzara/igr-cloud.cc
new file mode 100644
index 0000000..18d976f
--- /dev/null
+++ b/milena/sandbox/lazzara/igr-cloud.cc
@@ -0,0 +1,61 @@
+# include <cmath>
+# include <algorithm>
+
+# include <mln/core/alias/vec3d.hh>
+# include <mln/math/jacobi.hh>
+# include <mln/fun/x2x/all.hh>
+# include <mln/fun/x2v/all.hh>
+# include <mln/convert/to.hh>
+# include <mln/accu/compute.hh>
+# include <mln/accu/center.hh>
+# include <mln/accu/rms.hh>
+# include <mln/trait/image_from_grid.hh>
+# include <mln/set/compute.hh>
+
+//Should be removed when closest_point functors are moved.
+# include <mln/core/alias/neighb3d.hh>
+# include <mln/transform/internal/closest_point_functor.hh>
+# include <mln/canvas/distance_geodesic.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/io/ppm/save.hh>
+# include <mln/io/pbm/save.hh>
+# include <mln/debug/colorize.hh>
+
+# include <mln/literal/black.hh>
+# include <mln/literal/white.hh>
+# include <mln/literal/colors.hh>
+
+# include <mln/core/image/slice_image.hh>
+# include <mln/util/timer.hh>
+
+#include <mln/core/image/tr_image.hh>
+#include <mln/core/image/extension_fun.hh>
+
+#include <mln/accu/histo.hh>
+#include <mln/accu/sum.hh>
+#include <mln/debug/histo.hh>
+#include <mln/io/cloud/load.hh>
+
+#include <mln/registration/icp2.hh>
+
+int main(int, char *argv[])
+{
+  using namespace mln;
+  using namespace fun::x2x;
+  using value::rgb8;
+  using value::int_u8;
+  using value::label_16;
+
+  //Load image
+  typedef image3d<bool> K;
+
+  p_array<point3d> in_3d_, ref_3d_;
+  io::cloud::load(in_3d_, argv[1]);
+  io::cloud::load(ref_3d_, argv[2]);
+
+  typedef rotation<3u,float> rot_t;
+  typedef translation<3u,float> trans_t;
+  composed<trans_t,rot_t> qk = registration::registration(in_3d_, ref_3d_);
+
+}
diff --git a/milena/sandbox/lazzara/igr.cc b/milena/sandbox/lazzara/igr.cc
index 05d8471..0df1d92 100644
--- a/milena/sandbox/lazzara/igr.cc
+++ b/milena/sandbox/lazzara/igr.cc
@@ -16,6 +16,10 @@
 
 #include <mln/io/cloud/load.hh>
 #include <mln/util/timer.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/trait/ch_value.hh>
+
+#include <mln/fun/p2b/big_chess.hh>
 
 struct threshold : mln::Function_p2b<threshold>
 {
@@ -29,130 +33,10 @@ struct threshold : mln::Function_p2b<threshold>
 namespace mln
 {
 
-  using namespace fun::x2x;
-
-    template <typename P>
-    struct transf_quat_t
-    {
-      transf_quat_t()
-	: q_(1,0,0,0), t_(literal::zero)
-      {
-      }
-
-
-      inline
-	float epsilon()
-	{
-	  static const float e = 1e-5;
-	  return e;
-	}
-
-      inline
-	bool about_equal(float val1, float val2)
-	{
-	  return fabs(val1 - val2) < epsilon();
-	}
-
-      template <unsigned n>
-	algebra::vec<n,float> rotate(const algebra::quat& q, const algebra::vec<n,float>& p)
-	{
-	  return (q * algebra::quat(0. ,p) * q.inv()).v();
-	}
-
-
-      bool check_rotation(const algebra::h_mat<3,float>& mat, const algebra::quat& q)
-      {
-	srand(time(0));
-	assert(q.is_unit());
-	rotation<3,float> rot(mat);
-
-	algebra::vec<3,float>
-	  tmp = make::vec(rand(), rand(), rand()),
-	      p = tmp / norm::l2(tmp),
-	      p_rot_1 = rotate(q, p),
-	      p_rot_2 = rot(p);
-	return about_equal(norm::l2(p_rot_1 - p_rot_2), 0.f);
-      }
-
-
-      transf_quat_t(const algebra::quat& q, const vec3d_f& t)
-	: q_(q), t_(t)
-      {
-	assert(q.is_unit());
-	float
-	  w = q.to_vec()[0],
-	    x = q.to_vec()[1],  x2 = 2*x*x,  xw = 2*x*w,
-	    y = q.to_vec()[2],  y2 = 2*y*y,  xy = 2*x*y,  yw = 2*y*w,
-	    z = q.to_vec()[3],  z2 = 2*z*z,  xz = 2*x*z,  yz = 2*y*z,  zw = 2*z*w;
-	float data[9] = {1.f - y2 - z2,  xy - zw,  xz + yw,
-	  xy + zw,  1.f - x2 - z2,  yz - xw,
-	  xz - yw,  yz + xw,  1.f - x2 - y2};
-
-	algebra::h_mat<3,float> tmp = make::h_mat(data);
-	std::cout << tmp << std::endl;
-	// postcondition
-	assert(check_rotation(tmp, q));
-      }
-
-      void
-      set_quat(const algebra::quat& q)
-      {
-	q_ = q;
-      }
-
-
-      void
-      set_trans(const vec3d_f& t)
-      {
-	t_ = t;
-      }
-
-      algebra::vec<P::dim,float>
-      operator()(const algebra::vec<P::dim,float>& v) const
-      {
-	return (q_ * algebra::quat(0., v) * q_.inv()).v() + t_;
-      }
-
-      algebra::quat q_;
-      vec3d_f t_;
-    };
-
-
-    template <typename P>
-    struct transf_mat_t
-    {
-      typedef rotation<P::dim,float> rot_t;
-      typedef translation<P::dim,float> trans_t;
-
-      transf_mat_t() {}
-      transf_mat_t(const algebra::quat& q, const vec3d_f& t)
-	: r_(q), t_(t), c_(r_, t_)
-      {
-      }
-
-      void
-      set_quat(const algebra::quat& q)
-      {
-	r_ = rot_t(q);
-      }
-
-      void
-      set_trans_(const vec3d_f& t)
-      {
-	t_ = trans_t(t);
-      }
-
-      algebra::vec<P::dim,float>
-      operator()(const algebra::vec<P::dim,float>& v) const
-      {
-	return c_(v);
-      }
-
-      rot_t r_;
-      trans_t t_;
-      composed<rot_t, trans_t> c_;
-    };
-
+  namespace registration
+  {
+    extern std::string method;
+  }
 
 }
 
@@ -240,18 +124,16 @@ get_main_object_shape(const mln::Image<I>& in)
 
   typedef image2d<bool> J;
 
-//  threshold f;
-//  J in_bw = binarization::binarization(in, f);
-//  io::pbm::save(in_bw, "01_in_bw.pbm");
+  threshold f;
+  J in_bw = binarization::binarization(in, f);
+  io::pbm::save(in_bw, "01_in_bw.pbm");
 
-//  J ima = keep_largest_component(in_bw);
-  J ima = keep_largest_component(in);
-//  io::pbm::save(in_bw, "02_ima.pbm");
-  io::pbm::save(in, "ima.pbm");
+  J ima = keep_largest_component(in_bw);
+//  J ima = keep_largest_component(in);
+  io::pbm::save(ima, "02_ima.pbm");
 
   std::cout << "Compute gradient" << std::endl;
   J ima_grad = morpho::gradient(ima, win_c4p());
-  io::pbm::save(ima_grad, "ima_grad.pbm");
 
   return ima_grad;
 }
@@ -262,31 +144,87 @@ namespace mln
 
   namespace debug
   {
+
     template <typename I, typename T>
-    void
-    compare_registration(Image<I>& P_, Image<I>& X_, const T& transf)
+    image3d<value::rgb8>
+    make_registered_image(Image<I>& P_, Image<I>& X_, const T& transf)
     {
       I& P = exact(P_);
       I& X = exact(X_);
 
       mln_pset(I) box = geom::bbox(X);
-      box.enlarge(40);
+      box.enlarge(1, 60);
+      box.enlarge(2, 60);
 
       typedef mln_ch_value(I,value::rgb8) result_t;
       result_t result(box);
       extension_fun<result_t,pw::cst_<mln_value(result_t)> > ext_result(result, pw::cst(value::rgb8(0,0,0)));
       extension_fun<I,pw::cst_<mln_value(I)> > ext_X(X, pw::cst(false));
-
       data::fill(ext_result, literal::black);
-      data::fill((ext_result | (pw::value(ext_X) == true)).rw(), literal::white);
 
       mln_VAR(ig, (P | pw::value(P) == true));
       mln_piter(ig_t) p(ig.domain());
       for_all(p)
 	ext_result(transf(p.to_vec())) = literal::green;
 
-      io::ppm::save(slice(ext_result,0), "registered-1.ppm");
+      return ext_result;
     }
+
+    template <typename I, typename J>
+    void
+    compare_registration(Image<I>& registered_, Image<J>& X_)
+    {
+      I& registered = exact(registered_);
+      J& X = exact(X_);
+
+      typedef mln_ch_value(I,value::rgb8) result_t;
+      result_t result;
+      initialize(result, registered);
+      extension_fun<J,pw::cst_<mln_value(J)> > ext_X(X, pw::cst(false));
+
+      data::fill(result, literal::black);
+      data::fill((result | (pw::value(ext_X) == true)).rw(), literal::white);
+      data::fill((result | (pw::value(registered) != pw::cst(literal::black))).rw(),
+		 literal::green);
+
+      io::ppm::save(slice(result,0), "final_registered.ppm");
+    }
+
+
+
+    template <typename I, typename T>
+    void
+    compare_registration2(Image<I>& P_, Image<I>& X_,
+			  const T& transf)
+    {
+      I& P = exact(P_);
+      const I& X = exact(X_);
+
+      typedef extension_fun<I,pw::cst_<mln_value(I)> > ext_P_t;
+      ext_P_t ext_P(P, pw::cst(value::rgb8(literal::black)));
+      tr_image<box3d, ext_P_t, T> trima(P.domain(), ext_P, transf);
+      io::ppm::save(slice(trima, 0), "trima.ppm");
+
+      I reg(X.domain());
+      data::fill(reg, literal::black);
+      mln_piter(I) p(P.domain());
+      for_all(p)
+	if (reg.domain().has(transf(p.to_vec())))
+	  reg(transf(p.to_vec())) = P(p);
+      io::ppm::save(slice(reg,0), "registered-2.ppm");
+
+      I tmp2 = duplicate(X);
+      fun::p2b::big_chess<box3d> fun2(tmp2.domain(), 20);
+      data::paste((reg | fun2), tmp2);
+      io::ppm::save(slice(tmp2,0), "registration_filter-a.ppm");
+
+      I tmp = duplicate(X);
+      fun::p2b::big_chess<box3d> fun(tmp.domain(), 20);
+      data::paste((trima | fun), tmp);
+
+      io::ppm::save(slice(tmp,0), "registration_filter.ppm");
+    }
+
   }
 }
 
@@ -302,42 +240,67 @@ int main(int, char* argv[])
   //Load image
   typedef image2d<rgb8> I;
   typedef image2d<bool> J;
-
-//  I in;
-//  J in;
-//  io::pbm::load(in, argv[1]);
-//  J in_grad = get_main_object_shape(in);
-
-//  I ref;
-//  J ref;
-//  io::pbm::load(ref, argv[2]);
-//  J ref_grad = get_main_object_shape(ref);
-
   typedef image3d<bool> K;
-
-  p_array<point3d> in_3d_, ref_3d_;
-  io::cloud::load(in_3d_, argv[1]);
-  io::cloud::load(ref_3d_, argv[2]);
-
-  std::cout << "* loading data" << std::endl;
-  std::cout << "    igr.cc - in_3d_.nsites = " << in_3d_.nsites() << std::endl;
-  std::cout << "    igr.cc - ref_3d_.nsites = " << ref_3d_.nsites() << std::endl;
-  K in_3d = convert::to<K>(in_3d_);
-  K ref_3d = convert::to<K>(ref_3d_);
-
-  registration::closest_point_with_map<point3d> closest_point(ref_3d_);
-//  registration::closest_point_basic<point3d> closest_point(ref_3d_);
-
+  typedef image3d<value::rgb8> L;
+
+  I in;
+  io::ppm::load(in, argv[1]);
+  J in_obj = get_main_object_shape(in);
+  io::pbm::save(in_obj, "in_obj.pbm");
+
+  I ref;
+  io::ppm::load(ref, argv[2]);
+  J ref_obj = get_main_object_shape(ref);
+  io::pbm::save(ref_obj, "ref_obj.pbm");
+
+//  p_array<point3d> in_3d_, ref_3d_;
+//  io::cloud::load(in_3d_, argv[1]);
+//  io::cloud::load(ref_3d_, argv[2]);
+//
+//  std::cout << "* loading data" << std::endl;
+//  std::cout << "    igr.cc - in_3d_.nsites = " << in_3d_.nsites() << std::endl;
+//  std::cout << "    igr.cc - ref_3d_.nsites = " << ref_3d_.nsites() << std::endl;
+//  K in_3d = convert::to<image3d<bool> >(in_3d_);
+//  K ref_3d = convert::to<image3d<bool> >(ref_3d_);
+//  io::pbm::save(slice(in_3d,0), "in_shape.ppm");
+//  io::pbm::save(slice(ref_3d,0), "ref_shape.ppm");
+//  K in = duplicate(in_3d);
+//  K ref = duplicate(ref_3d);
+
+  K in_3d = make::image3d(in_obj);
+  K ref_3d = make::image3d(ref_obj);
+  std::cout << "    igr.cc - in_3d.nsites = " << in_3d.nsites() << std::endl;
+  std::cout << "    igr.cc - ref_3d.nsites = " << ref_3d.nsites() << std::endl;
+
+  typedef p_array<point3d> p_arr_t;
+  p_arr_t in_3d_ = convert::to<p_arr_t>(in_3d);
+  p_arr_t ref_3d_ = convert::to<p_arr_t>(ref_3d);
+
+
+/// Add objects shapes in original images.
+  L in_wborders = make::image3d(duplicate(in));
+  data::fill((in_wborders | in_3d_).rw(), literal::green);
+  io::ppm::save(slice(in_wborders,0), "in_with_borders.ppm");
+
+  L ref_wborders = make::image3d(duplicate(ref));
+  data::fill((ref_wborders | ref_3d_).rw(), literal::green);
+  io::ppm::save(slice(ref_wborders,0), "ref_with_borders.ppm");
+
+
+
+  // Starting registration.
   util::timer t;
   t.start();
-
   typedef rotation<3u,float> rot_t;
   typedef translation<3u,float> trans_t;
-  composed<trans_t,rot_t> qk = registration::icp_clean2(in_3d_, ref_3d_, closest_point);
+  composed<trans_t,rot_t> qk = registration::registration(in_3d_, ref_3d_);
+  std::cout << "igr.cc - Registration - " << t << "s" << std::endl;
 
-  std::cout << "igr.cc - Registration - " << t << std::endl;
 
   std::cout << "* Build result image" << std::endl;
-  debug::compare_registration(in_3d, ref_3d, qk);
+  image3d<value::rgb8> registered = debug::make_registered_image(in_3d, ref_3d, qk);
+  debug::compare_registration(registered, ref_3d);
+
+  debug::compare_registration2(in_wborders, ref_wborders, qk);
 
 }
diff --git a/milena/sandbox/lazzara/irm_seg_with_mm_and_rag.mine.cc b/milena/sandbox/lazzara/irm_seg_with_mm_and_rag.mine.cc
new file mode 100644
index 0000000..5b54eca
--- /dev/null
+++ b/milena/sandbox/lazzara/irm_seg_with_mm_and_rag.mine.cc
@@ -0,0 +1,331 @@
+
+#include <iterator>
+#include <iostream>
+#include <algorithm>
+
+#include <mln/core/image/image2d.hh>
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/extension_fun.hh>
+#include <mln/core/image/tr_image.hh>
+#include <mln/core/var.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/fun/p2b/big_chess.hh>
+#include <mln/fun/x2x/all.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+
+#include <mln/level/transform.hh>
+
+#include <mln/convert/to_window.hh>
+#include <mln/convert/to_image.hh>
+#include <mln/convert/to_fun.hh>
+
+#include <mln/labeling/compute.hh>
+#include <mln/labeling/background.hh>
+
+#include <mln/level/convert.hh>
+
+#include <mln/make/image3d.hh>
+
+#include <mln/morpho/gradient.hh>
+#include <mln/morpho/closing_area.hh>
+#include <mln/morpho/meyer_wst.hh>
+
+#include <mln/accu/mean.hh>
+//#include <mln/level/take.hh>
+
+#include <mln/util/graph.hh>
+
+#include <mln/literal/colors.hh>
+
+#include <mln/debug/println.hh>
+
+#include <mln/registration/icp2.hh>
+
+mln::value::int_u8 foo(unsigned u)
+{
+  return u == 0 ?
+    0 : // wshed line
+    1 + (u - 1) % 255; // basin
+}
+
+
+namespace mln
+{
+  namespace debug
+  {
+
+    template <typename I, typename T>
+    image3d<value::rgb8>
+    make_registered_image(Image<I>& P_, Image<I>& X_, const T& transf)
+    {
+      I& P = exact(P_);
+      I& X = exact(X_);
+
+      mln_pset(I) box = geom::bbox(X);
+      box.enlarge(1, 60);
+      box.enlarge(2, 60);
+
+      typedef mln_ch_value(I,value::rgb8) result_t;
+      result_t result(box);
+      extension_fun<result_t,pw::cst_<mln_value(result_t)> > ext_result(result, pw::cst(value::rgb8(0,0,0)));
+      extension_fun<I,pw::cst_<mln_value(I)> > ext_X(X, pw::cst(false));
+      data::fill(ext_result, literal::black);
+
+      mln_VAR(ig, (P | pw::value(P) == true));
+      mln_piter(ig_t) p(ig.domain());
+      for_all(p)
+	ext_result(transf(p.to_vec())) = literal::green;
+
+      return ext_result;
+    }
+
+    template <typename I, typename J>
+    void
+    compare_registration(Image<I>& registered_, Image<J>& X_)
+    {
+      I& registered = exact(registered_);
+      J& X = exact(X_);
+
+      typedef mln_ch_value(I,value::rgb8) result_t;
+      result_t result;
+      initialize(result, registered);
+      extension_fun<J,pw::cst_<mln_value(J)> > ext_X(X, pw::cst(false));
+
+      data::fill(result, literal::black);
+      data::fill((result | (pw::value(ext_X) == true)).rw(), literal::white);
+      data::fill((result | (pw::value(registered) != pw::cst(literal::black))).rw(),
+		 literal::green);
+
+      io::ppm::save(slice(result,0), "tmp_final_registered.ppm");
+    }
+
+
+
+    template <typename I, typename T>
+    void
+    compare_registration2(Image<I>& P_, Image<I>& X_,
+			  const T& transf)
+    {
+      I& P = exact(P_);
+      const I& X = exact(X_);
+
+      //FIXME: tr_image is bugged!
+//      typedef extension_fun<I,pw::cst_<mln_value(I)> > ext_P_t;
+//      ext_P_t ext_P(P, pw::cst(value::int_u8(0u)));
+//      tr_image<box3d, ext_P_t, T> trima(P.domain(), ext_P, transf);
+//      io::pgm::save(slice(trima, 0), "tmp_trima.ppm");
+
+      I reg(X.domain());
+      data::fill(reg, literal::zero);
+      mln_piter(I) p(P.domain());
+      for_all(p)
+	if (reg.domain().has(transf(p.to_vec())))
+	  reg(transf(p.to_vec())) = P(p);
+      io::pgm::save(slice(reg,0), "tmp_registered-2.ppm");
+
+      I tmp2 = duplicate(X);
+      fun::p2b::big_chess<box3d> fun2(tmp2.domain(), 20);
+      data::paste((reg | fun2), tmp2);
+      io::pgm::save(slice(tmp2,0), "tmp_registration_filter-a.ppm");
+
+//      I tmp = duplicate(X);
+//      fun::p2b::big_chess<box3d> fun(tmp.domain(), 20);
+//      data::paste((trima | fun), tmp);
+//
+//      io::pgm::save(slice(tmp,0), "tmp_registration_filter.ppm");
+    }
+
+  }
+
+
+  struct threshold : Function_p2b<threshold>
+  {
+    bool operator()(const value::rgb8& val) const
+    {
+      unsigned inty = (val.red() + val.blue() + val.green());
+      return inty > 100 && inty < 600;
+    }
+
+    bool operator()(const unsigned& val) const
+    {
+      return val < 120;// && val < 230;
+    }
+  };
+
+  template <typename I>
+  mln_ch_value(I,bool)
+  fill_holes(const mln::Image<I>& ima)
+  {
+    using namespace mln;
+
+    mln_ch_value(I,bool) output;
+    initialize(output, ima);
+    data::fill(output, true);
+
+    value::label_16 nlabels;
+    mln_ch_value(I, value::label_16) lbl = labeling::background(ima, c4(), nlabels);
+
+    mln_VAR(lbl_count, labeling::compute(accu::meta::count(), ima, lbl, nlabels));
+
+    unsigned max_id = 1;
+    for (unsigned i = 2; i <= nlabels; ++i)
+      if (lbl_count[max_id] < lbl_count[i])
+	max_id = i;
+
+    data::fill((output | pw::value(lbl) == max_id).rw(), false);
+
+    return output;
+  }
+
+
+  template <typename I>
+  mln_ch_value(I,bool)
+  keep_largest_component(const Image<I>& ima)
+  {
+    using namespace mln;
+
+    image2d<bool> in_bw_cleaned = fill_holes(ima);
+//    io::pbm::save(in_bw_cleaned, "in_bw_cleaned.pbm");
+
+    logical::not_inplace(in_bw_cleaned);
+    image2d<bool> in_bw_cleaned_full = fill_holes(in_bw_cleaned);
+//    io::pbm::save(in_bw_cleaned_full, "in_bw_cleaned_full.pbm");
+
+    logical::not_inplace(in_bw_cleaned_full);
+    return in_bw_cleaned_full;
+  }
+
+  template <typename I>
+  mln_ch_value(I,bool)
+  get_main_object_shape(const Image<I>& in)
+  {
+    using namespace mln;
+
+    typedef image2d<bool> J;
+
+//    threshold f;
+//    J in_bw = binarization::binarization(in, f);
+//    io::pbm::save(in_bw, "01_in_bw.pbm");
+
+//    J ima = keep_largest_component(in_bw);
+    J ima = keep_largest_component(in);
+
+    std::cout << "Compute gradient" << std::endl;
+    J ima_grad = morpho::gradient(ima, win_c4p());
+
+    return ima_grad;
+  }
+
+  //FIXME: add conversion from label_16 to bool.
+  struct to_bool : Function_v2v<to_bool>
+  {
+    typedef bool result;
+    bool operator()(const value::label_16& l) const
+    {
+      return l != 0u;
+    }
+
+  };
+
+
+  template <typename I>
+  mln_ch_value(I,bool)
+  get_cloud_image(const Image<I>& irm)
+  {
+    using namespace mln;
+    using value::int_u8;
+    using value::label_16;
+
+    window2d c4p = convert::to_window(c4());
+    c4p.insert(0,0);
+    //   debug::println(convert::to_image(c4p));
+    image2d<int_u8> grad = morpho::gradient(irm, c4p);
+    io::pgm::save( grad, "tmp_grad_c4p.pgm" );
+
+    image2d<int_u8> clo;
+    initialize(clo, irm);
+
+    clo = morpho::closing_area(grad, c4(), 100);
+    io::pgm::save( clo, "tmp_clo_a100.pgm" );
+
+    label_16 nbasins;
+    image2d<label_16> wshed = morpho::meyer_wst(clo, c4(), nbasins);
+    std::cout << "nbasins = " << nbasins << std::endl;
+    io::pgm::save( level::transform(wshed, convert::to_fun(foo)),
+	"tmp_wshed.pgm" );
+
+    mln_VAR(mean_values, labeling::compute(accu::meta::mean(), irm, wshed, nbasins));
+    fun::i2v::array<label_16> to_keep(nbasins.next(), 0);
+    threshold f;
+    for (label_16 i = 1; i < mean_values.nelements(); ++i)
+      if (f(mean_values[i]))
+	to_keep(i) = i;
+
+    wshed = level::transform(wshed, to_keep);
+    io::pgm::save( level::transform(wshed, convert::to_fun(foo)),
+	"tmp_wshed_2.pgm" );
+
+    image2d<bool> wshed_bw = level::transform(wshed, to_bool());
+    image2d<bool> main_obj = get_main_object_shape(wshed_bw);
+    io::pbm::save(main_obj, "tmp_main_obj");
+
+    return main_obj;
+  }
+
+} // end of namespace mln
+
+
+int main(int, char *argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+  using value::label_16;
+
+  image2d<int_u8> irm;
+  io::pgm::load(irm, argv[1]);
+
+  image2d<int_u8> irm_ref;
+  io::pgm::load(irm_ref, argv[2]);
+
+  std::cout << "compute irm" << std::endl;
+  image3d<bool> P = make::image3d(get_cloud_image(irm));
+  std::cout << "compute irm_ref" << std::endl;
+  image3d<bool> X = make::image3d(get_cloud_image(irm_ref));
+
+  std::cout << "Registration" << std::endl;
+  typedef fun::x2x::rotation<3u,float> rot_t;
+  typedef fun::x2x::translation<3u,float> trans_t;
+  typedef p_array<point3d> arr_t;
+  arr_t P_arr = convert::to<arr_t>(P);
+  arr_t X_arr = convert::to<arr_t>(X);
+  fun::x2x::composed<trans_t,rot_t> qk = registration::registration(P_arr, X_arr);
+
+
+  std::cout << "* Build result image" << std::endl;
+  image3d<value::rgb8> registered = debug::make_registered_image(P, X, qk);
+  debug::compare_registration(registered, X);
+
+
+
+  image3d<int_u8> irm_wborders = make::image3d(duplicate(irm));
+  data::fill((irm_wborders | P_arr).rw(), 255);
+  io::pgm::save(slice(irm_wborders,0), "tmp_irm_with_borders.ppm");
+
+  image3d<int_u8> ref_wborders = make::image3d(duplicate(irm_ref));
+  data::fill((ref_wborders | X_arr).rw(), 255);
+  io::pgm::save(slice(ref_wborders,0), "tmp_ref_with_borders.ppm");
+
+  debug::compare_registration2(irm_wborders, ref_wborders, qk);
+
+}
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Optimize the video labeling canvas.
	* mln/core/concept/neighborhood.hh (negative_offsets_wrt): New.
	* mln/core/concept/window.hh: Likewise.
	* mln/canvas/labeling.hh (labeling): Strenghten 's' type.
	Use negative_offsets_wrt.
	* mln/labeling/flat_zones.hh
	(flat_zones_functor): Remove useless typedef S.
	Fix ctor.
	(flat_zones): Fix.
	* tests/labeling/flat_zones.cc: Upgrade file doc style.
	Add commented bench.
	Add consistency test wrt both implementations.
 mln/canvas/labeling.hh           |   48 +++++++++++++++++++++------------------
 mln/core/concept/neighborhood.hh |   18 ++++++++++++++
 mln/core/concept/window.hh       |   30 ++++++++++++++++++++++++
 mln/labeling/flat_zones.hh       |   16 ++++---------
 tests/labeling/flat_zones.cc     |   47 ++++++++++++++++++++++++++++++++++----
 5 files changed, 122 insertions(+), 37 deletions(-)
Index: mln/core/concept/neighborhood.hh
--- mln/core/concept/neighborhood.hh	(revision 3320)
+++ mln/core/concept/neighborhood.hh	(working copy)
@@ -102,6 +102,10 @@
   util::array<int>
   offsets_wrt(const Image<I>& ima, const Neighborhood<N>& nbh);
 
+  template <typename I, typename N>
+  util::array<int>
+  negative_offsets_wrt(const Image<I>& ima, const Neighborhood<N>& nbh);
+
 
 
 # ifndef MLN_INCLUDE_ONLY
@@ -160,6 +164,20 @@
     return offsets_wrt(ima, nbh.win());
   }
 
+  template <typename I, typename N>
+  util::array<int>
+  negative_offsets_wrt(const Image<I>& ima_, const Neighborhood<N>& nbh_)
+  {
+    mln_is_simple_neighborhood(N)::check();
+
+    const I& ima = exact(ima_);
+    const N& nbh = exact(nbh_);
+    mln_precondition(ima.is_valid());
+    mln_precondition(nbh.is_valid());
+
+    return negative_offsets_wrt(ima, nbh.win());
+  }
+
 # endif // ! MLN_INCLUDE_ONLY
 
 } // end of namespace mln
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh	(revision 3320)
+++ mln/core/concept/window.hh	(working copy)
@@ -119,6 +119,10 @@
   util::array<int>
   offsets_wrt(const Image<I>& ima, const Window<W>& win);
   
+  template <typename I, typename W>
+  util::array<int>
+  negative_offsets_wrt(const Image<I>& ima, const Window<W>& win);
+  
 
 
   namespace convert
@@ -339,6 +343,32 @@
   }
 
 
+  template <typename I, typename W>
+  inline
+  util::array<int>
+  negative_offsets_wrt(const Image<I>& ima_, const Window<W>& win_)
+  {
+    mln_is_simple_window(W)::check();
+
+    const I& ima = exact(ima_);
+    const W& win = exact(win_);
+    mln_precondition(ima.is_valid());
+    mln_precondition(win.is_valid());
+
+    util::array<int> arr;
+    unsigned n = win.size();
+    
+    for (unsigned i = 0; i < n; ++i)
+      {
+	int offset = ima.delta_index(win.dp(i));
+	if (offset < 0)
+	  arr.append(offset);
+      }
+
+    return arr;
+  }
+
+
   namespace convert
   {
 
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh	(revision 3320)
+++ mln/canvas/labeling.hh	(working copy)
@@ -119,7 +119,7 @@
 		  typename S, typename F>
 	mln_ch_value(I, L)
 	  labeling(const Image<I>& input_, const Neighborhood<N>& nbh_, L& nlabels,
-		   const S& s, F& f)
+		   const Site_Set<S>& s_, F& f)
 	{
 	  trace::entering("canvas::impl::generic::labeling");
 
@@ -127,6 +127,7 @@
 
 	  const I& input = exact(input_);
 	  const N& nbh   = exact(nbh_);
+	  const S& s     = exact(s_);
 
 	  // Local type.
 	  typedef mln_psite(I) P;
@@ -254,7 +255,7 @@
 	// Initialization.
 	{
 	  initialize(deja_vu, input);
-	  mln::data::fill(deja_vu, false);
+   	  mln::data::fill(deja_vu, true);
 	  extension::fill(deja_vu, false); // So that the extension is ignored.
 
 	  initialize(parent, input);
@@ -268,8 +269,10 @@
 
 	// First Pass.
 	{
+	  util::array<int> dp = negative_offsets_wrt(input, nbh);
+	  const unsigned n_nbhs = dp.nelements();
+
 	  mln_pixter(const I) px(input);
-	  mln_nixter(const I, N) nx(px, nbh);
 	  for_all(px)
 	  {
 	    unsigned p = px.offset();
@@ -279,10 +282,10 @@
 	    // Make-Set.
 	    parent.element(p) = p;
 	    f.init_attr_(p);
-	    for_all(nx)
+	    for (unsigned i = 0; i < n_nbhs; ++i)
 	    {
-	      unsigned n = nx.offset();
-	      if (deja_vu.element(n))
+	      unsigned n = p + dp[i];
+ 	      if (deja_vu.element(n)) // Only false in the external border.
 		{
 		  if (f.equiv_(n, p))
 		    {
@@ -298,8 +301,6 @@
 		    f.do_no_union_(n, p);
 	      }
 	    }
-
-	    deja_vu.element(p) = true;
 	  }
 	}
 
@@ -465,19 +466,21 @@
 		typename F>
       inline
       mln_ch_value(I, L)
-      labeling_video(metal::false_, const Image<I>& input,
-	  const Neighborhood<N>& nbh, L& nlabels, F& functor)
+      labeling_video_dispatch(metal::false_,
+			      const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels,
+			      F& functor)
       {
-	return impl::generic::labeling(input, nbh, input.domain(),
-	    nlabels, functor);
+	return impl::generic::labeling(input, nbh, input.domain(), nlabels,
+				       functor);
       }
 
       template <typename I, typename N, typename L,
 	        typename F>
       inline
       mln_ch_value(I, L)
-      labeling_video(metal::true_, const Image<I>& input,
-	  const Neighborhood<N>& nbh, L& nlabels, F& functor)
+      labeling_video_dispatch(metal::true_,
+			      const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels,
+			      F& functor)
       {
 	return impl::labeling_video_fastest(input, nbh, nlabels, functor);
       }
@@ -486,8 +489,8 @@
 	        typename F>
       inline
       mln_ch_value(I, L)
-      labeling_video_dispatch(const Image<I>& input, const Neighborhood<N>& nbh,
-	  L& nlabels, F& functor)
+      labeling_video_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels,
+			      F& functor)
       {
 	enum {
 	  test = mlc_equal(mln_trait_image_speed(I),
@@ -495,8 +498,9 @@
 	    &&
 	    mln_is_simple_neighborhood(N)::value
 	};
-	return labeling_video(metal::bool_<test>(), input,
-	    nbh, nlabels, functor);
+	return labeling_video_dispatch(metal::bool_<test>(),
+				       input, nbh, nlabels,
+				       functor);
       }
 
 
@@ -513,8 +517,8 @@
 	  increasing ?
 	  level::sort_psites_increasing(input) :
 	  level::sort_psites_decreasing(input);
-	return impl::generic::labeling(input, nbh, nlabels,
-	    s, functor);
+	return impl::generic::labeling(input, nbh, nlabels, s,
+				       functor);
       }
 
       template <typename I, typename N, typename L, typename F>
@@ -528,8 +532,8 @@
 	  increasing ?
 	  level::sort_offsets_increasing(input) :
 	  level::sort_offsets_decreasing(input);
-	return impl::labeling_sorted_fastest(input, nbh, nlabels,
-	    s, functor);
+	return impl::labeling_sorted_fastest(input, nbh, nlabels, s,
+					     functor);
       }
 
       template <typename I, typename N, typename L, typename F>
Index: mln/labeling/flat_zones.hh
--- mln/labeling/flat_zones.hh	(revision 3320)
+++ mln/labeling/flat_zones.hh	(working copy)
@@ -67,16 +67,12 @@
       template <typename I>
       struct flat_zones_functor
       {
-	typedef mln_psite(I) P;
-
-	// Requirements from mln::canvas::labeling:
-
-        typedef mln_pset(I) S;
-
 	const I& input;
 
 	// Generic implementation.
 
+	typedef mln_psite(I) P;
+
 	void init()                          {}
 	bool handles(const P&) const             { return true; }
 	bool equiv(const P& n, const P& p) const { return input(n) ==
@@ -99,7 +95,7 @@
 
 	// end of requirements.
 
-	flat_zones_functor(const I& input, const N& nbh)
+	flat_zones_functor(const I& input)
 	  : input(input)
 	{}
       };
@@ -122,9 +118,9 @@
       const N& nbh = exact(nbh_);
       mln_precondition(input.is_valid());
 
-      // Calls the only implementation.
-      typedef flat_zones_functor<I,N,L> F;
-      F f(exact(input), exact(nbh));
+      // Call the labeling canvas.
+      typedef impl::flat_zones_functor<I> F;
+      F f(input);
       mln_ch_value(I, L) output = canvas::labeling_video(input, nbh, nlabels, f);
 
       trace::exiting("labeling::flat_zones");
Index: tests/labeling/flat_zones.cc
--- tests/labeling/flat_zones.cc	(revision 3320)
+++ tests/labeling/flat_zones.cc	(working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Laboratory (LRDE)
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -25,10 +26,11 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-/*! \file tests/labeling/flat_zones.cc
- *
- * \brief Test on mln::labeling::flat_zones.
- */
+/// \file tests/labeling/flat_zones.cc
+///
+/// Test on mln::labeling::flat_zones.
+///
+/// \todo Move commented bench to the 'bench' directory.
 
 #include <mln/core/image/image2d.hh>
 #include <mln/value/int_u8.hh>
@@ -38,6 +40,7 @@
 
 #include <mln/labeling/blobs.hh>
 #include <mln/pw/all.hh>
+#include <mln/level/compare.hh>
 
 #include "tests/data.hh"
 
@@ -49,11 +52,44 @@
 
   image2d<int_u8> lena = io::pgm::load<int_u8>(MLN_IMG_DIR "/tiny.pgm");
 
+
+  // Bench code:
+
+//   for (unsigned i = 0; i < 10; ++i)
+//   {
+//     typedef image2d<int_u8> I;
+//     labeling::impl::flat_zones_functor<I> f(lena);
+//     unsigned n;
+//     canvas::impl::labeling_video_fastest(lena,
+// 					 c4(),
+// 					 n,
+// 					 f);
+//   }
+
+
   unsigned n;
   image2d<unsigned> labels = labeling::flat_zones(lena, c4(), n);
   mln_assertion(n == 247);
 
   {
+    typedef image2d<int_u8> I;
+    labeling::impl::flat_zones_functor<I> f(lena);
+
+    unsigned nlabels_generic, nlabels_fastest;
+    mln_assertion(canvas::impl::generic::labeling(lena,
+						  c4(),
+						  nlabels_generic,
+						  lena.domain(),
+						  f)
+		  ==
+		  canvas::impl::labeling_video_fastest(lena,
+						       c4(),
+						       nlabels_fastest,
+						       f));
+    mln_assertion(nlabels_generic == nlabels_fastest);
+  }
+
+  {
     unsigned n_ = 0;
     for (unsigned i = 0; i <= 255; ++i)
       {
@@ -64,4 +100,5 @@
       }
     mln_assertion(n_ == n);
   }
+
 }
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0