https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Change fast_iterator hierarchy.
* tests/fast_median.cc: New test.
* tests/pixter_point2d.cc: Update test.
* mln/core/pixel.hh: Add typedefs in the class pixel_.
* mln/core/macros.hh: Add new macros.
* mln/core/concept/pixel_iterator.hh: New, rename Fast_Iterator concep as Pixel
Iterator.
* mln/core/concept/fast_iterator.hh: Remove.
* mln/core/concept/genpixel.hh: Constructor fixed.
* mln/core/pixter2d_b.hh: Broken!.
* mln/core/image2d_b.hh: Add new method point_at_offset.
* mln/core/dpoints_pixter.hh: Adapt dpoint_pixter to the new hierarchy.
* mln/core/internal/pixel_iterator_base.hh: New, rename fast_iterator_base_ as
pixel_iterator_base_.
* mln/core/internal/fast_iterator_base.hh: Remove.
* mln/level/fast_median.hh: New median using qixter.
mln/core/concept/genpixel.hh | 33 ++--
mln/core/concept/pixel_iterator.hh | 81 ++++++++++
mln/core/dpoints_pixter.hh | 35 +---
mln/core/image2d_b.hh | 22 ++
mln/core/internal/pixel_iterator_base.hh | 246 +++++++++++++++++++++++++++++++
mln/core/macros.hh | 9 +
mln/core/pixel.hh | 2
mln/core/pixter2d_b.hh | 5
mln/level/fast_median.hh | 176 ++++++++++++++++++++++
tests/fast_median.cc | 63 +++++++
tests/pixter_point2d.cc | 4
11 files changed, 630 insertions(+), 46 deletions(-)
Index: tests/fast_median.cc
--- tests/fast_median.cc (revision 0)
+++ tests/fast_median.cc (revision 0)
@@ -0,0 +1,63 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/fast_median.cc
+ *
+ * \brief Test on mln::level::fast_median.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/rectangle2d.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/value/int_u.hh>
+#include <mln/level/fast_median.hh>
+#include <mln/level/approx/median.hh>
+
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ rectangle2d rect(51, 51);
+ border::thickness = 52;
+
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/lena.pgm"),
+ out(lena.domain());
+
+ level::fast_median(lena, rect, out);
+ io::save_pgm(out, "out.pgm");
+
+// level::approx::median(lena, rec, out);
+// io::save_pgm(out, "outa.pgm");
+}
Index: tests/pixter_point2d.cc
--- tests/pixter_point2d.cc (revision 1021)
+++ tests/pixter_point2d.cc (working copy)
@@ -27,7 +27,6 @@
#include <cassert>
#include <mln/core/image2d_b.hh>
-#include <iostream>
int
@@ -35,7 +34,7 @@
{
using namespace mln;
- image2d_b<int> ima(2, 2);
+ image2d_b<int> ima(20, 20);
image2d_b<int>::piter p(ima.domain());
image2d_b<int>::pixter f(ima);
@@ -49,7 +48,6 @@
for_all(f)
{
- std::cout << *f << std::endl;
assert(*f == i ++);
*f = 5;
}
Index: mln/core/pixel.hh
--- mln/core/pixel.hh (revision 1021)
+++ mln/core/pixel.hh (working copy)
@@ -64,6 +64,8 @@
{
typedef mln_psite(I) psite;
typedef mln_value(I) value;
+ typedef mln_rvalue(I) rvalue;
+ typedef I ima;
pixel(I& ima);
pixel(I& ima, const psite& p);
Index: mln/core/macros.hh
--- mln/core/macros.hh (revision 1021)
+++ mln/core/macros.hh (working copy)
@@ -96,6 +96,15 @@
/// Shortcut to access the fwd_viter type associated to T.
# define mln_fwd_viter(T) typename T::fwd_viter
+// i
+
+/// Shortcut to access the fwd_viter type associated to T.
+# define mln_image(T) typename T::image
+
+/// Shortcut to access the fwd_viter type associated to T.
+# define mln_ima(T) typename T::ima
+
+
// l
Index: mln/core/concept/pixel_iterator.hh
--- mln/core/concept/pixel_iterator.hh (revision 0)
+++ mln/core/concept/pixel_iterator.hh (revision 0)
@@ -0,0 +1,81 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
+# define MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
+
+/*! \file mln/core/concept/fast_iterator.hh
+ * \brief Definition of the concept of mln::Pixel_Iterator.
+ */
+
+# include <mln/core/concept/iterator.hh>
+# include <mln/core/concept/genpixel.hh>
+
+namespace mln
+{
+
+ /*! \brief Pixel Iterator concept class.
+ *
+ * \see FIXME
+ */
+ template <typename E>
+ struct Pixel_Iterator :
+ public Iterator<E>,
+ public GenPixel<E>
+ {
+ /*
+ typedef rvalue
+ typedef lvalue
+ lvalue operator* ();
+ rvalue operator* () const;
+ */
+ protected:
+ Pixel_Iterator();
+ };
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <typename E>
+ Pixel_Iterator<E>::Pixel_Iterator()
+ {
+ typedef mln_value(E) value;
+ typedef mln_rvalue(E) rvalue;
+ typedef mln_lvalue(E) lvalue;
+
+ lvalue (E::*m1)() = & E::operator*;
+ m1 = 0;
+ rvalue (E::*m2)() const = & E::operator*;
+ m2 = 0;
+ }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_CONCEPT_PIXEL_ITERATOR_HH
Index: mln/core/concept/genpixel.hh
--- mln/core/concept/genpixel.hh (revision 1021)
+++ mln/core/concept/genpixel.hh (working copy)
@@ -60,12 +60,13 @@
{
/*
- typedef image; // not const!
- typedef psite;
+ typedef ima; // not const!
+ typede psite;
typedef rvalue;
+ typedef value;
- const image& image() const;
- const psite& psite() const; // FIXME ou cpy
+ const ima& image() const;
+ const psite& site() const; // FIXME ou cpy
rvalue operator*() const;
@@ -98,17 +99,19 @@
template <typename E>
GenPixel<E>::GenPixel()
{
- // FIXME
-// int dim = E::dim;
-// mln_invariant(dim > 0);
-// dim = 0;
-// typedef mln_point(E) point;
-// typedef mln_dpoint(E) dpoint;
-// typedef mln_coord(E) coord;
-// const point* (E::*m1)() const = & E::pointer;
-// m1 = 0;
-// coord (E::*m2)(unsigned i) const = & E::operator[];
-// m2 = 0;
+ typedef mln_value(E) value;
+ typedef mln_rvalue(E) rvalue;
+ typedef mln_ima(E) ima;
+ typedef mln_psite(E) psite;
+
+ const ima& (E::*m1)() const = & E::image;
+ m1 = 0;
+ const psite& (E::*m2)() const = & E::site;
+ m2 = 0;
+ rvalue (E::*m3)() const = & E::operator*;
+ m3 = 0;
+ const value* (E::*m4)() const = & E::address;
+ m4 = 0;
}
Index: mln/core/pixter2d_b.hh
--- mln/core/pixter2d_b.hh (revision 1021)
+++ mln/core/pixter2d_b.hh (working copy)
@@ -28,7 +28,7 @@
#ifndef MLN_CORE_PIXTER2D_B_HH
# define MLN_CORE_PIXTER2D_B_HH
-# include <mln/core/internal/fast_iterator_base.hh>
+# include <mln/core/internal/pixel_iterator_base.hh>
# include <mln/core/point2d.hh>
# include <iostream>
@@ -39,7 +39,6 @@
* \brief Pixel iterator class on a image 2d with border.
*/
-# include <mln/core/concept/fast_iterator.hh>
namespace mln
@@ -50,7 +49,7 @@
template <typename T>
class fwd_pixter2d_b :
- public internal::fast_iterator_base_< fwd_pixter2d_b<T>, image2d_b<T>
>
+ public internal::pixel_iterator_base_< fwd_pixter2d_b<T>, image2d_b<T>
>
{
public:
/// Image pixel value type.
Index: mln/core/image2d_b.hh
--- mln/core/image2d_b.hh (revision 1021)
+++ mln/core/image2d_b.hh (working copy)
@@ -151,9 +151,17 @@
T& at(int row, int col);
+ /// Fast Image method
+
/// Return the offset corresponding to the dpoint \p dp.
int offset(const dpoint2d& dp);
+ /// Return the offset corresponding to the dpoint \p p.
+ int offset(const point2d& p);
+
+ /// Return the point corresponding to the offset \p offset.
+ point2d point_at_offset(int offset);
+
private:
@@ -387,6 +395,20 @@
return dp[0] * vb_.len(1) + dp[1];
}
+ template <typename T>
+ int
+ image2d_b<T>::offset(const point2d& p)
+ {
+ return p[0] * vb_.len(1) + p[1];
+ }
+
+ template <typename T>
+ point2d
+ image2d_b<T>::point_at_offset(int offset)
+ {
+ return point2d(offset / (vb_.len(1) + 1), offset % (vb_.len(1) + 1));
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/dpoints_pixter.hh
--- mln/core/dpoints_pixter.hh (revision 1021)
+++ mln/core/dpoints_pixter.hh (working copy)
@@ -30,7 +30,7 @@
# include <cassert>
# include <vector>
-# include <mln/core/concept/fast_iterator.hh>
+# include <mln/core/internal/pixel_iterator_base.hh>
namespace mln
@@ -41,8 +41,9 @@
* The parameter \c I is the image type.
*/
template <typename I>
- class dpoints_pixter : public Fast_Iterator< dpoints_pixter<I> >
+ class dpoints_pixter : public internal::pixel_iterator_base_< I,
dpoints_pixter<I> >
{
+ typedef typename internal::pixel_iterator_base_< I, dpoints_pixter<I> >
super;
public:
/// Image pixel value
typedef mln_value(I) value;
@@ -51,14 +52,14 @@
/// Image pixel lvalue
typedef mln_lvalue(I) lvalue;
- /*! \brief Constructo.
+ /*! \brief Constructor.
*
* \param[in] dps Object that can provide an array of delta-points.
* \param[in] p_ref Center point to iterate around.
* \param[in] ima Image to iterate.
*/
template <typename Dps>
- dpoints_pixter(const Dps& dps, const typename I::point& p_ref,I& ima);
+ dpoints_pixter(const Dps& dps, const typename I::psite& p_ref,I& ima);
/// Set the iterator at the start.
void start();
@@ -69,10 +70,6 @@
/// Is the iterator valid?
bool is_valid() const;
- /// Get the iterator value
- rvalue operator* ();
- lvalue operator* () const;
-
private:
/// offset of each dpoints
std::vector<int> offset_;
@@ -87,8 +84,9 @@
template <typename I>
template <typename Dps>
- dpoints_pixter<I>::dpoints_pixter(const Dps& dps, const typename
I::point& ref, I& ima)
+ dpoints_pixter<I>::dpoints_pixter(const Dps& dps, const typename
I::psite& ref, I& ima) : super(ima)
{
+ this->p_ = ref;
pixref_ = &ima(ref);
for (typename std::vector<typename I::dpoint>::const_iterator it =
dps.vec().begin();
it != dps.vec().end();
@@ -100,13 +98,16 @@
template <typename I>
void dpoints_pixter<I>::start()
{
+ pixref_ = &ima_(this->p_);
i_ = offset_.begin();
+ this->current_value_ = pixref_ + *i_;
}
template <typename I>
void dpoints_pixter<I>::next_()
{
++i_;
+ this->current_value_ = pixref_ + *i_;
}
template <typename I>
@@ -121,22 +122,6 @@
i_ = offset_.end();
}
- template <typename I>
- typename dpoints_pixter<I>::rvalue
- dpoints_pixter<I>::operator* ()
- {
- assert(this->is_valid());
- return *(pixref_ + *i_);
- }
-
- template <typename I>
- typename dpoints_pixter<I>::lvalue
- dpoints_pixter<I>::operator* () const
- {
- assert(this->is_valid());
- return *(pixref_ + *i_);
- }
-
#endif // ! MLN_INCLUDE_ONLY
}
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh (revision 0)
+++ mln/core/internal/pixel_iterator_base.hh (revision 0)
@@ -0,0 +1,246 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
+# define MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
+
+/*! \file mln/core/internal/fast_iterator_base.hh
+ *
+ * \brief Base class for Fast_Iterator concept implementation.
+ * Usefull for code factorisation
+ */
+
+# include <mln/core/concept/pixel_iterator.hh>
+
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ /*! \brief pixel_iterator_base_ class
+ */
+ template <typename Image, typename Exact>
+ class pixel_iterator_base_ : public Pixel_Iterator<Exact>
+ {
+ public:
+ /// Image type.
+ typedef Image ima;
+ /// Image value type.
+ typedef mln_value(Image) value;
+ /// Image lvalue type.
+ typedef mln_lvalue(Image) lvalue;
+ /// Image rvalue type.
+ typedef mln_rvalue(Image) rvalue;
+ /// Image psite type.
+ typedef mln_psite(Image) psite;
+
+ /// Get the image associated to the current pixel iterator.
+ const ima& image() const;
+ /// pixel iterator value.
+ lvalue operator* ();
+ /// Get the pixel iterator value.
+ rvalue operator* () const;
+ /// Address of the current iterator value/pixel.
+ const value* address() const;
+ /// Address of the current iterator value/pixel.
+ value* address();
+
+ /// psite associated to the iterator.
+ const psite& site() const;
+ /// psite associated to the iterator.
+ psite& site();
+
+ protected:
+ /// Current pixel value
+ value* current_value_;
+ /// Image associated to the iterator
+ ima& ima_;
+ /// Psite of the pixel
+ psite p_;
+
+ pixel_iterator_base_(ima& source);
+ };
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <typename Image, typename Exact>
+ pixel_iterator_base_<Image, Exact>::pixel_iterator_base_(ima& source) :
+ ima_(source)
+ {
+ }
+
+ template <typename Image, typename Exact>
+ const typename pixel_iterator_base_<Image, Exact>::ima&
+ pixel_iterator_base_<Image, Exact>::image() const
+ {
+ return ima_;
+ }
+
+ template <typename Image, typename Exact>
+ typename pixel_iterator_base_<Image, Exact>::lvalue
+ pixel_iterator_base_<Image, Exact>::operator* ()
+ {
+ assert(exact(this)->is_valid());
+ return *current_value_;
+ }
+
+ template <typename Image, typename Exact>
+ typename pixel_iterator_base_<Image, Exact>::rvalue
+ pixel_iterator_base_<Image, Exact>::operator* () const
+ {
+ assert(exact(this)->is_valid());
+ return *current_value_;
+ }
+
+ template <typename Image, typename Exact>
+ const typename pixel_iterator_base_<Image, Exact>::value*
+ pixel_iterator_base_<Image, Exact>::address() const
+ {
+ assert(exact(this)->is_valid());
+ return current_value_;
+ }
+
+ template <typename Image, typename Exact>
+ typename pixel_iterator_base_<Image, Exact>::value*
+ pixel_iterator_base_<Image, Exact>::address()
+ {
+ assert(exact(this)->is_valid());
+ return current_value_;
+ }
+
+ template <typename Image, typename Exact>
+ const typename pixel_iterator_base_<Image, Exact>::psite&
+ pixel_iterator_base_<Image, Exact>::site() const
+ {
+ //FIXME: update psite
+ return p_;
+ }
+
+ template <typename Image, typename Exact>
+ typename pixel_iterator_base_<Image, Exact>::psite&
+ pixel_iterator_base_<Image, Exact>::site()
+ {
+ //FIXME: update psite
+ return p_;
+ }
+
+
+// FIXME: Dead code
+// /*! \brief pixel_iterator_base_ class
+// */
+// template <typename Exact, typename Image>
+// class pixel_iterator_base_ : public Pixel_Iterator<Exact>
+// {
+// public:
+// /// Image pixel value type.
+// typedef mln_value(Image) value;
+// /// Image pixel rvalue type.
+// typedef mln_value(Image)& rvalue;
+// /// Image pixel lvalue type
+// typedef mln_value(Image) lvalue;
+
+// // Go to the beginning of the image.
+// void start();
+// // Go on the next element.
+// void next_();
+// // Invalidate the iterator.
+// void invalidate();
+// // Is the iterator referencing a correct position in the image?
+// bool is_valid() const;
+
+
+// // Return the current pixel.
+// rvalue operator* ();
+// lvalue operator* () const;
+
+// protected:
+// // beginning of the image
+// value* start_;
+// // end of the image
+// value* eoi_;
+// // current position in the image
+// value* current_;
+// // End of Factoriasable
+
+// pixel_iterator_base_();
+// };
+
+// #ifndef MLN_INCLUDE_ONLY
+
+// template <typename Exact, typename Image>
+// pixel_iterator_base_<Exact, Image>::pixel_iterator_base_()
+// {
+// }
+
+// template <typename Exact, typename Image>
+// void pixel_iterator_base_<Exact, Image>::start()
+// {
+// current_ = start_;
+// }
+
+// template <typename Exact, typename Image>
+// void pixel_iterator_base_<Exact, Image>::next_()
+// {
+// ++current_;
+// }
+
+// template <typename Exact, typename Image>
+// void pixel_iterator_base_<Exact, Image>::invalidate()
+// {
+// current_ = eoi_;
+// }
+
+// template <typename Exact, typename Image>
+// bool pixel_iterator_base_<Exact, Image>::is_valid() const
+// {
+// return (current_ != eoi_);
+// }
+
+// template <typename Exact, typename Image>
+// typename pixel_iterator_base_<Exact, Image>::rvalue
+// pixel_iterator_base_<Exact, Image>::operator*()
+// {
+// return *current_;
+// }
+
+
+// template <typename Exact, typename Image>
+// typename pixel_iterator_base_<Exact, Image>::lvalue
+// pixel_iterator_base_<Exact, Image>::operator*() const
+// {
+// return *current_;
+// }
+
+#endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
Index: mln/level/fast_median.hh
--- mln/level/fast_median.hh (revision 0)
+++ mln/level/fast_median.hh (revision 0)
@@ -0,0 +1,176 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_LEVEL_FAST_MEDIAN_HH
+# define MLN_LEVEL_FAST_MEDIAN_HH
+
+/*! \file mln/level/median.hh
+ *
+ * \brief Fast Median filtering of an image.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/window2d.hh>
+# include <mln/accu/median.hh>
+# include <ostream>
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ /*! Compute in \p output the median filter of image \p input by
+ * the window \p win.
+ *
+ * \param[in] input The image to be filtered.
+ * \param[in] win The window.
+ * \param[in,out] output The output image.
+ *
+ * \pre \p input and \p output have to be initialized.
+ */
+ template <typename I, typename W, typename O>
+ void fast_median(Image<I>& input, const Window<W>& win,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace impl
+ {
+
+ template <typename I, typename W, typename O>
+ void fast_median(I& input,
+ const W& win,
+ O& output)
+ {
+ mln_precondition(input.has_data());
+ mln_precondition(output.has_data());
+
+ int
+ min_row = input.min_row(), max_row = input.max_row(),
+ min_col = input.min_col(), max_col = input.max_col();
+
+ window2d
+ win_fwd_plus = win - (win + left),
+ win_fwd_minus = (win + left) - win,
+ win_bkd_plus = win - (win + right),
+ win_bkd_minus = (win + right) - win,
+ win_bot = win - (win + up),
+ win_top = (win + up) - win;
+
+
+
+ //Fixme bug
+ point2d p;
+
+ accu::median_on<mln_value(I)> med;
+
+ // initialization
+
+ p = input.domain().pmin() + up;
+ mln_qixter(I)
+ q_fp(win_fwd_plus, p, input), q_fm(win_fwd_minus, p, input),
+ q_bp(win_bkd_plus, p, input), q_bm(win_bkd_minus, p, input),
+ q_top(win_top, p, input), q_bot(win_bot, p, input);
+
+ med.init();
+ {
+ mln_qixter(I) q(win, p, input);
+ for_all(q) //if (input.has(q))
+ med.take(*q);
+ }
+
+ int& row = p.row();
+ int& col = p.col();
+ bool fwd = true;
+
+ mln_assertion(p.col() == min_col);
+ mln_assertion(p.row() == min_row - 1);
+
+ for (row = min_row; row <= max_row; ++row)
+ {
+
+ // "go down"
+ for_all(q_top) //if (input.has(q_top))
+ med.untake(*q_top);
+
+ for_all(q_bot) //if (input.has(q_bot))
+ med.take(*q_bot);
+
+ output(p) = med;
+
+ if (fwd)
+ // browse line fwd
+ while (col < max_col)
+ {
+ std::cout << "debug: psite" << q_fm.psite() <<
"\n";
+ ++col;
+ for_all(q_fm) //if (input.has(q_fm))
+ med.untake(*q_fm);
+ for_all(q_fp) //if (input.has(q_fp))
+ med.take(*q_fp);
+ output(p) = med;
+ }
+ else
+ // browse line bkd
+ while (col > min_col)
+ {
+ --col;
+ for_all(q_bm) //if (input.has(q_bm))
+ med.untake(*q_bm);
+ for_all(q_bp) //if (input.has(q_bp))
+ med.take(*q_bp);
+ output(p) = med;
+ }
+ // change browsing
+ fwd = ! fwd;
+ }
+ }
+
+ } // end of namespace mln::level::impl
+
+
+ // facade
+
+ template <typename I, typename W, typename O>
+ void fast_median(Image<I>& input, const Window<W>& win,
+ Image<O>& output)
+ {
+ impl::fast_median(exact(input), exact(win), exact(output));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_FAST_MEDIAN_HH