https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add attribute image computation from a morpho tree.
* mln/morpho/tree/compute_attribute_image.hh: New.
* mln/morpho/tree/all.hh: Update.
* mln/morpho/tree/data.hh (function): New typedef.
(f): New method.
* mln/canvas/labeling.hh: Fix indentation.
Add dispatch.
* tests/morpho/tree/compute_attribute_image.cc: New.
* tests/morpho/tree/Makefile.am: Update.
* doc/examples/tuto_bis.cc (main): Fix missing update.
doc/examples/tuto_bis.cc | 2
mln/canvas/labeling.hh | 93 +++++++++++++++++---
mln/morpho/tree/all.hh | 1
mln/morpho/tree/compute_attribute_image.hh | 124 +++++++++++++++++++++++++++
mln/morpho/tree/data.hh | 9 +
tests/morpho/tree/Makefile.am | 2
tests/morpho/tree/compute_attribute_image.cc | 81 +++++++++++++++++
7 files changed, 299 insertions(+), 13 deletions(-)
Index: tests/morpho/tree/compute_attribute_image.cc
--- tests/morpho/tree/compute_attribute_image.cc (revision 0)
+++ tests/morpho/tree/compute_attribute_image.cc (revision 0)
@@ -0,0 +1,81 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file tests/morpho/tree/compute_attribute_image.cc
+///
+/// Tests on mln::morpho::tree::compute_attribute_image.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/site_set/p_array.hh>
+#include <mln/level/sort_psites.hh>
+
+#include <mln/debug/println.hh>
+#include <mln/core/var.hh>
+
+#include <mln/morpho/tree/data.hh>
+#include <mln/morpho/tree/compute_attribute_image.hh>
+
+#include <mln/accu/count.hh>
+#include <mln/accu/volume.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ {
+ unsigned vals[] = { 5, 6, 6,
+ 8, 9, 9,
+ 8, 9, 9 };
+
+ typedef image2d<unsigned> I;
+ I f = make::image2d(vals);
+ debug::println(f);
+
+ typedef p_array<point2d> S;
+ S s = level::sort_psites_increasing(f);
+
+ morpho::tree::data<I,S> t(f, s, c4());
+ debug::println(t.parent_image());
+
+ typedef util::pix<I> Px;
+
+ {
+ accu::count<Px> a;
+ image2d<unsigned> area = morpho::tree::compute_attribute_image(a, t);
+ debug::println(area);
+ }
+
+ {
+ accu::volume<I> v;
+ image2d<unsigned> volume = morpho::tree::compute_attribute_image(v, t);
+ debug::println(volume);
+ }
+ }
+
+}
Index: tests/morpho/tree/Makefile.am
--- tests/morpho/tree/Makefile.am (revision 2952)
+++ tests/morpho/tree/Makefile.am (working copy)
@@ -3,10 +3,12 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
+ compute_attribute_image \
compute_tree \
data \
max
+compute_attribute_image_SOURCES = compute_attribute_image.cc
compute_tree_SOURCES = compute_tree.cc
data_SOURCES = data.cc
max_SOURCES = max.cc
Index: doc/examples/tuto_bis.cc
--- doc/examples/tuto_bis.cc (revision 2952)
+++ doc/examples/tuto_bis.cc (working copy)
@@ -223,7 +223,7 @@
image2d<int> ima(3, 5);
mln_VAR(cell, ima | is_cell);
- level::fill(cell, fun::p2v::iota);
+ level::fill(cell, fun::p2v::iota());
debug::println(cell);
// 1 2 3
//
Index: mln/morpho/tree/compute_attribute_image.hh
--- mln/morpho/tree/compute_attribute_image.hh (revision 0)
+++ mln/morpho/tree/compute_attribute_image.hh (revision 0)
@@ -0,0 +1,124 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
+# define MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
+
+/// \file mln/morpho/tree/compute_attribute_image.hh
+///
+/// Compute a canonized tree from an image.
+///
+/// \todo Specialize for low quant (and try fastest).
+
+# include <mln/core/concept/image.hh>
+# include <mln/util/pix.hh>
+# include <mln/level/fill.hh>
+# include <mln/level/paste.hh>
+
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace tree
+ {
+
+ /// Compute a tree with a parent relationship between sites.
+ ///
+ /// Warning: \p s translates the ordering related to the
+ /// "natural" childhood relationship. The parenthood is thus
+ /// inverted w.r.t. to \p s.
+ ///
+ /// It is very convenient since all processing upon the parent
+ /// tree are performed following \p s (in the default "forward"
+ /// way).
+ ///
+ /// FIXME: Put it more clearly...
+ ///
+ /// The parent result image verifies: \n
+ /// - p is root iff parent(p) == p \n
+ /// - p is a node iff either p is root or f(parent(p)) != f(p).
+
+ template <typename A, typename T>
+ mln_ch_value(typename T::function, mln_result(A))
+ compute_attribute_image(const Accumulator<A>& a, const T& t);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade.
+
+ template <typename A, typename T>
+ inline
+ mln_ch_value(typename T::function, mln_result(A))
+ compute_attribute_image(const Accumulator<A>& a_, const T& t)
+ {
+ trace::entering("morpho::tree::compute_attribute_image");
+
+ const A& a = exact(a_);
+
+ typedef typename T::function I;
+ mln_ch_value(I, A) acc;
+ initialize(acc, t.f());
+
+ {
+ mln_piter(I) p(t.f().domain());
+ for_all(p)
+ acc(p).take_as_init(make::pix(t.f(), p));
+ }
+ {
+ mln_piter(T) p(t.domain());
+ for_all(p)
+ if (! t.is_root(p))
+ acc(t.parent(p)).take(acc(p));
+ }
+
+ typedef typename T::function I;
+ mln_ch_value(I, mln_result(A)) output;
+ initialize(output, acc);
+ // level::fill(output, acc);
+ level::paste(acc, output);
+
+ trace::exiting("morpho::tree::compute_attribute_image");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::tree
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
Index: mln/morpho/tree/all.hh
--- mln/morpho/tree/all.hh (revision 2952)
+++ mln/morpho/tree/all.hh (working copy)
@@ -46,6 +46,7 @@
}
+# include <mln/morpho/tree/compute_attribute_image.hh>
# include <mln/morpho/tree/compute_parent.hh>
# include <mln/morpho/tree/data.hh>
# include <mln/morpho/tree/max.hh>
Index: mln/morpho/tree/data.hh
--- mln/morpho/tree/data.hh (revision 2952)
+++ mln/morpho/tree/data.hh (working copy)
@@ -54,6 +54,10 @@
public:
+ /// Associated type of the function f.
+ typedef I function;
+
+
/// Ctor.
template <typename N>
data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh);
@@ -135,6 +139,11 @@
return nroots_;
}
+ const I& f() const
+ {
+ return f_;
+ }
+
protected:
const I& f_;
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 2952)
+++ mln/canvas/labeling.hh (working copy)
@@ -56,12 +56,42 @@
# ifndef MLN_INCLUDE_ONLY
+ // Tests.
+
+ namespace internal
+ {
+
+ template <typename I, typename N, typename F, typename L>
+ void
+ labeling_tests(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ const F& f, const L& nlabels)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.has_data());
+ // mln_precondition(nbh.is_valid());
+
+ (void) input;
+ (void) nbh;
+ }
+
+ } // end of namespace mln::canvas::internal
+
+
+
+ // Implementations.
+
+ namespace impl
+ {
+
+ namespace generic
+ {
template <typename I>
static inline
mln_psite(I)
- find_root(I& parent,
- const mln_psite(I)& x)
+ find_root(I& parent, const mln_psite(I)& x)
{
if (parent(x) == x)
return x;
@@ -74,7 +104,7 @@
labeling(const Image<I>& input_, const Neighborhood<N>& nbh_,
F& f, L& nlabels)
{
- trace::entering("canvas::labeling");
+ trace::entering("canvas::impl::generic::labeling");
// FIXME: Test?!
@@ -95,7 +125,6 @@
bool status;
// Initialization.
-
{
initialize(deja_vu, input);
mln::level::fill(deja_vu, false);
@@ -110,18 +139,14 @@
}
// First Pass.
-
{
mln_fwd_piter(S) p(f.s);
mln_niter(N) n(nbh, p);
for_all(p) if (f.handles(p))
{
-
// Make-Set.
- {
parent(p) = p;
f.init_attr(p);
- }
for_all(n)
if (input.domain().has(n) && deja_vu(n))
@@ -143,7 +168,7 @@
}
}
- // Second Pass. pass_2();
+ // Second Pass.
{
mln_bkd_piter(S) p(f.s);
for_all(p) if (f.handles(p))
@@ -164,13 +189,18 @@
output(p) = output(parent(p));
}
status = true;
-
}
- trace::exiting("canvas::labeling");
+ trace::exiting("canvas::impl::generic::labeling");
return output;
}
+ } // end of namespace mln::canvas::impl::generic
+
+ } // end of namespace mln::canvas::impl
+
+
+
@@ -324,9 +354,48 @@
*/
-# endif // ! MLN_INCLUDE_ONLY
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <typename I, typename N, typename F, typename L>
+ inline
+ mln_ch_value(I, L)
+ labeling_dispatch(const Image<I>& input, const Neighborhood<N>& nbh,
+ F& functor, L& nlabels)
+ {
+ return impl::generic::labeling(input, nbh, functor, nlabels);
+ }
+
+ } // end of namespace mln::canvas::internal
+
+
+
+ // Facade.
+
+ template <typename I, typename N, typename F, typename L>
+ inline
+ mln_ch_value(I, L)
+ labeling(const Image<I>& input, const Neighborhood<N>& nbh,
+ F& functor, L& nlabels)
+ {
+ trace::entering("canvas::labeling");
+
+ internal::labeling_tests(input, nbh, functor, nlabels);
+
+ mln_ch_value(I, L) output;
+ output = internal::labeling_dispatch(input, nbh, functor, nlabels);
+
+ trace::exiting("canvas::labeling");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln::canvas
} // end of namespace mln