
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Augment the documentation example on a 2D complex. * doc/examples/tuto_bis.cc: Re-activate the first two steps. * mln/core/image/image_if.hh (operator|): New overloads. It now works with C functions. * mln/core/alias/window1d.hh, * mln/core/alias/window2d.hh, * mln/core/alias/window3d.hh, * mln/core/neighb.hh, * mln/make/dual_neighb2d.hh: Fix missing include. We shall always first include from_to.hh in files that provide some overloading of from_to_. * mln/level/sort_psites.hh: Fix. * mln/convert/to_p_array.hh (reserve): Deactivate cause nsites is an optional method. * mln/fun/c.hh (C_Function): New concept declaration. (category): New specialization for C functions. (set_unary_, set_binary_): New specializations for C functions. (C): Fix missing default ctor. * mln/morpho/meyer_wst.hh (nbh): Fix missing exact. doc/examples/tuto_bis.cc | 180 +++++++++++++++++++++------------------------ mln/convert/to_p_array.hh | 2 mln/core/alias/window1d.hh | 1 mln/core/alias/window2d.hh | 1 mln/core/alias/window3d.hh | 1 mln/core/image/image_if.hh | 27 ++++++ mln/core/neighb.hh | 1 mln/fun/c.hh | 54 +++++++++++++ mln/level/sort_psites.hh | 4 - mln/make/dual_neighb2d.hh | 1 mln/morpho/meyer_wst.hh | 3 11 files changed, 177 insertions(+), 98 deletions(-) Index: doc/examples/tuto_bis.cc --- doc/examples/tuto_bis.cc (revision 2278) +++ doc/examples/tuto_bis.cc (working copy) @@ -1,32 +1,32 @@ -# include <vector> - # include <mln/core/var.hh> -# include <mln/core/alias/point2d.hh> +# include <mln/core/image/image2d.hh> +# include <mln/core/image/image_if.hh> +# include <mln/core/routine/extend.hh> + # include <mln/core/alias/window2d.hh> -# include <mln/make/win_multiple.hh> -# include <mln/convert/to.hh> # include <mln/make/dual_neighb2d.hh> -# include <mln/literal/origin.hh> -# include <mln/core/site_set/p_set.hh> + +# include <mln/debug/println.hh> +# include <mln/fun/p2v/iota.hh> + +# include <mln/level/paste.hh> +# include <mln/level/fill.hh> + +# include <mln/accu/min_max.hh> +# include <mln/morpho/meyer_wst.hh> /* -# include <mln/core/image/image2d.hh> +# include <vector> + # include <mln/core/image/sub_image.hh> -# include <mln/core/image/image_if.hh> # include <mln/core/alias/neighb2d.hh> # include <mln/core/alias/window2d.hh> # include <mln/convert/to_window.hh> -# include <mln/debug/println.hh> -# include <mln/fun/p2v/iota.hh> -# include <mln/level/paste.hh> -# include <mln/level/fill.hh> - # include <mln/morpho/dilation.hh> -# include <mln/morpho/gradient.hh> # include <mln/morpho/meyer_wst.hh> # include <mln/level/transform.hh> @@ -99,36 +99,6 @@ } // mln -struct is_cell_t : mln::Function_p2b<is_cell_t> -{ - typedef bool result; - bool operator()(const mln::point2d& p) const - { - return p.row() % 2 == 0 && p.col() % 2 == 0; - } -} - is_cell; - -struct is_edge_t : mln::Function_p2b<is_edge_t> -{ - typedef bool result; - bool operator()(const mln::point2d& p) const - { - return p.row() % 2 + p.col() % 2 == 1; - } -} - is_edge; - -struct is_point_t : mln::Function_p2b<is_point_t> -{ - typedef bool result; - bool operator()(const mln::point2d& p) const - { - return p.row() % 2 && p.col() % 2; - } -} - is_point; - */ @@ -150,8 +120,6 @@ exact(s).insert(q); } - - template <typename N, typename S> void convert_to_site_set(const Neighborhood<N>& nbh, const mln_psite(N)& p, @@ -165,15 +133,60 @@ exact(s).insert(n); } + + namespace morpho + { + + template <typename I, typename N> + mln_concrete(I) + gradient(const I& input, const N& nbh) + { + mln_concrete(I) output; + initialize(output, input); + accu::min_max_<mln_value(I)> mm; + + mln_piter(I) p(input.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + { + mm.init(); + for_all(n) if (input.has(n)) + mm.take(input(n)); + output(p) = mm.second() - mm.first(); + } + return output; } + } // mln::morpho + + +} // mln + + +// Functions bool is_row_odd(const mln::point2d& p) { return p.row() % 2; } +bool is_cell(const mln::point2d& p) +{ + return p.row() % 2 == 0 && p.col() % 2 == 0; +} + +bool is_edge(const mln::point2d& p) +{ + return p.row() % 2 + p.col() % 2 == 1; +} + +bool is_point(const mln::point2d& p) +{ + return p.row() % 2 && p.col() % 2; +} + + int main() @@ -192,10 +205,6 @@ mln_VAR( e2c, make::dual_neighb2d(is_row_odd, e2c_h, e2c_v) ); -// p_set<point2d> s; -// convert_to_site_set(e2c, literal::origin, s); -// std::cout << s << std::endl; - bool e2e_h[] = { 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, @@ -211,44 +220,6 @@ mln_VAR( e2e, make::dual_neighb2d(is_row_odd, e2e_h, e2e_v) ); - /* - - window2d c4 = convert::to_window(mln::c4()); - - - dbl_neighb_<dpoint2d, is_row_odd_t> nbh_e2c, win_p_e2c, nbh_e2e; - { - bool e2c_h[] = { 0, 1, 0, - 0, 0, 0, - 0, 1, 0 }; - - bool e2c_v[] = { 0, 0, 0, - 1, 0, 1, - 0, 0, 0 }; - nbh_e2c - .when_true (make::neighb2d(e2c_h)) - .when_false(make::neighb2d(e2c_v)); - - win_p_e2c = nbh_e2c; - win_p_e2c - .insert_true(dpoint2d(0,0)) - .insert_false(dpoint2d(0,0)); - - bool e2e_h[] = { 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0 }; - - bool e2e_v[] = { 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0 }; - nbh_e2e - .when_true (make::neighb2d(e2e_h)) - .when_false(make::neighb2d(e2e_v)); - } image2d<int> ima(3, 5); @@ -260,15 +231,38 @@ // // 4 5 6 - mln_VAR(edge, ima | is_edge); - level::paste(morpho::gradient(edge, nbh_e2c), edge); - // ^^^^^^^ - // edge -> neighbooring cells + + + mln_VAR(edge, extend(inplace(ima | is_edge), + pw::value(ima))); + level::paste(morpho::gradient(edge, e2c), edge); + // ^^^ + // edge -> neighboring cells debug::println(edge); // 1 1 // 3 3 3 // 1 1 + + unsigned nbasins; + mln_VAR(wst, morpho::meyer_wst(edge, e2e, nbasins)); + // ^^^ + // edge -> neighboring edges + debug::println(wst); + // 2 2 + // 0 0 0 + // 1 1 + + std::cout << nbasins << " bassins" << std::endl; + // 2 bassins + + + + /* + + window2d c4 = convert::to_window(mln::c4()); + + unsigned nbasins; mln_VAR(wst, morpho::meyer_wst(edge, nbh_e2e, nbasins)); // ^^^^^^^ Index: mln/core/image/image_if.hh --- mln/core/image/image_if.hh (revision 2278) +++ mln/core/image/image_if.hh (working copy) @@ -39,6 +39,7 @@ # include <mln/core/internal/image_domain_morpher.hh> # include <mln/core/site_set/p_if.hh> # include <mln/pw/all.hh> +# include <mln/convert/to_fun.hh> namespace mln @@ -149,6 +150,16 @@ + template <typename I, typename A> + image_if< const I, fun::C<bool(*)(A)> > + operator | (const Image<I>& ima, bool (*f)(A) ); + + template <typename I, typename A> + image_if< I, fun::C<bool(*)(A)> > + operator | (Image<I>& ima, bool (*f)(A) ); + + + # ifndef MLN_INCLUDE_ONLY // internal::data< image_if<I,F> > @@ -231,6 +242,22 @@ return tmp; } + + template <typename I, typename A> + image_if< const I, fun::C<bool(*)(A)> > + operator | (const Image<I>& ima, bool (*f)(A) ) + { + return exact(ima) | convert::to_fun(f); + } + + template <typename I, typename A> + image_if< I, fun::C<bool(*)(A)> > + operator | (Image<I>& ima, bool (*f)(A) ) + { + return exact(ima) | convert::to_fun(f); + } + + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: mln/core/alias/window1d.hh --- mln/core/alias/window1d.hh (revision 2278) +++ mln/core/alias/window1d.hh (working copy) @@ -34,6 +34,7 @@ # include <mln/core/window.hh> # include <mln/core/alias/dpoint1d.hh> +# include <mln/convert/from_to.hh> namespace mln Index: mln/core/alias/window2d.hh --- mln/core/alias/window2d.hh (revision 2278) +++ mln/core/alias/window2d.hh (working copy) @@ -35,6 +35,7 @@ # include <mln/core/window.hh> # include <mln/core/alias/dpoint2d.hh> # include <mln/metal/math/sqrt.hh> +# include <mln/convert/from_to.hh> namespace mln Index: mln/core/alias/window3d.hh --- mln/core/alias/window3d.hh (revision 2278) +++ mln/core/alias/window3d.hh (working copy) @@ -35,6 +35,7 @@ # include <cmath> # include <mln/core/window.hh> # include <mln/core/alias/dpoint3d.hh> +# include <mln/convert/from_to.hh> namespace mln Index: mln/core/neighb.hh --- mln/core/neighb.hh (revision 2278) +++ mln/core/neighb.hh (working copy) @@ -34,6 +34,7 @@ */ # include <mln/core/internal/neighborhood_base.hh> +# include <mln/convert/from_to.hh> Index: mln/level/sort_psites.hh --- mln/level/sort_psites.hh (revision 2278) +++ mln/level/sort_psites.hh (working copy) @@ -124,7 +124,7 @@ const I& input) { p_array<mln_psite(I)> v = convert::to_p_array(input.domain()); - std::sort(v.hook_().begin(), v.hook_().end(), + std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(), value_psite_less_<I>(input)); return v; } @@ -168,7 +168,7 @@ const I& input) { p_array<mln_psite(I)> v = convert::to_p_array(input.domain()); - std::sort(v.hook_().begin(), v.hook_().end(), + std::sort(v.hook_std_vector_().begin(), v.hook_std_vector_().end(), value_psite_greater_<I>(input)); return v; } Index: mln/make/dual_neighb2d.hh --- mln/make/dual_neighb2d.hh (revision 2278) +++ mln/make/dual_neighb2d.hh (working copy) @@ -33,6 +33,7 @@ * \brief Routine to create a dual neighborhood. */ +# include <mln/convert/to.hh> # include <mln/core/alias/window2d.hh> # include <mln/win/multiple.hh> # include <mln/core/neighb.hh> Index: mln/convert/to_p_array.hh --- mln/convert/to_p_array.hh (revision 2278) +++ mln/convert/to_p_array.hh (working copy) @@ -68,7 +68,7 @@ { const S& pset = exact(pset_); p_array<mln_psite(S)> v; - v.reserve(pset.nsites()); +// v.reserve(pset.nsites()); // FIXME: Why mln_fwd_piter and not mln_piter? mln_fwd_piter(S) p(pset); for_all(p) Index: mln/fun/c.hh --- mln/fun/c.hh (revision 2278) +++ mln/fun/c.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 @@ -41,6 +41,51 @@ namespace mln { + /// Concept-like. + template <typename E> + struct C_Function; + + + /// Category declaration for a unary C function. + template <typename R, typename A> + struct category< R (*)(A) > + { + typedef C_Function<void> ret; + }; + + + + // Forward declaration. + namespace fun { template <typename F> struct C; } + + + + namespace trait + { + + template <template <class> class Op, + typename R, typename A> + struct set_unary_< Op, C_Function, R (*)(A) > + { + typedef Op< fun::C<R (*)(A)> > Op_; + typedef typename Op_::ret ret; + }; + + template <template <class, class> class Op, + typename O, + typename R, typename A> + struct set_binary_< Op, + Object, O, + C_Function, R (*)(A) > + { + typedef Op< O, fun::C<R (*)(A)> > Op_; + typedef typename Op_::ret ret; + }; + + } // end of namespace trait + + + namespace fun { @@ -53,6 +98,7 @@ : fun::internal::selector_< R, A, C<R(*)(A)> >::ret { + C(); C(R (*f)(A)); typedef R result; R operator()(const mlc_unqualif(A)& a) const; @@ -65,6 +111,12 @@ template <typename R, typename A> inline + C<R(*)(A)>::C() + { + } + + template <typename R, typename A> + inline C<R(*)(A)>::C(R (*f)(A)) : f_(f) { Index: mln/morpho/meyer_wst.hh --- mln/morpho/meyer_wst.hh (revision 2278) +++ mln/morpho/meyer_wst.hh (working copy) @@ -104,10 +104,11 @@ template <typename L, typename I, typename N> mln_ch_value(I, L) - meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh, + meyer_wst(const Image<I>& input, const Neighborhood<N>& nbh_, L& nbasins) { /* FIXME: Ensure the input image has scalar values. */ + const N& nbh = exact(nbh_); typedef L marker; const marker unmarked = literal::zero;