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
 
                    
                        	* mln/literal/colors.hh,
	* mln/value/rgb.hh:
	Add literal::dark_red and literal::dark_orange.
---
 milena/ChangeLog             |    8 ++++++++
 milena/mln/literal/colors.hh |   18 ++++++++++++++++++
 milena/mln/value/rgb.hh      |   22 ++++++++++++++++++++++
 3 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 069fe9b..5fa5495 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,13 @@
 2008-10-29  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
+	Add new colors.
+
+	* mln/literal/colors.hh,
+	* mln/value/rgb.hh:
+	Add literal::dark_red and literal::dark_orange.
+
+2008-10-29  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
 	Add new methods to box.
 
 	* mln/core/site_set/box.hh: add crop_wrt(), nrows() and ncols.
diff --git a/milena/mln/literal/colors.hh b/milena/mln/literal/colors.hh
index a006dc1..069ae59 100644
--- a/milena/mln/literal/colors.hh
+++ b/milena/mln/literal/colors.hh
@@ -51,6 +51,16 @@ namespace mln
     {
     };
 
+    /// Type of literal dark red.
+    struct dark_red_t : public Literal<dark_red_t>
+    {
+    };
+
+    /// Type of literal dark orange.
+    struct dark_orange_t : public Literal<dark_orange_t>
+    {
+    };
+
     /// Type of literal green.
     struct green_t : public Literal<green_t>
     {
@@ -61,6 +71,14 @@ namespace mln
     // FIXME: Make this a proper global (issue #43).
     static const red_t red = red_t();
 
+    /// Literal dark red.
+    // FIXME: Make this a proper global (issue #43).
+    static const dark_red_t dark_red = dark_red_t();
+
+    /// Literal red.
+    // FIXME: Make this a proper global (issue #43).
+    static const dark_orange_t dark_orange = dark_orange_t();
+
     /// Literal green.
     // FIXME: Make this a proper global (issue #43).
     static const green_t green = green_t();
diff --git a/milena/mln/value/rgb.hh b/milena/mln/value/rgb.hh
index eed8c5a..1e3d7ca 100644
--- a/milena/mln/value/rgb.hh
+++ b/milena/mln/value/rgb.hh
@@ -56,6 +56,8 @@ namespace mln
     struct white_t;
 
     struct red_t;
+    struct dark_red_t;
+    struct dark_orange_t;
     struct blue_t;
     struct green_t;
     /// \}
@@ -204,6 +206,8 @@ namespace mln
 
       rgb<n>(const mln::literal::blue_t&);
       rgb<n>(const mln::literal::red_t&);
+      rgb<n>(const mln::literal::dark_red_t&);
+      rgb<n>(const mln::literal::dark_orange_t&);
       rgb<n>(const mln::literal::green_t&);
       /// \}
 
@@ -366,6 +370,24 @@ namespace mln
 
     template <unsigned n>
     inline
+    rgb<n>::rgb(const mln::literal::dark_red_t&)
+    {
+      this->v_[0] = mln_max(int_u<n>) / 3;
+      this->v_[1] = 0;
+      this->v_[2] = 0;
+    }
+
+    template <unsigned n>
+    inline
+    rgb<n>::rgb(const mln::literal::dark_orange_t&)
+    {
+      this->v_[0] = mln_max(int_u<n>) / 3;
+      this->v_[1] = mln_max(int_u<n>) / 3;
+      this->v_[2] = 0;
+    }
+
+    template <unsigned n>
+    inline
     rgb<n>::rgb(const mln::literal::green_t&)
     {
       this->v_[0] = 0;
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* scribo/demat.hh: New output showing the table matrix.
	* scribo/main.cc: Move and update the code...
	* scribo/photo.cc,
	* scribo/table.cc: Here. Add New main() functions.
---
 milena/sandbox/ChangeLog                    |   11 ++
 milena/sandbox/scribo/demat.hh              |  221 +++++++++++++++++++-------
 milena/sandbox/scribo/{main.cc => photo.cc} |    4 +-
 milena/sandbox/scribo/{main.cc => table.cc} |    2 +-
 4 files changed, 174 insertions(+), 64 deletions(-)
 copy milena/sandbox/scribo/{main.cc => photo.cc} (96%)
 rename milena/sandbox/scribo/{main.cc => table.cc} (98%)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index fd1c59a..62f319d 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,14 @@
+2008-10-29  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Improve code for Scribo.
+
+	* scribo/demat.hh: New output showing the table matrix.
+
+	* scribo/main.cc: Move and update the code...
+
+	* scribo/photo.cc,
+	* scribo/table.cc: Here. Add New main() functions.
+
 2008-10-29  Maxime van Noppen  <yabo(a)lrde.epita.fr>
 
 	Implement a simple filter on the max_tree.
diff --git a/milena/sandbox/scribo/demat.hh b/milena/sandbox/scribo/demat.hh
index 00f6169..7f88bb8 100644
--- a/milena/sandbox/scribo/demat.hh
+++ b/milena/sandbox/scribo/demat.hh
@@ -29,6 +29,7 @@
 # define DEMAT_HH_
 
 # include <mln/core/image/image2d.hh>
+# include <mln/core/image/image1d.hh>
 
 # include <mln/core/concept/function.hh>
 # include <mln/core/image/image_if.hh>
@@ -97,6 +98,19 @@ namespace scribo
     using value::int_u16;
     using value::rgb8;
 
+    char *input_file = 0;
+    int dbg_file_id = 0;
+
+    std::string output_file(const char *name)
+    {
+      std::string str = "";
+//      str += dbg_file_id;
+//      str += "-";
+//      str += input_file;
+//      str += "-";
+      str += name;
+      return str;
+    }
 
     void draw_component_boxes(image2d<rgb8>& output, const util::array<box2d>& boxes)
     {
@@ -116,9 +130,118 @@ namespace scribo
       for (unsigned i = 1; i <= nlabels; ++i)
 	f(i) = rgb8(255 / ((i % 10) + 1), (100 + i) % 255, (255 + i)%255);
       output = level::transform(lbl, f);
-      io::ppm::save(output, filename);
+      io::ppm::save(output, output_file(filename));
+    }
+
+
+    /// Functions related to the matrix extraction
+    /// \{
+
+    void draw_hline(image2d<rgb8>& ima,
+		  const box2d& box,
+		  const rgb8& v)
+    {
+      unsigned ncols = box.pmax().col() - box.pmin().col();
+      point2d p1 = box.center();
+      p1.col() -= ncols / 2;
+      point2d p2 = box.center();
+      p2.col() += ncols / 2;
+
+      draw::line(ima, p1, p2, v);
+    }
+
+    void draw_vline(image2d<rgb8>& ima,
+		  const box2d& box,
+		  const rgb8& v)
+    {
+      unsigned nrows = box.pmax().row() - box.pmin().row();
+      point2d p1 = box.center();
+      p1.row() -= nrows / 2;
+      point2d p2 = box.center();
+      p2.row() += nrows / 2;
+
+      draw::line(ima, p1, p2, v);
+    }
+
+    void draw_row(image2d<rgb8>& ima,
+	      unsigned line,
+	      const rgb8& v)
+    {
+      draw::line(ima, point2d(line, 0), point2d(line, ima.ncols()), v);
+    }
+
+    void draw_col(image2d<rgb8>& ima,
+	      unsigned line,
+	      const rgb8& v)
+    {
+      draw::line(ima, point2d(0, line), point2d(ima.nrows(), line), v);
     }
 
+    void
+    extract_matrix(const image2d<bool>& in,
+		   std::pair<util::array<box2d>, util::array<box2d> > tboxes)
+    {
+      std::cout << "Extracting matrix..." << std::endl;
+
+      image1d<unsigned> hend(in.ncols()),
+			hrow(in.nrows()),
+			vend(in.nrows()),
+			vcol(in.ncols());
+
+      level::fill(hend, 0);
+      level::fill(hrow, 0);
+      level::fill(vend, 0);
+      level::fill(vcol, 0);
+
+      for (unsigned i = 1; i < tboxes.first.nelements(); ++i)
+      {
+	++vend.at(tboxes.first[i].pmin().row());
+	++vend.at(tboxes.first[i].pmax().row());
+	++vcol.at(tboxes.first[i].center().col());
+      }
+
+      for (unsigned i = 1; i < tboxes.second.nelements(); ++i)
+      {
+	++hend.at(tboxes.second[i].pmin().col());
+	++hend.at(tboxes.second[i].pmax().col());
+	++hrow.at(tboxes.second[i].center().row());
+      }
+
+#ifndef NOUT
+      image2d<rgb8> tmp(in.domain());
+      level::fill(tmp, literal::black);
+
+      for (unsigned i = 1; i < in.ncols(); ++i)
+      {
+	if (hend.at(i) > 0)
+	  draw_row(tmp, i, literal::dark_orange);
+	if (vcol.at(i) > 0)
+	  draw_row(tmp, i, literal::dark_orange);
+      }
+
+      for (unsigned i = 1; i < in.nrows(); ++i)
+      {
+	if (hrow.at(i) > 0)
+	  draw_col(tmp, i, literal::dark_red);
+	if (vend.at(i) > 0)
+	  draw_col(tmp, i, literal::dark_red);
+      }
+
+      for (unsigned i = 1; i < tboxes.first.nelements(); ++i)
+	draw_vline(tmp, tboxes.first[i], literal::green);
+
+      for (unsigned i = 1; i < tboxes.second.nelements(); ++i)
+	draw_hline(tmp, tboxes.second[i], literal::red);
+
+      io::ppm::save(tmp, output_file("matrix.ppm"));
+#endif
+
+    }
+
+    /// \}
+
+
+
     /// Functions related to the table removal
     /// \{
 
@@ -128,7 +251,7 @@ namespace scribo
     component_boxes(const image2d<bool>& filter)
     {
       std::cout << "component boxes" << std::endl;
-      int_u16 nlabels;
+      int_u16 nlabels = 0;
       image2d<int_u16> lbl = labeling::blobs(filter, c4(), nlabels);
 
       return labeling::compute(accu::meta::bbox(), lbl, nlabels);
@@ -141,9 +264,18 @@ namespace scribo
     {
       for (unsigned i = 1; i < boxes.nelements(); ++i)
       {
-	boxes[i].enlarge(dim, bbox_enlarge);
-	level::paste((pw::cst(false)
-		    | (boxes[i] | (pw::value(output) == pw::cst(true)))), output);
+	boxes[i].enlarge(dim, bbox_enlarge + 1);
+	boxes[i].crop_wrt(output.domain());
+	level::paste((pw::cst(false) | boxes[i] |
+		(pw::value(output) == pw::cst(true))), output);
+      }
+      if (dim == 0)
+      {
+        io::pbm::save(output, "plop.pbm");
+	image2d<rgb8> tmp(output.domain());
+	level::fill(tmp, literal::black);
+	draw_component_boxes(tmp, boxes);
+	io::ppm::save(tmp, output_file("plop2.ppm"));
       }
     }
 
@@ -166,7 +298,7 @@ namespace scribo
       image2d<bool> vfilter = morpho::erosion(in, vline);
 
 #ifndef NOUT
-      io::pbm::save(vfilter, "./table-vfilter.pbm");
+      io::pbm::save(vfilter, output_file("table-vfilter.pbm"));
 #endif
 
       boxes_t vboxes = component_boxes(vfilter);
@@ -179,7 +311,7 @@ namespace scribo
       image2d<bool> hfilter = morpho::erosion(in, hline);
 
 #ifndef NOUT
-      io::pbm::save(hfilter, "./table-hfilter.pbm");
+      io::pbm::save(hfilter, output_file("table-hfilter.pbm"));
 #endif
 
       boxes_t hboxes = component_boxes(hfilter);
@@ -190,7 +322,7 @@ namespace scribo
       image2d<rgb8> tmp = clone(output);
       draw_component_boxes(tmp, vboxes);
       draw_component_boxes(tmp, hboxes);
-      io::ppm::save(tmp, "./table-filtered.ppm");
+      io::ppm::save(tmp, output_file("table-filtered.ppm"));
 #endif
 
       return std::make_pair(vboxes, hboxes);
@@ -217,7 +349,7 @@ namespace scribo
     uncurri_left_link(fun::i2v::array<int_u16>& left_link, unsigned i)
     {
       if (left_link(i) != i)
-	left_link(i) = most_left(left_link, left_link(i));
+	left_link(i) = uncurri_left_link(left_link, left_link(i));
       return left_link(i);
     }
 
@@ -252,7 +384,7 @@ namespace scribo
 
 #ifndef NOUT
       std::cout << "nlabels = " << nlabels << std::endl;
-      save_lbl_image(lbl, nlabels, "./lbl-small-comps-removed.pgm");
+      save_lbl_image(lbl, nlabels, "lbl-small-comps-removed.pgm");
 #endif
     }
 
@@ -266,19 +398,13 @@ namespace scribo
       util::array< accu::bbox<point2d> > tboxes;
       tboxes.resize(ncomp + 1);
       for (unsigned i = 1; i <= ncomp; ++i)
-      {
-	//if (left_link(i) != i)
-	//  left_link(i) = most_left(left_link, left_link(i));
-	tboxes[most_left(left_link, i)].take(cboxes[i]);
-      }
+	tboxes[uncurri_left_link(left_link, i)].take(cboxes[i]);
 
       //Update labels
-      for (unsigned i = 1; i <= ncomp; ++i)
-	uncurri_left_link(left_link, i);
       level::apply(lbl, left_link);
 
 #ifndef NOUT
-      save_lbl_image(lbl, ncomp, "./lbl-grouped-boxes.pgm");
+      save_lbl_image(lbl, ncomp, "lbl-grouped-boxes.pgm");
 #endif
 
       util::array<box2d> result;
@@ -341,37 +467,6 @@ namespace scribo
       return left_link;
     }
 
-/*
-    void merge_bboxes(util::array<box2d>& cboxes,
-		      image2d<int_u16>& lbl, unsigned &nlabels)
-    {
-      fun::i2v::array<int_u16> merge;
-      unsigned current = 1;
-
-      for (unsigned i = 1; i <= nlabels;)
-      {
-	unsigned midcol = (cboxes[i].pmax().col() - cboxes[i].pmin().col()) / 2;
-	point2d c = cboxes[i].center();
-	/// First site on the right of the center site
-	point2d p(c.row(), c.col() + 1);
-
-	// FIXME: Lemmings with a condition on the distance => write a special version?
-	while (lbl.domain().has(p) && (lbl(p) == 0 || lbl(p) == i)
-		&& (p.col() - c.col()) <= midcol)
-	  ++p.col();
-
-	if (lbl.domain().has(p) && lbl(p) != 0 && lbl(p) != i
-	    && (p.col() - c.col()) <= midcol)
-	{
-
-	}
-      }
-
-      level::apply(lbl, merge);
-      cboxes.resize(nlabels);
-    }
-*/
-
     util::array<box2d>
     extract_text(image2d<bool>& in,
 		 image2d<rgb8>& output,
@@ -396,7 +491,7 @@ namespace scribo
 #ifndef NOUT
       image2d<rgb8> tmp = clone(output);
       draw_component_boxes(tmp, cboxes);
-      io::ppm::save(tmp, "character-bboxes.ppm");
+      io::ppm::save(tmp, output_file("character-bboxes.ppm"));
 #endif
 
       //merge_bboxes(cboxes, lbl, nlabels);
@@ -418,31 +513,37 @@ namespace scribo
 
 
   // Facade
-  void demat(char *argv[])
+  void demat(char *argv[], bool treat_tables)
   {
     using namespace mln;
     using value::rgb8;
 
     border::thickness = 3;
-    trace::quiet = false;
+    trace::quiet = true;
 
     //Useful debug variables
-    unsigned l = atoi(argv[3]);
-    unsigned bbox_distance = atoi(argv[4]);
-    unsigned min_comp_size = atoi(argv[5]);
+    unsigned narg = 3;
+    internal::input_file = argv[2];
+    unsigned l;
+    if (treat_tables)
+      l = atoi(argv[narg++]);
+    unsigned bbox_distance = atoi(argv[narg++]);
+    unsigned min_comp_size = atoi(argv[narg++]);
 
     //Load image
     image2d<bool> in;
     io::pbm::load(in, argv[1]);
     logical::not_inplace(in);
 
-#ifndef NOUT
-    io::pbm::save(in, "in-neg.pbm");
-#endif
-
     image2d<rgb8> output = level::convert(rgb8(), in);
 
-    internal::extract_tables(in, output, l);
+    std::pair<util::array<box2d>,
+		    util::array<box2d> > tblboxes;
+    if (treat_tables)
+    {
+      tblboxes = internal::extract_tables(in, output, l);
+      internal::extract_matrix(in, tblboxes);
+    }
 
     util::array<box2d> tboxes =
       internal::extract_text(in, output, bbox_distance, min_comp_size);
diff --git a/milena/sandbox/scribo/main.cc b/milena/sandbox/scribo/photo.cc
similarity index 96%
copy from milena/sandbox/scribo/main.cc
copy to milena/sandbox/scribo/photo.cc
index a74521e..991cc0d 100644
--- a/milena/sandbox/scribo/main.cc
+++ b/milena/sandbox/scribo/photo.cc
@@ -44,8 +44,6 @@ int main(int argc, char*argv[])
 	      << std::endl << std::endl
 	      << "<out.ppm>	    RGB8 output image."
 	      << std::endl << std::endl
-	      << "<l>		    Line length"
-	      << std::endl << std::endl
 	      << "<bbox_distance>     Maximum distance between character bounding boxes. Used for bbox grouping."
 	      << std::endl << std::endl
 	      << "<min_comp_nsites>   Minimum site count of a character/text component."
@@ -60,7 +58,7 @@ int main(int argc, char*argv[])
     return 1;
   }
 
-  scribo::demat(argv);
+  scribo::demat(argv, false);
 
   return 0;
 }
diff --git a/milena/sandbox/scribo/main.cc b/milena/sandbox/scribo/table.cc
similarity index 98%
rename from milena/sandbox/scribo/main.cc
rename to milena/sandbox/scribo/table.cc
index a74521e..2837cb1 100644
--- a/milena/sandbox/scribo/main.cc
+++ b/milena/sandbox/scribo/table.cc
@@ -60,7 +60,7 @@ int main(int argc, char*argv[])
     return 1;
   }
 
