cleanup-2008 2472: Several fixes and updates on windows and morphology.

https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Several fixes and updates on windows and morphology. * mln/core/concept/window.hh (regular, has): New checks. Layout. * mln/convert/to_window.hh (to_window): Update version for neighborhoods. Cut useless dependencies to line_graph stuff. * mln/set/inter.hh (inter): Remove window version. * mln/win/shift.hh: Copy to... * mln/win/inter.hh: ...this new file. (shift): Model... (operator&&): ...this new operator. Update. * mln/win/multiple.hh (FIXME): Fix. (change_target): New. Use it. * mln/win/diff.hh (operator-): Move to mln namespace to disambiguate calls. (check): New checks. * mln/morpho/thin_fit.hh, * mln/morpho/thinning.hh, * mln/morpho/hit_or_miss.hh, * mln/morpho/thickening.hh, * mln/morpho/thick_miss.hh: Factor test routines. Use them. (set::inter): Replace by operator && on windows. * mln/morpho/dilation.hh (convert::to_window): Update to .win(). * mln/morpho/includes.hh (to_window): Remove include; obsolete. (set/inter): Update to win/inter. convert/to_window.hh | 53 +-------------------------- core/concept/window.hh | 14 ++++++- morpho/dilation.hh | 2 - morpho/hit_or_miss.hh | 55 ++++++++++++++++++++++------ morpho/includes.hh | 3 - morpho/thick_miss.hh | 4 +- morpho/thickening.hh | 37 ++++++++++++++++--- morpho/thin_fit.hh | 35 +++++++++++++++--- morpho/thinning.hh | 38 +++++++++++++++++-- set/inter.hh | 30 --------------- win/diff.hh | 6 --- win/inter.hh | 95 +++++++++++++++++++++++++++++-------------------- win/multiple.hh | 16 +++++++- 13 files changed, 232 insertions(+), 156 deletions(-) Index: mln/core/concept/window.hh --- mln/core/concept/window.hh (revision 2471) +++ mln/core/concept/window.hh (working copy) @@ -143,6 +143,10 @@ { static void run_extra() { + // Associated type. + typedef mln_regular(E) regular; + + // Methods. bool (E::*m1)() const = &E::is_centered; m1 = 0; bool (E::*m2)() const = &E::is_symmetric; @@ -152,21 +156,27 @@ unsigned (E::*m4)() const = &E::delta; m4 = 0; } + static void run(mln::trait::window::definition::unique) { typedef mln_dpsite(E) D; - const D& (E::*m)(unsigned) const = &E::dp; - m = 0; + const D& (E::*m1)(unsigned) const = &E::dp; + m1 = 0; + bool (E::*m2)(const D&) const = &E::has; + m2 = 0; run_extra(); } + static void run(mln::trait::window::definition::n_ary) { run_extra(); } + static void run(mln::trait::window::definition::varying) { /* No requirement. */ } + static void run() { run(mln_trait_window_definition(E)()); Index: mln/convert/to_window.hh --- mln/convert/to_window.hh (revision 2471) +++ mln/convert/to_window.hh (working copy) @@ -42,34 +42,16 @@ # include <mln/pw/cst.hh> # include <mln/metal/is_a.hh> -# include <mln/core/image/line_graph_elt_neighborhood.hh> -# include <mln/core/image/line_graph_elt_window.hh> - namespace mln { namespace convert { - // Return type trait of neighborhood-to-window conversions. - - /* FIXME: This trait should probably be moved elsewhere. And/or - it could encapsulate the conversion function, too. */ - - // Default case. - template <typename N> - struct nbh_to_win_trait - { typedef window<mln_dpsite(N)> ret; }; - - // Case of line_graph_elt_neighborhood<P>. - template <typename P> - struct nbh_to_win_trait< line_graph_elt_neighborhood<P> > - { typedef line_graph_elt_window<P> ret; }; - /// Convert a neighborhood \p nbh into a window. template <typename N> - typename nbh_to_win_trait<N>::ret to_window(const Neighborhood<N>& nbh); + mln_window(N) to_window(const Neighborhood<N>& nbh); /// Convert a binary image \p ima into a window. template <typename I> @@ -90,40 +72,11 @@ | Neighborhood-to-window conversions. | `-------------------------------------*/ - namespace impl - { - - template <typename N> - inline - window<mln_dpsite(N)> to_window(const N& nbh_) - { - const N& nbh = exact(nbh_); - typedef mln_dpsite(N) D; - typedef mln_psite(D) P; - window<D> win; - mln_niter(N) n(nbh, P::origin); - for_all(n) - win.insert(n - P::origin); - return win; - } - - template <typename P> - inline - line_graph_elt_window<P> - to_window(const line_graph_elt_neighborhood<P>& /* nbh_ */ ) - { - return line_graph_elt_window<P>(); - } - - } // end of namepace mln::convert::impl - - - // Facade. template <typename N> inline - typename nbh_to_win_trait<N>::ret to_window(const Neighborhood<N>& nbh) + mln_window(N) to_window(const Neighborhood<N>& nbh) { - return impl::to_window(exact(nbh)); + return exact(nbh).win(); } /*------------------------------. Index: mln/set/inter.hh --- mln/set/inter.hh (revision 2471) +++ mln/set/inter.hh (working copy) @@ -31,11 +31,10 @@ /*! \file mln/set/inter.hh * * \brief Several routines to compute the intersection between a - * couple of sets. + * couple of site sets. */ # include <mln/convert/to_std_set.hh> -# include <mln/convert/to_window.hh> # include <mln/convert/to_p_set.hh> # include <mln/metal/equal.hh> @@ -47,14 +46,6 @@ namespace set { - /*! \brief Intersection between a couple of windows. - * - * \relates mln::Window - */ - template <typename Wl, typename Wr> - window<mln_dpsite(Wl)> - inter(const Window<Wl>& lhs, const Window<Wr>& rhs); - /*! \brief Intersection between a couple of point sets. * * \relates mln::Site_Set @@ -67,25 +58,6 @@ template <typename Wl, typename Wr> inline - window<mln_dpsite(Wl)> - inter(const Window<Wl>& lhs, const Window<Wr>& rhs) - { - trace::entering("set::inter"); - mln::metal::equal<mln_dpsite(Wl), mln_dpsite(Wr)>::check(); - typedef mln_dpsite(Wl) D; - std::set<D> - sl = convert::to_std_set(lhs), - sr = convert::to_std_set(rhs), - s; - std::set_intersection(sl.begin(), sl.end(), - sr.begin(), sr.end(), - std::inserter(s, s.begin())); - trace::exiting("set::inter"); - return convert::to_window(s); - } - - template <typename Wl, typename Wr> - inline p_set<mln_psite(Wl)> inter(const Site_Set<Wl>& lhs, const Site_Set<Wr>& rhs) { Index: mln/win/inter.hh --- mln/win/inter.hh (revision 2469) +++ mln/win/inter.hh (working copy) @@ -25,12 +25,12 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_WIN_SHIFT_HH -# define MLN_WIN_SHIFT_HH +#ifndef MLN_WIN_INTER_HH +# define MLN_WIN_INTER_HH -/*! \file mln/win/shift.hh +/*! \file mln/win/inter.hh * - * \brief Define a function which shifts a window with a delta-point. + * \brief Define a function which inters a window with a delta-point. */ # include <mln/core/window.hh> @@ -40,76 +40,95 @@ namespace mln { - namespace win - { - - /// Shift a window \p win with a delta-point \p dp. - template <typename W> - mln_regular(W) - shift(const Window<W>& win, const mln_dpsite(W)& dp); + /// Inter a window \p win with a delta-point \p dp. + template <typename W1, typename W2> + mln_regular(W1) + operator && (const Window<W1>& win1, const Window<W2>& win2); # ifndef MLN_INCLUDE_ONLY + namespace win + { + namespace impl { - template <typename W> + template <typename W1, typename W2> inline - mln_regular(W) - shift_(trait::window::definition::unique, - const W& win, const mln_dpsite(W)& dp) + mln_regular(W1) + inter(trait::window::definition::unique, + const W1& win1, const W2& win2) { - mlc_is(mln_trait_window_size(W), + mlc_is(mln_trait_window_size(W1), + trait::window::size::fixed)::check(); + mlc_is(mln_trait_window_size(W2), trait::window::size::fixed)::check(); - mln_regular(W) tmp; - unsigned n = win.size(); + + mln_regular(W1) tmp; + unsigned n = win1.size(); for (unsigned i = 0; i < n; ++i) - tmp.insert(win.dp(i) + dp); + if (win2.has(win1.dp(i))) + tmp.insert(win1.dp(i)); return tmp; } - template <typename W> + template <typename W1, typename W2> inline - mln_regular(W) - shift_(trait::window::definition::multiple, - const W& win, const mln_dpsite(W)& dp) + mln_regular(W1) + inter(trait::window::definition::multiple, + const W1& win1, const W2& win2) { - mln_regular(W) tmp(win.function()); - const unsigned nw = win.nwindows(); + mln_precondition(win1.nwindows() == win2.nwindows()); + // FIXME: What about "win1.function() not equal win2.function()"! + + mln_regular(W1) tmp(win1.function()); + const unsigned nw = win1.nwindows(); for (unsigned w = 0; w < nw; ++w) - tmp.set_window(w, win::shift(win.window(w), dp)); + tmp.set_window(w, win1.window(w) && win2.window(w)); return tmp; } } // end of namespace mln::win::impl + } // end of namespace mln::win + // Facade. - template <typename W> + template <typename W1, typename W2> inline - mln_regular(W) - shift(const Window<W>& win, const mln_dpsite(W)& dp) + mln_regular(W1) + operator && (const Window<W1>& win1, const Window<W2>& win2) { - trace::entering("win::shift"); + trace::entering("win::inter"); - mlc_is(mln_trait_window_support(W), + // Compatibility checks. + mlc_equal(mln_regular(W1), mln_regular(W2))::check(); + mlc_converts_to(mln_dpsite(W1), mln_dpsite(W2))::check(); + + // Support checks. + mlc_is(mln_trait_window_support(W1), + trait::window::support::regular)::check(); + mlc_is(mln_trait_window_support(W2), trait::window::support::regular)::check(); - mlc_is_not(mln_trait_window_definition(W), + + // Definition checks. + mlc_equal(mln_trait_window_definition(W1), + mln_trait_window_definition(W2))::check(); + + mlc_is_not(mln_trait_window_definition(W1), trait::window::definition::varying)::check(); - mln_regular(W) tmp = impl::shift_(mln_trait_window_definition(W)(), - exact(win), dp); + mln_regular(W1) tmp = win::impl::inter(mln_trait_window_definition(W1)(), + exact(win1), exact(win2)); - trace::exiting("win::shift"); + trace::exiting("win::inter"); return tmp; } # endif // ! MLN_INCLUDE_ONLY - } // end of namespace mln::win - } // end of namespace mln -#endif // ! MLN_WIN_SHIFT_HH +#endif // ! MLN_WIN_INTER_HH Index: mln/win/multiple.hh --- mln/win/multiple.hh (revision 2471) +++ mln/win/multiple.hh (working copy) @@ -126,6 +126,8 @@ : public internal::site_relative_iterator_base< multiple<W,F>, multiple_qiter<W,F> > { + typedef multiple_qiter<W,F> self_; + typedef internal::site_relative_iterator_base< multiple<W,F>, self_ > super_; public: multiple_qiter(); @@ -133,6 +135,8 @@ template <typename P> multiple_qiter(const multiple<W,F>& w, const P& c); + void change_target(const multiple<W,F>& w); // Overridden to initialize size_. + /// Test the iterator validity. bool is_valid_() const; @@ -317,8 +321,16 @@ this->center_at(c); // We have to first change the center so that 'invalidate' can // work when changing the target. - this->change_target(w); - size_ = w.size(); // FIXME: In a local change_target! + change_target(w); + } + + template <typename W, typename F> + inline + void + multiple_qiter<W,F>::change_target(const multiple<W,F>& w) + { + this->super_::change_target(w); + size_ = w.size(); } template <typename W, typename F> Index: mln/win/diff.hh --- mln/win/diff.hh (revision 2471) +++ mln/win/diff.hh (working copy) @@ -41,14 +41,12 @@ namespace mln { - namespace win - { - /// Set difference between a couple of windows \p win1 and \p win2. template <typename W1, typename W2> mln_regular(W1) operator-(const Window<W1>& win1, const Window<W2>& win2); + /// Set difference between a couple of neighborhoods \p nbh1 and \p nbh2. template <typename N1, typename N2> neighb<mln_deduce(N1, window, regular)> @@ -96,8 +94,6 @@ # endif // ! MLN_INCLUDE_ONLY - } // end of namespace mln::win - } // end of namespace mln Index: mln/morpho/thin_fit.hh --- mln/morpho/thin_fit.hh (revision 2471) +++ mln/morpho/thin_fit.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 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 @@ -55,6 +55,34 @@ # ifndef MLN_INCLUDE_ONLY + namespace internal + { + + template <typename I, typename Wfg, typename Wbg> + inline + void + thin_fit_tests(const Image<I>& input_, + const Window<Wfg>& win_fg_, + const Window<Wbg>& win_bg_) + { + const I& input = exact(input_); + const Wfg& win_fg = exact(win_fg_); + const Wbg& win_bg = exact(win_bg_); + + // Tests. + mln_precondition(input.has_data()); + mln_precondition(win_fg.is_centered()); + mln_precondition((win_fg && win_bg).is_empty()); + + // Avoid warnings. + (void) input_; + (void) win_fg_; + (void) win_bg_; + } + + } // end of namespace mln::morpho::internal + + template <typename I, typename Wfg, typename Wbg> inline mln_concrete(I) @@ -62,9 +90,8 @@ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg) { trace::entering("morpho::thin_fit"); - mln_precondition(exact(input).has_data()); - mln_precondition(exact(win_fg).is_centered()); - mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + + internal::thin_fit_tests(input, win_fg, win_bg); mln_concrete(I) output = morpho::minus( input, Index: mln/morpho/thinning.hh --- mln/morpho/thinning.hh (revision 2471) +++ mln/morpho/thinning.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 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 @@ -58,6 +58,35 @@ # ifndef MLN_INCLUDE_ONLY + namespace internal + { + + template <typename I, typename Wfg, typename Wbg> + inline + void + thinning_tests(const Image<I>& input_, + const Window<Wfg>& win_fg_, + const Window<Wbg>& win_bg_) + { + const I& input = exact(input_); + const Wfg& win_fg = exact(win_fg_); + const Wbg& win_bg = exact(win_bg_); + + // Tests. + mln_precondition(input.has_data()); + mln_precondition(win_bg.is_centered()); + mln_precondition(! win_bg.is_empty()); + mln_precondition((win_fg && win_bg).is_empty()); + + // Avoid warnings. + (void) input_; + (void) win_fg_; + (void) win_bg_; + } + + } // end of namespace mln::morpho::internal + + template <typename I, typename Wfg, typename Wbg> inline mln_concrete(I) @@ -65,10 +94,9 @@ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg) { trace::entering("morpho::thinning"); - mln_precondition(exact(input).has_data()); - mln_precondition(exact(win_fg).is_centered()); - mln_precondition(! exact(win_bg).is_empty()); - mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + + + internal::thinning_tests(input, win_fg, win_bg); mln_concrete(I) output = morpho::minus( input, hit_or_miss(input, win_fg, win_bg) ); Index: mln/morpho/hit_or_miss.hh --- mln/morpho/hit_or_miss.hh (revision 2471) +++ mln/morpho/hit_or_miss.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 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 @@ -105,6 +105,35 @@ # ifndef MLN_INCLUDE_ONLY + + namespace internal + { + + template <typename I, typename Wh, typename Wm> + inline + void + hit_or_miss_tests(const Image<I>& input_, + const Window<Wh>& win_hit_, + const Window<Wm>& win_miss_) + { + const I& input = exact(input_); + const Wh& win_hit = exact(win_hit_); + const Wm& win_miss = exact(win_miss_); + + // Tests. + mln_precondition(input.has_data()); + mln_precondition(win_hit.is_centered()); + mln_precondition((win_hit && win_miss).is_empty()); + + // Avoid warnings. + (void) input_; + (void) win_hit_; + (void) win_miss_; + } + + } // end of namespace mln::morpho::internal + + namespace impl { @@ -113,11 +142,15 @@ template <typename I, typename Wh, typename Wm> inline - void hit_or_miss_preconditions_(const Image<I>& input, - const Window<Wh>& win_hit, const Window<Wm>& win_miss) - { - mln_precondition(exact(input).has_data()); - mln_precondition(set::inter(exact(win_hit), exact(win_miss)).is_empty()); + void hit_or_miss_preconditions_(const Image<I>& input_, + const Window<Wh>& win_hit_, + const Window<Wm>& win_miss_) + { + const I& input = exact(input_); + const Wh& win_hit = exact(win_hit_); + const Wm& win_miss = exact(win_miss_); + mln_precondition(input.has_data()); + mln_precondition((win_hit && win_miss).is_empty()); } @@ -203,7 +236,7 @@ const Window<Wh>& win_hit, const Window<Wm>& win_miss) { trace::entering("morpho::hit_or_miss"); - impl::hit_or_miss_preconditions_(input, win_hit, win_miss); + internal::hit_or_miss_tests(input, win_hit, win_miss); mln_concrete(I) output = impl::hit_or_miss_(mln_trait_image_kind(I)(), exact(input), @@ -221,7 +254,7 @@ const Window<Wh>& win_hit, const Window<Wm>& win_miss) { trace::entering("morpho::hit_or_miss_opening"); - impl::hit_or_miss_preconditions_(input, win_hit, win_miss); + internal::hit_or_miss_tests(input, win_hit, win_miss); mln_concrete(I) output = dilation( hit_or_miss(input, win_hit, win_miss), win::sym(win_hit) ); @@ -238,7 +271,7 @@ const Window<Wh>& win_hit, const Window<Wm>& win_miss) { trace::entering("morpho::hit_or_miss_background_opening"); - impl::hit_or_miss_preconditions_(input, win_hit, win_miss); + internal::hit_or_miss_tests(input, win_hit, win_miss); mln_concrete(I) output = hit_or_miss_opening(complementation(input), win_miss, win_hit); @@ -256,7 +289,7 @@ const Window<Wh>& win_hit, const Window<Wm>& win_miss) { trace::entering("morpho::hit_or_miss_closing"); - impl::hit_or_miss_preconditions_(input, win_hit, win_miss); + internal::hit_or_miss_tests(input, win_hit, win_miss); mln_concrete(I) output = complementation( hit_or_miss_opening( complementation(input), win_hit, win_miss ) ); @@ -274,7 +307,7 @@ const Window<Wh>& win_hit, const Window<Wm>& win_miss) { trace::entering("morpho::hit_or_miss_background_closing"); - impl::hit_or_miss_preconditions_(input, win_hit, win_miss); + internal::hit_or_miss_tests(input, win_hit, win_miss); mln_concrete(I) output = hit_or_miss_closing(input, win_miss, win_hit); Index: mln/morpho/thickening.hh --- mln/morpho/thickening.hh (revision 2471) +++ mln/morpho/thickening.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 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 @@ -55,6 +55,35 @@ # ifndef MLN_INCLUDE_ONLY + namespace internal + { + + template <typename I, typename Wfg, typename Wbg> + inline + void + thickening_tests(const Image<I>& input_, + const Window<Wfg>& win_fg_, + const Window<Wbg>& win_bg_) + { + const I& input = exact(input_); + const Wfg& win_fg = exact(win_fg_); + const Wbg& win_bg = exact(win_bg_); + + // Tests. + mln_precondition(input.has_data()); + mln_precondition(win_bg.is_centered()); + mln_precondition(! win_fg.is_empty()); + mln_precondition((win_fg && win_bg).is_empty()); + + // Avoid warnings. + (void) input_; + (void) win_fg_; + (void) win_bg_; + } + + } // end of namespace mln::morpho::internal + + template <typename I, typename Wfg, typename Wbg> inline mln_concrete(I) @@ -62,10 +91,8 @@ const Window<Wfg>& win_fg, const Window<Wbg>& win_bg) { trace::entering("morpho::thickening"); - mln_precondition(exact(input).has_data()); - mln_precondition(exact(win_bg).is_centered()); - mln_precondition(! exact(win_fg).is_empty()); - mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + + internal::thickening_tests(input, win_fg, win_bg); mln_concrete(I) output = morpho::plus( input, hit_or_miss(input, win_fg, win_bg) ); Index: mln/morpho/thick_miss.hh --- mln/morpho/thick_miss.hh (revision 2471) +++ mln/morpho/thick_miss.hh (working copy) @@ -1,4 +1,4 @@ -// Copyright (C) 2007 EPITA Research and Development Laboratory +// Copyright (C) 2007, 2008 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 @@ -64,7 +64,7 @@ trace::entering("morpho::thick_miss"); // FIXME: Fix the following line (win_miss ??) // mln_precondition(exact(win_miss).is_centered()); - mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + mln_precondition((exact(win_fg) && exact(win_bg)).is_empty()); mln_concrete(I) output = morpho::plus( input, Index: mln/morpho/dilation.hh --- mln/morpho/dilation.hh (revision 2471) +++ mln/morpho/dilation.hh (working copy) @@ -257,7 +257,7 @@ 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, convert::to_window(nbh), output); + dilation_wrt_win(input, nbh.win(), output); } #endif Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 2471) +++ mln/morpho/includes.hh (working copy) @@ -60,7 +60,7 @@ # include <mln/win/sym.hh> # include <mln/win/shift.hh> # include <mln/win/diff.hh> -# include <mln/set/inter.hh> +# include <mln/win/inter.hh> # include <mln/morpho/dilation.hh> # include <mln/morpho/erosion.hh> @@ -70,6 +70,5 @@ # include <mln/morpho/minus.hh> # include <mln/morpho/plus.hh> -# include <mln/convert/to_window.hh> #endif // ! MLN_MORPHO_INCLUDES_HH
participants (1)
-
Thierry Geraud