
* mln/core/site_set/box.hh: Add shrink() method. * mln/data/compute_in_inner_border.hh: Rewrite and add overloads. * mln/trait/routine/mean.hh: New trait for builtins. * mln/value/interval.hh: Fix overflow while counting elements. * mln/value/intsub.hh: Add a constructor based on int_u8. * mln/value/iota.hh: Add new specializations for builtins. --- milena/ChangeLog | 16 +++++ milena/mln/core/site_set/box.hh | 33 +++++++++- milena/mln/data/compute_in_inner_border.hh | 95 +++++++++------------------- milena/mln/trait/routine/mean.hh | 12 ++++ milena/mln/value/interval.hh | 12 +++- milena/mln/value/intsub.hh | 9 +++ milena/mln/value/iota.hh | 27 ++++++++ 7 files changed, 136 insertions(+), 68 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 1bfdd14..2a3885d 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,21 @@ 2012-10-24 Guillaume Lazzara <z@lrde.epita.fr> + Some fixes. + + * mln/core/site_set/box.hh: Add shrink() method. + + * mln/data/compute_in_inner_border.hh: Rewrite and add overloads. + + * mln/trait/routine/mean.hh: New trait for builtins. + + * mln/value/interval.hh: Fix overflow while counting elements. + + * mln/value/intsub.hh: Add a constructor based on int_u8. + + * mln/value/iota.hh: Add new specializations for builtins. + +2012-10-24 Guillaume Lazzara <z@lrde.epita.fr> + Add inner_border routines. * mln/inner_border/extend.hh, diff --git a/milena/mln/core/site_set/box.hh b/milena/mln/core/site_set/box.hh index 4256dc4..ed1ce91 100644 --- a/milena/mln/core/site_set/box.hh +++ b/milena/mln/core/site_set/box.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and +// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 EPITA Research and // Development Laboratory (LRDE) // // This file is part of Olena. @@ -141,6 +141,12 @@ namespace mln /// Enlarge the box with a border \p b for dimension \p dim. void enlarge(unsigned dim, unsigned b); + /// Shrink the box with a border \p b. + void shrink(unsigned b); + + /// Shrink the box with a border \p b for dimension \p dim. + void shrink(unsigned dim, unsigned b); + /// Give a larger box. box<P> to_larger(unsigned b) const; @@ -358,6 +364,31 @@ namespace mln template <typename P> inline + void + box<P>::shrink(unsigned b) + { + mln_precondition(is_valid()); + for (unsigned i = 0; i < P::dim; ++i) + { + pmin_[i] = static_cast<mln_coord(P)>(pmin_[i] + b); + pmax_[i] = static_cast<mln_coord(P)>(pmax_[i] - b); + } + mln_postcondition(is_valid()); + } + + template <typename P> + inline + void + box<P>::shrink(unsigned dim, unsigned b) + { + mln_precondition(is_valid()); + pmin_[dim] = static_cast<mln_coord(P)>(pmin_[dim] + b); + pmax_[dim] = static_cast<mln_coord(P)>(pmax_[dim] - b); + mln_postcondition(is_valid()); + } + + template <typename P> + inline box<P> larger_than(const box<P> a, const box<P> b) { diff --git a/milena/mln/data/compute_in_inner_border.hh b/milena/mln/data/compute_in_inner_border.hh index 20e8a37..917373e 100644 --- a/milena/mln/data/compute_in_inner_border.hh +++ b/milena/mln/data/compute_in_inner_border.hh @@ -32,6 +32,7 @@ # include <mln/core/concept/image.hh> # include <mln/core/concept/accumulator.hh> +# include <mln/inner_border/internal/on_frontiere.hh> # include <mln/geom/nrows.hh> # include <mln/geom/ncols.hh> @@ -58,6 +59,11 @@ namespace mln compute_in_inner_border(const Accumulator<A>& a, const Image<I>& input, unsigned inner_border_thickness); + /// \overload + /// inner_border_thickness is set to 1. + template <typename A, typename I> + mln_result(A) + compute_in_inner_border(const Accumulator<A>& a, const Image<I>& input); /// Compute an accumulator onto the inner border pixel values of /// the image \p input. @@ -75,6 +81,12 @@ namespace mln compute_in_inner_border(Accumulator<A>& a, const Image<I>& input, unsigned inner_border_thickness); + /// \overload + /// inner_border_thickness is set to 1. + template <typename A, typename I> + mln_result(A) + compute_in_inner_border(Accumulator<A>& a, const Image<I>& input); + # ifndef MLN_INCLUDE_ONLY @@ -85,10 +97,16 @@ namespace mln unsigned inner_border_thickness) { (void) a_; - A a; + A a(exact(a_)); return compute_in_inner_border(a, input, inner_border_thickness); } + template <typename A, typename I> + mln_result(A) + compute_in_inner_border(const Accumulator<A>& a, const Image<I>& input) + { + return compute_in_inner_border(a, input, 1); + } template <typename A, typename I> mln_result(A) @@ -106,74 +124,23 @@ namespace mln a.init(); - unsigned inner_border_thickness_1 = inner_border_thickness - 1; - unsigned nrows_1 = geom::nrows(input) - 1; - unsigned ncols_1 = geom::ncols(input) - 1; - - typedef mln_box(I) B; - - /* - .--------------------. - | b_top |<------ Image domain - |--------------------| - | | | | - |b| |b| - | | | | - |l| |r| - |e| |i| - |f| |g| - |t| |h| - | | |t| - |--------------------| - | b_bot | - .--------------------. - - */ - B b_top = B(input.domain().pmin(), - input.domain().pmin() - + inner_border_thickness_1 * down - + ncols_1 * right); - mln_piter(I) p_top(b_top); - - B b_bot = B(input.domain().pmax() - + inner_border_thickness_1 * up - + ncols_1 * left, - input.domain().pmax()); - mln_piter(I) p_bot(b_bot); - - B b_left = B(input.domain().pmin() - + inner_border_thickness * down, - input.domain().pmin() - + inner_border_thickness_1 * right - + (nrows_1 - inner_border_thickness) * down); - mln_piter(I) p_left(b_left); - - B b_right = B(input.domain().pmax() - + inner_border_thickness_1 * left - + (nrows_1 - inner_border_thickness) * up, - input.domain().pmax() - + inner_border_thickness * up); - mln_piter(I) p_right(b_right); - - mln_assertion(b_right.nsites() == b_left.nsites()); - mln_assertion(b_top.nsites() == b_bot.nsites()); - - for_all_2(p_top, p_bot) - { - a.take(input(p_top)); - a.take(input(p_bot)); - } - - for_all_2(p_left, p_right) - { - a.take(input(p_left)); - a.take(input(p_right)); - } + mln_piter(I) p(input.domain()); + for_all(p) + if (inner_border::internal::on_frontiere(p, input.domain(), + inner_border_thickness)) + a.take(input(p)); trace::exiting("mln::data::compute_in_inner_border"); return a; } + template <typename A, typename I> + mln_result(A) + compute_in_inner_border(Accumulator<A>& a, const Image<I>& input) + { + return compute_in_inner_border(a, input, 1); + } + # endif // ! MLN_INCLUDE_ONLY diff --git a/milena/mln/trait/routine/mean.hh b/milena/mln/trait/routine/mean.hh index 8cdbcc2..16bbfea 100644 --- a/milena/mln/trait/routine/mean.hh +++ b/milena/mln/trait/routine/mean.hh @@ -59,6 +59,18 @@ namespace mln }; template <unsigned nvalues> + struct mean< nvalues, unsigned > + { + typedef float ret; // FIXME: really ? + }; + + template <unsigned nvalues> + struct mean< nvalues, unsigned char > + { + typedef mln::value::intsub<nvalues> ret; + }; + + template <unsigned nvalues> struct mean< nvalues, float > { typedef float ret; diff --git a/milena/mln/value/interval.hh b/milena/mln/value/interval.hh index e2e9855..bdae72f 100644 --- a/milena/mln/value/interval.hh +++ b/milena/mln/value/interval.hh @@ -33,6 +33,7 @@ # include <cstdlib> # include <iostream> # include <mln/value/inc.hh> +# include <mln/value/succ.hh> # include <mln/value/concept/interval.hh> @@ -238,9 +239,14 @@ namespace mln first_ = first; last_ = last; - nelements_ = 0; - for (T v = first_; v <= last_; value::inc(v)) - ++nelements_; + nelements_ = 1; + // The second condition in the for-loop is required in case of + // overflow... + if (first != last) + { + for (T v = value::succ(first_); v <= last_ && v > first_; value::inc(v)) + ++nelements_; // FIXME: overflow with unsigned char + [0,255] + } } template <typename T> diff --git a/milena/mln/value/intsub.hh b/milena/mln/value/intsub.hh index ae71803..9fc7007 100644 --- a/milena/mln/value/intsub.hh +++ b/milena/mln/value/intsub.hh @@ -138,6 +138,10 @@ namespace mln intsub(const intsub<n>& rhs); template <unsigned m> intsub(const intsub<m>& rhs); + + // FIXME: Really ? + intsub(const value::int_u<8>& rhs); + /// Construct an intsub with value : \p int_part + 1 / \p denominator. intsub(int int_part, unsigned denominator); intsub(const literal::zero_t&); @@ -299,6 +303,11 @@ namespace mln this->v_ = rhs.to_enc() * (n / m); } + template <unsigned n> + intsub<n>::intsub(const value::int_u<8>& rhs) + { + this->v_ = n * rhs.to_equiv(); + } template <unsigned n> intsub<n>::intsub(const literal::zero_t&) diff --git a/milena/mln/value/iota.hh b/milena/mln/value/iota.hh index bdad60c..6fcd71a 100644 --- a/milena/mln/value/iota.hh +++ b/milena/mln/value/iota.hh @@ -56,6 +56,21 @@ namespace mln static int value(); }; + /// Specialization of \ref mln::value::internal::iota for unsigned + /// char. + template <> + struct iota<unsigned char> + { + static unsigned char value(); + }; + + /// Specialization of \ref mln::value::internal::iota for char. + template <> + struct iota<char> + { + static char value(); + }; + # ifndef MLN_INCLUDE_ONLY @@ -71,6 +86,18 @@ namespace mln return 1; } + unsigned char + iota<unsigned char>::value() + { + return 1u; + } + + char + iota<char>::value() + { + return 1; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::value -- 1.7.2.5