-  scribo::demat(argv);
+  scribo::demat(argv, true);
 
   return 0;
 }
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        	* mln/core/site_set/box.hh: add crop_wrt(), nrows() and nco
---
 milena/ChangeLog                |    6 +++++
 milena/mln/core/site_set/box.hh |   43 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index cd2632d..069fe9b 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,9 @@
+2008-10-29  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Add new methods to box.
+
+	* mln/core/site_set/box.hh: add crop_wrt(), nrows() and ncols.
+
 2008-10-28  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
 	Update the window and the neighborhood on graph vertices.
diff --git a/milena/mln/core/site_set/box.hh b/milena/mln/core/site_set/box.hh
index 5a47fa1..019d6ad 100644
--- a/milena/mln/core/site_set/box.hh
+++ b/milena/mln/core/site_set/box.hh
@@ -147,10 +147,19 @@ namespace mln
     /// FIXME: Do we want a routine as well like geom::bbox()?
     P center() const;
 
+    /// Return the column count of this box.
+    unsigned ncols() const;
+
+    /// Return the row count of this box.
+    unsigned nrows() const;
+
     /// Test that the box owns valid data, i.e., is initialized and
     /// with pmin being 'less-than' pmax.
     bool is_valid() const;
 
+    /// Crop this bbox in order to fit in the reference box \p b.
+    void crop_wrt(const box<P>& b);
+
     /// Return the size of this site set in memory.
     std::size_t memory_size() const;
 
@@ -194,6 +203,22 @@ namespace mln
 
   template <typename P>
   inline
+  void
+  box<P>::crop_wrt(const box<P>& ref)
+  {
+    if (pmin_.col() < ref.pmin().col())
+      pmin_.col() = ref.pmin().col();
+    if (pmin_.row() < ref.pmin().row())
+      pmin_.row() = ref.pmin().row();
+
+    if (pmax_.col() > ref.pmax().col())
+      pmax_.col() = ref.pmax().col();
+    if (pmax_.row() > ref.pmax().row())
+      pmax_.row() = ref.pmax().row();
+  }
+
+  template <typename P>
+  inline
   P
   box<P>::pmin() const
   {
@@ -359,6 +384,24 @@ namespace mln
 
   template <typename P>
   inline
+  unsigned
+  box<P>::ncols() const
+  {
+    mln_precondition(is_valid());
+    return pmax().col() - pmin().col();
+  }
+
+  template <typename P>
+  inline
+  unsigned
+  box<P>::nrows() const
+  {
+    mln_precondition(is_valid());
+    return pmax().row() - pmin().row();
+  }
+
+  template <typename P>
+  inline
   std::size_t
   box<P>::memory_size() const
   {
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    29 Oct '08
                    
                        	* mln/core/image/graph_elt_neighborhood.hh,
	* mln/core/image/graph_elt_window.hh:
	  Use the new util::graph API.
	* mln/core/image/graph_window_piter.hh,
	* mln/core/image/graph_neighborhood_piter.hh:
	  Update template parameters.
	* mln/core/image/graph_psite.hh:
	  Deleted.
	  Replaced by mln/util/internal/graph_vertex_psite.
	* mln/core/image/image2d.hh: Update comments.
	* mln/core/internal/graph_iter_base.hh:
	  Deleted.
	  Replaced by mln/util/internal/graph_iter_base.hh.
	* mln/core/internal/graph_vicinity_piter.hh: Renamed as...
	* mln/core/internal/graph_relative_piter.hh: ...this.
	* mln/core/internal/site_relative_iterator_base.hh:
	  Update an assertion.
	* mln/core/site_set/p_vertices.hh,
	* mln/core/site_set/p_edges.hh: returns the function by reference.
	* mln/labeling/blobs.hh,
	* mln/core/site_set/p_graph_piter.hh: reindent.
	* mln/core/var.hh: add mln_const_VAR().
	* mln/util/internal/graph_psite_base.hh:
	  pass the vertex id to the site set's function instead of the
	  vertex itself.
	* tests/core/image/graph_image.cc: Update according the new graph
	structure.
---
 milena/ChangeLog                                   |   43 +++
 milena/mln/core/image/graph_elt_neighborhood.hh    |   69 ++---
 milena/mln/core/image/graph_elt_window.hh          |   98 +++---
 milena/mln/core/image/graph_neighborhood_piter.hh  |  117 ++++----
 milena/mln/core/image/graph_psite.hh               |  341 --------------------
 milena/mln/core/image/graph_window_piter.hh        |  102 +++---
 milena/mln/core/image/image2d.hh                   |    4 +-
 milena/mln/core/internal/graph_iter_base.hh        |  135 --------
 ...h_vicinity_piter.hh => graph_relative_piter.hh} |   64 +---
 .../core/internal/site_relative_iterator_base.hh   |    3 +-
 milena/mln/core/site_set/p_edges.hh                |   13 +-
 milena/mln/core/site_set/p_graph_piter.hh          |    4 +-
 milena/mln/core/site_set/p_vertices.hh             |    4 +-
 milena/mln/core/var.hh                             |    5 +
 milena/mln/labeling/blobs.hh                       |    6 +-
 milena/mln/util/internal/graph_psite_base.hh       |    2 +-
 milena/tests/core/image/graph_image.cc             |  186 ++++++++----
 17 files changed, 388 insertions(+), 808 deletions(-)
 delete mode 100644 milena/mln/core/image/graph_psite.hh
 delete mode 100644 milena/mln/core/internal/graph_iter_base.hh
 rename milena/mln/core/internal/{graph_vicinity_piter.hh => graph_relative_piter.hh} (61%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index b1305d2..cd2632d 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,46 @@
+2008-10-28  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Update the window and the neighborhood on graph vertices.
+
+	* mln/core/image/graph_elt_neighborhood.hh,
+	* mln/core/image/graph_elt_window.hh:
+	  Use the new util::graph API.
+
+	* mln/core/image/graph_window_piter.hh,
+	* mln/core/image/graph_neighborhood_piter.hh:
+	  Update template parameters.
+
+	* mln/core/image/graph_psite.hh:
+	  Deleted.
+	  Replaced by mln/util/internal/graph_vertex_psite.
+
+	* mln/core/image/image2d.hh: Update comments.
+
+	* mln/core/internal/graph_iter_base.hh:
+	  Deleted.
+	  Replaced by mln/util/internal/graph_iter_base.hh.
+
+	* mln/core/internal/graph_vicinity_piter.hh: Renamed as...
+	* mln/core/internal/graph_relative_piter.hh: ...this.
+
+	* mln/core/internal/site_relative_iterator_base.hh:
+	  Update an assertion.
+
+	* mln/core/site_set/p_vertices.hh,
+	* mln/core/site_set/p_edges.hh: returns the function by reference.
+
+	* mln/labeling/blobs.hh,
+	* mln/core/site_set/p_graph_piter.hh: reindent.
+
+	* mln/core/var.hh: add mln_const_VAR().
+
+	* mln/util/internal/graph_psite_base.hh:
+	  pass the vertex id to the site set's function instead of the
+	  vertex itself.
+
+	* tests/core/image/graph_image.cc: Update according the new graph
+	structure.
+
 2008-10-28  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
 
 	Add morphological top hats.
diff --git a/milena/mln/core/image/graph_elt_neighborhood.hh b/milena/mln/core/image/graph_elt_neighborhood.hh
index df0420a..80f40d4 100644
--- a/milena/mln/core/image/graph_elt_neighborhood.hh
+++ b/milena/mln/core/image/graph_elt_neighborhood.hh
@@ -31,9 +31,6 @@
 /// \file mln/core/image/graph_elt_neighborhood.hh
 /// \brief Definition of the elementary ``neighborhood'' on a graph.
 
-/* FIXME: Have a consistent naming: we have neighborhood (without '_')
-   but point_, neighb_, etc.  */
-
 /* FIXME: Factor those classes:
    - mln::graph_elt_window
    - mln::graph_elt_neighborhood
@@ -42,14 +39,10 @@
 
    See https://trac.lrde.org/olena/ticket/139.  */
 
-/* FIXME: Due to the poor interface of mln::p_line_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
-
 # include <set>
 
 # include <mln/core/concept/neighborhood.hh>
-# include <mln/core/image/graph_psite.hh>
+# include <mln/util/internal/graph_vertex_psite.hh>
 # include <mln/core/image/graph_neighborhood_piter.hh>
 
 # include <mln/core/image/graph_elt_window.hh>
@@ -58,35 +51,35 @@
 namespace mln
 {
   // Fwd decls.
-  template <typename P, typename N> class graph_neighborhood_fwd_piter;
-  template <typename P, typename N> class graph_neighborhood_bkd_piter;
+  template <typename G, typename F, typename N> class graph_neighborhood_fwd_piter;
+  template <typename G, typename F, typename N> class graph_neighborhood_bkd_piter;
 
 
   /// \brief Elementary neighborhood on graph class.
-  template <typename P>
+  template <typename G, typename F>
   class graph_elt_neighborhood
-    : public Neighborhood< graph_elt_neighborhood<P> >
+    : public Neighborhood< graph_elt_neighborhood<G, F> >
   {
-    typedef graph_elt_neighborhood<P> self_;
+    typedef graph_elt_neighborhood<G, F> self_;
 
   public:
     /// Associated types.
     /// \{
     /// The type of psite corresponding to the neighborhood.
-    typedef graph_psite<P> psite;
+    typedef internal::vertex_psite<G, F> psite;
     /// The type of site corresponding to the neighborhood.
     typedef mln_site(psite) site;
     // The type of the set of neighbors (vertex ids adjacent to the
     // reference psite).
-    typedef std::set<util::vertex_id> sites_t;
+    typedef std::set<unsigned> sites_t;
 
     /// \brief Site_Iterator type to browse the psites of the
     /// neighborhood w.r.t. the ordering of vertices.
-    typedef graph_neighborhood_fwd_piter<P, self_> fwd_niter;
+    typedef graph_neighborhood_fwd_piter<G, F, self_> fwd_niter;
 
     /// \brief Site_Iterator type to browse the psites of the
     /// neighborhood w.r.t. the reverse ordering of vertices.
-    typedef graph_neighborhood_bkd_piter<P, self_> bkd_niter;
+    typedef graph_neighborhood_bkd_piter<G, F, self_> bkd_niter;
 
     /// The default niter type.
     typedef fwd_niter niter;
@@ -95,9 +88,9 @@ namespace mln
     /// Conversions.
     /// \{
     /// The window type corresponding to this neighborhood.
-    typedef graph_elt_window<P> window;
+    typedef graph_elt_window<G, F> window;
     /// Create a window corresponding to this neighborhood.
-    window to_window() const;
+    window win() const;
     /// \}
 
     /// Services for iterators.
@@ -111,44 +104,30 @@ namespace mln
 
 # ifndef MLN_INCLUDE_ONLY
 
-  template <typename P>
+  template <typename G, typename F>
   inline
-  graph_elt_window<P>
-  graph_elt_neighborhood<P>::to_window() const
+  graph_elt_window<G, F>
+  graph_elt_neighborhood<G, F>::win() const
   {
-    return graph_elt_window<P>();
+    return graph_elt_window<G, F>();
   }
 
-  template <typename P>
+  template <typename G, typename F>
   template <typename Piter>
   inline
   void
-  graph_elt_neighborhood<P>::compute_sites_(Site_Iterator<Piter>& piter_) const
+  graph_elt_neighborhood<G, F>::compute_sites_(Site_Iterator<Piter>& piter_) const
   {
     Piter& piter = exact(piter_);
-    util::vertex_id ref_vertex_id = piter.center().vertex_id();
+    unsigned central_vertex = piter.center().v().id();
+    const G& g = piter.center().graph();
+
     sites_t& sites = piter.sites();
     sites.clear();
-    const util::vertex<P>& ref_vertex =
-      piter.center().site_set().gr_->vertex(ref_vertex_id);
-    /* FIXME: Move this computation out of the neighborhood. In fact,
-       this should be a service of the graph, also proposed by the
-       p_line_graph.  */
+
     // Adjacent vertices.
-    for (std::vector<util::edge_id>::const_iterator e =
-	   ref_vertex.edges.begin();
-	 e != ref_vertex.edges.end(); ++e)
-      {
-	util::vertex_id v1 = piter.center().site_set().gr_->edges()[*e]->v1();
-	// We explicitly enforce that the reference piter vertex id is
-	// *not* inserted into SITES.
-	if (v1 != ref_vertex_id)
-	  sites.insert(v1);
-	util::vertex_id v2 = piter.center().site_set().gr_->edges()[*e]->v2();
-	// Likewise.
-	if (v2 != ref_vertex_id)
-	  sites.insert(v2);
-      }
+    for (unsigned i = 0; i < g.v_nmax_nbh_vertices(central_vertex); ++i)
+      sites.insert(g.v_ith_nbh_vertex(central_vertex, i));
   }
 
 # endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/image/graph_elt_window.hh b/milena/mln/core/image/graph_elt_window.hh
index c679afd..0c7bb06 100644
--- a/milena/mln/core/image/graph_elt_window.hh
+++ b/milena/mln/core/image/graph_elt_window.hh
@@ -31,9 +31,6 @@
 /// \file mln/core/image/graph_elt_window.hh
 /// \brief Definition of the elementary ``window'' on a graph.
 
-/* FIXME: Have a consistent naming: we have window (without '_') but
-   point_, neighb_, etc.  */
-
 /* FIXME: Factor those classes:
    - mln::graph_elt_window
    - mln::graph_elt_neighborhood
@@ -42,49 +39,60 @@
 
    See https://trac.lrde.org/olena/ticket/139.  */
 
-/* FIXME: Due to the poor interface of mln::p_line_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
-
 # include <mln/core/concept/window.hh>
-# include <mln/core/image/graph_psite.hh>
+# include <mln/util/internal/graph_vertex_psite.hh>
 # include <mln/core/image/graph_window_piter.hh>
 
 
 namespace mln
 {
-  // Fwd decls.
-  template <typename P, typename W> class graph_window_fwd_piter;
-  template <typename P, typename W> class graph_window_bkd_piter;
+
+  /// Forward declaration
+  template <typename G, typename F> class graph_elt_window;
+
+  namespace trait
+  {
+
+    ///FIXME: check that!
+    template <typename G, typename F>
+    struct window_< mln::graph_elt_window<G, F> >
+    {
+      typedef trait::window::size::unknown       size;
+      typedef trait::window::support::irregular  support;
+      typedef trait::window::definition::varying definition;
+    };
+
+  } // end of namespace mln::trait
 
 
   /// \brief Elementary window on graph class.
-  template <typename P>
-  class graph_elt_window : public Window< graph_elt_window<P> >
+  template <typename G, typename F>
+  class graph_elt_window : public Window< graph_elt_window<G, F> >
   {
-    typedef graph_elt_window<P> self_;
+    typedef graph_elt_window<G, F> self_;
+    typedef mln_result(F) P;
 
   public:
     /// Associated types.
     /// \{
     /// The type of psite corresponding to the window.
-    typedef graph_psite<P> psite;
+    typedef internal::vertex_psite<G, F> psite;
     /// The type of site corresponding to the window.
     typedef mln_site(psite) site;
     // The type of the set of window sites (vertex ids adjacent to the
     // reference psite).
-    typedef std::set<util::vertex_id> sites_t;
+    typedef std::set<unsigned> sites_t;
 
     // FIXME: This is a dummy value.
     typedef void dpsite;
 
     /// \brief Site_Iterator type to browse the psites of the window
     /// w.r.t. the ordering of vertices.
-    typedef graph_window_fwd_piter<P, self_> fwd_qiter;
+    typedef graph_window_fwd_piter<G, F, self_> fwd_qiter;
 
     /// \brief Site_Iterator type to browse the psites of the window
     /// w.r.t. the reverse ordering of vertices.
-    typedef graph_window_bkd_piter<P, self_> bkd_qiter;
+    typedef graph_window_bkd_piter<G, F, self_> bkd_qiter;
 
     /// The default qiter type.
     typedef fwd_qiter qiter;
@@ -127,75 +135,61 @@ namespace mln
 
 # ifndef MLN_INCLUDE_ONLY
 
-  template <typename P>
+  template <typename G, typename F>
   template <typename Piter>
   inline
   void
-  graph_elt_window<P>::compute_sites_(Site_Iterator<Piter>& piter_) const
+  graph_elt_window<G, F>::compute_sites_(Site_Iterator<Piter>& piter_) const
   {
     Piter& piter = exact(piter_);
-    util::vertex_id ref_vertex_id = piter.center().vertex_id();
+    const G& g = piter.center().graph();
+
+    unsigned central_vertex = piter.center().v().id();
     sites_t& sites = piter.sites();
     sites.clear();
-    const util::vertex<P>& ref_vertex =
-      piter.center().site_set().gr_->vertex(ref_vertex_id);
-    /* FIXME: Move this computation out of the window. In fact,
-       this should be a service of the graph, also proposed by the
-       p_line_graph.  */
-    /* Adjacent vertices.
-
-       We don't need to explicitely insert the reference piter (vertex
-       id) itself into SITES, since it is part of the set of vertices
-       adjacent to V1 and V2, and will therefore be
-       automatically added.  */
-    for (std::vector<util::edge_id>::const_iterator e =
-	   ref_vertex.edges.begin();
-	 e != ref_vertex.edges.end(); ++e)
-      {
-	util::vertex_id v1 = piter.center().site_set().gr_->edges()[*e]->v1();
-	sites.insert(v1);
-	util::vertex_id v2 = piter.center().site_set().gr_->edges()[*e]->v2();
-	sites.insert(v2);
-      }
+
+    sites.insert(central_vertex);
+    for (unsigned i = 0; i < g.v_nmax_nbh_vertices(central_vertex); ++i)
+      sites.insert(g.v_ith_nbh_vertex(central_vertex, i));
   }
 
