
* milena/mln/accu/center.hh: Add nsites() member. * milena/mln/accu/pair.hh: Provide access to the underlying accus. * milena/mln/accu/stat/variance.hh: Use literal::zero. * milena/mln/core/internal/labeled_image_base.hh: Indent. * milena/mln/core/site_set/box.hh: Rename center() as pcenter(). * milena/mln/labeling/blobs_and_compute.hh: Return the array of accumulators. * milena/mln/labeling/colorize.hh: Make sure a color is not used twice in the same image. * milena/mln/labeling/compute.hh: Add a new overload. * milena/mln/transform/influence_zone_geodesic.hh: Fix a segmentation fault when an image had a border. --- milena/ChangeLog | 25 +++++ milena/mln/accu/center.hh | 14 +++- milena/mln/accu/pair.hh | 26 ++++++ milena/mln/accu/stat/variance.hh | 4 +- milena/mln/core/internal/labeled_image_base.hh | 2 +- milena/mln/core/site_set/box.hh | 4 +- milena/mln/labeling/blobs_and_compute.hh | 14 ++- milena/mln/labeling/colorize.hh | 51 ++++++++--- milena/mln/labeling/compute.hh | 111 +++++++++++++++++++---- milena/mln/transform/influence_zone_geodesic.hh | 13 +-- 10 files changed, 214 insertions(+), 50 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 73b9647..ec2ef35 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,28 @@ +2010-02-19 Guillaume Lazzara <z@lrde.epita.fr> + + Small fixes in Milena. + + * milena/mln/accu/center.hh: Add nsites() member. + + * milena/mln/accu/pair.hh: Provide access to the underlying accus. + + * milena/mln/accu/stat/variance.hh: Use literal::zero. + + * milena/mln/core/internal/labeled_image_base.hh: Indent. + + * milena/mln/core/site_set/box.hh: Rename center() as pcenter(). + + * milena/mln/labeling/blobs_and_compute.hh: Return the array of + accumulators. + + * milena/mln/labeling/colorize.hh: Make sure a color is not used + twice in the same image. + + * milena/mln/labeling/compute.hh: Add a new overload. + + * milena/mln/transform/influence_zone_geodesic.hh: Fix a + segmentation fault when an image had a border. + 2009-12-14 Guillaume Lazzara <z@lrde.epita.fr> Add rbg_to_int_u function. diff --git a/milena/mln/accu/center.hh b/milena/mln/accu/center.hh index 7cfbe78..a3622b3 100644 --- a/milena/mln/accu/center.hh +++ b/milena/mln/accu/center.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009, 2010 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -73,6 +74,9 @@ namespace mln /// Check whether this accu is able to return a result. bool is_valid() const; + /// Return the number of sites taken in consideration. + unsigned nsites() const; + protected: algebra::vec<P::dim, mln_sum(mln_coord(P))> center_; unsigned nsites_; @@ -158,6 +162,14 @@ namespace mln return nsites_ > 0; } + template <typename P, typename V> + inline + unsigned + center<P,V>::nsites() const + { + return nsites_; + } + # endif // ! MLN_INCLUDE_ONLY diff --git a/milena/mln/accu/pair.hh b/milena/mln/accu/pair.hh index bb0b691..11f4dc6 100644 --- a/milena/mln/accu/pair.hh +++ b/milena/mln/accu/pair.hh @@ -81,9 +81,16 @@ namespace mln void get_result(result_1& r1, result_2& r2) const; /// \} + /// Return the result of the first accumulator. mln_result(A1) first() const; + /// Return the result of the second accumulator. mln_result(A2) second() const; + /// Return the first accumulator. + A1 first_accu() const; + /// Return the second accumulator. + A2 second_accu() const; + /// Check whether this accu is able to return a result. /// Always true here. bool is_valid() const; @@ -194,6 +201,25 @@ namespace mln return a2_.to_result(); } + + + template <typename A1, typename A2, typename T> + inline + A1 + pair<A1,A2,T>::first_accu() const + { + return a1_; + } + + template <typename A1, typename A2, typename T> + inline + A2 + pair<A1,A2,T>::second_accu() const + { + return a2_; + } + + template <typename A1, typename A2, typename T> inline bool diff --git a/milena/mln/accu/stat/variance.hh b/milena/mln/accu/stat/variance.hh index 23e7731..c19761e 100644 --- a/milena/mln/accu/stat/variance.hh +++ b/milena/mln/accu/stat/variance.hh @@ -125,7 +125,7 @@ namespace mln variance<T,S,R>::init() { n_ = 0; - sum_ = sum2_ = 0; + sum_ = sum2_ = literal::zero; } template <typename T, typename S, typename R> @@ -187,7 +187,7 @@ namespace mln variance<T,S,R>::mean() const { if (n_ == 0u) - return 0; // Safety. + return literal::zero; // Safety. return sum_ / n_; } diff --git a/milena/mln/core/internal/labeled_image_base.hh b/milena/mln/core/internal/labeled_image_base.hh index 9e2d314..86bb077 100644 --- a/milena/mln/core/internal/labeled_image_base.hh +++ b/milena/mln/core/internal/labeled_image_base.hh @@ -310,7 +310,7 @@ namespace mln const util::array<typename labeled_image_base<I,E>::bbox_t>& labeled_image_base<I,E>::bboxes() const { - return this->data_->bboxes_; + return this->data_->bboxes_; } diff --git a/milena/mln/core/site_set/box.hh b/milena/mln/core/site_set/box.hh index 75fb91c..077ac3d 100644 --- a/milena/mln/core/site_set/box.hh +++ b/milena/mln/core/site_set/box.hh @@ -143,7 +143,7 @@ namespace mln box<P> to_larger(unsigned b) const; /// Return the approximated central site of this box. - P center() const; + P pcenter() const; /// Test that the box owns valid data, i.e., is initialized and /// with pmin being 'less-than' pmax. @@ -390,7 +390,7 @@ namespace mln template <typename P> inline P - box<P>::center() const + box<P>::pcenter() const { mln_precondition(is_valid()); P center; diff --git a/milena/mln/labeling/blobs_and_compute.hh b/milena/mln/labeling/blobs_and_compute.hh index 4d5d5d8..b76b62a 100644 --- a/milena/mln/labeling/blobs_and_compute.hh +++ b/milena/mln/labeling/blobs_and_compute.hh @@ -53,7 +53,9 @@ namespace mln */ template <typename I, typename N, typename L, typename A> - util::couple<mln_ch_value(I, L), util::array<mln_result(A)> > + util::couple<mln_ch_value(I,L), + util::couple<util::array<mln_result(A)>, + util::array<A> > > blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, const Accumulator<A>& accu); @@ -72,7 +74,8 @@ namespace mln { typedef mln_result(A) accu_result; typedef mln_argument(A) accu_argument; - typedef util::array<accu_result> result; + typedef util::couple<util::array<accu_result>, + util::array<A> > result; void init() { @@ -133,7 +136,9 @@ namespace mln template <typename I, typename N, typename L, typename A> - util::couple<mln_ch_value(I,L), util::array<mln_result(A)> > + util::couple<mln_ch_value(I,L), + util::couple<util::array<mln_result(A)>, + util::array<A> > > blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels, const Accumulator<A>& accu) { @@ -151,7 +156,8 @@ namespace mln output = canvas::labeling::blobs(input, nbh, nlabels, functor); util::couple<out_t, typename func_t::result> - result = make::couple(output, functor.result_); + result = make::couple(output, + make::couple(functor.result_, functor.accus_)); trace::exiting("labeling::blobs_and_compute"); return result; diff --git a/milena/mln/labeling/colorize.hh b/milena/mln/labeling/colorize.hh index 26a78df..69493d5 100644 --- a/milena/mln/labeling/colorize.hh +++ b/milena/mln/labeling/colorize.hh @@ -103,11 +103,9 @@ namespace mln unsigned random_number() { - static unsigned last = 1; + unsigned last = colorize_::min_value + (colorize_::max_value - colorize_::min_value + 1) * rand(); - last = (323 * last + 6603) % 1025; - - return colorize_::min_value + last % colorize_::max_value; + return math::min(colorize_::min_value + last % colorize_::max_value, colorize_::max_value); } @@ -120,17 +118,42 @@ namespace mln mln::value::rgb<n> random_color(const mln::value::rgb<n>&) { - // Make sure the numbers are generated in the same order - // whatever the compiler used. - // For instance, ICC does not compute function arguments in - // the same order as GCC does. - unsigned - red = random_number(), - green = random_number(), + static unsigned + nelements = colorize_::max_value - colorize_::min_value + 1; + static util::array<util::set<unsigned> > + red_(nelements), + green_(nelements); + + unsigned red, green, blue; + + unsigned ntries = 0; + do + { + red = random_number(); + ++ntries; + } + while (red_[red - colorize_::min_value].nelements() == nelements + && ntries < nelements); + + if (ntries == nelements) + { + trace::warning("labeling::colorize - Can't find a new unique color. Returning black."); + return literal::black; + } + + + do + green = random_number(); + while (red_[red - colorize_::min_value].has(green) + || green_[green - colorize_::min_value].nelements() == nelements); + red_[red - colorize_::min_value].insert(green); + + do blue = random_number(); - return mln::value::rgb<n>(red, - green, - blue); + while (green_[green - colorize_::min_value].has(blue)); + green_[green - colorize_::min_value].insert(blue); + + return mln::value::rgb<n>(red, green, blue); } } diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh index d29242f..4f0d97d 100644 --- a/milena/mln/labeling/compute.hh +++ b/milena/mln/labeling/compute.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -60,23 +61,6 @@ namespace mln /// Compute an accumulator onto the pixel values of the image \p input. /// for each component of the image \p label. /// - /// \param[in] a An array of accumulator. - /// \param[in] input The input image. - /// \param[in] label The labeled image. - /// \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(util::array<A>& a, - const Image<I>& input, - 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 An accumulator. /// \param[in] input The input image. /// \param[in] label The labeled image. @@ -138,6 +122,23 @@ namespace mln 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 An array of accumulator. + /// \param[in] input The input image. + /// \param[in] label The labeled image. + /// \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(util::array<A>& a, + const Image<I>& input, + const Image<L>& label, + const mln_value(L)& nlabels); + + # ifndef MLN_INCLUDE_ONLY @@ -221,6 +222,49 @@ namespace mln return res; } + /// Generic implementation of labeling::compute. + /// + /// \param[in] accus_ An array of accumulators. If the size is + /// set to nlabels + 1, the accumulators are + /// considered as initialized. Otherwise, + /// the size is adjusted. + /// \param[in] label_ The labeled image. + /// \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> + inline + util::array<mln_result(A)> + compute(util::array<A>& accus, + const Image<L>& label_, + const mln_value(L)& nlabels) + { + trace::entering("labeling::impl::generic::compute"); + internal::compute_tests(A(), label_, nlabels); + + if (static_cast<unsigned>(nlabels) + 1 != accus.size()) + { + accus.resize(0); // Make sure all the accumulators are + // re-initialized when resizing on next + // line. + accus.resize(static_cast<unsigned>(nlabels) + 1); + } + + const L& label = exact(label_); + + mln_piter(L) p(label.domain()); + for_all(p) + accus[label(p)].take(p); + + util::array<mln_result(A)> res; + convert::from_to(accus, res); + + trace::exiting("labeling::impl::generic::compute"); + return res; + } + + /// Generic implementation of labeling::compute. /// @@ -343,6 +387,15 @@ namespace mln return impl::generic::compute(a, input, label, nlabels); } + template <typename A, typename L> + inline + util::array<mln_result(A)> + compute_dispatch(util::array<A>& accus, + const Image<L>& label, + const mln_value(L)& nlabels) + { + return impl::generic::compute(accus, label, nlabels); + } } // end of namespace mln::labeling::internal @@ -406,6 +459,28 @@ namespace mln template <typename A, typename L> inline util::array<mln_result(A)> + compute(util::array<A>& accus, + const Image<L>& label, + const mln_value(L)& nlabels) + { + trace::entering("labeling::compute"); + + internal::compute_tests(A(), label, nlabels); + + typedef util::array<mln_result(A)> R; + R res = internal::compute_dispatch(accus, label, nlabels); + + mln_postcondition(res.nelements() == static_cast<unsigned>(nlabels) + 1); + + trace::exiting("labeling::compute"); + return res; + } + + + + template <typename A, typename L> + inline + util::array<mln_result(A)> compute(const Accumulator<A>& a, const Image<L>& label, const mln_value(L)& nlabels) diff --git a/milena/mln/transform/influence_zone_geodesic.hh b/milena/mln/transform/influence_zone_geodesic.hh index 4d7255a..b9a763f 100644 --- a/milena/mln/transform/influence_zone_geodesic.hh +++ b/milena/mln/transform/influence_zone_geodesic.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -104,16 +105,12 @@ namespace mln const N& nbh = exact(nbh_); internal::influence_zone_geodesic_tests(input, nbh); - mln_precondition(input.domain().pmin() == literal::origin); std::queue<mln_value(I)*> q; mln_concrete(I) output; util::array<int> dp = offsets_wrt(input, nbh); const unsigned n_nbhs = dp.nelements(); - const unsigned - ncols = input.ncols(), - first_offset = input.border() * (ncols + 2 * input.border() + 1); // Initialization. { @@ -124,9 +121,9 @@ namespace mln extension::fill(output, 1); // in propagation const unsigned nelts = input.nelements(); - const mln_value(I)* p_i = & input.at_(0, 0); - mln_value(I)* p_o = & output.at_(0, 0); - for (unsigned i = first_offset; i < nelts; ++i, ++p_i, ++p_o) + const mln_value(I)* p_i = input.buffer(); + mln_value(I)* p_o = output.buffer(); + for (unsigned i = 0; i < nelts; ++i, ++p_i, ++p_o) { if (*p_i == 0) continue; -- 1.5.6.5