last-svn-commit-144-g85cda08 Introduce labeling::value_and_compute.

* mln/canvas/labeling/video.hh: Call more functor members. * mln/labeling/value.hh: Provide new members to the functor. * mln/labeling/value_and_compute.hh: New functor computing attributes while labeling. --- milena/ChangeLog | 11 ++ milena/mln/canvas/labeling/video.hh | 8 +- milena/mln/labeling/value.hh | 16 ++- milena/mln/labeling/value_and_compute.hh | 241 ++++++++++++++++++++++++++++++ 4 files changed, 270 insertions(+), 6 deletions(-) create mode 100644 milena/mln/labeling/value_and_compute.hh diff --git a/milena/ChangeLog b/milena/ChangeLog index 98e20b3..15a34bc 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,14 @@ +2010-06-15 Guillaume Lazzara <z@lrde.epita.fr> + + Introduce labeling::value_and_compute. + + * mln/canvas/labeling/video.hh: Call more functor members. + + * mln/labeling/value.hh: Provide new members to the functor. + + * mln/labeling/value_and_compute.hh: New functor computing + attributes while labeling. + 2010-05-18 Guillaume Lazzara <z@lrde.epita.fr> * mln/io/magick/load.hh: set minimum resolution for PDF files to diff --git a/milena/mln/canvas/labeling/video.hh b/milena/mln/canvas/labeling/video.hh index 31afda4..b46e930 100644 --- a/milena/mln/canvas/labeling/video.hh +++ b/milena/mln/canvas/labeling/video.hh @@ -162,14 +162,20 @@ namespace mln return output; } output.element(p) = ++nlabels; + f.set_new_label_(p, nlabels); } } else - output.element(p) = output.element(parent.element(p)); + { + L lbl = output.element(parent.element(p)); + output.element(p) = lbl; + f.set_label_(p, lbl); + } } status = true; } + f.finalize(); trace::exiting("canvas::impl::video_fastest"); return output; } diff --git a/milena/mln/labeling/value.hh b/milena/mln/labeling/value.hh index 5a16ca4..7e1608c 100644 --- a/milena/mln/labeling/value.hh +++ b/milena/mln/labeling/value.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2007, 2008, 2009 EPITA Research and Development +// Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development // Laboratory (LRDE) // // This file is part of Olena. @@ -73,7 +73,7 @@ namespace mln L& nlabels) { mln_precondition(exact(input).is_valid()); - // mln_precondition(exact(nbh).is_valid()); + mln_precondition(exact(nbh).is_valid()); (void) input; (void) val; @@ -90,7 +90,7 @@ namespace mln // Generic functor. - template <typename I> + template <typename I, typename L> struct value_functor { typedef mln_psite(I) P; @@ -108,9 +108,12 @@ namespace mln 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&, const P&) {} + void do_no_union(const P&, const P&) {} void init_attr(const P&) {} void merge_attr(const P&, const P&) {} + void set_new_label(const P& p, const L& l){} + void set_label(const P& p, const L& l) {} + void finalize() {} // Fastest implementation @@ -121,6 +124,9 @@ namespace mln void do_no_union_(unsigned, unsigned) {} void init_attr_(unsigned) {} void merge_attr_(unsigned, unsigned) {} + void set_new_label_(unsigned, const L&) {} + void set_label_(unsigned, const L&) {} + void finalize_() {} // end of Requirements. @@ -148,7 +154,7 @@ namespace mln internal::value_tests(input, val, nbh, nlabels); mln_ch_value(I, L) output; - impl::value_functor<I> f(input, val); + impl::value_functor<I,L> f(input, val); output = canvas::labeling::video(input, nbh, nlabels, f); trace::exiting("labeling::value"); diff --git a/milena/mln/labeling/value_and_compute.hh b/milena/mln/labeling/value_and_compute.hh new file mode 100644 index 0000000..d93fce9 --- /dev/null +++ b/milena/mln/labeling/value_and_compute.hh @@ -0,0 +1,241 @@ +// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project 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_VALUE_AND_COMPUTE_HH +# define MLN_LABELING_VALUE_AND_COMPUTE_HH + +/// \file +/// +/// Connected component labeling of image sites at a given value. + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/canvas/labeling/video.hh> +# include <mln/data/fill.hh> + + + +namespace mln +{ + + namespace labeling + { + + /// \brief Connected component labeling of the image sites at a given + /// value. + /// + /// \param[in] input The input image. + /// \param[in] val The value to consider. + /// \param[in] nbh The connectivity of components. + /// \param[out] nlabels The number of labels. + /// \return The label image. + // + template <typename I, typename N, typename L, typename A> + util::couple<mln_ch_value(I,L), + util::couple<util::array<mln_result(A)>, + util::array<A> > > + value_and_compute(const Image<I>& input, const mln_value(I)& val, + const Neighborhood<N>& nbh, L& nlabels, + const Accumulator<A>& accu); + + +# ifndef MLN_INCLUDE_ONLY + + + // Tests. + + namespace internal + { + + template <typename I, typename N, typename L, typename A> + void + value_and_compute_tests(const Image<I>& input, const mln_value(I)& val, + const Neighborhood<N>& nbh, L& nlabels, + const Accumulator<A>& accu) + { + mln_precondition(exact(input).is_valid()); + mln_precondition(exact(nbh).is_valid()); + + (void) accu; + (void) input; + (void) val; + (void) nbh; + (void) nlabels; + } + + } // end of namespace mln::labeling::internal + + + + namespace impl + { + + // Generic functor. + + template <typename I, typename L, typename A> + struct value_and_compute_functor + { + typedef mln_psite(I) P; + + util::array<mln_result(A)> result_; + util::array<A> accus_; + + const I& input; + const mln_value(I)& val; + + typedef mln_result(A) accu_result; + typedef mln_argument(A) accu_argument; + typedef util::couple<util::array<accu_result>, + util::array<A> > result; + + + // Requirements from mln::canvas::labeling. + + typedef mln_domain(I) S; + + // Generic implementation + + void init() {} + 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&, const P&) {} + void init_attr(const P&) {} + void merge_attr(const P&, const P&) {} + void set_new_label(const P& p, const L& l) + { + accus_.append(A()); + process__(accu_argument(), p, l); + } + void set_label(const P& p, const L& l) { process__(accu_argument(), p, l); }; + void finalize() { convert::from_to(accus_, result_); } + + + + // Fastest implementation + + void init_() { accus_.append(A()); } + 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, unsigned) {} + void init_attr_(unsigned) {} + void merge_attr_(unsigned, unsigned) {} + void set_new_label_(unsigned p, const L& l) + { + accus_.append(A()); + process__(accu_argument(), p, l); + }; + void set_label_(unsigned p, const L& l) { process__(accu_argument(), p, l); }; + void finalize_() { convert::from_to(accus_, result_); } + + // end of Requirements. + + + + value_and_compute_functor(const Image<I>& input_, const mln_value(I)& val) + : input(exact(input_)), + val(val) + { + } + + + private: + inline + void process__(const unsigned&, unsigned p, const L& l) + { + accus_[l].take(p); + } + + inline + void process__(const mln_psite(I)&, unsigned p, const L& l) + { + accus_[l].take(input.point_at_index(p)); + } + + + inline + void process__(const mln_psite(I)&, const mln_site(I)& p, const L& l) + { + accus_[l].take(p); + } + + inline + void process__(const mln_value(I)&, const mln_site(I)&, const L& l) + { + accus_[l].take(l); + } + + template <typename V> + inline + void process__(const V&, const mln_site(I)&, const L& l) + { + mlc_abort(V)::check(); + } + + + }; + + } // end of namespace mln::labeling::impl + + + + + // Facade. + + template <typename I, typename N, typename L, typename A> + util::couple<mln_ch_value(I,L), + util::couple<util::array<mln_result(A)>, + util::array<A> > > + value_and_compute(const Image<I>& input, const mln_value(I)& val, + const Neighborhood<N>& nbh, L& nlabels, + const Accumulator<A>& accu) + { + trace::entering("labeling::value_and_compute"); + + internal::value_and_compute_tests(input, val, nbh, nlabels, accu); + + typedef mln_ch_value(I,L) out_t; + typedef impl::value_and_compute_functor<I, L, A> func_t; + func_t f(input, val); + out_t output = canvas::labeling::video(input, nbh, nlabels, f); + + util::couple<out_t, typename func_t::result> + result = make::couple(output, + make::couple(f.result_, f.accus_)); + + + trace::exiting("labeling::value_and_compute"); + return result; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::labeling + +} // end of namespace mln + + +#endif // ! MLN_LABELING_VALUE_AND_COMPUTE_HH -- 1.5.6.5
participants (1)
-
Guillaume Lazzara