-  template <typename P>
+  template <typename G, typename F>
   inline
   bool
-  graph_elt_window<P>::is_empty() const
+  graph_elt_window<G, F>::is_empty() const
   {
     return false;
   }
 
-  template <typename P>
+  template <typename G, typename F>
   inline
   bool
-  graph_elt_window<P>::is_centered() const
+  graph_elt_window<G, F>::is_centered() const
   {
     return false;
   }
 
-  template <typename P>
+  template <typename G, typename F>
   inline
   bool
-  graph_elt_window<P>::is_symmetric() const
+  graph_elt_window<G, F>::is_symmetric() const
   {
     return true;
   }
 
-  template <typename P>
+  template <typename G, typename F>
   inline
   unsigned
-  graph_elt_window<P>::delta() const
+  graph_elt_window<G, F>::delta() const
   {
     // Dummy value (see the interface of the method above).
     return 0;
   }
 
-  template <typename P>
+  template <typename G, typename F>
   inline
-  graph_elt_window<P>&
-  graph_elt_window<P>::sym()
+  graph_elt_window<G, F>&
+  graph_elt_window<G, F>::sym()
   {
     return *this;
   }
diff --git a/milena/mln/core/image/graph_neighborhood_piter.hh b/milena/mln/core/image/graph_neighborhood_piter.hh
index a39128f..9823148 100644
--- a/milena/mln/core/image/graph_neighborhood_piter.hh
+++ b/milena/mln/core/image/graph_neighborhood_piter.hh
@@ -31,26 +31,25 @@
 /// \file   mln/core/image/graph_neighborhood_piter.hh
 /// \brief  Definition of a point iterator on a graph neighborhood.
 
-# include <mln/core/internal/graph_vicinity_piter.hh>
-
-/* FIXME: Due to the poor interface of mln::p_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
+# include <mln/core/internal/graph_relative_piter.hh>
 
 namespace mln
 {
 
-  /*-------------------------------------.
-  | graph_neighborhood_fwd_piter<P, N>.  |
-  `-------------------------------------*/
+  /*----------------------------------------.
+  | graph_neighborhood_fwd_piter<G, F, N>.  |
+  `----------------------------------------*/
 
-  template <typename P, typename N>
+  /// \p G Graph type.
+  /// \p F function i2p used in the p_vertices<G, F>.
+  /// \p N Type of the neighborhood.
+  template <typename G, typename F, typename N>
   class graph_neighborhood_fwd_piter :
-    public internal::graph_vicinity_piter_< P, N,
-					    graph_neighborhood_fwd_piter<P, N> >
+    public internal::graph_relative_piter< mln_result(F), N,
+					    graph_neighborhood_fwd_piter<G, F, N> >
   {
-    typedef graph_neighborhood_fwd_piter<P, N> self_;
-    typedef internal::graph_vicinity_piter_<P, N, self_> super_;
+    typedef graph_neighborhood_fwd_piter<G, F, N> self_;
+    typedef internal::graph_relative_piter<mln_result(F), N, self_> super_;
 
   public:
     /// The Point_Site type.
@@ -83,21 +82,21 @@ namespace mln
 
   private:
     /// An iterator on the set of adjacent edges.
-    typename super_::sites_t::const_iterator i_; 
+    typename super_::sites_t::const_iterator i_;
   };
 
 
-  /*-------------------------------------.
-  | graph_neighborhood_bkd_piter<P, N>.  |
-  `-------------------------------------*/
+  /*----------------------------------------.
+  | graph_neighborhood_bkd_piter<G, F, N>.  |
+  `----------------------------------------*/
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   class graph_neighborhood_bkd_piter :
-    public internal::graph_vicinity_piter_< P, N,
-					    graph_neighborhood_bkd_piter<P, N> >
+    public internal::graph_relative_piter< mln_result(F), N,
+					    graph_neighborhood_bkd_piter<G, F, N> >
   {
-    typedef graph_neighborhood_bkd_piter<P, N> self_;
-    typedef internal::graph_vicinity_piter_<P, N, self_> super_;
+    typedef graph_neighborhood_bkd_piter<G, F, N> self_;
+    typedef internal::graph_relative_piter<mln_result(F), N, self_> super_;
 
     /// The Point_Site type.
     typedef mln_psite(N) psite;
@@ -129,134 +128,134 @@ namespace mln
 
   private:
     /// An iterator on the set of adjacent edges.
-    typename super_::sites_t::const_reverse_iterator i_; 
+    typename super_::sites_t::const_reverse_iterator i_;
   };
 
 
 
 # ifndef MLN_INCLUDE_ONLY
 
