URL:
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
ChangeLog:
2008-09-12 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Add fast arbitrary erosion.
* mln/morpho/erosion.hh: (erosion_arbitrary_2d_fastest) New, erosion
on fast images with an arbitrary window using min_h and the snake
browsing.
(erosion_arbitrary_2d_fastest) New, erosion on non-fast images with an
arbitrary window using min_h and the snake browsing.
* mln/morpho/erosion.spe.hh: Dummy fix.
---
erosion.hh | 4
erosion.spe.hh | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 228 insertions(+), 30 deletions(-)
Index: branches/cleanup-2008/milena/mln/morpho/erosion.spe.hh
===================================================================
--- branches/cleanup-2008/milena/mln/morpho/erosion.spe.hh (revision 2248)
+++ branches/cleanup-2008/milena/mln/morpho/erosion.spe.hh (revision 2249)
@@ -34,6 +34,10 @@
# include <mln/win/octagon2d.hh>
# include <mln/win/rectangle2d.hh>
+# include <mln/geom/shift.hh>
+# include <mln/accu/min_h.hh>
+# include <mln/set/diff.hh>
+# include <mln/canvas/browsing/snake_fwd.hh>
/*! \file mln/morpho/erosion.spe.hh
@@ -57,30 +61,10 @@
erosion(const Image<I>& input, const Window<W>& win);
- namespace internal
- {
- template <typename I, typename W>
- mln_concrete(I)
- erosion_dispatch(const Image<I>& input, const Window<W>& win)
- {
- if (mlc_equal(mln_trait_image_kind(I)(),
- trait::image::kind::logic)::value == true)
- if (mlc_equal(mln_trait_image_speed(I)(),
- trait::image::speed::fastest)::value == true)
- impl::erosion_on_set_fastest(input, win);
- else
- impl::generic::erosion_on_set(input, win);
- else
- if (mlc_equal(mln_trait_image_speed(I)(),
- trait::image::speed::fastest)::value == true)
- impl::erosion_on_function_fastest(input, win);
- else
- impl::generic::erosion_on_function(input, win);
- }
-
namespace impl
{
+
namespace generic
{
// Fwd decl.
@@ -143,6 +127,7 @@
mln_pixter(const I) p(input);
mln_pixter(O) p_out(output);
+ mln_qixter(const I, W) q(p, win);
for_all_2(p, p_out)
{
for_all(q)
@@ -220,14 +205,11 @@
template <typename I>
inline
mln_concrete(I)
- erosion_rectangle2d(const Image<I>& input_, const Window<W>&
win_)
+ erosion_rectangle2d(const Image<I>& input_, const win::rectangle2d&
win)
{
- mlc_equal(W, win::rectangle2d)::check();
-
trace::entering("morpho::impl::erosion_rectangle2d");
const I& input = exact(input_);
- const W& win = exact(win_);
mln_concrete(I) temp, output;
temp = morpho::erosion(input, win::hline2d(win.width()));
@@ -241,11 +223,12 @@
template <typename I>
inline
mln_concrete(I)
- erosion_octagon2d(const I& input, const win::octagon2d& win)
+ erosion_octagon2d(const Image<I>& input_, const win::octagon2d& win)
{
- mlc_equal(W, win::octagon2d)::check();
-
trace::entering("morpho::impl::erosion_octagon2d");
+
+ const I& input = exact(input_);
+
const unsigned len = win.length() / 3 + 1;
mln_concrete(I) temp_1, temp_2, output;
@@ -258,8 +241,223 @@
return output;
}
+ template <typename I, typename W>
+ struct erosion_arbitrary_2d_fastest_functor
+ {
+ const I& input;
+ const W& win;
+ mln_concrete(I) output;
+ accu::min_h<mln_value(I)> min;
+
+ mln_psite(I) p;
+
+ window2d
+ win_left,
+ win_right,
+ win_bot,
+ win_top;
+
+ mln_qixter(const I, window2d)
+ q_l,
+ q_r,
+ q_top,
+ q_bot;
+
+ erosion_arbitrary_2d_fastest_functor(const I& input, const W& win)
+ : input(input),
+ win(win),
+ min(input.values()),
+ win_left(set::diff(geom::shift(win, left), win)),
+ win_right(set::diff(win, geom::shift(win, left))),
+ win_bot(set::diff(win, geom::shift(win, up))),
+ win_top(set::diff(geom::shift(win, up), win)),
+ q_l(input, win_left, p),
+ q_r(input, win_right, p),
+ q_top(input, win_top, p),
+ q_bot(input, win_bot, p)
+ { }
+
+ void init()
+ {
+ initialize(output, input);
+ min.init();
+ p = input.domain().pmin() + up;
+ mln_qixter(const I, W) q(input, win, p);
+ for_all(q)
+ min.take(q.val());
+ }
+
+ void fwd()
+ {
+ ++p.col();
+ for_all(q_l)
+ min.untake(q_l.val());
+ for_all(q_r)
+ min.take(q_r.val());
+ output(p) = min;
+ }
+
+ void bkd()
+ {
+ --p.col();
+ for_all(q_r)
+ min.untake(q_r.val());
+ for_all(q_l)
+ min.take(q_l.val());
+ output(p) = min;
+ }
+
+ void down()
+ {
+ ++p.row();
+ for_all(q_top)
+ min.untake(q_top.val());
+ for_all(q_bot)
+ min.take(q_bot.val());
+ output(p) = min;
+ }
+
+ };
+
+ template <typename I, typename W>
+ inline
+ mln_concrete(I)
+ erosion_arbitrary_2d_fastest(const Image<I>& input, const
Window<W>& win)
+ {
+ trace::entering("morpho::impl:erosion_arbitrary_2d_fastest");
+
+ typedef erosion_arbitrary_2d_fastest_functor<I, W> F;
+ mlc_equal(W, win::octagon2d)::check();
+ F f(input, win);
+ canvas::browsing::snake_fwd(f);
+
+ trace::exiting("morpho::impl:erosion_arbitrary_2d_fastest");
+
+ return f.output;
+ }
+
+
+ template <typename I, typename W>
+ struct erosion_arbitrary_2d_functor
+ {
+ const I& input;
+ const W& win;
+ mln_concrete(I) output;
+ accu::min_h<mln_value(I)> min;
+
+ mln_psite(I) p;
+
+ window2d
+ win_left,
+ win_right,
+ win_bot,
+ win_top;
+
+ mln_qiter(window2d)
+ q_l,
+ q_r,
+ q_top,
+ q_bot;
+
+ erosion_arbitrary_2d_functor(const I& input, const W& win)
+ : input(input),
+ win(win),
+ min(input.values()),
+ win_left(set::diff(geom::shift(win, left), win)),
+ win_right(set::diff(win, geom::shift(win, left))),
+ win_bot(set::diff(win, geom::shift(win, up))),
+ win_top(set::diff(geom::shift(win, up), win)),
+ q_l(win_left, p),
+ q_r(win_right, p),
+ q_top(win_top, p),
+ q_bot(win_bot, p)
+ { }
+
+ void init()
+ {
+ initialize(output, input);
+ min.init();
+ p = input.domain().pmin() + up;
+ mln_qiter(W) q(win, p);
+ for_all(q)
+ min.take(input(q));
+ }
+
+ void fwd()
+ {
+ ++p.col();
+ for_all(q_l)
+ min.untake(input(q_l));
+ for_all(q_r)
+ min.take(input(q_r));
+ output(p) = min;
+ }
+
+ void bkd()
+ {
+ --p.col();
+ for_all(q_r)
+ min.untake(input(q_r));
+ for_all(q_l)
+ min.take(input(q_l));
+ output(p) = min;
+ }
+
+ void down()
+ {
+ ++p.row();
+ for_all(q_top)
+ min.untake(input(q_top));
+ for_all(q_bot)
+ min.take(input(q_bot));
+ output(p) = min;
+ }
+
+ };
+
+ template <typename I, typename W>
+ inline
+ mln_concrete(I)
+ erosion_arbitrary_2d(const Image<I>& input, const Window<W>&
win)
+ {
+ trace::entering("morpho::impl:erosion_arbitrary_2d");
+
+ typedef erosion_arbitrary_2d_functor<I, W> F;
+ mlc_equal(W, win::octagon2d)::check();
+ F f(input, win);
+ canvas::browsing::snake_fwd(f);
+
+ trace::exiting("morpho::impl:erosion_arbitrary_2d");
+
+ return f.output;
+ }
+
} // end of namespace mln::morpho::impl
+
+ namespace internal
+ {
+ template <typename I, typename W>
+ mln_concrete(I)
+ erosion_dispatch(const Image<I>& input, const Window<W>& win)
+ {
+ if (mlc_equal(mln_trait_image_kind(I)(),
+ trait::image::kind::logic)::value == true)
+ if (mlc_equal(mln_trait_image_speed(I)(),
+ trait::image::speed::fastest)::value == true)
+ impl::erosion_on_set_fastest(input, win);
+ else
+ impl::generic::erosion_on_set(input, win);
+ else
+ if (mlc_equal(mln_trait_image_speed(I)(),
+ trait::image::speed::fastest)::value == true)
+ impl::erosion_on_function_fastest(input, win);
+ else
+ impl::generic::erosion_on_function(input, win);
+ }
+
+ } // end of namespace mln::morpho::internal
+
} // end of namespace mln::morpho
} // end of namespace mln
Index: branches/cleanup-2008/milena/mln/morpho/erosion.hh
===================================================================
--- branches/cleanup-2008/milena/mln/morpho/erosion.hh (revision 2248)
+++ branches/cleanup-2008/milena/mln/morpho/erosion.hh (revision 2249)
@@ -63,7 +63,7 @@
template <typename I, typename W>
inline
mln_concrete(I)
- erosion_on_function(const Image<I>& input_, const Window<W>& win_);
+ erosion_on_function(const Image<I>& input_, const Window<W>& win_)
{
trace::entering("morpho::impl::generic::erosion_on_function");
@@ -93,7 +93,7 @@
template <typename I, typename W>
inline
mln_concrete(I)
- erosion_on_set(const Image<I>& input_, const Window<W>& win_);
+ erosion_on_set(const Image<I>& input_, const Window<W>& win_)
{
trace::entering("morpho::impl::generic::erosion_on_set");