1688: Adjust the morphological dilation w.r.t. a neighborhood.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Adjust the morphological dilation w.r.t. a neighborhood. * mln/morpho/includes.hh: Include mln/metal/has_neighborhood.hh. * mln/morpho/dilation.hh: Remove dead code. (dilation(const Image<I>&, Image<O>&)): Update preconditions. Fix delegation to mln::morpho::impl::dilation_wrt_nbh. * tests/morpho/dilation.cc: Peform tests using neighborhoods. Use smaller structural elemements to speed up tests. mln/morpho/dilation.hh | 84 +++++++++++++++-------------------------------- mln/morpho/includes.hh | 2 + tests/morpho/dilation.cc | 26 ++++++++++---- 3 files changed, 48 insertions(+), 64 deletions(-) Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 1687) +++ mln/morpho/includes.hh (working copy) @@ -38,6 +38,8 @@ # include <mln/core/concept/window.hh> # include <mln/core/concept/neighborhood.hh> +# include <mln/metal/has_neighborhood.hh> + # include <mln/value/ops.hh> # include <mln/accu/min.hh> Index: mln/morpho/dilation.hh --- mln/morpho/dilation.hh (revision 1687) +++ mln/morpho/dilation.hh (working copy) @@ -92,32 +92,6 @@ namespace impl { - /*---------------------. - | Neighborhood-based. | - `---------------------*/ - - /* 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) - { - /* 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, to_window(nbh), output); - } - - /*---------------. | Window-based. | `---------------*/ @@ -171,24 +145,6 @@ } } - // FIXME: Seems to be duplicate code! - -// /// 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); -// } - - // ... - // ------------- // // Dispatchers. // @@ -284,6 +240,31 @@ /// \} + + /*---------------------. + | Neighborhood-based. | + `---------------------*/ + + /* 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) + { + /* 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, convert::to_window(nbh), output); + } + } // end of namespace mln::morpho::impl @@ -301,22 +282,13 @@ { trace::entering("morpho::dilation"); + metal::has_neighborhood<I>::check(); + mln_precondition(exact(output).domain() == exact(input).domain()); - // Ensure the image has a `neighb' typedef. typedef mln_neighb(I) neighb; - // FIXME: Encapsulate this in a class + a macro. - // FIXME: Do we have better concept checking tools? - { - // Ensure the image has a `neighb' method. - neighb (I::*m)() const = &I::neighb; - m = 0; - - // FIXME: Do we need to check for more? - } - - impl::dilation_wrt_nbh(input, output); + impl::dilation_wrt_nbh(input, exact(input).neighborhood(), output); trace::exiting("morpho::dilation"); } Index: tests/morpho/dilation.cc --- tests/morpho/dilation.cc (revision 1687) +++ tests/morpho/dilation.cc (working copy) @@ -51,6 +51,9 @@ #include <mln/convert/to_p_array.hh> #include <mln/convert/to_window.hh> +#include <mln/core/neighb2d.hh> +#include <mln/neighb/image.hh> + #include "tests/data.hh" @@ -70,23 +73,30 @@ io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm"); { - // FIXME: This struct. elt. is far too big for a routinely run - // test; either use a smaller one or qualify this test as - // ``long''. - win::rectangle2d rec(21, 21); + win::rectangle2d rec(5, 3); image2d<int_u8> out(lena.domain()); morpho::dilation(lena, rec, out); io::pgm::save(out, "out1.pgm"); } { - win::octagon2d oct(6); + win::octagon2d oct(7); image2d<int_u8> out(lena.domain()); morpho::dilation(lena, oct, out); io::pgm::save(out, "out2.pgm"); } - // FIXME: Add tests using neighborhoods, too. + { + image2d<int_u8> out(lena.domain()); + morpho::dilation(lena + c4(), out); + io::pgm::save(out, "out3.pgm"); + } + + { + image2d<int_u8> out(lena.domain()); + morpho::dilation(lena + c8(), out); + io::pgm::save(out, "out4.pgm"); + } // { // p_array<point2d> vec = convert::to_p_array(rec, point2d::zero); @@ -95,7 +105,7 @@ // image2d<int_u8> out(lena.domain()); // level::ero(lena, win, out); // morpho::dilation(lena, win, out); -// io::pgm::save(out, "out.pgm"); +// io::pgm::save(out, "out5.pgm"); // } // { @@ -107,7 +117,7 @@ // image2d<int_u8>::fwd_piter p(lena.domain()); // for_all(p) // test(p) = out(p) ? 255 : 0; -// io::pgm::save(test, "test.pgm"); +// io::pgm::save(test, "out6.pgm"); // } }
participants (1)
-
Roland Levillain