-  /*-------------------------------------.
-  | graph_neighborhood_fwd_piter<P, N>.  |
-  `-------------------------------------*/
+  /*----------------------------------------.
+  | graph_neighborhood_fwd_piter<G, F, N>.  |
+  `----------------------------------------*/
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
-  graph_neighborhood_fwd_piter<P, N>::graph_neighborhood_fwd_piter()
+  graph_neighborhood_fwd_piter<G, F, N>::graph_neighborhood_fwd_piter()
   {
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   template <typename Pref>
   inline
-  graph_neighborhood_fwd_piter<P, N>::graph_neighborhood_fwd_piter(const Neighborhood<N>& nbh,
+  graph_neighborhood_fwd_piter<G, F, N>::graph_neighborhood_fwd_piter(const Neighborhood<N>& nbh,
 								   const Pref& p_ref)
     : super_(p_ref)
   {
     this->change_target(exact(nbh));
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   bool
-  graph_neighborhood_fwd_piter<P, N>::is_valid_() const
+  graph_neighborhood_fwd_piter<G, F, N>::is_valid_() const
   {
     return i_ != this->sites_.end();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  graph_neighborhood_fwd_piter<P, N>::invalidate_()
+  graph_neighborhood_fwd_piter<G, F, N>::invalidate_()
   {
     i_ = this->sites_.end();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  graph_neighborhood_fwd_piter<P, N>::do_start_()
+  graph_neighborhood_fwd_piter<G, F, N>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.begin();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  graph_neighborhood_fwd_piter<P, N>::do_next_()
+  graph_neighborhood_fwd_piter<G, F, N>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   mln_psite(N)
-  graph_neighborhood_fwd_piter<P, N>::compute_p_() const
+  graph_neighborhood_fwd_piter<G, F, N>::compute_p_() const
   {
-    return graph_psite<P>(this->center().site_set(), *i_);
+    return internal::vertex_psite<G, F>(this->center().site_set(), *i_);
   }
 
 
-  /*-------------------------------------.
-  | graph_neighborhood_bkd_piter<P, N>.  |
-  `-------------------------------------*/
+  /*----------------------------------------.
+  | graph_neighborhood_bkd_piter<G, F, N>.  |
+  `----------------------------------------*/
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
-  graph_neighborhood_bkd_piter<P, N>::graph_neighborhood_bkd_piter()
+  graph_neighborhood_bkd_piter<G, F, N>::graph_neighborhood_bkd_piter()
   {
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   template <typename Pref>
   inline
-  graph_neighborhood_bkd_piter<P, N>::graph_neighborhood_bkd_piter(const Neighborhood<N>& nbh,
+  graph_neighborhood_bkd_piter<G, F, N>::graph_neighborhood_bkd_piter(const Neighborhood<N>& nbh,
 								   const Pref& p_ref)
     : super_(p_ref)
   {
     this->change_target(exact(nbh));
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   bool
-  graph_neighborhood_bkd_piter<P, N>::is_valid_() const
+  graph_neighborhood_bkd_piter<G, F, N>::is_valid_() const
   {
     return i_ != this->sites_.rend();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  graph_neighborhood_bkd_piter<P, N>::invalidate_()
+  graph_neighborhood_bkd_piter<G, F, N>::invalidate_()
   {
     i_ = this->sites_.rend();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  graph_neighborhood_bkd_piter<P, N>::do_start_()
+  graph_neighborhood_bkd_piter<G, F, N>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.rbegin();
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   void
-  graph_neighborhood_bkd_piter<P, N>::do_next_()
+  graph_neighborhood_bkd_piter<G, F, N>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename N>
+  template <typename G, typename F, typename N>
   inline
   mln_psite(N)
-  graph_neighborhood_bkd_piter<P, N>::compute_p_() const
+  graph_neighborhood_bkd_piter<G, F, N>::compute_p_() const
   {
-    return graph_psite<P>(this->center().site_set(), *i_);
+    return internal::vertex_psite<G, F>(this->center().site_set(), *i_);
   }
 
 
diff --git a/milena/mln/core/image/graph_psite.hh b/milena/mln/core/image/graph_psite.hh
deleted file mode 100644
index 23b0638..0000000
--- a/milena/mln/core/image/graph_psite.hh
+++ /dev/null
@@ -1,341 +0,0 @@
-// 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.
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef MLN_CORE_IMAGE_GRAPH_PSITE_HH
-# define MLN_CORE_IMAGE_GRAPH_PSITE_HH
-
-/// \file mln/core/image/graph_psite.hh
-/// \brief Definition of a graph-based psite.
-
-# include <mln/core/internal/pseudo_site_base.hh>
-
-# include <mln/core/site_set/p_graph.hh>
-
-/* FIXME: This class shares a lot with line_graph_psite.  Factor as
-   much as possible.  */
-
-// FIXME: Rename graph_psite as p_graph_psite, and move this
-// to core/site_set.
-
-
-namespace mln
-{
-
-  // Forward declaration.
-  template <typename P> class p_graph;
-  template <typename P> class graph_psite;
-
-
-  /// \brief Point site associated to a mln::graph_image.
-  ///
-  /// \arg \p P The type of the site.
-  template <typename P>
-  class graph_psite
-    : public internal::pseudo_site_base_< const P&, graph_psite<P> >
-  {
-    typedef graph_psite<P> self_;
-
-  public:
-    // This associated type is important to know that this particular
-    // pseudo site knows the site set it refers to.
-    typedef p_graph<P> target;
-
-    /// Construction and assignment.
-    /// \{
-    graph_psite();
-    graph_psite(const p_graph<P>& pg_, util::vertex_id id);
-    /// \}
-
-    /// Psite manipulators.
-    /// \{
-    /// Is this psite valid?
-    bool is_valid() const;
-    /// Invalidate this psite.
-    void invalidate();
-    /// \}
-
-    /// Site set manipulators.
-    /// \{
-    /// \brief Get the site set (shortcut for *target()).
-    /// \pre Member plg_ is non null.
-    const target& site_set() const;
-
-    /// Get a pointer to the target site_set.
-    const target* target_() const;
-    /// Set the target site_set.
-    void change_target(const target& new_target);
-    /// \}
-
-    /// Proxy manipulators.
-    /// \{
-    /// Return the site corresponding to this psite.
-    const P& subj_();
-    /// \}
-
-    /// Vertex id manipulators.
-    //// \{
-    /// Return the vertex id of this point site.
-    util::vertex_id vertex_id() const;
-    /// Set the vertex id of this point site.
-    void change_vertex_id(const util::vertex_id& id);
-    /// Increment the vertex id of this point site.
-    void inc_vertex_id();
-    /// Increment the vertex id of this point site.
-    void dec_vertex_id();
-    /// \}
-
-  private:
-    /// Site-related members.
-    /// \{
-    /// Update the site corresponding to this psite.
-    void update_();
-    // The site corresponding to this psite.
-    P p_;
-    /// \}
-
-  private:
-    /// Graph-related members.
-    /// \{
-    /// The p_graph this point site belongs to.
-   const target* pg_;
-    /// The id of the vertex this psite is pointing towards.
-    util::vertex_id id_;
-    /// \}
-  };
-
-
-  /// Comparison of two mln::graph_psite<P> instances.
-  /// \{
-  /* FIXME: Shouldn't those comparisons be part of a much general
-     mechanism?  */
-
-  /// \brief Is \a lhs equal to \a rhs?
-  ///
-  /// \pre Arguments \a lhs and \a rhs must belong to the same
-  /// mln::p_graph.
-  template <typename P>
-  bool
-  operator==(const graph_psite<P>& lhs, const graph_psite<P>& rhs);
-
-  /// \brief Is \a lhs not equal to \a rhs?
-  ///
-  /// \pre Arguments \a lhs and \a rhs must belong to the same
-  /// mln::p_graph.
-  template <typename P>
-  bool
-  operator!=(const graph_psite<P>& lhs, const graph_psite<P>& rhs);
-
-  /// \brief Is \a lhs ``less'' than \a rhs?
-  ///
-  /// This comparison is required by algorithms sorting psites.
-  ///
-  /// \pre Arguments \a lhs and \a rhs must belong to the same
-  /// mln::p_graph.
-  template <typename P>
-  bool
-  operator< (const graph_psite<P>& lhs, const graph_psite<P>& rhs);
-  /// \}
-
-
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const graph_psite<P>& p);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-  template <typename P>
-  inline
-  graph_psite<P>::graph_psite()
-    : pg_(0)
-  {
-  }
-
-  template <typename P>
-  inline
-  graph_psite<P>::graph_psite(const p_graph<P>& g, util::vertex_id id)
-    // FIXME: Use change_target instead.
-    : pg_(&g),
-      id_(id)
-  {
-    update_();
-  }
-
-  template <typename P>
-  inline
-  bool
-  graph_psite<P>::is_valid() const
-  {
-    /* FIXME: Instead of `plg_->gr_->nvertices()', we should have
-       something like `run_->has_edge_id(id_)' (see the implementation of
-       p_run_psite.  */
-    return pg_ && id_ < pg_->gr_->nvertices();
-  }
-
-  template <typename P>
-  inline
-  void
-  graph_psite<P>::invalidate()
-  {
-    /* FIXME: Instead of `plg_->gr_->nvertices()', we should have
-       something like `run_->has_edge_id(id_)' (see the implementation of
-       p_run_psite.  */
-    id_ = pg_->gr_->nvertices();
-  }
-
-  template <typename P>
-  inline
-  const p_graph<P>&
-  graph_psite<P>::site_set() const
-  {
-    mln_precondition(target_());
-    return *target_();
-  }
-
-  template <typename P>
-  inline
-  const p_graph<P>*
-  graph_psite<P>::target_() const
-  {
-    return pg_;
-  }
-
-  template <typename P>
-  inline
-  void
-  graph_psite<P>::change_target(const target& new_target)
-  {
-    pg_ = &new_target;
-    invalidate();
-  }
-
-  // FIXME: Write or extend a test to exercise this method.
-  template <typename P>
-  inline
-  const P&
-  graph_psite<P>::subj_()
-  {
-    return p_;
-  }
-
-  template <typename P>
-  inline
-  util::vertex_id
-  graph_psite<P>::vertex_id() const
-  {
-    return id_;
-  }
-
-  template <typename P>
-  inline
-  void
-  graph_psite<P>::change_vertex_id(const util::vertex_id& id)
-  {
-    id_ = id;
-    if (is_valid())
-      update_();
-  }
-
-  template <typename P>
-  inline
-  void
-  graph_psite<P>::inc_vertex_id()
-  {
-    ++id_.to_equiv();
-    if (is_valid())
-      update_();
-  }
-
-  template <typename P>
-  inline
-  void
-  graph_psite<P>::dec_vertex_id()
-  {
-    --id_.to_equiv();
-    if (is_valid())
-      update_();
-  }
-
-  template <typename P>
-  inline
-  void
-  graph_psite<P>::update_()
-  {
-    mln_precondition(is_valid());
-    p_ = site_set().point_from_id(id_);
-  }
-
-
-  /*--------------.
-  | Comparisons.  |
-  `--------------*/
-
-  template <typename P>
-  bool
-  operator==(const graph_psite<P>& lhs, const graph_psite<P>& rhs)
-  {
-    mln_assertion(lhs.target_() == rhs.target_());
-    return lhs.vertex_id() == rhs.vertex_id();
-  }
-
-  template <typename P>
-  bool
-  operator!=(const graph_psite<P>& lhs, const graph_psite<P>& rhs)
-  {
-    mln_assertion(lhs.target_() == rhs.target_());
-    return lhs.vertex_id() != rhs.vertex_id();
-  }
-
-  template <typename P>
-  bool
-  operator< (const graph_psite<P>& lhs, const graph_psite<P>& rhs)
-  {
-    mln_assertion(lhs.target_() == rhs.target_());
-    return lhs.vertex_id() < rhs.vertex_id();
-  }
-
-
-  /*------------------.
-  | Pretty-printing.  |
-  `------------------*/
-
-  template <typename P>
-  inline
-  std::ostream&
-  operator<<(std::ostream& ostr, const graph_psite<P>& p)
-  {
-    return ostr << p.unproxy_();
-  }
-
-# endif // ! MLN_INCLUDE_ONLY
-
-
-} // end of mln
-
-#endif // MLN_CORE_IMAGE_GRAPH_PSITE_HH
diff --git a/milena/mln/core/image/graph_window_piter.hh b/milena/mln/core/image/graph_window_piter.hh
index d9191ee..af15998 100644
--- a/milena/mln/core/image/graph_window_piter.hh
+++ b/milena/mln/core/image/graph_window_piter.hh
@@ -31,26 +31,22 @@
 /// \file   mln/core/image/graph_window_piter.hh
 /// \brief  Definition of a point iterator on a graph window.
 
-# include <mln/core/internal/graph_vicinity_piter.hh>
-
-/* FIXME: Due to the poor interface of mln::p_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
+# include <mln/core/internal/graph_relative_piter.hh>
 
 namespace mln
 {
 
-  /*-------------------------------.
-  | graph_window_fwd_piter<P, W>.  |
-  `-------------------------------*/
+  /*----------------------------------.
+  | graph_window_fwd_piter<G, F, W>.  |
+  `----------------------------------*/
 
   /// \brief Forward iterator on graph window.
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   class graph_window_fwd_piter :
-    public internal::graph_vicinity_piter_< P, W, graph_window_fwd_piter<P, W> >
+    public internal::graph_relative_piter< mln_result(F), W, graph_window_fwd_piter<G, F, W> >
   {
-    typedef graph_window_fwd_piter<P, W> self_;
-    typedef internal::graph_vicinity_piter_<P, W, self_> super_;
+    typedef graph_window_fwd_piter<G, F, W> self_;
+    typedef internal::graph_relative_piter<mln_result(F), W, self_> super_;
 
   public:
     /// The Point_Site type.
@@ -82,21 +78,21 @@ namespace mln
 
   private:
     /// An iterator on the set of adjacent vertices.
-    typename super_::sites_t::const_iterator i_; 
+    typename super_::sites_t::const_iterator i_;
   };
 
 
-  /*-------------------------------.
-  | graph_window_bkd_piter<P, W>.  |
-  `-------------------------------*/
+  /*----------------------------------.
+  | graph_window_bkd_piter<G, F, W>.  |
+  `----------------------------------*/
 
   /// \brief Backward iterator on graph window.
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   class graph_window_bkd_piter :
-    public internal::graph_vicinity_piter_< P, W, graph_window_bkd_piter<P, W> >
+    public internal::graph_relative_piter< mln_result(F), W, graph_window_bkd_piter<G, F, W> >
   {
-    typedef graph_window_bkd_piter<P, W> self_;
-    typedef internal::graph_vicinity_piter_<P, W, self_> super_;
+    typedef graph_window_bkd_piter<G, F, W> self_;
+    typedef internal::graph_relative_piter<mln_result(F), W, self_> super_;
 
   public:
     /// The Point_Site type.
@@ -128,7 +124,7 @@ namespace mln
 
   private:
     /// An iterator on the set of adjacent vertices.
-    typename super_::sites_t::const_reverse_iterator i_; 
+    typename super_::sites_t::const_reverse_iterator i_;
   };
 
 
@@ -136,126 +132,126 @@ namespace mln
 # ifndef MLN_INCLUDE_ONLY
 
   /*-------------------------------.
-  | graph_window_fwd_piter<P, W>.  |
+  | graph_window_fwd_piter<G, F, W>.  |
   `-------------------------------*/
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
-  graph_window_fwd_piter<P, W>::graph_window_fwd_piter()
+  graph_window_fwd_piter<G, F, W>::graph_window_fwd_piter()
   {
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   template <typename Pref>
   inline
-  graph_window_fwd_piter<P, W>::graph_window_fwd_piter(const Window<W>& win,
+  graph_window_fwd_piter<G, F, W>::graph_window_fwd_piter(const Window<W>& win,
 						       const Pref& p_ref)
     : super_(p_ref)
   {
     this->change_target(exact(win));
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   bool
-  graph_window_fwd_piter<P, W>::is_valid_() const
+  graph_window_fwd_piter<G, F, W>::is_valid_() const
   {
     return i_ != this->sites_.end();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  graph_window_fwd_piter<P, W>::invalidate_()
+  graph_window_fwd_piter<G, F, W>::invalidate_()
   {
     i_ = this->sites_.end();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  graph_window_fwd_piter<P, W>::do_start_()
+  graph_window_fwd_piter<G, F, W>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.begin();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  graph_window_fwd_piter<P, W>::do_next_()
+  graph_window_fwd_piter<G, F, W>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   mln_psite(W)
-  graph_window_fwd_piter<P, W>::compute_p_() const
+  graph_window_fwd_piter<G, F, W>::compute_p_() const
   {
-    return graph_psite<P>(this->center().site_set(), *i_);
+    return internal::vertex_psite<G, F>(this->center().site_set(), *i_);
   }
 
 
   /*-------------------------------.
-  | graph_window_bkd_piter<P, W>.  |
+  | graph_window_bkd_piter<G, F, W>.  |
   `-------------------------------*/
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
-  graph_window_bkd_piter<P, W>::graph_window_bkd_piter()
+  graph_window_bkd_piter<G, F, W>::graph_window_bkd_piter()
   {
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   template <typename Pref>
   inline
-  graph_window_bkd_piter<P, W>::graph_window_bkd_piter(const Window<W>& win,
+  graph_window_bkd_piter<G, F, W>::graph_window_bkd_piter(const Window<W>& win,
 						       const Pref& p_ref)
     : super_(p_ref)
   {
     this->change_target(exact(win));
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   bool
-  graph_window_bkd_piter<P, W>::is_valid_() const
+  graph_window_bkd_piter<G, F, W>::is_valid_() const
   {
     return i_ != this->sites_.rend();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  graph_window_bkd_piter<P, W>::invalidate_()
+  graph_window_bkd_piter<G, F, W>::invalidate_()
   {
     i_ = this->sites_.rend();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  graph_window_bkd_piter<P, W>::do_start_()
+  graph_window_bkd_piter<G, F, W>::do_start_()
   {
     this->site_set().compute_sites_(*this);
     i_ = this->sites_.rbegin();
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   void
-  graph_window_bkd_piter<P, W>::do_next_()
+  graph_window_bkd_piter<G, F, W>::do_next_()
   {
     ++i_;
   }
 
-  template <typename P, typename W>
+  template <typename G, typename F, typename W>
   inline
   mln_psite(W)
-  graph_window_bkd_piter<P, W>::compute_p_() const
+  graph_window_bkd_piter<G, F, W>::compute_p_() const
   {
-    return graph_psite<P>(this->center().site_set(), *i_);
+    return internal::vertex_psite<G, F>(this->center().site_set(), *i_);
   }
 
 # endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/image/image2d.hh b/milena/mln/core/image/image2d.hh
index 45c62bc..edf0a40 100644
--- a/milena/mln/core/image/image2d.hh
+++ b/milena/mln/core/image/image2d.hh
@@ -55,7 +55,7 @@
 namespace mln
 {
 
-  // Fwd decl.
+  // Forward declaration.
   template <typename T> struct image2d;
 
 
@@ -255,7 +255,7 @@ namespace mln
 
 
 
-  // Fwd decl.
+  // Forward declaration
 
   template <typename T>
   void init_(tag::border_t, unsigned& bdr, const image2d<T>& model);
diff --git a/milena/mln/core/internal/graph_iter_base.hh b/milena/mln/core/internal/graph_iter_base.hh
deleted file mode 100644
index 2d7297c..0000000
--- a/milena/mln/core/internal/graph_iter_base.hh
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (C) 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_CORE_INTERNAL_GRAPH_ITER_BASE_HH
-# define MLN_CORE_INTERNAL_GRAPH_ITER_BASE_HH
-
-# include <mln/core/concept/iterator.hh>
-# include <mln/core/concept/proxy.hh>
-
-/// \file   mln/core/internal/graph_iter_base.hh
-/// \brief  Base class for graph iterators.
-
-namespace mln
-{
-
-  namespace internal
-  {
-
-    /// Base class for graph iterators
-    /// \p G graph type.
-    /// \p S the type of the data pointed by the iterator.
-    /// For instance : edge, vertex....
-    template<typename G, typename S>
-    class graph_iterator_base
-      : public Iterator< graph_iterator_base<G> >,
-	public internal::proxy_impl< const S&, graph_iterator_base<G> >
-    {
-      public:
-	/// Constructors.
-	/// \{
-	graph_iterator_base();
-	graph_iterator_base(const G& g);
-	/// \}
-
-	/// Iterator interface.
-	/// \{
-	/// Test if the iterator is valid.
-	bool is_valid() const;
-	/// Invalidate the iterator.
-	void invalidate();
-
-	/// Start an iteration.
-	void start();
-
-	/// Go to the next value.
-	void next_();
-
-	/// Return current index
-	unsigned index() const;
-	/// \}
-
-	/// Proxy.
-	/// \{
-	/// Proxy subject
-	const S& subj_();
-	/// \}
-
-      protected:
-	const G *g_;
-	unsigned i_;
-    };
-
-
-    template<typename G, typename S>
-    class graph_fwd_iterator_base
-      : public Iterator< graph_fwd_iterator_base<G> >,
-	public internal::proxy_impl< const S&, graph_fwd_iterator_base<G> >
-    {
-      public:
-	/// Construction and assignment.
-	/// \{
-	graph_fwd_iterator_base();
-	graph_fwd_iterator_base(const G& g);
-	/// \}
-
-	/// Manipulation.
-	/// \{
-	/// Test if the iterator is valid.
-	bool is_valid() const;
-	/// Invalidate the iterator.
-	void invalidate();
-	/// \}
-
-	/// Start an iteration.
-	void start();
-
-	/// Go to the next value.
-	void next_();
-
-	/// Return current index
-	unsigned index() const;
-
-	/// Proxy.
-	/// \{
-	/// Proxy Subject type
-	typedef const mln_vertex(G)& q_subject;
-
-	/// Proxy subject
-	q_subject subj_();
-	/// \}
-
-      protected:
-	const G *g_;
-	unsigned i_;
-    };
-
-  } // End of namespace mln::internal.
-
-} // End of namespace mln.
-
-#endif // !MLN_CORE_INTERNAL_GRAPH_ITER_BASE_HH
diff --git a/milena/mln/core/internal/graph_vicinity_piter.hh b/milena/mln/core/internal/graph_relative_piter.hh
similarity index 61%
rename from milena/mln/core/internal/graph_vicinity_piter.hh
rename to milena/mln/core/internal/graph_relative_piter.hh
index b51ab97..5b09421 100644
--- a/milena/mln/core/internal/graph_vicinity_piter.hh
+++ b/milena/mln/core/internal/graph_relative_piter.hh
@@ -25,45 +25,31 @@
 // reasons why the executable file might be covered by the GNU General
 // Public License.
 
-#ifndef MLN_CORE_INTERNAL_GRAPH_VICINITY_PITER_HH
-# define MLN_CORE_INTERNAL_GRAPH_VICINITY_PITER_HH
+#ifndef MLN_CORE_INTERNAL_GRAPH_RELATIVE_PITER_HH
+# define MLN_CORE_INTERNAL_GRAPH_RELATIVE_PITER_HH
 
-/// \file   mln/core/internal/graph_vicinity_piter.hh
+/// \file   mln/core/internal/graph_relative_piter.hh
 /// \brief  Factored implementation for point iterators on a graph windows
-/// and graph neighborhoods, called "vicinities".
+/// and graph neighborhoods.
 
 # include <set>
 
 # include <mln/core/internal/site_relative_iterator_base.hh>
-# include <mln/core/site_set/p_graph.hh>
-# include <mln/core/image/graph_psite.hh>
 
 /* FIXME: Factor those classes:
 
-   - mln::internal::graph_vicinity_piter.hh
-   - mln::internal::line_graph_vicinity_piter.hh  */
-
-/* FIXME: Due to the poor interface of mln::p_graph and
-   mln::util::graph, we show to much implementation details here.
-   Enrich their interfaces to avoid that.  */
-
+   - mln::internal::graph_relative_piter.hh
+   - mln::internal::line_graph_relative_piter.hh  */
 
 namespace mln
 {
-  // Fwd decls.
-  template <typename P> class p_graph;
-  template <typename P> class graph_psite;
-
-  // FIXME: Consider renaming graph_vicinity_piter_ as
-  // graph_relative_piter_.
-
 
   namespace internal
   {
 
     /// \brief Base for iterator on a graph vicinity.
     template <typename P, typename S, typename E>
-    class graph_vicinity_piter_
+    class graph_relative_piter
       : public internal::site_relative_iterator_base< S, E >
     {
     public:
@@ -74,8 +60,8 @@ namespace mln
       // FIXME: Dummy value.
       typedef void mesh;
 
-      // The type of the set of vicinity sites (adjacent vertex ids).
-      typedef std::set<util::vertex_id> sites_t;
+      // The type of the set of sites (adjacent vertex ids).
+      typedef std::set<unsigned> sites_t;
 
     public:
       /// Return the set of sites (adjacent vertex ids).
@@ -84,9 +70,9 @@ namespace mln
     protected:
       /// Construction.
       /// \{
-      graph_vicinity_piter_();
+      graph_relative_piter();
       template <typename Pref>
-      graph_vicinity_piter_(const Pref& p_ref);
+      graph_relative_piter(const Pref& p_ref);
       /// \}
 
     protected:
@@ -94,52 +80,34 @@ namespace mln
       sites_t sites_;
     };
 
-
-    /// Print an mln::line_graph_vicinity_piter_<P, S, E>.
-    template <typename P, typename S, typename E>
-    inline
-    std::ostream&
-    operator<<(std::ostream& ostr, const graph_vicinity_piter_<P, S, E>& p);
-
-
-
 # ifndef MLN_INCLUDE_ONLY
 
     template <typename P, typename S, typename E>
     inline
-    graph_vicinity_piter_<P, S, E>::graph_vicinity_piter_()
+    graph_relative_piter<P, S, E>::graph_relative_piter()
     {
     }
 
     template <typename P, typename S, typename E>
     template <typename Pref>
     inline
-    graph_vicinity_piter_<P, S, E>::graph_vicinity_piter_(const Pref& p_ref)
+    graph_relative_piter<P, S, E>::graph_relative_piter(const Pref& p_ref)
     {
       center_at(p_ref);
     }
 
     template <typename P, typename S, typename E>
     inline
-    std::set<util::vertex_id>&
-    graph_vicinity_piter_<P, S, E>::sites()
+    std::set<unsigned>&
+    graph_relative_piter<P, S, E>::sites()
     {
       return sites_;
     }
 
-
-    template <typename P, typename S, typename E>
-    inline
-    std::ostream&
-    operator<<(std::ostream& ostr, const graph_vicinity_piter_<P, S, E>& p)
-    {
-      return ostr << p.unproxy_();
-    }
-
 # endif // ! MLN_INCLUDE_ONLY
 
   } // end of namespace mln::internal
 
 } // end of namespace mln
 
-#endif // ! MLN_CORE_INTERNAL_GRAPH_VICINITY_PITER_HH
+#endif // ! MLN_CORE_INTERNAL_GRAPH_RELATIVE_PITER_HH
diff --git a/milena/mln/core/internal/site_relative_iterator_base.hh b/milena/mln/core/internal/site_relative_iterator_base.hh
index eeb2092..9b3a7d4 100644
--- a/milena/mln/core/internal/site_relative_iterator_base.hh
+++ b/milena/mln/core/internal/site_relative_iterator_base.hh
@@ -191,8 +191,7 @@ namespace mln
     const mln_psite(S)&
     site_relative_iterator_base<S,E>::subj_()
     {
-      mln_psite(S) p_now = exact(this)->compute_p_();
-      mln_assertion(p_now == p_);
+      mln_assertion(exact(this)->compute_p_() == p_);
       return p_;
     }
 
diff --git a/milena/mln/core/site_set/p_edges.hh b/milena/mln/core/site_set/p_edges.hh
index 6a62f8b..2ce48b8 100644
--- a/milena/mln/core/site_set/p_edges.hh
+++ b/milena/mln/core/site_set/p_edges.hh
@@ -65,9 +65,10 @@ namespace mln
     typedef p_edges<G, F> self_;
     typedef internal::site_set_base_< typename F::result, self_ > super_;
 
+  public:
+    /// Type of the graph this site set is based on.
     typedef G graph_t;
 
-  public:
     /// \brief Construct a graph edge psite set from a graph and a function.
     ///
     /// \param gr The graph upon which the graph edge psite set is built.
@@ -118,7 +119,7 @@ namespace mln
     /// Return the graph associated to this site set
     const graph_t& graph() const;
     /// Return the mapping function.
-    F function() const;
+    const F& function() const;
     /// \}
 
   private:
@@ -231,7 +232,7 @@ namespace mln
 
   template <typename G, typename F>
   inline
-  F
+  const F&
   p_edges<G, F>::function() const
   {
     return f_;
@@ -241,11 +242,7 @@ namespace mln
   bool
   operator==(const p_edges<G, F>& lhs, const p_edges<G, F>& rhs)
   {
-    /* FIXME: We should not rely on pointer equality here, as graph
-       will soon become shells using (shared) tracked pointers to
-       actual data.  So, delegate the equality test to the graphs
-       themselves.  */
-    return (*lhs.g_) == (*rhs.g_);
+    return lhs.graph() == rhs.graph();
   }
 
   template <typename G, typename F>
diff --git a/milena/mln/core/site_set/p_graph_piter.hh b/milena/mln/core/site_set/p_graph_piter.hh
index 886be0d..ac356f3 100644
--- a/milena/mln/core/site_set/p_graph_piter.hh
+++ b/milena/mln/core/site_set/p_graph_piter.hh
@@ -139,8 +139,8 @@ namespace mln
   p_graph_piter<S,I>::start_()
   {
     iter_.start();
-      if (this->is_valid())
-	update_();
+    if (this->is_valid())
+      update_();
   }
 
   template <typename S, typename I>
diff --git a/milena/mln/core/site_set/p_vertices.hh b/milena/mln/core/site_set/p_vertices.hh
index cbae9fd..3b9eb82 100644
--- a/milena/mln/core/site_set/p_vertices.hh
+++ b/milena/mln/core/site_set/p_vertices.hh
@@ -138,7 +138,7 @@ namespace mln
     /// Return the graph associated to this site set (const version)
     const graph_t& graph() const;
     /// Return the association function.
-    F function() const;
+    const F& function() const;
     /// \}
 
   private:
@@ -293,7 +293,7 @@ namespace mln
 
   template <typename G, typename F>
   inline
-  F
+  const F&
   p_vertices<G, F>::function() const
   {
     return f_;
diff --git a/milena/mln/core/var.hh b/milena/mln/core/var.hh
index 39e5fa0..dfec471 100644
--- a/milena/mln/core/var.hh
+++ b/milena/mln/core/var.hh
@@ -40,5 +40,10 @@
   typeof(Expr) Var = Expr;			\
   typedef typeof(Expr) Var##_t
 
+#define mln_const_VAR(Var, Expr)		\
+						\
+  const typeof(Expr) Var = Expr;		\
+  typedef const typeof(Expr) Var##_t
+
 
 #endif // ! MLN_CORE_VAR_HH
diff --git a/milena/mln/labeling/blobs.hh b/milena/mln/labeling/blobs.hh
index 5711ac7..9f521a9 100644
--- a/milena/mln/labeling/blobs.hh
+++ b/milena/mln/labeling/blobs.hh
@@ -76,7 +76,7 @@ namespace mln
 
       namespace generic
       {
-	
+
 	template <typename I, typename N, typename L>
 	mln_ch_value(I, L)
 	  blobs_(const I& input, const N& nbh, L& nlabels)
@@ -122,10 +122,10 @@ namespace mln
 		  }
 		while (! qu.is_empty());
 	      }
-      
+
 	  return output;
 	}
-	
+
       } // end of namespace mln::labeling::impl::generic
 
 
diff --git a/milena/mln/util/internal/graph_psite_base.hh b/milena/mln/util/internal/graph_psite_base.hh
index 38431a8..8e5a515 100644
--- a/milena/mln/util/internal/graph_psite_base.hh
+++ b/milena/mln/util/internal/graph_psite_base.hh
@@ -222,7 +222,7 @@ namespace mln
       const typename graph_psite_base<V, P, S, E>::site&
       graph_psite_base<V, P, S, E>::to_site() const
       {
-        return t_->function()(v_);
+        return t_->function()(v_.id());
       }
 
     } // end of namespace internal
diff --git a/milena/tests/core/image/graph_image.cc b/milena/tests/core/image/graph_image.cc
index 7913589..34faf3a 100644
--- a/milena/tests/core/image/graph_image.cc
+++ b/milena/tests/core/image/graph_image.cc
@@ -33,13 +33,50 @@
 #include <mln/accu/bbox.hh>
 #include <mln/core/alias/box2d.hh>
 #include <mln/core/alias/point2d.hh>
-#include <mln/core/image/graph_image.hh>
+#include <mln/core/site_set/p_vertices.hh>
+
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/sub_image.hh>
+#include <mln/core/var.hh>
+#include <mln/core/routine/ops.hh>
+#include <mln/literal/ops.hh>
+#include <mln/fun/ops.hh>
+#include <mln/value/ops.hh>
 #include <mln/core/image/graph_elt_window.hh>
-#include <mln/core/image/graph_window_piter.hh>
+#include <mln/core/image/graph_elt_neighborhood.hh>
 
-#include <mln/draw/graph.hh>
-#include <mln/debug/iota.hh>
+#include <mln/fun/i2v/array.hh>
+#include <mln/fun/p2v/iota.hh>
+
+#include <mln/util/graph.hh>
+
+#include <mln/debug/graph.hh>
+//#include <mln/debug/iota.hh>
 #include <mln/debug/println.hh>
+#include <mln/core/concept/function.hh>
+
+template <typename S>
+struct viota_t : public mln::Function_p2v< viota_t<S> >
+{
+  typedef unsigned result;
+
+  viota_t(unsigned size)
+  {
+    v_.resize(size);
+    for (unsigned i = 0; i < size; ++i)
+      v_[i] = 10 + i;
+  }
+
+  unsigned
+  operator()(const mln_psite(S)& p) const
+  {
+    return v_[p.v().id()];
+  }
+
+  protected:
+    std::vector<result> v_;
+};
+
 
 
 int main()
@@ -64,18 +101,19 @@ int main()
   */
 
   // Points associated to vertices.
-  std::vector<point2d> points;
-  points.push_back(point2d(0,0)); // Point associated to vertex 0.
-  points.push_back(point2d(2,2)); // Point associated to vertex 1.
-  points.push_back(point2d(0,4)); // Point associated to vertex 2.
-  points.push_back(point2d(4,3)); // Point associated to vertex 3.
-  points.push_back(point2d(4,4)); // Point associated to vertex 4.
+  typedef fun::i2v::array<point2d> fpoint_t;
+  fpoint_t points(5);
+  points(0) = point2d(0,0); // Point associated to vertex 0.
+  points(1) = point2d(2,2); // Point associated to vertex 1.
+  points(2) = point2d(0,4); // Point associated to vertex 2.
+  points(3) = point2d(4,3); // Point associated to vertex 3.
+  points(4) = point2d(4,4); // Point associated to vertex 4.
 
   // Edges.
-  util::graph<point2d> g;
+  util::graph g;
   // Populate the graph with vertices.
   for (unsigned i = 0; i < points.size(); ++i)
-    g.add_vertex (points[i]);
+    g.add_vertex();
   // Populate the graph with edges.
   g.add_edge(0, 1);
   g.add_edge(1, 2);
@@ -89,37 +127,31 @@ int main()
   | Graph image support.  |
   `----------------------*/
 
-  p_graph<point2d> pg(g);
-
-  // Check adjacencies of vertex 1.
-  mln_assertion( pg.adjacent(1, 0));
-  mln_assertion(!pg.adjacent(1, 1));
-  mln_assertion( pg.adjacent(1, 2));
-  mln_assertion( pg.adjacent(1, 3));
-  mln_assertion(!pg.adjacent(1, 4));
+  typedef p_vertices<util::graph, fpoint_t> S;
+  S pv(g, points);
 
   /*-------------.
   | Graph image.  |
   `-------------*/
 
-  // Values ("empty" vector).
-  std::vector<int> values(5);
-  // Graph image.
-  typedef graph_image<point2d, int> ima_t;
-  ima_t ima(pg, values);
-  // Initialize values.
-  debug::iota(ima);
-  // Compute the bounding box of IMA.
-  /* FIXME: mln::graph_image should automatically feature a bbox when
-     its parameter P is akin to a point.  */
-  accu::bbox<point2d> a;
-  for (std::vector<point2d>::const_iterator i = points.begin();
-       i != points.end(); ++i)
-      a.take(*i);
-  box2d bbox = a.to_result();
+  // Graph values.
+  viota_t<S> iota(5);
+
+  // Create graph image.
+  mln_const_VAR(ima, (iota | pv));
+
+  {
+    // Compute the bounding box of 'ima'.
+    accu::bbox<point2d> a;
+    mln_piter_(ima_t) p(ima.domain());
+    for_all(p)
+      a.take(p);
+    box2d bbox = a.to_result();
+    mln_assertion(bbox == make::box2d(5, 5));
+
   // Print the image.
   /* FIXME: Unfortunately, displaying graph images is not easy right
-     now (2008-02-05).  We could use 
+     now (2008-02-05).  We could use
 
        debug::println(ima);
 
@@ -128,40 +160,84 @@ int main()
      interface of graph_image to work with points (not psites).
      Moreover, this implementation only shows *values*, not the graph
      itslef.
- 
-     An alternative is to use draw::graph (which, again, is misnamed),
+
+     An alternative is to use debug::graph,
      but it doesn't show the values, only the vertices and edges of the
      graph.
 
-     The current solution is a mix between draw::graph and hand-made
+     The current solution is a mix between debug::graph and hand-made
      iterations.  */
-  image2d<int> ima_rep(bbox);
-  // We use the value 9 in draw::graph instead of the default (which is
-  // 1) to represent edges to distinguish it from vertices holding a
-  // value of 1.
-  draw::graph (ima_rep, ima, 9);
-  debug::println (ima_rep);
+    image2d<int> ima_rep(bbox);
 
+  // We use the value 9 in debug::graph to represent edges to distinguish it
+  // from vertices holding a value of 1.
+    debug::graph(ima_rep, pv, 1, 9);
+    debug::println(ima_rep);
+  }
 
   /*------------.
   | Iterators.  |
   `------------*/
 
-  // Manual iteration over the domain of IMA.
+  // iteration over the domain of IMA.
   mln_piter_(ima_t) p(ima.domain());
   for_all (p)
     std::cout << "ima (" << p << ") = " << ima(p) << std::endl;
 
-  // Manual iterations over the neighborhoods of each point site of IMA.
-  typedef graph_elt_window<point2d> win_t;
-  win_t win;
-  mln_qiter_(win_t) q(win, p);
-  for_all (p)
   {
-    std::cout << "neighbors of " << p << " (" << ima(p) << "), "
-	      << "including the site itself:" << std::endl;
-    for_all (q)
-      std::cout << "  " << q << " (level = " << ima(q) << ")" << std::endl;
+    // Window - Forward iteration
+    typedef graph_elt_window<util::graph, fpoint_t> win_t;
+    win_t win;
+    mln_qiter_(win_t) q(win, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
+		<< "including the site itself:" << std::endl;
+      for_all (q)
+	std::cout << "  " << q << " (level = " << ima(q) << ")" << std::endl;
+    }
+  }
+
+  {
+    // Window - Backward iteration
+    typedef graph_elt_window<util::graph, fpoint_t> win_t;
+    win_t win;
+    mln_bkd_qiter_(win_t) q(win, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
+		<< "including the site itself:" << std::endl;
+      for_all (q)
+	std::cout << "  " << q << " (level = " << ima(q) << ")" << std::endl;
+    }
+  }
+
+  {
+    // Neighborhood - Forward iteration
+    typedef graph_elt_neighborhood<util::graph, fpoint_t> neigh_t;
+    neigh_t neigh;
+    mln_niter_(neigh_t) n(neigh, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
+		<< "including the site itself:" << std::endl;
+      for_all (n)
+	std::cout << "  " << n << " (level = " << ima(n) << ")" << std::endl;
+    }
+  }
+
+  {
+    // Neighborhood - Backward iteration
+    typedef graph_elt_neighborhood<util::graph, fpoint_t> neigh_t;
+    neigh_t neigh;
+    mln_bkd_niter_(neigh_t) n(neigh, p);
+    for_all (p)
+    {
+      std::cout << "neighbors of " << p << " (" << ima(p) << "), "
+		<< "including the site itself:" << std::endl;
+      for_all (n)
+	std::cout << "  " << n << " (level = " << ima(n) << ")" << std::endl;
+    }
   }
   std::cout << std::endl;
 }
-- 
1.5.6.5
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        From: Maxime van Noppen <yabo(a)lrde.epita.fr>
To: olena-patches(a)lrde.epita.fr
Subject: r2723: Implement a simple filter on the max_tree
  URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
ChangeLog:
2008-10-29  Maxime van Noppen  <yabo(a)lrde.epita.fr>
	Implement a simple filter on the max_tree.
	* Makefile: Add nice rules.
	* max_tree.hh: Add to_ppm, compute_mean_colors and number_of_nodes.
	* v2.cc: Fix the getopt.
---
 Makefile    |    9 ++++++
 max_tree.hh |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 v2.cc       |   21 ++++++++++-----
 3 files changed, 105 insertions(+), 7 deletions(-)
Index: branches/cleanup-2008/milena/sandbox/classif/max_tree.hh
===================================================================
--- branches/cleanup-2008/milena/sandbox/classif/max_tree.hh	(revision 2722)
+++ branches/cleanup-2008/milena/sandbox/classif/max_tree.hh	(revision 2723)
@@ -12,9 +12,11 @@
 # include <mln/core/image/image3d.hh>
 # include <mln/core/alias/neighb2d.hh>
 # include <mln/value/int_u8.hh>
+# include <mln/value/rgb8.hh>
 # include <mln/io/pgm/load.hh>
 # include <mln/core/site_set/p_array.hh>
 # include <mln/debug/println.hh>
+# include <mln/io/ppm/save.hh>
 
 using namespace mln;
 
@@ -39,8 +41,13 @@
   image3d<unsigned> nb_represent;
   image3d<double> density;
 
+  //tags
+  image3d<bool> is_active;
+  image3d< algebra::vec<3, double> > mean_color;
+
   max_tree_(const I& f, const N& nbh)
-    : f(f), nbh(nbh), vol(f.domain()), nb_represent(f.domain()), density(f.domain())
+    : f(f), nbh(nbh), vol(f.domain()), nb_represent(f.domain()), density(f.domain()),
+      is_active(f.domain()), mean_color(f.domain())
   {
     run();
   }
@@ -139,6 +146,79 @@
     }
   }
 
+  void compute_mean_color()
+  {
+    level::fill(mean_color, make::vec(0, 0, 0));
+
+    mln_fwd_piter(S) p(s);
+    for_all(p)
+      mean_color(p) = make::vec(p[0], p[1], p[2]);
+
+    for_all(p)
+      mean_color(parent(p)) = (mean_color(parent(p)) + mean_color(p)) / 2.;
+  }
+
+  void simple_filter_1(int lambda)
+  {
+    level::fill(is_active, true);
+
+    mln_fwd_piter(S) p(s);
+    for_all(p)
+    {
+      if (vol(p) < lambda)
+	is_active(p) = false;
+    }
+  }
+
+  template < typename J >
+  void to_ppm(const J& ima, const std::string& file, unsigned f)
+  {
+    J out(ima.domain());
+    level::fill(out, value::rgb8(0, 0, 0));
+
+    mln_piter(J) p(ima.domain());
+    for_all(p)
+    {
+      point3d p3 = point3d(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f);
+
+      point3d node = p3;
+      if (not is_node(p3))
+      {
+	if (is_active(parent(p3)))
+	  goto write;
+
+	node = parent(p3);
+      }
+
+      while (not is_active(node))
+	node = parent(node);
+
+write:
+      out(p) = value::rgb8(static_cast<unsigned char>(mean_color(node)[0] * f),
+	                   static_cast<unsigned char>(mean_color(node)[1] * f),
+			   static_cast<unsigned char>(mean_color(node)[2] * f));
+      //out(p) = value::rgb8(mean_color(node)[0] * f, mean_color(node)[1] * f, mean_color(node)[2] * f);
+    }
+
+    io::ppm::save(out, file);
+  }
+
+  unsigned number_of_nodes()
+  {
+    p_array<point> node;
+
+    mln_fwd_piter(S) p(s);
+    for_all(p)
+      if (is_node(p))
+	node.insert(p);
+
+    std::cout << s.nsites() << std::endl;
+    std::cout << parent.domain().nsites() << std::endl;
+    std::cout << node.nsites() << std::endl;
+
+    return s.nsites();
+  }
+
   bool is_root(const point& p) const
   {
     return parent(p) == p;
Index: branches/cleanup-2008/milena/sandbox/classif/v2.cc
===================================================================
--- branches/cleanup-2008/milena/sandbox/classif/v2.cc	(revision 2722)
+++ branches/cleanup-2008/milena/sandbox/classif/v2.cc	(revision 2723)
@@ -24,7 +24,7 @@
 mln::image3d<unsigned>
 fill_histo(const I& ima, int f)
 {
-  const value::int_u8 v = 255 / f; // FIXME
+  const value::int_u8 v = 256 / f; // FIXME
   image3d<unsigned> histo(v,v,v);
   level::fill(histo, 0);
   unsigned i = 0;
@@ -40,10 +40,10 @@
 
 template <typename I, typename J, typename N>
 unsigned
-compute_max_tree(const I& ima, const J& histo, const N& nbh, const unsigned f)
+compute_max_tree(const I& ima, const J& histo, const N& nbh, const unsigned f, int lambda)
 {
   max_tree_<J,N> run(histo, nbh);
-
+#if 0
   I out(ima.domain());
   mln_piter(I) p(ima.domain());
   for_all(p)
@@ -55,15 +55,22 @@
     out(p) = value::rgb8(pn[0] * f, pn[1] * f, pn[2] * f);
   }
   io::ppm::save(out, "tmp.ppm");
+#endif
 
+  //run.number_of_nodes();
   run.volume();
+  run.simple_filter_1(lambda);
+  run.compute_mean_color();
+  run.to_ppm(ima, "out.ppm", f);
+
+  //std::cout << " Number of nodes : " << run.number_of_nodes() << std::endl;
 }
 
 bool usage(int argc, char ** argv)
 {
-  if (argc != 3)
+  if (argc != 4)
   {
-    std::cout << "usage: " << argv[0] << " image div_factor" << std::endl;
+    std::cout << "usage: " << argv[0] << " image div_factor lambda" << std::endl;
     return false;
   }
   return true;
@@ -73,9 +80,11 @@
 {
   if (not usage(argc, argv))
     return 1;
+
   image2d<value::rgb8> ima;
   ima = io::ppm::load<value::rgb8>(argv[1]);
   const int div_factor = atoi(argv[2]);
+  const int lambda = atoi(argv[3]);
 
   //make histo
   image3d<unsigned> histo = fill_histo(ima,div_factor);
@@ -87,5 +96,5 @@
   //debug::println(phisto);
 
   // Compute max_tree
-  compute_max_tree(ima, histo, c6(), div_factor);
+  compute_max_tree(ima, histo, c6(), div_factor, lambda);
 }
Index: branches/cleanup-2008/milena/sandbox/classif/Makefile
===================================================================
--- branches/cleanup-2008/milena/sandbox/classif/Makefile	(revision 2722)
+++ branches/cleanup-2008/milena/sandbox/classif/Makefile	(revision 2723)
@@ -55,9 +55,18 @@
 	cat stdout.log
 	$(DISP) out.ppm &
 
+v2-check: $(V2)
+	./v2 $(IMG) $(DIV) $(LAMBDA) $(LOG)
+	cat stdout.log
+	$(DISP) out.ppm &
+
 valgrind: $(ICCVG_DBG)
 	valgrind --log-file=valgrind.log ./iccvg_dbg ../../img/lena.ppm $(DIV) $(LAMBDA) $(LOG)
 
 gdb: $(ICCVG_DBG)
 	echo "run ../../img/lena.ppm $(DIV) $(LAMBDA)" > gdb.cmd
 	gdb $(ICCVG_DBG) -x gdb.cmd
+
+v2-gdb: $(V2_DBG)
+	echo "run ../../img/lena.ppm $(DIV) $(LAMBDA) $(LOG)" > gdb.cmd
+	gdb $(V2_DBG) -x gdb.cmd
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    29 Oct '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
Index: ChangeLog
from  Alexandre Abraham  <abraham(a)lrde.epita.fr>
	INIM : nature filters and little bug fixes.
	* abraham/mln/trait: New.
	* abraham/mln/trait/images.hh: New
	    (mln::trait::default_image_morpher) : Adjust quant according
	      to new value quant..
	* abraham/mln/morpho/hit_or_miss.hh: New
	    (mln::morpho::hit_or_miss) : First implementation of hit or
	      miss algorithm.
	* abraham/mln/level/transform.hh: New
	    (mln::level::transform) : Add procedure.
	* abraham/mln/core/image/thru.hh:
	    Temporary trait modification.
	* abraham/mln/core/image/shell.hh:
	    Add include of function.hh.
	* abraham/mln/fun/meta/hue.hh: New
	    Allow direct access to hue.
	* abraham/mln/fun/meta/inty.hh: New
	    Allow direct access to intensity..
	* abraham/mln/fun/meta/sat.hh: New
	    Allow direct access to saturation..
	* abraham/mln/fun/v2v: New.
	* abraham/mln/fun/v2v/rgb_to_hsi.hh: New
	    Fix wrong conversion formula.
	* abraham/mln/binarization: New.
	* abraham/mln/binarization/binarization.hh: New
	    Fix call to level::transform procedure (output must be empty).
	* abraham/mln/value: New.
	* abraham/mln/value/builtin: New.
	* abraham/mln/value/builtin/symbolics.hh: New
	    Add min and max for bool traits.
	* nature/erosion.cc: New
	    Test of erosion filter.
	* nature/gradient.cc: New
	    Test of gradient filter.
	* nature/histo_hsi.cc: New
	    Decompose image in hsi format.
	* nature/hom.cc: New
	    First hit or miss test.
	* nature/opening.cc: New
	    Test of opening filter.
	* nature/Makefile: New.
 abraham/mln/binarization/binarization.hh |  106 +++++++++++++
 abraham/mln/core/image/shell.hh          |    1 
 abraham/mln/core/image/thru.hh           |   14 +
 abraham/mln/fun/meta/hue.hh              |   64 ++++++++
 abraham/mln/fun/meta/inty.hh             |   64 ++++++++
 abraham/mln/fun/meta/sat.hh              |   64 ++++++++
 abraham/mln/fun/v2v/rgb_to_hsi.hh        |  175 ++++++++++++++++++++++
 abraham/mln/level/transform.hh           |  209 +++++++++++++++++++++++++++
 abraham/mln/morpho/hit_or_miss.hh        |   84 ++++++++++
 abraham/mln/trait/images.hh              |  239 +++++++++++++++++++++++++++++++
 abraham/mln/value/builtin/symbolics.hh   |   76 +++++++++
 nature/Makefile                          |   16 ++
 nature/erosion.cc                        |   59 +++++++
 nature/gradient.cc                       |   59 +++++++
 nature/histo_hsi.cc                      |  166 +++++++++++++++++++++
 nature/hom.cc                            |   72 +++++++++
 nature/opening.cc                        |   59 +++++++
 17 files changed, 1527 insertions(+)
Index: abraham/mln/trait/images.hh
--- abraham/mln/trait/images.hh	(revision 0)
+++ abraham/mln/trait/images.hh	(revision 0)
@@ -0,0 +1,239 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// 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_IMAGES_HH
+# define MLN_TRAIT_IMAGES_HH
+
+/*! \file mln/trait/images.hh
+ *
+ * \brief Some base trait types for images.
+ *
+ * \todo Split this file into many.
+ *
+ * \todo the 'nature' prop is not set yet in image types.
+ */
+
+# 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>
+
+
+
+# define mln_trait_image_category(I) typename mln::trait::image_< I >::category
+# define mln_trait_image_speed(I)    typename mln::trait::image_< I >::speed
+# define mln_trait_image_size(I)     typename mln::trait::image_< I >::size
+
+# define mln_trait_image_value_access(I)     typename mln::trait::image_< I >::value_access
+# define mln_trait_image_value_storage(I)    typename mln::trait::image_< I >::value_storage
+# define mln_trait_image_value_browsing(I)   typename mln::trait::image_< I >::value_browsing
+# define mln_trait_image_value_io(I)         typename mln::trait::image_< I >::value_io
+# define mln_trait_image_pw_io(I)            typename mln::trait::image_< I >::pw_io
+# define mln_trait_image_vw_io(I)            typename mln::trait::image_< I >::vw_io
+# define mln_trait_image_vw_set(I)           typename mln::trait::image_< I >::vw_set
+# define mln_trait_image_value_alignement(I) typename mln::trait::image_< I>::value_alignement
+
+# define mln_trait_image_localization(I) typename mln::trait::image_< I >::localization
+# define mln_trait_image_dimension(I)    typename mln::trait::image_< I >::dimension
+
+# define mln_trait_image_ext_domain(I) typename mln::trait::image_< I >::ext_domain
+# define mln_trait_image_ext_value(I)  typename mln::trait::image_< I >::ext_value
+# define mln_trait_image_ext_io(I)     typename mln::trait::image_< I >::ext_io
+
+# define mln_trait_image_kind(I)   typename mln::trait::image_< I >::kind
+# define mln_trait_image_nature(I) typename mln::trait::image_< I >::nature
+# define mln_trait_image_quant(I)  typename mln::trait::image_< I >::quant
+
+
+// For value_io: I const => read_only, otherwise like I
+
+# define mln_internal_trait_image_value_io_from(I)	\
+							\
+  mlc_if( mlc_is_const(I),				\
+	  mln::trait::image::value_io::read_only,	\
+	  mln_trait_image_value_io(I) )
+
+
+# define mln_internal_trait_image_speed_from(I)						\
+											\
+  mlc_if( mlc_equal( mln_trait_image_speed(I), mln::trait::image::speed::fastest ),	\
+	  mln::trait::image::speed::fast,						\
+	  mln_trait_image_speed(I) )
+
+
+
+namespace mln
+{
+
+  // Primitive types.
+  template <typename T> struct image1d;
+  template <typename T> struct image2d;
+  template <typename T> struct image3d;
+  namespace pw { template <typename F, typename S> struct image; }
+  template <typename P, typename T> class rle_image;
+  template <typename P, typename T> class sparse_image;
+
+  // Morphers.
+  template <typename I, typename F> struct image_if_base;
+  template <typename I, typename D> class decorated_image;
+  template <typename I, typename S> class sub_image;
+  template <typename I> struct t_image;
+  template <typename I> class safe_image;
+  template <typename T, typename I> class cast_image_;
+  namespace value { template <unsigned n, typename I> struct stack_image; }
+
+
+  namespace trait
+  {
+
+    template <typename I>
+    struct undefined_image_
+    {
+      // misc
+      typedef undef category;
+      typedef undef speed;
+      typedef undef size;
+
+      // value
+      typedef undef vw_io;
+      typedef undef vw_set;
+      typedef undef value_alignement;
+      typedef undef value_access;
+      typedef undef value_storage;
+      typedef undef value_browsing;
+      typedef undef value_io;
+
+      // site
+      typedef undef pw_io;
+      typedef undef localization;
+      typedef undef dimension;
+
+      // extended domain
+      typedef undef ext_domain;
+      typedef undef ext_value;
+      typedef undef ext_io;
+
+      // data (I::value)
+      typedef undef kind;
+      typedef undef nature;
+      typedef undef quant;
+    };
+
+
+    template <typename I>
+    struct image_ : undefined_image_<I>
+    {
+    };
+
+
+    template <typename I>
+    struct image_<const I> : image_<I>
+    {
+      // FIXME: TODO: io cannot contain "write"...
+    };
+
+
+    template <typename T, typename I>
+    struct default_image_ : undefined_image_<I>
+    {
+    private:
+      typedef mlc_equal(mln_trait_value_quant(T),
+			trait::value::quant::high) is_high_quant_;
+    public:
+      typedef mln_trait_value_kind(T) kind;
+      typedef mlc_if( is_high_quant_,
+		      trait::image::quant::high,
+		      trait::image::quant::low ) quant;
+      // FIXME: typedef undef value;  // scalar, vectorial, structed
+
+      // speed is fast by default (neither "fastest" nor "slow")
+      typedef trait::image::speed::fast speed;
+    };
+
+
+    template <typename D, typename T, typename I>
+    struct default_image_morpher : default_image_<T, I>
+    {
+      // misc => delegation except for 'category'
+      typedef typename image_<D>::size  size;
+      typedef mln_internal_trait_image_speed_from(D) speed; // un-fastest
+
+      // value => delegation
+      typedef typename image_<D>::vw_io            vw_io;
+      typedef typename image_<D>::vw_set           vw_set;
+      typedef typename image_<D>::value_alignement value_alignement;
+      typedef typename image_<D>::value_access     value_access;
+      typedef typename image_<D>::value_storage    value_storage;
+      typedef typename image_<D>::value_browsing   value_browsing;
+      typedef mln_internal_trait_image_value_io_from(D) value_io; // un-write when D is const
+
+      // site => delegation
+      typedef typename image_<D>::pw_io        pw_io;
+      typedef typename image_<D>::localization localization;
+      typedef typename image_<D>::dimension    dimension;
+
+      // extended domain => delegation
+      typedef typename image_<D>::ext_domain ext_domain;
+      typedef typename image_<D>::ext_value  ext_value;
+      typedef typename image_<D>::ext_io     ext_io;
+
+      // data (I::value) => delegation
+      typedef typename image_<D>::nature nature;
+      typedef typename image_<D>::kind   kind;
+      // typedef typename image_<D>::quant  quant;
+      typedef
+      mlc_if(mlc_equal(typename value_<T>::quant, trait::value::quant::low),
+	// Then
+	trait::image::quant::low,
+	// Else
+	     mlc_if(mlc_equal(typename value_<T>::quant, trait::value::quant::high),
+		    // Then
+		    trait::image::quant::high,
+		    // Else
+		    undef)
+	     )
+	quant;
+
+    };
+
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+# include <mln/trait/image/print.hh>
+
+
+#endif // ! MLN_TRAIT_IMAGES_HH
Index: abraham/mln/morpho/hit_or_miss.hh
--- abraham/mln/morpho/hit_or_miss.hh	(revision 0)
+++ abraham/mln/morpho/hit_or_miss.hh	(revision 0)
@@ -0,0 +1,84 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_HIT_OR_MISS_HH
+# define MLN_MORPHO_HIT_OR_MISS_HH
+
+/*! \file mln/morpho/hit_or_miss.hh
+ *
+ * \brief Morphological gradient.
+ *
+ * \todo Save memory.
+ */
+
+# include <mln/morpho/includes.hh>
+# include <mln/arith/revert.hh>
+
+namespace mln
+{
+
+  namespace morpho
+  {
+
+    /*! Morphological hit or miss.
+     *
+     */
+    template <typename I, typename Wout, typename Win>
+    mln_concrete(I) hit_or_miss(const Image<I>& input, const Window<Wout>& win_out, const Window<Win>& win_in);
+
+
+    // FIXME : epaississement et amincissement
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    template <typename I, typename Wout, typename Win>
+    inline
+    mln_concrete(I) hit_or_miss(const Image<I>& input, const Window<Wout>& win_out, const Window<Win>& win_in)
+    {
+      trace::entering("morpho::hit_or_miss");
+      mln_precondition(exact(input).has_data());
+      mln_precondition(! exact(win_out).is_empty());
+      mln_precondition(! exact(win_in).is_empty());
+
+      mln_concrete(I) output = morpho::min(erosion(arith::revert(input), win_out),
+					   erosion(input, win_in));
+
+      mln_postcondition(test::positive(output));
+      trace::exiting("morpho::hit_or_miss");
+      return output;
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_HIT_OR_MISS_HH
Index: abraham/mln/level/transform.hh
--- abraham/mln/level/transform.hh	(revision 0)
+++ abraham/mln/level/transform.hh	(revision 0)
@@ -0,0 +1,209 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// 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_LEVEL_TRANSFORM_HH
+# define MLN_LEVEL_TRANSFORM_HH
+
+/*! \file mln/level/transform.hh
+ *
+ * \brief Transform the contents of an image into another one.
+ *
+ * \todo Clean this file + overload with pixel iterators.
+ *
+ * \todo Re-activate tests and make them static.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
+
+# include <mln/value/set.hh>
+# include <mln/value/lut_vec.hh>
+
+
+// Specializations are in:
+# include <mln/level/transform.spe.hh>
+
+
+namespace mln
+{
+
+  namespace level
+  {
+
+    /*! Transform the image \p input through a function \p f to set
+     *  the \p output image.
+     *
+     * \param[in] input The input image.
+     * \param[in] f The function.
+     * \param[out] output The result image.
+     *
+     * This routine runs: \n
+     * for all p of \p input, \p output(p) = \p f( \p input(p) ).
+     *
+     * \pre \p output.domain >= \p input.domain
+     */
+    template <typename I, typename F, typename O>
+    void transform(const Image<I>& input, const Function_v2v<F>& f,
+		   Image<O>& output);
+
+
+    template <typename I, typename F>
+    mln_ch_value(I, mln_result(F))
+    transform(const Image<I>& input, const Function_v2v<F>& f);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace internal
+    {
+      template <typename I, typename F, typename O>
+      inline
+      void transform_tests(const Image<I>& input,
+                           const Function_v2v<F>& f,
+                           Image<O>& output)
+      {
+	// Avoid a warning about an undefined variable when NDEBUG
+	// is not defined.
+	(void) input;
+        (void) f;
+        (void) output;
+
+        // Properties check
+	// FIXME: Re-activate!
+//         mln_precondition((mlc_is(mln_trait_image_pw_io(O),
+//                             trait::image::pw_io::read_write)::value ||
+//                      mlc_is(mln_trait_image_vw_io(O),
+//                             trait::image::vw_io::read_write)::value));
+
+        // FIXME Convert test
+	mlc_converts_to(mln_result(F), mln_value(O))::check();
+
+
+        // Dynamic tests
+	mln_precondition(exact(input).has_data());
+        mln_precondition(exact(output).domain() >= exact(input).domain());
+      }
+    } // end of namespace mln::level::internal
+
+
+    namespace impl
+    {
+
+
+      namespace generic
+      {
+
+        // Generic implementation.
+	template <typename I, typename F, typename O>
+	inline
+	void transform(const Image<I>& input_, const Function_v2v<F>& f_,
+			Image<O>& output_)
+	{
+          trace::entering("level::impl::generic::transform");
+
+
+	  const I& input  = exact(input_);
+	  const F& f      = exact(f_);
+          O& output       = exact(output_);
+
+          level::internal::transform_tests(input, f, output);
+
+          mlc_is(mln_trait_image_pw_io(O),
+                 trait::image::pw_io::read_write)::check();
+
+	  mln_piter(I) p(input.domain());
+	  for_all(p)
+	    output(p) = f(input(p));
+
+
+	  trace::exiting("level::impl::generic::transform");
+	}
+
+      } // end of namespace mln::level::impl::generic
+
+
+
+    // Facade.
+
+    namespace internal
+    {
+      template <typename I, typename F, typename O>
+      inline
+      void transform_(const Image<I>& input, const Function_v2v<F>& f,
+                      Image<O>& output)
+      {
+        trace::entering("level::transform");
+
+        mln_precondition(exact(output).domain() >= exact(input).domain());
+        transform_dispatch_(exact(input), exact(f), exact(output));
+
+        trace::exiting("level::transform");
+      }
+    }
+
+    } // end of namespace mln::level::impl
+
+    template <typename I, typename F, typename O>
+    inline
+    void transform(const Image<I>& input, const Function_v2v<F>& f,
+		    Image<O>& output)
+    {
+      trace::entering("level::transform");
+
+      mln_precondition(exact(input).has_data());
+      initialize(output, input);
+      impl::internal::transform_(input, f, output);
+
+      trace::exiting("level::transform");
+    }
+
+
+    template <typename I, typename F>
+    inline
+    mln_ch_value(I, mln_result(F))
+    transform(const Image<I>& input, const Function_v2v<F>& f)
+    {
+      trace::entering("level::transform");
+
+      mln_precondition(exact(input).has_data());
+      mln_ch_value(I, mln_result(F)) output;
+      initialize(output, input);
+      impl::internal::transform_(input, f, output);
+
+      trace::exiting("level::transform");
+      return output;
+    }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_TRANSFORM_HH
Index: abraham/mln/core/image/thru.hh
--- abraham/mln/core/image/thru.hh	(revision 2721)
+++ abraham/mln/core/image/thru.hh	(working copy)
@@ -39,6 +39,8 @@
 # include <mln/trait/images.hh>
 # include <mln/value/set.hh>
 # include <mln/core/image/shell.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/equal.hh>
 
 namespace mln
 {
@@ -69,6 +71,18 @@
       typedef trait::image::value_io::read_write      value_io;
       typedef trait::image::value_access::computed    value_access;
       typedef trait::image::value_storage::disrupted  value_storage;
+      typedef
+      mlc_if(mlc_equal(typename value_<mln_result(F)>::quant, trait::value::quant::low),
+	// Then
+	trait::image::quant::low,
+	// Else
+	     mlc_if(mlc_equal(typename value_<mln_result(F)>::quant, trait::value::quant::high),
+		    // Then
+		    trait::image::quant::high,
+		    // Else
+		    undef)
+	     )
+	quant;
     };
 
   } // end of namespace mln::trait
Index: abraham/mln/core/image/shell.hh
--- abraham/mln/core/image/shell.hh	(revision 2721)
+++ abraham/mln/core/image/shell.hh	(working copy)
@@ -28,6 +28,7 @@
 #ifndef MLN_CORE_VALUE_SHELL_HH
 # define MLN_CORE_VALUE_SHELL_HH
 
+# include <mln/core/concept/function.hh>
 # include <mln/core/concept/image.hh>
 
 namespace mln
Index: abraham/mln/fun/meta/hue.hh
--- abraham/mln/fun/meta/hue.hh	(revision 0)
+++ abraham/mln/fun/meta/hue.hh	(revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_FUN_META_HUE_HH
+# define MLN_FUN_META_HUE_HH
+
+# include <mln/value/hsi.hh>
+# include <mln/core/concept/meta_fun.hh>
+
+namespace mln {
+
+  namespace meta {
+
+    template <class H>
+    struct hue : impl< hue<H> > { typedef H value; };
+
+  };
+
+  template <class H, class S, class I>
+  struct function< meta::hue< value::hsi_<H, S, I> > > : public Function_v2w_w2v<function< meta::hue < value::hsi_<H, S, I> > > >
+  {
+    typedef value::hsi_<H, S, I> value;
+
+    typedef H result;
+    H read(const value& h)
+    {
+      return h.hue();
+    }
+
+    typedef H& lresult;
+    H& write(value& h)
+    {
+      return h.hue();
+    }
+  };
+
+
+};
+
+#endif // MLN_FUN_META_HUE_HH
Index: abraham/mln/fun/meta/inty.hh
--- abraham/mln/fun/meta/inty.hh	(revision 0)
+++ abraham/mln/fun/meta/inty.hh	(revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_FUN_META_INTY_HH
+# define MLN_FUN_META_INTY_HH
+
+# include <mln/value/hsi.hh>
+# include <mln/core/concept/meta_fun.hh>
+
+namespace mln {
+
+  namespace meta {
+
+    template <class H>
+    struct inty : impl< inty<H> > { typedef H value; };
+
+  };
+
+  template <class H, class S, class I>
+  struct function< meta::inty< value::hsi_<H, S, I> > > : public Function_v2w_w2v<function< meta::inty < value::hsi_<H, S, I> > > >
+  {
+    typedef value::hsi_<H, S, I> value;
+
+    typedef H result;
+    H read(const value& h)
+    {
+      return h.inty();
+    }
+
+    typedef H& lresult;
+    H& write(value& h)
+    {
+      return h.inty();
+    }
+  };
+
+
+};
+
+#endif // MLN_FUN_META_INTY_HH
Index: abraham/mln/fun/meta/sat.hh
--- abraham/mln/fun/meta/sat.hh	(revision 0)
+++ abraham/mln/fun/meta/sat.hh	(revision 0)
@@ -0,0 +1,64 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_FUN_META_SAT_HH
+# define MLN_FUN_META_SAT_HH
+
+# include <mln/value/hsi.hh>
+# include <mln/core/concept/meta_fun.hh>
+
+namespace mln {
+
+  namespace meta {
+
+    template <class H>
+    struct sat : impl< sat<H> > { typedef H value; };
+
+  };
+
+  template <class H, class S, class I>
+  struct function< meta::sat< value::hsi_<H, S, I> > > : public Function_v2w_w2v<function< meta::sat < value::hsi_<H, S, I> > > >
+  {
+    typedef value::hsi_<H, S, I> value;
+
+    typedef H result;
+    H read(const value& h)
+    {
+      return h.sat();
+    }
+
+    typedef H& lresult;
+    H& write(value& h)
+    {
+      return h.sat();
+    }
+  };
+
+
+};
+
+#endif // MLN_FUN_META_SAT_HH
Index: abraham/mln/fun/v2v/rgb_to_hsi.hh
--- abraham/mln/fun/v2v/rgb_to_hsi.hh	(revision 0)
+++ abraham/mln/fun/v2v/rgb_to_hsi.hh	(revision 0)
@@ -0,0 +1,175 @@
+// Copyright (C) 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.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_FUN_V2V_RGB_TO_HSI_HH
+# define MLN_FUN_V2V_RGB_TO_HSI_HH
+
+#include <cmath>
+
+#include <mln/value/rgb8.hh>
+#include <mln/math/round.hh>
+
+#include <mln/value/hsi.hh>
+
+
+// FIXME: Split interface and implementation.
+
+namespace mln
+{
+
+
+  namespace fun
+  {
+
+    namespace v2v
+    {
+
+      template <typename T_hsi>
+      struct f_rgb_to_hsi_ : public Function_v2v< f_rgb_to_hsi_<T_hsi> >
+      {
+	typedef T_hsi result;
+
+	template <typename T_rgb>
+	T_hsi operator()(const T_rgb& rgb) const
+	{
+	  // Locals.
+
+	  // wtf?
+
+// 	  static const double sqrt3_3 = std::sqrt(3) / 3;
+// 	  static const double inv_sqrt6 = 1 / std::sqrt(6);
+// 	  static const double inv_sqrt2 = 1 / std::sqrt(2);
+
+ 	  T_hsi hsi;
+
+// 	  double alpha = inv_sqrt2 * rgb.green() - inv_sqrt2 * rgb.blue();
+// 	  double beta =
+// 	    2 * inv_sqrt6 * rgb.red() -
+// 	    inv_sqrt6 * rgb.green() -
+// 	    inv_sqrt6 * rgb.blue();
+
+
+// 	  hsi.hue() = atan2(beta, alpha) / 3.1415 * 180.0;
+// 	  if (hsi.hue() < 0)
+// 	    hsi.hue() = hsi.hue() + 360.0;
+// 	  mln_invariant(hsi.hue() >= 0);
+// 	  hsi.sat() = std::sqrt(alpha * alpha + beta * beta);
+// 	  hsi.inty() =
+// 	    sqrt3_3 * rgb.red() +
+// 	    sqrt3_3 * rgb.green() +
+// 	    sqrt3_3 * rgb.blue();
+
+	  hsi.inty() = (rgb.red() + rgb.green() + rgb.blue()) / 3;
+
+	  typename T_rgb::red_t min = rgb.red();
+	  if (rgb.green() < min)
+	    min = rgb.green();
+
+	  if (rgb.blue() < min)
+	    min = rgb.blue();
+
+
+	  if (hsi.inty())
+	    hsi.sat() = (1 - (double) 3 * min / (double)(rgb.red() + rgb.green() + rgb.blue())) * 100;
+	  else
+	    hsi.sat() = 0; // this is black for any value of saturation
+
+	  if (hsi.sat())
+	    hsi.hue() = acos( 0.5 * (2 * rgb.red() - rgb.green() - rgb.blue()) /
+			      std::sqrt((rgb.red() - rgb.green()) * (rgb.red() - rgb.green()) + (rgb.red() - rgb.blue()) * (rgb.green() - rgb.blue()))) / 3.1415 * 180.0;
+	    else
+	      hsi.hue() = 0; // this is grey for any value of hue
+
+ 	  if (hsi.hue() < 0)
+ 	    hsi.hue() = hsi.hue() + 360.0;
+
+ 	  mln_invariant(hsi.hue() >= 0);
+ 	  mln_invariant(hsi.hue() < 360);
+ 	  mln_invariant(hsi.sat() >= 0);
+ 	  mln_invariant(hsi.inty() >= 0);
+
+	  return hsi;
+	}
+      };
+
+      typedef f_rgb_to_hsi_<value::hsi_f> f_rgb_to_hsi_f_t;
+
+      // FIXME: Warning: global object.
+      f_rgb_to_hsi_f_t f_rgb_to_hsi_f;
+
+
+      template <typename T_rgb>
+      struct f_hsi_to_rgb_ : public Function_v2v< f_hsi_to_rgb_<T_rgb> >
+      {
+	typedef T_rgb result;
+
+	template <typename T_hsi>
+	T_rgb operator()(const T_hsi& hsi) const
+	{
+	  typedef typename T_rgb::red_t   red_t;
+	  typedef typename T_rgb::green_t green_t;
+	  typedef typename T_rgb::blue_t  blue_t;
+
+	  static math::round<red_t>   to_r;
+	  static math::round<green_t> to_g;
+	  static math::round<blue_t>  to_b;
+
+	  static const float
+	    sqrt3_3 = std::sqrt(3) / 3,
+	    inv_sqrt6 = 1 / std::sqrt(6),
+	    inv_sqrt2 = 1 / std::sqrt(2);
+
+	  float
+	    h = hsi.hue() / 180.0 * 3.1415,
+	    alpha = hsi.sat() * std::cos(h),
+	    beta = hsi.sat() * std::sin(h);
+
+
+	  red_t   r = to_r(sqrt3_3 * hsi.inty() + 2 * inv_sqrt6 * beta);
+	  green_t g =
+	    to_g(sqrt3_3 * hsi.inty() + inv_sqrt2 * alpha - inv_sqrt6 * beta);
+	  blue_t  b =
+	    to_b(sqrt3_3 * hsi.inty() - inv_sqrt2 * alpha - inv_sqrt6 * beta);
+
+	  T_rgb rgb(r, g, b);
+
+	  return rgb;
+	}
+      };
+
+      typedef f_hsi_to_rgb_<value::rgb8> f_hsi_to_rgb_3x8_t;
+
+      // FIXME: Warning: global object.
+      f_hsi_to_rgb_3x8_t f_hsi_to_rgb_3x8;
+
+    } // end of namespace fun::v2v
+
+  } // end of namespace fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_RGB_TO_HSI_HH
Index: abraham/mln/binarization/binarization.hh
--- abraham/mln/binarization/binarization.hh	(revision 0)
+++ abraham/mln/binarization/binarization.hh	(revision 0)
@@ -0,0 +1,106 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// 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_BINARIZATION_BINARIZATION_HH
+# define MLN_BINARIZATION_BINARIZATION_HH
+
+/*! \file mln/binarization/threshold.hh
+ *
+ * \brief Threshold the contents of an image into another binary one.
+ */
+
+# include <mln/core/concept/function.hh>
+# include <mln/level/transform.hh>
+
+
+namespace mln
+{
+
+  namespace binarization
+  {
+
+    /*! Thresholds the values of \p input so that they can be stored in
+     *  the \p output binary image.
+     *
+     * \param[in] input The input image.
+     * \param[in] fun The thresholding function, from value(I) to bool.
+     *
+     * for_all(p), output(p) = fun(p)
+     *
+     */
+    template <typename I, typename F>
+    inline
+    mln_concrete_ch_value(I, bool)
+    binarization(const Image<I>& input, const Function_v2b<F>& fun);
+
+# ifndef MLN_INCLUDE_ONLY
+
+    namespace impl
+    {
+
+      template <typename I, typename F>
+      inline
+      mln_concrete_ch_value(I, bool)
+      binarization_(const I& input, const Function_v2b<F>& fun)
+      {
+	trace::entering("binarization::impl::binarization_");
+	mln_concrete_ch_value(I, bool) output;
+
+	level::transform(input, fun, output);
+
+	trace::exiting("binarization::impl::binarization_");
+	return output;
+      }
+
+    } // end of namespace mln::binarization::impl
+
+
+    template <typename I, typename F>
+    inline
+    mln_concrete_ch_value(I, bool)
+    binarization(const Image<I>& input, const Function_v2b<F>& fun)
+    {
+      trace::entering("binarization::binarization");
+      mln_precondition(exact(input).has_data());
+      mlc_is(mln_trait_value_nature(mln_value(I)),
+	     trait::value::nature::scalar)::check();
+
+      mln_concrete_ch_value(I, bool) output(exact(input).domain());
+      output = impl::binarization_(exact(input), fun);
+
+      trace::exiting("binarization::binarization");
+      return output;
+    }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+  } // end of namespace mln::binarization
+
+} // end of namespace mln
+
+
+#endif // ! MLN_BINARIZATION_BINARIZATION_HH
Index: abraham/mln/value/builtin/symbolics.hh
--- abraham/mln/value/builtin/symbolics.hh	(revision 0)
+++ abraham/mln/value/builtin/symbolics.hh	(revision 0)
@@ -0,0 +1,76 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// 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_VALUE_BUILTIN_SYMBOLICS_HH
+# define MLN_VALUE_BUILTIN_SYMBOLICS_HH
+
+/*! \file mln/value/builtin/symbolics.hh
+ *
+ * \brief Some definitions about built-in symbolic types.
+ */
+
+# include <mln/value/concept/built_in.hh>
+# include <mln/value/concept/symbolic.hh>
+# include <mln/trait/value_.hh>
+
+
+namespace mln
+{
+
+
+  template <>
+  struct category< bool >
+  {
+    typedef value::Built_In< value::Symbolic<void> > ret;
+  };
+
+
+  namespace trait
+  {
+
+    template <>
+    struct value_< bool>
+    {
+      typedef value::nature::symbolic nature;
+      typedef value::kind::binary     kind;
+
+      enum {
+	nbits = 1,
+	card  = 2
+      };
+      typedef value::quant::low       quant;
+
+      static bool min() { return false; }
+      static bool max() { return true;}
+    };
+
+  } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_BUILTIN_SYMBOLICS_HH
Index: nature/erosion.cc
--- nature/erosion.cc	(revision 0)
+++ nature/erosion.cc	(revision 0)
@@ -0,0 +1,59 @@
+// 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.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/morpho/gradient.hh>
+
+
+int main(int argc, const char * argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+
+  if (argc < 2) {
+    std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
+    return 1;
+  }
+
+  for (unsigned i = 1; i < argc; ++i)
+    {
+      image2d<int_u8> ima;
+      io::pgm::load(ima, argv[i]);
+
+      win::hline2d f(31);
+      border::thickness = 16;
+
+      io::pgm::save( morpho::erosion(ima, f),
+		     "out.pgm" );
+    }
+}
Index: nature/gradient.cc
--- nature/gradient.cc	(revision 0)
+++ nature/gradient.cc	(revision 0)
@@ -0,0 +1,59 @@
+// 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.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/morpho/gradient.hh>
+
+
+int main(int argc, const char * argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+
+  if (argc < 2) {
+    std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
+    return 1;
+  }
+
+  for (unsigned i = 1; i < argc; ++i)
+    {
+      image2d<int_u8> ima;
+      io::pgm::load(ima, argv[i]);
+
+      win::rectangle2d rect(5, 5);
+      border::thickness = 5;
+
+      io::pgm::save( morpho::gradient(ima, rect),
+		     "out.pgm" );
+    }
+}
Index: nature/histo_hsi.cc
--- nature/histo_hsi.cc	(revision 0)
+++ nature/histo_hsi.cc	(revision 0)
@@ -0,0 +1,166 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// 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 <iterator>
+#include <string>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/thru.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/site_set/p_set.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/hsi.hh>
+
+#include <mln/fun/v2v/rgb_to_hsi.hh>
+#include <mln/fun/meta/hue.hh>
+#include <mln/fun/meta/sat.hh>
+#include <mln/fun/meta/inty.hh>
+
+#include <mln/level/compare.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/accu/histo.hh>
+#include <mln/histo/compute.hh>
+#include <mln/level/transform.hh>
+#include <mln/level/fill.hh>
+
+using namespace mln;
+using namespace value;
+
+typedef int_u16 u_t;
+
+
+template <typename I>
+void save_histo(Image<I> &i, std::string &name, unsigned width, unsigned height, unsigned npoints)
+{
+  I& ima = exact(i);
+
+  histo::data<u_t> h = histo::compute(ima);
+
+  double norm = (double) npoints / (double) height;
+
+  image2d<bool> output(height + 1, width + 1, 0);
+  level::fill(output, true);
+
+  mln_viter(mln::value::set<u_t>) v(h.vset());
+  for_all(v)
+    if (h(v) > 0)
+      for (u_t i = 0; i < h(v)/norm; ++i)
+	{
+	  // std::cout << height - i << ", " << (u_t)v << std::endl;
+	  output(point2d(height - i, (u_t)v)) = false;
+	}
+
+  io::pbm::save(output, name);
+}
+
+int main (int argc, const char* argv [])
+{
+  if (argc < 2) {
+    std::cerr << "usage: " << argv[0] << " in.ppm [other_files.ppm]" << std::endl;
+    return 1;
+  }
+
+  for (unsigned i = 1; i < argc; ++i)
+    {
+
+      image2d<rgb8> input;
+      io::ppm::load(input, argv[i]);
+
+      unsigned npoints = input.ncols() * input.nrows();
+
+      image2d<hsi_f> hsi = level::transform(input, fun::v2v::f_rgb_to_hsi_f);
+      thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > h(hsi);
+      cast_image_<u_t, thru<mln::meta::hue<hsi_f>, image2d<hsi_f> > > hue(h);
+
+      std::string n(argv[i]);
+      n.erase(n.length() - 4);
+      io::pgm::save(hue, n.append("_hue.pgm"));
+
+      image2d<hsi_f>::piter p(hsi.domain());
+      float m = 0;
+      for_all(p)
+      {
+	if (h(p) > m)
+	  m = h(p);
+      }
+      std::cout << std::endl << m << std::endl;
+
+
+
+      std::string name(argv[i]);
+      name.erase(name.length() - 4);
+      save_histo(hue, name.append("_hue.pbm"), 256, 360, npoints);
+
+      thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > s(hsi);
+      cast_image_<u_t, thru<mln::meta::sat<hsi_f>, image2d<hsi_f> > > sat(s);
+
+      n = argv[i];
+      n.erase(n.length() - 4);
+      io::pgm::save(sat, n.append("_sat.pgm"));
+
+      m = 0;
+      for_all(p)
+      {
+	if (s(p) > m)
+	  m = s(p);
+      }
+      std::cout << std::endl << m << std::endl;
+
+
+      name = argv[i];
+      name.erase(name.length() - 4);
+      save_histo(sat, name.append("_sat.pbm"), 100, 2560, npoints);
+
+      thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > l(hsi);
+      cast_image_<u_t, thru<mln::meta::inty<hsi_f>, image2d<hsi_f> > > inty(l);
+
+      n = argv[i];
+      n.erase(n.length() - 4);
+      io::pgm::save(inty, n.append("_inty.pgm"));
+
+
+      m = 0;
+      for_all(p)
+      {
+	if (l(p) > m)
+	  m = l(p);
+      }
+      std::cout << std::endl << m << std::endl;
+
+
+      name = argv[i];
+      name.erase(name.length() - 4);
+      save_histo(inty, name.append("_inty.pbm"), 256, 256, npoints);
+    }
+}
Index: nature/hom.cc
--- nature/hom.cc	(revision 0)
+++ nature/hom.cc	(revision 0)
@@ -0,0 +1,72 @@
+// 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.
+
+
+#include <mln/core/image/image2d.hh>
+
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pbm/save.hh>
+
+#include <mln/value/int_u8.hh>
+
+
+
+#include <mln/level/transform.hh>
+#include <mln/binarization/threshold.hh>
+#include <mln/estim/mean.hh>
+#include <mln/morpho/hit_or_miss.hh>
+
+
+
+int main(int argc, const char * argv[])
+{
+  using namespace mln;
+  using value::int_u16;
+
+  if (argc < 2) {
+    std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
+    return 1;
+  }
+
+  for (unsigned i = 1; i < argc; ++i)
+    {
+      image2d<int_u16> ima;
+      io::pgm::load(ima, argv[i]);
+
+      // Compute the mean
+      int_u16 mean = estim::mean(ima);
+
+      win::rectangle2d rectout(3, 3);
+      win::rectangle2d rectin(5, 5);
+
+
+      io::pbm::save( morpho::hit_or_miss(binarization::threshold(ima, mean), rectout, rectin),
+		     "out.pbm" );
+    }
+}
Index: nature/opening.cc
--- nature/opening.cc	(revision 0)
+++ nature/opening.cc	(revision 0)
@@ -0,0 +1,59 @@
+// 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.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/win/rectangle2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/morpho/opening.hh>
+
+
+int main(int argc, const char * argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+
+  if (argc < 2) {
+    std::cerr << "usage: " << argv[0] << " in.pgm [other_files.pgm]" << std::endl;
+    return 1;
+  }
+
+  for (unsigned i = 1; i < argc; ++i)
+    {
+      image2d<int_u8> ima;
+      io::pgm::load(ima, argv[i]);
+
+      win::rectangle2d rect(1, 51);
+      border::thickness = 100;
+
+      io::pgm::save( morpho::opening(ima, rect),
+		     "out.pgm" );
+    }
+}
Index: nature/Makefile
--- nature/Makefile	(revision 0)
+++ nature/Makefile	(revision 0)
@@ -0,0 +1,16 @@
+SRC=$(wildcard *.cc)
+OBJ=$(SRC:.cc=.o)
+EXEC=$(SRC:.cc=)
+CC=g++
+CXXFLAGS=-Wall -W -I ../abraham -I ../.. -g
+
+all: $(EXEC)
+
+clean:
+	rm -rf *.o
+	rm -rf *~
+
+distclean: clean
+	rm -rf $(EXEC)
+
+.PHONY: clean distclean
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    29 Oct '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Add a distance by propagation sample code.
	* geraud/skel.cc: New.
 skel.cc |  104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)
Index: geraud/skel.cc
--- geraud/skel.cc	(revision 0)
+++ geraud/skel.cc	(revision 0)
@@ -0,0 +1,104 @@
+# include <mln/core/var.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/core/site_set/p_queue_fast.hh>
+
+# include <mln/io/pbm/load.hh>
+# include <mln/io/pgm/save.hh>
+# include <mln/value/int_u8.hh>
+
+# include <mln/level/fill.hh>
+
+# include <mln/debug/println.hh>
+
+
+namespace mln
+{
+
+  template <typename D, typename I, typename N>
+  mln_ch_value(I, D)
+    distance(D, const I& input, const N& nbh)
+  {
+    const D M = mln_max(D);
+    mln_ch_value(I, D) output;
+    initialize(output, input);
+
+    mln_ch_value(I, bool) deja_vu;
+    initialize(deja_vu, input);
+    level::fill(deja_vu, input);
+
+    typedef mln_site(I) P;
+    p_queue_fast<P> q;
+
+    // Initialization.
+    {
+      level::fill(output, M);
+      mln_piter(I) p(input.domain());
+      mln_niter(N) n(nbh, p);
+      for_all(p)
+	if (input(p) == true) // p in object
+	  {
+	    output(p) = 0;
+	    for_all(n)
+	      if (input.domain().has(n) && input(n) == false) // n in background
+		{
+		  q.push(p);
+		  break;
+		}
+	  }
+    }
+
+    // Propagation.
+    {
+      P p;
+      mln_niter(N) n(nbh, p);
+      while (! q.is_empty())
+	{
+	  p = q.pop_front();
+	  for_all(n)
+	    if (input.domain().has(n) && output(n) == M)
+	      {
+		output(n) = output(p) + 1;
+		if (output(n) == M)
+		  {
+		    // Saturation so stop.
+		    q.clear();
+		    break;
+		  }
+		q.push(n);
+		deja_vu(n) = true;
+	      }
+	}
+    }
+
+    return output;
+  }
+
+
+} // mln
+
+
+
+void usage(char* argv[])
+{
+  std::cerr << "usage: " << argv[0] << " input.pbm output.pgm" << std::endl;
+  abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+  using namespace mln;
+  using value::int_u8;
+
+  if (argc != 3)
+    usage(argv);
+
+  image2d<bool> input;
+  io::pbm::load(input, argv[1]);
+
+  image2d<int_u8> output = distance(int_u8(), input, c4());
+  io::pgm::save(output, argv[2]);
+}
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    29 Oct '08
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
Index: ChangeLog
from  Alexandre Abraham  <abraham(a)lrde.epita.fr>
	Make meta-functions work with thru morpher.
	* abraham/tests/fun/meta/red.cc: Update example.
	* abraham/mln/core/image/thru.hh: .
	* abraham/mln/core/image/shell.hh: Fix result value.
	* abraham/mln/core/concept/meta_fun.hh:
	    (mln::meta::impl) : now templated by return type
	                        (necessary to typedef result).
	* abraham/mln/fun/meta/red.hh: .
 mln/core/concept/meta_fun.hh |   28 +++++++++++----------------
 mln/core/image/shell.hh      |   44 ++++++++++++++++++++++++++++++++++++++++---
 mln/core/image/thru.hh       |    2 -
 mln/fun/meta/red.hh          |    5 +---
 tests/fun/meta/red.cc        |    8 +++++--
 5 files changed, 62 insertions(+), 25 deletions(-)
Index: abraham/tests/fun/meta/red.cc
--- abraham/tests/fun/meta/red.cc	(revision 2689)
+++ abraham/tests/fun/meta/red.cc	(working copy)
@@ -14,8 +14,10 @@
   };
 
   template <class T>
-  struct function< meta::red, rgb<T> > : public Function_v2w_w2v<function< meta::red, rgb<T> > >
+  struct function< meta::red< rgb<T> > > : public Function_v2w_w2v<function< meta::red < rgb<T> > > >
   {
+    typedef rgb<T> value;
+
     typedef T result;
     T read(const rgb<T>& c)
     {
@@ -50,7 +52,9 @@
   c.r = 1;
   i(mln::point2d(2,1)) = c;
 
-  mln::thru<mln::meta::red, mln::image2d<C> > out(i);
+  mln::thru<mln::meta::red <C>, mln::image2d<C> > out(i);
+
+  mln_piter_(mln::image2d<C>) p(i.domain());
 
   for_all (p)
     std::cout << out(p) << std::endl;
Index: abraham/mln/core/image/thru.hh
--- abraham/mln/core/image/thru.hh	(revision 2689)
+++ abraham/mln/core/image/thru.hh	(working copy)
@@ -89,7 +89,7 @@
     typedef mln_result(F) rvalue;
 
     /// Return type of read-write access.
-    typedef shell<F,I> lvalue;
+    typedef shell<F,I> lvalue; // FIXME : if I is const or F is Function_v2v, there is no shell
 
     /// Skeleton.
     typedef thru< tag::value_<mln_result(F)>, tag::image_<I> > skeleton;
Index: abraham/mln/core/image/shell.hh
--- abraham/mln/core/image/shell.hh	(revision 2689)
+++ abraham/mln/core/image/shell.hh	(working copy)
@@ -57,7 +57,7 @@
   template <typename F, typename I>
   struct shell : shell_write<F, I, typename F::category> // FIXME : inherit of value_base or sth?
   {
-    typedef mln_value(I) value;
+    typedef typename F::result value;
 
     // Ctor
     shell(Image<I> &ima, const mln_site(I) &s);
@@ -66,7 +66,14 @@
     operator value ();
 
     // Write
-    mln_value(I) operator= (typename F::result);
+    value operator= (value);
+
+    // <<
+    // std::ostream& operator<<(std::ostream& ostr);
+
+    // >>
+    // std::istream& operator>>(std::istream& istr);
+
 
     protected :
       I &ima;
@@ -92,9 +99,10 @@
 
     // Write for everyone
   template <typename F, typename I>
-  mln_value(I) shell<F, I>::operator= (typename F::result v)
+  typename F::result shell<F, I>::operator= (typename F::result v)
   {
     set_(ima, s, v);
+    return v;
   }
 
   template <typename F, typename I>
@@ -111,6 +119,36 @@
     return ima(s);
   }
 
+//   template <typename F, typename I>
+//   std::ostream& shell<F, I>::operator<<(std::ostream& ostr)
+//   {
+//     ostr << ima(s);
+//     return ostr;
+//   }
+
+//   template <typename F, typename I>
+//   std::istream& shell<F, I>::operator>>(std::istream& istr)
+//   {
+//     ima(s) >> istr;
+//     return istr;
+//   }
+
+  template <typename F, typename I>
+  std::ostream& operator<<(std::ostream& ostr, shell<F, I> &s)
+  {
+    ostr << (typename shell<F, I>::value) s;
+    return ostr;
+  }
+
+  template <typename F, typename I>
+  std::istream& operator>>(std::istream& istr, shell<F, I> &s)
+  {
+    (typename shell<F, I>::value) s >> istr;
+    return istr;
+  }
+
+
+
 # endif // MLN_INCLUDE_ONLY
 
 }; // end of namespace mln
Index: abraham/mln/core/concept/meta_fun.hh
--- abraham/mln/core/concept/meta_fun.hh	(revision 2689)
+++ abraham/mln/core/concept/meta_fun.hh	(working copy)
@@ -39,7 +39,7 @@
 namespace mln
 {
 
-  template <class M, class T>
+  template <class M>
   struct function;
 
   namespace meta
@@ -49,27 +49,23 @@
     struct impl
     {
 
-      template <class T>
-      struct info
-      {
-	typedef function<M, T> F;
+      typedef function<M> F;
+      typedef typename F::value value;
 	typedef typename F::result result;
 	typedef typename F::lresult lresult;
-      };
+      typedef typename F::category category;
 
-      template <class T>
-      typename info<T>::result
-      operator()(const T& t) const
+      result
+      operator()(const value& t) const
       {
-	function<M,T> f;
+	F f;
 	return f.read(t);
       }
 
-      template <class T>
-      T&
-      f_1(typename info<T>::result v, T& t)
+      value&
+      f_1(result v, value& t)
       {
-	function<M,T> f;
+	F f;
 	f.write(t) = v;
 	return t;
       }
Index: abraham/mln/fun/meta/red.hh
--- abraham/mln/fun/meta/red.hh	(revision 2689)
+++ abraham/mln/fun/meta/red.hh	(working copy)
@@ -34,12 +34,11 @@
 
   namespace meta {
 
-    struct red : impl<red> { };
+    template <class T>
+    struct red : impl< red<T> > { typedef T value; };
 
   };
 
-  meta::red red; // fun obj
-
 };
 
 #endif // MLN_FUN_META_RED_HH
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        From: Jimmy Ma <jimmy.ma(a)lrde.epita.fr>
To: olena-patches(a)lrde.epita.fr
Subject: r2719: Update OCR preprocessing
  URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
ChangeLog:
2008-10-29  Jimmy Ma  <jimmy.ma(a)lrde.epita.fr>
	Update OCR preprocessing.
	* garrigues/ocr/ocr_with_preprocess.cc: Apply gaussian blur and
	  naive thresholding.
---
 ocr_with_preprocess.cc |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
Index: branches/cleanup-2008/milena/sandbox/garrigues/ocr/ocr_with_preprocess.cc
===================================================================
--- branches/cleanup-2008/milena/sandbox/garrigues/ocr/ocr_with_preprocess.cc	(revision 2718)
+++ branches/cleanup-2008/milena/sandbox/garrigues/ocr/ocr_with_preprocess.cc	(revision 2719)
@@ -37,7 +37,7 @@
 
 #include "resize.hh"
 #include "enlarge.hh"
-//#include "skeleton.hh"
+#include "skeleton.hh"
 #include <mln/linear/gaussian.hh>
 
 #include <mln/trace/all.hh>
@@ -96,17 +96,17 @@
   image2d<int_u8> output = enlarge(input, 1);
 
   // TODO CLEANUP
-#if 0
+#if 1
   // Blur.
   output = linear::gaussian(output, 1);
 #endif
 
-#if 0
+#if 1
   // Threshold
   mln_piter_(image2d<unsigned>) p(output.domain());
   for_all(p)
   {
-    output(p) = output(p) > 127 ? 1 : 0;
+    output(p) = output(p) > 150 ? 255 : 0;
   }
 #endif
 
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008
Index: ChangeLog
from  Thierry Geraud  <thierry.geraud(a)lrde.epita.fr>
	Few updates.
	* milena/tests/draw/line.cc: Fix missing update.
	* milena/mln/draw/line.hh: Make it safe.
	* milena/mln/morpho/closing_volume.hh (closing_volume): New
	overload with output as return.
	* milena/mln/morpho/all.hh: Better doc.
	(include): Update.
	* milena/sandbox/geraud/wst_edge.cc: Prefer volume closing over
	area closing.
 mln/draw/line.hh             |   12 +++++++-----
 mln/morpho/all.hh            |   20 +++++++-------------
 mln/morpho/closing_volume.hh |   12 ++++++++++++
 sandbox/geraud/wst_edge.cc   |    4 ++--
 tests/draw/line.cc           |    2 +-
 5 files changed, 29 insertions(+), 21 deletions(-)
Index: milena/tests/draw/line.cc
--- milena/tests/draw/line.cc	(revision 2717)
+++ milena/tests/draw/line.cc	(working copy)
@@ -47,7 +47,7 @@
   using namespace mln;
 
   point2d b = point2d(0,0), e = point2d(6,9);
-  line2d l(b, e);
+  p_line2d l(b, e);
   mln_assertion(l.nsites() == 10);
 
   image2d<bool> ima(10,10);
Index: milena/mln/draw/line.hh
--- milena/mln/draw/line.hh	(revision 2717)
+++ milena/mln/draw/line.hh	(working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -35,6 +35,7 @@
 
 # include <mln/core/concept/image.hh>
 # include <mln/core/site_set/p_line2d.hh>
+# include <mln/core/image/safe.hh>
 # include <mln/level/paste.hh>
 # include <mln/pw/image.hh>
 # include <mln/pw/cst.hh>
@@ -69,14 +70,15 @@
 
     template <typename I>
     inline
-    void line(Image<I>& ima,
+    void line(Image<I>& ima_,
 	      const mln_psite(I)& beg, const mln_psite(I)& end,
 	      const mln_value(I)& v)
     {
-      mln_precondition(exact(ima).has_data());
-      mln_precondition(exact(ima).has(beg) && exact(ima).has(end));
+      I& ima = exact(ima_);
+      mln_precondition(ima.has_data());
+      // if (! ima.has(beg) ||  ! ima.has(end)) trace::warning("out");
       level::paste(pw::cst(v) | p_line2d(beg, end),
-		   ima);
+		   safe(ima).rw());
     }
 
 # endif // ! MLN_INCLUDE_ONLY
Index: milena/mln/morpho/closing_volume.hh
--- milena/mln/morpho/closing_volume.hh	(revision 2717)
+++ milena/mln/morpho/closing_volume.hh	(working copy)
@@ -30,6 +30,8 @@
 
 /// \file mln/morpho/closing_volume.hh
 /// \brief Morphological volume closing.
+///
+/// \todo Clean!
 
 # include <mln/morpho/closing_attribute.hh>
 # include <mln/accu/volume.hh>
@@ -46,6 +48,16 @@
     void closing_volume(const Image<I>& input, const Neighborhood<N>& nbh,
 			std::size_t lambda, Image<O>& output);
 
+    template <typename I, typename N>
+    mln_concrete(I)
+    closing_volume(const Image<I>& input, const Neighborhood<N>& nbh, std::size_t lambda)
+    {
+      mln_concrete(I) output;
+      initialize(output, input);
+      closing_volume(input, nbh, lambda, output);
+      return output;
+    }
+
 
 # ifndef MLN_INCLUDE_ONLY
 
Index: milena/mln/morpho/all.hh
--- milena/mln/morpho/all.hh	(revision 2717)
+++ milena/mln/morpho/all.hh	(working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
 //
 // This file is part of the Olena Library.  This library is free
 // software; you can redistribute it and/or modify it under the terms
@@ -41,26 +41,18 @@
   namespace morpho
   {
 
-    /*!
-     * Namespace of morphological image processing routines
-     * implementation details.
-     *
-     */
+    /// Namespace of morphological image processing routines
+    /// implementations.
     namespace impl
     {
 
-      /*!
-       * Namespace of morphological image processing routines
-       * implementation generic implementations.
-       *
-       */
+      /// Namespace of morphological image processing routines
+      /// generic implementations.
       namespace generic
       {}
 
     }
-
   }
-
 }
 
 
@@ -88,6 +80,8 @@
 # include <mln/morpho/thinning.hh>
 # include <mln/morpho/top_hat.hh>
 
+# include <mln/morpho/elementary/all.hh>
+
 
 
 #endif // ! MLN_MORPHO_ALL_HH
Index: milena/sandbox/geraud/wst_edge.cc
--- milena/sandbox/geraud/wst_edge.cc	(revision 2717)
+++ milena/sandbox/geraud/wst_edge.cc	(working copy)
@@ -33,7 +33,7 @@
 # include <mln/extension/fill.hh>
 
 # include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_area.hh>
+# include <mln/morpho/closing_volume.hh>
 
 # include <mln/debug/println.hh>
 
@@ -315,7 +315,7 @@
   }
 
 
-  level::paste( morpho::closing_area(edge, e2e, lambda), edge );
+  level::paste( morpho::closing_volume(edge, e2e, lambda), edge );
   
 
   image2d<unsigned> label(ima.bbox(), 0);
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0