1056: Augment morpho and add saturation for int-like types.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Augment morpho and add saturation for int-like types. * mln/arith/minus.hh (minus_inplace): New. * mln/arith/plus.hh (plus_inplace): New. * mln/fun/v2v/saturate.hh: New. * mln/level/abs.hh: New. * mln/level/saturate.hh: New. * mln/linear/sobel.hh: Update. * mln/math/round.hh (round_): Rename as... (round): ...this. * tests/convolve.cc, * tests/line_convolve.cc, * tests/sobel.cc: Update. * mln/linear/line_convolve.hh, * mln/linear/line_x2_convolve.hh, * mln/make/w_window_line.hh: Unconst array literals to help g++-2.95. * mln/core/concept/function.hh (Function_v2b): New. * mln/core/macros.hh (mln_value_): New. * mln/fun/ops.hh (l_, r_, f_): Add const. (mln_decl_binary_expr_): Use 'Out' part of fun type name. (mln_decl_unary_expr_): Likewise. New overload for "v2v -> v2b" operators. * mln/fun/v2v/id.hh: New. * mln/level/assign.hh, * mln/level/fill.hh: Add todo. * mln/morpho/erosion.hh: Update. * mln/morpho/includes.hh, * mln/morpho/closing.hh, * mln/morpho/dilation.hh * mln/morpho/gradient.hh * mln/morpho/opening.hh: New. * mln/test: New directory. * mln/test/positive.hh, * mln/test/predicate.hh, * tests/morpho_gradient.cc: New. mln/arith/minus.hh | 72 +++++++++++++++++++-- mln/arith/plus.hh | 42 ++++++++++++ mln/core/concept/function.hh | 70 ++++++++++++++++++++ mln/core/macros.hh | 1 mln/fun/internal/selector.hh | 22 +++--- mln/fun/ops.hh | 42 +++++++++--- mln/fun/v2v/id.hh | 77 ++++++++++++++++++++++ mln/fun/v2v/saturate.hh | 105 ++++++++++++++++++++++++++++++ mln/level/abs.hh | 89 ++++++++++++++++++++++++++ mln/level/assign.hh | 2 mln/level/fill.hh | 2 mln/level/saturate.hh | 121 +++++++++++++++++++++++++++++++++++ mln/linear/line_convolve.hh | 4 - mln/linear/line_x2_convolve.hh | 4 - mln/linear/sobel.hh | 16 ++-- mln/make/w_window_line.hh | 4 - mln/math/round.hh | 4 - mln/morpho/closing.hh | 79 +++++++++++++++++++++++ mln/morpho/dilation.hh | 102 ++++++++++++++++++++++++++++++ mln/morpho/erosion.hh | 32 ++++----- mln/morpho/gradient.hh | 139 +++++++++++++++++++++++++++++++++++++++++ mln/morpho/includes.hh | 56 ++++++++++++++++ mln/morpho/opening.hh | 79 +++++++++++++++++++++++ mln/test/positive.hh | 73 +++++++++++++++++++++ mln/test/predicate.hh | 128 +++++++++++++++++++++++++++++++++++++ tests/convolve.cc | 2 tests/line_convolve.cc | 3 tests/morpho_gradient.cc | 58 +++++++++++++++++ tests/sobel.cc | 6 - tests/test_positive.cc | 64 ++++++++++++++++++ 30 files changed, 1431 insertions(+), 67 deletions(-) Index: tests/convolve.cc --- tests/convolve.cc (revision 1055) +++ tests/convolve.cc (working copy) @@ -63,7 +63,7 @@ image2d_b<float> tmp(lena.domain()); linear::convolve(lena, w, tmp); - level::transform(tmp, math::round_<int_u8>(), out); + level::transform(tmp, math::round<int_u8>(), out); io::save_pgm(out, "out.pgm"); } Index: tests/sobel.cc --- tests/sobel.cc (revision 1055) +++ tests/sobel.cc (working copy) @@ -32,13 +32,11 @@ #include <mln/core/image2d_b.hh> #include <mln/value/int_u8.hh> +#include <mln/level/saturate.hh> #include <mln/io/load_pgm.hh> #include <mln/io/save_pgm.hh> -#include <mln/math/round_sat.hh> -#include <mln/level/transform.hh> - #include <mln/border/thickness.hh> #include <mln/linear/sobel.hh> @@ -57,6 +55,6 @@ image2d_b<int> tmp(lena.domain()); linear::sobel(lena, tmp); - level::transform(tmp, math::round_sat_<int_u8>(), out); + level::saturate(tmp, out); io::save_pgm(out, "out.pgm"); } Index: tests/test_positive.cc --- tests/test_positive.cc (revision 0) +++ tests/test_positive.cc (revision 0) @@ -0,0 +1,64 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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. + +/*! \file tests/test_positive.cc + * + * \brief Tests on mln::test::positive. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/level/fill.hh> +#include <mln/test/positive.hh> + + +// both test routines can be called with a p2b function + +template <typename F> +void test_p2v(const mln::Function_p2v<F>&) +{ +} + +template <typename F> +void test_v2b(const mln::Function_v2b<F>&) +{ +} + + + +int main() +{ + using namespace mln; + typedef image2d_b<int> I; + + I ima(1,1); + level::fill(ima, 0); + + test_v2b(fun::v2v::id<mln_value_(I)>() >= pw::cst(0)); + + // test2(fun::v2v::id<mln_value_(I)>() >= pw::cst(0)); + // test::positive(ima); +} Index: tests/line_convolve.cc --- tests/line_convolve.cc (revision 1055) +++ tests/line_convolve.cc (working copy) @@ -36,7 +36,6 @@ #include <mln/io/load_pgm.hh> #include <mln/io/save_pgm.hh> #include <mln/math/round.hh> -#include <mln/math/round_sat.hh> #include <mln/level/transform.hh> #include <mln/core/w_window2d_float.hh> @@ -59,6 +58,6 @@ float ws[] = { .11, .11, .11, .11, .11, .11, .11, .11, .11 }; linear::line_convolve(lena, ws, tmp); - level::transform(tmp, math::round_<int_u8>(), out); + level::transform(tmp, math::round<int_u8>(), out); io::save_pgm(out, "out.pgm"); } Index: tests/morpho_gradient.cc --- tests/morpho_gradient.cc (revision 0) +++ tests/morpho_gradient.cc (revision 0) @@ -0,0 +1,58 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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. + +/*! \file tests/erosion.cc + * + * \brief Test on mln::morpho::erosion. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/core/win/rectangle2d.hh> + +#include <mln/io/load_pgm.hh> +#include <mln/io/save_pgm.hh> + +#include <mln/value/int_u8.hh> +#include <mln/morpho/gradient.hh> + + + +int main() +{ + using namespace mln; + using value::int_u8; + + win::rectangle2d rect(5, 5); + border::thickness = 2; + + image2d_b<int_u8> + lena = io::load_pgm("../img/tiny.pgm"), + out(lena.domain()); + + morpho::gradient(lena, rect, out); + io::save_pgm(out, "out.pgm"); +} Index: mln/test/positive.hh --- mln/test/positive.hh (revision 0) +++ mln/test/positive.hh (revision 0) @@ -0,0 +1,73 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_TEST_POSITIVE_HH +# define MLN_TEST_POSITIVE_HH + +/*! \file mln/test/positive.hh + * + * \brief Test if an image only contains positive values. + */ + +# include <mln/test/predicate.hh> +# include <mln/pw/all.hh> +# include <mln/fun/v2v/id.hh> + + +namespace mln +{ + + namespace test + { + + /// Test if an image only contains positive values. + template <typename I> + bool positive(const Image<I>& input); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + bool positive(const Image<I>& input_) + { + const I& input = exact(input_); + mln_precondition(input.has_data()); + return test::predicate(input.domain(), + pw::value(input) >= pw::cst(0)); + // FIXME: test the version below. +// return test::predicate(input, +// fun::v2v::id<mln_value(I)>() >= pw::cst(0)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::test + +} // end of namespace mln + + +#endif // ! MLN_TEST_POSITIVE_HH Index: mln/test/predicate.hh --- mln/test/predicate.hh (revision 0) +++ mln/test/predicate.hh (revision 0) @@ -0,0 +1,128 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_TEST_PREDICATE_HH +# define MLN_TEST_PREDICATE_HH + +/*! \file mln/test/predicate.hh + * + * \brief Test a predicate on the pixel values of an image. + */ + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/function.hh> +# include <mln/core/concept/point_set.hh> + + +namespace mln +{ + + namespace test + { + + /*! Test if all pixel values of \p ima verify the predicate \p + * f. + * + * \param[in] ima The image. + * \param[in] f The predicate. + */ + template <typename I, typename F> + bool predicate(const Image<I>& ima, const Function_v2b<F>& f); + + + /*! Test if all points of \p pset verify the predicate \p f. + * + * \param[in] pset The point set. + * \param[in] f The predicate. + */ + template <typename S, typename F> + bool predicate(const Point_Set<S>& pset, const Function_p2b<F>& f); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename F> + bool predicate_(const Image<I>& ima_, const F& f) + { + const I& ima = exact(ima_); + mln_piter(I) p(ima.domain()); + for_all(p) + if (! f(ima(p))) + return false; + return true; + } + + template <typename I, typename F> + bool predicate_(const Fast_Image<I>& ima_, const F& f) + { + const I& ima = exact(ima_); + mln_pixter(const I) pxl(ima); + for_all(pxl) + if (! f(pxl.val())) + return false; + return true; + } + + template <typename S, typename F> + bool predicate_(const Point_Set<S>& pset, const F& f) + { + mln_piter(S) p(exact(pset)); + for_all(p) + if (! f(p)) + return false; + return true; + } + + } // end of namespace mln::test::impl + + + // Facades. + + template <typename I, typename F> + bool predicate(const Image<I>& ima, const Function_v2b<F>& f) + { + mln_precondition(exact(ima).has_data()); + return impl::predicate_(exact(ima), exact(f)); + } + + template <typename S, typename F> + bool predicate(const Point_Set<S>& pset, const Function_p2b<F>& f) + { + return impl::predicate_(exact(pset), exact(f)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::test + +} // end of namespace mln + + +#endif // ! MLN_TEST_PREDICATE_HH Index: mln/pw/value.hh Index: mln/core/macros.hh --- mln/core/macros.hh (revision 1055) +++ mln/core/macros.hh (working copy) @@ -148,6 +148,7 @@ /// Shortcut to access the value type associated to T. # define mln_value(T) typename T::value +# define mln_value_(T) T::value /// Shortcut to the kind of values for an image with type \c I. # define mln_value_kind(I) typename mln::value::props< mln_value(I) >::kind Index: mln/core/concept/function.hh --- mln/core/concept/function.hh (revision 1055) +++ mln/core/concept/function.hh (working copy) @@ -53,6 +53,7 @@ */ protected: Function(); + Function(const Function&); }; @@ -65,6 +66,7 @@ { protected: Function_v2v(); + Function_v2v(const Function_v2v&); }; @@ -77,6 +79,7 @@ { protected: Function_i2v(); + Function_i2v(const Function_i2v&); }; @@ -85,10 +88,25 @@ /// Base class for implementation of function-objects from point to /// value. template <typename E> - struct Function_p2v : public Function_v2v<E> + struct Function_p2v : public virtual Function_v2v<E> { protected: Function_p2v(); + Function_p2v(const Function_p2v&); + }; + + + // Value -> bool. + + /// Base class for implementation of function-objects from value to + /// bool. + template <typename E> + struct Function_v2b : public virtual Function_v2v<E> + { + typedef bool result; + protected: + Function_v2b(); + Function_v2b(const Function_v2b&); }; @@ -97,11 +115,13 @@ /// Base class for implementation of function-objects from point to /// bool. template <typename E> - struct Function_p2b : public Function_p2v<E> + struct Function_p2b : public Function_p2v<E>, + public Function_v2b<E> { typedef bool result; protected: Function_p2b(); + Function_p2b(const Function_p2b&); }; @@ -114,6 +134,7 @@ { protected: Function_p2p(); + Function_p2p(const Function_p2p&); }; @@ -127,25 +148,70 @@ } template <typename E> + Function<E>::Function(const Function<E>&) + { + } + + template <typename E> Function_v2v<E>::Function_v2v() { } template <typename E> + Function_v2v<E>::Function_v2v(const Function_v2v<E>&) + { + } + + template <typename E> Function_i2v<E>::Function_i2v() { } template <typename E> + Function_i2v<E>::Function_i2v(const Function_i2v<E>&) + { + } + + template <typename E> Function_p2v<E>::Function_p2v() { } template <typename E> + Function_p2v<E>::Function_p2v(const Function_p2v<E>&) + { + } + + template <typename E> + Function_v2b<E>::Function_v2b() + { + } + + template <typename E> + Function_v2b<E>::Function_v2b(const Function_v2b<E>&) + { + } + + template <typename E> Function_p2b<E>::Function_p2b() { } + template <typename E> + Function_p2b<E>::Function_p2b(const Function_p2b<E>&) + { + } + + template <typename E> + Function_p2p<E>::Function_p2p() + { + } + + template <typename E> + Function_p2p<E>::Function_p2p(const Function_p2p<E>&) + { + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/fun/ops.hh --- mln/fun/ops.hh (revision 1055) +++ mln/fun/ops.hh (working copy) @@ -34,6 +34,7 @@ */ # include <mln/core/concept/function.hh> +# include <mln/fun/internal/selector.hh> @@ -43,11 +44,12 @@ { \ \ template <typename L, typename R> \ - struct Name##_expr_ : public Function_##Out < Name##_expr_<L,R> > \ + struct Name##_##Out##_expr_ \ + : public Function_##Out < Name##_##Out##_expr_<L,R> > \ { \ typedef mln_result(L) result; \ \ - Name##_expr_(const L& l, const R& r) \ + Name##_##Out##_expr_(const L& l, const R& r) \ : l_(l), r_(r) \ { \ } \ @@ -59,17 +61,17 @@ } \ \ protected: \ - L l_; \ - R r_; \ + const L l_; \ + const R r_; \ }; \ \ } \ \ template <typename L, typename R> \ - fun::Name##_expr_<L,R> \ + fun::Name##_##Out##_expr_<L,R> \ operator Symbol (const Function_##In<L>& lhs, const Function_##In<R>& rhs) \ { \ - fun::Name##_expr_<L,R> tmp(exact(lhs), exact(rhs)); \ + fun::Name##_##Out##_expr_<L,R> tmp(exact(lhs), exact(rhs)); \ return tmp; \ } \ \ @@ -82,11 +84,12 @@ { \ \ template <typename F> \ - struct Name##_expr_ : public Function_##Out< Name##_expr_<F> > \ + struct Name##_##Out##_expr_ \ + : public Function_##Out< Name##_##Out##_expr_<F> > \ { \ typedef mln_result(F) result; \ \ - Name##_expr_(const F& f) \ + Name##_##Out##_expr_(const F& f) \ : f_(f) \ { \ } \ @@ -98,16 +101,16 @@ } \ \ protected: \ - F f_; \ + const F f_; \ }; \ \ } \ \ template <typename F> \ - fun::Name##_expr_<F> \ + fun::Name##_##Out##_expr_<F> \ operator Symbol (const Function_##In<F>& f) \ { \ - fun::Name##_expr_<F> tmp(exact(f)); \ + fun::Name##_##Out##_expr_<F> tmp(exact(f)); \ return tmp; \ } \ \ @@ -117,6 +120,7 @@ namespace mln { + // -> p2v mln_decl_binary_expr_(p2v, p2b, equal, =); mln_decl_binary_expr_(p2v, p2b, not_equal, !=); @@ -141,6 +145,22 @@ mln_decl_unary_expr_(p2v, p2v, uplus, +); mln_decl_unary_expr_(p2v, p2v, uminus, -); + // -> v2b + + mln_decl_binary_expr_(v2v, v2b, equal, =); + mln_decl_binary_expr_(v2v, v2b, not_equal, !=); + + mln_decl_binary_expr_(v2v, v2b, less, <); + mln_decl_binary_expr_(v2v, v2b, less_or_equal, <=); + mln_decl_binary_expr_(v2v, v2b, greater_or_equal, >=); + mln_decl_binary_expr_(v2v, v2b, greater, >); + + mln_decl_binary_expr_(v2b, v2b, and, &&); + mln_decl_binary_expr_(v2b, v2b, or, ||); + mln_decl_binary_expr_(v2b, v2b, xor, ^); + + mln_decl_unary_expr_(v2b, v2b, not, !); + } // end of namespace mln Index: mln/fun/internal/selector.hh --- mln/fun/internal/selector.hh (revision 1055) +++ mln/fun/internal/selector.hh (working copy) @@ -51,11 +51,13 @@ // Function_v2v // | - // + -- Function_i2v - // | - // + -- Function_p2v - // | - // + -- Function_p2b + // + ---------------------- Function_v2b + // | | + // + -- Function_i2v | + // | | + // + -- Function_p2v | + // | | + // + -- Function_p2b -- + // | // + -- Function_p2p @@ -69,9 +71,9 @@ template <int arg, int res, typename E> struct helper_selector_; - // no b2* type => v2v type + // b2* => v2v type, except for v2b template <typename E> - struct helper_selector_< b_, b_, E > { typedef Function_v2v<E> ret; }; + struct helper_selector_< b_, b_, E > { typedef Function_v2b<E> ret; }; template <typename E> struct helper_selector_< b_, i_, E > { typedef Function_v2v<E> ret; }; template <typename E> @@ -79,7 +81,7 @@ template <typename E> struct helper_selector_< b_, v_, E > { typedef Function_v2v<E> ret; }; - // i2* => only i2v type + // i2* => i2v type template <typename E> struct helper_selector_< i_, b_, E > { typedef Function_i2v<E> ret; }; template <typename E> @@ -99,9 +101,9 @@ template <typename E> struct helper_selector_< p_, v_, E > { typedef Function_p2v<E> ret; }; - // v2* => only v2v type + // v2* => v2v type, except for v2b template <typename E> - struct helper_selector_< v_, b_, E > { typedef Function_v2v<E> ret; }; + struct helper_selector_< v_, b_, E > { typedef Function_v2b<E> ret; }; template <typename E> struct helper_selector_< v_, i_, E > { typedef Function_v2v<E> ret; }; template <typename E> Index: mln/fun/v2v/saturate.hh --- mln/fun/v2v/saturate.hh (revision 0) +++ mln/fun/v2v/saturate.hh (revision 0) @@ -0,0 +1,105 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_FUN_V2V_SATURATE_HH +# define MLN_FUN_V2V_SATURATE_HH + +/*! \file mln/fun/v2v/saturate.hh + * + * \brief FIXME. + */ + +# include <mln/core/concept/function.hh> +# include <mln/value/props.hh> + + +namespace mln +{ + + namespace fun + { + + namespace v2v + { + + // FIXME: Doc! + + template <typename V> + struct saturate : public Function_v2v< saturate<V> > + { + saturate(); + saturate(const V& min, const V& max); + + typedef V result; + + template <typename W> + V operator()(const W& v) const; + + protected: + V min_, max_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename V> + saturate<V>::saturate() + : min_(mln_min(V)), + max_(mln_max(V)) + { + } + + template <typename V> + saturate<V>::saturate(const V& min, const V& max) + : min_(min), + max_(max) + { + mln_precondition(max > min); + } + + template <typename V> + template <typename W> + V + saturate<V>::operator()(const W& v) const + { + if (v < min_) + return min_; + if (v > max_) + return max_; + return v; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::v2v + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_V2V_SATURATE_HH Index: mln/fun/v2v/id.hh --- mln/fun/v2v/id.hh (revision 0) +++ mln/fun/v2v/id.hh (revision 0) @@ -0,0 +1,77 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_FUN_V2V_ID_HH +# define MLN_FUN_V2V_ID_HH + +/*! \file mln/fun/id.hh + * + * \brief FIXME. + */ + +# include <mln/fun/internal/selector.hh> + + +namespace mln +{ + + namespace fun + { + + namespace v2v + { + + // FIXME: Doc! + + template <typename T> + struct id + : fun::internal::selector_<T, T, id<T> >::ret + { + typedef T result; + T operator()(const T& t) const; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename T> + T + id<T>::operator()(const T& t) const + { + return t; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::v2v + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_V2V_ID_HH Index: mln/math/round.hh --- mln/math/round.hh (revision 1055) +++ mln/math/round.hh (working copy) @@ -47,7 +47,7 @@ template <typename R> - struct round_ : public Function_v2v< round_<R> > + struct round : public Function_v2v< round<R> > { typedef R result; @@ -61,7 +61,7 @@ template <typename R> template <typename T> - R round_<R>::operator()(const T& v) const + R round<R>::operator()(const T& v) const { return (long int)(v + 0.49999); // FIXME: !!! } Index: mln/morpho/dilation.hh --- mln/morpho/dilation.hh (revision 0) +++ mln/morpho/dilation.hh (revision 0) @@ -0,0 +1,102 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_MORPHO_DILATION_HH +# define MLN_MORPHO_DILATION_HH + +/*! \file mln/morpho/dilation.hh + * + * \brief Morphological dilation. + * + * \todo Mimic erosion.hh when completed. + */ + +# include <mln/morpho/includes.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological dilation. + */ + template <typename I, typename W, typename O> + void dilation(const Image<I>& input, const Window<W>& win, Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename W, typename O> + void dilation_on_function(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) + { + const I& input = exact(input_); + const W& win = exact(win_); + O& output = exact(output_); + + accu::max<mln_value(I)> max; + + mln_piter(I) p(input.domain()); + mln_qiter(W) q(win, p); + for_all(p) + { + max.init(); + for_all(q) if (input.has(q)) + max.take(input(q)); + output(p) = max.to_value(); + } + } + + } // end of namespace mln::morpho::impl + + + // Facade. + + template <typename I, typename W, typename O> + void dilation(const Image<I>& input, const Window<W>& win, Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + mln_precondition(! exact(win).is_empty()); + + impl::dilation_on_function(input, win, output); + + if (exact(win).is_centered()) + mln_postcondition(output >= input); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_DILATION_HH Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 0) +++ mln/morpho/includes.hh (revision 0) @@ -0,0 +1,56 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_MORPHO_INCLUDES_HH +# define MLN_MORPHO_INCLUDES_HH + +/*! \file mln/morpho/includes.hh + * + * \brief Basic list of includes for all files in mln/morpho/. + */ + + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/window.hh> + +# include <mln/accu/min.hh> +# include <mln/accu/max.hh> + +# include <mln/arith/minus.hh> + +# include <mln/level/compare.hh> +# include <mln/level/fill.hh> + +# include <mln/border/resize.hh> +# include <mln/border/fill.hh> + +# include <mln/morpho/dilation.hh> +# include <mln/morpho/erosion.hh> + + + +#endif // ! MLN_MORPHO_INCLUDES_HH Index: mln/morpho/gradient.hh --- mln/morpho/gradient.hh (revision 0) +++ mln/morpho/gradient.hh (revision 0) @@ -0,0 +1,139 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_MORPHO_GRADIENT_HH +# define MLN_MORPHO_GRADIENT_HH + +/*! \file mln/morpho/gradient.hh + * + * \brief Morphological gradient. + */ + +# include <mln/morpho/includes.hh> +# include <mln/test/positive.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological gradient. + * + * This operator is d_B - e_B. + */ + template <typename I, typename W, typename O> + void gradient(const Image<I>& input, const Window<W>& win, + Image<O>& output); + + + /*! Morphological internal gradient. + * + * This operator is Id - e_B. + */ + template <typename I, typename W, typename O> + void gradient_internal(const Image<I>& input, const Window<W>& win, + Image<O>& output); + + + /*! Morphological external gradient. + * + * This operator is d_B - Id. + */ + template <typename I, typename W, typename O> + void gradient_external(const Image<I>& input, const Window<W>& win, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename W, typename O> + void gradient(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) + { + const I& input = exact(input_); + const W& win = exact(win_); + O& output = exact(output_); + + mln_precondition(output.domain() = input.domain()); + mln_precondition(! win.is_empty()); + + O temp(input.domain()); + erosion(input, win, temp); + + dilation(input, win, output); + arith::minus_inplace(output, temp); + + mln_postcondition(test::positive(output)); + } + + template <typename I, typename W, typename O> + void gradient_internal(const Image<I>& input_, const Window<W>& win_, + Image<O>& output_) + { + const I& input = exact(input_); + const W& win = exact(win_); + O& output = exact(output_); + + mln_precondition(output.domain() = input.domain()); + mln_precondition(! win.is_empty()); + + O temp(input.domain()); + erosion(input, win, temp); + + arith::minus(input, temp, output); + + mln_postcondition(test::positive(output)); + } + + template <typename I, typename W, typename O> + void gradient_external(const Image<I>& input_, const Window<W>& win_, + Image<O>& output_) + { + const I& input = exact(input_); + const W& win = exact(win_); + O& output = exact(output_); + + mln_precondition(output.domain() = input.domain()); + mln_precondition(! win.is_empty()); + + O temp(input.domain()); + dilation(input, win, temp); + + arith::minus(temp, input, output); + + mln_postcondition(test::positive(output)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_GRADIENT_HH Index: mln/morpho/erosion.hh --- mln/morpho/erosion.hh (revision 1055) +++ mln/morpho/erosion.hh (working copy) @@ -28,13 +28,7 @@ #ifndef MLN_MORPHO_EROSION_HH # define MLN_MORPHO_EROSION_HH -# include <mln/core/concept/image.hh> -# include <mln/core/concept/window.hh> -# include <mln/accu/min.hh> -# include <mln/value/props.hh> -# include <mln/level/compare.hh> -# include <mln/level/fill.hh> -// FIXME: # include <mln/border/assign.hh> +# include <mln/morpho/includes.hh> namespace mln @@ -43,6 +37,11 @@ namespace morpho { + /*! Morphological erosion. + * + * \todo Overload erosion_wrt_win for hline and vline and for fast + * images. + */ template <typename I, typename W, typename O> void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output); @@ -52,7 +51,7 @@ namespace impl { - // on function + // On function. template <typename I, typename W, typename O> void erosion_on_function(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) @@ -75,7 +74,7 @@ } - // on set + // On set. template <typename I, typename W, typename O> void erosion_on_set(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) @@ -104,10 +103,10 @@ - // FIXME: stage 3: dispatch w.r.t. fast property + // FIXME: Stage 3: dispatch w.r.t. fast property - // stage 2: dispatch w.r.t. the value kind + // Stage 2: dispatch w.r.t. the value kind. template <typename I, typename W, typename O> void erosion_wrt_value(value::binary_kind, // binary => morphology on sets @@ -125,7 +124,7 @@ - // stage 1: dispatch w.r.t. the window type + // Stage 1: dispatch w.r.t. the window type. // | // V @@ -142,9 +141,9 @@ template <typename I, typename O> void erosion_wrt_win(const Image<I>& input, const win::rectangle2d& win, Image<O>& output) { - O tmp(exact(output).domain()); - morpho::erosion(input, win::hline2d(win.width()), tmp); - morpho::erosion(tmp, win::vline2d(win.height()), output); + O temp(exact(output).domain()); + morpho::erosion(input, win::hline2d(win.width()), temp); + morpho::erosion(temp, win::vline2d(win.height()), output); } # endif // MLN_CORE_WIN_RECTANGLE2D_HH @@ -157,7 +156,7 @@ } // end of namespace mln::morpho::impl - // facade + // Facade. template <typename I, typename W, typename O> void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output) @@ -166,6 +165,7 @@ mln_precondition(! exact(win).is_empty()); impl::erosion_wrt_win(input, exact(win), output); + if (exact(win).is_centered()) mln_postcondition(output <= input); } Index: mln/morpho/closing.hh --- mln/morpho/closing.hh (revision 0) +++ mln/morpho/closing.hh (revision 0) @@ -0,0 +1,79 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_MORPHO_CLOSING_HH +# define MLN_MORPHO_CLOSING_HH + +/*! \file mln/morpho/closing.hh + * + * \brief Morphological closing. + */ + +# include <mln/morpho/includes.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological closing. + * + * This operator is e_{-B} o d_B. + */ + template <typename I, typename W, typename O> + void closing(const Image<I>& input, const Window<W>& win, Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename W, typename O> + void closing(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) + { + const I& input = exact(input_); + const W& win = exact(win_); + O& output = exact(output_); + + mln_precondition(output.domain() = input.domain()); + mln_precondition(! win.is_empty()); + + O temp(input.domain()); + dilation(input, win, temp); + erosion(temp, -win, output); + + mln_postcondition(output >= input); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_CLOSING_HH Index: mln/morpho/opening.hh --- mln/morpho/opening.hh (revision 0) +++ mln/morpho/opening.hh (revision 0) @@ -0,0 +1,79 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_MORPHO_OPENING_HH +# define MLN_MORPHO_OPENING_HH + +/*! \file mln/morpho/opening.hh + * + * \brief Morphological opening. + */ + +# include <mln/morpho/includes.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological opening. + * + * This operator is d_{-B} o e_B. + */ + template <typename I, typename W, typename O> + void opening(const Image<I>& input, const Window<W>& win, Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename W, typename O> + void opening(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) + { + const I& input = exact(input_); + const W& win = exact(win_); + O& output = exact(output_); + + mln_precondition(output.domain() = input.domain()); + mln_precondition(! win.is_empty()); + + O temp(input.domain()); + erosion(input, win, temp); + dilation(temp, -win, output); + + mln_postcondition(output <= input); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_OPENING_HH Index: mln/level/assign.hh --- mln/level/assign.hh (revision 1055) +++ mln/level/assign.hh (working copy) @@ -31,6 +31,8 @@ /*! \file mln/level/assign.hh * * \brief Assignment between a couple of images. + * + * \todo Assign should be a precondition then a call to level::fill. */ # include <mln/core/concept/image.hh> Index: mln/level/fill.hh --- mln/level/fill.hh (revision 1055) +++ mln/level/fill.hh (working copy) @@ -31,6 +31,8 @@ /*! \file mln/level/fill.hh * * \brief Fill an image, that is, set pixel values. + * + * \todo Overload for fast images. */ # include <cstring> Index: mln/level/saturate.hh --- mln/level/saturate.hh (revision 0) +++ mln/level/saturate.hh (revision 0) @@ -0,0 +1,121 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_LEVEL_SATURATE_HH +# define MLN_LEVEL_SATURATE_HH + +/*! \file mln/level/saturate.hh + * + * \brief Apply a saturation function to image pixel values. + */ + +# include <mln/fun/v2v/saturate.hh> +# include <mln/level/apply.hh> +# include <mln/level/transform.hh> + + +namespace mln +{ + + namespace level + { + + + /*! Apply the saturate function to image pixel values. + * + * \param[in] input The input image. + * \param[out] output The output image. + * + * The saturation is based on the min and max values of the output + * value type. This assumes that the range of values in the input + * image is larger than the one of the output image. + */ + template <typename I, typename O> + void saturate(const Image<I>& input, Image<O>& output); + + + /*! Apply the saturate function to image pixel values. + * + * \param[in] input The input image. + * \param[in] min The minimum output value. + * \param[in] max The maximum output value. + * \param[out] output The output image. + */ + template <typename I, typename O> + void saturate(const Image<I>& input, + const mln_value(O)& min, const mln_value(O)& max, + Image<O>& output); + + + /*! Apply the saturate function to image pixel values. + * + * \param[in,out] input The input image. + * \param[in] min The minimum output value. + * \param[in] max The maximum output value. + */ + template <typename I> + void saturate_inplace(Image<I>& input, + const mln_value(I)& min, const mln_value(I)& max); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename O> + void saturate(const Image<I>& input, Image<O>& output) + { + mln_precondition(exact(input).domain() = exact(output).domain()); + fun::v2v::saturate<mln_value(O)> f; + level::transform(input, f, output); + } + + template <typename I, typename O> + void saturate(const Image<I>& input, + const mln_value(O)& min, const mln_value(O)& max, + Image<O>& output) + { + mln_precondition(exact(input).domain() = exact(output).domain()); + fun::v2v::saturate<mln_value(O)> f(min, max); + level::transform(input, f, output); + } + + template <typename I> + void saturate_inplace(Image<I>& input, + const mln_value(I)& min, const mln_value(I)& max) + { + mln_precondition(exact(input).has_data()); + fun::v2v::saturate<mln_value(I)> f(min, max); + level::apply(input, f); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::level + +} // end of namespace mln + + +#endif // ! MLN_LEVEL_SATURATE_HH Index: mln/level/abs.hh --- mln/level/abs.hh (revision 0) +++ mln/level/abs.hh (revision 0) @@ -0,0 +1,89 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_LEVEL_ABS_HH +# define MLN_LEVEL_ABS_HH + +/*! \file mln/level/abs.hh + * + * \brief Apply the absolute value (abs) function to image pixel + * values. + */ + +# include <mln/fun/v2v/abs.hh> +# include <mln/level/apply.hh> +# include <mln/level/transform.hh> + + +namespace mln +{ + + namespace level + { + + + /*! Apply the absolute value (abs) function to image pixel values. + * + * \param[in] input The input image. + * \param[out] output The output image. + */ + template <typename I, typename O> + void abs(const Image<I>& input, Image<O>& output); + + + /*! Apply the absolute value (abs) function to image pixel values. + * + * \param[in,out] input The input image. + */ + template <typename I> + void abs_inplace(Image<I>& input); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename O> + void abs(const Image<I>& input, Image<O>& output) + { + mln_precondition(exact(input).domain() = exact(output).domain()); + level::transform(input, fun::v2v::abs<mln_value(I)>(), output); + } + + template <typename I> + void abs_inplace(Image<I>& input) + { + mln_precondition(exact(input).has_data()); + level::apply(input, fun::v2v::abs<mln_value(I)>()); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::level + +} // end of namespace mln + + +#endif // ! MLN_LEVEL_ABS_HH Index: mln/arith/plus.hh --- mln/arith/plus.hh (revision 1055) +++ mln/arith/plus.hh (working copy) @@ -54,6 +54,20 @@ void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + /*! Point-wise addition of image \p rhs in image \p lhs. + * + * \param[in] lhs First operand image (subject to addition). + * \param[in,out] rhs Second operand image (to be added to \p lhs). + * + * This addition performs: \n + * for all p of rhs.domain \n + * lhs(p) += rhs(p) + * + * \pre \p rhs.domain <= \p lhs.domain + */ + template <typename L, typename R> + void plus_inplace(Image<L>& lhs, const Image<R>& rhs); + # ifndef MLN_INCLUDE_ONLY @@ -81,10 +95,29 @@ op.val() = lp.val() + rp.val(); } + template <typename L, typename R> + void plus_inplace_(Image<L>& lhs_, const Image<R>& rhs_) + { + L& lhs = exact(lhs_); + const R& rhs = exact(rhs_); + mln_piter(R) p(rhs.domain()); + for_all(p) + lhs(p) += rhs(p); + } + + template <typename L, typename R> + void plus_inplace_(Fast_Image<L>& lhs, const Fast_Image<R>& rhs) + { + mln_pixter(L) lp(exact(lhs)); + mln_pixter(const R) rp(exact(rhs)); + for_all_2(rp, lp) + lp.val() += rp.val(); + } + } // end of namespace mln::arith::impl - // Facade. + // Facades. template <typename L, typename R, typename O> void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output) @@ -94,6 +127,13 @@ impl::plus_(exact(lhs), exact(rhs), exact(output)); } + template <typename L, typename R> + void plus_inplace(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() <= exact(lhs).domain()); + impl::plus_inplace_(exact(lhs), exact(rhs)); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::arith Index: mln/arith/minus.hh --- mln/arith/minus.hh (revision 1055) +++ mln/arith/minus.hh (working copy) @@ -54,22 +54,84 @@ void minus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + /*! Point-wise substraction of image \p lhs in image \p rhs. + * + * \param[in,out] lhs First operand image (subject to substraction). + * \param[in] rhs Second operand image (to be substracted to \p lhs). + * + * This substraction performs: \n + * for all p of rhs.domain \n + * lhs(p) -= rhs(p) + * + * \pre \p rhs.domain <= \p lhs.domain + */ + template <typename L, typename R> + void minus_inplace(Image<L>& lhs, const Image<R>& rhs); + # ifndef MLN_INCLUDE_ONLY + namespace impl + { + template <typename L, typename R, typename O> - void minus(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_) + void minus_(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_) { const L& lhs = exact(lhs_); const R& rhs = exact(rhs_); O& output = exact(output_); + mln_piter(L) p(lhs.domain()); + for_all(p) + output(p) = lhs(p) - rhs(p); + } - mln_precondition(rhs.domain() = lhs.domain()); - mln_precondition(output.domain() = lhs.domain()); + template <typename L, typename R, typename O> + void minus_(const Fast_Image<L>& lhs, const Fast_Image<R>& rhs, Fast_Image<O>& output) + { + mln_pixter(const L) lp(exact(lhs)); + mln_pixter(const R) rp(exact(rhs)); + mln_pixter(O) op(exact(output)); + for_all_3(lp, rp, op) + op.val() = lp.val() - rp.val(); + } - mln_piter(I) p(output.domain()); + template <typename L, typename R> + void minus_inplace_(Image<L>& lhs_, const Image<R>& rhs_) + { + L& lhs = exact(lhs_); + const R& rhs = exact(rhs_); + mln_piter(R) p(rhs.domain()); for_all(p) - output(p) = lhs(p) - rhs(p); + lhs(p) -= rhs(p); + } + + template <typename L, typename R> + void minus_inplace_(Fast_Image<L>& lhs, const Fast_Image<R>& rhs) + { + mln_pixter(L) lp(exact(lhs)); + mln_pixter(const R) rp(exact(rhs)); + for_all_2(rp, lp) + lp.val() -= rp.val(); + } + + } // end of namespace mln::arith::impl + + + // Facades. + + template <typename L, typename R, typename O> + void minus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + impl::minus_(exact(lhs), exact(rhs), exact(output)); + } + + template <typename L, typename R> + void minus_inplace(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() <= exact(lhs).domain()); + impl::minus_inplace_(exact(lhs), exact(rhs)); } # endif // ! MLN_INCLUDE_ONLY Index: mln/linear/line_convolve.hh --- mln/linear/line_convolve.hh (revision 1055) +++ mln/linear/line_convolve.hh (working copy) @@ -56,14 +56,14 @@ * \pre output.domain = input.domain */ template <typename I, typename W, unsigned N, typename O> - void line_convolve(const Image<I>& input, const W (&weights)[N], + void line_convolve(const Image<I>& input, W (&weights)[N], Image<O>& output); # ifndef MLN_INCLUDE_ONLY template <typename I, typename W, unsigned N, typename O> - void line_convolve(const Image<I>& input, const W (&weights)[N], + void line_convolve(const Image<I>& input, W (&weights)[N], Image<O>& output) { mln_precondition(exact(output).domain() = exact(input).domain()); Index: mln/linear/sobel.hh --- mln/linear/sobel.hh (revision 1055) +++ mln/linear/sobel.hh (working copy) @@ -34,8 +34,7 @@ */ # include <mln/arith/plus.hh> -# include <mln/fun/v2v/abs.hh> -# include <mln/level/apply.hh> +# include <mln/level/abs.hh> # include <mln/linear/line_x2_convolve.hh> @@ -97,11 +96,14 @@ template <typename I, typename O> void sobel_(const Image<I>& input, Image<O>& output) { - O temp_h(exact(input).domain()), temp_v(exact(input).domain()); - sobel_h(input, temp_h); - sobel_v(input, temp_v); - arith::plus(temp_h, temp_v, output); - level::apply(exact(output), fun::v2v::abs<mln_value(O)>()); + // h + sobel_h(input, output); + // v + O temp(exact(input).domain()); + sobel_v(input, temp); + // output + arith::plus_inplace(output, temp); + level::abs_inplace(output); } } // end of namespace mln::linear::impl Index: mln/linear/line_x2_convolve.hh --- mln/linear/line_x2_convolve.hh (revision 1055) +++ mln/linear/line_x2_convolve.hh (working copy) @@ -59,7 +59,7 @@ typename W, unsigned Nr, unsigned Nc, typename O> void line_x2_convolve(const Image<I>& input, - const W (&row_weights)[Nr], const W (&col_weights)[Nc], + W (&row_weights)[Nr], W (&col_weights)[Nc], Image<O>& output); @@ -69,7 +69,7 @@ typename W, unsigned Nr, unsigned Nc, typename O> void line_x2_convolve(const Image<I>& input, - const W (&row_weights)[Nr], const W (&col_weights)[Nc], + W (&row_weights)[Nr], W (&col_weights)[Nc], Image<O>& output) { // FIXME: Check 2D. Index: mln/make/w_window_line.hh --- mln/make/w_window_line.hh (revision 1055) +++ mln/make/w_window_line.hh (working copy) @@ -52,13 +52,13 @@ * \return A window. */ template <typename D, typename W, unsigned L> - mln::w_window<D,W> w_window_line(const W (&w)[L]); + mln::w_window<D,W> w_window_line(W (&w)[L]); # ifndef MLN_INCLUDE_ONLY template <typename D, typename W, unsigned L> - mln::w_window<D,W> w_window_line(const W (&w)[L]) + mln::w_window<D,W> w_window_line(W (&w)[L]) { mln_precondition(L % 2 = 1); mln::w_window<D,W> w_win;
participants (1)
-
Thierry Geraud