
https://svn.lrde.epita.fr/svn/oln/trunk Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Update milena. * milena/test/main.cc: Use erosion. * milena/debug/println.hh: Remove version with win. Add a facade. New 2D version. * milena/level/fill.hh: Add overloads. * milena/core/concept/point_set.hh (npoints): New. * milena/core/concept/box.hh (npoints): New. * milena/core/image2d.hh (operator=): New. (image2d): New cpy ctor. * milena/value/props.hh: Extend. core/concept/box.hh | 17 ++++++++++ core/concept/point_set.hh | 3 + core/image2d.hh | 31 +++++++++++++++++++ debug/println.hh | 42 +++++++++++++++----------- level/fill.hh | 35 ++++++++++++++++++++-- test/main.cc | 38 +++++++++++++++++++---- value/props.hh | 73 ++++++++++++++++++++++++++++++++++++++++++++-- 7 files changed, 209 insertions(+), 30 deletions(-) Index: milena/test/main.cc --- milena/test/main.cc (revision 984) +++ milena/test/main.cc (working copy) @@ -1,3 +1,5 @@ +#include <cmath> + #include <core/image2d.hh> #include <level/fill.hh> #include <debug/println.hh> @@ -8,28 +10,50 @@ #include <morpho/erosion.hh> +int cos_sin(const mln::point2d& p) +{ + return int(255 * std::cos(float(p.row())) * std::sin(float(p.col()))); +} + + int main() { using namespace mln; - box2d b = mk_box2d(/* row = */ 1, 2, - /* col = */ 3, 5); + box2d b = mk_box2d(/* row = */ 1, 3, + /* col = */ 4, 6); std::cout << b << std::endl; - image2d<int> ima(b); - level::fill(ima, 51); - debug::println(ima); - bool w[] { 0, 1, 0, 0, 1, 0, 1, 0, 0 }; window2d win = mk_window2d(w); + + /* + { + image2d<int> ima(b); + level::fill(ima, 51); + debug::println(ima); + std::cout << win << std::endl; - debug::println(ima, win); morpho::erosion(ima, win); rectangle2d rec(1, 2); std::cout << rec << std::endl; } + */ + + + { + image2d<int> ima(b); + level::fill(ima, cos_sin); + debug::println(ima); + + std::cout << std::endl; + + image2d<int> ima2 = morpho::erosion(ima, win); + debug::println(ima2); + } +} Index: milena/debug/println.hh --- milena/debug/println.hh (revision 984) +++ milena/debug/println.hh (working copy) @@ -3,6 +3,7 @@ # include <core/concept/image.hh> # include <core/concept/window.hh> +# include <core/box2d.hh> namespace mln @@ -12,7 +13,7 @@ { template <typename I> - void println(const Image<I>& input_); + void println(const Image<I>& input); template <typename I, typename W> void println(const Image<I>& input_, @@ -21,8 +22,11 @@ # ifndef MLN_INCLUDE_ONLY - template <typename I> - void println(const Image<I>& input_) + namespace impl + { + + template <typename S, typename I> + void println(const S&, const Image<I>& input_) { const I& input = exact(input_); mln_piter(I) p(input.domain()); @@ -31,26 +35,30 @@ std::cout << std::endl; } - - template <typename I, typename W> - void println(const Image<I>& input_, - const Window<W>& win_) + template <typename I> + void println(const box2d& b, + const I& input) { - const I& input = exact(input_); - const W& win = exact(win_); - - mln_piter(I) p(input.domain()); - mln_qiter(W) q(win, p); - for_all(p) + for (int row = b.pmin().row(); row <= b.pmax().row(); ++row) { - std::cout << input(p) << ':'; - for_all(q) - if (input.owns_(q)) - std::cout << input(q) << ' '; + for (int col = b.pmin().col(); col <= b.pmax().col(); ++col) + std::cout << input(mk_point2d(row, col)) << ' '; std::cout << std::endl; } } + } // end of namespace mln::debug::impl + + + + // facade + + template <typename I> + void println(const Image<I>& input) + { + impl::println(exact(input).domain(), exact(input)); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::debug Index: milena/level/fill.hh --- milena/level/fill.hh (revision 984) +++ milena/level/fill.hh (working copy) @@ -11,13 +11,23 @@ { template <typename I> - void fill(Image<I>& ima_, const mln_value(I)& value); + void fill(Image<I>& ima_, + const mln_value(I)& value); + + template <typename I> + void fill(Image<I>& ima_, + mln_value(I) (*f)(const mln_point(I)& p)); + + template <typename I> + void fill(Image<I>& ima_, + const mln_value(I) array[]); # ifndef MLN_INCLUDE_ONLY template <typename I> - void fill(Image<I>& ima_, const mln_value(I)& value) + void fill(Image<I>& ima_, + const mln_value(I)& value) { I& ima = exact(ima_); mln_piter(I) p(ima.domain()); @@ -25,6 +35,27 @@ ima(p) = value; } + template <typename I> + void fill(Image<I>& ima_, + mln_value(I) (*f)(const mln_point(I)& p)) + { + I& ima = exact(ima_); + mln_piter(I) p(ima.domain()); + for_all(p) + ima(p) = f(p); + } + + template <typename I> + void fill(Image<I>& ima_, + const mln_value(I) array[]) + { + I& ima = exact(ima_); + mln_piter(I) p(ima.domain()); + unsigned i = 0; + for_all(p) + ima(p) = array[i++]; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::level Index: milena/core/concept/point_set.hh --- milena/core/concept/point_set.hh (revision 984) +++ milena/core/concept/point_set.hh (working copy) @@ -20,6 +20,7 @@ bool has(const psite& p) const; const box_<point>& bbox() const; + std::size_t npoints() const; */ protected: @@ -45,6 +46,8 @@ m1 = 0; const box_<point>& (E::*m2)() const = & E::bbox; m2 = 0; + std::size_t (E::*m3)() const = & E::npoints; + m3 = 0; } # endif // ! MLN_INCLUDE_ONLY Index: milena/core/concept/box.hh --- milena/core/concept/box.hh (revision 984) +++ milena/core/concept/box.hh (working copy) @@ -15,7 +15,9 @@ const point& pmax() const; */ - const E& bbox() const; // final + // final + const E& bbox() const; + std::size_t npoints() const; protected: Box(); @@ -40,6 +42,19 @@ m2 = 0; } + template <typename E> + std::size_t + Box<E>::npoints() const + { + std::size_t count = 1; + for (unsigned i = 0; i < E::point::dim; ++i) + count *+ exact(this)->pmax()[i] + + 1 + - exact(this)->pmin()[i]; + return count; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: milena/core/image2d.hh --- milena/core/image2d.hh (revision 984) +++ milena/core/image2d.hh (working copy) @@ -18,6 +18,9 @@ image2d(); image2d(int nrows, int ncols); image2d(const box2d& b); + image2d(const image2d<T>& rhs); + + image2d& operator=(const image2d<T>& rhs); bool has_data() const; const box2d& domain() const; @@ -63,6 +66,34 @@ allocate_(); } + template <typename T> + image2d<T>::image2d(const image2d<T>& rhs) + : b_(rhs.domain()) + { + allocate_(); + std::memcpy(this->buffer_, + rhs.buffer_, + b_.npoints() * sizeof(value)); + } + + // assignment + + template <typename T> + image2d<T>& + image2d<T>::operator=(const image2d<T>& rhs) + { + assert(rhs.has_data()); + if (& rhs = this) + return *this; + if (this->has_data()) + this->deallocate_(); + this->b_ = rhs.domain(); + std::memcpy(this->buffer_, + rhs.buffer_, + b_.npoints() * sizeof(value)); + return *this; + } + // methods template <typename T> Index: milena/value/props.hh --- milena/value/props.hh (revision 984) +++ milena/value/props.hh (working copy) @@ -24,6 +24,15 @@ # ifndef MLN_INCLUDE_ONLY template <> + struct props<bool> + { + static bool min() { return false; } + static bool max() { return true; } + }; + + // integers + + template <> struct props<unsigned char> { static unsigned char min() { return 0; } @@ -31,10 +40,68 @@ }; template <> - struct props<int> + struct props<signed char> + { + static signed char min() { return -128; } + static signed char max() { return 127; } + }; + + template <> + struct props<unsigned short> + { + static unsigned short min() { return 0; } + static unsigned short max() { return 65535; } + }; + + template <> + struct props<signed short> + { + static signed short min() { return -32768; } + static signed short max() { return 32767; } + }; + + template <> + struct props<unsigned int> + { + static unsigned int min() { return std::numeric_limits<unsigned int>::min(); } + static unsigned int max() { return std::numeric_limits<unsigned int>::max(); } + }; + + template <> + struct props<signed int> + { + static signed int min() { return std::numeric_limits<signed int>::min(); } + static signed int max() { return std::numeric_limits<signed int>::max(); } + }; + + template <> + struct props<unsigned long int> + { + static unsigned long int min() { return std::numeric_limits<unsigned long int>::min(); } + static unsigned long int max() { return std::numeric_limits<unsigned long int>::max(); } + }; + + template <> + struct props<signed long int> + { + static signed long int min() { return std::numeric_limits<signed long int>::min(); } + static signed long int max() { return std::numeric_limits<signed long int>::max(); } + }; + + // floating + + template <> + struct props<float> + { + static float min() { return std::numeric_limits<float>::min(); } + static float max() { return std::numeric_limits<float>::max(); } + }; + + template <> + struct props<double> { - static int min() { return std::numeric_limits<int>::min(); } - static int max() { return std::numeric_limits<int>::max(); } + static double min() { return std::numeric_limits<double>::min(); } + static double max() { return std::numeric_limits<double>::max(); } }; # endif // ! MLN_INCLUDE_ONLY