https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Some cleanups in classical filters.
* mln/data/memcpy_.hh: Deactivate trace.
This internal routine floods the trace file because it can
be called in a loop.
* mln/linear/gaussian.hh (class): Replace by...
(typename): ...this.
See sandbox/theo/exec/ for a fastest implementation.
* mln/accu/transform_line.hh (transform_line_fastest): New.
* mln/morpho/rank_filter.hh (rank_filter_line): New.
(rank_filter_dispatch): New overload for rectangle2d.
* mln/morpho/includes.hh: Update.
* img/BUG_lean_ascii.pgm.gz: New.
This file makes io::pgm::load bug.
mln/accu/transform_line.hh | 149 ++++++++++++++++++++++++++++++++++++++++++++-
mln/data/memcpy_.hh | 12 +--
mln/linear/gaussian.hh | 22 ++++--
mln/morpho/includes.hh | 5 -
mln/morpho/rank_filter.hh | 62 ++++++++++++++++--
5 files changed, 226 insertions(+), 24 deletions(-)
Index: mln/data/memcpy_.hh
--- mln/data/memcpy_.hh (revision 3553)
+++ mln/data/memcpy_.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -78,7 +78,7 @@
inline
void memcpy__(Pd& dest, const Ps& src, std::size_t n)
{
- trace::entering("data::impl::memcpy__");
+ // trace::entering("data::impl::memcpy__");
typedef mln_image(Pd) Id;
typedef mln_image(Ps) Is;
@@ -105,7 +105,7 @@
*p_d++ = *p_s++;
}
- trace::exiting("data::impl::memcpy__");
+ // trace::exiting("data::impl::memcpy__");
}
}
@@ -116,7 +116,7 @@
const Generalized_Pixel<Ps>& src_,
std::size_t n)
{
- trace::entering("data::memcpy_");
+ // trace::entering("data::memcpy_");
typedef mln_image(Pd) Id;
metal::is_not_const<Id>::check();
@@ -143,7 +143,7 @@
impl::memcpy__(dest, src, n);
- trace::exiting("data::memcpy_");
+ // trace::exiting("data::memcpy_");
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/linear/gaussian.hh
--- mln/linear/gaussian.hh (revision 3553)
+++ mln/linear/gaussian.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2001, 2002, 2003, 2004, 2008 EPITA Research and
+// Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009 EPITA Research and
// Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
@@ -63,10 +63,16 @@
///
/// \pre output.domain = input.domain
///
- template <class I>
+ template <typename I>
mln_concrete(I)
gaussian(const Image<I>& input, float sigma);
+
+ template <typename I>
+ mln_concrete(I)
+ gaussian(const Image<I>& input, float sigma, int dir);
+
+
# ifndef MLN_INCLUDE_ONLY
namespace impl
@@ -637,7 +643,7 @@
* \pre input.is_valid
* \pre dir < dimension(input)
*/
- template <class I>
+ template <typename I>
inline
mln_concrete(I)
gaussian(const Image<I>& input, float sigma, int dir)
@@ -669,7 +675,7 @@
* \pre input.is_valid
* \pre dir < dimension(input)
*/
- template <class I>
+ template <typename I>
inline
mln_concrete(I)
gaussian_1st_derivative(const Image<I>& input, float sigma, int dir)
@@ -702,7 +708,7 @@
* \pre input.is_valid
* \pre dir < dimension(input)
*/
- template <class I>
+ template <typename I>
inline
mln_concrete(I)
gaussian_2nd_derivative(const Image<I>& input, float sigma, int dir)
@@ -734,7 +740,7 @@
*
* \pre input.is_valid
*/
- template <class I>
+ template <typename I>
inline
mln_concrete(I)
gaussian(const Image<I>& input, float sigma)
@@ -763,7 +769,7 @@
*
* \pre input.is_valid
*/
- template <class I>
+ template <typename I>
inline
mln_concrete(I)
gaussian_1st_derivative(const Image<I>& input, float sigma)
@@ -791,7 +797,7 @@
*
* \pre input.is_valid
*/
- template <class I>
+ template <typename I>
inline
mln_concrete(I)
gaussian_2nd_derivative(const Image<I>& input, float sigma)
Index: mln/accu/transform_line.hh
--- mln/accu/transform_line.hh (revision 3553)
+++ mln/accu/transform_line.hh (working copy)
@@ -66,8 +66,10 @@
# ifndef MLN_INCLUDE_ONLY
+
// Tests.
+
namespace internal
{
@@ -89,6 +91,10 @@
} // end of namespace mln::accu::internal
+
+ // Implementations.
+
+
namespace impl
{
@@ -188,10 +194,150 @@
} // end of namespace mln::accu::impl::generic
+
+
+ template <typename A, typename I>
+ inline
+ mln_ch_value(I, mln_result(A))
+ transform_line_fastest(const Accumulator<A>& a_,
+ const Image<I>& input_,
+ unsigned length, unsigned dir)
+ {
+ trace::entering("accu::impl::transform_line_fastest");
+
+ const I& input = exact(input_);
+ A a = exact(a_);
+
+ internal::transform_line_tests(a, input);
+
+ mln_ch_value(I, mln_result(A)) output;
+ initialize(output, input);
+
+ typedef mln_psite(I) P;
+
+ mln_delta(P) dp(literal::zero);
+ dp[dir] = 1;
+ int step = input.delta_index(dp);
+
+ P pmin = input.domain().pmin(),
+ pmax = input.domain().pmax();
+ const def::coord
+ pmax_dir = pmax[dir],
+ pmin_dir = pmin[dir];
+
+ P p = pmin; // Starting point.
+ def::coord& p_dir = p[dir];
+
+ do
+ {
+ unsigned o_qu, o_qt;
+ unsigned o_p = input.index_of_point(p);
+
+ // Start the line.
+ // ----------------
+
+ a.take_as_init(input.element(o_p));
+ o_qu = o_p;
+ for (unsigned i = 1; i <= length / 2; ++i)
+ {
+ o_qu -= step;
+ a.take(input.element(o_qu));
+ }
+ o_qt = o_p;
+ for (unsigned i = 1; i <= length / 2; ++i)
+ {
+ o_qt += step;
+ a.take(input.element(o_qt));
+ }
+ output.element(o_p) = a.to_result();
+
+ // Browse the line.
+ // ----------------
+
+ while (p_dir < pmax_dir)
+ {
+ ++p_dir;
+
+ o_p += step;
+ o_qt += step;
+ o_qu += step;
+
+ a.take(input.element(o_qt));
+ a.untake(input.element(o_qu));
+
+ output.element(o_p) = a.to_result();
+ }
+
+ p_dir = pmin_dir;
+
+ // Go to the next line.
+ // --------------------
+
+ for (int c = P::dim - 1; c >= 0; --c)
+ {
+ if (c == int(dir))
+ continue;
+ if (p[c] != pmax[c])
+ {
+ ++p[c];
+ break;
+ }
+ p[c] = pmin[c];
+ }
+
+ } while (p != pmin);
+
+ trace::exiting("accu::impl::transform_line_fastest");
+ return output;
+ }
+
+
} // end of namespace mln::accu::impl
+
+ // Dispatch.
+
+
+ namespace internal
+ {
+
+ template <typename A, typename I>
+ inline
+ mln_ch_value(I, mln_result(A))
+ transform_line_dispatch(trait::image::speed::any,
+ const Accumulator<A>& a,
+ const Image<I>& input,
+ unsigned length, unsigned dir)
+ {
+ return impl::generic::transform_line(a,
+ input,
+ length, dir);
+ }
+
+// template <typename A, typename I>
+// inline
+// mln_ch_value(I, mln_result(A))
+// transform_line_dispatch(trait::image::speed::fastest,
+// const Accumulator<A>& a,
+// const Image<I>& input,
+// unsigned length, unsigned dir)
+// {
+// return impl::transform_line_fastest(a,
+// input,
+// length, dir);
+// }
+
+
+ } // end of namespace mln::accu::internal
+
+
+
+
+ // Facades.
+
+
template <typename A, typename I>
inline
mln_ch_value(I, mln_result(A))
@@ -205,7 +351,8 @@
extension::adjust(input, length / 2);
mln_ch_value(I, mln_result(A)) output;
- output = impl::generic::transform_line(a, input, length, dir);
+ output = internal::transform_line_dispatch(mln_trait_image_speed(I)(),
+ a, input, length, dir);
trace::exiting("accu::transform_line");
return output;
Index: mln/morpho/rank_filter.hh
--- mln/morpho/rank_filter.hh (revision 3553)
+++ mln/morpho/rank_filter.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -31,11 +31,16 @@
/// \file mln/morpho/rank_filter.hh
///
-/// Morphological rank_filter.
+/// Morphological rank filter.
+///
+/// \todo Rely on the same mechanism as erosion/dilation.
# include <mln/morpho/includes.hh>
+# include <mln/accu/transform_line.hh>
# include <mln/convert/to_p_array.hh>
+
+
namespace mln
{
@@ -51,6 +56,8 @@
# ifndef MLN_INCLUDE_ONLY
+ // Tests.
+
namespace internal
{
@@ -73,6 +80,10 @@
} // end of namespace mln::morpho::internal
+
+ // Implementations.
+
+
namespace impl
{
@@ -119,9 +130,27 @@
template <typename I, typename W>
inline
mln_concrete(I)
+ rank_filter_line(const Image<I>& input, const Window<W>& win,
unsigned k, unsigned dir)
+ {
+ trace::entering("morpho::impl::rank_filter_line");
+
+ internal::rank_filter_tests(input, win, k);
+
+ accu::rank<mln_value(I)> accu(k);
+ extension::adjust_fill(input, geom::delta(win) + 1, accu);
+ mln_concrete(I) output = accu::transform_line(accu, input, exact(win).length(), dir);
+
+ trace::exiting("morpho::impl::rank_filter_line");
+ return output;
+ }
+
+
+ template <typename I, typename W>
+ inline
+ mln_concrete(I)
rank_filter_directional(const Image<I>& input, const Window<W>&
win, unsigned k, unsigned dir)
{
- trace::entering("morpho::impl::generic::rank_filter_directional");
+ trace::entering("morpho::impl::rank_filter_directional");
internal::rank_filter_tests(input, win, k);
@@ -129,13 +158,18 @@
extension::adjust_fill(input, geom::delta(win) + 1, accu);
mln_concrete(I) output = accu::transform_directional(accu, input, win, dir);
- trace::exiting("morpho::impl::generic::rank_filter_directional");
+ trace::exiting("morpho::impl::rank_filter_directional");
return output;
}
+
} // end of namespace mln::morpho::impl
+
+ // Dispatch.
+
+
namespace internal
{
@@ -144,10 +178,22 @@
mln_concrete(I)
rank_filter_dispatch(const Image<I>& input, const win::line<M, i,
C> & win, unsigned k)
{
- return impl::rank_filter_directional(input, win, k, i);
+ return impl::rank_filter_line(input, win, k, i);
}
-
+ template <typename I>
+ inline
+ mln_concrete(I)
+ rank_filter_dispatch(const Image<I>& input, const win::rectangle2d&
win, unsigned k)
+ {
+ if (win.height() <= 3 && win.width() <= 3)
+ return impl::generic::rank_filter(input, win, k);
+ else
+ if (win.height() < win.width())
+ return impl::rank_filter_directional(input, win, k, 1);
+ else
+ return impl::rank_filter_directional(input, win, k, 0);
+ }
template <typename I, typename W>
inline
@@ -163,12 +209,14 @@
// Facades.
+
template <typename I, typename W>
inline
mln_concrete(I)
rank_filter(const Image<I>& input, const Window<W>& win, unsigned
k)
{
trace::entering("morpho::rank_filter");
+
mln_precondition(exact(input).is_valid());
mln_precondition(! exact(win).is_empty());
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 3553)
+++ mln/morpho/includes.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -49,6 +49,7 @@
# include <mln/accu/transform_directional.hh>
# include <mln/accu/transform_diagonal.hh>
+# include <mln/accu/transform_line.hh>
# include <mln/accu/transform_snake.hh>
# include <mln/fun/v2v/saturate.hh>
Index: img/BUG_lean_ascii.pgm.gz
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: img/BUG_lean_ascii.pgm.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream