
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2009-02-06 Fabien Freling <freling@lrde.epita.fr> Implement labeling_video_fastest. * fabien/labeling.hh: Implement video_fastest. * fabien/level.cc: Test file. * fabien/level.hh: Implement fastest implementation. --- labeling.hh | 22 +++++++++---------- level.cc | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ level.hh | 48 +++++++++++++---------------------------- 3 files changed, 96 insertions(+), 43 deletions(-) Index: trunk/milena/sandbox/fabien/level.hh =================================================================== --- trunk/milena/sandbox/fabien/level.hh (revision 3310) +++ trunk/milena/sandbox/fabien/level.hh (revision 3311) @@ -36,7 +36,9 @@ # include <mln/core/concept/image.hh> # include <mln/core/concept/neighborhood.hh> -# include <mln/canvas/labeling.hh> + +# include "labeling.hh" + # include <mln/data/fill.hh> @@ -93,35 +95,10 @@ namespace impl { - - struct labeling_functor_base - { - void init() {} - - template <typename P> - bool handles(const P&) const { return true; } - - template <typename L, typename R> - bool equiv(const L&, const R&) const { return false; } - - template <typename P> - bool labels(const P&) const { return true; } - - template <typename L, typename R> - void do_no_union(const L&, const R&) {} - - template <typename P> - void init_attr(const P&) {} - - template <typename L, typename R> - void merge_attr(const L&, const R&) {} - }; - - // Generic functor. template <typename I> - struct level_functor : labeling_functor_base + struct level_functor { typedef mln_psite(I) P; @@ -138,14 +115,19 @@ bool handles(const P& p) const { return input(p) == val; } bool equiv(const P& n, const P&) const { return input(n) == val; } bool labels(const P&) const { return true; } + void do_no_union(const P& n, const P& p) {} + void init_attr(const P&) {} + void merge_attr(const P& r, const P& p) {} // Fastest implementation void init_() {} - bool handles_(const P& p) const { return input.element(p) == val; } - bool equiv_(const P& n, const P&) const { return input.element(n) == val; } - bool labels_(const P&) const { return true; } - + bool handles_(unsigned p) const { return input.element(p) == val; } + bool equiv_(unsigned n, unsigned) const { return input.element(n) == val; } + bool labels_(unsigned) const { return true; } + void do_no_union_(unsigned n, unsigned p) {} + void init_attr_(unsigned) {} + void merge_attr_(unsigned r, unsigned p) {} // end of Requirements. @@ -156,6 +138,8 @@ } }; + } // end of namespace mln::labeling::impl + @@ -171,7 +155,7 @@ internal::level_tests(input, val, nbh, nlabels); mln_ch_value(I, L) output; - level_functor<I> f(input, val); + impl::level_functor<I> f(input, val); output = canvas::labeling_video(input, nbh, nlabels, f); trace::exiting("labeling::level"); Index: trunk/milena/sandbox/fabien/labeling.hh =================================================================== --- trunk/milena/sandbox/fabien/labeling.hh (revision 3310) +++ trunk/milena/sandbox/fabien/labeling.hh (revision 3311) @@ -232,7 +232,7 @@ typename F> mln_ch_value(I, L) labeling_video_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, - F& f, L& nlabels) + L& nlabels, F& f) { trace::entering("canvas::impl::labeling_video_fastest"); @@ -273,27 +273,27 @@ { mln_pixter(const I) p(input); mln_nixter(const I, N) n(p, nbh); - for_all(p) if (f.handles_(p)) + for_all(p) if (f.handles_(p.offset())) { // Make-Set. - parent.element(p) = p; - f.init_attr(p); + parent(p).val() = p; + f.init_attr_(p.offset()); for_all(n) - if (input.domain().has(n) && deja_vu(n)) + if (input.has(n) && deja_vu(n)) { - if (f.equiv_(n, p)) + if (f.equiv_(n.offset(), p.offset())) { // Do-Union. - unsigned r = find_root_fastest(parent, n); + unsigned r = find_root_fastest(parent, n.val()); if (r != p) { parent.element(r) = p; - f.merge_attr_(r, p); + f.merge_attr_(r, p.offset()); } } else - f.do_no_union_(n, p); + f.do_no_union_(n.offset(), p.offset()); } deja_vu(p) = true; } @@ -306,7 +306,7 @@ { if (parent.element(p) == p) // if p is root { - if (f.labels_(p)) + if (f.labels_(p.offset())) { if (nlabels == mln_max(L)) { @@ -488,7 +488,7 @@ && mln_is_simple_neighborhood(N)::value }; - return impl::generic::labeling(metal::bool_<test>(), input, + return labeling_video(metal::bool_<test>(), input, nbh, nlabels, functor); } Index: trunk/milena/sandbox/fabien/level.cc =================================================================== --- trunk/milena/sandbox/fabien/level.cc (revision 0) +++ trunk/milena/sandbox/fabien/level.cc (revision 3311) @@ -0,0 +1,69 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/// \file tests/labeling/level.cc +/// +/// Test on mln::labeling::level. + +#include <mln/core/image/image2d.hh> +#include <mln/core/alias/neighb2d.hh> +#include <mln/value/int_u8.hh> +#include <mln/io/pgm/load.hh> + +#include <mln/accu/count.hh> +#include <mln/accu/compute.hh> + +#include "level.hh" + +#include <mln/pw/all.hh> +#include <mln/core/image/image_if.hh> + +#include <mln/debug/println.hh> + +#include <tests/data.hh> + + +int main() +{ + using namespace mln; + using value::int_u8; + + image2d<int_u8> lena = io::pgm::load<int_u8>(MLN_IMG_DIR "/tiny.pgm"); + image2d<bool> lvl(lena.domain()); + + unsigned n, npixels = 0; + for (unsigned l = 0; l <= 255; ++l) + { + image2d<unsigned> labels = labeling::level(lena, l, c4(), n); + unsigned npix = + accu::compute(accu::meta::count(), + labels | (pw::value(labels) != pw::cst(0u))); + npixels += npix; + } + mln_assertion(npixels == lena.nsites()); +}