milena r1125: Add labeling and update border.

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-09-18 Guillaume Duhamel <guillaume.duhamel@lrde.epita.fr> Add labeling and update border. * canvas_labeling.hh: Copy from mln/canvas/labeling.hh. * labeling_level.hh: Specialize with fast image. * border_duplicate.cc, * border_duplicate.hh, * border_fill.cc, * border_fill.hh: Update. --- border_duplicate.cc | 22 ++-- border_duplicate.hh | 1 border_fill.cc | 2 border_fill.hh | 8 + canvas_labeling.hh | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++ labeling_level.hh | 147 +++++++++++++++++++++++++++ 6 files changed, 441 insertions(+), 14 deletions(-) Index: trunk/milena/sandbox/duhamel/border_fill.hh =================================================================== --- trunk/milena/sandbox/duhamel/border_fill.hh (revision 1124) +++ trunk/milena/sandbox/duhamel/border_fill.hh (revision 1125) @@ -42,6 +42,7 @@ #include <mln/core/image2d_b.hh> #include <mln/core/image2d_b.hh> #include <mln/core/pixel.hh> +#include <mln/core/line_piter.hh> namespace mln { @@ -83,11 +84,14 @@ point2d p = ima.bbox ().pmin (); // FIXME : REMOVE THIS LOOP BY MEMSET - for (std::size_t i = 0; i < border * (2 * (border + 1) + nbcols); ++i) + + std::size_t s = border * (2 * (border + 1) + nbcols); + for (std::size_t i = 0; i < s; ++i) const_cast<I&>(ima)[i] = v; // ACCESS TO RIGHT UP CORNER - for (std::size_t i = 0; i < nbcols + 1; ++i) + s = nbcols + 1; + for (std::size_t i = 0; i < s; ++i) p = p + right; // FILL BORDER Index: trunk/milena/sandbox/duhamel/border_duplicate.cc =================================================================== --- trunk/milena/sandbox/duhamel/border_duplicate.cc (revision 1124) +++ trunk/milena/sandbox/duhamel/border_duplicate.cc (revision 1125) @@ -41,21 +41,21 @@ int main (void) { - image2d_b<value::int_u8> i1(5, 7); + image2d_b<value::int_u8> i1(10000, 1000); // Fill with randomized value. - for (unsigned int i = 0; i < i1.ncells (); ++i) - i1[i] = i;//(i * 4452) % 10; - std::cout << "before duplicate" - << std::endl - << std::endl; - debug::println_with_border(i1); +// for (unsigned int i = 0; i < i1.ncells (); ++i) +// i1[i] = i;//(i * 4452) % 10; +// std::cout << "before duplicate" +// << std::endl +// << std::endl; +// debug::println_with_border(i1); border::duplicate (i1); - std::cout << "after duplicate" - << std::endl - << std::endl; - debug::println_with_border(i1); +// std::cout << "after duplicate" +// << std::endl +// << std::endl; +// debug::println_with_border(i1); } Index: trunk/milena/sandbox/duhamel/labeling_level.hh =================================================================== --- trunk/milena/sandbox/duhamel/labeling_level.hh (revision 0) +++ trunk/milena/sandbox/duhamel/labeling_level.hh (revision 1125) @@ -0,0 +1,147 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_LABELING_LEVEL_HH +# define MLN_LABELING_LEVEL_HH + +/*! \file mln/labeling/level.hh + * + * \brief Connected component labeling of the image objects at a given + * level. + */ + +# include <mln/labeling/base.hh> +# include <mln/level/fill.hh> + + +namespace mln +{ + + namespace labeling + { + + /*! Connected component labeling of the image objects at a given + * level. + * + * \param[in] input The input image. + * \param[in] val The level to consider for the labeling. + * \param[in] nbh The neighborhood. + * \param[out] output The label image. + * \param[out] nlabels The number of labels. + * + * \return Succeed or not. + */ + template <typename I, typename N, typename O> + bool level(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh, + Image<O>& output, unsigned& nlabels); + + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + // Functors. + + template <typename I_, typename N_, typename O_> + struct level_t : base_<I_,N_,O_> + { + typedef mln_point(I_) P; + + // requirements from mln::canvas::labeling: + + typedef mln_pset(I_) S; + const S& s; + + void init() { mln::level::fill(this->output, 0); } + bool handles(const P& p) const { return input(p) == val; } + bool equiv(const P& n, const P&) const { return input(n) == val; } + + // end of requirements + + const mln_value(I_)& val; + + level_t(const I_& input, const mln_value(I_)& val, const N_& nbh, O_& output) + : base_<I_,N_,O_>(input, nbh, output), + s(input.domain()), + val(val) + {} + }; + + // Routines. + + template <typename I, typename N, typename O> + bool level_(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh, + Image<O>& output, unsigned& nlabels) + { + typedef impl::level_t<I,N,O> F; + F f(exact(input), val, exact(nbh), exact(output)); + canvas::labeling<F> run(f); + nlabels = f.nlabels; + return f.status; + } + + // FIXME: Add fast versions. + + // FIXME (ADD) + // + template <typename I, typename N, typename O> + bool level_(const Fast_Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh, + Image<O>& output, unsigned& nlabels) + { + typedef impl::level_t<I,N,O> F; + F f(exact(input), val, exact(nbh), exact(output)); + canvas::labeling_fast<F> run(f); + nlabels = f.nlabels; + return f.status; + } + + // + //END FIXME (ADD) + + } // end of namespace mln::labeling::impl + + + // Facade. + + template <typename I, typename N, typename O> + bool level(const Image<I>& input, const mln_value(I)& val, const Neighborhood<N>& nbh, + Image<O>& output, unsigned& nlabels) + { + mln_precondition(exact(output).domain() == exact(input).domain()); + return impl::level_(exact(input), val, nbh, output, nlabels); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::labeling + +} // end of namespace mln + + +#endif // ! MLN_LABELING_LEVEL_HH Index: trunk/milena/sandbox/duhamel/border_duplicate.hh =================================================================== --- trunk/milena/sandbox/duhamel/border_duplicate.hh (revision 1124) +++ trunk/milena/sandbox/duhamel/border_duplicate.hh (revision 1125) @@ -79,6 +79,7 @@ std::size_t real_nbcols = (nbcols + 1) + 2 * border; std::size_t start = real_nbcols * border + border; std::size_t s = start; + // duplicate top left corner for (std::size_t i = 0; i < border + 1; ++i) for (std::size_t j = 0; j < border + 1; ++j) Index: trunk/milena/sandbox/duhamel/canvas_labeling.hh =================================================================== --- trunk/milena/sandbox/duhamel/canvas_labeling.hh (revision 0) +++ trunk/milena/sandbox/duhamel/canvas_labeling.hh (revision 1125) @@ -0,0 +1,275 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CANVAS_LABELING_HH +# define MLN_CANVAS_LABELING_HH + +/*! \file mln/canvas/labeling.hh + * + * \brief Connected component labeling of the object part in a binary + * image. + */ + +# include <mln/level/fill.hh> +# include <mln/level/sort_points.hh> + +# include <mln/convert/to_window.hh> + +namespace mln +{ + + namespace canvas + { + + // General version. + + template <typename F> + struct labeling + { + F& f; + + typedef typename F::I I; + typedef typename F::N N; + typedef typename F::O O; + typedef typename F::S S; + typedef mln_point(I) point; + + // aux: + mln_ch_value(O, bool) deja_vu; + mln_ch_value(O, point) parent; + + labeling(F& f) + : f(f), + deja_vu(f.output.domain()), + parent(f.output.domain()) + { + run(); + } + + void run() + { + // init + { + f.nlabels = 0; + mln::level::fill(deja_vu, false); + f.init(); + } + // first pass + { + mln_fwd_piter(S) p(f.s); + mln_niter(N) n(f.nbh, p); + for_all(p) if (f.handles(p)) + { + make_set(p); + for_all(n) + if (f.input.has(n) && deja_vu(n)) + if (f.equiv(n, p)) + do_union(n, p); + else + f.do_no_union(n, p); + deja_vu(p) = true; + } + } + + // second pass + { + mln_bkd_piter(S) p(f.s); + for_all(p) if (f.handles(p)) + { + if (is_root(p)) + { + if (f.labels(p)) + { + if (f.nlabels == mln_max(mln_value(O))) + { + f.status = false; + return; + } + f.output(p) = ++f.nlabels; + } + } + else + f.output(p) = f.output(parent(p)); + } + f.status = true; + } + + } // end of run() + + void make_set(const point& p) + { + parent(p) = p; + f.init_attr(p); + } + + bool is_root(const point& p) const + { + return parent(p) == p; + } + + point find_root(const point& x) + { + if (parent(x) == x) + return x; + else + return parent(x) = find_root(parent(x)); + } + + void do_union(const point& n, const point& p) + { + point r = find_root(n); + if (r != p) + { + parent(r) = p; + f.merge_attr(r, p); + } + } + + }; + + + // FIXME: Fast version. + + // FIXME (ADD) + // + template <typename F> + struct labeling_fast + { + F& f; + + typedef typename F::I I; + typedef typename F::N N; + typedef typename F::O O; + typedef typename F::S S; + typedef mln_point(I) point; + + labeling_fast(F& f) + : f(f) + { + run(); + } + + void run() + { + // init + { + f.nlabels = 0; + f.init(); + } + // first pass + { + typedef mln_dpoint(N) DP; + typedef mln_point(N) P; + typedef window<DP> W; + + mln_fwd_pixter(const I) pix_input(f.input); + W win = convert::to_window(f.nbh); + + mln_qiter(W) q_input(win, P::zero); + + for_all(pix_input) + { +// if (f.handles(pix_input)) +// { + const point p = pix_input; + make_set(p); + for_all(q_input) + { +// const point q; +// if (f.equiv(q, p)) +// do_union(q, p); +// else +// f.do_no_union(q, p); + } +// } + } + } + +// // second pass +// { +// mln_bkd_piter(S) p(f.s); +// for_all(p) if (f.handles(p)) +// { +// if (is_root(p)) +// { +// if (f.labels(p)) +// { +// if (f.nlabels == mln_max(mln_value(O))) +// { +// f.status = false; +// return; +// } +// f.output(p) = ++f.nlabels; +// } +// } +// else +// f.output(p) = f.output(parent(p)); +// } +// f.status = true; +// } + + } // end of run() + + void make_set(const point& p) + { + parent(p) = p; + f.init_attr(p); + } + + bool is_root(const point& p) const + { + return parent(p) == p; + } + + point find_root(const point& x) + { + if (parent(x) == x) + return x; + else + return parent(x) = find_root(parent(x)); + } + + void do_union(const point& n, const point& p) + { + point r = find_root(n); + if (r != p) + { + parent(r) = p; + f.merge_attr(r, p); + } + } + }; + // + // END FIXME (ADD) + + + } // end of namespace mln::canvas + +} // end of namespace mln + + +#endif // ! MLN_CANVAS_LABELING_HH Index: trunk/milena/sandbox/duhamel/border_fill.cc =================================================================== --- trunk/milena/sandbox/duhamel/border_fill.cc (revision 1124) +++ trunk/milena/sandbox/duhamel/border_fill.cc (revision 1125) @@ -41,7 +41,7 @@ int main (void) { - image2d_b<value::int_u8> i1(9, 7); + image2d_b<value::int_u8> i1(9, 6); border::fill (i1, 8); debug::println_with_border(i1);
participants (1)
-
Guillaume Duhamel