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
April 2009
- 11 participants
- 187 discussions
* apps/statues/test-mesh-complex-skel.in: New test.
* apps/statues/Makefile.am (TESTS): Add test-mesh-complex-skel.
---
milena/ChangeLog | 7 +++++++
milena/apps/statues/Makefile.am | 1 +
milena/apps/statues/test-mesh-complex-skel.in | 10 ++++++++++
3 files changed, 18 insertions(+), 0 deletions(-)
create mode 100644 milena/apps/statues/test-mesh-complex-skel.in
diff --git a/milena/ChangeLog b/milena/ChangeLog
index ab602ac..910aac6 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+ Exercise apps/statues/mesh-complex-skel.
+
+ * apps/statues/test-mesh-complex-skel.in: New test.
+ * apps/statues/Makefile.am (TESTS): Add test-mesh-complex-skel.
+
+2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+
Write and application computing skeletons on complex-based images.
* apps/statues/mesh-complex-skel.cc: New.
diff --git a/milena/apps/statues/Makefile.am b/milena/apps/statues/Makefile.am
index 9c7c9ca..1407fbe 100644
--- a/milena/apps/statues/Makefile.am
+++ b/milena/apps/statues/Makefile.am
@@ -110,3 +110,4 @@ TESTS += test-mesh-complex-max-curv-segm
# Skeletonization program working on precomputed meshes with curvatures data.
bin_PROGRAMS += mesh-complex-skel
mesh_complex_skel_SOURCES = mesh-complex-skel.cc
+TESTS += test-mesh-complex-skel
diff --git a/milena/apps/statues/test-mesh-complex-skel.in b/milena/apps/statues/test-mesh-complex-skel.in
new file mode 100644
index 0000000..1f8a184
--- /dev/null
+++ b/milena/apps/statues/test-mesh-complex-skel.in
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+set -ex
+
+mesh_dir=@top_srcdir@/milena/mesh
+
+time ./mesh-complex-skel $mesh_dir/three-triangles.off 25 three-triangles-skel.off
+time ./mesh-complex-skel $mesh_dir/socket-max-curv.off 25 socket-max-curv-skel.off
+time ./mesh-complex-skel $mesh_dir/teapot-max-curv.off 50 teapot-max-curv-skel.off
+time ./mesh-complex-skel $mesh_dir/bunny-holefilled-pinv-curv.off 500 bunny-holefilled-pinv-curv-skel.off
--
1.6.1.2
1
0
[PATCH 05/10] Write and application computing skeletons on complex-based images.
by Roland Levillain 06 Apr '09
by Roland Levillain 06 Apr '09
06 Apr '09
* apps/statues/mesh-complex-skel.cc: New.
* apps/statues/save_bin_alt.hh: New.
Workaround over mln::io::off::save's limitations.
* mln/topo/complex.hh [NDEBUG]: Remove a warning.
* apps/statues/Makefile.am (AM_CXXFLAGS): Add -Wall -Wextra.
(bin_PROGRAMS): Add mesh-complex-skel.
(mesh_complex_skel_SOURCES): New.
---
milena/ChangeLog | 12 +
milena/apps/statues/Makefile.am | 16 +-
milena/apps/statues/mesh-complex-skel.cc | 704 ++++++++++++++++++++++++++++++
milena/apps/statues/save_bin_alt.hh | 188 ++++++++
milena/mln/topo/complex.hh | 2 +
5 files changed, 921 insertions(+), 1 deletions(-)
create mode 100644 milena/apps/statues/mesh-complex-skel.cc
create mode 100644 milena/apps/statues/save_bin_alt.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index ce5e952..ab602ac 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,17 @@
2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+ Write and application computing skeletons on complex-based images.
+
+ * apps/statues/mesh-complex-skel.cc: New.
+ * apps/statues/save_bin_alt.hh: New.
+ Workaround over mln::io::off::save's limitations.
+ * mln/topo/complex.hh [NDEBUG]: Remove a warning.
+ * apps/statues/Makefile.am (AM_CXXFLAGS): Add -Wall -Wextra.
+ (bin_PROGRAMS): Add mesh-complex-skel.
+ (mesh_complex_skel_SOURCES): New.
+
+2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+
Allow the comparison of faces of different dimensions using `<'.
* mln/topo/face.hh (operator< (const face<D>&, const face<D>&)):
diff --git a/milena/apps/statues/Makefile.am b/milena/apps/statues/Makefile.am
index e132895..9c7c9ca 100644
--- a/milena/apps/statues/Makefile.am
+++ b/milena/apps/statues/Makefile.am
@@ -8,7 +8,8 @@ include $(top_srcdir)/external/trimesh/gluit/gluit.mk
AM_CPPFLAGS = -I$(top_srcdir)/milena
CPPFLAGS_trimesh = -I$(top_srcdir)/external/trimesh/include
# Produce fast code.
-AM_CXXFLAGS = -O3 -DNDEBUG -ggdb
+# FIXME: This is GCC-dependent; use a variable computed by configure instead.
+AM_CXXFLAGS = -Wall -Wextra -ggdb -O3 -DNDEBUG
# Find the trimesh library and its dependencies.
#
# Don't use TRIMESH_LDFLAGS, since it looks like the LDFLAGS of the
@@ -39,6 +40,9 @@ TESTS =
#
# TESTS += test-mesh-segm
+# FIXME: mesh_skel is unfinished. Anyway, it should be superseded by
+# another program, using no Trimesh code.
+
# mesh_skel_SOURCES = mesh-skel.cc io.hh
# mesh_skel_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_trimesh)
# mesh_skel_LDFLAGS = $(LDFLAGS_trimesh)
@@ -68,6 +72,9 @@ TESTS += test-mesh-max-curv
noinst_HEADERS = trimesh/misc.hh
EXTRA_DIST = trimesh/README
+## Segmentation.
+## ------------
+
# A small program exercising the curvature computation routines ported
# from Trimesh to Milena.
bin_PROGRAMS += mesh-complex-max-curv
@@ -96,3 +103,10 @@ TESTS += test-mesh-complex-max-curv-segm
# FIXME: Implement `mesh-complex-pinv-curv-segm' (factor as much
# code as possible with `mesh-complex-max-curv-segm'.
# ...
+
+## Skeletonization.
+## ----------------
+
+# Skeletonization program working on precomputed meshes with curvatures data.
+bin_PROGRAMS += mesh-complex-skel
+mesh_complex_skel_SOURCES = mesh-complex-skel.cc
diff --git a/milena/apps/statues/mesh-complex-skel.cc b/milena/apps/statues/mesh-complex-skel.cc
new file mode 100644
index 0000000..e58c5cd
--- /dev/null
+++ b/milena/apps/statues/mesh-complex-skel.cc
@@ -0,0 +1,704 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file apps/statues/mesh-complex-skel.cc
+/// \brief A program computing a skeleton of the surface of the
+/// (triangle) mesh of a statue (by thinning), using a complex-based
+/// image.
+
+#include <cstdlib>
+#include <cmath>
+
+#include <algorithm>
+#include <utility>
+#include <iostream>
+
+#include <mln/core/image/complex_image.hh>
+#include <mln/core/image/complex_neighborhoods.hh>
+#include <mln/core/image/image_if.hh>
+
+#include <mln/core/site_set/p_set.hh>
+
+#include <mln/pw/value.hh>
+#include <mln/pw/cst.hh>
+
+#include <mln/value/label_16.hh>
+#include <mln/literal/white.hh>
+
+#include <mln/core/routine/duplicate.hh>
+#include <mln/labeling/regional_minima.hh>
+
+#include <mln/io/off/load.hh>
+#include <mln/io/off/save.hh>
+/* FIXME: Remove as soon as mln::io::off::save is able to save a
+ morphed mln::complex_image (i.e., seen through image_if). */
+#include "save_bin_alt.hh"
+
+
+// FIXME: This is bad. Remove as soon as all routines have been moved
+// to the library.
+using namespace mln;
+
+// Fwd. decl.
+template <typename I> struct is_simple_triangle;
+
+// // A very simple and limited predicate for the simplicity of a point.
+// template <typename I>
+// class is_simple_triangle
+// : public mln::Function_p2b< is_simple_triangle<I> >
+// {
+// public:
+// /// Dimension of the image (and therefore of the complex).
+// static const unsigned D = I::dim;
+// /// Geometry of the image.
+// typedef mln_geom(I) G;
+// /// Psite type.
+// typedef mln::complex_psite<D, G> psite;
+
+// /// Result type of the functor.
+// typedef bool result;
+
+// is_simple_triangle()
+// : ima_(0), nbh_()
+// {
+// }
+
+// is_simple_triangle(const mln::Image<I>& ima)
+// : ima_(mln::exact(&ima)), nbh_()
+// {
+// }
+
+// /* FIXME: Rename as init() or something like this? See how other
+// functors are written. */
+// /// Set the underlying image.
+// void set_image(const mln::Image<I>& ima)
+// {
+// ima_ = mln::exact(&ima);
+// }
+
+// bool operator()(const psite& p) const
+// {
+// mln_precondition(ima_);
+// unsigned nneighbs = 0;
+// mln_niter(nbh_t) n(nbh_, p);
+// for_all(n)
+// if ((*ima_)(n))
+// ++nneighbs;
+// mln_invariant(n <= 3);
+// /* FIXME: Dummy: A triangle is considered simple if it is not
+// completely attached nor completely detached (i.e, if it has
+// more than 0 adjacent triangles but less than three). This test
+// is obiously simplistic and wrong, but we'll use it as a first
+// approximation. We should use the notion of free pair later.
+// And provide efficient, mask-based version as well. */
+// return 0 < nneighbs && nneighbs < 3;
+// }
+
+// private:
+// const I* ima_;
+
+// // FIXME: Make this type a parameter of the functor?
+// typedef mln::complex_lower_dim_connected_n_face_neighborhood<D, G> nbh_t;
+// nbh_t nbh_;
+// };
+
+
+// FIXME: Doc.
+template <unsigned D, typename G>
+bool
+is_facet(const mln::complex_psite<D, G>& f)
+{
+ typedef mln::complex_higher_neighborhood<D, G> higher_adj_nbh_t;
+ higher_adj_nbh_t higher_adj_nbh;
+ mln_niter(higher_adj_nbh_t) n(higher_adj_nbh, f);
+ for_all(n)
+ // If the neighborhood is not empty, then F is included in a face
+ // of higher dimension.
+ return false;
+ // Otherwise, F is a facet.
+ return true;
+}
+
+
+/** \brief Compute the set of faces of the cell corresponding to the
+ facet \a f.
+
+ \pre \a f is a facet (it does not belong to any face of higher
+ dimension)
+
+ \return a set of faces containing the attachment. */
+template <unsigned D, typename G>
+mln::p_set< complex_psite<D, G> >
+cell(const complex_psite<D, G>& f)
+{
+ // Ensure the face F is a facet.
+ mln_precondition(is_facet(f));
+
+ typedef complex_psite<D, G> psite;
+ typedef p_set<psite> faces_t;
+
+ // Compute the cell F^HAT.
+ faces_t f_hat;
+ /* FIXME: We need a cell-iterator here
+ (see https://trac.lrde.org/olena/ticket/162) */
+ typedef complex_m_face_neighborhood<D, G> m_faces_nbh_t;
+ m_faces_nbh_t m_faces_nbh;
+ mln_niter(m_faces_nbh_t) g(m_faces_nbh, f);
+ for (unsigned m = 0; m < f.n(); ++m)
+ {
+ g.iter().set_m(m);
+ for_all(g)
+ {
+ f_hat.insert(g);
+// // FIXME: Debug.
+// std::cerr << g << std::endl;
+ }
+ }
+ f_hat.insert(f);
+// // FIXME: Debug.
+// std::cerr << f << std::endl;
+ return f_hat;
+}
+
+
+/** \brief Compute the attachment of the cell corresponding to the
+ facet \a f to the image \a ima.
+
+ \pre ima is an image of Boolean values.
+
+ \return a set of faces containing the attachment.
+
+ We do not use the fomal definition of the attachment here (see
+ couprie.08.pami). We use the following (equivalent) definition:
+ an N-face F in CELL is in the attachment of CELL to IMA if it is
+ adjacent to at least an (N-1)-face or an (N+1)-face that does not
+ belong to CELL. */
+template <unsigned D, typename G, typename V>
+mln::p_set< complex_psite<D, G> >
+attachment(const mln::complex_psite<D, G>& f,
+ const mln::complex_image<D, G, V>& ima)
+{
+ mlc_equal(V, bool)::check();
+
+ typedef complex_psite<D, G> psite;
+ typedef p_set<psite> faces_t;
+
+ faces_t f_hat = cell(f);
+// // FIXME: Debug.
+// std::cerr << "f_hat.nsites() = " << f_hat.nsites() << std::endl;
+ faces_t att_f;
+
+ typedef complex_lower_higher_neighborhood<D, G> adj_nbh_t;
+ adj_nbh_t adj_nbh;
+ mln_piter(faces_t) g(f_hat);
+ mln_niter(adj_nbh_t) n(adj_nbh, g);
+ for_all(g)
+ for_all(n)
+ if (ima(n) && !f_hat.has(n))
+ {
+ att_f.insert(g);
+ break;
+ }
+// // FIXME: Debug.
+// std::cerr << "att_f.nsites() = " << att_f.nsites() << std::endl;
+ return att_f;
+}
+
+
+/** \brief Compute the detachment of the cell corresponding to the
+ facet \a f to the image \a ima.
+
+ \pre ima is an image of Boolean values.
+
+ \return a set of faces containing the detachment.
+
+ We do not use the fomal definition of the detachment here (see
+ couprie.08.pami). We use the following (equivalent) definition:
+ an N-face F in CELL is not in the detachment of CELL from IMA if
+ it is adjacent to at least an (N-1)-face or an (N+1)-face that
+ does not belong to CELL. */
+template <unsigned D, typename G, typename V>
+mln::p_set< complex_psite<D, G> >
+detachment(const mln::complex_psite<D, G>& f,
+ const mln::complex_image<D, G, V>& ima)
+{
+ mlc_equal(V, bool)::check();
+
+ typedef complex_psite<D, G> psite;
+ typedef p_set<psite> faces_t;
+
+ faces_t f_hat = cell(f);
+ // Initialize DETACH_F to F_HAT.
+ faces_t detach_f = f_hat;
+
+ typedef complex_lower_higher_neighborhood<D, G> adj_nbh_t;
+ adj_nbh_t adj_nbh;
+ mln_piter(faces_t) g(f_hat);
+ mln_niter(adj_nbh_t) n(adj_nbh, g);
+ for_all(g)
+ for_all(n)
+ if (ima(n) && !f_hat.has(n))
+ {
+ detach_f.remove(g);
+ break;
+ }
+ return detach_f;
+}
+
+
+/** \brief A predicate for the simplicity of a point based on the
+ collapse property of the attachment.
+
+ The functor does not actually take a cell as input, but a face
+ that is expected to be a 2-facet. */
+template <typename I>
+class is_simple_cell
+ : public mln::Function_p2b< is_simple_cell<I> >
+{
+public:
+ /// Dimension of the image (and therefore of the complex).
+ static const unsigned D = I::dim;
+ /// Geometry of the image.
+ typedef mln_geom(I) G;
+ /// Psite type.
+ typedef mln::complex_psite<D, G> psite;
+
+ /// Result type of the functor.
+ typedef bool result;
+
+ is_simple_cell()
+ : ima_(0)
+ {
+ }
+
+ is_simple_cell(const mln::Image<I>& ima)
+ : ima_(mln::exact(&ima))
+ {
+ }
+
+ /* FIXME: Rename as init() or something like this? See how other
+ functors are written. */
+ /// Set the underlying image.
+ void set_image(const mln::Image<I>& ima)
+ {
+ ima_ = mln::exact(&ima);
+ }
+
+ // Based on the algorithm A2 from couprie.08.pami.
+ bool operator()(const psite& p) const
+ {
+// // FIXME: Debug.
+// std::cerr << "is_simple_cell(" << p << ")" << std::endl;
+
+ mln_precondition(ima_);
+
+ typedef p_set<psite> faces_t;
+
+ // Compute the attachment of the cell corresponding to P to he
+ // domain of *IMA_.
+ faces_t att = attachment(p, *ima_);
+
+ // A cell with an empty attachment is not simple.
+ /* FIXME: Why does p_set not provide an empty() predicate? */
+ if (att.nsites() == 0)
+ return false;
+
+ /* FIXME: This part could be moved to its own function/method
+ (`is_collapsible'). Moreover, the code could be split: looking
+ up for a free pair (g, h) could be performed in another
+ routine. */
+ // Try to collapse the attachment (to a single point).
+ {
+ typedef complex_lower_neighborhood<D, G> lower_adj_nbh_t;
+ typedef complex_higher_neighborhood<D, G> higher_adj_nbh_t;
+ lower_adj_nbh_t lower_adj_nbh;
+ higher_adj_nbh_t higher_adj_nbh;
+ while (att.nsites() > 1)
+ {
+
+ bool simple_pair_collapsed = false;
+ /* FIXME: The selection of G and H is probably suboptimal
+ (i.e., selecting G has a face of highest avalaible
+ dimension in CELL is probably smarter). */
+ mln_piter(faces_t) g(att);
+ for_all(g)
+ /* G cannot have dimension 0, since we later look for an
+ adjacent face H of lower dimension. */
+ if (static_cast<psite>(g).n() > 0)
+ {
+ // Check whether G is a facet within ATT.
+ bool g_is_facet = true;
+ mln_niter(higher_adj_nbh_t) f(higher_adj_nbh, g);
+ for_all(f)
+ if (att.has(f))
+ {
+ g_is_facet = false;
+ break;
+ }
+ if (!g_is_facet)
+ break;
+
+ // Look for a face H stricly included in G.
+ bool gh_is_simple_pair = false;
+ mln_niter(lower_adj_nbh_t) h(lower_adj_nbh, g);
+ for_all(h)
+ {
+ bool h_strictly_in_g = true;
+ if (att.has(h))
+ {
+ mln_niter(higher_adj_nbh_t) i(higher_adj_nbh, h);
+ for_all(i)
+ if (i != g && att.has(i))
+ {
+ h_strictly_in_g = false;
+ break;
+ }
+ }
+ if (h_strictly_in_g)
+ {
+ gh_is_simple_pair = true;
+ att.remove(g);
+ att.remove(h);
+ mln_invariant(att.nsites() > 0);
+ break;
+ }
+ } // for_all(h)
+
+ // If a free pair (G, H) has been found and removed,
+ // restart the free pair look up from the beginning.
+ if (gh_is_simple_pair)
+ {
+ simple_pair_collapsed = true;
+ break;
+ }
+ } // for_all(g)
+
+ if (!simple_pair_collapsed)
+ // If no free pair (G, H) was found, then the attachment is
+ // not collapsible.
+ return false;
+
+ } // while (att.nsites() > 1)
+
+ mln_postcondition(att.nsites() == 1);
+ mln_postcondition(att[0].n() == 0);
+ // If the attachment is collapsible to a 0-face, then the cell
+ // corresponding to the (face) P is simple.
+ return true;
+ }
+ }
+
+private:
+ const I* ima_;
+};
+
+
+// FIXME: Doc.
+template <unsigned D, typename G, typename V>
+void
+detach (const mln::complex_psite<D, G>f, mln::complex_image<D, G, V>& ima)
+{
+ mlc_equal(V, bool)::check();
+
+ typedef mln::complex_psite<D, G> psite;
+ typedef p_set<psite> faces_t;
+
+ // Compute the detachment of P from IMA.
+ faces_t detach = detachment(f, ima);
+ // Detach all its faces from IMA.
+#if 0
+ // FIXME: Does not work yet? Check again.
+ data::fill(ima | detach, false);
+#endif
+ mln_piter(faces_t) p(detach);
+ for_all(p)
+ ima(p) = false;
+}
+
+
+// FIXME: Move this elsewhere.
+// FIXME: Use a generic `I' instead of `mln::bin_2complex_image3df'.
+// FIXME: Add a constraint/priority argument (K/P).
+/** \brief Breadth-First Thinning.
+
+ A non generic implementation of a binary skeleton on a triangle
+ surface (mesh).
+
+ \a N is the adjacency relation between triangles, but it probably
+ does not make sense to use something other than an instance of
+ mln::complex_lower_dim_connected_n_face_neighborhood if the image type is
+ hard-coded as mln::bin_2complex_image3df. */
+template <typename N, typename F>
+mln::bin_2complex_image3df
+skeleton(const mln::bin_2complex_image3df& input,
+ const mln::Neighborhood<N>& nbh_,
+ mln::Function_p2b<F>& is_simple_)
+{
+ const N& nbh = exact(nbh_);
+ F& is_simple = exact(is_simple_);
+
+ typedef mln::bin_2complex_image3df I;
+ typedef mln_psite(I) psite;
+
+ I output = mln::duplicate(input);
+ // Attach the work image to IS_SIMPLE.
+ is_simple.set_image(output);
+
+ typedef mln::p_set<psite> set_t;
+ set_t set;
+
+// // FIXME: Debug.
+// unsigned count = 0;
+
+ // Populate the set with candiate simple points.
+ mln_piter(I) p(output.domain());
+ for_all(p)
+ {
+ /* FIXME: Cheat! We'd like to iterate on 2-cells only, but
+ we cannot constrain the domain of the input using
+ image_if (yet). Hence this filter to restrict the
+ dimension of the considered cells. A less dirty
+ approaach would be to use a constraint predicate (see
+ comment above). */
+ if (p.unproxy_().n() != I::dim)
+ continue;
+
+// // FIXME: Debug.
+// std::cerr << "skeleton: Iteration (for_all(p)) : "
+// << count++ << std::endl;
+
+// // FIXME: Debug.
+// std::cerr << " output(p) = " << output(p) << std::endl;
+// std::cerr << " is_simple(p) = " << is_simple(p) << std::endl;
+
+ if (output(p) && is_simple(p))
+ set.insert(p);
+ }
+
+// // FIXME: Debug.
+// std::cerr << "skeleton: set.nsites() = " << set.nsites() << std::endl;
+
+// // FIXME: Debug.
+// count = 0;
+
+ while (!set.is_empty())
+ {
+// // FIXME: Debug.
+// mln_piter(set_t) ps(set);
+// std::cerr << "set = " << std::endl;
+// for_all(ps)
+// std::cerr << " " << static_cast<psite>(ps) << std::endl;
+// std::cerr << std::endl;
+
+// // FIXME: Debug.
+// std::cerr << "skeleton: Iteration (while (!set.is_empty())) : "
+// << count++ << std::endl;
+
+ set_t next_set;
+ // FIXME: Use a piter on SET instead of this hand-made iteration.
+ for (unsigned i = 0; i < set.nsites(); ++i)
+ {
+ psite p = set[i];
+
+ /* FIXME: Cheat! We'd like to iterate on 2-cells only, but
+ we cannot constrain the domain of the input using
+ image_if (yet). Hence this filter to restrict the
+ dimension of the considered cells. A less dirty
+ approaach would be to use a constraint predicate (see
+ comment above). */
+ if (p.n() != I::dim)
+ continue;
+
+ /* FIXME: We compute the cell and attachment of P twice:
+ within is_simple and within detach. How could we reuse
+ this elegantly, without breaking the genericity of the
+ skeleton algorithm? */
+ if (is_simple(p))
+ {
+ // FIXME: `detach' could be a functor, as is `is_simple'.
+ detach(p, output);
+ mln_niter(N) n(nbh, p);
+ for_all(n)
+ {
+ /* FIXME: Cheat! We'd like to iterate on 2-cells only, but
+ we cannot constrain the domain of the input using
+ image_if (yet). Hence this filter to restrict the
+ dimension of the considered cells. A less dirty
+ approaach would be to use a constraint predicate (see
+ comment above). */
+ if (n.unproxy_().n() != I::dim)
+ continue;
+
+ if (output.domain().has(n) && output(n) && is_simple(n))
+ next_set.insert(n);
+ }
+ }
+ }
+ set.clear();
+ std::swap(set, next_set);
+ }
+
+ return output;
+}
+
+
+// Fwd. decl.
+template <unsigned N> struct is_n_face;
+
+/// A functor testing wheter a mln::complex_psite is an \N-face.
+template <unsigned N>
+struct is_n_face : public mln::Function_p2b< is_n_face<N> >
+{
+ typedef bool result;
+
+ template <unsigned D, typename G>
+ bool operator()(const mln::complex_psite<D, G>& p)
+ {
+ return p.n() == N;
+ }
+};
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 4)
+ {
+ std::cerr << "usage: " << argv[0] << " input.off lambda output.off"
+ << std::endl;
+ std::exit(1);
+ }
+
+ std::string input_filename = argv[1];
+ // FIXME: Use lambda to filter the input.
+#if 0
+ unsigned lambda = atoi(argv[2]);
+#endif
+ std::string output_filename = argv[3];
+
+ /*----------------.
+ | Complex image. |
+ `----------------*/
+
+ // Image type.
+ typedef mln::float_2complex_image3df ima_t;
+ // Dimension of the image (and therefore of the complex).
+ static const unsigned D = ima_t::dim;
+ // Geometry of the image.
+ typedef mln_geom_(ima_t) G;
+
+ ima_t input;
+ mln::io::off::load(input, input_filename);
+
+ /* FIXME: Workaround: Set maximal values on vertices and edges to
+ exclude them from the set of minimal values. */
+ mln::p_n_faces_fwd_piter<D, G> v(input.domain(), 0);
+ for_all(v)
+ input(v) = mln_max(float);
+ mln::p_n_faces_fwd_piter<D, G> e(input.domain(), 1);
+ for_all(e)
+ input(e) = mln_max(float);
+
+ /*---------------.
+ | Local minima. |
+ `---------------*/
+
+ typedef mln::value::label_16 label_t;
+ label_t nminima;
+
+ typedef mln::complex_lower_dim_connected_n_face_neighborhood<D, G> nbh_t;
+ nbh_t nbh;
+
+ /* FIXME: We should use something like `ima_t | p_n_faces(2)' instead
+ of `ima_t' here. Or better: `input' should only associate data
+ to 2-faces. */
+ mln_ch_value_(ima_t, label_t) minima =
+ mln::labeling::regional_minima(input, nbh, nminima);
+
+ /*-----------------------.
+ | Initial binary image. |
+ `-----------------------*/
+
+ typedef mln_ch_value_(ima_t, bool) bin_ima_t;
+ bin_ima_t surface(input.domain());
+ mln::data::fill(surface, true);
+ // Dig ``holes'' in the surface surface by setting minima faces to false.
+#if 0
+ /* FIXME: The `is_n_face<2>' predicate is required because the
+ domain of SURFACE also comprises 0-faces and 1-faces... */
+ mln::data::fill(surface
+ | is_n_face<2>()
+ | mln::pw::value(minima) != mln::pw::cst(mln::literal::zero),
+ false);
+#endif
+ /* FIXME: The code above does not compile (yet). Probably because
+ of an incompatibility between complex_image and image_if. Use
+ this hand-made filling for the moment. */
+ mln::p_n_faces_fwd_piter<D, G> t(input.domain(), 2);
+ for_all(t)
+ if (minima(t) != mln::literal::zero)
+ surface(t) = false;
+
+// #if 0
+// /* FIXME: Debug. But alas, this does not work (yet).
+// Use workaround mln::io::off::save_bin_salt instead (bad!) */
+// # if 0
+// mln::io::off::save(surface | mln::pw::value(surface) == mln::pw::cst(true),
+// "surface.off");
+// # endif
+// mln::io::off::save_bin_alt(surface, "surface.off");
+// #endif
+
+// // FIXME: Debug.
+// typedef mln_ch_value_(ima_t, bool) bin_ima_t;
+// bin_ima_t surface;
+// mln::io::off::load(surface,
+// "/Users/roland/src/olena/milena/mesh/two-triangles.off");
+// // Set one of the two triangle to false.
+// p_n_faces_fwd_piter<D, G> t(surface.domain(), 2);
+// t.start();
+// mln_precondition(t.is_valid());
+// surface(t) = false;
+
+ /*-----------.
+ | Skeleton. |
+ `-----------*/
+
+ is_simple_cell<bin_ima_t> is_simple_p;
+ bin_ima_t skel = skeleton(surface, nbh, is_simple_p);
+
+ /*---------.
+ | Output. |
+ `---------*/
+
+ /* FIXME: This does not work (yet).
+ Use workaround mln::io::off::save_bin_salt instead (bad!) */
+#if 0
+ mln::io::off::save(skel | mln::pw::value(skel) == mln::pw::cst(true),
+ output_filename);
+#endif
+ mln::io::off::save_bin_alt(skel, output_filename);
+}
diff --git a/milena/apps/statues/save_bin_alt.hh b/milena/apps/statues/save_bin_alt.hh
new file mode 100644
index 0000000..b2def9b
--- /dev/null
+++ b/milena/apps/statues/save_bin_alt.hh
@@ -0,0 +1,188 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef APPS_STATUES_SAVE_BIN_ALT_HH
+# define APPS_STATUES_SAVE_BIN_ALT_HH
+
+/*--------------------------------------------------------------------.
+| FIXME: Copied and adjusted (in a hurry) from mln/io/off/save.hh, |
+| because fixing image_if + complex_image was much too long. Sorry. |
+`--------------------------------------------------------------------*/
+
+# include <cstdlib>
+
+# include <iostream>
+# include <fstream>
+# include <sstream>
+
+# include <string>
+
+# include <mln/core/alias/complex_image.hh>
+# include <mln/core/image/complex_neighborhoods.hh>
+# include <mln/core/image/complex_neighborhood_piter.hh>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace off
+ {
+
+ /** FIXME: Similar to
+ mln::io::off::save(const bin_2complex_image3df&, const std::string&),
+ but does not save faces whose value is `false'. */
+ template <typename I>
+ void save_bin_alt(const I& ima,
+ const std::string& filename)
+ {
+ const std::string me = "mln::io::off::save";
+
+ std::ofstream ostr(filename.c_str());
+ if (!ostr)
+ {
+ std::cerr << me << ": `" << filename << "' invalid file."
+ << std::endl;
+ /* FIXME: Too violent. We should allow the use of
+ exceptions, at least to have Milena's code behave
+ correctly in interpreted environments (std::exit() or
+ std::abort() causes the termination of a Python
+ interpreter, for instance!). */
+ std::exit(1);
+ }
+
+ /*---------.
+ | Header. |
+ `---------*/
+
+ static const unsigned D = I::dim;
+ typedef mln_geom(I) G;
+
+ /* ``The .off files in the Princeton Shape Benchmark conform
+ to the following standard.'' */
+
+ /* ``OFF files are all ASCII files beginning with the
+ keyword OFF. '' */
+ ostr << "OFF" << std::endl;
+
+ // A comment.
+ ostr << "# Generated by Milena 1.0 http://olena.lrde.epita.fr\n"
+ << "# EPITA Research and Development Laboratory (LRDE)"
+ << std::endl;
+
+ // Count the number of 2-faces set to `true'.
+ unsigned n2faces = 0;
+ p_n_faces_fwd_piter<D, G> f(ima.domain(), 2);
+ for_all(f)
+ if (ima(f))
+ ++n2faces;
+
+ /* ``The next line states the number of vertices, the number
+ of faces, and the number of edges. The number of edges can
+ be safely ignored.'' */
+ /* FIXME: This is too long. We shall be able to write
+
+ ima.domain().template nfaces<0>()
+
+ or even
+
+ ima.template nfaces<0>().
+ */
+ ostr << ima.domain().cplx().template nfaces<0>() << ' '
+ << n2faces << ' '
+ << ima.domain().cplx().template nfaces<1>() << std::endl;
+
+ /*-------.
+ | Data. |
+ `-------*/
+
+ // ------------------------------------------ //
+ // Vertices & geometry (vertices locations). //
+ // ------------------------------------------ //
+
+ /* ``The vertices are listed with x, y, z coordinates, written
+ one per line.'' */
+
+ // Traverse the 0-faces (vertices).
+ p_n_faces_fwd_piter<D, G> v(ima.domain(), 0);
+ for_all(v)
+ {
+ mln_invariant(v.to_site().size() == 1);
+ ostr << v.to_site().front()[0] << ' '
+ << v.to_site().front()[1] << ' '
+ << v.to_site().front()[2] << std::endl;
+ }
+
+ // --------------- //
+ // Faces & edges. //
+ // --------------- //
+
+ /* ``After the list of vertices, the faces are listed, with one
+ face per line. For each face, the number of vertices is
+ specified, followed by indices into the list of
+ vertices.'' */
+
+ // Traverse the 2-faces (polygons).
+ typedef complex_m_face_neighborhood<D, G> nbh_t;
+ // A neighborhood where neighbors are the set of 0-faces
+ // transitively adjacent to the reference point.
+ nbh_t nbh;
+ mln_fwd_niter(nbh_t) u(nbh, f);
+ /* FIXME: We should be able to pas this value (m) either at
+ the construction of the neighborhood or at the construction
+ of the iterator. */
+ u.iter().set_m(0);
+
+ // For each (2-)face, iterate on (transitively) ajacent
+ // vertices (0-faces).
+ for_all(f)
+ if (ima(f))
+ {
+ unsigned nvertices = 0;
+ std::ostringstream vertices;
+ for_all(u)
+ {
+ // FIXME: Likewise, this is a bit too long...
+ vertices << ' ' << u.unproxy_().face().face_id();
+ ++nvertices;
+ }
+ ostr << nvertices << vertices.str();
+ ostr << std::endl;
+ }
+
+ ostr.close();
+ }
+
+ } // end of namespace mln::io::off
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+#endif // ! APPS_STATUES_SAVE_BIN_ALT_HH
diff --git a/milena/mln/topo/complex.hh b/milena/mln/topo/complex.hh
index 2b392ac..c182743 100644
--- a/milena/mln/topo/complex.hh
+++ b/milena/mln/topo/complex.hh
@@ -951,6 +951,8 @@ namespace mln
{
// If we reached this method, then N should be 0.
mln_precondition(n == 0);
+ // Prevent ``unused variable'' warnings when NDEBUG is defined.
+ (void) n;
return f(faces_);
}
--
1.6.1.2
1
0
[PATCH 04/10] Allow the comparison of faces of different dimensions using `<'.
by Roland Levillain 06 Apr '09
by Roland Levillain 06 Apr '09
06 Apr '09
* mln/topo/face.hh (operator< (const face<D>&, const face<D>&)):
Here.
This way, a standard container relying on operator< can accept
faces of different dimensions.
---
milena/ChangeLog | 9 +++++++++
milena/mln/topo/face.hh | 5 ++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index d49139e..ce5e952 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+ Allow the comparison of faces of different dimensions using `<'.
+
+ * mln/topo/face.hh (operator< (const face<D>&, const face<D>&)):
+ Here.
+ This way, a standard container relying on operator< can accept
+ faces of different dimensions.
+
+2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+
Add some simple triangle meshes.
* mesh/one-triangle.off:
diff --git a/milena/mln/topo/face.hh b/milena/mln/topo/face.hh
index 74077f1..9c9872f 100644
--- a/milena/mln/topo/face.hh
+++ b/milena/mln/topo/face.hh
@@ -405,9 +405,8 @@ namespace mln
{
// Ensure LHS and RHS belong to the same complex.
mln_precondition(lhs.cplx() == rhs.cplx());
- // Ensure LHS and RHS have the same dimension.
- mln_precondition(lhs.n() == rhs.n());
- return lhs.face_id() < rhs.face_id();
+ return lhs.n() < rhs.n() ||
+ (lhs.n() == rhs.n() && lhs.face_id() < rhs.face_id());
}
--
1.6.1.2
1
0
* mesh/one-triangle.off:
* mesh/two-triangles.off:
* mesh/three-triangles.off:
New.
---
milena/ChangeLog | 9 +++++++++
milena/mesh/one-triangle.off | 6 ++++++
milena/mesh/three-triangles.off | 10 ++++++++++
milena/mesh/two-triangles.off | 8 ++++++++
4 files changed, 33 insertions(+), 0 deletions(-)
create mode 100644 milena/mesh/one-triangle.off
create mode 100644 milena/mesh/three-triangles.off
create mode 100644 milena/mesh/two-triangles.off
diff --git a/milena/ChangeLog b/milena/ChangeLog
index aab403c..d49139e 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+ Add some simple triangle meshes.
+
+ * mesh/one-triangle.off:
+ * mesh/two-triangles.off:
+ * mesh/three-triangles.off:
+ New.
+
+2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+
Aesthetic changes in the output of the save routine for OFF file.
* mln/io/off/save.hh
diff --git a/milena/mesh/one-triangle.off b/milena/mesh/one-triangle.off
new file mode 100644
index 0000000..947d460
--- /dev/null
+++ b/milena/mesh/one-triangle.off
@@ -0,0 +1,6 @@
+OFF
+3 1 3
+0.0 1.0 0.0
+2.0 0.0 0.0
+2.0 2.0 0.0
+3 1 0 2
diff --git a/milena/mesh/three-triangles.off b/milena/mesh/three-triangles.off
new file mode 100644
index 0000000..2889413
--- /dev/null
+++ b/milena/mesh/three-triangles.off
@@ -0,0 +1,10 @@
+OFF
+5 3 7
+0.0 1.0 0.0
+2.0 0.0 0.0
+2.0 2.0 0.0
+0.0 3.0 0.0
+2.0 4.0 0.0
+3 1 0 2 0.75 0.75 0.75 1.0
+3 2 0 3 0.50 0.50 0.50 1.0
+3 2 3 4 0.25 0.25 0.25 1.0
diff --git a/milena/mesh/two-triangles.off b/milena/mesh/two-triangles.off
new file mode 100644
index 0000000..2225ecf
--- /dev/null
+++ b/milena/mesh/two-triangles.off
@@ -0,0 +1,8 @@
+OFF
+4 2 5
+0.0 1.0 0.0
+2.0 0.0 0.0
+2.0 2.0 0.0
+0.0 3.0 0.0
+3 1 0 2
+3 2 0 3
--
1.6.1.2
1
0
[PATCH 02/10] Aesthetic changes in the output of the save routine for OFF file.
by Roland Levillain 06 Apr '09
by Roland Levillain 06 Apr '09
06 Apr '09
* mln/io/off/save.hh
(mln::io::off::internal::float_off_saver::write_face_data)
(mln::io::off::internal::rgb8_off_saver::write_face_data):
Do not print extra blank lines.
---
milena/ChangeLog | 9 +++++++++
milena/mln/io/off/save.hh | 5 ++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 423ebb4..aab403c 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+ Aesthetic changes in the output of the save routine for OFF file.
+
+ * mln/io/off/save.hh
+ (mln::io::off::internal::float_off_saver::write_face_data)
+ (mln::io::off::internal::rgb8_off_saver::write_face_data):
+ Do not print extra blank lines.
+
+2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+
Add a load routine for color (RGB) OFF (surface mesh) files.
* mln/io/off/load.hh
diff --git a/milena/mln/io/off/save.hh b/milena/mln/io/off/save.hh
index 7bb4292..e983525 100644
--- a/milena/mln/io/off/save.hh
+++ b/milena/mln/io/off/save.hh
@@ -127,7 +127,6 @@ namespace mln
void write_face_data(std::ostream& ostr, const value& v) const;
};
-
struct int_u8_off_saver
: public off_saver< int_u8_2complex_image3df, int_u8_off_saver >
{
@@ -423,7 +422,7 @@ namespace mln
mln_assertion(0.0f <= v);
mln_assertion(v <= 1.0f);
ostr << ' ' << v << ' ' << v << ' ' << v
- << ' ' << 1.0f << std::endl;
+ << ' ' << 1.0f;
}
void
@@ -436,7 +435,7 @@ namespace mln
the range 0..255. A fourth channel, A, controls the
transparency. */
ostr << ' ' << v.red() << ' ' << v.green() << ' ' << v.blue()
- << ' ' << 1.0f << std::endl;
+ << ' ' << 1.0f;
}
/* \} */
--
1.6.1.2
1
0
[PATCH 01/10] Add a load routine for color (RGB) OFF (surface mesh) files.
by Roland Levillain 06 Apr '09
by Roland Levillain 06 Apr '09
06 Apr '09
* mln/io/off/load.hh
(mln::io::off::load(rgb8_2complex_image3df, const std::string&)):
New function.
(mln::io::off::internal::rgb8_off_loader): New class.
---
milena/ChangeLog | 9 +++++
milena/mln/io/off/load.hh | 84 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 92 insertions(+), 1 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 3fc4587..423ebb4 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,12 @@
+2009-04-06 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Add a load routine for color (RGB) OFF (surface mesh) files.
+
+ * mln/io/off/load.hh
+ (mln::io::off::load(rgb8_2complex_image3df, const std::string&)):
+ New function.
+ (mln::io::off::internal::rgb8_off_loader): New class.
+
2009-04-03 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add optional paramater for plot::save().
diff --git a/milena/mln/io/off/load.hh b/milena/mln/io/off/load.hh
index 03fc3f3..1f8fefe 100644
--- a/milena/mln/io/off/load.hh
+++ b/milena/mln/io/off/load.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -41,6 +41,8 @@
# include <string>
+# include <mln/literal/black.hh>
+
# include <mln/core/concept/object.hh>
# include <mln/core/alias/complex_image.hh>
@@ -63,6 +65,9 @@ namespace mln
existence of faces. */
void load(bin_2complex_image3df& ima, const std::string& filename);
+ // FIXME: Implement a load routine for for
+ // int_u8_2complex_image3df.
+
/** Load a floating-point OFF image into a complex image.
\param[out] ima A reference to the image to construct.
@@ -72,6 +77,15 @@ namespace mln
1-faces and 0-faces are set to 0.0f. */
void load(float_2complex_image3df& ima, const std::string& filename);
+ /** Load a 3x8-bit RGB (color) OFF image into a complex image.
+
+ \param[out] ima A reference to the image to construct.
+ \param[in] filename The name of the file to load.
+
+ Read floating-point data is attached to 2-faces only;
+ 1-faces and 0-faces are set to 0.0f. */
+ void load(rgb8_2complex_image3df& ima, const std::string& filename);
+
namespace internal
{
@@ -118,6 +132,10 @@ namespace mln
};
+ /* Factor float_off_loader::reserve and rgb8_off_loader::reserve
+ and float_off_loader::assign and rgb8_off_loader::assign
+ by introducing an intermediate class. */
+
struct float_off_loader
: public off_loader< float_2complex_image3df, float_off_loader >
{
@@ -134,6 +152,23 @@ namespace mln
std::vector<float> face_value;
};
+
+ struct rgb8_off_loader
+ : public off_loader< rgb8_2complex_image3df, rgb8_off_loader >
+ {
+ /// Read face data.
+ void read_face_data(std::istream& istr);
+
+ /// Pre-allocate data.
+ void reserve(unsigned nvertices, unsigned nedges, unsigned nfaces);
+
+ /// Assign values to image.
+ void assign(values& vs, const domain& s);
+
+ /// 2-face floating-point values.
+ std::vector<value::rgb8> face_value;
+ };
+
} // end of namespace mln::io::off::internal
@@ -160,6 +195,15 @@ namespace mln
trace::exiting("mln::io::off::load");
}
+ void
+ load(rgb8_2complex_image3df& ima, const std::string& filename)
+ {
+ trace::entering("mln::io::off::load");
+ internal::rgb8_off_loader()(ima, filename);
+ trace::exiting("mln::io::off::load");
+ }
+
+
/*-------------------------.
| Actual implementations. |
@@ -485,6 +529,25 @@ namespace mln
mln_assertion(0.0f <= a); mln_assertion(a <= 1.0f);
face_value.push_back(r);
}
+
+ void
+ rgb8_off_loader::read_face_data(std::istream& istr)
+ {
+ /* We just use R, G, and B and ignore A (transparency) when
+ considering the value (``color'') associated to a face.
+
+ R must (and G, B and A should) be floating-point values
+ between 0 and 1, according to the OFF file format
+ definition. */
+ // FIXME: `A' should be optional.
+ float r, g, b, a;
+ istr >> r >> g >> b >> a;
+ mln_assertion(0.0f <= r); mln_assertion(r <= 1.0f);
+ mln_assertion(0.0f <= g); mln_assertion(g <= 1.0f);
+ mln_assertion(0.0f <= b); mln_assertion(b <= 1.0f);
+ mln_assertion(0.0f <= a); mln_assertion(a <= 1.0f);
+ face_value.push_back(value::rgb8(r, g, b));
+ }
/* \} */
@@ -506,6 +569,15 @@ namespace mln
void
+ rgb8_off_loader::reserve(unsigned /* nvertices */,
+ unsigned /* nedges */,
+ unsigned nfaces)
+ {
+ face_value.reserve(nfaces);
+ }
+
+
+ void
bin_off_loader::assign(values& vs, const domain& s)
{
// Default values.
@@ -523,6 +595,16 @@ namespace mln
vs[D] = face_value;
}
+ void
+ rgb8_off_loader::assign(values& vs, const domain& s)
+ {
+ // Default values for n-face with n in [0, D[.
+ for (unsigned i = 0; i < D; ++i)
+ vs[i].insert(vs[i].begin(), s.cplx().nfaces(i), literal::black);
+ // Values for D-faces.
+ vs[D] = face_value;
+ }
+
// --------- //
// Helpers. //
--
1.6.1.2
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-04-06 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Consider box cardinality for line detection criteria.
* edwin/tree/test.cc: Consider box cardinality for line
detection criteria.
---
Makefile | 1813 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
configure | 7
test.cc | 103 ---
3 files changed, 1839 insertions(+), 84 deletions(-)
Index: trunk/milena/sandbox/edwin/tree/configure
===================================================================
--- trunk/milena/sandbox/edwin/tree/configure (revision 3608)
+++ trunk/milena/sandbox/edwin/tree/configure (revision 3609)
@@ -1,13 +1,12 @@
#! /bin/bash
-
for arg in "$@"; do
if [ "$arg" == "--debug" ]; then
debug=1;
- fi
-
- if [ "$arg" == "--release" ]; then
+ elif [ "$arg" == "--release" ]; then
release=1;
+ elif [ "${arg#--mln_dir=}" ]; then
+ MLN_DIR=${arg#--mln_dir=}
fi
done
@@ -19,3 +18,4 @@
if [ "$release" ]; then
echo 'RELEASE=1' > makefile.rules
fi
\ No newline at end of file
+echo "MLN_DIR = $MLN_DIR" > makefile.rules
\ No newline at end of file
Index: trunk/milena/sandbox/edwin/tree/test.cc
===================================================================
--- trunk/milena/sandbox/edwin/tree/test.cc (revision 3608)
+++ trunk/milena/sandbox/edwin/tree/test.cc (revision 3609)
@@ -2,9 +2,12 @@
#include <mln/core/image/image2d.hh>
#include <mln/core/image/image_if.hh>
#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/routine/duplicate.hh>
#include <mln/core/alias/window2d.hh>
+#include <mln/core/alias/w_window2d_int.hh>
+#include <mln/core/routine/duplicate.hh>
#include <mln/core/var.hh>
+
+/* mln value */
#include <mln/value/int_u16.hh>
/* Site set */
@@ -18,24 +21,17 @@
#include "run.hh"
#include "accumulator/arg_max.hh"
-/* morpho closing */
-// #include <mln/morpho/opening/structural.hh>
-// #include <mln/morpho/closing/structural.hh>
/* Attributes */
-// #include <mln/transform/distance_geodesic.hh>
-#include <mln/core/alias/window2d.hh>
-#include <mln/core/alias/w_window2d_int.hh>
#include <mln/transform/distance_front.hh>
-#include <mln/morpho/attribute/card.hh>
#include "../attributes/bbox.hh"
+#include <mln/morpho/attribute/card.hh>
#include <mln/make/w_window2d_int.hh>
/* io */
#include <mln/io/pbm/load.hh>
#include <mln/io/pgm/save.hh>
#include <mln/io/ppm/save.hh>
-//#include <../../theo/color/change_attributes.hh>
/* data & pw */
#include <mln/core/concept/function.hh>
@@ -55,6 +51,7 @@
/* std */
#include <string>
#include <iostream>
+#include <cmath>
bool mydebug = false;
@@ -72,30 +69,33 @@
<< "*********************" << std::endl;
}
-template <typename P2V>
-struct ratio_ : public mln::Function_p2v< ratio_<P2V> >
+template <typename P2V, typename G>
+struct ratio_ : public mln::Function_p2v< ratio_<P2V, G> >
{
typedef double result;
- ratio_(const P2V& f) :
- f_ (f)
+ ratio_(const P2V& f, const G& g) :
+ f_ (f), g_ (g)
{
}
template <typename P>
double operator() (const P& p) const
{
- return (double) (f_(p).len(1)) / (double)(f_(p).len(0));
+ mln_VAR(box, f_(p));
+ double a = (double) (box.len(1)) / (double)(box.len(0));
+ return a * std::log(g_(p));
}
protected:
const P2V& f_;
+ const G& g_;
};
-template <typename P2V>
-ratio_<P2V> ratio(const mln::Function_p2v<P2V>& f)
+template <typename P2V, typename G>
+ratio_<P2V, G> ratio(const mln::Function_p2v<P2V>& f, const mln::Function_p2v<G>& g)
{
- return ratio_<P2V>(exact(f));
+ return ratio_<P2V, G>(exact(f), exact(g));
}
@@ -104,7 +104,6 @@
int main(int argc, char* argv[])
{
using namespace mln;
-// using value::int_u8;
using value::int_u16;
std::string arg;
@@ -140,7 +139,6 @@
io::pbm::load(input_, argv[1]);
/* Work on geodesic distance image */
-// I input = transform::distance_geodesic(input_, c8(), mln_max(int_u8));
I input;
{
const int weights[9] =
@@ -153,29 +151,9 @@
input = transform::distance_front(input_, c8(), win, mln_max(int_u16));
}
- if (mydebug)
+ if (mydebug) {
dsp("Distance geodesic");
-
- /* Closing */
- {
- bool w[3][1];
-
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 1; j++)
- w[i][j] = 1;
-
-// input = morpho::closing::structural(input, convert::to<window2d>(w));
- }
-
- /* Opening */
- {
- bool w[1][15];
-
- for (int i = 0; i < 1; i++)
- for (int j = 0; j < 15; j++)
- w[i][j] = 1;
-
-// input = morpho::opening::structural(input, convert::to<window2d>(w));
+ io::pgm::save(input, "distance.pgm");
}
/* Component tree creation */
@@ -185,42 +163,20 @@
S sorted_sites = level::sort_psites_decreasing(input);
tree_t tree(input, sorted_sites, c4());
-
- io::pgm::save(input, "distance.pgm");
-
/* Compute Attribute On Image */
typedef morpho::attribute::bbox<I> bbox_t;
+ typedef morpho::attribute::card<I> card_t;
typedef mln_ch_value_(I, double) A;
mln_VAR(attr_image, morpho::tree::compute_attribute_image(bbox_t (), tree));
- A a = duplicate(ratio(pw::value(attr_image)) | attr_image.domain());
+ mln_VAR(card_image, morpho::tree::compute_attribute_image(card_t (), tree));
+ A a = duplicate(ratio(pw::value(attr_image), pw::value(card_image)) | attr_image.domain());
morpho::tree::propagate_representant(tree, a);
if (mydebug) {
dsp("Image sharp attribute");
}
- /* We don't want little components */
-
- // So we compute card attribute and we filter big components
- // FIXME: some attributes are compositions of attributes, here
- // sharpness can give area so, it would be fine if we could give an
- // optional extra argument to compute_attribute where the
- // accumulators image will be stored.
-
-// typedef morpho::attribute::card<I> card_t;
-// typedef mln_ch_value_(tree_t::function, mln_result_(card_t)) B;
-
-// B b = morpho::tree::compute_attribute_image(card_t (), tree);
-// morpho::tree::propagate_representant(tree, b);
-
-// if (mydebug) {
-// dsp("Image card attribute"); display_tree_attributes(tree, b);
-// }
-
-// a = duplicate((fun::p2v::ternary(pw::value(b) > pw::cst(2), pw::value(a), pw::cst(0.0))) | a.domain());
-
-
/* Run max accumulator */
accumulator::arg_max<A> argmax(a);
p_array< mln_psite_(A) > obj_array; // Array of object components.
@@ -271,22 +227,21 @@
/* Labeling */
typedef mln_ch_value_(I, value::label<8>) L;
+ typedef mln_ch_value_(I, value::rgb<8>) O;
value::label<8> nlabel;
L label = labeling::blobs(mask, c4(), nlabel);
- io::ppm::save(debug::colorize(value::rgb8(), label, nlabel), "label.pgm");
+ O output = debug::colorize(value::rgb8(), label, nlabel);
+ io::ppm::save(output, "label.pgm");
/* Now store output image image */
- I out;
+ O out;
initialize(out, input);
- data::fill(out, 0);
- data::paste(input | pw::value(mask), out);
+ data::fill(out, literal::black_t());
+ data::paste(output | pw::value(input_), out);
if (mydebug) {
- mln_fwd_piter_(p_array< mln_psite_(I) >) c(obj_array);
- for_all(c)
- draw::box(out, attr_image(c), mln_max(int_u16));
dsp("Mask input");
}
- io::pgm::save(out, "output.pgm");
+ io::ppm::save(out, "output.pgm");
}
Index: trunk/milena/sandbox/edwin/tree/Makefile
===================================================================
--- trunk/milena/sandbox/edwin/tree/Makefile (revision 3608)
+++ trunk/milena/sandbox/edwin/tree/Makefile (revision 3609)
@@ -1,7 +1,10 @@
include makefile.rules
-TARGET=sharp
-SRC=sharp.cc
-OBJS=${SRC:.cc=.o}
+TARGET=test
+sharp_SRC=sharp.cc
+sharp_OBJS=${sharp_SRC:.cc=.o}
+
+test_SRC=test.cc
+test_OBJS=${test_SRC:.cc=.o}
OLENADIR=$(MLN_DIR)/..
MILENADIR=$(OLENADIR)/milena
@@ -16,11 +19,11 @@
LD=g++
LDFLAGS=
-all: clean $(TARGET)
+all: $(TARGET)
-$(TARGET): $(OBJS) $(SRC)
- $(LD) $(LDFLAGS) -o $@ $(OBJS)
+$(TARGET): $($(TARGET)_OBJS) $($(TARGET)_SRC)
+ $(LD) $(LDFLAGS) -o $@ $($(TARGET)_OBJS)
%.o: %.cc
$(CXX) $(CXXFLAGS) -c $<
@@ -28,7 +31,1805 @@
%.o: %.hh
$(CXX) $(CXXFLAGS) -c $<
+depend:
+ makedepend -- $(CXXFLAGS) -- -v $($(TARGET)_SRC)
+
clean:
rm -f *.o $(TARGET)
#rm -f *.pbm
#find -name "*.pgm" \! -regex ".*/affiche2?.pgm" -delete
+# DO NOT DELETE
+
+test.o: /work/carlinet/trunk/milena/mln/core/image/image2d.hh
+# /work/carlinet/trunk/milena/mln/core/image/image2d.hh includes:
+# mln/core/internal/image_primary.hh
+# mln/core/internal/fixme.hh
+# mln/core/alias/box2d.hh
+# mln/core/routine/init.hh
+# mln/border/thickness.hh
+# mln/value/set.hh
+# mln/fun/i2v/all_to.hh
+# mln/core/trait/pixter.hh
+# mln/core/dpoints_pixter.hh
+# mln/core/pixter2d.hh
+# mln/make/image.hh
+# mln/make/image2d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/image_primary.hh
+# /work/carlinet/trunk/milena/mln/core/internal/image_primary.hh includes:
+# mln/core/internal/image_base.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/image_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/image_base.hh includes:
+# mln/core/concept/image.hh
+# mln/core/grids.hh
+# mln/core/trait/qlf_value.hh
+# mln/core/internal/check/image_all.hh
+# mln/core/internal/data.hh
+# mln/core/internal/morpher_lvalue.hh
+# mln/util/tracked_ptr.hh
+# mln/value/set.hh
+# mln/value/super_value.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/image.hh
+# /work/carlinet/trunk/milena/mln/core/concept/image.hh includes:
+# mln/core/concept/site_set.hh
+# mln/core/concept/mesh.hh
+# mln/core/trait/all.hh
+# mln/core/macros.hh
+# mln/core/site_set/box.hh
+# mln/trait/concrete.hh
+# mln/trait/images.hh
+# mln/metal/is_a.hh
+# mln/metal/equal.hh
+# mln/tag/init.hh
+# mln/core/routine/initialize.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/site_set.hh
+# /work/carlinet/trunk/milena/mln/core/concept/site_set.hh includes:
+# mln/core/concept/site_iterator.hh
+# mln/trait/site_sets.hh
+# mln/metal/not_equal.hh
+# mln/metal/is_a.hh
+# mln/metal/is_unqualif.hh
+# mln/util/ord.hh
+# mln/core/site_set/operators.hh
+# mln/core/routine/ops.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/site_iterator.hh
+# /work/carlinet/trunk/milena/mln/core/concept/site_iterator.hh includes:
+# mln/core/concept/site_proxy.hh
+# mln/core/concept/iterator.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/site_proxy.hh
+# /work/carlinet/trunk/milena/mln/core/concept/site_proxy.hh includes:
+# mln/core/concept/proxy.hh
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/proxy.hh
+# /work/carlinet/trunk/milena/mln/core/concept/proxy.hh includes:
+# mln/core/concept/object.hh
+# mln/value/ops.hh
+# mln/convert/from_to.hxx
+# mln/core/concept/proxy.hxx
+test.o: /work/carlinet/trunk/milena/mln/core/concept/object.hh
+# /work/carlinet/trunk/milena/mln/core/concept/object.hh includes:
+# mln/core/macros.hh
+# mln/core/category.hh
+# mln/core/contract.hh
+# mln/core/internal/fixme.hh
+# mln/trace/all.hh
+# mln/metal/abort.hh
+# mln/metal/is_a.hh
+# mln/metal/is_not_a.hh
+# mln/metal/is.hh
+# mln/metal/is_not.hh
+# mln/metal/equal.hh
+# mln/metal/not_equal.hh
+# mln/metal/converts_to.hh
+# mln/metal/ret.hh
+# mln/metal/unqualif.hh
+# mln/metal/math/all.hh
+# mln/core/routine/exact.hh
+# mln/core/routine/ops.hh
+test.o: /work/carlinet/trunk/milena/mln/core/macros.hh
+test.o: /work/carlinet/trunk/milena/mln/core/category.hh
+# /work/carlinet/trunk/milena/mln/core/category.hh includes:
+# mln/metal/equal.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/equal.hh
+# /work/carlinet/trunk/milena/mln/metal/equal.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/bool.hh
+# /work/carlinet/trunk/milena/mln/metal/bool.hh includes:
+# mln/metal/bexpr.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/bexpr.hh
+# /work/carlinet/trunk/milena/mln/metal/bexpr.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/core/contract.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/fixme.hh
+test.o: /work/carlinet/trunk/milena/mln/trace/all.hh
+# /work/carlinet/trunk/milena/mln/trace/all.hh includes:
+# mln/trace/quiet.hh
+# mln/trace/entering.hh
+# mln/trace/exiting.hh
+# mln/trace/stop.hh
+# mln/trace/resume.hh
+# mln/trace/warning.hh
+test.o: /work/carlinet/trunk/milena/mln/trace/quiet.hh
+# /work/carlinet/trunk/milena/mln/trace/quiet.hh includes:
+# sys/time.h
+test.o: /usr/include/sys/time.h
+# /usr/include/sys/time.h includes:
+# features.h
+# bits/types.h
+# time.h
+# bits/time.h
+# sys/select.h
+test.o: /usr/include/features.h
+# /usr/include/features.h includes:
+# sys/cdefs.h
+# gnu/stubs.h
+test.o: /usr/include/sys/cdefs.h
+# /usr/include/sys/cdefs.h includes:
+# bits/wordsize.h
+test.o: /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h
+# /usr/include/gnu/stubs.h includes:
+# bits/wordsize.h
+# gnu/stubs-32.h
+test.o: /usr/include/gnu/stubs-32.h /usr/include/bits/types.h
+# /usr/include/bits/types.h includes:
+# features.h
+# bits/wordsize.h
+# bits/typesizes.h
+test.o: /usr/include/bits/typesizes.h /usr/include/time.h
+# /usr/include/time.h includes:
+# bits/types.h
+test.o: /usr/include/bits/time.h
+# /usr/include/bits/time.h includes:
+# bits/types.h
+test.o: /usr/include/sys/select.h
+# /usr/include/sys/select.h includes:
+# features.h
+# bits/types.h
+# bits/select.h
+# bits/sigset.h
+# time.h
+# bits/time.h
+test.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
+test.o: /work/carlinet/trunk/milena/mln/trace/entering.hh
+# /work/carlinet/trunk/milena/mln/trace/entering.hh includes:
+# mln/trace/quiet.hh
+test.o: /work/carlinet/trunk/milena/mln/trace/exiting.hh
+# /work/carlinet/trunk/milena/mln/trace/exiting.hh includes:
+# mln/core/contract.hh
+# mln/trace/quiet.hh
+test.o: /work/carlinet/trunk/milena/mln/trace/stop.hh
+# /work/carlinet/trunk/milena/mln/trace/stop.hh includes:
+# mln/trace/quiet.hh
+test.o: /work/carlinet/trunk/milena/mln/trace/resume.hh
+# /work/carlinet/trunk/milena/mln/trace/resume.hh includes:
+# mln/trace/quiet.hh
+test.o: /work/carlinet/trunk/milena/mln/trace/warning.hh
+# /work/carlinet/trunk/milena/mln/trace/warning.hh includes:
+# mln/trace/quiet.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/abort.hh
+# /work/carlinet/trunk/milena/mln/metal/abort.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is_a.hh
+# /work/carlinet/trunk/milena/mln/metal/is_a.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is_not_a.hh
+# /work/carlinet/trunk/milena/mln/metal/is_not_a.hh includes:
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is.hh
+# /work/carlinet/trunk/milena/mln/metal/is.hh includes:
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is_not.hh
+# /work/carlinet/trunk/milena/mln/metal/is_not.hh includes:
+# mln/metal/is.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/not_equal.hh
+# /work/carlinet/trunk/milena/mln/metal/not_equal.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/converts_to.hh
+# /work/carlinet/trunk/milena/mln/metal/converts_to.hh includes:
+# mln/metal/is_a.hh
+# mln/metal/const.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/const.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/ret.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/unqualif.hh
+# /work/carlinet/trunk/milena/mln/metal/unqualif.hh includes:
+# mln/metal/unconst.hh
+# mln/metal/unref.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/unconst.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/unref.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/math/all.hh
+# /work/carlinet/trunk/milena/mln/metal/math/all.hh includes:
+# mln/metal/math/pow.hh
+# mln/metal/math/root.hh
+# mln/metal/math/sqrt.hh
+# mln/metal/math/max.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/math/pow.hh
+# /work/carlinet/trunk/milena/mln/metal/math/pow.hh includes:
+# mln/metal/bool.hh
+# mln/metal/int.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/int.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/math/root.hh
+# /work/carlinet/trunk/milena/mln/metal/math/root.hh includes:
+# mln/metal/math/pow.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/math/sqrt.hh
+# /work/carlinet/trunk/milena/mln/metal/math/sqrt.hh includes:
+# mln/metal/bool.hh
+# mln/metal/int.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/math/max.hh
+# /work/carlinet/trunk/milena/mln/metal/math/max.hh includes:
+# mln/metal/bool.hh
+# mln/metal/int.hh
+test.o: /work/carlinet/trunk/milena/mln/core/routine/exact.hh
+# /work/carlinet/trunk/milena/mln/core/routine/exact.hh includes:
+# mln/core/internal/exact.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/exact.hh
+# /work/carlinet/trunk/milena/mln/core/internal/exact.hh includes:
+# mln/core/concept/object.hh
+test.o: /work/carlinet/trunk/milena/mln/core/routine/ops.hh
+# /work/carlinet/trunk/milena/mln/core/routine/ops.hh includes:
+# mln/trait/op/all.hh
+# mln/core/concept/object.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/all.hh
+# /work/carlinet/trunk/milena/mln/trait/op/all.hh includes:
+# mln/trait/op/plus.hh
+# mln/trait/op/minus.hh
+# mln/trait/op/times.hh
+# mln/trait/op/div.hh
+# mln/trait/op/mod.hh
+# mln/trait/op/uplus.hh
+# mln/trait/op/uminus.hh
+# mln/trait/op/preinc.hh
+# mln/trait/op/postinc.hh
+# mln/trait/op/predec.hh
+# mln/trait/op/postdec.hh
+# mln/trait/op/eq.hh
+# mln/trait/op/neq.hh
+# mln/trait/op/less.hh
+# mln/trait/op/leq.hh
+# mln/trait/op/geq.hh
+# mln/trait/op/greater.hh
+# mln/trait/op/and.hh
+# mln/trait/op/or.hh
+# mln/trait/op/xor.hh
+# mln/trait/op/lor.hh
+# mln/trait/op/not.hh
+# mln/trait/op/ord.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/plus.hh
+# /work/carlinet/trunk/milena/mln/trait/op/plus.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/promote.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/decl.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/promote.hh
+# /work/carlinet/trunk/milena/mln/trait/promote.hh includes:
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/solve.hh
+# /work/carlinet/trunk/milena/mln/trait/solve.hh includes:
+# mln/core/category.hh
+# mln/metal/equal.hh
+# mln/metal/if.hh
+# mln/metal/ret.hh
+# mln/trait/solve_unary.hh
+# mln/trait/solve_binary.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/if.hh
+# /work/carlinet/trunk/milena/mln/metal/if.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/solve_unary.hh
+# /work/carlinet/trunk/milena/mln/trait/solve_unary.hh includes:
+# mln/core/category.hh
+# mln/core/routine/exact.hh
+# mln/metal/equal.hh
+# mln/metal/if.hh
+# mln/metal/ret.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/solve_binary.hh
+# /work/carlinet/trunk/milena/mln/trait/solve_binary.hh includes:
+# mln/core/category.hh
+# mln/core/routine/exact.hh
+# mln/metal/equal.hh
+# mln/metal/if.hh
+# mln/metal/ret.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/minus.hh
+# /work/carlinet/trunk/milena/mln/trait/op/minus.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/promote.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/times.hh
+# /work/carlinet/trunk/milena/mln/trait/op/times.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/div.hh
+# /work/carlinet/trunk/milena/mln/trait/op/div.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/promote.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/mod.hh
+# /work/carlinet/trunk/milena/mln/trait/op/mod.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/promote.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/uplus.hh
+# /work/carlinet/trunk/milena/mln/trait/op/uplus.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/uminus.hh
+# /work/carlinet/trunk/milena/mln/trait/op/uminus.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/preinc.hh
+# /work/carlinet/trunk/milena/mln/trait/op/preinc.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/postinc.hh
+# /work/carlinet/trunk/milena/mln/trait/op/postinc.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/predec.hh
+# /work/carlinet/trunk/milena/mln/trait/op/predec.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/postdec.hh
+# /work/carlinet/trunk/milena/mln/trait/op/postdec.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/eq.hh
+# /work/carlinet/trunk/milena/mln/trait/op/eq.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/neq.hh
+# /work/carlinet/trunk/milena/mln/trait/op/neq.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/less.hh
+# /work/carlinet/trunk/milena/mln/trait/op/less.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/leq.hh
+# /work/carlinet/trunk/milena/mln/trait/op/leq.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/geq.hh
+# /work/carlinet/trunk/milena/mln/trait/op/geq.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/greater.hh
+# /work/carlinet/trunk/milena/mln/trait/op/greater.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/and.hh
+# /work/carlinet/trunk/milena/mln/trait/op/and.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/or.hh
+# /work/carlinet/trunk/milena/mln/trait/op/or.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/xor.hh
+# /work/carlinet/trunk/milena/mln/trait/op/xor.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/lor.hh
+# /work/carlinet/trunk/milena/mln/trait/op/lor.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/not.hh
+# /work/carlinet/trunk/milena/mln/trait/op/not.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/op/ord.hh
+# /work/carlinet/trunk/milena/mln/trait/op/ord.hh includes:
+# mln/trait/op/decl.hh
+# mln/trait/solve.hh
+# mln/util/ord.hh
+test.o: /work/carlinet/trunk/milena/mln/util/ord.hh
+# /work/carlinet/trunk/milena/mln/util/ord.hh includes:
+# mln/core/concept/object.hh
+# mln/trait/op/ord.hh
+test.o: /work/carlinet/trunk/milena/mln/value/ops.hh
+# /work/carlinet/trunk/milena/mln/value/ops.hh includes:
+# mln/trait/op/all.hh
+# mln/value/builtin/all.hh
+# mln/value/concept/all.hh
+# mln/value/equiv.hh
+# mln/trait/value_.hh
+# mln/literal/zero.hh
+# mln/literal/one.hh
+# mln/literal/ops.hh
+# mln/metal/ret.hh
+test.o: /work/carlinet/trunk/milena/mln/value/builtin/all.hh
+# /work/carlinet/trunk/milena/mln/value/builtin/all.hh includes:
+# mln/value/builtin/carrays.hh
+# mln/value/builtin/integers.hh
+# mln/value/builtin/floatings.hh
+# mln/value/builtin/symbolics.hh
+# mln/value/builtin/promotions.hh
+# mln/value/builtin/ops.hh
+test.o: /work/carlinet/trunk/milena/mln/value/builtin/carrays.hh
+# /work/carlinet/trunk/milena/mln/value/builtin/carrays.hh includes:
+# mln/value/concept/built_in.hh
+# mln/value/concept/vectorial.hh
+# mln/trait/value_.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/built_in.hh
+# /work/carlinet/trunk/milena/mln/value/concept/built_in.hh includes:
+# mln/core/category.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/vectorial.hh
+# /work/carlinet/trunk/milena/mln/value/concept/vectorial.hh includes:
+# mln/core/concept/value.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/value.hh
+# /work/carlinet/trunk/milena/mln/core/concept/value.hh includes:
+# mln/core/concept/object.hh
+# mln/trait/value_.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value_.hh
+# /work/carlinet/trunk/milena/mln/trait/value_.hh includes:
+# mln/metal/int.hh
+# mln/metal/math/pow.hh
+# mln/metal/if.hh
+# mln/trait/value/all.hh
+# mln/core/def/low_quant_nbits.hh
+# mln/trait/value/print.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value/all.hh
+# /work/carlinet/trunk/milena/mln/trait/value/all.hh includes:
+# mln/trait/undef.hh
+# mln/trait/value/nature.hh
+# mln/trait/value/kind.hh
+# mln/trait/value/quant.hh
+# mln/trait/value/internal/all.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/undef.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value/nature.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value/kind.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value/quant.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value/internal/all.hh
+# /work/carlinet/trunk/milena/mln/trait/value/internal/all.hh includes:
+# mln/trait/value/internal/comp.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value/internal/comp.hh
+# /work/carlinet/trunk/milena/mln/trait/value/internal/comp.hh includes:
+# mln/metal/bool.hh
+# mln/metal/if.hh
+test.o: /work/carlinet/trunk/milena/mln/core/def/low_quant_nbits.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/value/print.hh
+# /work/carlinet/trunk/milena/mln/trait/value/print.hh includes:
+# mln/trait/value_.hh
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/value/builtin/integers.hh
+# /work/carlinet/trunk/milena/mln/value/builtin/integers.hh includes:
+# mln/value/internal/limits.hh
+# mln/value/concept/built_in.hh
+# mln/value/concept/integer.hh
+# mln/trait/value_.hh
+# mln/metal/int.hh
+# mln/metal/if.hh
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/value/internal/limits.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/integer.hh
+# /work/carlinet/trunk/milena/mln/value/concept/integer.hh includes:
+# mln/value/concept/scalar.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/scalar.hh
+# /work/carlinet/trunk/milena/mln/value/concept/scalar.hh includes:
+# mln/core/concept/value.hh
+# mln/literal/one.hh
+test.o: /work/carlinet/trunk/milena/mln/literal/one.hh
+# /work/carlinet/trunk/milena/mln/literal/one.hh includes:
+# mln/core/concept/literal.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/literal.hh
+# /work/carlinet/trunk/milena/mln/core/concept/literal.hh includes:
+# mln/core/concept/object.hh
+test.o: /work/carlinet/trunk/milena/mln/value/builtin/floatings.hh
+# /work/carlinet/trunk/milena/mln/value/builtin/floatings.hh includes:
+# mln/value/internal/limits.hh
+# mln/value/concept/built_in.hh
+# mln/value/concept/floating.hh
+# mln/trait/value_.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/floating.hh
+# /work/carlinet/trunk/milena/mln/value/concept/floating.hh includes:
+# mln/value/concept/scalar.hh
+test.o: /work/carlinet/trunk/milena/mln/value/builtin/symbolics.hh
+# /work/carlinet/trunk/milena/mln/value/builtin/symbolics.hh includes:
+# mln/value/concept/built_in.hh
+# mln/value/concept/symbolic.hh
+# mln/trait/value_.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/symbolic.hh
+# /work/carlinet/trunk/milena/mln/value/concept/symbolic.hh includes:
+# mln/core/concept/value.hh
+test.o: /work/carlinet/trunk/milena/mln/value/builtin/promotions.hh
+# /work/carlinet/trunk/milena/mln/value/builtin/promotions.hh includes:
+# mln/trait/promote.hh
+# mln/metal/ret.hh
+test.o: /work/carlinet/trunk/milena/mln/value/builtin/ops.hh
+# /work/carlinet/trunk/milena/mln/value/builtin/ops.hh includes:
+# mln/value/scalar.hh
+# mln/trait/op/all.hh
+# mln/value/builtin/promotions.hh
+test.o: /work/carlinet/trunk/milena/mln/value/scalar.hh
+# /work/carlinet/trunk/milena/mln/value/scalar.hh includes:
+# mln/value/concept/scalar.hh
+# mln/metal/is_a.hh
+# mln/metal/if.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/all.hh
+# /work/carlinet/trunk/milena/mln/value/concept/all.hh includes:
+# mln/value/concept/built_in.hh
+# mln/value/concept/data.hh
+# mln/value/concept/floating.hh
+# mln/value/concept/integer.hh
+# mln/value/concept/scalar.hh
+# mln/value/concept/structured.hh
+# mln/value/concept/symbolic.hh
+# mln/value/concept/vectorial.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/data.hh
+# /work/carlinet/trunk/milena/mln/value/concept/data.hh includes:
+# mln/core/concept/value.hh
+test.o: /work/carlinet/trunk/milena/mln/value/concept/structured.hh
+# /work/carlinet/trunk/milena/mln/value/concept/structured.hh includes:
+# mln/core/concept/value.hh
+test.o: /work/carlinet/trunk/milena/mln/value/equiv.hh
+# /work/carlinet/trunk/milena/mln/value/equiv.hh includes:
+# mln/core/concept/value.hh
+# mln/value/cast.hh
+test.o: /work/carlinet/trunk/milena/mln/value/cast.hh
+# /work/carlinet/trunk/milena/mln/value/cast.hh includes:
+# mln/core/concept/value.hh
+# mln/value/equiv.hh
+test.o: /work/carlinet/trunk/milena/mln/literal/zero.hh
+# /work/carlinet/trunk/milena/mln/literal/zero.hh includes:
+# mln/core/concept/literal.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/literal/ops.hh
+# /work/carlinet/trunk/milena/mln/literal/ops.hh includes:
+# mln/core/concept/literal.hh
+# mln/trait/all.hh
+# mln/metal/equal.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/all.hh
+# /work/carlinet/trunk/milena/mln/trait/all.hh includes:
+# mln/trait/solve.hh
+# mln/trait/promote.hh
+# mln/trait/op/all.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/from_to.hxx
+# /work/carlinet/trunk/milena/mln/convert/from_to.hxx includes:
+# mln/core/def/all.hh
+# mln/core/grids.hh
+test.o: /work/carlinet/trunk/milena/mln/core/def/all.hh
+# /work/carlinet/trunk/milena/mln/core/def/all.hh includes:
+# mln/core/def/coord.hh
+# mln/core/def/coordf.hh
+# mln/core/def/low_quant_nbits.hh
+test.o: /work/carlinet/trunk/milena/mln/core/def/coord.hh
+test.o: /work/carlinet/trunk/milena/mln/core/def/coordf.hh
+test.o: /work/carlinet/trunk/milena/mln/core/grids.hh
+# /work/carlinet/trunk/milena/mln/core/grids.hh includes:
+# mln/core/concept/regular_grid.hh
+# mln/core/def/coord.hh
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/regular_grid.hh
+# /work/carlinet/trunk/milena/mln/core/concept/regular_grid.hh includes:
+# mln/core/concept/mesh.hh
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/mesh.hh
+# /work/carlinet/trunk/milena/mln/core/concept/mesh.hh includes:
+# mln/core/concept/object.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/proxy.hxx
+# /work/carlinet/trunk/milena/mln/core/concept/proxy.hxx includes:
+# mln/core/internal/force_exact.hh
+# mln/metal/unqualif.hh
+# mln/metal/is_a.hh
+# mln/metal/if.hh
+# mln/metal/is_const.hh
+# mln/metal/const.hh
+# mln/metal/unconst.hh
+# mln/metal/is_not_ref.hh
+# mln/metal/ref.hh
+# mln/metal/fix_return.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/force_exact.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is_const.hh
+# /work/carlinet/trunk/milena/mln/metal/is_const.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is_not_ref.hh
+# /work/carlinet/trunk/milena/mln/metal/is_not_ref.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/ref.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/fix_return.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/iterator.hh
+# /work/carlinet/trunk/milena/mln/core/concept/iterator.hh includes:
+# mln/core/concept/object.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/site_sets.hh
+# /work/carlinet/trunk/milena/mln/trait/site_sets.hh includes:
+# mln/trait/undef.hh
+# mln/trait/site_set/props.hh
+# mln/trait/site_set/print.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/site_set/props.hh
+# /work/carlinet/trunk/milena/mln/trait/site_set/props.hh includes:
+# mln/trait/undef.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/site_set/print.hh
+# /work/carlinet/trunk/milena/mln/trait/site_set/print.hh includes:
+# mln/trait/site_sets.hh
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is_unqualif.hh
+# /work/carlinet/trunk/milena/mln/metal/is_unqualif.hh includes:
+# mln/metal/equal.hh
+# mln/metal/unqualif.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/operators.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/operators.hh includes:
+# mln/core/concept/site_set.hh
+test.o: /work/carlinet/trunk/milena/mln/core/trait/all.hh
+# /work/carlinet/trunk/milena/mln/core/trait/all.hh includes:
+# mln/core/trait/op_mult.hh
+# mln/core/trait/pixter.hh
+# mln/core/trait/qlf_value.hh
+test.o: /work/carlinet/trunk/milena/mln/core/trait/op_mult.hh
+test.o: /work/carlinet/trunk/milena/mln/core/trait/pixter.hh
+# /work/carlinet/trunk/milena/mln/core/trait/pixter.hh includes:
+# mln/metal/none.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/none.hh
+test.o: /work/carlinet/trunk/milena/mln/core/trait/qlf_value.hh
+# /work/carlinet/trunk/milena/mln/core/trait/qlf_value.hh includes:
+# mln/core/macros.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/box.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/box.hh includes:
+# mln/core/concept/box.hh
+# mln/core/internal/box_impl.hh
+# mln/core/point.hh
+# mln/literal/origin.hh
+# mln/core/site_set/box_piter.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/box.hh
+# /work/carlinet/trunk/milena/mln/core/concept/box.hh includes:
+# mln/core/concept/site_set.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/box_impl.hh
+# /work/carlinet/trunk/milena/mln/core/internal/box_impl.hh includes:
+# mln/core/internal/force_exact.hh
+test.o: /work/carlinet/trunk/milena/mln/core/point.hh
+# /work/carlinet/trunk/milena/mln/core/point.hh includes:
+# mln/core/def/coord.hh
+# mln/core/concept/proxy.hh
+# mln/core/concept/gpoint.hh
+# mln/core/internal/coord_impl.hh
+# mln/fun/i2v/all_to.hh
+# mln/metal/bool.hh
+# mln/metal/is_not.hh
+# mln/algebra/vec.hh
+# mln/metal/converts_to.hh
+# mln/algebra/h_vec.hh
+# mln/util/yes.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/gpoint.hh
+# /work/carlinet/trunk/milena/mln/core/concept/gpoint.hh includes:
+# mln/core/concept/site.hh
+# mln/core/concept/gdpoint.hh
+# mln/value/concept/scalar.hh
+# mln/algebra/vec.hh
+# mln/util/ord.hh
+# mln/debug/format.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/site.hh
+# /work/carlinet/trunk/milena/mln/core/concept/site.hh includes:
+# mln/core/concept/object.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/gdpoint.hh
+# /work/carlinet/trunk/milena/mln/core/concept/gdpoint.hh includes:
+# mln/core/concept/object.hh
+# mln/core/grids.hh
+# mln/trait/all.hh
+# mln/value/scalar.hh
+# mln/debug/format.hh
+test.o: /work/carlinet/trunk/milena/mln/debug/format.hh
+test.o: /work/carlinet/trunk/milena/mln/algebra/vec.hh
+# /work/carlinet/trunk/milena/mln/algebra/vec.hh includes:
+# mln/core/concept/object.hh
+# mln/literal/zero.hh
+# mln/literal/origin.hh
+# mln/norm/l2.hh
+# mln/trait/all.hh
+# mln/trait/value_.hh
+# mln/fun/i2v/all_to.hh
+# mln/debug/format.hh
+# mln/value/ops.hh
+# mln/make/vec.hh
+test.o: /work/carlinet/trunk/milena/mln/literal/origin.hh
+# /work/carlinet/trunk/milena/mln/literal/origin.hh includes:
+# mln/core/concept/literal.hh
+test.o: /work/carlinet/trunk/milena/mln/norm/l2.hh
+# /work/carlinet/trunk/milena/mln/norm/l2.hh includes:
+# mln/math/sqr.hh
+# mln/math/sqrt.hh
+# mln/algebra/vec.hh
+# mln/value/ops.hh
+test.o: /work/carlinet/trunk/milena/mln/math/sqr.hh
+test.o: /work/carlinet/trunk/milena/mln/math/sqrt.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/i2v/all_to.hh
+# /work/carlinet/trunk/milena/mln/fun/i2v/all_to.hh includes:
+# mln/core/concept/function.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/function.hh
+# /work/carlinet/trunk/milena/mln/core/concept/function.hh includes:
+# mln/core/concept/object.hh
+test.o: /work/carlinet/trunk/milena/mln/make/vec.hh
+# /work/carlinet/trunk/milena/mln/make/vec.hh includes:
+# mln/algebra/vec.hh
+# mln/core/concept/function.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/coord_impl.hh
+# /work/carlinet/trunk/milena/mln/core/internal/coord_impl.hh includes:
+# mln/core/internal/force_exact.hh
+test.o: /work/carlinet/trunk/milena/mln/algebra/h_vec.hh
+# /work/carlinet/trunk/milena/mln/algebra/h_vec.hh includes:
+# mln/algebra/vec.hh
+# mln/literal/one.hh
+test.o: /work/carlinet/trunk/milena/mln/util/yes.hh
+# /work/carlinet/trunk/milena/mln/util/yes.hh includes:
+# mln/core/concept/object.hh
+# mln/core/routine/ops.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/box_piter.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/box_piter.hh includes:
+# mln/core/internal/site_set_iterator_base.hh
+# mln/core/concept/box.hh
+# mln/core/site_set/box.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/site_set_iterator_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/site_set_iterator_base.hh includes:
+# mln/core/internal/site_iterator_base.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/site_iterator_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/site_iterator_base.hh includes:
+# mln/core/concept/site_iterator.hh
+# mln/core/concept/pseudo_site.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/pseudo_site.hh
+# /work/carlinet/trunk/milena/mln/core/concept/pseudo_site.hh includes:
+# mln/core/concept/site_proxy.hh
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/concrete.hh
+# /work/carlinet/trunk/milena/mln/trait/concrete.hh includes:
+# mln/trait/ch_value.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/ch_value.hh
+# /work/carlinet/trunk/milena/mln/trait/ch_value.hh includes:
+# mln/tag/skeleton.hh
+# mln/trait/image_from_grid.hh
+# mln/trait/ch_function_value.hh
+test.o: /work/carlinet/trunk/milena/mln/tag/skeleton.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/image_from_grid.hh
+# /work/carlinet/trunk/milena/mln/trait/image_from_grid.hh includes:
+# mln/core/grids.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/ch_function_value.hh
+# /work/carlinet/trunk/milena/mln/trait/ch_function_value.hh includes:
+# mln/fun/v2v/ch_function_value.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/v2v/ch_function_value.hh
+# /work/carlinet/trunk/milena/mln/fun/v2v/ch_function_value.hh includes:
+# mln/core/concept/function.hh
+# mln/fun/internal/ch_function_value_impl.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/internal/ch_function_value_impl.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/images.hh
+# /work/carlinet/trunk/milena/mln/trait/images.hh includes:
+# mln/trait/undef.hh
+# mln/trait/image/props.hh
+# mln/trait/value_.hh
+# mln/metal/bexpr.hh
+# mln/metal/equal.hh
+# mln/metal/if.hh
+# mln/metal/is_const.hh
+# mln/trait/image/print.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/image/props.hh
+# /work/carlinet/trunk/milena/mln/trait/image/props.hh includes:
+# mln/trait/undef.hh
+# mln/trait/value/kind.hh
+# mln/core/def/coord.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/image/print.hh
+# /work/carlinet/trunk/milena/mln/trait/image/print.hh includes:
+# mln/trait/images.hh
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/tag/init.hh
+test.o: /work/carlinet/trunk/milena/mln/core/routine/initialize.hh
+# /work/carlinet/trunk/milena/mln/core/routine/initialize.hh includes:
+# mln/core/concept/image.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/check/image_all.hh
+# /work/carlinet/trunk/milena/mln/core/internal/check/image_all.hh includes:
+# mln/trait/images.hh
+# mln/core/internal/check/image_fastest.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/check/image_fastest.hh
+# /work/carlinet/trunk/milena/mln/core/internal/check/image_fastest.hh includes:
+# mln/metal/bool.hh
+# mln/core/macros.hh
+# mln/core/trait/pixter.hh
+# mln/core/trait/qlf_value.hh
+# mln/core/internal/force_exact.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/data.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/morpher_lvalue.hh
+# /work/carlinet/trunk/milena/mln/core/internal/morpher_lvalue.hh includes:
+# mln/core/macros.hh
+test.o: /work/carlinet/trunk/milena/mln/util/tracked_ptr.hh
+# /work/carlinet/trunk/milena/mln/util/tracked_ptr.hh includes:
+# mln/core/contract.hh
+test.o: /work/carlinet/trunk/milena/mln/value/set.hh
+# /work/carlinet/trunk/milena/mln/value/set.hh includes:
+# mln/value/internal/iterable_set.hh
+# mln/trait/value_.hh
+test.o: /work/carlinet/trunk/milena/mln/value/internal/iterable_set.hh
+# /work/carlinet/trunk/milena/mln/value/internal/iterable_set.hh includes:
+# mln/core/concept/value_set.hh
+# mln/trait/value_.hh
+# mln/value/builtin/all.hh
+# mln/value/internal/convert.hh
+# mln/value/viter.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/value_set.hh
+# /work/carlinet/trunk/milena/mln/core/concept/value_set.hh includes:
+# mln/core/concept/value_iterator.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/value_iterator.hh
+# /work/carlinet/trunk/milena/mln/core/concept/value_iterator.hh includes:
+# mln/core/concept/iterator.hh
+test.o: /work/carlinet/trunk/milena/mln/value/internal/convert.hh
+# /work/carlinet/trunk/milena/mln/value/internal/convert.hh includes:
+# mln/core/contract.hh
+# mln/trait/value_.hh
+test.o: /work/carlinet/trunk/milena/mln/value/viter.hh
+# /work/carlinet/trunk/milena/mln/value/viter.hh includes:
+# mln/core/concept/value_iterator.hh
+# mln/core/concept/value_set.hh
+test.o: /work/carlinet/trunk/milena/mln/value/super_value.hh
+# /work/carlinet/trunk/milena/mln/value/super_value.hh includes:
+# mln/value/sign.hh
+test.o: /work/carlinet/trunk/milena/mln/value/sign.hh
+# /work/carlinet/trunk/milena/mln/value/sign.hh includes:
+# mln/value/internal/integer.hh
+# mln/trait/value_.hh
+# mln/literal/zero.hh
+# mln/literal/one.hh
+# mln/debug/format.hh
+test.o: /work/carlinet/trunk/milena/mln/value/internal/integer.hh
+# /work/carlinet/trunk/milena/mln/value/internal/integer.hh includes:
+# mln/value/concept/scalar.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/box2d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/box2d.hh includes:
+# mln/core/site_set/box.hh
+# mln/core/alias/point2d.hh
+# mln/make/box2d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/point2d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/point2d.hh includes:
+# mln/core/point.hh
+# mln/core/concept/site_proxy.hh
+# mln/core/internal/force_exact.hh
+# mln/core/alias/dpoint2d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/dpoint2d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/dpoint2d.hh includes:
+# mln/core/dpoint.hh
+# mln/core/def/coord.hh
+# mln/core/alias/point2d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/dpoint.hh
+# /work/carlinet/trunk/milena/mln/core/dpoint.hh includes:
+# mln/core/def/coord.hh
+# mln/core/concept/gdpoint.hh
+# mln/core/internal/coord_impl.hh
+# mln/fun/i2v/all.hh
+# mln/algebra/vec.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/i2v/all.hh
+# /work/carlinet/trunk/milena/mln/fun/i2v/all.hh includes:
+# mln/fun/i2v/all_to.hh
+# mln/fun/i2v/array.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/i2v/array.hh
+# /work/carlinet/trunk/milena/mln/fun/i2v/array.hh includes:
+# mln/core/concept/function.hh
+# mln/fun/internal/array_base.hh
+# mln/util/array.hh
+# mln/metal/equal.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/internal/array_base.hh
+# /work/carlinet/trunk/milena/mln/fun/internal/array_base.hh includes:
+# mln/util/array.hh
+# mln/tag/init.hh
+test.o: /work/carlinet/trunk/milena/mln/util/array.hh
+# /work/carlinet/trunk/milena/mln/util/array.hh includes:
+# mln/core/concept/proxy.hh
+# mln/core/concept/iterator.hh
+test.o: /work/carlinet/trunk/milena/mln/make/box2d.hh
+# /work/carlinet/trunk/milena/mln/make/box2d.hh includes:
+# mln/core/alias/box2d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/routine/init.hh
+# /work/carlinet/trunk/milena/mln/core/routine/init.hh includes:
+# mln/tag/init.hh
+# mln/geom/bbox.hh
+# mln/border/find.hh
+# mln/core/routine/init.hxx
+test.o: /work/carlinet/trunk/milena/mln/geom/bbox.hh
+# /work/carlinet/trunk/milena/mln/geom/bbox.hh includes:
+# mln/core/site_set/box.hh
+# mln/core/concept/image.hh
+# mln/core/concept/window.hh
+# mln/core/concept/weighted_window.hh
+# mln/literal/zero.hh
+# mln/accu/bbox.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/window.hh
+# /work/carlinet/trunk/milena/mln/core/concept/window.hh includes:
+# mln/core/concept/object.hh
+# mln/core/concept/iterator.hh
+# mln/trait/windows.hh
+# mln/core/site_set/p_array.hh
+# mln/core/internal/geom_bbox.hh
+# mln/convert/from_to.hxx
+# mln/util/array.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/windows.hh
+# /work/carlinet/trunk/milena/mln/trait/windows.hh includes:
+# mln/trait/undef.hh
+# mln/trait/window/props.hh
+# mln/trait/window/print.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/window/props.hh
+# /work/carlinet/trunk/milena/mln/trait/window/props.hh includes:
+# mln/trait/undef.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/window/print.hh
+# /work/carlinet/trunk/milena/mln/trait/window/print.hh includes:
+# mln/trait/windows.hh
+# mln/metal/is_a.hh
+# mln/metal/bexpr.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/p_array.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/p_array.hh includes:
+# mln/core/internal/site_set_base.hh
+# mln/core/internal/site_set_iterator_base.hh
+# mln/core/internal/pseudo_site_base.hh
+# mln/util/index.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/site_set_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/site_set_base.hh includes:
+# mln/core/concept/site_set.hh
+# mln/core/concept/site_proxy.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/pseudo_site_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/pseudo_site_base.hh includes:
+# mln/core/concept/pseudo_site.hh
+test.o: /work/carlinet/trunk/milena/mln/util/index.hh
+# /work/carlinet/trunk/milena/mln/util/index.hh includes:
+# mln/core/concept/object.hh
+# mln/util/dindex.hh
+test.o: /work/carlinet/trunk/milena/mln/util/dindex.hh
+# /work/carlinet/trunk/milena/mln/util/dindex.hh includes:
+# mln/util/index.hh
+# mln/literal/zero.hh
+# mln/literal/one.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/geom_bbox.hh
+# /work/carlinet/trunk/milena/mln/core/internal/geom_bbox.hh includes:
+# mln/accu/bbox.hh
+# mln/literal/origin.hh
+test.o: /work/carlinet/trunk/milena/mln/accu/bbox.hh
+# /work/carlinet/trunk/milena/mln/accu/bbox.hh includes:
+# mln/core/site_set/box.hh
+# mln/core/concept/meta_accumulator.hh
+# mln/accu/internal/base.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/meta_accumulator.hh
+# /work/carlinet/trunk/milena/mln/core/concept/meta_accumulator.hh includes:
+# mln/core/concept/object.hh
+# mln/core/concept/accumulator.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/accumulator.hh
+# /work/carlinet/trunk/milena/mln/core/concept/accumulator.hh includes:
+# mln/core/concept/proxy.hh
+# mln/metal/fix_return.hh
+# mln/metal/const.hh
+# mln/trait/accumulators.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/accumulators.hh
+# /work/carlinet/trunk/milena/mln/trait/accumulators.hh includes:
+# mln/trait/accumulator/props.hh
+# mln/trait/undef.hh
+# mln/trait/accumulator/print.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/accumulator/props.hh
+test.o: /work/carlinet/trunk/milena/mln/trait/accumulator/print.hh
+# /work/carlinet/trunk/milena/mln/trait/accumulator/print.hh includes:
+# mln/trait/accumulators.hh
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/accu/internal/base.hh
+# /work/carlinet/trunk/milena/mln/accu/internal/base.hh includes:
+# mln/core/concept/accumulator.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/weighted_window.hh
+# /work/carlinet/trunk/milena/mln/core/concept/weighted_window.hh includes:
+# mln/core/concept/object.hh
+# mln/core/concept/iterator.hh
+# mln/trait/windows.hh
+test.o: /work/carlinet/trunk/milena/mln/border/find.hh
+# /work/carlinet/trunk/milena/mln/border/find.hh includes:
+# mln/core/internal/image_morpher.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/image_morpher.hh
+# /work/carlinet/trunk/milena/mln/core/internal/image_morpher.hh includes:
+# mln/core/internal/image_base.hh
+# mln/metal/const.hh
+# mln/metal/is_const.hh
+# mln/metal/is_not_const.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/is_not_const.hh
+# /work/carlinet/trunk/milena/mln/metal/is_not_const.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/core/routine/init.hxx
+test.o: /work/carlinet/trunk/milena/mln/border/thickness.hh
+test.o: /work/carlinet/trunk/milena/mln/core/dpoints_pixter.hh
+# /work/carlinet/trunk/milena/mln/core/dpoints_pixter.hh includes:
+# mln/core/concept/proxy.hh
+# mln/core/concept/pixel_iterator.hh
+# mln/core/internal/pixel_impl.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/pixel_iterator.hh
+# /work/carlinet/trunk/milena/mln/core/concept/pixel_iterator.hh includes:
+# mln/core/concept/iterator.hh
+# mln/core/concept/generalized_pixel.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/generalized_pixel.hh
+# /work/carlinet/trunk/milena/mln/core/concept/generalized_pixel.hh includes:
+# mln/core/concept/object.hh
+# mln/core/internal/force_exact.hh
+# mln/core/trait/qlf_value.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/pixel_impl.hh
+# /work/carlinet/trunk/milena/mln/core/internal/pixel_impl.hh includes:
+# mln/core/concept/image.hh
+# mln/core/internal/force_exact.hh
+# mln/util/pix.hh
+test.o: /work/carlinet/trunk/milena/mln/util/pix.hh
+# /work/carlinet/trunk/milena/mln/util/pix.hh includes:
+# mln/core/concept/image.hh
+# mln/make/pix.hh
+test.o: /work/carlinet/trunk/milena/mln/make/pix.hh
+# /work/carlinet/trunk/milena/mln/make/pix.hh includes:
+# mln/util/pix.hh
+test.o: /work/carlinet/trunk/milena/mln/core/pixter2d.hh
+# /work/carlinet/trunk/milena/mln/core/pixter2d.hh includes:
+# mln/core/internal/pixel_iterator_base.hh
+# mln/core/alias/point2d.hh
+# mln/geom/size2d.hh
+# mln/opt/at.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/pixel_iterator_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/pixel_iterator_base.hh includes:
+# mln/core/concept/pixel_iterator.hh
+# mln/core/internal/pixel_impl.hh
+# mln/core/trait/qlf_value.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/size2d.hh
+# /work/carlinet/trunk/milena/mln/geom/size2d.hh includes:
+# mln/geom/nrows.hh
+# mln/geom/ncols.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/nrows.hh
+# /work/carlinet/trunk/milena/mln/geom/nrows.hh includes:
+# mln/geom/min_row.hh
+# mln/geom/max_row.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/min_row.hh
+# /work/carlinet/trunk/milena/mln/geom/min_row.hh includes:
+# mln/core/concept/image.hh
+# mln/geom/bbox.hh
+# mln/metal/bexpr.hh
+# mln/metal/int.hh
+# mln/metal/equal.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/max_row.hh
+# /work/carlinet/trunk/milena/mln/geom/max_row.hh includes:
+# mln/core/concept/image.hh
+# mln/geom/bbox.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/ncols.hh
+# /work/carlinet/trunk/milena/mln/geom/ncols.hh includes:
+# mln/geom/min_col.hh
+# mln/geom/max_col.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/min_col.hh
+# /work/carlinet/trunk/milena/mln/geom/min_col.hh includes:
+# mln/core/concept/image.hh
+# mln/geom/bbox.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/max_col.hh
+# /work/carlinet/trunk/milena/mln/geom/max_col.hh includes:
+# mln/core/concept/image.hh
+# mln/geom/bbox.hh
+test.o: /work/carlinet/trunk/milena/mln/opt/at.hh
+# /work/carlinet/trunk/milena/mln/opt/at.hh includes:
+# mln/core/concept/image.hh
+# mln/trait/images.hh
+# mln/trace/all.hh
+# mln/core/alias/point1d.hh
+# mln/core/alias/point2d.hh
+# mln/core/alias/point3d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/point1d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/point1d.hh includes:
+# mln/core/point.hh
+# mln/core/concept/site_proxy.hh
+# mln/core/internal/force_exact.hh
+# mln/core/alias/dpoint1d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/dpoint1d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/dpoint1d.hh includes:
+# mln/core/dpoint.hh
+# mln/core/grids.hh
+# mln/core/def/coord.hh
+# mln/core/alias/point1d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/point3d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/point3d.hh includes:
+# mln/core/point.hh
+# mln/core/concept/site_proxy.hh
+# mln/core/internal/force_exact.hh
+# mln/core/alias/dpoint3d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/dpoint3d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/dpoint3d.hh includes:
+# mln/core/dpoint.hh
+# mln/core/grids.hh
+# mln/core/def/coord.hh
+# mln/core/alias/point3d.hh
+test.o: /work/carlinet/trunk/milena/mln/make/image.hh
+# /work/carlinet/trunk/milena/mln/make/image.hh includes:
+# mln/core/image/image1d.hh
+# mln/core/image/image2d.hh
+# mln/core/image/image3d.hh
+# mln/opt/at.hh
+test.o: /work/carlinet/trunk/milena/mln/core/image/image1d.hh
+# /work/carlinet/trunk/milena/mln/core/image/image1d.hh includes:
+# mln/core/internal/fixme.hh
+# mln/core/internal/image_primary.hh
+# mln/core/alias/box1d.hh
+# mln/border/thickness.hh
+# mln/value/set.hh
+# mln/fun/i2v/all_to.hh
+# mln/core/trait/pixter.hh
+# mln/core/dpoints_pixter.hh
+# mln/core/pixter1d.hh
+# mln/core/w_window.hh
+# mln/make/image.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/box1d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/box1d.hh includes:
+# mln/core/site_set/box.hh
+# mln/core/alias/point1d.hh
+# mln/make/box1d.hh
+test.o: /work/carlinet/trunk/milena/mln/make/box1d.hh
+# /work/carlinet/trunk/milena/mln/make/box1d.hh includes:
+# mln/core/alias/box1d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/pixter1d.hh
+# /work/carlinet/trunk/milena/mln/core/pixter1d.hh includes:
+# mln/core/internal/pixel_iterator_base.hh
+# mln/core/alias/point1d.hh
+# mln/geom/size1d.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/size1d.hh
+# /work/carlinet/trunk/milena/mln/geom/size1d.hh includes:
+# mln/geom/ninds.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/ninds.hh
+# /work/carlinet/trunk/milena/mln/geom/ninds.hh includes:
+# mln/geom/min_ind.hh
+# mln/geom/max_ind.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/min_ind.hh
+# /work/carlinet/trunk/milena/mln/geom/min_ind.hh includes:
+# mln/core/concept/image.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/max_ind.hh
+# /work/carlinet/trunk/milena/mln/geom/max_ind.hh includes:
+# mln/core/concept/image.hh
+test.o: /work/carlinet/trunk/milena/mln/core/w_window.hh
+# /work/carlinet/trunk/milena/mln/core/w_window.hh includes:
+# mln/core/internal/weighted_window_base.hh
+# mln/core/concept/image.hh
+# mln/core/site_set/box.hh
+# mln/core/window.hh
+# mln/core/dpsites_piter.hh
+# mln/value/ops.hh
+# mln/util/ord.hh
+# mln/geom/bbox.hh
+# mln/literal/zero.hh
+# mln/convert/to.hh
+# mln/make/w_window.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/weighted_window_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/weighted_window_base.hh includes:
+# mln/core/concept/weighted_window.hh
+test.o: /work/carlinet/trunk/milena/mln/core/window.hh
+# /work/carlinet/trunk/milena/mln/core/window.hh includes:
+# mln/core/internal/window_base.hh
+# mln/core/concept/gdpoint.hh
+# mln/metal/is_a.hh
+# mln/util/set.hh
+# mln/fun/i2v/all_to.hh
+# mln/norm/linfty.hh
+# mln/literal/zero.hh
+# mln/core/dpsites_piter.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/window_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/window_base.hh includes:
+# mln/core/concept/window.hh
+test.o: /work/carlinet/trunk/milena/mln/util/set.hh
+# /work/carlinet/trunk/milena/mln/util/set.hh includes:
+# mln/core/concept/proxy.hh
+# mln/util/ord.hh
+test.o: /work/carlinet/trunk/milena/mln/norm/linfty.hh
+# /work/carlinet/trunk/milena/mln/norm/linfty.hh includes:
+# mln/math/abs.hh
+# mln/algebra/vec.hh
+test.o: /work/carlinet/trunk/milena/mln/math/abs.hh
+# /work/carlinet/trunk/milena/mln/math/abs.hh includes:
+# mln/value/int_u.hh
+test.o: /work/carlinet/trunk/milena/mln/value/int_u.hh
+# /work/carlinet/trunk/milena/mln/value/int_u.hh includes:
+# mln/trait/all.hh
+# mln/value/ops.hh
+# mln/metal/math/pow.hh
+# mln/value/internal/value_like.hh
+# mln/value/internal/encoding.hh
+# mln/value/concept/integer.hh
+# mln/trait/value_.hh
+# mln/debug/format.hh
+test.o: /work/carlinet/trunk/milena/mln/value/internal/value_like.hh
+# /work/carlinet/trunk/milena/mln/value/internal/value_like.hh includes:
+# mln/core/concept/value.hh
+# mln/core/internal/force_exact.hh
+test.o: /work/carlinet/trunk/milena/mln/value/internal/encoding.hh
+test.o: /work/carlinet/trunk/milena/mln/core/dpsites_piter.hh
+# /work/carlinet/trunk/milena/mln/core/dpsites_piter.hh includes:
+# mln/core/internal/site_relative_iterator_base.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/site_relative_iterator_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/site_relative_iterator_base.hh includes:
+# mln/core/internal/site_iterator_base.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/to.hh
+# /work/carlinet/trunk/milena/mln/convert/to.hh includes:
+# mln/core/routine/exact.hh
+# mln/metal/equal.hh
+# mln/trace/all.hh
+# mln/convert/from_to.hh
+# mln/convert/from_to.hxx
+test.o: /work/carlinet/trunk/milena/mln/convert/from_to.hh
+# /work/carlinet/trunk/milena/mln/convert/from_to.hh includes:
+# mln/convert/impl/all.hh
+# mln/convert/from_to.hxx
+# mln/metal/abort.hh
+# mln/metal/converts_to.hh
+# mln/metal/is.hh
+# mln/metal/is_a.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/all.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/all.hh includes:
+# mln/convert/impl/from_double_to_value.hh
+# mln/convert/impl/from_float_to_value.hh
+# mln/convert/impl/from_image_to_site_set.hh
+# mln/convert/impl/from_int_to_value.hh
+# mln/convert/impl/from_site_set_to_image.hh
+# mln/convert/impl/from_unsigned_to_value.hh
+# mln/convert/impl/from_value_to_value.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/from_double_to_value.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/from_double_to_value.hh includes:
+# mln/value/concept/integer.hh
+# mln/value/concept/floating.hh
+# mln/core/concept/value.hh
+# mln/math/round.hh
+test.o: /work/carlinet/trunk/milena/mln/math/round.hh
+# /work/carlinet/trunk/milena/mln/math/round.hh includes:
+# mln/core/concept/function.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/from_float_to_value.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/from_float_to_value.hh includes:
+# mln/value/concept/integer.hh
+# mln/value/concept/floating.hh
+# mln/core/concept/value.hh
+# mln/math/round.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/from_image_to_site_set.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/from_image_to_site_set.hh includes:
+# mln/core/site_set/p_run.hh
+# mln/core/site_set/p_array.hh
+# mln/metal/converts_to.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/p_run.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/p_run.hh includes:
+# mln/core/internal/site_set_base.hh
+# mln/core/site_set/box.hh
+# mln/core/internal/pseudo_site_base.hh
+# mln/util/index.hh
+# mln/core/site_set/p_run_piter.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/p_run_piter.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/p_run_piter.hh includes:
+# mln/core/site_set/p_run.hh
+# mln/core/internal/site_set_iterator_base.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/from_int_to_value.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/from_int_to_value.hh includes:
+# mln/value/concept/integer.hh
+# mln/core/concept/value.hh
+# mln/math/round.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/from_site_set_to_image.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/from_site_set_to_image.hh includes:
+# mln/core/image/sub_image.hh
+# mln/geom/bbox.hh
+# mln/trait/image_from_grid.hh
+# mln/data/fill.hh
+test.o: /work/carlinet/trunk/milena/mln/core/image/sub_image.hh
+# /work/carlinet/trunk/milena/mln/core/image/sub_image.hh includes:
+# mln/core/internal/image_domain_morpher.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/image_domain_morpher.hh
+# /work/carlinet/trunk/milena/mln/core/internal/image_domain_morpher.hh includes:
+# mln/core/internal/image_morpher.hh
+test.o: /work/carlinet/trunk/milena/mln/data/fill.hh
+# /work/carlinet/trunk/milena/mln/data/fill.hh includes:
+# mln/core/concept/function.hh
+# mln/pw/image.hh
+# mln/convert/to_fun.hh
+# mln/data/fill_with_image.hh
+# mln/data/fill_with_value.hh
+test.o: /work/carlinet/trunk/milena/mln/pw/image.hh
+# /work/carlinet/trunk/milena/mln/pw/image.hh includes:
+# mln/core/internal/image_primary.hh
+# mln/core/concept/function.hh
+# mln/value/set.hh
+# mln/metal/unqualif.hh
+# mln/metal/not_equal.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/to_fun.hh
+# /work/carlinet/trunk/milena/mln/convert/to_fun.hh includes:
+# mln/pw/value.hh
+# mln/fun/c.hh
+test.o: /work/carlinet/trunk/milena/mln/pw/value.hh
+# /work/carlinet/trunk/milena/mln/pw/value.hh includes:
+# mln/fun/internal/selector.hh
+# mln/core/concept/image.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/internal/selector.hh
+# /work/carlinet/trunk/milena/mln/fun/internal/selector.hh includes:
+# mln/core/concept/function.hh
+# mln/core/concept/site.hh
+# mln/core/concept/pseudo_site.hh
+# mln/metal/unqualif.hh
+# mln/metal/if.hh
+# mln/metal/is_a.hh
+# mln/algebra/vec.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/c.hh
+# /work/carlinet/trunk/milena/mln/fun/c.hh includes:
+# mln/fun/internal/selector.hh
+# mln/metal/unqualif.hh
+test.o: /work/carlinet/trunk/milena/mln/data/fill_with_image.hh
+# /work/carlinet/trunk/milena/mln/data/fill_with_image.hh includes:
+# mln/core/concept/image.hh
+# mln/data/fill_with_image.spe.hh
+test.o: /work/carlinet/trunk/milena/mln/data/fill_with_image.spe.hh
+# /work/carlinet/trunk/milena/mln/data/fill_with_image.spe.hh includes:
+# mln/data/memcpy_.hh
+# mln/data/fill_with_value.hh
+# mln/core/pixel.hh
+# mln/core/box_runstart_piter.hh
+# mln/border/get.hh
+# mln/opt/value.hh
+# mln/opt/element.hh
+test.o: /work/carlinet/trunk/milena/mln/data/memcpy_.hh
+# /work/carlinet/trunk/milena/mln/data/memcpy_.hh includes:
+# mln/core/concept/image.hh
+# mln/core/pixel.hh
+# mln/metal/is_not_const.hh
+# mln/opt/element.hh
+test.o: /work/carlinet/trunk/milena/mln/core/pixel.hh
+# /work/carlinet/trunk/milena/mln/core/pixel.hh includes:
+# mln/core/concept/generalized_pixel.hh
+# mln/core/internal/pixel_impl.hh
+# mln/make/pixel.hh
+test.o: /work/carlinet/trunk/milena/mln/make/pixel.hh
+# /work/carlinet/trunk/milena/mln/make/pixel.hh includes:
+# mln/core/concept/image.hh
+# mln/core/pixel.hh
+test.o: /work/carlinet/trunk/milena/mln/opt/element.hh
+# /work/carlinet/trunk/milena/mln/opt/element.hh includes:
+# mln/core/concept/image.hh
+# mln/trait/images.hh
+test.o: /work/carlinet/trunk/milena/mln/data/fill_with_value.hh
+# /work/carlinet/trunk/milena/mln/data/fill_with_value.hh includes:
+# mln/core/concept/image.hh
+# mln/data/fill_with_value.spe.hh
+test.o: /work/carlinet/trunk/milena/mln/data/fill_with_value.spe.hh
+# /work/carlinet/trunk/milena/mln/data/fill_with_value.spe.hh includes:
+# mln/data/memset_.hh
+# mln/opt/value.hh
+# mln/opt/element.hh
+test.o: /work/carlinet/trunk/milena/mln/data/memset_.hh
+# /work/carlinet/trunk/milena/mln/data/memset_.hh includes:
+# mln/core/concept/image.hh
+# mln/core/pixel.hh
+# mln/metal/is_not_const.hh
+# mln/opt/element.hh
+test.o: /work/carlinet/trunk/milena/mln/opt/value.hh
+# /work/carlinet/trunk/milena/mln/opt/value.hh includes:
+# mln/core/concept/image.hh
+# mln/trait/images.hh
+test.o: /work/carlinet/trunk/milena/mln/core/box_runstart_piter.hh
+# /work/carlinet/trunk/milena/mln/core/box_runstart_piter.hh includes:
+# mln/core/internal/site_iterator_base.hh
+# mln/core/site_set/box.hh
+test.o: /work/carlinet/trunk/milena/mln/border/get.hh
+# /work/carlinet/trunk/milena/mln/border/get.hh includes:
+# mln/trait/images.hh
+# mln/trace/all.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/from_unsigned_to_value.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/from_unsigned_to_value.hh includes:
+# mln/value/concept/integer.hh
+# mln/core/concept/value.hh
+# mln/value/label.hh
+# mln/math/round.hh
+test.o: /work/carlinet/trunk/milena/mln/value/label.hh
+# /work/carlinet/trunk/milena/mln/value/label.hh includes:
+# mln/debug/format.hh
+# mln/metal/math/pow.hh
+# mln/trait/value_.hh
+# mln/value/concept/symbolic.hh
+# mln/value/internal/value_like.hh
+# mln/value/internal/convert.hh
+# mln/value/internal/encoding.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/impl/from_value_to_value.hh
+# /work/carlinet/trunk/milena/mln/convert/impl/from_value_to_value.hh includes:
+# mln/core/concept/image.hh
+# mln/core/concept/site_set.hh
+# mln/value/concept/all.hh
+# mln/core/site_set/p_run.hh
+# mln/metal/converts_to.hh
+# mln/convert/from_to.hxx
+test.o: /work/carlinet/trunk/milena/mln/make/w_window.hh
+# /work/carlinet/trunk/milena/mln/make/w_window.hh includes:
+# mln/core/concept/window.hh
+# mln/core/concept/function.hh
+# mln/core/w_window.hh
+test.o: /work/carlinet/trunk/milena/mln/core/image/image3d.hh
+# /work/carlinet/trunk/milena/mln/core/image/image3d.hh includes:
+# mln/core/internal/fixme.hh
+# mln/core/internal/image_primary.hh
+# mln/core/alias/box3d.hh
+# mln/border/thickness.hh
+# mln/value/set.hh
+# mln/fun/i2v/all_to.hh
+# mln/core/trait/pixter.hh
+# mln/core/dpoints_pixter.hh
+# mln/core/pixter3d.hh
+# mln/core/w_window.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/box3d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/box3d.hh includes:
+# mln/core/site_set/box.hh
+# mln/core/alias/point3d.hh
+# mln/make/box3d.hh
+test.o: /work/carlinet/trunk/milena/mln/make/box3d.hh
+# /work/carlinet/trunk/milena/mln/make/box3d.hh includes:
+# mln/core/alias/box3d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/pixter3d.hh
+# /work/carlinet/trunk/milena/mln/core/pixter3d.hh includes:
+# mln/core/internal/pixel_iterator_base.hh
+# mln/core/alias/point3d.hh
+# mln/geom/size3d.hh
+# mln/opt/at.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/size3d.hh
+# /work/carlinet/trunk/milena/mln/geom/size3d.hh includes:
+# mln/geom/nslis.hh
+# mln/geom/nrows.hh
+# mln/geom/ncols.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/nslis.hh
+# /work/carlinet/trunk/milena/mln/geom/nslis.hh includes:
+# mln/geom/min_sli.hh
+# mln/geom/max_sli.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/min_sli.hh
+# /work/carlinet/trunk/milena/mln/geom/min_sli.hh includes:
+# mln/core/concept/image.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/max_sli.hh
+# /work/carlinet/trunk/milena/mln/geom/max_sli.hh includes:
+# mln/core/concept/image.hh
+test.o: /work/carlinet/trunk/milena/mln/make/image2d.hh
+# /work/carlinet/trunk/milena/mln/make/image2d.hh includes:
+# mln/core/image/image2d.hh
+test.o: /work/carlinet/trunk/milena/mln/core/image/image_if.hh
+# /work/carlinet/trunk/milena/mln/core/image/image_if.hh includes:
+# mln/core/internal/image_domain_morpher.hh
+# mln/core/site_set/p_if.hh
+# mln/pw/all.hh
+# mln/convert/to_fun.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/p_if.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/p_if.hh includes:
+# mln/core/internal/site_set_base.hh
+# mln/core/concept/function.hh
+# mln/core/site_set/p_if_piter.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/p_if_piter.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/p_if_piter.hh includes:
+# mln/core/internal/piter_adaptor.hh
+# mln/core/site_set/p_if.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/piter_adaptor.hh
+# /work/carlinet/trunk/milena/mln/core/internal/piter_adaptor.hh includes:
+# mln/core/internal/site_iterator_base.hh
+test.o: /work/carlinet/trunk/milena/mln/pw/all.hh
+# /work/carlinet/trunk/milena/mln/pw/all.hh includes:
+# mln/pw/cst.hh
+# mln/pw/image.hh
+# mln/pw/value.hh
+# mln/pw/var.hh
+# mln/fun/ops.hh
+test.o: /work/carlinet/trunk/milena/mln/pw/cst.hh
+# /work/carlinet/trunk/milena/mln/pw/cst.hh includes:
+# mln/fun/internal/selector.hh
+test.o: /work/carlinet/trunk/milena/mln/pw/var.hh
+# /work/carlinet/trunk/milena/mln/pw/var.hh includes:
+# mln/core/concept/function.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/ops.hh
+# /work/carlinet/trunk/milena/mln/fun/ops.hh includes:
+# mln/core/concept/function.hh
+# mln/fun/internal/selector.hh
+# mln/trait/all.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/neighb2d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/neighb2d.hh includes:
+# mln/core/alias/window2d.hh
+# mln/core/neighb.hh
+# mln/convert/from_to.hh
+test.o: /work/carlinet/trunk/milena/mln/core/alias/window2d.hh
+# /work/carlinet/trunk/milena/mln/core/alias/window2d.hh includes:
+# mln/core/window.hh
+# mln/core/alias/dpoint2d.hh
+# mln/metal/math/sqrt.hh
+# mln/convert/from_to.hxx
+test.o: /work/carlinet/trunk/milena/mln/core/neighb.hh
+# /work/carlinet/trunk/milena/mln/core/neighb.hh includes:
+# mln/core/internal/neighborhood_base.hh
+# mln/core/internal/site_relative_iterator_base.hh
+# mln/core/internal/neighb_niter_impl.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/neighborhood_base.hh
+# /work/carlinet/trunk/milena/mln/core/internal/neighborhood_base.hh includes:
+# mln/core/concept/neighborhood.hh
+# mln/core/concept/window.hh
+test.o: /work/carlinet/trunk/milena/mln/core/concept/neighborhood.hh
+# /work/carlinet/trunk/milena/mln/core/concept/neighborhood.hh includes:
+# mln/core/concept/window.hh
+# mln/trait/windows.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/neighb_niter_impl.hh
+# /work/carlinet/trunk/milena/mln/core/internal/neighb_niter_impl.hh includes:
+# mln/core/macros.hh
+# mln/core/internal/force_exact.hh
+test.o: /work/carlinet/trunk/milena/mln/core/routine/duplicate.hh
+# /work/carlinet/trunk/milena/mln/core/routine/duplicate.hh includes:
+# mln/core/concept/image.hh
+# mln/core/routine/init.hh
+# mln/data/fill.hh
+test.o: /work/carlinet/trunk/milena/mln/core/var.hh
+# /work/carlinet/trunk/milena/mln/core/var.hh includes:
+# mln/core/macros.hh
+test.o: /work/carlinet/trunk/milena/mln/level/sort_psites.hh
+# /work/carlinet/trunk/milena/mln/level/sort_psites.hh includes:
+# mln/core/concept/image.hh
+# mln/convert/to_p_array.hh
+# mln/histo/compute.hh
+# mln/util/ord.hh
+# mln/geom/nsites.hh
+test.o: /work/carlinet/trunk/milena/mln/convert/to_p_array.hh
+# /work/carlinet/trunk/milena/mln/convert/to_p_array.hh includes:
+# mln/core/site_set/p_array.hh
+# mln/core/concept/image.hh
+# mln/core/concept/window.hh
+test.o: /work/carlinet/trunk/milena/mln/histo/compute.hh
+# /work/carlinet/trunk/milena/mln/histo/compute.hh includes:
+# mln/core/concept/image.hh
+# mln/histo/array.hh
+# mln/histo/compute.spe.hh
+test.o: /work/carlinet/trunk/milena/mln/histo/array.hh
+# /work/carlinet/trunk/milena/mln/histo/array.hh includes:
+# mln/value/set.hh
+test.o: /work/carlinet/trunk/milena/mln/histo/compute.spe.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/nsites.hh
+# /work/carlinet/trunk/milena/mln/geom/nsites.hh includes:
+# mln/core/concept/image.hh
+# mln/set/card.hh
+test.o: /work/carlinet/trunk/milena/mln/set/card.hh
+# /work/carlinet/trunk/milena/mln/set/card.hh includes:
+# mln/core/concept/site_set.hh
+test.o: /work/carlinet/trunk/milena/mln/morpho/tree/data.hh
+# /work/carlinet/trunk/milena/mln/morpho/tree/data.hh includes:
+# mln/morpho/tree/compute_parent.hh
+# mln/core/site_set/p_array.hh
+# mln/core/internal/site_set_iterator_base.hh
+# mln/core/internal/piter_identity.hh
+test.o: /work/carlinet/trunk/milena/mln/morpho/tree/compute_parent.hh
+# /work/carlinet/trunk/milena/mln/morpho/tree/compute_parent.hh includes:
+# mln/core/concept/image.hh
+# mln/core/concept/neighborhood.hh
+# mln/data/fill.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/piter_identity.hh
+# /work/carlinet/trunk/milena/mln/core/internal/piter_identity.hh includes:
+# mln/core/internal/piter_adaptor.hh
+test.o: /work/carlinet/trunk/milena/mln/morpho/tree/compute_attribute_image.hh
+# /work/carlinet/trunk/milena/mln/morpho/tree/compute_attribute_image.hh includes:
+# mln/core/concept/image.hh
+# mln/morpho/tree/data.hh
+# mln/trait/accumulators.hh
+# mln/util/pix.hh
+# mln/data/fill.hh
+test.o: propagate.hh
+# propagate.hh includes:
+# mln/morpho/tree/data.hh
+test.o: run.hh
+# run.hh includes:
+# mln/core/concept/accumulator.hh
+# mln/core/concept/image.hh
+# mln/core/concept/function.hh
+# mln/core/site_set/p_array.hh
+# mln/util/pix.hh
+# mln/trace/entering.hh
+# mln/trace/exiting.hh
+# propagate_node.hh
+test.o: propagate_node.hh
+# propagate_node.hh includes:
+# mln/morpho/tree/data.hh
+# mln/core/site_set/p_array.hh
+test.o: accumulator/arg_max.hh
+# accumulator/arg_max.hh includes:
+# mln/core/concept/image.hh
+# mln/accu/internal/base.hh
+# mln/util/pix.hh
+test.o: /work/carlinet/trunk/milena/mln/transform/distance_geodesic.hh
+# /work/carlinet/trunk/milena/mln/transform/distance_geodesic.hh includes:
+# mln/canvas/distance_geodesic.hh
+# mln/transform/internal/distance_functor.hh
+test.o: /work/carlinet/trunk/milena/mln/canvas/distance_geodesic.hh
+# /work/carlinet/trunk/milena/mln/canvas/distance_geodesic.hh includes:
+# mln/core/concept/image.hh
+# mln/core/concept/neighborhood.hh
+# mln/core/routine/duplicate.hh
+# mln/core/site_set/p_queue_fast.hh
+# mln/data/fill.hh
+# mln/extension/adjust_fill.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/p_queue_fast.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/p_queue_fast.hh includes:
+# mln/core/site_set/p_array.hh
+test.o: /work/carlinet/trunk/milena/mln/extension/adjust_fill.hh
+# /work/carlinet/trunk/milena/mln/extension/adjust_fill.hh includes:
+# mln/extension/adjust.hh
+# mln/extension/fill.hh
+test.o: /work/carlinet/trunk/milena/mln/extension/adjust.hh
+# /work/carlinet/trunk/milena/mln/extension/adjust.hh includes:
+# mln/border/adjust.hh
+# mln/core/concept/window.hh
+# mln/core/concept/weighted_window.hh
+# mln/core/concept/neighborhood.hh
+# mln/geom/delta.hh
+test.o: /work/carlinet/trunk/milena/mln/border/adjust.hh
+# /work/carlinet/trunk/milena/mln/border/adjust.hh includes:
+# mln/border/resize.hh
+test.o: /work/carlinet/trunk/milena/mln/border/resize.hh
+# /work/carlinet/trunk/milena/mln/border/resize.hh includes:
+# mln/core/concept/image.hh
+# mln/core/routine/duplicate.hh
+# mln/core/routine/primary.hh
+# mln/border/get.hh
+# mln/data/fill.hh
+test.o: /work/carlinet/trunk/milena/mln/core/routine/primary.hh
+# /work/carlinet/trunk/milena/mln/core/routine/primary.hh includes:
+# mln/core/concept/image.hh
+test.o: /work/carlinet/trunk/milena/mln/geom/delta.hh
+# /work/carlinet/trunk/milena/mln/geom/delta.hh includes:
+# mln/core/concept/window.hh
+# mln/core/concept/weighted_window.hh
+# mln/core/concept/neighborhood.hh
+test.o: /work/carlinet/trunk/milena/mln/extension/fill.hh
+# /work/carlinet/trunk/milena/mln/extension/fill.hh includes:
+# mln/core/concept/image.hh
+# mln/trait/image/props.hh
+# mln/border/fill.hh
+# mln/data/fill_with_value.hh
+test.o: /work/carlinet/trunk/milena/mln/border/fill.hh
+# /work/carlinet/trunk/milena/mln/border/fill.hh includes:
+# mln/core/concept/image.hh
+# mln/core/box_runstart_piter.hh
+# mln/opt/element.hh
+test.o: /work/carlinet/trunk/milena/mln/transform/internal/distance_functor.hh
+# /work/carlinet/trunk/milena/mln/transform/internal/distance_functor.hh includes:
+# mln/core/macros.hh
+test.o: /work/carlinet/trunk/milena/mln/morpho/attribute/card.hh
+# /work/carlinet/trunk/milena/mln/morpho/attribute/card.hh includes:
+# mln/accu/internal/base.hh
+# mln/util/pix.hh
+test.o: ../attributes/bbox.hh
+# ../attributes/bbox.hh includes:
+# mln/core/concept/box.hh
+test.o: /work/carlinet/trunk/milena/mln/io/pbm/load.hh
+# /work/carlinet/trunk/milena/mln/io/pbm/load.hh includes:
+# mln/core/image/image2d.hh
+# mln/core/image/image3d.hh
+# mln/io/pnm/load_header.hh
+# mln/make/image3d.hh
+test.o: /work/carlinet/trunk/milena/mln/io/pnm/load_header.hh
+test.o: /work/carlinet/trunk/milena/mln/make/image3d.hh
+# /work/carlinet/trunk/milena/mln/make/image3d.hh includes:
+# mln/core/image/image3d.hh
+# mln/core/image/image2d.hh
+# mln/core/image/slice_image.hh
+# mln/data/paste.hh
+# mln/util/array.hh
+test.o: /work/carlinet/trunk/milena/mln/core/image/slice_image.hh
+# /work/carlinet/trunk/milena/mln/core/image/slice_image.hh includes:
+# mln/core/internal/image_domain_morpher.hh
+# mln/core/alias/box3d.hh
+# mln/core/alias/box2d.hh
+test.o: /work/carlinet/trunk/milena/mln/data/paste.hh
+# /work/carlinet/trunk/milena/mln/data/paste.hh includes:
+# mln/core/concept/image.hh
+# mln/data/paste.spe.hh
+test.o: /work/carlinet/trunk/milena/mln/data/paste.spe.hh
+# /work/carlinet/trunk/milena/mln/data/paste.spe.hh includes:
+# mln/core/pixel.hh
+# mln/data/fill_with_value.hh
+# mln/data/memcpy_.hh
+# mln/core/box_runstart_piter.hh
+# mln/border/get.hh
+# mln/opt/value.hh
+# mln/opt/element.hh
+test.o: /work/carlinet/trunk/milena/mln/io/pgm/save.hh
+# /work/carlinet/trunk/milena/mln/io/pgm/save.hh includes:
+# mln/io/pnm/save.hh
+# mln/geom/size2d.hh
+# mln/metal/bexpr.hh
+# mln/metal/is_not_a.hh
+# mln/value/concept/vectorial.hh
+test.o: /work/carlinet/trunk/milena/mln/io/pnm/save.hh
+# /work/carlinet/trunk/milena/mln/io/pnm/save.hh includes:
+# mln/core/concept/image.hh
+# mln/core/alias/point2d.hh
+# mln/value/concept/scalar.hh
+# mln/value/rgb.hh
+# mln/value/rgb8.hh
+# mln/value/int_u8.hh
+# mln/metal/templated_by.hh
+# mln/metal/not_equal.hh
+# mln/io/pnm/save_header.hh
+# mln/io/pnm/macros.hh
+# mln/geom/size2d.hh
+test.o: /work/carlinet/trunk/milena/mln/value/rgb.hh
+# /work/carlinet/trunk/milena/mln/value/rgb.hh includes:
+# mln/value/ops.hh
+# mln/value/concept/vectorial.hh
+# mln/value/int_u.hh
+# mln/algebra/vec.hh
+# mln/fun/v2v/rgb_to_hsl.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/v2v/rgb_to_hsl.hh
+# /work/carlinet/trunk/milena/mln/fun/v2v/rgb_to_hsl.hh includes:
+# mln/math/round.hh
+# mln/math/max.hh
+# mln/math/min.hh
+# mln/trait/value_.hh
+# mln/value/rgb.hh
+test.o: /work/carlinet/trunk/milena/mln/math/max.hh
+test.o: /work/carlinet/trunk/milena/mln/math/min.hh
+test.o: /work/carlinet/trunk/milena/mln/value/rgb8.hh
+# /work/carlinet/trunk/milena/mln/value/rgb8.hh includes:
+# mln/value/rgb.hh
+test.o: /work/carlinet/trunk/milena/mln/value/int_u8.hh
+# /work/carlinet/trunk/milena/mln/value/int_u8.hh includes:
+# mln/value/int_u.hh
+test.o: /work/carlinet/trunk/milena/mln/metal/templated_by.hh
+# /work/carlinet/trunk/milena/mln/metal/templated_by.hh includes:
+# mln/metal/bool.hh
+test.o: /work/carlinet/trunk/milena/mln/io/pnm/save_header.hh
+# /work/carlinet/trunk/milena/mln/io/pnm/save_header.hh includes:
+# mln/io/pnm/max_component.hh
+# mln/value/rgb.hh
+# mln/geom/nrows.hh
+# mln/geom/ncols.hh
+test.o: /work/carlinet/trunk/milena/mln/io/pnm/max_component.hh
+# /work/carlinet/trunk/milena/mln/io/pnm/max_component.hh includes:
+# mln/value/rgb.hh
+# mln/value/int_u.hh
+test.o: /work/carlinet/trunk/milena/mln/io/pnm/macros.hh
+test.o: /work/carlinet/trunk/milena/mln/io/ppm/save.hh
+# /work/carlinet/trunk/milena/mln/io/ppm/save.hh includes:
+# mln/core/concept/image.hh
+# mln/metal/templated_by.hh
+# mln/io/pnm/save.hh
+test.o: ./../../theo/color/change_attributes.hh
+test.o: /work/carlinet/trunk/milena/mln/fun/p2v/ternary.hh
+# /work/carlinet/trunk/milena/mln/fun/p2v/ternary.hh includes:
+# mln/fun/internal/selector.hh
+test.o: /work/carlinet/trunk/milena/mln/labeling/blobs.hh
+# /work/carlinet/trunk/milena/mln/labeling/blobs.hh includes:
+# mln/core/concept/image.hh
+# mln/core/concept/neighborhood.hh
+# mln/data/fill.hh
+# mln/core/site_set/p_queue_fast.hh
+test.o: /work/carlinet/trunk/milena/mln/debug/colorize.hh
+# /work/carlinet/trunk/milena/mln/debug/colorize.hh includes:
+# mln/core/concept/image.hh
+# mln/fun/i2v/array.hh
+# mln/value/rgb8.hh
+# mln/literal/black.hh
+# mln/level/transform.hh
+test.o: /work/carlinet/trunk/milena/mln/literal/black.hh
+# /work/carlinet/trunk/milena/mln/literal/black.hh includes:
+# mln/core/concept/literal.hh
+test.o: /work/carlinet/trunk/milena/mln/level/transform.hh
+# /work/carlinet/trunk/milena/mln/level/transform.hh includes:
+# mln/core/concept/image.hh
+# mln/core/concept/function.hh
+# mln/value/set.hh
+# mln/level/transform.spe.hh
+test.o: /work/carlinet/trunk/milena/mln/level/transform.spe.hh
+# /work/carlinet/trunk/milena/mln/level/transform.spe.hh includes:
+# mln/core/concept/image.hh
+# mln/core/concept/function.hh
+# mln/data/fill_with_value.hh
+# mln/value/set.hh
+# mln/value/lut_vec.hh
+# mln/opt/value.hh
+test.o: /work/carlinet/trunk/milena/mln/value/lut_vec.hh
+# /work/carlinet/trunk/milena/mln/value/lut_vec.hh includes:
+# mln/core/concept/value_set.hh
+# mln/core/concept/function.hh
+# mln/trait/value_.hh
+# mln/value/viter.hh
+test.o: /work/carlinet/trunk/milena/mln/draw/box.hh
+# /work/carlinet/trunk/milena/mln/draw/box.hh includes:
+# mln/core/concept/image.hh
+# mln/core/alias/box2d.hh
+# mln/data/paste.hh
+# mln/draw/line.hh
+# mln/pw/image.hh
+# mln/pw/cst.hh
+test.o: /work/carlinet/trunk/milena/mln/draw/line.hh
+# /work/carlinet/trunk/milena/mln/draw/line.hh includes:
+# mln/core/concept/image.hh
+# mln/core/site_set/p_line2d.hh
+# mln/core/image/safe.hh
+# mln/data/paste.hh
+# mln/pw/image.hh
+# mln/pw/cst.hh
+test.o: /work/carlinet/trunk/milena/mln/core/site_set/p_line2d.hh
+# /work/carlinet/trunk/milena/mln/core/site_set/p_line2d.hh includes:
+# mln/core/site_set/p_array.hh
+# mln/core/alias/box2d.hh
+# mln/math/sign.hh
+# mln/math/abs.hh
+# mln/math/min.hh
+# mln/math/max.hh
+test.o: /work/carlinet/trunk/milena/mln/math/sign.hh
+test.o: /work/carlinet/trunk/milena/mln/core/image/safe.hh
+# /work/carlinet/trunk/milena/mln/core/image/safe.hh includes:
+# mln/core/internal/image_identity.hh
+test.o: /work/carlinet/trunk/milena/mln/core/internal/image_identity.hh
+# /work/carlinet/trunk/milena/mln/core/internal/image_identity.hh includes:
+# mln/core/internal/image_morpher.hh
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Rename ICDAR-HSC 'input to lines' source.
* icdar/2009/hsc/main.cc: Rename as...
* icdar/2009/hsc/input_to_lines.cc: ...this.
(usage): Fix text.
input_to_lines.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: icdar/2009/hsc/input_to_lines.cc
--- icdar/2009/hsc/input_to_lines.cc (revision 3607)
+++ icdar/2009/hsc/input_to_lines.cc (working copy)
@@ -267,7 +267,7 @@
std::cerr << "usage: " << argv[0] << " input.pbm output.pgm" << std::endl
<< " HSC @ ICDAR'2009" << std::endl
<< " input.pbm: input 2D binary image (text is black; background is white)" << std::endl
- << " output.dump: output image where line components are labeled (int_u8)" << std::endl
+ << " output.pgm: output image where line components are labeled (int_u8)" << std::endl
<< " 0 is the background label." << std::endl;
std::abort();
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make a common room for ICDAR.
* icdar: New directory.
* icdar/2009: New directory.
* icdar/2009/hsc: New directory.
* theo/icdar/hsc/main.cc (tmp_clo): New debug image.
Copy to...
* icdar/2009/hsc/main.cc: ...this new file.
(output): Update.
* theo/exec/diff_abs.cc: New.
Propagate Edwin's modifications.
* theo/esiee/laurent/presentation/wst_edge.cc: Update.
* theo/color/change_attributes.hh: Update.
* theo/color/segment.hh: Update.
* theo/color/segment_rgb_pixels.cc: Update.
* theo/color/filter_rgb_pixels.cc: New.
* theo/color/filter_blen_rgb_edges.cc: New.
* lazzara/icdar/quasi.cc: New.
* lazzara/icdar/binarization.cc: Augment.
icdar/2009/hsc/main.cc | 25 -
lazzara/icdar/binarization.cc | 664 +++++++++++++++++++++++++---
lazzara/icdar/quasi.cc | 180 +++++++
theo/color/change_attributes.hh | 10
theo/color/filter_blen_rgb_edges.cc | 387 ++++++++++++++++
theo/color/filter_rgb_pixels.cc | 227 +++++++++
theo/color/segment.hh | 78 ++-
theo/color/segment_rgb_pixels.cc | 28 -
theo/esiee/laurent/presentation/wst_edge.cc | 4
theo/exec/diff_abs.cc | 38 +
theo/icdar/hsc/main.cc | 4
11 files changed, 1552 insertions(+), 93 deletions(-)
Index: icdar/2009/hsc/main.cc
--- icdar/2009/hsc/main.cc (revision 0)
+++ icdar/2009/hsc/main.cc (working copy)
@@ -264,8 +264,11 @@
void usage(char* argv[])
{
- std::cerr << "usage: " << argv[0] << " input.pbm output.pgm [output.ppm]" << std::endl
- << " ICDAR'2009: HSC." << std::endl;
+ std::cerr << "usage: " << argv[0] << " input.pbm output.pgm" << std::endl
+ << " HSC @ ICDAR'2009" << std::endl
+ << " input.pbm: input 2D binary image (text is black; background is white)" << std::endl
+ << " output.dump: output image where line components are labeled (int_u8)" << std::endl
+ << " 0 is the background label." << std::endl;
std::abort();
}
@@ -277,7 +280,7 @@
using value::int_u8;
using value::rgb8;
- if (argc != 3 && argc != 4)
+ if (argc != 3)
usage(argv);
@@ -331,6 +334,10 @@
clo = morpho::closing::structural(fuzzy, win::rectangle2d(height, width));
+# ifdef LOG
+ io::pgm::save(clo, "tmp_clo.pgm");
+# endif
+
int_u8 n_basins;
ws = morpho::watershed::flooding(clo, c4(), n_basins);
@@ -358,26 +365,14 @@
{
image2d<int_u8> output(input.domain());
- image2d<rgb8>
- cool = debug::colorize(rgb8(), spc, n_basins),
- lab(input.domain());
-
mln_piter_(box2d) p(input.domain());
for_all(p)
if (input(p))
- {
output(p) = 0;
- lab(p) = literal::black;
- }
else
- {
output(p) = spc.at_(p.row() / subsampling_factor, p.col() / subsampling_factor);
- lab(p) = cool.at_(p.row() / subsampling_factor, p.col() / subsampling_factor);
- }
io::pgm::save(output, argv[2]);
- if (argc == 4)
- io::ppm::save(lab, argv[3]);
}
Property changes on: icdar/2009/hsc/main.cc
___________________________________________________________________
Added: svn:mergeinfo
Index: theo/icdar/hsc/main.cc
--- theo/icdar/hsc/main.cc (revision 3606)
+++ theo/icdar/hsc/main.cc (working copy)
@@ -331,6 +331,10 @@
clo = morpho::closing::structural(fuzzy, win::rectangle2d(height, width));
+# ifdef LOG
+ io::pgm::save(clo, "tmp_clo.pgm");
+# endif
+
int_u8 n_basins;
ws = morpho::watershed::flooding(clo, c4(), n_basins);
Index: theo/exec/diff_abs.cc
--- theo/exec/diff_abs.cc (revision 0)
+++ theo/exec/diff_abs.cc (revision 0)
@@ -0,0 +1,38 @@
+#include "filetype.hh"
+
+#include <mln/fun/vv2v/diff_abs.hh>
+#include <mln/level/transform.hh>
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input1.pgm input2.pgm output.pgm" << std::endl
+ << " Point-wise diff abs." << std::endl;
+ std::abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 4)
+ usage(argv);
+
+
+ trace::entering("main");
+
+ image2d<int_u8> input1, input2;
+ io::pgm::load(input1, argv[1]);
+ io::pgm::load(input2, argv[2]);
+
+ io::pgm::save(level::transform(input1,
+ input2,
+ fun::vv2v::diff_abs<int_u8>()),
+ argv[3]);
+
+ trace::exiting("main");
+}
Index: theo/esiee/laurent/presentation/wst_edge.cc
--- theo/esiee/laurent/presentation/wst_edge.cc (revision 3606)
+++ theo/esiee/laurent/presentation/wst_edge.cc (working copy)
@@ -33,7 +33,7 @@
# include <mln/extension/fill.hh>
# include <mln/morpho/meyer_wst.hh>
-# include <mln/morpho/closing_volume.hh>
+# include <mln/morpho/closing/volume.hh>
# include <mln/opt/at.hh>
@@ -318,7 +318,7 @@
}
- data::paste( morpho::closing_volume(edge, e2e, lambda), edge );
+ data::paste( morpho::closing::volume(edge, e2e, lambda), edge );
image2d<unsigned> label(ima.bbox(), 0);
Index: theo/color/segment.hh
--- theo/color/segment.hh (revision 3606)
+++ theo/color/segment.hh (working copy)
@@ -16,7 +16,7 @@
#include <mln/pw/all.hh>
#include <mln/morpho/tree/data.hh>
-#include <mln/morpho/closing_attribute.hh>
+#include <mln/morpho/closing/leveling.hh>
#include "change_attributes.hh"
@@ -120,7 +120,7 @@
// Propagate attribute from a site to its parent.
{
- mln_fwd_piter(T) p(t.domain());
+ mln_up_site_piter(T) p(t); // WAS: mln_fwd_piter(T) p(t.domain());
for_all(p)
if (! t.is_root(p))
acc(t.parent(p)).take(acc(p));
@@ -131,12 +131,11 @@
// Change accumulator into its result.
{
initialize(attr, acc);
- typedef typename T::nodes_t N;
- mln_piter(N) p(t.nodes());
- for_all(p)
+ mln_node_piter(T) n(t);
+ for_all(n)
{
- mln_invariant(t.is_a_node(p));
- attr(p) = acc(p).to_result();
+ mln_invariant(t.is_a_node(n));
+ attr(n) = acc(n).to_result();
}
}
@@ -213,14 +212,22 @@
data::fill(nchildren, 0);
{
- mln_fwd_piter(T) p(t.domain());
- // Propagate attribute from a site to its parent.
- for_all(p)
- if (t.is_a_non_root_node(p))
- {
- mln_invariant(t.is_a_node(t.parent(p)));
- ++nchildren(t.parent(p)); // so parent(p) is a node
- }
+ mln_up_node_piter(T) n(t);
+ for_all(n)
+ if (! t.is_root(n))
+ {
+ mln_invariant(t.is_a_node(t.parent(n)));
+ ++nchildren(t.parent(n)); // so parent(n) is a node
+ }
+
+ // WAS:
+// mln_fwd_piter(T) p(t.domain());
+// for_all(p)
+// if (t.is_a_non_root_node(p))
+// {
+// mln_invariant(t.is_a_node(t.parent(p)));
+// ++nchildren(t.parent(p)); // so parent(p) is a node
+// }
}
return nchildren;
@@ -325,7 +332,10 @@
mln_concrete(I) g;
{
initialize(g, t.f());
- mln_bkd_piter(T) p(t.domain());
+
+// mln_bkd_piter(T) p(t.domain());
+
+ mln_dn_site_piter(T) p(t);
for_all(p)
if (t.is_a_node(p) && a(p) >= lambda)
g(p) = t.f(p);
@@ -357,7 +367,7 @@
unsigned n_objects, unsigned less,
bool echo = false)
{
- mln_concrete(I) g_ref = morpho::closing_attribute<A>(f, nbh, lambda);
+ mln_concrete(I) g_ref = morpho::closing::leveling(f, nbh, A(), lambda);
unsigned n_regmins_g_ref;
mln_ch_value(I, unsigned) regmin_g_ref = labeling::regional_minima(g_ref, nbh, n_regmins_g_ref);
@@ -402,6 +412,40 @@
+
+
+
+ template <typename A, typename T, typename N>
+ inline
+ mln_concrete(typename T::function)
+ do_filter(A& a, const T& t, const N& nbh,
+ const mln_value(A)& lambda)
+ {
+ typedef typename T::function I;
+
+ const typename T::parent_t& par = t.parent_image();
+
+ // No need for attributes back propagation since we process the
+ // tree downwards: nodes are set *before* their children nodes and
+ // their related (non-nodes) sites.
+
+ mln_concrete(I) g;
+ initialize(g, t.f());
+
+ mln_dn_site_piter(T) p(t);
+ for_all(p)
+ if (t.is_a_node(p) && a(p) >= lambda)
+ g(p) = t.f(p);
+ else
+ g(p) = g(par(p));
+
+ return g;
+ }
+
+
+
+
+
// Filter facade.
template <typename F, typename N, typename A>
Index: theo/color/segment_rgb_pixels.cc
--- theo/color/segment_rgb_pixels.cc (revision 3606)
+++ theo/color/segment_rgb_pixels.cc (working copy)
@@ -14,7 +14,8 @@
#include <mln/io/pbm/save.hh>
#include <mln/level/convert.hh>
-#include <mln/morpho/meyer_wst.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/morpho/attribute/card.hh>
#include "mean_rgb_pix.hh"
#include "segment.hh"
@@ -75,8 +76,7 @@
mln_ch_value(A, value::int_u8) d;
initialize(d, a);
- typedef typename T::nodes_t N;
- mln_fwd_piter(N) n(t.nodes());
+ mln_up_node_piter(T) n(t);
for_all(n)
d(n) = dist(a(n), a(t.parent(n)));
@@ -98,6 +98,7 @@
{
std::cerr << "usage: " << argv[0] << " input.ppm n echo output.ppm" << std::endl;
std::cerr << "color version on pixels (without edges)" << std::endl;
+ std::cerr << "attribute is 'card'" << std::endl;
std::cerr << " n >= 2" << std::endl;
std::cerr << " echo = 0 (mute) or 1 (verbose)" << std::endl;
abort();
@@ -147,11 +148,22 @@
typedef morpho::tree::data<F,S> tree_t;
tree_t t(f, s, c4());
+
+ morpho::attribute::card<F> a_;
+ mln_VAR(a, compute_attribute_on_nodes(a_, t));
+
+ unsigned lambda;
+ unsigned less;
+ image2d<int_u8> g = run_filter(a, t, c4(), n_objects, // input
+ less, lambda, // output
+ echo);
+
+ /*
+
accu::rgb_image_ = input;
accu::mean_rgb_pix< util::pix<F> > a_;
mln_VAR(a, compute_attribute_on_nodes(a_, t));
-
mln_VAR(d, dists_from_means(t, a, echo));
make_attribute_grow(t, d);
if (echo)
@@ -160,19 +172,21 @@
display_tree_attributes(t, d);
}
-
// BAD: extinct_attributes(t, d, echo);
-
int_u8 lambda;
unsigned less;
image2d<int_u8> g = run_filter(d, t, c4(), n_objects, // input
less, lambda, // output
echo);
+ */
+
+
io::pbm::save( (pw::value(g) != pw::value(f)) | f.domain(),
"temp_activity.pbm" );
+
// if (echo)
// debug::println("activity (g != f) = ", (pw::value(g) != pw::value(f)) | f.domain());
@@ -181,7 +195,7 @@
typedef value::label_16 L;
L nbasins;
- mln_ch_value_(I, L) w = morpho::meyer_wst(g, c4(), nbasins);
+ mln_ch_value_(I, L) w = morpho::watershed::flooding(g, c4(), nbasins);
std::cout << "n basins = " << nbasins << std::endl;
image2d<rgb8> output = duplicate(input);
Index: theo/color/filter_rgb_pixels.cc
--- theo/color/filter_rgb_pixels.cc (revision 0)
+++ theo/color/filter_rgb_pixels.cc (revision 0)
@@ -0,0 +1,227 @@
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/literal/colors.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/level/convert.hh>
+
+#include <mln/morpho/watershed/flooding.hh>
+
+#include "mean_rgb_pix.hh"
+#include "segment.hh"
+
+
+
+namespace mln
+{
+
+
+ // Distance, stored on pixels, of neighboring colors.
+
+ template <typename N>
+ image2d<value::int_u8>
+ dist_on_pixels(const image2d<value::rgb8>& input, const N& nbh)
+ {
+ using value::int_u8;
+ image2d<int_u8> output(input.domain());
+
+ mln_piter(box2d) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ int_u8 d = 0u;
+ for_all(n) if (input.domain().has(n))
+ {
+ int_u8 d_ = dist(input(p), input(n));
+ if (d_ > d)
+ d = d_;
+ }
+ output(p) = d;
+ }
+
+ io::pgm::save(output, "temp_dist.pgm");
+
+ return output;
+ }
+
+
+
+ // Distance between 2 rgb8 colors.
+ // -----------------------------------------------------------
+
+
+ value::int_u8 dist_mean(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = 0;
+ d += (math::diff_abs(c1.red(), c2.red()) + 2) / 3;
+ d += (math::diff_abs(c1.green(), c2.green()) + 2) / 3;
+ d += (math::diff_abs(c1.blue(), c2.blue()) + 2) / 3;
+ if (d > 255)
+ d = 255;
+ return d;
+ }
+
+ value::int_u8 dist_sat(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = 0;
+ d += math::diff_abs(c1.red(), c2.red());
+ d += math::diff_abs(c1.green(), c2.green());
+ d += math::diff_abs(c1.blue(), c2.blue());
+ if (d > 255)
+ d = 255;
+ return d;
+ }
+
+ value::int_u8 dist_max(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = 0, d_;
+ d_ = math::diff_abs(c1.red(), c2.red());
+ if (d_ > d) d = d_;
+ d_ = math::diff_abs(c1.green(), c2.green());
+ if (d_ > d) d = d_;
+ d_ = math::diff_abs(c1.blue(), c2.blue());
+ if (d_ > d) d = d_;
+ return d;
+ }
+
+
+
+ // From 'mean color' attributes to 'mean difference p/par(p)'.
+ // -----------------------------------------------------------
+
+
+ template <typename T, typename A>
+ inline
+ mln_ch_value(A, value::int_u8)
+ dists_from_means(const T& t, const A& a, bool echo = false)
+ {
+ if (echo)
+ {
+ std::cout << "means:" << std::endl;
+ display_tree_attributes(t, a);
+ }
+
+ mln_ch_value(A, value::int_u8) d;
+ initialize(d, a);
+
+ mln_up_node_piter(T) n(t);
+ for_all(n)
+ d(n) = dist_max(a(n), a(t.parent(n)));
+
+ if (echo)
+ {
+ std::cout << "dists:" << std::endl;
+ display_tree_attributes(t, d);
+ }
+
+ return d;
+ }
+
+
+
+
+
+} // mln
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.ppm lambda echo output.ppm" << std::endl;
+ std::cerr << "color version on pixels (without edges)" << std::endl;
+ std::cerr << "attribute is 'distance of color means'" << std::endl;
+ std::cerr << " lambda >= 0 and <= 255" << std::endl;
+ std::cerr << " echo = 0 (mute) or 1 (verbose)" << std::endl;
+ abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+
+ using value::int_u8;
+ using value::rgb8;
+
+
+ if (argc != 5)
+ usage(argv);
+
+
+ // Color debase (on pixels, not edges) version.
+ // --------------------------------------------
+
+
+ typedef image2d<rgb8> I;
+
+ I input;
+ io::ppm::load(input, argv[1]);
+
+ int lambda = atoi(argv[2]);
+ if (lambda < 0 || lambda > 255)
+ usage(argv);
+
+ bool echo = atoi(argv[3]);
+
+
+ // Neighborhood.
+ mln_VAR(nbh, c4());
+
+
+ // Changing input into 'f'.
+
+ typedef image2d<int_u8> F;
+ F f = dist_on_pixels(input, c4());
+
+
+ typedef p_array<mln_psite_(F)> S;
+ S s = level::sort_psites_decreasing(f);
+
+ typedef morpho::tree::data<F,S> tree_t;
+ tree_t t(f, s, c4());
+
+
+ accu::rgb_image_ = input;
+ accu::mean_rgb_pix< util::pix<F> > a_;
+ mln_VAR(a, compute_attribute_on_nodes(a_, t));
+
+ mln_VAR(d, dists_from_means(t, a, echo));
+ make_attribute_grow(t, d);
+ if (echo)
+ {
+ std::cout << "dists growing:" << std::endl;
+ display_tree_attributes(t, d);
+ }
+
+ image2d<int_u8> g = do_filter(d, t, c4(), lambda);
+
+
+ io::pbm::save( (pw::value(g) != pw::value(f)) | f.domain(),
+ "temp_activity.pbm" );
+
+
+// debug::println("activity (g != f) = ", (pw::value(g) != pw::value(f)) | f.domain());
+
+
+ // Watershed transform.
+
+ typedef value::label_16 L;
+ L nbasins;
+ mln_ch_value_(I, L) w = morpho::watershed::flooding(g, c4(), nbasins);
+ std::cout << "n basins = " << nbasins << std::endl;
+
+ image2d<rgb8> output = duplicate(input);
+ data::fill((output | (pw::value(w) == 0)).rw(), literal::black);
+
+ io::ppm::save(output, argv[4]);
+}
Index: theo/color/change_attributes.hh
--- theo/color/change_attributes.hh (revision 3606)
+++ theo/color/change_attributes.hh (working copy)
@@ -16,8 +16,11 @@
initialize(deja_vu, a);
data::fill(deja_vu, false);
- typedef typename T::nodes_t nodes_t;
- mln_fwd_piter(nodes_t) p(t.nodes());
+ // WAS:
+ // typedef typename T::nodes_t nodes_t;
+ // mln_fwd_piter(nodes_t) p(t.nodes());
+
+ mln_up_node_piter(T) p(t);
for_all(p)
{
if (deja_vu(p))
@@ -91,7 +94,8 @@
void
back_propagate(const T& t, A& a)
{
- mln_fwd_piter(T) p(t.domain());
+ // WAS: mln_fwd_piter(T) p(t.domain());
+ mln_site_piter(T) p(t);
for_all(p)
if (! t.is_a_node(p))
{
Index: theo/color/filter_blen_rgb_edges.cc
--- theo/color/filter_blen_rgb_edges.cc (revision 0)
+++ theo/color/filter_blen_rgb_edges.cc (revision 0)
@@ -0,0 +1,387 @@
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/box3d.hh>
+
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/make/double_neighb2d.hh>
+
+#include <mln/value/label_8.hh>
+#include <mln/value/label_16.hh>
+
+#include <mln/core/image/image_if.hh>
+#include <mln/core/routine/extend.hh>
+#include <mln/core/routine/duplicate.hh>
+#include <mln/data/paste.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/debug/colorize.hh>
+
+#include <mln/morpho/dilation.hh>
+#include <mln/morpho/erosion.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/labeling/compute.hh>
+
+#include <mln/accu/count.hh>
+#include <mln/accu/volume.hh>
+#include <mln/accu/mean.hh>
+
+#include "sum_pix.hh"
+#include "segment.hh"
+
+
+
+namespace mln
+{
+
+ point3d color2point(const value::rgb8& c)
+ {
+ point3d p(c.red(), c.green(), c.blue());
+ return p;
+ }
+
+
+ image2d<value::rgb8> blen_image;
+
+
+ template <typename B>
+ void accu_blen_take(B& b, const point2d& e)
+ {
+ if (e.row() % 2)
+ {
+ b.take(color2point(blen_image(e + up)));
+ b.take(color2point(blen_image(e + down)));
+ }
+ else
+ {
+ b.take(color2point(blen_image(e + left)));
+ b.take(color2point(blen_image(e + right)));
+ }
+ }
+
+}
+
+#include "blen_pix.hh"
+
+
+
+
+namespace mln
+{
+
+ // Functions.
+
+ inline
+ bool is_row_odd(const point2d& p)
+ {
+ return p.row() % 2;
+ }
+
+ inline
+ bool is_square(const point2d& p)
+ {
+ return p.row() % 2 == 0 && p.col() % 2 == 0;
+ }
+
+ inline
+ bool is_edge(const point2d& p)
+ {
+ return p.row() % 2 + p.col() % 2 == 1;
+ }
+
+ inline
+ bool is_point(const point2d& p)
+ {
+ return p.row() % 2 && p.col() % 2;
+ }
+
+
+ // Neighborhoods.
+
+ typedef neighb< win::multiple<window2d, bool(*)(const point2d&)> > dbl_neighb2d;
+
+ const dbl_neighb2d& e2c()
+ {
+ static bool e2c_h[] = { 0, 1, 0,
+ 0, 0, 0,
+ 0, 1, 0 };
+ static bool e2c_v[] = { 0, 0, 0,
+ 1, 0, 1,
+ 0, 0, 0 };
+ static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2c_h, e2c_v);
+ return nbh;
+ }
+
+ const dbl_neighb2d& e2e()
+ {
+ static bool e2e_h[] = { 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0 };
+ static bool e2e_v[] = { 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 1, 0, 0, 0, 1,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0 };
+ static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2e_h, e2e_v);
+ return nbh;
+ }
+
+
+ // Transforms.
+
+ template <typename T>
+ image2d<T>
+ image2full(const image2d<T>& input)
+ {
+ image2d<T> output(2 * input.nrows() - 1,
+ 2 * input.ncols() - 1);
+ for (int row = 0; row < input.nrows(); ++row)
+ for (int col = 0; col < input.ncols(); ++col)
+ opt::at(output, 2 * row, 2 * col) = opt::at(input, row, col);
+ return output;
+ }
+
+ template <typename T>
+ image2d<T>
+ full2image(const image2d<T>& input)
+ {
+ image2d<T> output((input.nrows() + 1) / 2,
+ (input.ncols() + 1) / 2);
+ for (int row = 0; row < input.nrows(); row += 2)
+ for (int col = 0; col < input.ncols(); col += 2)
+ opt::at(output, row / 2, col / 2) =
+ opt::at(input, row, col);
+ return output;
+ }
+
+
+ // Display.
+
+ template <typename I>
+ I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
+ {
+ unsigned nrows = ima.nrows() / 2 + 1;
+ unsigned ncols = ima.ncols() / 2 + 1;
+ I output(nrows * (zoom + 1) - 1,
+ ncols * (zoom + 1) - 1);
+ data::fill(output, bg);
+ mln_VAR( edge, ima | is_edge );
+ mln_piter(edge_t) p(edge.domain());
+ for_all(p)
+ if (p.row() % 2) // horizontal edge
+ {
+ unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
+ unsigned col = (p.col() / 2) * (zoom + 1);
+ for (unsigned i = 0; i < zoom; ++i)
+ opt::at(output, row, col + i) = ima(p);
+ }
+ else // vertical edge
+ {
+ unsigned row = (p.row() / 2) * (zoom + 1);
+ unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
+ for (unsigned i = 0; i < zoom; ++i)
+ opt::at(output, row + i, col) = ima(p);
+ }
+ return output;
+ }
+
+
+
+ // Distance, stored on edges, of a couple of colors.
+
+ template <typename I, typename N>
+ image2d<value::int_u8>
+ dist_on_edges(const I& input, const N& nbh)
+ {
+ image2d<value::int_u8> output;
+ initialize(output, input);
+ data::fill(output, 0);
+
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ n.start();
+ value::rgb8 c1 = input(n);
+ n.next();
+ value::rgb8 c2 = input(n);
+ output(p) = dist(c1, c2);
+ }
+
+ io::pgm::save(output, "temp_dist.pgm");
+
+ return output;
+ }
+
+
+ value::int_u8 L_to_int_u8(unsigned l)
+ {
+ return l == 0 ?
+ 0 : // wshed line
+ 1 + (l - 1) % 255; // basin
+ }
+
+
+} // mln
+
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.ppm lambda echo output.ppm" << std::endl;
+ std::cerr << " lambda >= 0" << std::endl;
+ std::cerr << " echo = 0 (mute) or 1 (verbose)" << std::endl;
+ abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::rgb8;
+
+ if (argc != 5)
+ usage(argv);
+
+
+ // Color version.
+ // --------------
+
+
+ image2d<rgb8> input;
+ io::ppm::load(input, argv[1]);
+
+
+ int lambda = atoi(argv[2]);
+ if (lambda < 0)
+ usage(argv);
+
+ bool echo = atoi(argv[3]);
+
+
+ // Changing input into 'f on edges'.
+
+ image2d<int_u8> f_;
+ image2d<rgb8> input_ = image2full(input);
+ {
+ f_ = dist_on_edges(extend(input_ | is_edge, pw::value(input_)),
+ e2c());
+ }
+ mln_VAR(f, f_ | is_edge);
+ typedef f_t I;
+
+
+ typedef p_array<mln_psite_(I)> S;
+ S s = level::sort_psites_decreasing(f);
+
+ typedef morpho::tree::data<I,S> tree_t;
+ tree_t t(f, s, e2e());
+
+
+ blen_image = input_;
+ accu::blen_pix<I> a_;
+ mln_VAR(a, compute_attribute_on_nodes(a_, t));
+
+
+ f_t g = do_filter(a, t, e2e(), lambda);
+
+
+ if (echo)
+ debug::println("activity (g != f) = ", (pw::value(g) != pw::value(f)) | f.domain());
+
+ // Watershed transform.
+
+ typedef value::label_16 L;
+ L nbasins;
+ mln_ch_value_(f_t, L) w = morpho::watershed::flooding(g, e2e(), nbasins);
+
+ std::cout << "n basins = " << nbasins << std::endl;
+
+ io::pgm::save(display_edge(w.unmorph_(), 0, 3), "temp_w.pgm");
+
+ if (echo)
+ {
+ image2d<int_u8> g_(f_.domain());
+
+ data::fill(g_, 0);
+ data::paste(g | (pw::value(w) != 0), g_);
+ debug::println("g | basins = ", g_ | is_edge);
+
+ data::fill(g_, 0);
+ data::paste(g | (pw::value(w) == 0), g_);
+ debug::println("g | w line = ", g_ | is_edge);
+ }
+
+ image2d<L> w_all = w.unmorph_();
+
+ // edges -> squares
+ mln_VAR(w_squares, w_all | is_square);
+ data::paste(morpho::dilation(extend(w_squares, pw::value(w_all)),
+ c4().win()),
+ w_all);
+ // edges -> points
+ mln_VAR(w_points, w_all | is_point);
+ data::paste(morpho::erosion(extend(w_points, pw::value(w_all)),
+ c4().win()),
+ w_all);
+
+
+ io::ppm::save(debug::colorize(rgb8(),
+ w_all,
+ nbasins),
+ "temp_w_all.ppm");
+
+
+ // Outputing.
+ // ----------
+
+ image2d<L> out_w = full2image(w_all);
+
+// io::ppm::save(debug::colorize(rgb8(),
+// out_w,
+// nbasins),
+// argv[4]);
+
+
+ typedef algebra::vec<3,float> vec3f;
+
+ util::array<vec3f> m_3f = labeling::compute(accu::mean<rgb8>(),
+ input,
+ full2image(w_all),
+ nbasins);
+ m_3f[0] = vec3f::zero;
+
+ util::array<rgb8> m(m_3f.nelements());
+ // convert::from_to(m_3f, m); // FIXME: Do not work!
+ for (unsigned i = 0; i < m_3f.nelements(); ++i)
+ m[i] = rgb8(m_3f[i][0], m_3f[i][1], m_3f[i][2]);
+
+
+ io::ppm::save( level::transform(out_w,
+ convert::to< fun::i2v::array<rgb8> >(m) ),
+ argv[4] );
+
+
+// io::ppm::save( level::transform(w_all,
+// convert::to< fun::i2v::array<rgb8> >(m) ),
+// argv[4] );
+
+
+// debug::println("input_", input_);
+// debug::println("w_squares", w_squares);
+
+// FIXME: The code below does not work!
+
+// util::array<vec3f> m_3f = labeling::compute(accu::mean<rgb8>(),
+// input_,
+// w_squares,
+// nbasins);
+
+}
Index: lazzara/icdar/quasi.cc
--- lazzara/icdar/quasi.cc (revision 0)
+++ lazzara/icdar/quasi.cc (revision 0)
@@ -0,0 +1,180 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/pw/all.hh>
+#include <mln/core/image/image_if.hh>
+
+#include <mln/core/site_set/p_queue.hh>
+#include <mln/core/site_set/p_array.hh>
+
+#include <mln/data/fill.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pbm/save.hh>
+
+#include <mln/debug/colorize.hh>
+#include <mln/fun/i2v/array.hh>
+
+#include <mln/labeling/regional_minima.hh>
+#include <mln/labeling/wrap.hh>
+
+#include <mln/level/transform.hh>
+#include <mln/level/convert.hh>
+
+#include <mln/math/diff_abs.hh>
+
+
+
+
+
+namespace mln
+{
+
+ float
+ sim(unsigned v1, unsigned v2)
+ {
+ if (v1 == 0 && v2 == 0)
+ return 1.f;
+ return v1 < v2 ? float(v1) / float(v2) : float(v2) / float(v1); // min / max
+ }
+
+
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, bool)
+ labeling__quasi_regional_minima(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ unsigned threshold,
+ L& cur_lab)
+ {
+ trace::entering("labeling__quasi_regional_minima");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ mln_precondition(input.is_valid());
+
+ typedef mln_psite(I) P;
+ p_array<P> s = level::sort_psites_increasing(input);
+
+ std::vector<bool> valid;
+ valid.push_back(false); // For valid[0] where 0 is the non-label value.
+
+ mln_ch_value(I, L) lab;
+ initialize(lab, input);
+ data::fill(lab, 0);
+
+ cur_lab = 0;
+ unsigned
+ n_stop_unknown,
+ n_stop_object,
+ n_stop_background;
+
+ p_queue<P> q;
+ P p_;
+ mln_niter(N) n(nbh, p_);
+
+ mln_piter(p_array<P>) p(s);
+ for_all(p)
+ {
+ if (lab(p) != 0)
+ continue;
+
+ mln_invariant(q.is_empty());
+
+ // Initialization.
+ ++cur_lab;
+ n_stop_unknown = 0;
+ n_stop_object = 0;
+ n_stop_background = 0;
+
+ mln_value(I) input_p = input(p);
+ lab(p) = cur_lab;
+ q.push(p);
+
+ while (! q.is_empty())
+ {
+ p_ = q.pop_front();
+ mln_invariant(lab(p_) != 0); // Already seen.
+ for_all(n) if (input.domain().has(n))
+ {
+ if (lab(n) == cur_lab)
+ continue;
+ if (lab(n) == 0)
+ {
+// if (sim(input(n), input(p_)) > 0.7
+// &&
+// sim(input(n), input_p) > 0.8)
+ if (math::diff_abs(input(n), input(p_)) < threshold
+ &&
+ math::diff_abs(input(n), input_p) < 2 * threshold)
+ {
+ lab(n) = cur_lab;
+ q.push(n);
+ }
+ else
+ ++n_stop_unknown; // Stop because of threshold.
+ continue;
+ }
+ mln_invariant(lab(n) != 0 && lab(n) != cur_lab); // Another component.
+
+ if (valid[lab(n)])
+ ++n_stop_object;
+ else
+ ++n_stop_background;
+ }
+ }
+
+ if (n_stop_object + n_stop_background <= n_stop_unknown / 4)
+ {
+ valid.push_back(true);
+ continue;
+ }
+ valid.push_back(false);
+ }
+
+ fun::i2v::array<bool> f_valid;
+ convert::from_to(valid, f_valid);
+
+ mln_ch_value(I, bool) out = level::transform(lab, f_valid);
+
+ io::pgm::save(labeling::wrap(value::int_u8(), lab),
+ "tmp_lab.pgm");
+
+ trace::exiting("labeling__quasi_regional_minima");
+ return out;
+ }
+
+
+} // end of namespace mln
+
+
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+ using namespace value;
+
+ // trace::quiet = false;
+
+ if (argc != 4)
+ {
+ std::cout << argv[0] << " input.pgm threshold output.pbm" << std::endl;
+ return 1;
+ }
+
+ int threshold = std::atoi(argv[2]);
+
+
+ image2d<int_u8> input;
+ io::pgm::load(input, argv[1]);
+
+ unsigned n_regions;
+ image2d<bool> output = labeling__quasi_regional_minima(input,
+ c4(),
+ threshold,
+ n_regions);
+
+ std::cout << n_regions << std::endl;
+
+ io::pbm::save(output, argv[3]);
+}
Index: lazzara/icdar/binarization.cc
--- lazzara/icdar/binarization.cc (revision 3606)
+++ lazzara/icdar/binarization.cc (working copy)
@@ -1,34 +1,67 @@
+#include <mln/core/var.hh>
+
+#include <mln/core/image/image1d.hh>
+#include <mln/core/alias/neighb1d.hh>
+
#include <mln/core/image/image2d.hh>
-#include <mln/core/site_set/box.hh>
-#include <mln/data/fill.hh>
-#include <mln/core/alias/dpoint2d.hh>
-#include <mln/core/macros.hh>
-#include <mln/core/concept/function.hh>
#include <mln/core/alias/neighb2d.hh>
+#include <mln/make/double_neighb2d.hh>
+
+#include <mln/pw/all.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/site_set/p_queue.hh>
+
+#include <mln/core/routine/extend.hh>
+#include <mln/core/routine/duplicate.hh>
+#include <mln/data/fill.hh>
+
#include <mln/core/site_set/p_edges.hh>
#include <mln/core/site_set/p_vertices.hh>
+#include <mln/core/image/graph_elt_neighborhood.hh>
+
#include <mln/io/essential.hh>
#include <mln/value/int_u8.hh>
#include <mln/value/int_u16.hh>
+#include <mln/value/label_8.hh>
#include <mln/value/label_16.hh>
#include <mln/value/rgb8.hh>
+#include <mln/literal/colors.hh>
+
+#include <mln/histo/compute.hh>
+
+#include <mln/morpho/erosion.hh>
+#include <mln/morpho/dilation.hh>
#include <mln/morpho/elementary/gradient_internal.hh>
#include <mln/morpho/closing/volume.hh>
+#include <mln/morpho/closing/height.hh>
#include <mln/morpho/watershed/flooding.hh>
+
#include <mln/make/rag_and_labeled_wsl.hh>
#include <mln/util/graph.hh>
#include <mln/util/couple.hh>
#include <mln/debug/colorize.hh>
#include <mln/fun/i2v/array.hh>
+
#include <mln/labeling/compute.hh>
+#include <mln/labeling/regional_minima.hh>
+#include <mln/labeling/wrap.hh>
+
+#include <mln/level/transform.hh>
+#include <mln/level/convert.hh>
+
+#include <mln/linear/gaussian_1d.hh>
+
#include <mln/accu/center.hh>
#include <mln/accu/median_h.hh>
#include <mln/accu/mean.hh>
-#include <mln/pw/cst.hh>
+
#include <mln/math/abs.hh>
-#include <mln/literal/colors.hh>
#include <mln/debug/draw_graph.hh>
+
+
+
+
namespace mln
{
@@ -202,6 +235,339 @@
} // end of namespace mln::make
+ int
+ find_threshold(const histo::array<value::int_u8>& h)
+ {
+
+ const float sigma = 5; // FIXME: hard-coded!
+
+ util::array<point1d> c;
+ value::label_8 n;
+
+ {
+ image1d<unsigned> h_, hs_;
+ image1d<value::label_8> l;
+
+ convert::from_to(h, h_);
+ hs_ = linear::gaussian_1d(h_, sigma, 0);
+ l = labeling::regional_minima(hs_, c2(), n);
+
+ {
+// debug::println("l", l);
+// debug::histo(h, "tmp_h.txt");
+
+// std::ofstream file("tmp_hs.txt");
+// mln_piter_(box1d) p(h_.domain());
+// for_all(p)
+// file << p.ind() << ' ' << hs_(p) << std::endl;
+// file.close();
+ }
+
+ accu::center<point1d, point1d> a;
+ c = labeling::compute(a, l, n);
+
+ c[0] = point1d(0); // Force a neutral value for the non-label value (0).
+
+ // std::cout << "c = " << c << std::endl;
+ }
+
+
+ int threshold;
+
+ {
+ std::vector<int> v;
+ for (unsigned i = 0; i <= n; ++i)
+ v.push_back(c[i].ind());
+ std::sort(v.begin(), v.end());
+
+ for (unsigned i = 0; i <= n; ++i)
+ if (v[i] != 0)
+ {
+ threshold = v[i];
+ break;
+ }
+
+ std::cout << "threshold = " << threshold << std::endl;
+ }
+
+ return threshold;
+ }
+
+
+ image2d<bool> contours(const image2d<value::int_u8>& f, unsigned& threshold)
+ {
+ using value::int_u8;
+ typedef int_u8 V;
+ histo::array<V> h;
+
+ image2d<int_u8> g;
+ g = morpho::elementary::gradient_internal(f, c4());
+ g = morpho::closing::height(g, c4(), 3); // FIXME: hard-coded!
+
+ unsigned nbasins;
+ image2d<unsigned> w = morpho::watershed::flooding(g, c4(), nbasins);
+
+ h = histo::compute(g | (pw::value(w) == pw::cst(0)));
+
+ threshold = find_threshold(h);
+
+ return duplicate((pw::value(g) > pw::cst(threshold)) | f.domain());
+ }
+
+
+ // Distances.
+
+ value::int_u8 dist(const value::int_u8& g1, const value::int_u8& g2)
+ {
+ return math::diff_abs(g1, g2);
+ }
+
+ value::int_u8 dist(const value::rgb8& c1, const value::rgb8& c2)
+ {
+ unsigned d = math::diff_abs(c1.red(), c2.red());
+ unsigned d_;
+ d_ = math::diff_abs(c1.green(), c2.green());
+ if (d_ > d)
+ d = d_;
+ d_ = math::diff_abs(c1.blue(), c2.blue());
+ if (d_ > d)
+ d = d_;
+ return d;
+ }
+
+
+ // Functions.
+
+ inline
+ bool is_row_odd(const point2d& p)
+ {
+ return p.row() % 2;
+ }
+
+ inline
+ bool is_square(const point2d& p)
+ {
+ return p.row() % 2 == 0 && p.col() % 2 == 0;
+ }
+
+ inline
+ bool is_edge(const point2d& p)
+ {
+ return p.row() % 2 + p.col() % 2 == 1;
+ }
+
+ inline
+ bool is_point(const point2d& p)
+ {
+ return p.row() % 2 && p.col() % 2;
+ }
+
+
+ // Neighborhoods.
+
+ typedef neighb< win::multiple<window2d, bool(*)(const point2d&)> > dbl_neighb2d;
+
+ const dbl_neighb2d& e2c()
+ {
+ static bool e2c_h[] = { 0, 1, 0,
+ 0, 0, 0,
+ 0, 1, 0 };
+ static bool e2c_v[] = { 0, 0, 0,
+ 1, 0, 1,
+ 0, 0, 0 };
+ static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2c_h, e2c_v);
+ return nbh;
+ }
+
+ const dbl_neighb2d& e2e()
+ {
+ static bool e2e_h[] = { 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0 };
+ static bool e2e_v[] = { 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 1, 0, 0, 0, 1,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0 };
+ static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2e_h, e2e_v);
+ return nbh;
+ }
+
+
+ // Transforms.
+
+ template <typename T>
+ image2d<T>
+ image2full(const image2d<T>& input)
+ {
+ image2d<T> output(2 * input.nrows() - 1,
+ 2 * input.ncols() - 1);
+ for (int row = 0; row < input.nrows(); ++row)
+ for (int col = 0; col < input.ncols(); ++col)
+ opt::at(output, 2 * row, 2 * col) = opt::at(input, row, col);
+ return output;
+ }
+
+ template <typename T>
+ image2d<T>
+ full2image(const image2d<T>& input)
+ {
+ image2d<T> output((input.nrows() + 1) / 2,
+ (input.ncols() + 1) / 2);
+ for (int row = 0; row < input.nrows(); row += 2)
+ for (int col = 0; col < input.ncols(); col += 2)
+ opt::at(output, row / 2, col / 2) =
+ opt::at(input, row, col);
+ return output;
+ }
+
+
+ // Display.
+
+ template <typename I>
+ I display_edge(const I& ima, mln_value(I) bg, unsigned zoom)
+ {
+ unsigned nrows = ima.nrows() / 2 + 1;
+ unsigned ncols = ima.ncols() / 2 + 1;
+ I output(nrows * (zoom + 1) - 1,
+ ncols * (zoom + 1) - 1);
+ data::fill(output, bg);
+ mln_VAR( edge, ima | is_edge );
+ mln_piter(edge_t) p(edge.domain());
+ for_all(p)
+ if (p.row() % 2) // horizontal edge
+ {
+ unsigned row = (p.row() / 2 + 1) * (zoom + 1) - 1;
+ unsigned col = (p.col() / 2) * (zoom + 1);
+ for (unsigned i = 0; i < zoom; ++i)
+ opt::at(output, row, col + i) = ima(p);
+ }
+ else // vertical edge
+ {
+ unsigned row = (p.row() / 2) * (zoom + 1);
+ unsigned col = (p.col() / 2 + 1) * (zoom + 1) - 1;
+ for (unsigned i = 0; i < zoom; ++i)
+ opt::at(output, row + i, col) = ima(p);
+ }
+ return output;
+ }
+
+
+
+ // Distance, stored on edges, of a couple of colors.
+
+ template <typename I, typename N>
+ image2d<value::int_u8>
+ dist_on_edges(const I& input, const N& nbh)
+ {
+ image2d<value::int_u8> output;
+ initialize(output, input);
+ data::fill(output, 0);
+
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ n.start();
+ mln_value(I) c1 = input(n);
+ n.next();
+ mln_value(I) c2 = input(n);
+ output(p) = dist(c1, c2);
+ }
+
+ // io::pgm::save(output, "temp_dist.pgm");
+
+ return output;
+ }
+
+
+ value::int_u8 L_to_int_u8(unsigned l)
+ {
+ return l == 0 ?
+ 0 : // wshed line
+ 1 + (l - 1) % 255; // basin
+ }
+
+
+
+
+ template <typename I, typename N, typename L>
+ mln_ch_value(I, bool)
+ labeling__quasi_regional_minima(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ unsigned threshold,
+ L& nlabels)
+ {
+ trace::entering("labeling__quasi_regional_minima");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ mln_precondition(input.is_valid());
+
+ typedef mln_psite(I) P;
+ p_array<P> s = level::sort_psites_increasing(input);
+
+ std::vector<bool> valid;
+ valid.push_back(false); // For valid[0] where 0 is the non-label value.
+
+ mln_ch_value(I, L) lab;
+ initialize(lab, input);
+ data::fill(lab, 0);
+
+ L cur_lab = 0;
+
+ p_queue<P> q;
+ P p_;
+ mln_niter(N) n(nbh, p_);
+
+ mln_piter(p_array<P>) p(s);
+ for_all(p)
+ {
+ if (lab(p) != 0)
+ continue;
+
+ mln_invariant(q.is_empty());
+
+ // Initialization.
+ ++cur_lab;
+ valid.push_back(true);
+ mln_invariant(valid[cur_lab] == true);
+ lab(p) = cur_lab;
+ q.push(p);
+
+ while (! q.is_empty())
+ {
+ p_ = q.pop_front();
+ mln_invariant(lab(p_) != 0); // Already seen.
+ for_all(n)
+ {
+ if (lab(n) == cur_lab)
+ continue;
+ if (lab(n) == 0)
+ if (math::diff_abs(input(n), input(p_)) < threshold)
+ {
+ lab(n) = cur_lab;
+ q.push(n);
+ continue;
+ }
+ mln_invariant(lab(n) != 0 && lab(n) != cur_lab);
+ if (valid[cur_lab])
+ valid[cur_lab] = false; // Invalidation.
+ }
+ }
+ }
+
+ fun::i2v::array<bool> f_valid;
+ convert::from_to(valid, f_valid);
+
+ mln_ch_value(I, bool) out = level::transform(lab, f_valid);
+
+ trace::exiting("labeling__quasi_regional_minima");
+ return out;
+ }
+
+
} // end of namespace mln
@@ -211,63 +577,263 @@
using namespace mln;
using namespace value;
- if (argc < 2)
+ // trace::quiet = false;
+
+ if (argc != 5)
+ {
+ std::cout << argv[0] << " input.pgm lambda echo output.pbm" << std::endl;
+ return 1;
+ }
+
+ int lambda_grad = std::atoi(argv[2]);
+ int echo = std::atoi(argv[3]);
+
+
+ if (echo != 0 && echo != 1)
{
- std::cout << argv[0] << " <input.pgm> " << std::endl;
+ std::cout << argv[0] << " input.pgm lambda echo output.pbm" << std::endl;
return 1;
}
+
image2d<int_u8> input;
io::pgm::load(input, argv[1]);
- image2d<int_u8> grad = morpho::elementary::gradient_internal(input, c4());
- io::pgm::save(grad, "binarization_grad.pgm");
+ image2d<int_u8> input_ = image2full(input); // Larger to make room to edges.
+
+ image2d<int_u8> grad_;
+ {
+ grad_ = dist_on_edges(extend(input_ | is_edge, pw::value(input_)),
+ e2c());
+ }
+
+ // io::pgm::save(grad_, "grad_.pgm");
+
+ mln_VAR(grad, grad_ | is_edge);
+ typedef grad_t E;
+
+ grad = morpho::closing::volume(grad,
+ e2e(),
+ lambda_grad);
+
+ // io::pgm::save(grad.unmorph_(), "grad.pgm");
+
+ typedef label_16 L; // Label type.
+
+ L nbasins;
+
+ typedef mln_ch_value_(E, L) EL;
+
+ EL wst = morpho::watershed::flooding(grad,
+ e2e(),
+ nbasins);
+
+ std::cout << "n basins = " << nbasins << std::endl;
+
+
+ if (echo)
+ {
+ io::ppm::save(display_edge(debug::colorize(rgb8(),
+ wst,
+ nbasins).unmorph_(),
+ literal::black,
+ 3),
+ "temp_wst_edges.ppm");
+ }
+
+
+ image2d<L> w_all = wst.unmorph_();
+
+ // edges -> squares
+ mln_VAR(w_squares, w_all | is_square);
+ data::paste(morpho::dilation(extend(w_squares, pw::value(w_all)),
+ c4().win()),
+ w_all);
+ // edges -> points
+ mln_VAR(w_points, w_all | is_point);
+ data::paste(morpho::erosion(extend(w_points, pw::value(w_all)),
+ c4().win()),
+ w_all);
+
+ image2d<L> ws = full2image(w_all);
+
+ if (echo)
+ {
+ io::ppm::save(debug::colorize(rgb8(), ws, nbasins),
+ "temp_ws.ppm");
+ }
+
+ util::couple<util::graph, image2d<L> >
+ rag_data = make::rag_and_labeled_wsl(w_all, c8(), nbasins);
+
+ if (echo)
+ io::pgm::save(labeling::wrap(int_u8(),
+ rag_data.second()),
+ "temp_lwsl.pgm");
+
- image2d<int_u8> clo_vol = morpho::closing::volume(grad, c4(), 500);
- io::pgm::save(clo_vol, "binarization_clo.pgm");
+ unsigned threshold;
+ contours(input, threshold);
- label_16 nbasins;
- image2d<label_16> wst = morpho::watershed::flooding(clo_vol, c4(), nbasins);
- io::ppm::save(debug::colorize(rgb8(), wst, nbasins), "binarization_wst.ppm");
+ typedef accu::median_h<int_u8> A;
+ typedef fun::i2v::array<point2d> F;
- util::couple<util::graph, image2d<label_16> >
- rag_data = make::rag_and_labeled_wsl(wst, c4(), nbasins);
- io::pgm::save(rag_data.second(), "binarization_lwsl.pgm");
- io::ppm::save(debug::colorize(rgb8(), rag_data.second(), nbasins), "binarization_lwsl.ppm");
+ util::array<int_u8> basin_med = labeling::compute(A(), input, ws, nbasins);
+ basin_med[0] = 0;
+
+
+
+ if (echo)
+ io::ppm::save(debug::colorize(rgb8(), w_all, nbasins),
+ "temp_w_all.ppm");
+
+
+
+ // ----------------------------- R A G --------------------------------
+
+
+ util::graph& gr = rag_data.first();
+
+ fun::i2v::array<int_u8> f_med;
+ convert::from_to(basin_med, f_med);
+
+ if (echo)
+ {
+ io::pgm::save(level::transform(w_all, f_med),
+ "temp_w_all.pgm");
+ io::pgm::save(level::transform(ws, f_med), "temp_basin_med.pgm");
+ }
p_vertices<util::graph, fun::i2v::array<point2d> >
- pv = make::common_pvertices(wst, nbasins, rag_data.first());
+ pv = make::common_pvertices(ws, nbasins, rag_data.first());
+
+ mln_VAR( med, f_med | pv );
+
+
+ typedef graph_elt_neighborhood<util::graph, F> N;
+ N nbh;
+
+ threshold = 25; // FIXME
+
+ L n_objects;
+ mln_VAR( lab, labeling__quasi_regional_minima(med, nbh, threshold, n_objects) );
+
+
+ io::pbm::save(pw::value(level::transform(ws, lab.function()))
+ | input.domain(),
+ argv[4]);
+
+// io::pbm::save((pw::value(level::transform(ws,
+// lab.function())) != pw::cst(0))
+// | input.domain(),
+// argv[4]);
+
+
+ /*
+
+ int_u8
+ object = 255,
+ background = 0,
+ unknown = 128;
+
+ med_t out;
+ initialize(out, med);
+ data::fill(out, unknown);
+
+ // Initialization.
+
+ mln_piter_(med_t) p(med.domain());
+ mln_niter_(N) n(nbh, p);
+ for_all(p)
+ for_all(n)
+ {
+ int d = math::diff_abs(med(p), med(n));
+ // if (2 * d > 3 * threshold)
+ if (d > threshold)
+ {
+ if (med(p) < med(n))
+ {
+ out(p) = object;
+ out(n) = background;
+ }
+ else
+ {
+ out(n) = object;
+ out(p) = background;
+ }
+ break;
+ }
+ }
+
+ if (echo)
+ {
+ io::pgm::save(level::transform(ws, out.function()),
+ "temp_out.pgm");
+ }
+
+
+ // Enqueuing.
+
+ typedef mln_psite_(med_t) P;
+ p_queue<P> q;
+
+ for_all(p)
+ {
+ if (out(p) != unknown)
+ continue;
+ for_all(n)
+ if (out(n) != unknown)
+ {
+ q.insert(p);
+ break;
+ }
+ }
+
+ // Propagation.
+
+ P p_;
+ mln_niter_(N) n_(nbh, p_);
+ while (! q.is_empty())
+ {
+ p_ = q.pop_front();
+
+ if (out(p_) != unknown)
+ continue; // std::cerr << "oops! (1)" << std::endl;
+
+ unsigned d = 256, id;
+ for_all(n_)
+ {
+ if (out(n_) == unknown)
+ {
+ q.insert(n_);
+ continue;
+ }
+ unsigned d_ = math::diff_abs(med(p_), med(n_));
+ if (d_ < d)
+ {
+ d = d_;
+ id = out(n_);
+ }
+ }
+ if (d == 256)
+ std::cerr << "oops! (2)" << std::endl;
+
+ out(p_) = id; // object or background.
+ }
+
+ if (echo)
+ {
+ io::pgm::save(level::transform(ws, out.function()),
+ "temp_out_2.pgm");
+ }
- pw::image<fun::i2v::array<int_u8>,
- p_vertices<util::graph, fun::i2v::array<point2d> > >
- ima_v = make::vertex_image(accu::mean<int_u8>(), pv, input, wst, nbasins);
-
- pw::image<fun::i2v::array<int_u8>,
- p_edges<util::graph,pw::cst_<literal::origin_t> > >
- ima_e = make::edge_image(ima_v,
- make::dummy_pedges(rag_data.first(),literal::origin),
- edge_values());
-
-
- io::pgm::save(make::debug_graph_image(input,ima_v, ima_e, 4, 0), "binarization_graph.ppm");
-
- // FIXME: we should use the following line instead. We cannot since currently
- // graph edges are numbered from 0 and we must use mln_max() - 1 as
- // background id.
- //
- //label_16 nelts = rag.first().e_nmax();
- label_16 nelts = mln_max(label_16).prev();
-
- util::array<int_u8> median_grad = labeling::compute(accu::meta::median_h(),
- grad,
- rag_data.second(),
- nelts);
- fun::i2v::array<int_u8> f;
- convert::from_to(median_grad, f);
+ io::pbm::save((pw::value(level::transform(ws,
+ out.function())) == pw::cst(255))
+ | input.domain(),
+ argv[4]);
- image2d<int_u8> med = level::transform(rag_data.second(), f);
+ */
- io::pgm::save(med, "binarization_median_grad.pgm");
}
1
0
05 Apr '09
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-04-05 Frederic Bour <bour(a)lrde.epita.fr>
Update to our line recognition using component trees..
* edwin/tree/test.cc: Now use weighted distance front.
---
test.cc | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 91 insertions(+), 18 deletions(-)
Index: trunk/milena/sandbox/edwin/tree/test.cc
===================================================================
--- trunk/milena/sandbox/edwin/tree/test.cc (revision 3604)
+++ trunk/milena/sandbox/edwin/tree/test.cc (revision 3605)
@@ -3,7 +3,9 @@
#include <mln/core/image/image_if.hh>
#include <mln/core/alias/neighb2d.hh>
#include <mln/core/routine/duplicate.hh>
+#include <mln/core/alias/window2d.hh>
#include <mln/core/var.hh>
+#include <mln/value/int_u16.hh>
/* Site set */
#include <mln/core/site_set/p_array.hh>
@@ -16,16 +18,24 @@
#include "run.hh"
#include "accumulator/arg_max.hh"
+/* morpho closing */
+// #include <mln/morpho/opening/structural.hh>
+// #include <mln/morpho/closing/structural.hh>
+
/* Attributes */
-#include <mln/transform/distance_geodesic.hh>
+// #include <mln/transform/distance_geodesic.hh>
+#include <mln/core/alias/window2d.hh>
+#include <mln/core/alias/w_window2d_int.hh>
+#include <mln/transform/distance_front.hh>
#include <mln/morpho/attribute/card.hh>
#include "../attributes/bbox.hh"
+#include <mln/make/w_window2d_int.hh>
/* io */
#include <mln/io/pbm/load.hh>
#include <mln/io/pgm/save.hh>
#include <mln/io/ppm/save.hh>
-#include <../../theo/color/change_attributes.hh>
+//#include <../../theo/color/change_attributes.hh>
/* data & pw */
#include <mln/core/concept/function.hh>
@@ -48,14 +58,13 @@
bool mydebug = false;
-
void usage(char** argv)
{
- std::cerr << "usage: " << argv[0] << " input [--debug]" << std::endl;
+ std::cerr << "usage: " << argv[0] << " input [--debug] [-n nbr_components | -s sharpness] [-c card]" << std::endl;
abort();
}
-void dsp(const char* str)
+void dsp(const std::string& str)
{
std::cout << std::endl
<< "*********************" << std::endl
@@ -95,27 +104,79 @@
int main(int argc, char* argv[])
{
using namespace mln;
- using value::int_u8;
+// using value::int_u8;
+ using value::int_u16;
+
+ std::string arg;
+ unsigned nb_components = 0;
+ unsigned card = 0;
+ double treshold = 0;
if (argc < 2)
usage(argv);
- mydebug = (argc >= 3 && std::string(argv[2]) == "--debug");
+ for (int i = 2; i < argc; i++)
+ {
+ arg = std::string(argv[i]);
+ if (arg == "--debug")
+ mydebug = true;
+ else if (arg == "-n" && i != argc)
+ nb_components = atoi(argv[++i]);
+ else if (arg == "-t" && i != argc)
+ treshold = atof(argv[++i]);
+ else if (arg == "-c" && i != argc)
+ card = atoi(argv[++i]);
+ else if (arg == "--trace")
+ trace::quiet = false;
+ else
+ usage (argv);
+ }
/* Image loadin' */
- typedef image2d<int_u8> I;
+ typedef image2d<int_u16> I;
image2d<bool> input_;
io::pbm::load(input_, argv[1]);
/* Work on geodesic distance image */
- I input = transform::distance_geodesic(input_, c8(), mln_max(int_u8));
+// I input = transform::distance_geodesic(input_, c8(), mln_max(int_u8));
+ I input;
+ {
+ const int weights[9] =
+ { 10, 9, 10,
+ 1, 0, 1,
+ 10, 9, 10 };
+
+ w_window2d_int win;
+ mln::convert::from_to(weights, win);
+ input = transform::distance_front(input_, c8(), win, mln_max(int_u16));
+ }
if (mydebug)
dsp("Distance geodesic");
- io::pgm::save(input, "distance.pgm");
+ /* Closing */
+ {
+ bool w[3][1];
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 1; j++)
+ w[i][j] = 1;
+
+// input = morpho::closing::structural(input, convert::to<window2d>(w));
+ }
+
+ /* Opening */
+ {
+ bool w[1][15];
+
+ for (int i = 0; i < 1; i++)
+ for (int j = 0; j < 15; j++)
+ w[i][j] = 1;
+
+// input = morpho::opening::structural(input, convert::to<window2d>(w));
+ }
/* Component tree creation */
typedef p_array< mln_site_(I) > S;
@@ -124,6 +185,9 @@
S sorted_sites = level::sort_psites_decreasing(input);
tree_t tree(input, sorted_sites, c4());
+
+ io::pgm::save(input, "distance.pgm");
+
/* Compute Attribute On Image */
typedef morpho::attribute::bbox<I> bbox_t;
typedef mln_ch_value_(I, double) A;
@@ -133,7 +197,7 @@
morpho::tree::propagate_representant(tree, a);
if (mydebug) {
- dsp("Image sharp attribute"); display_tree_attributes(tree, a);
+ dsp("Image sharp attribute");
}
/* We don't want little components */
@@ -161,11 +225,20 @@
accumulator::arg_max<A> argmax(a);
p_array< mln_psite_(A) > obj_array; // Array of object components.
- mln_VAR(predicate, pw::value(a) > pw::cst(0.5));
- obj_array = morpho::tree::run_while(tree, a, argmax, predicate);
-
if (mydebug) {
- dsp("Run max accumulator, lk 4 5 objs"); display_tree_attributes(tree, a);
+ std::stringstream s("Run max accumulator, look for ");
+ if (nb_components)
+ s << nb_components << " components.";
+ else
+ s << "components whose treshold > " << treshold;
+ dsp(s.str());
+ }
+
+ if (!nb_components) {
+ mln_VAR(predicate, pw::value(a) > pw::cst(treshold));
+ obj_array = morpho::tree::run_while(tree, a, argmax, predicate);
+ } else {
+ obj_array = morpho::tree::run_ntimes(tree, a, argmax, nb_components);
}
/* Print them */
@@ -193,7 +266,7 @@
// mask now contains all nodes related to objects
if (mydebug) {
- dsp("Create mask and propagate"); display_tree_attributes(tree, mask);
+ dsp("Create mask and propagate");
}
/* Labeling */
@@ -211,8 +284,8 @@
if (mydebug) {
mln_fwd_piter_(p_array< mln_psite_(I) >) c(obj_array);
for_all(c)
- draw::box(out, attr_image(c), mln_max(int_u8));
- dsp("Mask input"); display_tree_attributes(tree, out);
+ draw::box(out, attr_image(c), mln_max(int_u16));
+ dsp("Mask input");
}
io::pgm::save(out, "output.pgm");
1
0