[PATCH 14/31] Add 'set compute accumulator with weights'.

* mln/core/internal/site_iterator_base.hh (operator): Remove conversion; already present (inherited). Add a commentary about that. * mln/set/compute.hh: Copy to... * mln/set/compute_with_weights.hh: ...this new file. Modify. * mln/labeling/compute.hh: . * tests/set/compute.cc: Fix copyright. * tests/set/compute_with_weights.cc: New. --- milena/ChangeLog | 14 + milena/mln/core/internal/site_iterator_base.hh | 24 +-- milena/mln/labeling/compute.hh | 34 ++-- milena/mln/set/compute.hh | 79 +++++-- milena/mln/set/compute_with_weights.hh | 255 ++++++++++++++++++++ milena/tests/set/compute.cc | 3 +- .../set/{compute.cc => compute_with_weights.cc} | 51 ++++- 7 files changed, 398 insertions(+), 62 deletions(-) create mode 100644 milena/mln/set/compute_with_weights.hh copy milena/tests/set/{compute.cc => compute_with_weights.cc} (54%) diff --git a/milena/ChangeLog b/milena/ChangeLog index d8e82fc..d717702 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,17 @@ +2009-05-07 Thierry Geraud <thierry.geraud@lrde.epita.fr> + + Add 'set compute accumulator with weights'. + + * mln/core/internal/site_iterator_base.hh + (operator): Remove conversion; already present (inherited). + Add a commentary about that. + * mln/set/compute.hh: Copy to... + * mln/set/compute_with_weights.hh: ...this new file. + Modify. + * mln/labeling/compute.hh: . + * tests/set/compute.cc: Fix copyright. + * tests/set/compute_with_weights.cc: New. + 2009-05-07 Fabien Freling <fabien.freling@lrde.epita.fr> Fix display_edge() and float01_ constructors. diff --git a/milena/mln/core/internal/site_iterator_base.hh b/milena/mln/core/internal/site_iterator_base.hh index 893a9b2..15cb023 100644 --- a/milena/mln/core/internal/site_iterator_base.hh +++ b/milena/mln/core/internal/site_iterator_base.hh @@ -68,14 +68,15 @@ namespace mln /// Return the site it points to (as a Site_Proxy). const mln_site(S)& to_site() const; - /// Conversion towards the site it designates (as a Site_Proxy). - /// - /// \warning This is a final method; iterator classes should not - /// re-defined this method. - /// - /// \pre The iterator is valid. - /// - operator mln_site(S)() const; + + // Technical note: + // + // A conversion operator towards the site it designates is + // not required since it is inherited from 'proxy_impl'. + // Defining '::operator mln_site(S)() const' here can lead to + // ambiguities in very special cases since we inherit a couple + // of conversions (const and non-const) + /// Give the subject (required by the Proxy interface). const mln_psite(S)& subj_(); @@ -107,13 +108,6 @@ namespace mln template <typename S, typename E> inline - site_iterator_base<S, E>::operator mln_site(S)() const - { - return this->to_site(); - } - - template <typename S, typename E> - inline const mln_site(S)& site_iterator_base<S, E>::to_site() const { diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh index 3c07233..9b99c2f 100644 --- a/milena/mln/labeling/compute.hh +++ b/milena/mln/labeling/compute.hh @@ -35,6 +35,9 @@ /// of an image. /// /// \todo write fastest version. +/// +/// \todo Move versions without 'input' as arg into mln::set +/// and change 'input' from Image to Site_Set! # include <mln/core/concept/image.hh> # include <mln/core/concept/accumulator.hh> @@ -55,10 +58,9 @@ namespace mln /// \param[in] a An accumulator. /// \param[in] input The input image. /// \param[in] label The labeled image. - /// \param[in] input The number of component in \p label. - /// \return A mln::p_array of accumulator result. One result per component in - /// \p label. - /// + /// \param[in] nlabels The number of labels in \p label. + /// \return A mln::p_array of accumulator result (one result per label). + // template <typename A, typename I, typename L> util::array<mln_result(A)> compute(const Accumulator<A>& a, @@ -66,16 +68,16 @@ namespace mln const Image<L>& label, const mln_value(L)& nlabels); + /// Compute an accumulator onto the pixel values of the image \p input. /// for each component of the image \p label. /// /// \param[in] a A meta-accumulator. /// \param[in] input The input image. /// \param[in] label The labeled image. - /// \param[in] input The number of component in \p label. - /// \return A mln::p_array of accumulator result. One result per component in - /// \p label. - /// + /// \param[in] nlabels The number of labels in \p label. + /// \return A mln::p_array of accumulator result (one result per label). + // template <typename A, typename I, typename L> util::array<mln_accu_with(A, mln_value(I))::result> compute(const Meta_Accumulator<A>& a, @@ -83,30 +85,30 @@ namespace mln const Image<L>& label, const mln_value(L)& nlabels); + /// Compute an accumulator onto the pixel sites of each component domain of /// \p label. /// /// \param[in] a An accumulator. /// \param[in] label The labeled image. - /// \param[in] input The number of component in \p label. - /// \return A mln::p_array of accumulator result. One result per component in - /// \p label. - /// + /// \param[in] nlabels The number of labels in \p label. + /// \return A mln::p_array of accumulator result (one result per label). + // template <typename A, typename L> util::array<mln_result(A)> compute(const Accumulator<A>& a, const Image<L>& label, const mln_value(L)& nlabels); + /// Compute an accumulator onto the pixel sites of each component domain of /// \p label. /// /// \param[in] a A meta-accumulator. /// \param[in] label The labeled image. - /// \param[in] input The number of component in \p label. - /// \return A mln::p_array of accumulator result. One result per component in - /// \p label. - /// + /// \param[in] nlabels The number of labels in \p label. + /// \return A mln::p_array of accumulator result (one result per label). + // template <typename A, typename L> util::array<mln_accu_with(A, mln_psite(L))::result> compute(const Meta_Accumulator<A>& a, diff --git a/milena/mln/set/compute.hh b/milena/mln/set/compute.hh index 0942a4f..6dbc9a1 100644 --- a/milena/mln/set/compute.hh +++ b/milena/mln/set/compute.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 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 @@ -30,9 +31,7 @@ /// \file mln/set/compute.hh /// -/// Compute an accumulator on a site set or a binary image. -/// -/// \todo Add a version with a binary image as input. +/// Compute an accumulator on a site set. # include <mln/core/concept/meta_accumulator.hh> # include <mln/core/concept/image.hh> @@ -45,23 +44,23 @@ namespace mln namespace set { - /// Compute an accumulator onto the sites of a site set. + /// Compute an accumulator onto a site set. /// /// \param[in] a An accumulator. /// \param[in] s A site set. /// \return The accumulator result. - /// + // template <typename A, typename S> mln_result(A) compute(const Accumulator<A>& a, const Site_Set<S>& s); - /// Compute an accumulator onto the sites of a site set. + /// Compute an accumulator onto a site set. /// /// \param[in] a A meta-accumulator. /// \param[in] s A site set. // \return The accumulator result. - /// + // template <typename A, typename S> mln_accu_with(A, mln_site(S))::result compute(const Meta_Accumulator<A>& a, const Site_Set<S>& s); @@ -70,39 +69,75 @@ namespace mln # ifndef MLN_INCLUDE_ONLY + + // Implementation. + + + namespace impl + { + + namespace generic + { + + template <typename A, typename S> + inline + mln_result(A) + compute(const Accumulator<A>& a_, const Site_Set<S>& s_) + { + trace::entering("set::impl::generic::compute"); + + mlc_converts_to(mln_site(S), mln_argument(A))::check(); + + A a = exact(a_); + const S& s = exact(s_); + + a.init(); + mln_piter(S) p(s); + for_all(p) + a.take(p); + + trace::exiting("set::impl::generic::compute"); + return a.to_result(); + } + + } // end of namespace mln::set::impl::generic + + } // end of namespace mln::set::impl + + + + // Facades. + + template <typename A, typename S> inline mln_result(A) - compute(const Accumulator<A>& a_, const Site_Set<S>& s_) + compute(const Accumulator<A>& a, const Site_Set<S>& s) { trace::entering("set::compute"); - A a = exact(a_); - const S& s = exact(s_); + mlc_converts_to(mln_site(S), mln_argument(A))::check(); - mln_piter(S) p(s); - for_all(p) - a.take(p); + mln_result(A) r = impl::generic::compute(a, s); trace::exiting("set::compute"); - return a.to_result(); + return r; } + template <typename A, typename S> mln_accu_with(A, mln_site(S))::result - compute(const Meta_Accumulator<A>& a_, const Site_Set<S>& s_) + compute(const Meta_Accumulator<A>& a, const Site_Set<S>& s) { trace::entering("set::compute"); - mln_accu_with(A, mln_site(S)) a = accu::unmeta(exact(a_), mln_site(S)()); - const S& s = exact(s_); + typedef mln_accu_with(A, mln_site(S)) A_; + A_ a_ = accu::unmeta(exact(a), mln_site(S)()); - mln_piter(S) p(s); - for_all(p) - a.take(p); + mln_result(A_) r = impl::generic::compute(a_, s); trace::exiting("set::compute"); - return a.to_result(); + return r; } # endif // ! MLN_INCLUDE_ONLY diff --git a/milena/mln/set/compute_with_weights.hh b/milena/mln/set/compute_with_weights.hh new file mode 100644 index 0000000..1a4107e --- /dev/null +++ b/milena/mln/set/compute_with_weights.hh @@ -0,0 +1,255 @@ +// Copyright (C) 2008, 2009 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_SET_COMPUTE_WITH_WEIGHTS_HH +# define MLN_SET_COMPUTE_WITH_WEIGHTS_HH + +/// \file mln/set/compute_with_weights.hh +/// +/// Compute an accumulator on a site set described by an image. +/// +/// \todo Add a meta version for the labeling variation. + +# include <mln/core/concept/meta_accumulator.hh> +# include <mln/core/concept/image.hh> +# include <mln/core/concept/site_set.hh> +# include <mln/util/array.hh> +# include <mln/convert/from_to.hh> + + +namespace mln +{ + + namespace set + { + + /// Compute an accumulator on a site set described by an image. + /// + /// \param[in] a An accumulator. + /// \param[in] w An image of weights (a site -> a weight). + /// \return The accumulator result. + // + template <typename A, typename I> + mln_result(A) + compute_with_weights(const Accumulator<A>& a, const Image<I>& w); + + + template <typename A, typename I, typename L> + util::array<mln_result(A)> + compute_with_weights(const Accumulator<A>& a, + const Image<I>& w, + const Image<L>& label, + const mln_value(L)& nlabels); + + + /// Compute an accumulator on a site set described by an image. + /// + /// \param[in] a A meta-accumulator. + /// \param[in] s A site set. + // \return The accumulator result. + /// + template <typename A, typename I> + mln_accu_with(A, mln_site(I))::result + compute_with_weights(const Meta_Accumulator<A>& a, const Image<I>& w); + + + +# ifndef MLN_INCLUDE_ONLY + + + // Tests. + + + namespace internal + { + + template <typename A, typename I, typename L> + void + compute_with_weights_tests(const Accumulator<A>& a_, + const Image<I>& w_, + const Image<L>& label_) + { + const A& a = exact(a_); + const I& w = exact(w_); + const L& label = exact(label_); + + mln_precondition(w.is_valid()); + mln_precondition(label.is_valid()); + mln_precondition(w.domain() <= label.domain()); + + (void) a_; + (void) w_; + (void) label_; + } + + } // end of namespace mln::internal + + + + // Implementations. + + + namespace impl + { + + namespace generic + { + + template <typename A, typename I> + inline + mln_result(A) + compute_with_weights(const Accumulator<A>& a_, const Image<I>& w_) + { + trace::entering("set::impl::generic::compute_with_weights"); + + mlc_converts_to(mln_site(I), mln_argument(A))::check(); + mlc_converts_to(mln_value(I), unsigned)::check(); + + A a = exact(a_); + const I& w = exact(w_); + + a.init(); + mln_piter(I) p(w.domain()); + for_all(p) + a.take_n_times(w(p), p); + + trace::exiting("set::impl::generic::compute_with_weights"); + return a.to_result(); + } + + template <typename A, typename I, typename L> + util::array<mln_result(A)> + compute_with_weights(const Accumulator<A>& a_, + const Image<I>& w_, + const Image<L>& label_, + const mln_value(L)& nlabels) + { + trace::entering("set::impl::generic::compute_with_weights"); + + mlc_equal(mln_site(I), mln_site(L))::check(); + mlc_converts_to(mln_site(I), mln_argument(A))::check(); + mlc_converts_to(mln_value(I), unsigned)::check(); + + A a = exact(a_); + const I& w = exact(w_); + const L& label = exact(label_); + + internal::compute_with_weights_tests(a, w, label); + + util::array<A> accus(static_cast<unsigned>(nlabels) + 1, a); + + mln_piter(I) p(w.domain()); + for_all(p) + accus[label(p)].take_n_times(w(p), p); + + util::array<mln_result(A)> r; + convert::from_to(accus, r); + + trace::exiting("set::impl::generic::compute_with_weights"); + return r; + } + + } // end of namespace mln::set::impl::generic + + } // end of namespace mln::set::impl + + + + // Facades. + + + template <typename A, typename I> + inline + mln_result(A) + compute_with_weights(const Accumulator<A>& a, const Image<I>& w) + { + trace::entering("set::compute_with_weights"); + + mlc_converts_to(mln_site(I), mln_argument(A))::check(); + mlc_converts_to(mln_value(I), unsigned)::check(); + mln_precondition(exact(w).is_valid()); + + mln_result(A) r = impl::generic::compute_with_weights(a, w); + + trace::exiting("set::compute_with_weights"); + return r; + } + + + template <typename A, typename I, typename L> + util::array<mln_result(A)> + compute_with_weights(const Accumulator<A>& a, + const Image<I>& w, + const Image<L>& label, + const mln_value(L)& nlabels) + { + trace::entering("set::compute_with_weights"); + + mlc_equal(mln_site(I), mln_site(L))::check(); + mlc_converts_to(mln_site(I), mln_argument(A))::check(); + mlc_converts_to(mln_value(I), unsigned)::check(); + + internal::compute_with_weights_tests(a, w, label); + + util::array<mln_result(A)> r; + r = impl::generic::compute_with_weights(a, w, label, nlabels); + + trace::exiting("set::compute_with_weights"); + return r; + } + + + template <typename A, typename I> + inline + mln_accu_with(A, mln_site(I))::result + compute_with_weights(const Meta_Accumulator<A>& a, const Image<I>& w) + { + trace::entering("set::compute_with_weights"); + + mlc_converts_to(mln_value(I), unsigned)::check(); + + mln_precondition(exact(w).is_valid()); + + typedef mln_site(I) P; + typedef mln_accu_with(A, P) A_; + A_ a_ = accu::unmeta(exact(a), P()); + + mln_result(A_) r = impl::generic::compute_with_weights(a_, w); + + trace::exiting("set::compute_with_weights"); + return r; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::set + +} // end of namespace mln + + +#endif // ! MLN_SET_COMPUTE_WITH_WEIGHTS_HH diff --git a/milena/tests/set/compute.cc b/milena/tests/set/compute.cc index 64497b1..fd426e8 100644 --- a/milena/tests/set/compute.cc +++ b/milena/tests/set/compute.cc @@ -1,4 +1,5 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 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 diff --git a/milena/tests/set/compute.cc b/milena/tests/set/compute_with_weights.cc similarity index 54% copy from milena/tests/set/compute.cc copy to milena/tests/set/compute_with_weights.cc index 64497b1..80548e9 100644 --- a/milena/tests/set/compute.cc +++ b/milena/tests/set/compute_with_weights.cc @@ -1,4 +1,5 @@ -// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 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 @@ -25,20 +26,54 @@ // reasons why the executable file might be covered by the GNU General // Public License. -/// \file tests/set/compute.cc +/// \file tests/set/compute_with_weights.cc /// -/// Tests on mln::set::compute. +/// Tests on mln::set::compute_with_weights. #include <mln/core/site_set/p_set.hh> -#include <mln/core/alias/point2d.hh> -#include <mln/accu/count.hh> -#include <mln/set/compute.hh> +#include <mln/core/image/image2d.hh> +#include <mln/accu/center.hh> +#include <mln/set/compute_with_weights.hh> int main() { using namespace mln; - p_set<point2d> s; - mln_assertion(set::compute(accu::meta::count(), s) == 0); + { + bool vals[] = { 1, 1, 0, + 1, 1, 1, + 0, 1, 1 }; + image2d<bool> msk = make::image2d(vals); + accu::center<point2d,point2d> a; + mln_assertion(set::compute_with_weights(a, msk) == point2d(1,1)); + } + + { + unsigned vals[] = { 3, 1, 0, + 1, 5, 1, + 0, 1, 3 }; + image2d<unsigned> w = make::image2d(vals); + accu::center<point2d,point2d> a; + mln_assertion(set::compute_with_weights(a, w) == point2d(1,1)); + } + + { + unsigned ws[] = { 1, 5, 0, + 0, 5, 0, + 0, 5, 1 }; + image2d<unsigned> w = make::image2d(ws); + + unsigned ls[] = { 0, 1, 2, + 0, 1, 2, + 0, 1, 2 }; + image2d<unsigned> l = make::image2d(ls); + + accu::center<point2d,point2d> a; + util::array<point2d> p = set::compute_with_weights(a, w, l, 2); + + for (unsigned l = 0; l <= 2; ++l) + mln_assertion(p[l] == point2d(l, l)); + } + } -- 1.6.1.2
participants (1)
-
Roland Levillain