
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Augment tools for linear filtering; add sobel. * mln/core/decorated_image.hh (helper_decorated_image_write_): Replace by... (decorated_image_impl_): ...this. (impl_): New. (lvalue): Update. (write_): Remove; now in impl_. * mln/value/all.hh: Update. * mln/value/props.hh, * mln/value/int_u.hh, * mln/value/int_s.hh (min, max): Change to proc. * mln/value/props.hh (mln_min, mln_max): Update. (epsilon): Change to proc. * mln/value/aliases.hh: New. * mln/level/stretch.hh: Update. * mln/arith/abs.hh: New. * mln/arith/plus.hh: Overload. * mln/fun/v2v/abs.hh: New. * mln/level/apply.hh: Fix meaning; add todo. * mln/math/abs.hh: Overload. * mln/core/concept/iterator.hh (for_all_3): New. * mln/math/round_sat.hh: New. * mln/make/w_window_line.hh: New. * mln/metal/abort.hh: New. * mln/linear/line_convolve.hh: New. * mln/linear/line_x2_convolve.hh: New. * mln/linear/sobel.hh: New. * tests/line_convolve.cc: New. * tests/sobel.cc: New. mln/arith/plus.hh | 34 ++++++++- mln/core/concept/iterator.hh | 9 ++ mln/core/decorated_image.hh | 55 +++++++++------- mln/fun/v2v/abs.hh | 77 ++++++++++++++++++++++ mln/level/apply.hh | 42 +++++------- mln/level/stretch.hh | 2 mln/linear/convolve.hh | 8 +- mln/linear/hconvolve.hh | 109 +++++++++++++++++++++++++++++++ mln/linear/line_convolve.hh | 82 ++++++++++++++++++++++++ mln/linear/line_x2_convolve.hh | 92 ++++++++++++++++++++++++++ mln/linear/sobel.hh | 140 +++++++++++++++++++++++++++++++++++++++++ mln/make/w_window_line.hh | 81 +++++++++++++++++++++++ mln/math/abs.hh | 13 +++ mln/math/round_sat.hh | 83 ++++++++++++++++++++++++ mln/metal/abort.hh | 50 ++++++++++++++ mln/value/aliases.hh | 43 ++++++++++++ mln/value/all.hh | 9 ++ mln/value/int_s.hh | 23 ++---- mln/value/int_u.hh | 13 --- mln/value/props.hh | 52 +++++++-------- tests/line_convolve.cc | 64 ++++++++++++++++++ tests/sobel.cc | 62 ++++++++++++++++++ 22 files changed, 1034 insertions(+), 109 deletions(-) Index: tests/sobel.cc --- tests/sobel.cc (revision 0) +++ tests/sobel.cc (revision 0) @@ -0,0 +1,62 @@ +// 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/sobel.cc + * + * \brief Tests on mln::linear::sobel. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/value/int_u8.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> + + +int main() +{ + using namespace mln; + using value::int_u8; + + border::thickness = 1; + + image2d_b<int_u8> + lena = io::load_pgm("../img/lena.pgm"), + out(lena.domain()); + + image2d_b<int> tmp(lena.domain()); + linear::sobel(lena, tmp); + + level::transform(tmp, math::round_sat_<int_u8>(), out); + io::save_pgm(out, "out.pgm"); +} Index: tests/line_convolve.cc --- tests/line_convolve.cc (revision 0) +++ tests/line_convolve.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/line_convolve.cc + * + * \brief Tests on mln::linear::line_convolve. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/value/int_u8.hh> + +#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> +#include <mln/border/thickness.hh> +#include <mln/linear/line_convolve.hh> + + +int main() +{ + using namespace mln; + using value::int_u8; + + border::thickness = 4; + + image2d_b<int_u8> + lena = io::load_pgm("../img/lena.pgm"), + out(lena.domain()); + + image2d_b<float> tmp(lena.domain()); + 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); + io::save_pgm(out, "out.pgm"); +} Index: mln/core/decorated_image.hh --- mln/core/decorated_image.hh (revision 1054) +++ mln/core/decorated_image.hh (working copy) @@ -35,13 +35,39 @@ namespace mln { + // Fwd decl. + template <typename I, typename D> class decorated_image; + + + namespace internal + { + + template <typename I, typename E> + struct decorated_image_impl_ + { + typedef mln::value::proxy<E> lvalue; + void write_(const mln_psite(I)& p, const mln_value(I)& v); + }; + + template <typename I, typename E> + struct decorated_image_impl_< const I, E > + { + typedef mln::value::proxy<const E> lvalue; + }; + + } // end of namespace::internal + + + // FIXME: Doc! template <typename I, typename D> - class decorated_image : public internal::image_adaptor_< I, decorated_image<I,D> > + class decorated_image : public internal::image_adaptor_< I, decorated_image<I,D> >, + public internal::decorated_image_impl_< I, decorated_image<I,D> > { typedef decorated_image<I, D> self_; typedef internal::image_adaptor_< I, self_ > super_; + typedef internal::decorated_image_impl_< I, self_ > impl_; public: decorated_image(I& ima, const D& deco); @@ -49,13 +75,12 @@ typedef mln_value(I) value; typedef mln::value::proxy<const self_> rvalue; - typedef mln::value::proxy<self_> lvalue; + typedef typename impl_::lvalue lvalue; rvalue operator()(const mln_psite(I)& p) const; lvalue operator()(const mln_psite(I)& p); mln_value(I) read_(const mln_psite(I)& p) const; - void write_(const mln_psite(I)& p, const mln_value(I)& v); template <typename V> struct change_value @@ -110,7 +135,7 @@ } template <typename I, typename D> - mln::value::proxy< const decorated_image<I,D> > + typename decorated_image<I,D>::rvalue decorated_image<I,D>::operator()(const mln_psite(I)& p) const { rvalue tmp(*this, p); @@ -118,7 +143,7 @@ } template <typename I, typename D> - mln::value::proxy< decorated_image<I,D> > + typename decorated_image<I,D>::lvalue decorated_image<I,D>::operator()(const mln_psite(I)& p) { lvalue tmp(*this, p); @@ -128,32 +153,18 @@ namespace internal { - template <typename I, typename D> + template <typename I, typename E> void - helper_decorated_image_write_(decorated_image<I,D>& ima, - const mln_psite(I)& p, const mln_value(I)& v) + decorated_image_impl_<I,E>::write_(const mln_psite(I)& p, const mln_value(I)& v) { + E& ima = internal::force_exact<E>(*this); ima.decoration().writing(ima.adaptee(), p, v); ima.adaptee()(p) = v; } - template <typename I, typename D> - void - helper_decorated_image_write_(decorated_image<const I,D>&, - const mln_psite(I)&, const mln_value(I)&) - // FIXME: Static assertion instead. - ; - } // end of namespace mln::internal template <typename I, typename D> - void - decorated_image<I,D>::write_(const mln_psite(I)& p, const mln_value(I)& v) - { - internal::helper_decorated_image_write_(*this, p, v); - } - - template <typename I, typename D> mln_value(I) decorated_image<I,D>::read_(const mln_psite(I)& p) const { Index: mln/core/concept/iterator.hh --- mln/core/concept/iterator.hh (revision 1054) +++ mln/core/concept/iterator.hh (working copy) @@ -46,6 +46,15 @@ # define for_all_2(x1, x2) for(x1.start(),x2.start(); x1.is_valid(); x1.next(),x2.next()) +/*! \brief Loop to browse all the elements targetted by the triplet of + * iterators \p x1, \p x2, and \p x3. + */ +# define for_all_3(x1, x2, x3) \ + for(x1.start(), x2.start(), x3.start(); \ + x1.is_valid(); \ + x1.next(), x2.next(), x3.next()) + + /*! \brief Loop to browse all the remaining elements targetted by the * iterator \p x. */ Index: mln/fun/v2v/abs.hh --- mln/fun/v2v/abs.hh (revision 0) +++ mln/fun/v2v/abs.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_ABS_HH +# define MLN_FUN_V2V_ABS_HH + +/*! \file mln/fun/v2v/abs.hh + * + * \brief FIXME. + */ + +# include <mln/core/concept/function.hh> +# include <mln/math/abs.hh> + + +namespace mln +{ + + namespace fun + { + + namespace v2v + { + + // FIXME: Doc! + + template <typename V> + struct abs : public Function_v2v< abs<V> > + { + typedef V result; + V operator()(const V& v) const; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename V> + V + abs<V>::operator()(const V& v) const + { + return mln::math::abs(v); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::v2v + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_V2V_ABS_HH Index: mln/math/abs.hh --- mln/math/abs.hh (revision 1054) +++ mln/math/abs.hh (working copy) @@ -34,6 +34,7 @@ */ # include <cmath> +# include <mln/value/all.hh> @@ -55,6 +56,18 @@ return std::abs(v); } + template <unsigned n> + value::int_u<n> abs(const value::int_u<n>& v) + { + return v; + } + + template <unsigned n> + value::int_s<n> abs(const value::int_s<n>& v) + { + return std::abs(v.to_enc()); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::math Index: mln/math/round_sat.hh --- mln/math/round_sat.hh (revision 0) +++ mln/math/round_sat.hh (revision 0) @@ -0,0 +1,83 @@ +// 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_MATH_ROUND_SAT_HH +# define MLN_MATH_ROUND_SAT_HH + +/*! \file mln/math/round_sat.hh + * + * \brief Define round_sat routine. + */ + +# include <cmath> + +# include <mln/core/concept/function.hh> +# include <mln/value/props.hh> + + + +namespace mln +{ + + namespace math + { + + + template <typename R> + struct round_sat_ : public Function_v2v< round_sat_<R> > + { + typedef R result; + + template <typename T> + result operator()(const T& v) const; + + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename R> + template <typename T> + R round_sat_<R>::operator()(const T& v) const + { + long int l = (long int)(v + 0.49999); // FIXME: !!! + return + l < mln_min(R) + ? mln_min(R) + : (l > mln_max(R) + ? mln_max(R) + : R(l)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::math + +} // end of namespace mln + + +#endif // ! MLN_MATH_ROUND_SAT_HH Index: mln/metal/abort.hh --- mln/metal/abort.hh (revision 0) +++ mln/metal/abort.hh (revision 0) @@ -0,0 +1,50 @@ +// 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_METAL_ABORT_HH +# define MLN_METAL_ABORT_HH + +# include <mln/metal/bool.hh> + + +namespace mln +{ + + namespace metal + { + + template <typename T> + struct abort : false_ + {}; + + + } // end of namespace mln::metal + +} // end of namespace mln + + +#endif // ! MLN_METAL_ABORT_HH Index: mln/level/apply.hh --- mln/level/apply.hh (revision 1054) +++ mln/level/apply.hh (working copy) @@ -34,7 +34,7 @@ */ # include <mln/core/concept/image.hh> -# include <mln/core/concept/accumulator.hh> +# include <mln/core/concept/function.hh> namespace mln @@ -45,19 +45,19 @@ /*! Apply a function-object to the image \p input. * - * \param[in] input The input image. + * \param[in,out] input The input image. * \param[in] f The function-object. - * \result A copy of the function-object. * * This routine runs: \n - * for all p of \p input, \p f( \p input(p) ) \n - * return \p f + * for all p of \p input, \p input(p) = \p f( \p input(p) ) \n * - * \todo Find a meaning for this routine! (Clue: f is mutable - * and/or same for input?) + * This routine is equivalent to level::tranform(input, f, input) + * but it is faster since a single iterator is required. + * + * \todo Add versions for lowq images. */ template <typename I, typename F> - F apply(const Image<I>& input, const Function<F>& f); + void apply(Image<I>& input, const Function_v2v<F>& f); @@ -67,39 +67,33 @@ { template <typename I, typename F> - F apply(const Image<I>& input_, const Function<F>& f_) + void apply_(Image<I>& input_, const F& f) { - const I& input = exact(input_); - F f = exact(f_); - + I& input = exact(input_); mln_piter(I) p(input.domain()); for_all(p) - f(input(p)); - return f; + input(p) = f(input(p)); } template <typename I, typename F> - F apply(const Fast_Image<I>& input_, const Function<F>& f_) + void apply_(Fast_Image<I>& input_, const F& f) { - const I& input = exact(input_); - F f = exact(f_); - - mln_pixter(const I) pxl(input); + I& input = exact(input_); + mln_pixter(I) pxl(input); for_all(pxl) - f(pxl.val()); - return f; + pxl.val() = f(pxl.val()); } } // end of namespace mln::level::impl - // Facades. + // Facade. template <typename I, typename F> - F apply(const Image<I>& input, const Function<F>& f) + void apply(Image<I>& input, const Function_v2v<F>& f) { mln_precondition(exact(input).has_data()); - return impl::apply(exact(input), f); + impl::apply_(exact(input), exact(f)); } # endif // ! MLN_INCLUDE_ONLY Index: mln/level/stretch.hh --- mln/level/stretch.hh (revision 1054) +++ mln/level/stretch.hh (working copy) @@ -71,7 +71,7 @@ if (max_ = min_) return; // FIXME float min = float(min_), max = float(max_); - const float epsilon = value::props<float>::epsilon; + const float epsilon = value::props<float>::epsilon(); float m = 0.0f - 0.5f + epsilon; float M = mln_max(value::int_u<n>) + 0.5f - epsilon; float a = (M - m) / (max - min); Index: mln/arith/plus.hh --- mln/arith/plus.hh (revision 1054) +++ mln/arith/plus.hh (working copy) @@ -57,21 +57,43 @@ # ifndef MLN_INCLUDE_ONLY + namespace impl + { + template <typename L, typename R, typename O> - void plus(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_) + void plus_(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_precondition(rhs.domain() = lhs.domain()); - mln_precondition(output.domain() = lhs.domain()); - - mln_piter(I) p(output.domain()); + mln_piter(L) p(lhs.domain()); for_all(p) output(p) = lhs(p) + rhs(p); } + template <typename L, typename R, typename O> + void plus_(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(); + } + + } // end of namespace mln::arith::impl + + + // Facade. + + template <typename L, typename R, typename O> + void plus(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::plus_(exact(lhs), exact(rhs), exact(output)); + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::arith Index: mln/linear/line_convolve.hh --- mln/linear/line_convolve.hh (revision 0) +++ mln/linear/line_convolve.hh (revision 0) @@ -0,0 +1,82 @@ +// 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_LINEAR_LINE_CONVOLVE_HH +# define MLN_LINEAR_LINE_CONVOLVE_HH + +/*! \file mln/linear/line_convolve.hh + * + * \brief Convolution by a line-shaped kernel. + */ + +# include <mln/linear/convolve.hh> +# include <mln/make/w_window_line.hh> + + + +namespace mln +{ + + namespace linear + { + + /*! Convolution of an image \p input by a line-shaped weighted + * window defined by the array of \p weights. + * + * \warning Computation of \p output(p) is performed with the + * value type of \p output. + * + * \warning The weighted window is used as-is, considering that + * its symmetrization is handled by the client. + * + * \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], + 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], + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + linear::convolve(input, + make::w_window_line<mln_dpoint(I)>(weights), + output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::linear + +} // end of namespace mln + + +#endif // ! MLN_LINEAR_LINE_CONVOLVE_HH Index: mln/linear/hconvolve.hh --- mln/linear/hconvolve.hh (revision 0) +++ mln/linear/hconvolve.hh (revision 0) @@ -0,0 +1,109 @@ +// 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_LINEAR_LINE_CONVOLVE_HH +# define MLN_LINEAR_LINE_CONVOLVE_HH + +/*! \file mln/linear/line_convolve.hh + * + * \brief Convolution by an horizontal kernel. + */ + +# include <vector> + +# include <mln/linear/convolve.hh> +# include <mln/make/w_window_line.hh> +# include <mln/core/t_image.hh> + + + +namespace mln +{ + + namespace linear + { + + /*! Convolution of an image \p input by an horizontal weighted + * window defined by the array of \p weights. + * + * \warning Computation of \p output(p) is performed with the + * value type of \p output. + * + * \warning The weighted window is used as-is, considering that + * its symmetrization is handled by the client. + * + * \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], + Image<O>& output); + + // FIXME: Doc! + template <typename I, typename W, unsigned Nr, unsigned Nc, typename O> + void line_convolve(const Image<I>& input, + const W (&row_weights)[Nr], const W (&col_weights)[Nc], + 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], + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + linear::convolve(input, + make::w_window_line<mln_dpoint(I)>(weights), + output); + } + + + template <typename I, typename W, unsigned Nr, unsigned Nc, typename O> + void line_convolve(const Image<I>& input, + const W (&row_weights)[Nr], const W (&col_weights)[Nc], + Image<O>& output) + { + // FIXME: Check 2D. + mln_precondition(exact(output).domain() = exact(input).domain()); + O tmp(exact(output).domain()); + linear::convolve(input, + make::w_window_line<mln_dpoint(I)>(row_weights), + tmp); + t_image<O> swap_output = swap_coords(output, 0, 1); + linear::convolve(swap_coords(tmp, 0, 1), + make::w_window_line<mln_dpoint(I)>(col_weights), + swap_output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::linear + +} // end of namespace mln + + +#endif // ! MLN_LINEAR_LINE_CONVOLVE_HH Index: mln/linear/sobel.hh --- mln/linear/sobel.hh (revision 0) +++ mln/linear/sobel.hh (revision 0) @@ -0,0 +1,140 @@ +// 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_LINEAR_SOBEL_HH +# define MLN_LINEAR_SOBEL_HH + +/*! \file mln/linear/sobel.hh + * + * \brief Sobel filter. + */ + +# include <mln/arith/plus.hh> +# include <mln/fun/v2v/abs.hh> +# include <mln/level/apply.hh> +# include <mln/linear/line_x2_convolve.hh> + + + +namespace mln +{ + + namespace linear + { + + /*! Convolution of an image \p input by the weighted window \p w_win. + * + * \warning Computation of \p output(p) is performed with the + * value type of \p output. + * + * \warning The weighted window is used as-is, considering that + * its symmetrization is handled by the client. + * + * \pre output.domain = input.domain + * + * \todo Only for 2D so check + generalize. + * + * \todo Suboptimal since it is not point-wise and it costs temp + * images. + */ + template <typename I, typename O> + void sobel_v(const Image<I>& input, Image<O>& output); + + template <typename I, typename O> + void sobel_h(const Image<I>& input, Image<O>& output); + + template <typename I, typename O> + void sobel(const Image<I>& input, Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename O> + void sobel_h_(const Image<I>& input, Image<O>& output) + { + int wrow[] = { -1, 0, 1 }, wcol[] = { 1, + 2, + 1 }; + linear::line_x2_convolve(input, wrow, wcol, output); + } + + template <typename I, typename O> + void sobel_v_(const Image<I>& input, Image<O>& output) + { + int wrow[] = { 1, 2, 1 }, wcol[] = { -1, + 0, + +1 }; + linear::line_x2_convolve(input, wrow, wcol, output); + } + + 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)>()); + } + + } // end of namespace mln::linear::impl + + + // Facades. + + template <typename I, typename O> + void sobel_h(const Image<I>& input, Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + impl::sobel_h_(exact(input), exact(output)); + } + + template <typename I, typename O> + void sobel_v(const Image<I>& input, Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + impl::sobel_v_(exact(input), exact(output)); + } + + template <typename I, typename O> + void sobel(const Image<I>& input, Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + impl::sobel_(exact(input), exact(output)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::linear + +} // end of namespace mln + + +#endif // ! MLN_LINEAR_SOBEL_HH Index: mln/linear/convolve.hh --- mln/linear/convolve.hh (revision 1054) +++ mln/linear/convolve.hh (working copy) @@ -46,7 +46,7 @@ namespace linear { - /*! Convolution of image \p input by the weighted window \p w_win. + /*! Convolution of an image \p input by the weighted window \p w_win. * * \warning Computation of \p output(p) is performed with the * value type of \p output. @@ -67,7 +67,7 @@ { template <typename I, typename W, typename O> - void convolve(const Image<I>& input_, const Weighted_Window<W>& w_win_, + void convolve_(const Image<I>& input_, const Weighted_Window<W>& w_win_, Image<O>& output_) { const I& input = exact(input_); @@ -87,7 +87,7 @@ } template <typename I, typename W, typename O> - void convolve(const Fast_Image<I>& input_, const Weighted_Window<W>& w_win_, + void convolve_(const Fast_Image<I>& input_, const Weighted_Window<W>& w_win_, Fast_Image<O>& output_) { const I& input = exact(input_); @@ -122,7 +122,7 @@ Image<O>& output) { mln_precondition(exact(output).domain() = exact(input).domain()); - impl::convolve(exact(input), exact(w_win), exact(output)); + impl::convolve_(exact(input), exact(w_win), exact(output)); } # endif // ! MLN_INCLUDE_ONLY Index: mln/linear/line_x2_convolve.hh --- mln/linear/line_x2_convolve.hh (revision 0) +++ mln/linear/line_x2_convolve.hh (revision 0) @@ -0,0 +1,92 @@ +// 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_LINEAR_LINE_X2_CONVOLVE_HH +# define MLN_LINEAR_LINE_X2_CONVOLVE_HH + +/*! \file mln/linear/line_x2_convolve.hh + * + * \brief 2D convolution by a couple of line kernels. + */ + +# include <mln/linear/line_convolve.hh> +# include <mln/core/t_image.hh> + + + +namespace mln +{ + + namespace linear + { + + /*! Convolution of an image \p input by two weighted line-shapes + * windows. + * + * \warning Computation of \p output(p) is performed with the + * value type of \p output. + * + * \warning The weighted window is used as-is, considering that + * its symmetrization is handled by the client. + * + * \pre output.domain = input.domain + */ + template <typename I, + 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], + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, + 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], + Image<O>& output) + { + // FIXME: Check 2D. + mln_precondition(exact(output).domain() = exact(input).domain()); + + O tmp(exact(output).domain()); + linear::line_convolve(input, row_weights, tmp); + + t_image<O> swap_output = swap_coords(output, 0, 1); + linear::line_convolve(swap_coords(tmp, 0, 1), col_weights, swap_output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::linear + +} // end of namespace mln + + +#endif // ! MLN_LINEAR_LINE_X2_CONVOLVE_HH Index: mln/value/aliases.hh --- mln/value/aliases.hh (revision 0) +++ mln/value/aliases.hh (revision 0) @@ -0,0 +1,43 @@ +// 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_VALUE_ALIASES_HH +# define MLN_VALUE_ALIASES_HH + +/*! \file mln/value/aliases.hh + * + * \brief File that includes all aliases of value types. + */ + + +# include <mln/value/int_u8.hh> +# include <mln/value/int_u16.hh> + +# include <mln/value/int_s8.hh> + + +#endif // ! MLN_VALUE_ALIASES_HH Index: mln/value/props.hh --- mln/value/props.hh (revision 1054) +++ mln/value/props.hh (working copy) @@ -42,11 +42,11 @@ /// Get the minimum value of type \c T. -# define mln_min(T) mln::value::props< T >::min +# define mln_min(T) mln::value::props< T >::min() /// Get the maximum value of type \c T. -# define mln_max(T) mln::value::props< T >::max +# define mln_max(T) mln::value::props< T >::max() /// Get the number of values for value type \c T. @@ -108,8 +108,8 @@ template <> struct props<bool> { - static const bool min = false; - static const bool max = true; + static const bool min() { return false; } + static const bool max() { return true; } static const std::size_t card_ = 2; typedef binary_kind kind; }; @@ -120,8 +120,8 @@ template <> struct props<unsigned char> { - static const unsigned char min = 0; - static const unsigned char max = 255; + static const unsigned char min() { return 0; } + static const unsigned char max() { return 255; } static const std::size_t card_ = 256; typedef data_kind kind; typedef float sum; @@ -130,8 +130,8 @@ template <> struct props<signed char> { - static const signed char min = -128; - static const signed char max = 127; + static const signed char min() { return -128; } + static const signed char max() { return 127; } static const std::size_t card_ = 256; typedef data_kind kind; typedef float sum; @@ -140,8 +140,8 @@ template <> struct props<unsigned short> { - static const unsigned short min = 0; - static const unsigned short max = 65535; + static const unsigned short min() { return 0; } + static const unsigned short max() { return 65535; } static const std::size_t card_ = 65536; typedef data_kind kind; typedef float sum; @@ -150,8 +150,8 @@ template <> struct props<signed short> { - static const signed short min = -32768; - static const signed short max = 32767; + static const signed short min() { return -32768; } + static const signed short max() { return 32767; } static const std::size_t card_ = 655356; typedef data_kind kind; typedef float sum; @@ -160,8 +160,8 @@ template <> struct props<unsigned int> { - static const unsigned int min = 0; - static const unsigned int max = UINT_MAX; + static const unsigned int min() { return 0; } + static const unsigned int max() { return UINT_MAX; } typedef data_kind kind; static const std::size_t card_ = 0; typedef float sum; @@ -170,8 +170,8 @@ template <> struct props<signed int> { - static const signed int min = INT_MIN; - static const signed int max = INT_MAX; + static const signed int min() { return INT_MIN; } + static const signed int max() { return INT_MAX; } typedef data_kind kind; static const std::size_t card_ = 0; typedef float sum; @@ -180,8 +180,8 @@ template <> struct props<unsigned long int> { - static const unsigned long int min = 0; - static const unsigned long int max = ULONG_MAX; + static const unsigned long int min() { return 0; } + static const unsigned long int max() { return ULONG_MAX; } typedef data_kind kind; static const std::size_t card_ = 0; typedef float sum; @@ -190,8 +190,8 @@ template <> struct props<signed long int> { - static const signed long int min = LONG_MIN; - static const signed long int max = LONG_MAX; + static const signed long int min() { return LONG_MIN; } + static const signed long int max() { return LONG_MAX; } typedef data_kind kind; static const std::size_t card_ = 0; typedef float sum; @@ -203,9 +203,9 @@ template <> struct props<float> { - static const float min = FLT_MIN; - static const float max = FLT_MAX; - static const float epsilon = 0.00001f; + static const float min() { return FLT_MIN; } + static const float max() { return FLT_MAX; } + static const float epsilon() { return 0.00001f; } typedef data_kind kind; static const std::size_t card_ = 0; typedef float sum; @@ -214,9 +214,9 @@ template <> struct props<double> { - static const double min = DBL_MIN; - static const double max = DBL_MAX; - static const double epsilon = 0.0000001; + static const double min() { return DBL_MIN; } + static const double max() { return DBL_MAX; } + static const double epsilon() { return 0.0000001; } typedef data_kind kind; static const std::size_t card_ = 0; typedef double sum; Index: mln/value/all.hh --- mln/value/all.hh (revision 1054) +++ mln/value/all.hh (working copy) @@ -44,7 +44,16 @@ } +# include <mln/value/aliases.hh> +# include <mln/value/label.hh> # include <mln/value/props.hh> +# include <mln/value/proxy.hh> + + +// FIXME: that includes concept/image.hh! + +// # include <mln/value/cast.hh> +// # include <mln/value/stack.hh> Index: mln/value/int_s.hh --- mln/value/int_s.hh (revision 1054) +++ mln/value/int_s.hh (working copy) @@ -89,23 +89,24 @@ + // Safety. + template <> struct int_s<0>; + template <> struct int_s<1>; + + + template <unsigned n> struct props< int_s<n> > { - static const int_s<n> max; // = 2^(n-1) - 1 - static const int_s<n> min; // = - max static const std::size_t card_ = metal::pow<2, n>::value; + static const int_s<n> max() { return metal::pow<2, n-1>::value - 1; } + static const int_s<n> min() { return - max(); } static const unsigned nbits = n; typedef data_kind kind; typedef float sum; }; - // Safety. - template <> struct int_s<0>; - template <> struct int_s<1>; - - /*! \brief Print an signed integer \p i into the output stream \p ostr. * @@ -167,14 +168,6 @@ const int_s<n> int_s<n>::one = 1; template <unsigned n> - const int_s<n> - props< int_s<n> >::min = 1 - metal::pow<2, n - 1>::value; - - template <unsigned n> - const int_s<n> - props< int_s<n> >::max = metal::pow<2, n - 1>::value - 1; - - template <unsigned n> std::ostream& operator<<(std::ostream& ostr, const int_s<n>& i) { return ostr << debug::format(i.to_equiv()); Index: mln/value/int_u.hh --- mln/value/int_u.hh (revision 1054) +++ mln/value/int_u.hh (working copy) @@ -95,8 +95,8 @@ struct props< int_u<n> > { static const std::size_t card_ = metal::pow<2, n>::value; - static const int_u<n> min; // = 0 - static const int_u<n> max; // = card_ - 1 + static const int_u<n> min() { return 0; } + static const int_u<n> max() { return card_ - 1; } static const unsigned nbits = n; typedef data_kind kind; typedef float sum; @@ -156,15 +156,6 @@ template <unsigned n> const int_u<n> int_u<n>::one = 1; - - template <unsigned n> - const int_u<n> - props< int_u<n> >::min = 0; - - template <unsigned n> - const int_u<n> - props< int_u<n> >::max = metal::pow<2, n>::value - 1; - template <unsigned n> std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i) { Index: mln/make/w_window_line.hh --- mln/make/w_window_line.hh (revision 0) +++ mln/make/w_window_line.hh (revision 0) @@ -0,0 +1,81 @@ +// 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_MAKE_W_WINDOW_LINE_HH +# define MLN_MAKE_W_WINDOW_LINE_HH + +/*! \file mln/make/w_window_line.hh + * + * \brief Routine to create an horizontal mln::w_window. + */ + +# include <mln/core/w_window.hh> + + +namespace mln +{ + + namespace make + { + + /*! \brief Create an horizontal centered and symmetrical + * mln::w_window. + * + * The free parameter \c D is a type of delta-point. + * + * \pre The window length \c L has to be odd. + * + * \return A window. + */ + template <typename D, typename W, unsigned L> + mln::w_window<D,W> w_window_line(const 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_precondition(L % 2 = 1); + mln::w_window<D,W> w_win; + D dp = D::zero; + for (unsigned i = 0; i < L; ++i) + { + dp[D::dim - 1] = i - L / 2; + w_win.insert(w[i], dp); + } + return w_win; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::make + +} // end of namespace mln + + +#endif // ! MLN_MAKE_W_WINDOW_LINE_HH