https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Make morpho erosion rely on a general code.
* mln/morpho/erosion.spe.hh
(erosion_on_set, erosion_on_set_fastest): Rename as...
* mln/morpho/erosion.hh
(general_on_set, general_on_set_fastest): ...these.
(erosion_op): New.
(erosion): Call the general facade.
* mln/morpho/erosion.spe.hh: Rename as...
* mln/morpho/general.spe.hh: ...this new file.
(*erosion*): Rename routines as...
(*general*):... these.
(general_dispatch_for_generic): New overload for logic and
fastest. Now _on_set_fastest routines can be accessible!
* mln/accu/land_basic.hh (todo): New.
(land_basic): New meta version.
* mln/accu/land.hh: Likewise.
* mln/morpho/general.hh: New.
* tests/morpho/erosion.cc: Copy to...
* tests/morpho/general.cc: ...this new file.
Update.
* tests/morpho/erosion.cc: Update.
mln/accu/land.hh | 22 ++
mln/accu/land_basic.hh | 20 ++
mln/morpho/erosion.hh | 117 +++++++++------
mln/morpho/general.hh | 95 ++++++++----
mln/morpho/general.spe.hh | 339 ++++++++++++++++++++--------------------------
tests/morpho/erosion.cc | 65 +-------
tests/morpho/general.cc | 160 ++++++++-------------
7 files changed, 403 insertions(+), 415 deletions(-)
Index: tests/morpho/general.cc
--- tests/morpho/general.cc (revision 2970)
+++ tests/morpho/general.cc (working copy)
@@ -26,19 +26,16 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file tests/morpho/erosion.cc
+/// \file tests/morpho/general.cc
///
-/// Test on mln::morpho::erosion.
+/// Test on mln::morpho::general.
#include <mln/core/image/image2d.hh>
-#include <mln/win/all.hh>
-
-#include <mln/debug/iota.hh>
-
+#include <mln/value/int_u8.hh>
#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
+#include <mln/io/pbm/load.hh>
-#include <mln/value/int_u8.hh>
+#include <mln/win/all.hh>
#include <mln/morpho/erosion.hh>
#include "tests/data.hh"
@@ -49,130 +46,101 @@
using namespace mln;
using value::int_u8;
- border::thickness = 0;
- image2d<int_u8> lena;
- io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
+ // Windows.
+ win::rectangle2d rec(5, 5);
+ win::hline2d hline(7);
+ win::vline2d vline(7);
+ win::diag2d diag2d(7);
+ win::backdiag2d backdiag2d(7);
+ win::octagon2d oct(2 * 3 + 1);
- win::rectangle2d rec(21, 21);
- win::hline2d hline(31);
- win::vline2d vline(31);
- win::diag2d diag2d(31);
- win::backdiag2d backdiag2d(31);
- win::octagon2d oct(6 * 3 + 1);
- image2d<int_u8> out;
- image2d<int_u8> ref;
-
-// trace::quiet = false;
+ morpho::erosion_op ero;
+ {
+ image2d<int_u8> lena, out, ref;
+ io::pgm::load(lena, MLN_IMG_DIR "/tiny.pgm");
- // Rectangle
- {
- ref = morpho::impl::generic::erosion_on_function(lena, rec);
- }
+ // Rectangle.
- {
- out = morpho::erosion(lena, rec);
- bool test = out == ref;
- mln_assertion(test);
- }
+ ref = morpho::impl::generic::general_on_function(ero, lena, rec);
- {
- out = morpho::impl::erosion_arbitrary_2d(lena, rec);
- bool test = out == ref;
- mln_assertion(test);
- }
+ out = morpho::impl::general_rectangle2d(ero, lena, rec);
+ mln_assertion(out == ref);
+ out = morpho::impl::general_arbitrary_2d(ero, lena, rec);
+ mln_assertion(out == ref);
- // Hline
+ out = morpho::impl::general_directional(ero, lena, rec, 0);
+ mln_assertion(out == ref);
- {
- ref = morpho::impl::generic::erosion_on_function(lena, hline);
- }
+ out = morpho::impl::general_directional(ero, lena, rec, 1);
+ mln_assertion(out == ref);
- {
- out = morpho::erosion(lena, hline);
- bool test = out == ref;
- mln_assertion(test);
- }
+ /*
- {
- out = morpho::impl::erosion_arbitrary_2d(lena, hline);
- bool test = out == ref;
- mln_assertion(test);
- }
+ // Hline.
+ ref = morpho::impl::generic::general_on_function(ero, lena, hline);
+ // Vline.
+ ref = morpho::impl::generic::general_on_function(ero, lena, vline);
- // Vline
+ // Diag2d.
+ ref = morpho::impl::generic::erosion_on_function(lena, diag2d);
- {
- ref = morpho::impl::generic::erosion_on_function(lena, vline);
- }
+ // Backdiag2d.
+ ref = morpho::impl::generic::erosion_on_function(lena, backdiag2d);
- {
- out = morpho::erosion(lena, vline);
- bool test = out == ref;
- mln_assertion(test);
- }
+ // Octagon
+ ref = morpho::impl::generic::erosion_on_function(lena, oct);
+ // io::pgm::save(ref, "out_oct_ref.pgm");
- {
- out = morpho::impl::erosion_arbitrary_2d(lena, vline);
- bool test = out == ref;
- mln_assertion(test);
+ */
}
- // Diag2d
+ /*
{
- ref = morpho::impl::generic::erosion_on_function(lena, diag2d);
- }
+ trace::quiet = false;
- {
- out = morpho::erosion(lena, diag2d);
- bool test = out == ref;
- mln_assertion(test);
- }
+ image2d<bool> pic;
+ io::pbm::load(pic, MLN_IMG_DIR "/tiny.pbm");
- {
- out = morpho::impl::erosion_arbitrary_2d(lena, diag2d);
- bool test = out == ref;
- mln_assertion(test);
+ morpho::general(ero, pic, win::rectangle2d(3,3));
+
+ trace::quiet = true;
}
+ */
- // Backdiag2d
{
- ref = morpho::impl::generic::erosion_on_function(lena, backdiag2d);
- }
+ image2d<bool> pic, out, ref;
+ io::pbm::load(pic, MLN_IMG_DIR "/tiny.pbm");
- {
- out = morpho::erosion(lena, backdiag2d);
- bool test = out == ref;
- mln_assertion(test);
- }
+ // Rectangle.
- {
- out = morpho::impl::erosion_arbitrary_2d(lena, backdiag2d);
- bool test = out == ref;
- mln_assertion(test);
- }
+ ref = morpho::impl::generic::general_on_set(ero, pic, rec);
+ out = morpho::impl::general_on_set_centered(ero, pic, rec);
+ mln_assertion(out == ref);
+ out = morpho::impl::general_on_set_centered_fastest(ero, pic, rec);
+ mln_assertion(out == ref);
- // Octagon
+ out = morpho::impl::general_rectangle2d(ero, pic, rec);
+ mln_assertion(out == ref);
- {
- ref = morpho::impl::generic::erosion_on_function(lena, oct);
- io::pgm::save(ref, "out_oct_ref.pgm");
- }
+ out = morpho::impl::general_arbitrary_2d(ero, pic, rec);
+ mln_assertion(out == ref);
- {
- out = morpho::erosion(lena, oct);
- bool test = out == ref;
- mln_assertion(test);
+ out = morpho::impl::general_directional(ero, pic, rec, 0);
+ mln_assertion(out == ref);
+
+ out = morpho::impl::general_directional(ero, pic, rec, 1);
+ mln_assertion(out == ref);
}
}
Index: tests/morpho/erosion.cc
--- tests/morpho/erosion.cc (revision 2971)
+++ tests/morpho/erosion.cc (working copy)
@@ -32,13 +32,9 @@
#include <mln/core/image/image2d.hh>
#include <mln/win/all.hh>
-
-#include <mln/debug/iota.hh>
-
#include <mln/io/pgm/load.hh>
-#include <mln/io/pgm/save.hh>
-
#include <mln/value/int_u8.hh>
+
#include <mln/morpho/erosion.hh>
#include "tests/data.hh"
@@ -63,6 +59,7 @@
image2d<int_u8> out;
image2d<int_u8> ref;
+
// trace::quiet = false;
@@ -70,18 +67,12 @@
{
ref = morpho::impl::generic::erosion_on_function(lena, rec);
- }
- {
out = morpho::erosion(lena, rec);
- bool test = out == ref;
- mln_assertion(test);
- }
+ mln_assertion(out == ref);
- {
out = morpho::impl::erosion_arbitrary_2d(lena, rec);
- bool test = out == ref;
- mln_assertion(test);
+ mln_assertion(out == ref);
}
@@ -89,18 +80,12 @@
{
ref = morpho::impl::generic::erosion_on_function(lena, hline);
- }
- {
out = morpho::erosion(lena, hline);
- bool test = out == ref;
- mln_assertion(test);
- }
+ mln_assertion(out == ref);
- {
out = morpho::impl::erosion_arbitrary_2d(lena, hline);
- bool test = out == ref;
- mln_assertion(test);
+ mln_assertion(out == ref);
}
@@ -108,18 +93,12 @@
{
ref = morpho::impl::generic::erosion_on_function(lena, vline);
- }
- {
out = morpho::erosion(lena, vline);
- bool test = out == ref;
- mln_assertion(test);
- }
+ mln_assertion(out == ref);
- {
out = morpho::impl::erosion_arbitrary_2d(lena, vline);
- bool test = out == ref;
- mln_assertion(test);
+ mln_assertion(out == ref);
}
@@ -127,18 +106,12 @@
{
ref = morpho::impl::generic::erosion_on_function(lena, diag2d);
- }
- {
out = morpho::erosion(lena, diag2d);
- bool test = out == ref;
- mln_assertion(test);
- }
+ mln_assertion(out == ref);
- {
out = morpho::impl::erosion_arbitrary_2d(lena, diag2d);
- bool test = out == ref;
- mln_assertion(test);
+ mln_assertion(out == ref);
}
@@ -146,18 +119,12 @@
{
ref = morpho::impl::generic::erosion_on_function(lena, backdiag2d);
- }
- {
out = morpho::erosion(lena, backdiag2d);
- bool test = out == ref;
- mln_assertion(test);
- }
+ mln_assertion(out == ref);
- {
out = morpho::impl::erosion_arbitrary_2d(lena, backdiag2d);
- bool test = out == ref;
- mln_assertion(test);
+ mln_assertion(out == ref);
}
@@ -166,13 +133,9 @@
{
ref = morpho::impl::generic::erosion_on_function(lena, oct);
- io::pgm::save(ref, "out_oct_ref.pgm");
- }
-
- {
+ // io::pgm::save(ref, "out_oct_ref.pgm");
out = morpho::erosion(lena, oct);
- bool test = out == ref;
- mln_assertion(test);
+ mln_assertion(out == ref);
}
}
Index: mln/accu/land_basic.hh
--- mln/accu/land_basic.hh (revision 2971)
+++ mln/accu/land_basic.hh (working copy)
@@ -32,6 +32,8 @@
/// \file mln/accu/land_basic.hh
///
/// Define a basic 'logical-and' accumulator.
+///
+/// \todo Have land_basic be parameterized.
# include <mln/accu/internal/base.hh>
@@ -77,6 +79,24 @@
};
+ namespace meta
+ {
+
+ /// Meta accumulator for land_basic.
+
+ struct land_basic : public Meta_Accumulator< land_basic >
+ {
+ template <typename T>
+ struct with
+ {
+ typedef accu::land_basic ret;
+ };
+ };
+
+ } // end of namespace mln::accu::meta
+
+
+
# ifndef MLN_INCLUDE_ONLY
inline
Index: mln/accu/land.hh
--- mln/accu/land.hh (revision 2971)
+++ mln/accu/land.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
@@ -32,6 +33,7 @@
///
/// Define a 'logical-and' accumulator.
///
+/// \todo Have land_basic be parameterized.
# include <mln/accu/internal/base.hh>
@@ -73,6 +75,24 @@
};
+ namespace meta
+ {
+
+ /// Meta accumulator for land.
+
+ struct land : public Meta_Accumulator< land >
+ {
+ template <typename T>
+ struct with
+ {
+ typedef accu::land ret;
+ };
+ };
+
+ } // end of namespace mln::accu::meta
+
+
+
# ifndef MLN_INCLUDE_ONLY
inline
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh (revision 2971)
+++ mln/morpho/erosion.hh (working copy)
@@ -31,12 +31,10 @@
/// \file mln/morpho/erosion.hh
///
-/// \brief Morphological erosion.
+/// Morphological erosion.
# include <mln/morpho/includes.hh>
-
-// Specializations are in:
-# include <mln/morpho/erosion.spe.hh>
+# include <mln/morpho/general.hh>
namespace mln
@@ -45,8 +43,7 @@
namespace morpho
{
- /*! Morphological erosion.
- */
+ /// Morphological erosion.
template <typename I, typename W>
mln_concrete(I)
erosion(const Image<I>& input, const Window<W>& win);
@@ -55,80 +52,106 @@
# ifndef MLN_INCLUDE_ONLY
- namespace internal
+ struct erosion_op
{
- template <typename I, typename W>
- inline
- void
- erosion_tests(const Image<I>& input_, const Window<W>& win_)
+ template <typename I>
+ mln_morpho_select_accu(I, land_basic, min)
+ accu(const Image<I>&) const
{
- const I& input = exact(input_);
- const W& win = exact(win_);
+ mln_morpho_select_accu(I, land_basic, min) tmp;
+ return tmp;
+ }
- mln_precondition(input.has_data());
- mln_precondition(! win.is_empty());
- // mln_precondition(win.is_valid());
+ template <typename I>
+ mln_morpho_select_accu(I, land, min_h)
+ accu_incr(const Image<I>&) const
+ {
+ mln_morpho_select_accu(I, land, min_h) tmp;
+ return tmp;
+ }
- (void) input;
- (void) win;
+ template <typename I>
+ mln_value(I) neutral(const Image<I>&) const
+ {
+ return internal::neutral<I>::supremum();
}
- } // end of mln::morpho::internal
+ };
namespace impl
{
- namespace generic
- {
-
- // On function.
+ // On set with centered window (overloads).
template <typename I, typename W>
- inline
mln_concrete(I)
- erosion_on_function(const Image<I>& input, const Window<W>& win)
+ general_on_set_centered(const erosion_op&,
+ const Image<I>& input_, const Window<W>& win_)
{
- trace::entering("morpho::impl::generic::erosion_on_function");
+ trace::entering("morpho::impl::general_on_set_centered__erosion");
+
+ typedef mln_concrete(I) O;
+ const I& input = exact(input_);
+ const W& win = exact(win_);
- internal::erosion_tests(input, win);
+ extension::adjust_fill(input, win, true);
+
+ O output;
+ output = clone(input);
- extension::adjust_fill(input, win, mln_max(mln_value(I)));
- mln_concrete(I) output;
- output = accu::transform(input, accu::meta::min(), win);
+ mln_piter(I) p(input.domain());
+ mln_qiter(W) q(win, p);
+ for_all(p)
+ if (input(p) == true)
+ for_all(q) if (input.has(q))
+ if (input(q) == false)
+ {
+ output(p) = false;
+ break;
+ }
- trace::exiting("morpho::impl::generic::erosion_on_function");
+ trace::exiting("morpho::impl::general_on_set_centered__erosion");
return output;
}
- // On set.
template <typename I, typename W>
- inline
mln_concrete(I)
- erosion_on_set(const Image<I>& input, const Window<W>& win)
+ general_on_set_centered_fastest(const erosion_op&,
+ const Image<I>& input_, const Window<W>& win_)
{
- trace::entering("morpho::impl::generic::erosion_on_set");
+ trace::entering("morpho::impl::general_on_set_centered_fastest__erosion");
- internal::erosion_tests(input, win);
+ typedef mln_concrete(I) O;
+ const I& input = exact(input_);
+ const W& win = exact(win_);
extension::adjust_fill(input, win, true);
- mln_concrete(I) output;
- output = accu::transform_stop(input, accu::land_basic(), win);
- trace::exiting("morpho::impl::generic::erosion_on_set");
- return output;
- }
-
- } // end of namespace mln::morpho::impl::generic
+ O output;
+ output = clone(input);
- } // end of namespace mln::morpho::impl
+ mln_pixter(const I) p(input);
+ mln_qixter(const I, W) q(p, win);
+ mln_pixter(O) p_out(output);
+ for_all_2(p, p_out)
+ if (p.val() == true)
+ for_all(q)
+ if (q.val() == false)
+ {
+ p_out.val() = false;
+ break;
+ }
+ trace::exiting("morpho::impl::general_on_set_centered_fastest__erosion");
+ return output;
+ }
+ } // end of namespace morpho::impl
- // Facades.
template <typename I, typename W>
inline
@@ -139,11 +162,11 @@
mln_precondition(exact(input).has_data());
mln_precondition(! exact(win).is_empty());
- internal::erosion_tests(input, win);
- mln_concrete(I) output = internal::erosion_dispatch(input, win);
+ mln_concrete(I) output = general(erosion_op(), input, win);
if (exact(win).is_centered())
mln_postcondition(output <= input);
+
trace::exiting("morpho::erosion");
return output;
}
Index: mln/morpho/general.spe.hh
--- mln/morpho/general.spe.hh (revision 2970)
+++ mln/morpho/general.spe.hh (working copy)
@@ -26,12 +26,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MORPHO_EROSION_SPE_HH
-# define MLN_MORPHO_EROSION_SPE_HH
+#ifndef MLN_MORPHO_GENERAL_SPE_HH
+# define MLN_MORPHO_GENERAL_SPE_HH
-# ifndef MLN_MORPHO_EROSION_HH
+# ifndef MLN_MORPHO_GENERAL_HH
# error "Forbidden inclusion of *.spe.hh"
-# endif // ! MLN_MORPHO_EROSION_HH
+# endif // ! MLN_MORPHO_GENERAL_HH
# include <mln/core/alias/window2d.hh>
# include <mln/core/alias/dpoint2d.hh>
@@ -43,14 +43,18 @@
# include <mln/accu/line.hh>
-/// \file mln/morpho/erosion.spe.hh
+/// \file mln/morpho/general.spe.hh
///
-/// Specialization for mln::morpho::erosion.
+/// Specialization for mln::morpho::general.
///
/// \todo Warning: we should also have the "arbitrary" versions working
/// on sets (not only on functions!)
///
/// \todo HERE Factor dispatch for lines...
+///
+/// \todo Re-activate impl::line_on_function.
+///
+/// \todo Re-activate special code for centered window on sets.
# ifndef MLN_INCLUDE_ONLY
@@ -62,9 +66,9 @@
{
// Fwd decl of the facade.
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion(const Image<I>& input, const Window<W>& win);
+ general(const Op& op, const Image<I>& input, const Window<W>&
win);
namespace impl
@@ -73,94 +77,49 @@
namespace generic
{
- // Fwd decl.
- // Implementation is in mln/morpho/erosion.hh.
- template <typename I, typename W>
+ // Forward declaration.
+ // Implementation is in mln/morpho/general.hh.
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_on_function(const Image<I>& input_, const Window<W>& win_);
+ general_on_function(const Op& op, const Image<I>& input_, const
Window<W>& win_);
- // Fwd decl.
- // Implementation is in mln/morpho/erosion.hh.
- template <typename I, typename W>
+ // Forward declaration.
+ // Implementation is in mln/morpho/general.hh.
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_on_set(const Image<I>& input_, const Window<W>& win_);
+ general_on_set(const Op& op, const Image<I>& input_, const
Window<W>& win_);
}
+
// On set with centered window.
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_on_set_centered(const Image<I>& input_, const
Window<W>& win_)
- {
- trace::entering("morpho::impl::erosion_on_set_centered");
-
- typedef mln_concrete(I) O;
- const I& input = exact(input_);
- const W& win = exact(win_);
-
- extension::adjust_fill(input, win, true);
-
- O output;
- output = clone(input);
-
- mln_piter(I) p(input.domain());
- mln_qiter(W) q(win, p);
- for_all(p)
- if (input(p) == true)
- for_all(q) if (input.has(q))
- if (input(q) == false)
+ general_on_set_centered(const Op& op, const Image<I>& input, const
Window<W>& win)
{
- output(p) = false;
- break;
+ return generic::general_on_set(op, input, win);
}
- trace::exiting("morpho::impl::erosion_on_set_centered");
- return output;
- }
-
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_on_set_centered_fastest(const Image<I>& input_, const
Window<W>& win_)
- {
- trace::entering("morpho::impl::erosion_on_set_centered_fastest");
-
- typedef mln_concrete(I) O;
- const I& input = exact(input_);
- const W& win = exact(win_);
-
- extension::adjust_fill(input, win, true);
-
- O output;
- output = clone(input);
-
- mln_pixter(const I) p(input);
- mln_qixter(const I, W) q(p, win);
- mln_pixter(O) p_out(output);
- for_all_2(p, p_out)
- if (p.val() == true)
- for_all(q)
- if (q.val() == false)
+ general_on_set_centered_fastest(const Op& op, const Image<I>& input,
const Window<W>& win)
{
- p_out.val() = false;
- break;
- }
- trace::exiting("morpho::impl::erosion_on_set_centered_fastest");
-
- return output;
+ return generic::general_on_set(op, input, win);
}
+/*
// Line case.
- template <typename I, typename G, unsigned Dir, typename C>
+ template <typename Op, typename I, typename G, unsigned Dir, typename C>
inline
mln_concrete(I)
- erosion_line_on_function(const Image<I>& input_, const
win::line<G,Dir,C>& win)
+ general_line_on_function(const Op& op, const Image<I>& input_, const
win::line<G,Dir,C>& win)
{
- trace::entering("morpho::impl::erosion_line");
+ trace::entering("morpho::impl::general_line");
typedef mln_site(I) P;
enum { dim = P::dim };
@@ -199,108 +158,100 @@
}
while (p != pmin);
- trace::exiting("morpho::impl::erosion_line");
+ trace::exiting("morpho::impl::general_line");
return output;
}
+*/
// Particular windows.
- template <typename I>
+ template <typename Op, typename I>
inline
mln_concrete(I)
- erosion_rectangle2d(const Image<I>& input_, const win::rectangle2d&
win)
+ general_rectangle2d(const Op& op, const Image<I>& input_, const
win::rectangle2d& win)
{
- trace::entering("morpho::impl::erosion_rectangle2d");
+ trace::entering("morpho::impl::general_rectangle2d");
const I& input = exact(input_);
mln_concrete(I) temp, output;
- temp = morpho::erosion(input, win::hline2d(win.width()));
- output = morpho::erosion(temp, win::vline2d(win.height()));
+ temp = morpho::general(op, input, win::hline2d(win.width()));
+ output = morpho::general(op, temp, win::vline2d(win.height()));
- trace::exiting("morpho::impl::erosion_rectangle2d");
+ trace::exiting("morpho::impl::general_rectangle2d");
return output;
}
- template <typename I>
+ template <typename Op, typename I>
inline
mln_concrete(I)
- erosion_octagon2d(const Image<I>& input_, const win::octagon2d& win)
+ general_octagon2d(const Op& op, const Image<I>& input_, const
win::octagon2d& win)
{
- trace::entering("morpho::impl::erosion_octagon2d");
+ trace::entering("morpho::impl::general_octagon2d");
const I& input = exact(input_);
const unsigned len = (win.length() + 2) / 3;
mln_concrete(I) output;
- output = morpho::erosion(input, win::hline2d(len));
- output = morpho::erosion(output, win::vline2d(len));
- output = morpho::erosion(output, win::diag2d(len));
- output = morpho::erosion(output, win::backdiag2d(len));
+ output = morpho::general(op, input, win::hline2d(len));
+ output = morpho::general(op, output, win::vline2d(len));
+ output = morpho::general(op, output, win::diag2d(len));
+ output = morpho::general(op, output, win::backdiag2d(len));
- trace::exiting("morpho::impl::erosion_(win::octagon2d)");
+ trace::exiting("morpho::impl::general_(win::octagon2d)");
return output;
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
inline
mln_concrete(I)
- erosion_arbitrary_2d(const Image<I>& input, const Window<W>&
win)
+ general_arbitrary_2d(const Op& op, const Image<I>& input, const
Window<W>& win)
{
- trace::entering("morpho::impl:erosion_arbitrary_2d");
+ trace::entering("morpho::impl:general_arbitrary_2d");
- typedef mlc_is(mln_trait_image_kind(I), trait::image::kind::binary) is_binary;
- typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
- A a;
-
- extension::adjust_fill(input, geom::delta(win) + 1, a);
- mln_concrete(I) output = accu::transform_snake(a, input, win);
+ extension::adjust_fill(input, geom::delta(win) + 1, op.neutral(input));
+ mln_concrete(I) output;
+ output = accu::transform_snake(op.accu_incr(input), input, win);
- trace::exiting("morpho::impl:erosion_arbitrary_2d");
+ trace::exiting("morpho::impl:general_arbitrary_2d");
return output;
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
inline
mln_concrete(I)
- erosion_directional(const Image<I>& input, const Window<W>&
win, unsigned dir)
+ general_directional(const Op& op, const Image<I>& input, const
Window<W>& win, unsigned dir)
{
- trace::entering("morpho::impl:erosion_directional");
+ trace::entering("morpho::impl:general_directional");
- typedef mlc_is(mln_trait_image_kind(I), trait::image::kind::binary) is_binary;
- typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
- A a;
-
- extension::adjust_fill(input, geom::delta(win) + 1, a);
- mln_concrete(I) output = accu::transform_directional(a, input, win, dir);
+ extension::adjust_fill(input, geom::delta(win) + 1, op.neutral(input));
+ mln_concrete(I) output;
+ output = accu::transform_directional(op.accu_incr(input), input, win, dir);
- trace::exiting("morpho::impl:erosion_directional");
+ trace::exiting("morpho::impl:general_directional");
return output;
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
inline
mln_concrete(I)
- erosion_diagonal_2d(const Image<I>& input, const Window<W>&
win)
+ general_diagonal_2d(const Op& op, const Image<I>& input, const
Window<W>& win)
{
- trace::entering("morpho::impl:erosion_diagonal_2d");
-
- typedef mlc_is(mln_trait_image_kind(I), trait::image::kind::binary) is_binary;
- typedef mlc_if(is_binary, accu::land, accu::min_h<mln_value(I)>) A;
- A a;
+ trace::entering("morpho::impl:general_diagonal_2d");
- extension::adjust_fill(input, geom::delta(win) + 1, a);
- mln_concrete(I) output = accu::transform_diagonal(a, input, win);
+ extension::adjust_fill(input, geom::delta(win) + 1, op.neutral(input));
+ mln_concrete(I) output;
+ output = accu::transform_diagonal(op.accu_incr(input), input, win);
- trace::exiting("morpho::impl:erosion_diagonal_2d");
+ trace::exiting("morpho::impl:general_diagonal_2d");
return output;
}
@@ -317,37 +268,49 @@
namespace internal
{
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_for_generic(trait::image::kind::logic, // On sets.
- trait::image::speed::any,
- const I& input, const W& win)
+ general_dispatch_for_generic(trait::image::kind::logic, // On sets.
+ trait::image::speed::any, // Any speed.
+ const Op& op, const I& input, const W& win)
{
if (win.is_centered())
- return impl::erosion_on_set_centered(input, win);
+ return impl::general_on_set_centered(op, input, win);
else
- return impl::generic::erosion_on_set(input, win);
+ return impl::generic::general_on_set(op, input, win);
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_for_generic(trait::image::kind::any, // On functions.
+ general_dispatch_for_generic(trait::image::kind::logic, // On sets.
+ trait::image::speed::fastest, // Fastest.
+ const Op& op, const I& input, const W& win)
+ {
+ if (win.is_centered())
+ return impl::general_on_set_centered_fastest(op, input, win);
+ else
+ return impl::generic::general_on_set(op, input, win);
+ }
+
+ template <typename Op, typename I, typename W>
+ mln_concrete(I)
+ general_dispatch_for_generic(trait::image::kind::any, // On functions.
trait::image::speed::any,
- const I& input, const W& win)
+ const Op& op, const I& input, const W& win)
{
- return impl::generic::erosion_on_function(input, win);
+ return impl::generic::general_on_function(op, input, win);
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_for_generic(const I& input, const W& win) // Entry point.
+ general_dispatch_for_generic(const Op& op, const I& input, const W&
win) // Entry point.
{
- trace::entering("morpho::erosion_dispatch_for_generic");
+ trace::entering("morpho::general_dispatch_for_generic");
mln_concrete(I) ima =
- erosion_dispatch_for_generic(mln_trait_image_kind(I)(),
+ general_dispatch_for_generic(mln_trait_image_kind(I)(),
mln_trait_image_speed(I)(),
- input, win);
- trace::entering("morpho::erosion_dispatch_for_generic");
+ op, input, win);
+ trace::entering("morpho::general_dispatch_for_generic");
return ima;
}
@@ -357,25 +320,25 @@
// dispatch w.r.t. win
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_wrt_arbitrary_win(metal::true_,
- const I& input, const W& win)
+ general_dispatch_wrt_arbitrary_win(metal::true_,
+ const Op& op, const I& input, const W& win)
{
- return morpho::impl::erosion_arbitrary_2d(input, win);
+ return morpho::impl::general_arbitrary_2d(op, input, win);
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_wrt_arbitrary_win(metal::false_,
- const I& input, const W& win)
+ general_dispatch_wrt_arbitrary_win(metal::false_,
+ const Op& op, const I& input, const W& win)
{
- return erosion_dispatch_for_generic(input, win);
+ return general_dispatch_for_generic(op, input, win);
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_wrt_win(const I& input, const W& win)
+ general_dispatch_wrt_win(const I& input, const W& win)
{
// FIXME:
// The test "win.size() >= 10" (size is not too small) has been
@@ -389,32 +352,32 @@
&&
mlc_not_equal(mln_trait_image_value_storage(I),
trait::image::value_storage::disrupted)::value };
- return erosion_dispatch_wrt_arbitrary_win(metal::bool_<test>(),
+ return general_dispatch_wrt_arbitrary_win(metal::bool_<test>(),
input, win);
}
- template <typename I>
+ template <typename Op, typename I>
mln_concrete(I)
- erosion_dispatch_wrt_win(const I& input, const win::rectangle2d& win)
+ general_dispatch_wrt_win(const Op& op, const I& input, const
win::rectangle2d& win)
{
if (win.size() == 1)
return clone(input);
if (win.size() <= 9) // FIXME: Hard-coded!
- return erosion_dispatch_for_generic(input, win);
- return impl::erosion_rectangle2d(input, win);
+ return general_dispatch_for_generic(op, input, win);
+ return impl::general_rectangle2d(op, input, win);
}
- template <typename I>
+ template <typename Op, typename I>
mln_concrete(I)
- erosion_dispatch_wrt_win(const I& input, const win::octagon2d& win)
+ general_dispatch_wrt_win(const Op& op, const I& input, const
win::octagon2d& win)
{
if (win.length() < 5)
- return impl::erosion_arbitrary_2d(input, win);
+ return impl::general_arbitrary_2d(op, input, win);
else
- return impl::erosion_octagon2d(input, win);
+ return impl::general_octagon2d(op, input, win);
}
@@ -422,37 +385,37 @@
/// Handling win::line(s).
/// \{
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_line(metal::true_,
- const I& input, const W& win)
+ general_dispatch_line(metal::true_,
+ const Op& op, const I& input, const W& win)
{
- return impl::erosion_directional(input, win, W::dir);
+ return impl::general_directional(op, input, win, W::dir);
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_line(metal::false_,
- const I& input, const W& win)
+ general_dispatch_line(metal::false_,
+ const Op& op, const I& input, const W& win)
{
- return erosion_dispatch_for_generic(input, win);
+ return general_dispatch_for_generic(op, input, win);
}
- template <typename I, typename M, unsigned i, typename C>
+ template <typename Op, typename I, typename M, unsigned i, typename C>
mln_concrete(I)
- erosion_dispatch_wrt_win(const I& input, const win::line<M,i,C>&
win)
+ general_dispatch_wrt_win(const Op& op, const I& input, const
win::line<M,i,C>& win)
{
if (win.size() == 1)
return clone(input);
else if (win.size() == 3)
- return erosion_dispatch_for_generic(input, win);
+ return general_dispatch_for_generic(op, input, win);
else
{
enum { test = mlc_is_a(mln_pset(I), Box)::value
&& mlc_equal(mln_trait_image_quant(I),
mln::trait::image::quant::low)::value };
- return erosion_dispatch_line(metal::bool_<test>(),
- input, win);
+ return general_dispatch_line(metal::bool_<test>(),
+ op, input, win);
}
}
@@ -464,53 +427,53 @@
/// Handling diagonals.
/// \{
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_diagonal(metal::true_,
- const I& input, const W& win)
+ general_dispatch_diagonal(metal::true_,
+ const Op& op, const I& input, const W& win)
{
- return impl::erosion_diagonal_2d(input, win);
+ return impl::general_diagonal_2d(op, input, win);
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_diagonal(metal::false_,
- const I& input, const W& win)
+ general_dispatch_diagonal(metal::false_,
+ const Op& op, const I& input, const W& win)
{
- return erosion_dispatch_for_generic(input, win);
+ return general_dispatch_for_generic(op, input, win);
}
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch_diagonal(const I& input, const W& win)
+ general_dispatch_diagonal(const Op& op, const I& input, const W& win)
{
if (win.size() == 1)
return clone(input);
else if (win.size() == 3)
- return erosion_dispatch_for_generic(input, win);
+ return general_dispatch_for_generic(op, input, win);
else
{
enum { test = mlc_is_a(mln_pset(I), Box)::value
&& mlc_equal(mln_trait_image_quant(I),
mln::trait::image::quant::low)::value };
- return erosion_dispatch_diagonal(metal::bool_<test>(),
- input, win);
+ return general_dispatch_diagonal(metal::bool_<test>(),
+ op, input, win);
}
}
- template <typename I>
+ template <typename Op, typename I>
mln_concrete(I)
- erosion_dispatch_wrt_win(const I& input, const win::diag2d& win)
+ general_dispatch_wrt_win(const Op& op, const I& input, const
win::diag2d& win)
{
- return erosion_dispatch_diagonal(input, win);
+ return general_dispatch_diagonal(op, input, win);
}
- template <typename I>
+ template <typename Op, typename I>
mln_concrete(I)
- erosion_dispatch_wrt_win(const I& input, const win::backdiag2d& win)
+ general_dispatch_wrt_win(const Op& op, const I& input, const
win::backdiag2d& win)
{
- return erosion_dispatch_diagonal(input, win);
+ return general_dispatch_diagonal(op, input, win);
}
/// \}
@@ -519,11 +482,11 @@
// The dispatch entry point.
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion_dispatch(const Image<I>& input, const Window<W>& win)
+ general_dispatch(const Op& op, const Image<I>& input, const
Window<W>& win)
{
- return erosion_dispatch_wrt_win(exact(input), exact(win));
+ return general_dispatch_wrt_win(op, exact(input), exact(win));
}
} // end of namespace mln::morpho::internal
@@ -535,4 +498,4 @@
# endif // ! MLN_INCLUDE_ONLY
-#endif // ! MLN_MORPHO_EROSION_SPE_HH
+#endif // ! MLN_MORPHO_GENERAL_SPE_HH
Index: mln/morpho/general.hh
--- mln/morpho/general.hh (revision 2970)
+++ mln/morpho/general.hh (working copy)
@@ -26,17 +26,28 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MORPHO_EROSION_HH
-# define MLN_MORPHO_EROSION_HH
+#ifndef MLN_MORPHO_GENERAL_HH
+# define MLN_MORPHO_GENERAL_HH
-/// \file mln/morpho/erosion.hh
+/// \file mln/morpho/general.hh
///
-/// \brief Morphological erosion.
+/// Morphological general routine with dispatch.
+///
+/// \todo Have infimum and supremum for value types, apart from
+/// morphology!
# include <mln/morpho/includes.hh>
// Specializations are in:
-# include <mln/morpho/erosion.spe.hh>
+# include <mln/morpho/general.spe.hh>
+
+
+
+# define mln_morpho_select_accu(I, S, F) \
+typename mln::metal::if_< mln::metal::is< mln_trait_image_kind(I), \
+ trait::image::kind::binary >, \
+ mln::accu::meta::S, \
+ mln::accu::meta::F >::ret
namespace mln
@@ -45,11 +56,10 @@
namespace morpho
{
- /*! Morphological erosion.
- */
- template <typename I, typename W>
+ /// Morphological general routine.
+ template <typename Op, typename I, typename W>
mln_concrete(I)
- erosion(const Image<I>& input, const Window<W>& win);
+ general(const Op& op, const Image<I>& input, const Window<W>&
win);
# ifndef MLN_INCLUDE_ONLY
@@ -58,10 +68,10 @@
namespace internal
{
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
inline
void
- erosion_tests(const Image<I>& input_, const Window<W>& win_)
+ general_tests(const Op& op, const Image<I>& input_, const
Window<W>& win_)
{
const I& input = exact(input_);
const W& win = exact(win_);
@@ -70,10 +80,31 @@
mln_precondition(! win.is_empty());
// mln_precondition(win.is_valid());
+ (void) op;
(void) input;
(void) win;
}
+
+ // Temporary code; see 'todo' above.
+ template <typename I, bool is_binary> // true
+ struct neutral_impl
+ {
+ static mln_value(I) infimum() { return false; }
+ static mln_value(I) supremum() { return true; }
+ };
+ template <typename I>
+ struct neutral_impl< I, false >
+ {
+ static mln_value(I) infimum() { return mln_min(mln_value(I)); }
+ static mln_value(I) supremum() { return mln_max(mln_value(I)); }
+ };
+ template <typename I>
+ struct neutral : neutral_impl< I, mlc_is(mln_trait_image_kind(I),
+ trait::image::kind::binary)::value >
+ {
+ };
+
} // end of mln::morpho::internal
@@ -86,39 +117,39 @@
// On function.
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
inline
mln_concrete(I)
- erosion_on_function(const Image<I>& input, const Window<W>& win)
+ general_on_function(const Op& op, const Image<I>& input, const
Window<W>& win)
{
- trace::entering("morpho::impl::generic::erosion_on_function");
+ trace::entering("morpho::impl::generic::general_on_function");
- internal::erosion_tests(input, win);
+ internal::general_tests(op, input, win);
- extension::adjust_fill(input, win, mln_max(mln_value(I)));
+ extension::adjust_fill(input, win, op.neutral(input));
mln_concrete(I) output;
- output = accu::transform(input, accu::meta::min(), win);
+ output = accu::transform(input, op.accu(input), win);
- trace::exiting("morpho::impl::generic::erosion_on_function");
+ trace::exiting("morpho::impl::generic::general_on_function");
return output;
}
// On set.
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
inline
mln_concrete(I)
- erosion_on_set(const Image<I>& input, const Window<W>& win)
+ general_on_set(const Op& op, const Image<I>& input, const
Window<W>& win)
{
- trace::entering("morpho::impl::generic::erosion_on_set");
+ trace::entering("morpho::impl::generic::general_on_set");
- internal::erosion_tests(input, win);
+ internal::general_tests(op, input, win);
- extension::adjust_fill(input, win, true);
+ extension::adjust_fill(input, win, op.neutral(input));
mln_concrete(I) output;
- output = accu::transform_stop(input, accu::land_basic(), win);
+ output = accu::transform_stop(input, op.accu(input), win);
- trace::exiting("morpho::impl::generic::erosion_on_set");
+ trace::exiting("morpho::impl::generic::general_on_set");
return output;
}
@@ -130,21 +161,21 @@
// Facades.
- template <typename I, typename W>
+ template <typename Op, typename I, typename W>
inline
mln_concrete(I)
- erosion(const Image<I>& input, const Window<W>& win)
+ general(const Op& op, const Image<I>& input, const Window<W>&
win)
{
- trace::entering("morpho::erosion");
+ trace::entering("morpho::general");
mln_precondition(exact(input).has_data());
mln_precondition(! exact(win).is_empty());
- internal::erosion_tests(input, win);
- mln_concrete(I) output = internal::erosion_dispatch(input, win);
+ internal::general_tests(op, input, win);
+ mln_concrete(I) output = internal::general_dispatch(op, input, win);
if (exact(win).is_centered())
mln_postcondition(output <= input);
- trace::exiting("morpho::erosion");
+ trace::exiting("morpho::general");
return output;
}
@@ -155,4 +186,4 @@
} // end of namespace mln
-#endif // ! MLN_MORPHO_EROSION_HH
+#endif // ! MLN_MORPHO_GENERAL_HH