
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Hack morphological dilation so it is practicable. * tests/morpho/dilation.cc: Fix copyright. (neighb/image.hh): Fix missing guards for this include. * mln/morpho/dilation.hh (todo): New. Fix copyright. (impl): Remove all implementations; they were obsolete. (dilation_as_erosion_dual): New implementation. (dilation_tests, dilation_dispatch): New. mln/morpho/dilation.hh | 251 ++++++----------------------------------------- tests/morpho/dilation.cc | 9 + 2 files changed, 45 insertions(+), 215 deletions(-) Index: tests/morpho/dilation.cc --- tests/morpho/dilation.cc (revision 2768) +++ tests/morpho/dilation.cc (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -49,7 +50,13 @@ #include <mln/fun/ops.hh> #include <mln/core/alias/neighb2d.hh> + + /* FIXME: Re-enable these tests for Olena 1.1, when associated + neighborhoods (i.e., the neighb::image morpher) are supported and + shipped. */ +#if 0 #include <mln/neighb/image.hh> +#endif #include "tests/data.hh" Index: mln/morpho/dilation.hh --- mln/morpho/dilation.hh (revision 2768) +++ mln/morpho/dilation.hh (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -29,9 +30,10 @@ # define MLN_MORPHO_DILATION_HH /// \file mln/morpho/dilation.hh -/// \brief Morphological dilation. /// -/// \todo Activate the FIXMEs (border::adjust). +/// Morphological dilation. +/// +/// \todo Revamp. # include <mln/morpho/includes.hh> @@ -42,28 +44,9 @@ namespace morpho { - /// Morphological dilation using the neighborhood bound to an image. - /// - /// \{ - /* FIXME: Re-enable this routine for Olena 1.1, when associated - neighborhoods (i.e., the neighb::image morpher) are supported - and shipped. */ -#if 0 - /// Perform a morphological dilation of \a input using its - /// neighborhood and return the result. - /// - /// \pre \a input must be an image with a neighborhood. - template <typename I> - mln_concrete(I) - dilation(const Image<I>& input); - /// \} -#endif /// Morphological dilation using windows. /// - /// \todo Overload dilation_wrt_win for hline and vline and for fast - /// images. - /// /// \{ /// Perform a morphological dilation of \a input using \a win and /// return the result. @@ -74,223 +57,68 @@ -# ifndef MLN_INCLUDE_ONLY - - namespace impl - { - - /*---------------. - | Window-based. | - `---------------*/ - - // On function. - - template <typename I, typename W, typename O> - inline - void dilation_on_function(const Image<I>& input_, const Window<W>& win_, - Image<O>& output_) - { - const I& input = exact(input_); - const W& win = exact(win_); - O& output = exact(output_); - // FIXME: border::adjust(input, win.delta()); - extension::fill(input, mln_min(mln_value(I))); +# ifndef MLN_INCLUDE_ONLY - accu::max<mln_value(I)> max; + // Tests. - mln_piter(I) p(input.domain()); - mln_qiter(W) q(win, p); - for_all(p) + namespace internal { - max.init(); - for_all(q) if (input.has(q)) - max.take(input(q)); - output(p) = max.to_result(); - } - } - // On set. - - template <typename I, typename W, typename O> - inline - void dilation_on_set(const Image<I>& input_, const Window<W>& win_, - Image<O>& output_) + template <typename I, typename W> + void + dilation_tests(const Image<I>& input_, const Window<W>& win_) { const I& input = exact(input_); const W& win = exact(win_); - O& output = exact(output_); - - // FIXME: border::adjust(input, win.delta()); - extension::fill(input, false); - - level::fill(output, input); - - mln_piter(I) p(input.domain()); - mln_qiter(W) q(win, p); - for_all(p) - if (!input(p)) - for_all(q) if (input.has(q)) - if (input(q)) - { - output(p) = true; - break; + mln_precondition(input.has_data()); + // mln_precondition(win.is_valid()); + (void) input; + (void) win; } - } - - // ------------- // - // Dispatchers. // - // ------------- // + } // end of namespace mln::morpho::internal - // FIXME: Stage 3: dispatch w.r.t. speed property. - // ... + // Implementations. - /// Stage 2: dispatch w.r.t. the value kind. - /// \{ - - /// Binary => morphology on sets. - template <typename I, typename W, typename O> - inline - void dilation_wrt_value(trait::image::kind::logic, - const Image<I>& input, const Window<W>& win, - Image<O>& output) + namespace impl { - return impl::dilation_on_set(exact(input), exact(win), output); - } - /// Otherwise => morphology on functions. - template <typename I, typename W, typename O> - inline - void dilation_wrt_value(trait::image::kind::any, - const Image<I>& input, const Window<W>& win, - Image<O>& output) + template <typename I, typename W> + mln_concrete(I) + dilation_as_erosion_dual(const Image<I>& input, const Window<W>& win) { - return impl::dilation_on_function(exact(input), exact(win), output); - } - - // End of stage 2. - - /// \} + trace::entering("morpho::impl::dilation_as_erosion_dual"); + mln_concrete(I) output = morpho::erosion(morpho::complementation(input), + win); + morpho::complementation_inplace(output); - - /// Stage 1: dispatch w.r.t. the window type. - /// \{ - - /// Default case. - template <typename I, typename W, typename O> - inline - void dilation_wrt_win(const Image<I>& input, const Window<W>& win, - Image<O>& output) - { - // Perform stage 2: dispatch w.r.t. the value kind. - dilation_wrt_value(mln_trait_image_kind(I)(), exact(input), - exact(win), output); + trace::exiting("morpho::impl::dilation_as_erosion_dual"); + return output; } -# ifdef MLN_CORE_WIN_RECTANGLE2D_HH - - /// Rectangle window. - template <typename I, typename O> - inline - void dilation_wrt_win(const Image<I>& input, const win::rectangle2d& win, - Image<O>& output) - { - O temp(exact(output).domain()); - morpho::dilation(input, win::hline2d(win.width()), temp); - morpho::dilation(temp, win::vline2d(win.height()), output); - } + } // end of namespace mln::morpho::impl -# endif // MLN_CORE_WIN_RECTANGLE2D_HH -# ifdef MLN_CORE_WIN_OCTAGON2D_HH -# ifdef MLN_CORE_WIN_DIAG2D_HH -# ifdef MLN_CORE_WIN_BACKDIAG2D_HH + // Dispatch. - /// Octagon window. - template <typename I, typename O> - void dilation_wrt_win(const Image<I>& input, const win::octagon2d& win, - Image<O>& output) + namespace internal { - const unsigned len = win.length() / 3 + 1; - - O temp1(exact(output).domain()); - O temp2(exact(output).domain()); - morpho::dilation(input, win::hline2d(len), temp1); - morpho::dilation(temp1, win::vline2d(len), temp2); - morpho::dilation(temp2, win::diag2d(len), temp1); - morpho::dilation(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. - - /// \} - - - /*---------------------. - | Neighborhood-based. | - `---------------------*/ - - // FIXME: Disabled (see above). -#if 0 - /* FIXME: We might want to move this function into the body of - the facade (see at the bottom of the file. */ - // Sole case. Convert the neighborhood into a window, and - // delegate to the window-based implementation. - template <typename I, typename N, typename O> - inline - void dilation_wrt_nbh(const Image<I>& input, const Neighborhood<N>& nbh, - Image<O>& output) + template <typename I, typename W> + mln_concrete(I) + dilation_dispatch(const Image<I>& input, const Window<W>& win) { - /* FIXME: The following comment applies to every algorithm - having a neighborhood and a window flavor: move it - elsewhere. - - We solely depend on the neighborhood-to-window conversion - here. This means the conversion should be smart enough to - produce a working window, even in the case of a non - dpoint-set-based neighborhood. */ - dilation_wrt_win(input, nbh.win(), output); + return impl::dilation_as_erosion_dual(input, win); } -#endif - } // end of namespace mln::morpho::impl + } // end of namespace mln::morpho::internal - /*----------. - | Facades. | - `----------*/ - - // ----------------------------------------------- // - // Facade for neighborhood-based implementations. // - // ----------------------------------------------- // - - // FIXME: Disabled (see above). -#if 0 - template <typename I> - mln_concrete(I) - dilation(const Image<I>& input) - { - trace::entering("morpho::dilation"); - - metal::has_neighborhood<I>::check(); - typedef mln_neighb(I) neighb; - - mln_concrete(I) output; - initialize(output, input); - impl::dilation_wrt_nbh(input, exact(input).neighborhood(), output); - trace::exiting("morpho::dilation"); - return output; - } -#endif // ----------------------------------------- // // Facade for window-based implementations. // @@ -301,15 +129,10 @@ dilation(const Image<I>& input, const Window<W>& win) { trace::entering("morpho::dilation"); - mln_precondition(exact(input).has_data()); - mln_precondition(! exact(win).is_empty()); - mln_concrete(I) output; - initialize(output, input); - impl::dilation_wrt_win(input, exact(win), output); + internal::dilation_tests(input, win); + mln_concrete(I) output = internal::dilation_dispatch(input, win); - if (exact(win).is_centered()) - mln_postcondition(output >= input); trace::exiting("morpho::dilation"); return output; }