
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add hit-or-miss and p2v ternary+elif functions. * tests/morpho_hit_or_miss.cc: New. * mln/fun/p2v/elifs.hh: New. * mln/fun/p2v/ternary.hh: New. * mln/morpho/min.hh: New. * mln/morpho/hit_or_miss.hh: New. * mln/arith/min.hh: New. * mln/value/int_u_sat.hh: New. * img/picasso.pgm: New. * mln/arith/revert.hh: Fix. * mln/morpho/includes.hh: Update. img/picasso.pgm | 0 mln/arith/min.hh | 147 ++++++++++++++++++++++++++ mln/arith/revert.hh | 2 mln/fun/p2v/elifs.hh | 84 +++++++++++++++ mln/fun/p2v/ternary.hh | 117 +++++++++++++++++++++ mln/morpho/hit_or_miss.hh | 243 ++++++++++++++++++++++++++++++++++++++++++++ mln/morpho/includes.hh | 4 mln/morpho/min.hh | 121 +++++++++++++++++++++ mln/value/int_u_sat.hh | 191 ++++++++++++++++++++++++++++++++++ tests/morpho_hit_or_miss.cc | 85 +++++++++++++++ 10 files changed, 992 insertions(+), 2 deletions(-) Index: tests/morpho_hit_or_miss.cc --- tests/morpho_hit_or_miss.cc (revision 0) +++ tests/morpho_hit_or_miss.cc (revision 0) @@ -0,0 +1,85 @@ +// 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/morpho_hit_or_miss.cc + * + * \brief Test on mln::morpho::hit_or_miss. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/win/rectangle2d.hh> +#include <mln/core/window2d.hh> +#include <mln/geom/shift.hh> +#include <mln/set/diff.hh> + +#include <mln/io/load_pgm.hh> +#include <mln/io/save_pgm.hh> +#include <mln/level/fill.hh> +#include <mln/level/stretch.hh> + +#include <mln/morpho/hit_or_miss.hh> + + +int main() +{ + using namespace mln; + using value::int_u8; + + window2d win_hit = geom::shift(win::rectangle2d(3, 3), + make::dpoint2d(+1, +1)); + window2d win_miss = set::diff(win::rectangle2d(5, 5), win_hit); + + { + bool hit[] = { 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1 }; + window2d win_hit_ = make::window2d(hit); + mln_precondition(win_hit_ = win_hit); + + bool miss[] = { 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0 }; + window2d win_miss_ = make::window2d(miss); + mln_precondition(win_miss_ = win_miss); + } + + border::thickness = 2; + + image2d_b<int_u8> + lena = io::load_pgm("../img/picasso.pgm"), + out(lena.domain()); + + morpho::hit_or_miss(lena, win_hit, win_miss, out); + + io::save_pgm(out, "out.pgm"); +} Index: mln/fun/p2v/elifs.hh --- mln/fun/p2v/elifs.hh (revision 0) +++ mln/fun/p2v/elifs.hh (revision 0) @@ -0,0 +1,84 @@ +// 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_P2V_ELIFS_HH +# define MLN_FUN_P2V_ELIFS_HH + +/*! \file mln/fun/p2v/elifs.hh + * + * \brief FIXME. + */ + +# include <mln/fun/p2v/ternary.hh> + + +namespace mln +{ + + namespace fun + { + + namespace p2v + { + + template <typename T1, typename N1, + typename T2, typename N2, + typename O> + ternary_<T1, N1, + ternary_<T2, N2, O> > + elifs(const Function_p2b<T1>& f_if_1, const Function_p2v<N1>& f_then_1, + const Function_p2b<T2>& f_if_2, const Function_p2v<N2>& f_then_2, + const Function_p2v<O>& f_otherwise); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename T1, typename N1, + typename T2, typename N2, + typename O> + ternary_<T1, N1, + ternary_<T2, N2, O> > + elifs(const Function_p2b<T1>& f_if_1, const Function_p2v<N1>& f_then_1, + const Function_p2b<T2>& f_if_2, const Function_p2v<N2>& f_then_2, + const Function_p2v<O>& f_otherwise) + { + typedef ternary_<T2, N2, O> T2_N2_O; + T2_N2_O f_otherwise_1(f_if_2, f_then_2, f_otherwise); + ternary_<T1, N1, T2_N2_O> tmp(f_if_1, f_then_1, f_otherwise_1); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::p2v + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_P2V_ELIFS_HH Index: mln/fun/p2v/ternary.hh --- mln/fun/p2v/ternary.hh (revision 0) +++ mln/fun/p2v/ternary.hh (revision 0) @@ -0,0 +1,117 @@ +// 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_P2V_TERNARY_HH +# define MLN_FUN_P2V_TERNARY_HH + +/*! \file mln/fun/p2v/ternary.hh + * + * \brief FIXME. + */ + +# include <mln/fun/internal/selector.hh> + + +namespace mln +{ + + namespace fun + { + + namespace p2v + { + + template <typename P, typename T, typename F> + struct ternary_ + : fun::internal::selector_p2_<mln_result(T), ternary_<P,T,F> >::ret + { + typedef mln_result(T) result; + + ternary_(const Function_p2b<P>& f_pred, + const Function_p2v<T>& f_true, + const Function_p2v<F>& f_false); + + template <typename Pt> + result operator()(const Pt& p) const; + + protected: + const P f_pred_; + const T f_true_; + const F f_false_; + }; + + + template <typename P, typename T, typename F> + ternary_<P, T, F> + ternary(const Function_p2b<P>& f_pred, + const Function_p2v<T>& f_true, + const Function_p2v<F>& f_false); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename P, typename T, typename F> + ternary_<P,T,F>::ternary_(const Function_p2b<P>& f_pred, + const Function_p2v<T>& f_true, + const Function_p2v<F>& f_false) + : f_pred_(exact(f_pred)), + f_true_(exact(f_true)), + f_false_(exact(f_false)) + { + } + + template <typename P, typename T, typename F> + template <typename Pt> + mln_result(T) + ternary_<P,T,F>::operator()(const Pt& p) const + { + return f_pred_(p) ? f_true_(p) : f_false_(p); + } + + + template <typename P, typename T, typename F> + ternary_<P, T, F> + ternary(const Function_p2b<P>& f_pred, + const Function_p2v<T>& f_true, + const Function_p2v<F>& f_false) + { + ternary_<P, T, F> tmp(exact(f_pred), + exact(f_true), + exact(f_false)); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::p2v + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_P2V_TERNARY_HH Index: mln/morpho/min.hh --- mln/morpho/min.hh (revision 0) +++ mln/morpho/min.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_MORPHO_MIN_HH +# define MLN_MORPHO_MIN_HH + +# include <mln/level/compare.hh> +# include <mln/logical/and.hh> +# include <mln/arith/min.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological min: either a logical "and" (if morpho on sets) + * or an arithmetical min (if morpho on functions). + */ + template <typename I, typename J, typename O> + void min(const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output); + + /*! Morphological min, inplace version: either a logical "and" (if + * morpho on sets) or an arithmetical min (if morpho on + * functions). + */ + template <typename I, typename J> + void min_inplace(Image<I>& lhs, const Image<J>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I, typename J, typename O> + void min_(value::binary_kind, // binary => morphology on sets + const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output) + { + return logical::and_(lhs, rhs, output); + } + + template <typename K, typename I, typename J, typename O> + void min_(K, // otherwise => morphology on functions + const Image<I>& lhs, const Image<J>& rhs, + Image<O>& output) + { + return arith::min(lhs, rhs, output); + } + + // in place + + template <typename I, typename J> + void min_inplace_(value::binary_kind, // binary => morphology on sets + Image<I>& lhs, const Image<J>& rhs) + { + return logical::and_inplace(lhs, rhs); + } + + template <typename K, typename I, typename J> + void min_inplace_(K, // otherwise => morphology on functions + Image<I>& lhs, const Image<J>& rhs) + { + return arith::min_inplace(lhs, rhs); + } + + } // end of namespace mln::morpho::impl + + + // Facades. + + template <typename I, typename J, typename O> + void min(const Image<I>& lhs, const Image<J>& rhs, Image<O>& output) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + mln_precondition(exact(output).domain() = exact(lhs).domain()); + impl::min_(mln_value_kind(I)(), exact(lhs), exact(rhs), output); + } + + template <typename I, typename J> + void min_inplace(Image<I>& lhs, const Image<J>& rhs) + { + mln_precondition(exact(rhs).domain() = exact(lhs).domain()); + impl::min_inplace_(mln_value_kind(I)(), exact(lhs), exact(rhs)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_MIN_HH Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 1062) +++ mln/morpho/includes.hh (working copy) @@ -49,13 +49,15 @@ # include <mln/border/fill.hh> # include <mln/geom/sym.hh> +# include <mln/set/inter.hh> # include <mln/morpho/dilation.hh> # include <mln/morpho/erosion.hh> +# include <mln/morpho/min.hh> +# include <mln/morpho/complementation.hh> # include <mln/morpho/minus.hh> # include <mln/morpho/plus.hh> -# include <mln/morpho/complementation.hh> #endif // ! MLN_MORPHO_INCLUDES_HH Index: mln/morpho/hit_or_miss.hh --- mln/morpho/hit_or_miss.hh (revision 0) +++ mln/morpho/hit_or_miss.hh (revision 0) @@ -0,0 +1,243 @@ +// 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_HIT_OR_MISS_HH +# define MLN_MORPHO_HIT_OR_MISS_HH + +/*! \file mln/morpho/hit_or_miss.hh + * + * \brief Morphological hit-or-miss. + * + * \todo Save memory. + */ + +# include <mln/morpho/includes.hh> +# include <mln/pw/all.hh> +# include <mln/fun/p2v/ternary.hh> + + +namespace mln +{ + + namespace morpho + { + + + bool constrained_hit_or_miss = true; + + + /*! Morphological hit-or-miss. + * + * This operator is HMT_(Bh,Bm) = e_Bh /\ (e_Bm o C). + */ + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output); + + /*! Morphological hit-or-miss opening. + * + * This operator is d_(-Bh) o HMT_(Bh,Bm). + */ + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_opening(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output); + + /*! Morphological hit-or-miss opening of the background. + * + * This operator is FIXME. + */ + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_background_opening(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output); + + /*! Morphological hit-or-miss closing. + * + * This operator is FIXME. + */ + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_closing(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output); + + /*! Morphological hit-or-miss closing of the background. + * + * This operator is FIXME. + */ + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_background_closing(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + // Preconditions. + + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_preconditions_(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + mln_precondition(set::inter(exact(win_hit), exact(win_miss)).is_empty()); + } + + // On sets. + + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_(value::binary_kind, // binary => morphology on sets + const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + erosion(input, win_hit, output); // output = ero(input)_hit + + O temp_1(exact(input).domain()); + complementation(input, temp_1); // temp1 = C(input) + + O temp_2(exact(input).domain()); + erosion(temp_1, win_miss, temp_2); // temp_2 = ero(C(input))_miss + + logical::and_inplace(output, temp_2); // output = ero(input)_hit /\ ero(C(input))_miss + } + + // On functions. + + template <typename K, + typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_(K, // otherwise => morphology on functions + const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + typedef mln_value(O) V; + + if (constrained_hit_or_miss) // CHMT. + { + if (exact(win_hit).is_centered()) + { + O ero_fg(exact(input).domain()), dil_bg(exact(input).domain()); + erosion(input, win_hit, ero_fg); + dilation(input, win_miss, dil_bg); + level::fill(output, + fun::p2v::ternary(pw::value(input) = pw::value(ero_fg) && pw::value(dil_bg) < pw::value(input), + pw::value(input) - pw::value(dil_bg), + pw::cst(V::zero))); + } + else if (exact(win_miss).is_centered()) + { + O ero_bg(exact(input).domain()), dil_fg(exact(input).domain()); + erosion(input, win_miss, ero_bg); + dilation(input, win_hit, dil_fg); + level::fill(output, + fun::p2v::ternary(pw::value(input) = pw::value(dil_fg) && pw::value(ero_bg) > pw::value(input), + pw::value(ero_bg) - pw::value(input), + pw::cst(V::zero))); + } + else + level::fill(output, pw::cst(V::zero)); + } + else // Unconstrained: UHMT. + { + O ero(exact(input).domain()), dil(exact(input).domain()); + erosion(input, win_hit, ero); + dilation(input, win_miss, dil); + level::fill(output, + fun::p2v::ternary(pw::value(dil) < pw::value(ero), + pw::value(ero) - pw::value(dil), + pw::cst(V::zero))); + } + } + + } // end of mln::morpho::impl + + + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output); + impl::hit_or_miss_(mln_value_kind(I)(), input, win_hit, win_miss, output); + } + + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_opening(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output); + + O temp(exact(input).domain()); + hit_or_miss(input, win_hit, win_miss, temp); + dilation(temp, geom::sym(win_hit), output); + } + + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_background_opening(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output); + hit_or_miss_opening(input, win_miss, win_hit, output); + } + + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_closing(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output); + I temp(input.domain()); + complementation(input, temp); + hit_or_miss_opening(temp, win_hit, win_miss, output); + complementation_inplace(output); + } + + template <typename I, typename Wh, typename Wm, typename O> + void hit_or_miss_background_closing(const Image<I>& input, + const Window<Wh>& win_hit, const Window<Wm>& win_miss, + Image<O>& output) + { + impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output); + hit_or_miss_closing(input, win_miss, win_hit, output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_HIT_OR_MISS_HH Index: mln/arith/min.hh --- mln/arith/min.hh (revision 0) +++ mln/arith/min.hh (revision 0) @@ -0,0 +1,147 @@ +// 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_ARITH_MIN_HH +# define MLN_ARITH_MIN_HH + +/*! \file mln/arith/min.hh + * + * \brief Point-wise min between images. + */ + +# include <mln/core/concept/image.hh> + + +namespace mln +{ + + namespace arith + { + + /*! Point-wise min of images \p lhs and \p rhs. + * + * \param[in] lhs First operand image. + * \param[in] rhs Second operand image. + * \param[out] output The result image. + * + * \pre \p output.domain = \p lhs.domain = \p rhs.domain + */ + template <typename L, typename R, typename O> + void min(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + + + /*! Point-wise min of image \p lhs in image \p rhs. + * + * \param[in,out] lhs First operand image. + * \param[in] rhs Second operand image. + * + * This substraction performs: \n + * for all p of rhs.domain \n + * if rhs(p) < lhs(p) \n + * lhs(p) = rhs(p) + * + * \pre \p rhs.domain <= \p lhs.domain + */ + template <typename L, typename R> + void min_inplace(Image<L>& lhs, const Image<R>& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename L, typename R, typename O> + void min_(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) ? lhs(p) : rhs(p); + } + + template <typename L, typename R, typename O> + void min_(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() ? lp.val() : rp.val(); + } + + template <typename L, typename R> + void min_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) + if (rhs(p) < lhs(p)) + lhs(p) = rhs(p); + } + + template <typename L, typename R> + void min_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) + if (rp.val() < lp.val()) + lp.val() = rp.val(); + } + + } // end of namespace mln::arith::impl + + + // Facades. + + template <typename L, typename R, typename O> + void min(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::min_(exact(lhs), exact(rhs), exact(output)); + } + + template <typename L, typename R> + void min_inplace(Image<L>& lhs, const Image<R>& rhs) + { + mln_precondition(exact(rhs).domain() <= exact(lhs).domain()); + impl::min_inplace_(exact(lhs), exact(rhs)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::arith + +} // end of namespace mln + + +#endif // ! MLN_ARITH_MIN_HH Index: mln/arith/revert.hh --- mln/arith/revert.hh (revision 1062) +++ mln/arith/revert.hh (working copy) @@ -95,7 +95,7 @@ mln_pixter(const I) ip(exact(input)); mln_pixter(O) op(exact(output)); for_all_2(ip, op) - op.val() = mln_min(V) + (mln_max(V) - op.val()); + op.val() = mln_min(V) + (mln_max(V) - ip.val()); } } // end of namespace mln::arith::impl Index: mln/value/int_u_sat.hh --- mln/value/int_u_sat.hh (revision 0) +++ mln/value/int_u_sat.hh (revision 0) @@ -0,0 +1,191 @@ +// 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_INT_U_SAT_HH +# define MLN_VALUE_INT_U_SAT_HH + +/*! \file mln/value/int_u_sat.hh + * + * \brief Define a generic class for unsigned integers with saturation + * behavior. + */ + +# include <mln/metal/math.hh> +# include <mln/value/internal/value_like.hh> +# include <mln/value/internal/encoding.hh> +# include <mln/value/props.hh> +# include <mln/debug/format.hh> + + +namespace mln +{ + + namespace value + { + + + /*! \brief Unsigned integer value class with saturation behavior. + * + * The parameter is \c n the number of encoding bits. + */ + template <unsigned n> + struct int_u_sat + : public internal::value_like_< typename internal::encoding_unsigned_<n>::ret, + int_u_sat<n> > + { + protected: + typedef internal::value_like_< typename internal::encoding_unsigned_<n>::ret, + int_u_sat<n> > super; + + public: + + /// Encoding associated type. + typedef typename super::enc enc; + + /// Constructor without argument. + int_u_sat(); + + /// Constructor from an integer. + int_u_sat(int i); + + /// Assignment from an integer. + int_u_sat<n>& operator=(int i); + + /// Zero value. + static const int_u_sat<n> zero; + + /// Unit value. + static const int_u_sat<n> one; + + /// Self addition. + int_u_sat<n>& operator+=(int i); + + /// Self subtraction. + int_u_sat<n>& operator-=(int i); + }; + + + // Safety. + template <> struct int_u_sat<0>; + template <> struct int_u_sat<1>; + + + + template <unsigned n> + struct props< int_u_sat<n> > + { + static const std::size_t card_ = metal::pow<2, n>::value; + static const int_u_sat<n> min() { return 0; } + static const int_u_sat<n> max() { return card_ - 1; } + static const unsigned nbits = n; + typedef data_kind kind; + typedef float sum; + }; + + + + /*! \brief Print a saturated unsigned integer \p i into the output + * stream \p ostr. + * + * \param[in,out] ostr An output stream. + * \param[in] i A saturated unsigned integer. + * + * \return The modified output stream \p ostr. + */ + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const int_u_sat<n>& i); + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n> + int_u_sat<n>::int_u_sat() + { + } + + template <unsigned n> + int_u_sat<n>::int_u_sat(int i) + { + if (i < 0) + this->v_ = enc(0); + else if (i > mln_max(enc)) + this->v_ = mln_max(enc); + else + this->v_ = enc(i); + } + + template <unsigned n> + int_u_sat<n>& + int_u_sat<n>::operator=(int i) + { + if (i < 0) + this->v_ = enc(0); + else if (i > mln_max(enc)) + this->v_ = mln_max(enc); + else + this->v_ = enc(i); + return *this; + } + + template <unsigned n> + int_u_sat<n>& + int_u_sat<n>::operator+=(int i) + { + int v = int(this->v_) + i; + *this = v; + return *this; + } + + template <unsigned n> + int_u_sat<n>& + int_u_sat<n>::operator-=(int i) + { + int v = int(this->v_) - i; + *this = v; + return *this; + } + + template <unsigned n> + const int_u_sat<n> int_u_sat<n>::zero = 0; + + template <unsigned n> + const int_u_sat<n> int_u_sat<n>::one = 1; + + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const int_u_sat<n>& i) + { + return ostr << debug::format(i.to_equiv()); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_INT_U_SAT_HH Index: img/picasso.pgm Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: img/picasso.pgm ___________________________________________________________________ Name: svn:mime-type + application/octet-stream