
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from 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. mln/core/internal/site_iterator_base.hh | 24 +-- mln/labeling/compute.hh | 34 ++--- mln/set/compute.hh | 69 ++++++++-- mln/set/compute_with_weights.hh | 206 ++++++++++++++++++++++++++------ tests/set/compute.cc | 3 tests/set/compute_with_weights.cc | 51 ++++++- 6 files changed, 297 insertions(+), 90 deletions(-) Index: mln/core/internal/site_iterator_base.hh --- mln/core/internal/site_iterator_base.hh (revision 3774) +++ mln/core/internal/site_iterator_base.hh (working copy) @@ -68,14 +68,15 @@ /// 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 @@ 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 { Index: mln/set/compute_with_weights.hh --- mln/set/compute_with_weights.hh (revision 3772) +++ mln/set/compute_with_weights.hh (working copy) @@ -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,18 +26,20 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_SET_COMPUTE_HH -# define MLN_SET_COMPUTE_HH +#ifndef MLN_SET_COMPUTE_WITH_WEIGHTS_HH +# define MLN_SET_COMPUTE_WITH_WEIGHTS_HH -/// \file mln/set/compute.hh +/// \file mln/set/compute_with_weights.hh /// -/// Compute an accumulator on a site set or a binary image. +/// Compute an accumulator on a site set described by an image. /// -/// \todo Add a version with a binary image as input. +/// \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 @@ -45,64 +48,201 @@ namespace set { - /// Compute an accumulator onto the sites of a site set. + /// Compute an accumulator on a site set described by an image. /// /// \param[in] a An accumulator. - /// \param[in] s A site set. + /// \param[in] w An image of weights (a site -> a weight). /// \return The accumulator result. - /// - template <typename A, typename S> + // + template <typename A, typename I> mln_result(A) - compute(const Accumulator<A>& a, const Site_Set<S>& s); + 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 onto the sites of a site set. + + /// 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 S> - mln_accu_with(A, mln_site(S))::result - compute(const Meta_Accumulator<A>& a, const Site_Set<S>& s); + 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 - template <typename A, typename S> + + // 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(const Accumulator<A>& a_, const Site_Set<S>& s_) + compute_with_weights(const Accumulator<A>& a_, const Image<I>& w_) { - trace::entering("set::compute"); + 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 S& s = exact(s_); + const I& w = exact(w_); - mln_piter(S) p(s); + a.init(); + mln_piter(I) p(w.domain()); for_all(p) - a.take(p); + a.take_n_times(w(p), p); - trace::exiting("set::compute"); + trace::exiting("set::impl::generic::compute_with_weights"); return a.to_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_) + 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"); + trace::entering("set::impl::generic::compute_with_weights"); - mln_accu_with(A, mln_site(S)) a = accu::unmeta(exact(a_), mln_site(S)()); - const S& s = exact(s_); + 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(); - mln_piter(S) p(s); + 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) - a.take(p); + accus[label(p)].take_n_times(w(p), p); - trace::exiting("set::compute"); - return a.to_result(); + 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 @@ -112,4 +252,4 @@ } // end of namespace mln -#endif // ! MLN_SET_COMPUTE_HH +#endif // ! MLN_SET_COMPUTE_WITH_WEIGHTS_HH Property changes on: mln/set/compute_with_weights.hh ___________________________________________________________________ Added: svn:mergeinfo Index: mln/set/compute.hh --- mln/set/compute.hh (revision 3774) +++ mln/set/compute.hh (working copy) @@ -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 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 @@ # 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::compute"); + 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::compute"); + 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) + { + trace::entering("set::compute"); + + mlc_converts_to(mln_site(S), mln_argument(A))::check(); + + mln_result(A) r = impl::generic::compute(a, s); + + trace::exiting("set::compute"); + 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 Index: mln/labeling/compute.hh --- mln/labeling/compute.hh (revision 3774) +++ mln/labeling/compute.hh (working copy) @@ -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 @@ /// \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 @@ 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 @@ 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, Index: tests/set/compute.cc --- tests/set/compute.cc (revision 3774) +++ tests/set/compute.cc (working copy) @@ -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 Index: tests/set/compute_with_weights.cc --- tests/set/compute_with_weights.cc (revision 3772) +++ tests/set/compute_with_weights.cc (working copy) @@ -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)); + } + } Property changes on: tests/set/compute_with_weights.cc ___________________________________________________________________ Added: svn:mergeinfo