https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)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");
// }
}