milena r1274: Refactoring erosion with dispatch mecanism and tracing

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-10-08 Simon Nivault <simon.nivault@lrde.epita.fr> Refactoring erosion with dispatch mecanism and tracing. * mln/morpho/erosion.hh: Add fastest image version. * mln/morpho/erosion.spe.hh: New. * mln/morpho/includes.hh: Includes min_h and max_h. --- erosion.hh | 108 +++----------------- erosion.spe.hh | 294 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ includes.hh | 2 3 files changed, 313 insertions(+), 91 deletions(-) Index: trunk/milena/mln/morpho/erosion.spe.hh =================================================================== --- trunk/milena/mln/morpho/erosion.spe.hh (revision 0) +++ trunk/milena/mln/morpho/erosion.spe.hh (revision 1274) @@ -0,0 +1,294 @@ +// 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_EROSION_SPE_HH +# define MLN_MORPHO_EROSION_SPE_HH + +/*! \file mln/morpho/erosion.spe.hh + * + * \brief Specialization for mln::morpho::erosion. + */ + +# ifndef MLN_INCLUDE_ONLY + +namespace mln +{ + + namespace morpho + { + + // Fwd decl. + template <typename I, typename W, typename O> + void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output); + + namespace impl + { + + namespace generic + { + // Fwd decl. + template <typename I, typename W, typename O, typename A> + void erosion_on_function(const I& input, const W& win, O& output, A& min); + + // Fwd decl. + template <typename I, typename W, typename O> + void erosion_on_set(const I& input, const W& win, O& output); + } + + + template <typename I, typename W, typename O, typename A> + void erosion_on_function_fast(const I& input, const W& win, O& output, A& min) + { + trace::entering("morpho::impl::erosion_on_function_fast"); + border::fill(input, mln_max(mln_value(I))); + + mln_pixter(const I) p(input); + mln_pixter(O) p_out(output); + mln_qixter(const I, W) q(p, win); + for_all_2(p, p_out) + { + min.init(); + for_all(q) + min.take(q.val()); + p_out.val() = min.to_result(); + } + trace::exiting("morpho::impl::erosion_on_function_fast"); + } + + template <typename I, typename W, typename O> + void erosion_on_set_fast(const I& input, const W& win, O& output) + { + trace::entering("morpho::impl::erosion_on_set_fast"); + level::fill(output, input); + border::fill(input, true); + + mln_pixter(const I) p(input); + mln_pixter(O) p_out(output); + mln_qixter(const I, W) q(p, win); + for_all_2(p, p_out) + if (p.val()) + for_all(q) + if (! q.val()) + { + p_out.val() = false; + break; + } + trace::exiting("morpho::impl::erosion_on_set_fast"); + } + + + // Stage 5: dispatch w.r.t. fast property + // | + // V + + template <typename I, typename W, typename O> + void erosion_set_wrt_fast(trait::image::speed::any, const I& input, + const W& win, O& output) + { + trace::entering("morpho::impl::erosion_set_wrt_fast"); + generic::erosion_on_set(input, win, output); + trace::exiting("morpho::impl::erosion_set_wrt_fast"); + } + + template <typename I, typename W, typename O> + void erosion_set_wrt_fast(trait::image::speed::fastest, const I& input, + const W& win, O& output) + { + trace::entering("morpho::impl::erosion_set_wrt_fast"); + impl::erosion_on_set_fast(input, win, output); + trace::exiting("morpho::impl::erosion_set_wrt_fast"); + } + + template <typename I, typename W, typename O, typename A> + void erosion_fun_wrt_fast(trait::image::speed::any, const I& input, + const W& win, O& output, A& min) + { + trace::entering("morpho::impl::erosion_fun_wrt_fast"); + generic::erosion_on_function(input, win, output, min); + trace::exiting("morpho::impl::erosion_fun_wrt_fast"); + } + + template <typename I, typename W, typename O, typename A> + void erosion_fun_wrt_fast(trait::image::speed::fastest, const I& input, + const W& win, O& output, A& min) + { + trace::entering("morpho::impl::erosion_fun_wrt_fast"); + impl::erosion_on_function_fast(input, win, output, min); + trace::exiting("morpho::impl::erosion_fun_wrt_fast"); + } + + // ^ + // | + // end of stage 5 (dispatch w.r.t. fast property) + + // Stage 4: dispatch w.r.t. data quantification + // | + // V + + template <typename I, typename W, typename O> + void erosion_wrt_data(trait::image::quant::high, const I& input, + const W& win, O& output) + { + trace::entering("morpho::impl::erosion_wrt_data"); + accu::min_<mln_value(I)> min; + impl::erosion_fun_wrt_fast(mln_trait_image_speed(I)(), input, + win, output, min); + trace::exiting("morpho::impl::erosion_wrt_data"); + } + + template <typename I, typename W, typename O> + void erosion_wrt_data(trait::image::quant::low, const I& input, + const W& win, O& output) + { + trace::entering("morpho::impl::erosion_wrt_data"); + accu::min_h<mln_vset(I)> min; + impl::erosion_fun_wrt_fast(mln_trait_image_speed(I)(), input, + win, output, min); + trace::exiting("morpho::impl::erosion_wrt_data"); + } + + // ^ + // | + // end of stage 4 (dispatch w.r.t. the data quantification) + + // Stage 3: dispatch w.r.t. the value type + // | + // V + + template <typename I, typename W, typename O> + void erosion_wrt_value(const I& input, const W& win, O& output) + { + trace::entering("morpho::impl::erosion_wrt_value"); + + if (mlc_is(mln_trait_image_kind(I), trait::image::kind::logic)::value) + impl::erosion_set_wrt_fast(mln_trait_image_speed(I)(), input, + win, output); + // | + // `--> call stage 5: dispatch w.r.t. fast property + else + impl::erosion_wrt_data(mln_trait_image_quant(I)(), input, + win, output); + // | + // `--> call stage 4: dispatch w.r.t. the data quantification + trace::exiting("morpho::impl::erosion_wrt_value"); + } + + // ^ + // | + // end of stage 3 (dispatch w.r.t. the value type) + + + + // Stage 2: dispatch w.r.t. the window morphology + // | + // V + + template <typename I, typename W, typename O> + void erosion_wrt_mor(const I& input, const W& win, O& output) + { + trace::entering("morpho::impl::erosion_wrt_mor"); + // FIXME : Choose the right algorithm between : + impl::erosion_wrt_value(input, win, output); + // and : + // impl::erosion_incr_wrt_value(input, win, output); + trace::exiting("morpho::impl::erosion_wrt_mor"); + } + + // ^ + // | + // end of stage 2 (dispatch w.r.t. the window morphology) + + + + // Stage 1: dispatch w.r.t. the window type. + // | + // V + + template <typename I, typename W, typename O> + void erosion_wrt_win(const Image<I>& input_, const W& win_, Image<O>& output_) + { + trace::entering("morpho::impl::erosion_wrt_win"); + const I& input = exact(input_); + const W& win = exact(win_); + O& output = exact(output_); + + impl::erosion_wrt_mor(input, win, output); + // | + // `--> call stage 2: dispatch w.r.t. the data quantification + trace::exiting("morpho::impl::erosion_wrt_win"); + } + +# ifdef MLN_CORE_WIN_RECTANGLE2D_HH + + template <typename I, typename O> + void erosion_wrt_win(const Image<I>& input, const win::rectangle2d& win, Image<O>& 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 + + +# ifdef MLN_CORE_WIN_OCTAGON2D_HH +# ifdef MLN_CORE_WIN_DIAG2D_HH +# ifdef MLN_CORE_WIN_BACKDIAG2D_HH + + template <typename I, typename O> + void erosion_wrt_win(const Image<I>& input, const win::octagon2d& win, Image<O>& output) + { + const unsigned len = win.length() / 3 + 1; + + O temp1(exact(output).domain()); + O temp2(exact(output).domain()); + morpho::erosion(input, win::hline2d(len), temp1); + morpho::erosion(temp1, win::vline2d(len), temp2); + morpho::erosion(temp2, win::diag2d(len), temp1); + morpho::erosion(temp1, win::backdiag2d(len), output); + } + +# endif // MLN_CORE_WIN_BACKDIAG2D_HH +# endif // MLN_CORE_WIN_DIAG2D_HH +# endif // MLN_CORE_WIN_OCTAGON2D_HH + + // ^ + // | + // end of stage 1 (dispatch w.r.t. the window type) + + + + } // end of namespace mln::morpho::impl + + } // end of namespace mln::morpho + +} // end of namespace mln + + +# endif // ! MLN_INCLUDE_ONLY + +#endif // ! MLN_MORPHO_EROSION_SPE_HH Index: trunk/milena/mln/morpho/includes.hh =================================================================== --- trunk/milena/mln/morpho/includes.hh (revision 1273) +++ trunk/milena/mln/morpho/includes.hh (revision 1274) @@ -40,6 +40,8 @@ # include <mln/accu/min.hh> # include <mln/accu/max.hh> +# include <mln/accu/min_h.hh> +# include <mln/accu/max_h.hh> # include <mln/level/compare.hh> # include <mln/level/fill.hh> Index: trunk/milena/mln/morpho/erosion.hh =================================================================== --- trunk/milena/mln/morpho/erosion.hh (revision 1273) +++ trunk/milena/mln/morpho/erosion.hh (revision 1274) @@ -36,6 +36,9 @@ # include <mln/morpho/includes.hh> +// Specializations are in: +# include <mln/morpho/erosion.spe.hh> + namespace mln { @@ -57,17 +60,15 @@ namespace impl { - // On function. - template <typename I, typename W, typename O> - void erosion_on_function(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) + namespace generic { - const I& input = exact(input_); - const W& win = exact(win_); - O& output = exact(output_); - - accu::min_<mln_value(I)> min; + // On function. + template <typename I, typename W, typename O, typename A> + void erosion_on_function(const I& input, const W& win, O& output, A& min) + { + trace::entering("morpho::impl::generic::erosion_on_function"); mln_piter(I) p(input.domain()); mln_qiter(W) q(win, p); for_all(p) @@ -77,18 +78,15 @@ min.take(input(q)); output(p) = min.to_result(); } + trace::exiting("morpho::impl::generic::erosion_on_function"); } - // On set. template <typename I, typename W, typename O> - void erosion_on_set(const Image<I>& input_, const Window<W>& win_, Image<O>& output_) + void erosion_on_set(const I& input, const W& win, O& output) { - const I& input = exact(input_); - const W& win = exact(win_); - O& output = exact(output_); - + trace::entering("morpho::impl::generic::erosion_on_set"); level::fill(output, input); mln_piter(I) p(input.domain()); @@ -101,94 +99,21 @@ output(p) = false; break; } + trace::exiting("morpho::impl::generic::erosion_on_set"); } - - - // ... - - - - // FIXME: Stage 3: dispatch w.r.t. fast property - - - // Stage 2: dispatch w.r.t. the value kind. - - template <typename I, typename W, typename O> - void erosion_wrt_value(trait::image::kind::logic, // binary => morphology on sets - const Image<I>& input, const Window<W>& win, Image<O>& output) - { - return impl::erosion_on_set(exact(input), exact(win), output); - } - - template <typename K, typename I, typename W, typename O> - void erosion_wrt_value(K, // otherwise => morphology on functions - const Image<I>& input, const Window<W>& win, Image<O>& output) - { - return impl::erosion_on_function(exact(input), exact(win), output); - } - - - - // Stage 1: dispatch w.r.t. the window type. - // | - // V - - template <typename I, typename W, typename O> - void erosion_wrt_win(const Image<I>& input, const Window<W>& win, Image<O>& output) - { - erosion_wrt_value(mln_trait_image_kind(I)(), exact(input), exact(win), output); - // | - // --> call stage 2: dispatch w.r.t. the value kind - } - -# ifdef MLN_CORE_WIN_RECTANGLE2D_HH - - template <typename I, typename O> - void erosion_wrt_win(const Image<I>& input, const win::rectangle2d& win, Image<O>& 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 - - -# ifdef MLN_CORE_WIN_OCTAGON2D_HH -# ifdef MLN_CORE_WIN_DIAG2D_HH -# ifdef MLN_CORE_WIN_BACKDIAG2D_HH - - template <typename I, typename O> - void erosion_wrt_win(const Image<I>& input, const win::octagon2d& win, Image<O>& output) - { - const unsigned len = win.length() / 3 + 1; - - O temp1(exact(output).domain()); - O temp2(exact(output).domain()); - morpho::erosion(input, win::hline2d(len), temp1); - morpho::erosion(temp1, win::vline2d(len), temp2); - morpho::erosion(temp2, win::diag2d(len), temp1); - morpho::erosion(temp1, win::backdiag2d(len), output); - } - -# endif // MLN_CORE_WIN_BACKDIAG2D_HH -# endif // MLN_CORE_WIN_DIAG2D_HH -# endif // MLN_CORE_WIN_OCTAGON2D_HH - - // ^ - // | - // end of stage1 (dispatch w.r.t. the window type) - + } // end of namespace mln::morpho::impl::generic } // end of namespace mln::morpho::impl + // Facade. template <typename I, typename W, typename O> void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output) { + trace::entering("morpho::erosion"); mln_precondition(exact(output).domain() == exact(input).domain()); mln_precondition(! exact(win).is_empty()); @@ -196,6 +121,7 @@ if (exact(win).is_centered()) mln_postcondition(output <= input); + trace::exiting("morpho::erosion"); } # endif // ! MLN_INCLUDE_ONLY
participants (1)
-
Simon Nivault