2953: Add attribute image computation from a morpho tree.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@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
participants (1)
-
Thierry Geraud