https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Repair lineary pixel iterator.
* mln/core/pixter2d_b.hh: Adapt pixter2d_b to the new pixel iterator hierachy.
* mln/core/internal/pixel_iterator_base.hh: Fix dead code.
* mln/core/internal/lineary_pixel_iterator_base.hh: New factorization class.
internal/lineary_pixel_iterator_base.hh | 109 ++++++++++++++++++++++++++++++++
internal/pixel_iterator_base.hh | 101 +----------------------------
pixter2d_b.hh | 31 +++++----
3 files changed, 131 insertions(+), 110 deletions(-)
Index: mln/core/pixter2d_b.hh
--- mln/core/pixter2d_b.hh (revision 1023)
+++ 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/pixel_iterator_base.hh>
+# include <mln/core/internal/lineary_pixel_iterator_base.hh>
# include <mln/core/point2d.hh>
# include <iostream>
@@ -49,8 +49,9 @@
template <typename T>
class fwd_pixter2d_b :
- public internal::pixel_iterator_base_< fwd_pixter2d_b<T>, image2d_b<T> >
+ public internal::lineary_pixel_iterator_base_<image2d_b<T>, fwd_pixter2d_b<T> >
{
+ typedef internal::lineary_pixel_iterator_base_<image2d_b<T>, fwd_pixter2d_b<T> > super;
public:
/// Image pixel value type.
typedef mln_value(image2d_b<T>) value;
@@ -59,37 +60,41 @@
*
* \param[in] ima Image to iterate.
*/
- fwd_pixter2d_b(image2d_b<T>& ima);
- /// Move the iterator to the next elements
+ fwd_pixter2d_b(image2d_b<T>& image);
+ /// Move the iterator on the next element.
void next_();
private:
+ /// Size of the image border.
unsigned border_size_;
+ /// Row offset.
unsigned row_offset_;
+ /// End of a row.
value *eor_;
};
#ifndef MLN_INCLUDE_ONLY
template <typename T>
- fwd_pixter2d_b<T>::fwd_pixter2d_b(image2d_b<T>& ima) :
- border_size_(ima.border()),
- row_offset_((ima.domain().pmax()[1] - ima.domain().pmin()[1])
+ fwd_pixter2d_b<T>::fwd_pixter2d_b(image2d_b<T>& image) :
+ super(image),
+ border_size_(image.border()),
+ row_offset_((image.domain().pmax()[1] - image.domain().pmin()[1])
+ 2 * border_size_ + 1)
{
- this->start_ = &ima(ima.domain().pmin());
- this->eor_ = &ima(make::point2d(ima.domain().pmin()[0], ima.domain().pmax()[1])) + 1;
- this->eoi_ = &ima(ima.domain().pmax()) + 1;
+ this->start_ = &image(image.domain().pmin());
+ this->eor_ = &image(make::point2d(image.domain().pmin()[0], image.domain().pmax()[1])) + 1;
+ this->eoi_ = &image(image.domain().pmax()) + 1;
}
template <typename T>
void fwd_pixter2d_b<T>::next_()
{
- ++(this->current_);
+ ++(this->value_ptr_);
- if (this->current_ == this->eor_ && this->current_ != this->eoi_)
+ if (this->value_ptr_ == this->eor_ && this->value_ptr_ != this->eoi_)
{
- this->current_ += 2 * this->border_size_;
+ this->value_ptr_ += 2 * this->border_size_;
this->eor_ += this->row_offset_;
}
}
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh (revision 1023)
+++ mln/core/internal/pixel_iterator_base.hh (working copy)
@@ -93,12 +93,12 @@
protected:
- /// Current pixel / value
- value* value_ptr_;
-
/// Image associated to the iterator
I& image_;
+ /// Current pixel / value
+ value* value_ptr_;
+
// FIXME: Inactivated:
// /// Psite of the pixel
@@ -174,101 +174,8 @@
// return p_;
// }
-
-
-
-
-// FIXME: Dead code
-// #################
-
-
-
-// /*! \brief pixel_iterator_base_ class
-// */
-// template <typename E, typename I>
-// class pixel_iterator_base_ : public Pixel_Iterator<E>
-// {
-// public:
-// /// I pixel value type.
-// typedef mln_value(I) value;
-// /// I pixel rvalue type.
-// typedef mln_value(I)& rvalue;
-// /// I pixel lvalue type
-// typedef mln_value(I) 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 E, typename I>
-// pixel_iterator_base_<E,I>::pixel_iterator_base_()
-// {
-// }
-
-// template <typename E, typename I>
-// void pixel_iterator_base_<E,I>::start()
-// {
-// current_ = start_;
-// }
-
-// template <typename E, typename I>
-// void pixel_iterator_base_<E,I>::next_()
-// {
-// ++current_;
-// }
-
-// template <typename E, typename I>
-// void pixel_iterator_base_<E,I>::invalidate()
-// {
-// current_ = eoi_;
-// }
-
-// template <typename E, typename I>
-// bool pixel_iterator_base_<E,I>::is_valid() const
-// {
-// return (current_ != eoi_);
-// }
-
-// template <typename E, typename I>
-// typename pixel_iterator_base_<E,I>::rvalue
-// pixel_iterator_base_<E,I>::operator*()
-// {
-// return *current_;
-// }
-
-
-// template <typename E, typename I>
-// typename pixel_iterator_base_<E,I>::lvalue
-// pixel_iterator_base_<E,I>::operator*() const
-// {
-// return *current_;
-// }
-
#endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace internal
} // end of namespace mln
Index: mln/core/internal/lineary_pixel_iterator_base.hh
--- mln/core/internal/lineary_pixel_iterator_base.hh (revision 0)
+++ mln/core/internal/lineary_pixel_iterator_base.hh (revision 0)
@@ -0,0 +1,109 @@
+// 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_LINEARY_PIXEL_ITERATOR_BASE_HH
+# define MLN_CORE_INTERNAL_LINEARY_PIXEL_ITERATOR_BASE_HH
+
+/*! \file mln/core/internal/lineary_pixel_iterator_base.hh
+ *
+ * \brief Code factorization for lineary pixel iterator classes.
+ */
+
+# include <mln/core/internal/pixel_iterator_base.hh>
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ /*! \brief lineary_pixel_iterator_base_ class
+ *
+ */
+ template <typename I, typename E>
+ class lineary_pixel_iterator_base_ : public pixel_iterator_base_<I, E>
+ {
+ typedef pixel_iterator_base_<I, E> super;
+ public:
+ /// Image pixel value type.
+ typedef mln_value(I) value;
+
+ /// Go to the beginning of the image.
+ void start();
+ /// Invalidate the iterator.
+ void invalidate();
+ /// Is the iterator referencing a correct position in the image?
+ bool is_valid() const;
+
+
+ protected:
+ /// beginning of the image
+ value* start_;
+ /// end of the image
+ value* eoi_;
+
+ /// Constructor
+ lineary_pixel_iterator_base_(I& image);
+ };
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename E>
+ lineary_pixel_iterator_base_<I, E>::lineary_pixel_iterator_base_(I& image)
+ : super(image)
+ {
+ }
+
+ template <typename I, typename E>
+ void
+ lineary_pixel_iterator_base_<I, E>::start()
+ {
+ this->value_ptr_ = start_;
+ }
+
+ template <typename I, typename E>
+ void
+ lineary_pixel_iterator_base_<I, E>::invalidate()
+ {
+ this->value_ptr_ = eoi_;
+ }
+
+ template <typename I, typename E>
+ bool
+ lineary_pixel_iterator_base_<I, E>::is_valid() const
+ {
+ return (this->value_ptr_ != eoi_);
+ }
+
+#endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_LINEARY_PIXEL_ITERATOR_BASE_HH
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
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
New 2D window types in mln.
* tests/median.cc: Clean up.
* tests/hmedian.cc: New.
* tests/erosion.cc: Clean up.
* tests/rectangle2d.cc: Update.
* mln/core/hline2d.hh: New.
* mln/core/rectangle2d.hh
(half_width_, half_height_): Change to...
(width_, height_): ...these.
Update.
* mln/core/vline2d.hh: New.
* mln/morpho/erosion.hh (erosion_wrt_win): New overload.
* mln/level/was.median.hh: New.
* mln/level/approx: New.
* mln/level/approx/median.hh: New.
* mln/level/median.hh (median_as_procedure): Move into...
* mln/level/was.hmedian.hh: ...this new file.
mln/core/hline2d.hh | 176 ++++++++++++++++++++++++++++++++++++++++++++
mln/core/rectangle2d.hh | 48 ++++++------
mln/core/vline2d.hh | 178 +++++++++++++++++++++++++++++++++++++++++++++
mln/level/approx/median.hh | 90 ++++++++++++++++++++++
mln/level/median.hh | 157 +++++++++++++++++----------------------
mln/level/was.hmedian.hh | 102 +++++++++++++++++++++++++
mln/level/was.median.hh | 136 ++++++++++++++++++++++++++++++++++
mln/morpho/erosion.hh | 31 ++++++-
tests/erosion.cc | 8 +-
tests/hmedian.cc | 64 ++++++++++++++++
tests/median.cc | 15 ++-
tests/rectangle2d.cc | 4 -
12 files changed, 883 insertions(+), 126 deletions(-)
Index: tests/median.cc
--- tests/median.cc (revision 1020)
+++ tests/median.cc (working copy)
@@ -38,21 +38,26 @@
#include <mln/value/int_u.hh>
#include <mln/level/median.hh>
+#include <mln/level/approx/median.hh>
-using namespace mln;
-using namespace mln::value;
int main()
{
- rectangle2d rec(64, 64);
- border::thickness = 66;
+ 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::median(lena, rec, out);
+ level::median(lena, rect, out);
io::save_pgm(out, "out.pgm");
+
+// level::approx::median(lena, rec, out);
+// io::save_pgm(out, "outa.pgm");
}
Index: tests/hmedian.cc
--- tests/hmedian.cc (revision 0)
+++ tests/hmedian.cc (revision 0)
@@ -0,0 +1,64 @@
+// 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/hmedian.cc
+ *
+ * \brief Test on the hline2d version of mln::level::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/median.hh>
+#include <mln/level/compare.hh>
+
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ border::thickness = 0;
+
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/lena.pgm"),
+ out(lena.domain()),
+ ref(lena.domain());
+
+ level::median(lena, rectangle2d(1, 101), ref);
+
+ level::median(lena, hline2d(101), out);
+ io::save_pgm(out, "out.pgm");
+
+ // FIXME: mln_assertion(out = ref);
+}
Index: tests/erosion.cc
--- tests/erosion.cc (revision 1020)
+++ tests/erosion.cc (working copy)
@@ -45,13 +45,13 @@
#include <mln/fun/ops.hh>
-using namespace mln;
-using namespace mln::value;
-
int main()
{
- rectangle2d rec(4, 4);//64, 64);
+ using namespace mln;
+ using value::int_u8;
+
+ rectangle2d rec(21, 21);
border::thickness = 66;
image2d_b<int_u8>
Index: tests/rectangle2d.cc
--- tests/rectangle2d.cc (revision 1020)
+++ tests/rectangle2d.cc (working copy)
@@ -38,12 +38,12 @@
{
using namespace mln;
- const unsigned h = 3, w = 4;
+ const unsigned h = 3, w = 5;
rectangle2d rec(h, w);
mln_assertion(rec.is_centered());
mln_assertion(rec.is_symmetric());
mln_assertion(rec = -rec);
- mln_assertion(rec.nelements() = (2*h+1) * (2*w+1));
+ mln_assertion(rec.nelements() = h * w);
}
Index: mln/core/hline2d.hh
--- mln/core/hline2d.hh (revision 0)
+++ mln/core/hline2d.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_CORE_HLINE2D_HH
+# define MLN_CORE_HLINE2D_HH
+
+/*! \file mln/core/hline2d.hh
+ *
+ * \brief Definition of the mln::hline2d window.
+ */
+
+# include <mln/core/concept/window.hh>
+# include <mln/core/internal/set_of.hh>
+# include <mln/core/dpoint2d.hh>
+# include <mln/core/dpoints_piter.hh>
+
+
+namespace mln
+{
+
+ /*! \brief Horizontal line window defined on the 2D square grid.
+ *
+ * An hline2d is centered and symmetrical; so its height is 1 and
+ * its width (length) is odd.
+ *
+ * For instance: \n
+ * o o x o o \n
+ * is defined with length = 5.
+ */
+ struct hline2d : public Window< hline2d >,
+ public internal::set_of_<dpoint2d>
+ {
+ /// Point associated type.
+ typedef point2d point;
+
+ /// Dpoint associated type.
+ typedef dpoint2d dpoint;
+
+ /*! \brief Piter type to browse a hline such as: "for each row
+ * (increasing), for each column (increasing)."
+ */
+ typedef dpoints_fwd_piter<dpoint2d> fwd_qiter;
+
+ /*! \brief Piter type to browse a hline such as: "for each row
+ * (decreasing), for each column (decreasing)."
+ */
+ typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
+
+ /*! \brief Same as fwd_qiter.
+ */
+ typedef fwd_qiter qiter;
+
+ /*! \brief Constructor.
+ *
+ * \param[in] length Length, thus width, of the horizontal line.
+ *
+ * \pre \p length is odd.
+ */
+ hline2d(unsigned length);
+
+ /*! \brief Test if the window is centered.
+ *
+ * \return True.
+ */
+ bool is_centered() const;
+
+ /*! \brief Test if the window is symmetric.
+ *
+ * \return true.
+ */
+ bool is_symmetric() const;
+
+ /*! \brief Give the hline length, that is, its width.
+ */
+ unsigned length() const;
+
+ /*! \brief Give the maximum coordinate gap between the window
+ * center and a window point.
+ */
+ unsigned delta() const;
+
+ /// Get the symmetrical window.
+ hline2d sym_() const;
+
+ protected:
+ unsigned length_;
+ };
+
+
+ /*! \brief Print an horizontal 2D line window \p win into the output
+ * stream \p ostr.
+ *
+ * \param[in,out] ostr An output stream.
+ * \param[in] win An horizontal 2D line window.
+ *
+ * \return The modified output stream \p ostr.
+ *
+ * \relates mln::hline2d
+ */
+ std::ostream& operator<<(std::ostream& ostr, const hline2d& win);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ hline2d::hline2d(unsigned length)
+ : length_(length)
+ {
+ mln_precondition(length % 2 = 1);
+ const int dcol = length / 2;
+ for (int col = - dcol; col <= dcol; ++col)
+ insert(make::dpoint2d(0, col));
+ }
+
+ bool hline2d::is_centered() const
+ {
+ return true;
+ }
+
+ bool hline2d::is_symmetric() const
+ {
+ return true;
+ }
+
+ unsigned hline2d::length() const
+ {
+ return length_;
+ }
+
+ unsigned hline2d::delta() const
+ {
+ return length_ / 2;
+ }
+
+ hline2d hline2d::sym_() const
+ {
+ return *this;
+ }
+
+ std::ostream& operator<<(std::ostream& ostr, const hline2d& win)
+ {
+ ostr << "[line2d: length=" << win.length() << ']';
+ return ostr;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_CORE_HLINE2D_HH
Index: mln/core/rectangle2d.hh
--- mln/core/rectangle2d.hh (revision 1020)
+++ mln/core/rectangle2d.hh (working copy)
@@ -47,13 +47,11 @@
* A rectangle2d is a 2D window with rectangular shape. It is
* centered and symmetrical.
*
- * For instance:
- * o o o o o
- * o o x o o
- * o o o o o
- * is defined with half_height = 1 and half_width = 2.
- *
- * \todo Consider width instead of half_width (same for height).
+ * For instance: \n
+ * o o o o o \n
+ * o o x o o \n
+ * o o o o o \n
+ * is defined with height = 3 and width = 5.
*/
struct rectangle2d : public Window< rectangle2d >,
public internal::set_of_<dpoint2d>
@@ -80,12 +78,12 @@
/*! \brief Constructor.
*
- * \param[in] half_height sic
- * \param[in] half_width sic
+ * \param[in] height sic
+ * \param[in] width sic
*
- * \pre half_height != 0 and half_width != 0
+ * \pre Height and width are odd.
*/
- rectangle2d(unsigned half_height, unsigned half_width);
+ rectangle2d(unsigned height, unsigned width);
/*! \brief Test if the window is centered.
*
@@ -116,7 +114,7 @@
rectangle2d sym_() const;
protected:
- unsigned half_height_, half_width_;
+ unsigned height_, width_;
};
@@ -136,12 +134,12 @@
# ifndef MLN_INCLUDE_ONLY
- rectangle2d::rectangle2d(unsigned half_height, unsigned half_width)
- : half_height_(half_height),
- half_width_(half_width)
+ rectangle2d::rectangle2d(unsigned height, unsigned width)
+ : height_(height),
+ width_(width)
{
- mln_precondition(half_height != 0 && half_width != 0);
- const int drow = half_height, dcol = half_width;
+ mln_precondition(height % 2 = 1 && width % 2 = 1);
+ const int drow = height / 2, dcol = width / 2;
for (int row = - drow; row <= drow; ++row)
for (int col = - dcol; col <= dcol; ++col)
insert(make::dpoint2d(row, col));
@@ -159,17 +157,17 @@
unsigned rectangle2d::height() const
{
- return 2 * half_height_ + 1;
+ return height_;
}
unsigned rectangle2d::width() const
{
- return 2 * half_width_ + 1;
+ return width_;
}
unsigned rectangle2d::delta() const
{
- return half_width_ > half_height_ ? half_width_ : half_height_;
+ return width_ > height_ ? width_ / 2 : height_ / 2;
}
rectangle2d rectangle2d::sym_() const
@@ -177,10 +175,9 @@
return *this;
}
- std::ostream& operator<<(std::ostream& ostr,
- const rectangle2d& win)
+ std::ostream& operator<<(std::ostream& ostr, const rectangle2d& win)
{
- ostr << "[width=" << win.width() << ", height=" << win.height() << ']';
+ ostr << "[rectangle2d: width=" << win.width() << ", height=" << win.height() << ']';
return ostr;
}
@@ -190,4 +187,9 @@
+// when rectangle2d is involved, one surely also wants:
+# include <mln/core/hline2d.hh>
+# include <mln/core/vline2d.hh>
+
+
#endif // ! MLN_CORE_RECTANGLE2D_HH
Index: mln/core/vline2d.hh
--- mln/core/vline2d.hh (revision 0)
+++ mln/core/vline2d.hh (revision 0)
@@ -0,0 +1,178 @@
+// 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_VLINE2D_HH
+# define MLN_CORE_VLINE2D_HH
+
+/*! \file mln/core/vline2d.hh
+ *
+ * \brief Definition of the mln::vline2d window.
+ */
+
+# include <mln/core/concept/window.hh>
+# include <mln/core/internal/set_of.hh>
+# include <mln/core/dpoint2d.hh>
+# include <mln/core/dpoints_piter.hh>
+
+
+namespace mln
+{
+
+ /*! \brief Vertical line window defined on the 2D square grid.
+ *
+ * An vline2d is centered and symmetrical; so its width is 1 and
+ * its height (length) is odd.
+ *
+ * For instance: \n
+ * o \n
+ * x \n
+ * o \n
+ * is defined with length = 5.
+ */
+ struct vline2d : public Window< vline2d >,
+ public internal::set_of_<dpoint2d>
+ {
+ /// Point associated type.
+ typedef point2d point;
+
+ /// Dpoint associated type.
+ typedef dpoint2d dpoint;
+
+ /*! \brief Piter type to browse a vline such as: "for each row
+ * (increasing), for each column (increasing)."
+ */
+ typedef dpoints_fwd_piter<dpoint2d> fwd_qiter;
+
+ /*! \brief Piter type to browse a vline such as: "for each row
+ * (decreasing), for each column (decreasing)."
+ */
+ typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
+
+ /*! \brief Same as fwd_qiter.
+ */
+ typedef fwd_qiter qiter;
+
+ /*! \brief Constructor.
+ *
+ * \param[in] length Length, thus height, of the vertical line.
+ *
+ * \pre \p length is odd.
+ */
+ vline2d(unsigned length);
+
+ /*! \brief Test if the window is centered.
+ *
+ * \return True.
+ */
+ bool is_centered() const;
+
+ /*! \brief Test if the window is symmetric.
+ *
+ * \return true.
+ */
+ bool is_symmetric() const;
+
+ /*! \brief Give the vline length, that is, its height.
+ */
+ unsigned length() const;
+
+ /*! \brief Give the maximum coordinate gap between the window
+ * center and a window point.
+ */
+ unsigned delta() const;
+
+ /// Get the symmetrical window.
+ vline2d sym_() const;
+
+ protected:
+ unsigned length_;
+ };
+
+
+ /*! \brief Print a vertical 2D line window \p win into the output
+ * stream \p ostr.
+ *
+ * \param[in,out] ostr An output stream.
+ * \param[in] win A vertical 2D line window.
+ *
+ * \return The modified output stream \p ostr.
+ *
+ * \relates mln::vline2d
+ */
+ std::ostream& operator<<(std::ostream& ostr, const vline2d& win);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ vline2d::vline2d(unsigned length)
+ : length_(length)
+ {
+ mln_precondition(length % 2 = 1);
+ const int drow = length / 2;
+ for (int row = - drow; row <= drow; ++row)
+ insert(make::dpoint2d(row, 0));
+ }
+
+ bool vline2d::is_centered() const
+ {
+ return true;
+ }
+
+ bool vline2d::is_symmetric() const
+ {
+ return true;
+ }
+
+ unsigned vline2d::length() const
+ {
+ return length_;
+ }
+
+ unsigned vline2d::delta() const
+ {
+ return length_ / 2;
+ }
+
+ vline2d vline2d::sym_() const
+ {
+ return *this;
+ }
+
+ std::ostream& operator<<(std::ostream& ostr, const vline2d& win)
+ {
+ ostr << "[line2d: length=" << win.length() << ']';
+ return ostr;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_CORE_VLINE2D_HH
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh (revision 1020)
+++ mln/morpho/erosion.hh (working copy)
@@ -106,6 +106,7 @@
// FIXME: stage 3: dispatch w.r.t. fast property
+
// stage 2: dispatch w.r.t. the value kind
template <typename I, typename W, typename O>
@@ -123,19 +124,34 @@
}
+
// stage 1: dispatch w.r.t. the window type
+ // |
+ // V
- template <typename I, typename W, typename O> // general case
+ template <typename I, typename W, typename O>
void erosion_wrt_win(const Image<I>& input, const Window<W>& win, Image<O>& output)
{
erosion_wrt_value(mln_kind(I)(), exact(input), exact(win), output);
+ // |
+ // --> call stage 2: dispatch w.r.t. the value kind
}
-// template <typename I, typename O> // rectangle2d
-// void erosion_wrt_win(const Image<I>& input, const rectangle2d& win, Image<O>& output)
-// {
-// return FIXME;
-// }
+# ifdef MLN_CORE_RECTANGLE2D_HH
+
+ template <typename I, typename O>
+ void erosion_wrt_win(const Image<I>& input, const rectangle2d& win, Image<O>& output)
+ {
+ O tmp(exact(output).domain());
+ morpho::erosion(input, hline2d(win.width()), tmp);
+ morpho::erosion(tmp, vline2d(win.height()), output);
+ }
+
+# endif // MLN_CORE_RECTANGLE2D_HH
+
+ // ^
+ // |
+ // end of stage1 (dispatch w.r.t. the window type)
} // end of namespace mln::morpho::impl
@@ -146,6 +162,9 @@
template <typename I, typename W, typename O>
void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output)
{
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(! exact(win).is_empty());
+
impl::erosion_wrt_win(input, exact(win), output);
if (exact(win).is_centered())
mln_postcondition(output <= input);
Index: mln/level/was.median.hh
--- mln/level/was.median.hh (revision 0)
+++ mln/level/was.median.hh (revision 0)
@@ -0,0 +1,136 @@
+// 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_WAS_MEDIAN_HH
+# define MLN_LEVEL_WAS_MEDIAN_HH
+
+/*! \file mln/level/was.median.hh
+ *
+ * \brief Obsolete routine for the median filter.
+ */
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ namespace impl
+ {
+
+ template <typename I, typename W, typename O>
+ void median_as_procedure(const 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;
+
+ point2d p;
+ mln_qiter(W)
+ q_fp(win_fwd_plus, p), q_fm(win_fwd_minus, p),
+ q_bp(win_bkd_plus, p), q_bm(win_bkd_minus, p),
+ q_top(win_top, p), q_bot(win_bot, p);
+
+ accu::median_on<mln_value(I)> med;
+
+ // initialization
+
+ p = input.domain().pmin() + up;
+ med.init();
+ {
+ mln_qiter(W) q(win, p);
+ for_all(q) if (input.has(q))
+ med.take(input(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(input(q_top));
+ for_all(q_bot) if (input.has(q_bot))
+ med.take(input(q_bot));
+ output(p) = med;
+
+ if (fwd)
+ // browse line fwd
+ while (col < max_col)
+ {
+ ++col;
+ for_all(q_fm) if (input.has(q_fm))
+ med.untake(input(q_fm));
+ for_all(q_fp) if (input.has(q_fp))
+ med.take(input(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(input(q_bm));
+ for_all(q_bp) if (input.has(q_bp))
+ med.take(input(q_bp));
+ output(p) = med;
+ }
+
+ // change browsing
+ fwd = ! fwd;
+ }
+ }
+
+
+ } // end of namespace mln::level::impl
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_WAS_MEDIAN_HH
Index: mln/level/approx/median.hh
--- mln/level/approx/median.hh (revision 0)
+++ mln/level/approx/median.hh (revision 0)
@@ -0,0 +1,90 @@
+// 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_APPROX_MEDIAN_HH
+# define MLN_LEVEL_APPROX_MEDIAN_HH
+
+/*! \file mln/level/median.hh
+ *
+ * \brief Approximates of some median filters of an image.
+ */
+
+# include <mln/level/median.hh>
+# include <mln/core/rectangle2d.hh>
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ namespace approx
+ {
+
+ /*! Compute in \p output an approximate of the median filter of
+ * image \p input by the 2D rectangle \p win.
+ *
+ * \param[in] input The image to be filtered.
+ * \param[in] win The rectangle.
+ * \param[in,out] output The output image.
+ *
+ * The approximation is based on a vertical median ran after
+ * an horizontal median.
+ *
+ * \pre \p input and \p output have to be initialized.
+ */
+ template <typename I, typename O>
+ void median(const Image<I>& input, const rectangle2d& win,
+ Image<O>& output);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename O>
+ void median(const Image<I>& input_, const rectangle2d& win,
+ Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ O& output = exact(output_);
+ mln_assertion(output.domain() = input.domain());
+
+ O tmp(output.domain());
+ level::median(input, hline2d(win.width()), tmp);
+ level::median(tmp, vline2d(win.height()), output);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::level::approx
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_APPROX_MEDIAN_HH
Index: mln/level/median.hh
--- mln/level/median.hh (revision 1020)
+++ mln/level/median.hh (working copy)
@@ -34,9 +34,11 @@
*/
# include <mln/core/concept/image.hh>
+
# include <mln/core/window2d.hh>
-# include <mln/accu/median.hh>
+# include <mln/core/hline2d.hh>
+# include <mln/accu/median.hh>
# include <mln/canvas/sbrowsing.hh>
@@ -66,88 +68,6 @@
namespace impl
{
- template <typename I, typename W, typename O>
- void median_as_procedure(const 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;
-
- point2d p;
- mln_qiter(W)
- q_fp(win_fwd_plus, p), q_fm(win_fwd_minus, p),
- q_bp(win_bkd_plus, p), q_bm(win_bkd_minus, p),
- q_top(win_top, p), q_bot(win_bot, p);
-
- accu::median_on<mln_value(I)> med;
-
- // initialization
-
- p = input.domain().pmin() + up;
- med.init();
- {
- mln_qiter(W) q(win, p);
- for_all(q) if (input.has(q))
- med.take(input(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(input(q_top));
- for_all(q_bot) if (input.has(q_bot))
- med.take(input(q_bot));
- output(p) = med;
-
- if (fwd)
- // browse line fwd
- while (col < max_col)
- {
- ++col;
- for_all(q_fm) if (input.has(q_fm))
- med.untake(input(q_fm));
- for_all(q_fp) if (input.has(q_fp))
- med.take(input(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(input(q_bm));
- for_all(q_bp) if (input.has(q_bp))
- med.take(input(q_bp));
- output(p) = med;
- }
-
- // change browsing
- fwd = ! fwd;
- }
- }
-
template <typename I, typename W, typename O>
struct median_functor
@@ -167,7 +87,7 @@
// ctor
- median_functor(I& input_, const W& win_, O& output_)
+ median_functor(const I& input_, const W& win_, O& output_)
:
// i/o
input(exact(input_)),
@@ -224,15 +144,79 @@
}; // end of median_functor
+
+
template <typename I, typename W, typename O>
- void median(I& input, const W& win, O& output)
+ void median(const I& input, const Window<W>& win, O& output)
{
// FIXME: resize border!
- impl::median_functor<I,W,O> f(input, win, output);
+ impl::median_functor<I,W,O> f(input, exact(win), output);
canvas::sbrowsing(f);
}
+
+
+ template <typename I, typename O>
+ void median(const I& input, const hline2d& win, O& output)
+ {
+ const int
+ max_row = input.max_row(),
+ min_col = input.min_col(),
+ max_col = input.max_col();
+ const unsigned half = win.length() / 2;
+
+ point2d p;
+ int& row = p.row();
+ int& col = p.col();
+
+ accu::median_on<mln_value(I)> med;
+
+ for (row = input.min_row(); row <= max_row; ++row)
+ {
+ int ct, cu;
+
+ // initialization (before first point of the row)
+ med.init();
+ for (ct = min_col; ct < min_col + half; ++ct)
+ med.take(input.at(row, ct));
+
+ // left columns (just take new points)
+ for (col = min_col; col <= min_col + half; ++col, ++ct)
+ {
+ med.take(input.at(row, ct));
+ output(p) = med;
+ }
+
+ // middle columns (both take and untake)
+ cu = min_col;
+ for (; col <= max_col - half; ++cu, ++col, ++ct)
+ {
+ med.take(input.at(row, ct));
+ med.untake(input.at(row, cu));
+ output(p) = med;
+ }
+
+ // right columns (now just untake old points)
+ for (; col <= max_col; ++cu, ++col)
+ {
+ med.untake(input.at(row, cu));
+ output(p) = med;
+ }
+ }
+ }
+
+
+ // FIXME: Use transpose.
+
+// template <typename I, typename O>
+// void median(const I& input, const vline2d& win, O& output)
+// {
+
+// median(, hline2d(win.length()), output);
+// }
+
+
} // end of namespace mln::level::impl
@@ -242,6 +226,7 @@
void median(const Image<I>& input, const Window<W>& win,
Image<O>& output)
{
+ mln_assertion(exact(output).domain() = exact(input).domain());
impl::median(exact(input), exact(win), exact(output));
}
Index: mln/level/was.hmedian.hh
--- mln/level/was.hmedian.hh (revision 0)
+++ mln/level/was.hmedian.hh (revision 0)
@@ -0,0 +1,102 @@
+// 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_WAS_HMEDIAN_HH
+# define MLN_LEVEL_WAS_HMEDIAN_HH
+
+/*! \file mln/level/was.hmedian.hh
+ *
+ * \brief Median filtering of an image.
+ */
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ namespace impl
+ {
+
+ template <typename I, typename O>
+ void hmedian(const I& input, const hline2d& win, O& output)
+ {
+ const int
+ max_row = input.max_row(),
+ min_col = input.min_col(),
+ max_col = input.max_col();
+ const unsigned half = win.length() / 2;
+
+ point2d p;
+ int& row = p.row();
+ int& col = p.col();
+
+ accu::median_on<mln_value(I)> med;
+
+ for (row = input.min_row(); row <= max_row; ++row)
+ {
+ int ct, cu;
+
+ // initialization (before first point of the row)
+ med.init();
+ for (ct = min_col; ct < min_col + half; ++ct)
+ med.take(input.at(row, ct));
+
+ // left columns (just take new points)
+ for (col = min_col; col <= min_col + half; ++col, ++ct)
+ {
+ med.take(input.at(row, ct));
+ output(p) = med;
+ }
+
+ // middle columns (both take and untake)
+ cu = min_col;
+ for (; col <= max_col - half; ++cu, ++col, ++ct)
+ {
+ med.take(input.at(row, ct));
+ med.untake(input.at(row, cu));
+ output(p) = med;
+ }
+
+ // right columns (now just untake old points)
+ for (; col <= max_col; ++cu, ++col)
+ {
+ med.untake(input.at(row, cu));
+ output(p) = med;
+ }
+ }
+ }
+
+ } // end of namespace mln::level::impl
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_WAS_HMEDIAN_HH
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add delta to windows in mln.
* tests/erosion.cc: New.
* mln/arith/minus.hh: New.
* mln/core/point.hh,
* mln/core/dpoint.hh (vec_t, to_vec): New.
* mln/core/rectangle2d.hh,
* mln/core/concept/window.hh,
* mln/core/concept/doc/window.hh,
* mln/core/window.hh (delta): New.
* mln/level/fill.hh: New overload.
* mln/norm: New.
* mln/norm/infty.hh: New.
* mln/accu/min.hh: New.
* mln/accu/sum.hh: New.
* mln/accu/max.hh: New.
* tests/window2d.cc: Use delta.
* tests/box2d.cc: Add assertion.
* tests/dpoint2d.cc: Test to_vec.
* mln/morpho/erosion.hh: Add dispatch.
* mln/accu/mean.hh: Rewrite.
mln/accu/max.hh | 112 +++++++++++++++++++++++++++++++++++++++++
mln/accu/mean.hh | 17 +++---
mln/accu/min.hh | 112 +++++++++++++++++++++++++++++++++++++++++
mln/accu/sum.hh | 112 +++++++++++++++++++++++++++++++++++++++++
mln/arith/minus.hh | 82 ++++++++++++++++++++++++++++++
mln/core/concept/doc/window.hh | 5 +
mln/core/concept/window.hh | 6 +-
mln/core/dpoint.hh | 8 ++
mln/core/point.hh | 7 ++
mln/core/rectangle2d.hh | 10 +++
mln/core/window.hh | 24 ++++++++
mln/level/fill.hh | 24 ++++++++
mln/morpho/erosion.hh | 99 ++++++++++++++++++++++++++++++------
mln/norm/infty.hh | 86 +++++++++++++++++++++++++++++++
tests/box2d.cc | 1
tests/dpoint2d.cc | 3 +
tests/erosion.cc | 78 ++++++++++++++++++++++++++++
tests/window2d.cc | 1
18 files changed, 761 insertions(+), 26 deletions(-)
Index: tests/window2d.cc
--- tests/window2d.cc (revision 1015)
+++ tests/window2d.cc (working copy)
@@ -49,4 +49,5 @@
w.insert(make::dpoint2d( 1, 1));
image2d_b<bool> ima = convert::to_image(w);
debug::println(ima);
+ mln_assertion(w.delta() = 1);
}
Index: tests/erosion.cc
--- tests/erosion.cc (revision 0)
+++ tests/erosion.cc (revision 0)
@@ -0,0 +1,78 @@
+// 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/median.cc
+ *
+ * \brief Test on mln::level::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/fill.hh>
+#include <mln/morpho/erosion.hh>
+
+#include <mln/fun/pw_value.hh>
+#include <mln/fun/val.hh>
+#include <mln/fun/ops.hh>
+
+
+using namespace mln;
+using namespace mln::value;
+
+
+int main()
+{
+ rectangle2d rec(4, 4);//64, 64);
+ border::thickness = 66;
+
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/lena.pgm"),
+ out(lena.domain());
+
+ morpho::erosion(lena, rec, out);
+ io::save_pgm(out, "out.pgm");
+
+ /*
+ {
+ image2d_b<bool> bin(lena.domain()), out(lena.domain());
+ level::fill(bin, pw_value(1) > val(127));
+ morpho::erosion(bin, rec, out);
+
+ image2d_b<int_u8> test(lena.domain());
+ image2d_b<int_u8>::piter p(lena.domain());
+ for_all(p)
+ test(p) = out(p) ? 255 : 0;
+ io::save_pgm(test, "test.pgm");
+ }
+ */
+
+}
Index: tests/box2d.cc
--- tests/box2d.cc (revision 1015)
+++ tests/box2d.cc (working copy)
@@ -39,4 +39,5 @@
using namespace mln;
box2d b = make::box2d(2, 3);
+ mln_assertion(b.nrows() = 2);
}
Index: tests/dpoint2d.cc
--- tests/dpoint2d.cc (revision 1015)
+++ tests/dpoint2d.cc (working copy)
@@ -47,4 +47,7 @@
mln_assertion(dp = q - p);
mln_assertion(q = p + dp);
+
+ const int (&vec)[2] = dp.to_vec();
+ mln_assertion(vec[0] = 3);
}
Index: mln/core/point.hh
--- mln/core/point.hh (revision 1015)
+++ mln/core/point.hh (working copy)
@@ -96,6 +96,13 @@
/// Origin point (all coordinates are 0).
static const point_<n,C> zero;
+
+ /// Type of the array of coordinates.
+ typedef const C (&vec_t)[n];
+
+ /// Hook to coordinates.
+ vec_t to_vec() const { return coord_; }
+
protected:
C coord_[n];
};
Index: mln/core/rectangle2d.hh
--- mln/core/rectangle2d.hh (revision 1015)
+++ mln/core/rectangle2d.hh (working copy)
@@ -107,6 +107,11 @@
*/
unsigned width() const;
+ /*! \brief Give the maximum coordinate gap between the window
+ * center and a window point.
+ */
+ unsigned delta() const;
+
/// Get the symmetrical window.
rectangle2d sym_() const;
@@ -162,6 +167,11 @@
return 2 * half_width_ + 1;
}
+ unsigned rectangle2d::delta() const
+ {
+ return half_width_ > half_height_ ? half_width_ : half_height_;
+ }
+
rectangle2d rectangle2d::sym_() const
{
return *this;
Index: mln/core/dpoint.hh
--- mln/core/dpoint.hh (revision 1015)
+++ mln/core/dpoint.hh (working copy)
@@ -96,6 +96,14 @@
/// Null delta-point (all coordinates are 0).
static const dpoint_<n,C> zero;
+ const C* coords_() const { return coord_; }
+
+ /// Type of the array of coordinates.
+ typedef const C (&vec_t)[n];
+
+ /// Hook to coordinates.
+ vec_t to_vec() const { return coord_; }
+
protected:
C coord_[n];
};
Index: mln/core/concept/window.hh
--- mln/core/concept/window.hh (revision 1015)
+++ mln/core/concept/window.hh (working copy)
@@ -59,6 +59,8 @@
bool is_centered() const;
bool is_symmetric() const;
+ unsigned delta() const;
+
E sym_() const;
*/
@@ -93,8 +95,10 @@
m2 = 0;
bool (E::*m3)() const = & E::is_symmetric;
m3 = 0;
- E (E::*m4)() const = & E::sym_;
+ unsigned (E::*m4)() const = & E::delta;
m4 = 0;
+ E (E::*m_)() const = & E::sym_;
+ m_ = 0;
}
template <typename W>
Index: mln/core/concept/doc/window.hh
--- mln/core/concept/doc/window.hh (revision 1015)
+++ mln/core/concept/doc/window.hh (working copy)
@@ -76,6 +76,11 @@
*/
bool is_symmetric() const;
+ /*! \brief Give the maximum coordinate gap between the window
+ center and a window point.
+ */
+ unsigned delta() const;
+
/*! \brief Give the symmetrical window.
*/
E sym_() const;
Index: mln/core/window.hh
--- mln/core/window.hh (revision 1015)
+++ mln/core/window.hh (working copy)
@@ -41,6 +41,7 @@
# include <mln/convert/to_dpoint.hh>
# include <mln/fun/all.hh>
+# include <mln/norm/infty.hh>
namespace mln
@@ -97,6 +98,11 @@
*/
bool is_symmetric() const;
+ /*! \brief Give the maximum coordinate gap between the window
+ center and a window point.
+ */
+ unsigned delta() const;
+
/// Give the symmetrical window.
window_<D> sym_() const;
@@ -128,6 +134,8 @@
# ifndef MLN_INCLUDE_ONLY
+ // window_<D>
+
template <typename D>
window_<D>::window_()
{
@@ -147,6 +155,20 @@
}
template <typename D>
+ unsigned window_<D>::delta() const
+ {
+ unsigned d = 0;
+ const unsigned n = this->nelements();
+ for (unsigned i = 0; i < n; ++i)
+ {
+ unsigned dd = norm::infty(this->element(i).to_vec());
+ if (dd > d)
+ d = dd;
+ }
+ return d;
+ }
+
+ template <typename D>
window_<D>
window_<D>::sym_() const
{
@@ -157,6 +179,8 @@
return tmp;
}
+ // operators
+
template <typename W>
window_<mln_dpoint(W)> operator+(const Window<W>& win,
const mln_dpoint(W)& dp)
Index: mln/morpho/erosion.hh
--- mln/morpho/erosion.hh (revision 1015)
+++ mln/morpho/erosion.hh (working copy)
@@ -30,8 +30,11 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/window.hh>
-// FIXME: # include <mln/border/assign.hh>
+# include <mln/accu/min.hh>
# include <mln/value/props.hh>
+# include <mln/level/compare.hh>
+# include <mln/level/fill.hh>
+// FIXME: # include <mln/border/assign.hh>
namespace mln
@@ -40,8 +43,8 @@
namespace morpho
{
- template <typename I, typename W>
- I erosion(const Image<I>& input, const Window<W>& win);
+ template <typename I, typename W, typename O>
+ void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output);
# ifndef MLN_INCLUDE_ONLY
@@ -49,41 +52,103 @@
namespace impl
{
- template <typename I, typename W>
- I erosion(const Image<I>& input_, const Window<W>& win_)
+ // on function
+
+ template <typename I, typename W, typename O>
+ void erosion_on_function(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
{
const I& input = exact(input_);
const W& win = exact(win_);
+ O& output = exact(output_);
- typedef mln_value(I) value;
+ accu::min<mln_value(I)> min;
- I output(input.domain());
mln_piter(I) p(input.domain());
mln_qiter(W) q(win, p);
for_all(p)
{
- value v = mln_max(value);
- for_all(q) if (input.owns_(q))
- {
- if (input(q) < v)
- v = input(q);
+ min.init();
+ for_all(q) if (input.has(q))
+ min.take(input(q));
+ output(p) = min;
+ }
}
- output(p) = v;
+
+
+ // on set
+
+ template <typename I, typename W, typename O>
+ void erosion_on_set(const Image<I>& input_, const Window<W>& win_, Image<O>& output_)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ O& output = exact(output_);
+
+ level::fill(output, input);
+
+ mln_piter(I) p(input.domain());
+ mln_qiter(W) q(win, p);
+ for_all(p)
+ if (input(p))
+ for_all(q) if (input.has(q))
+ if (! input(q))
+ {
+ output(p) = false;
+ break;
}
- return output;
}
+
+
// ...
+
+
+ // FIXME: stage 3: dispatch w.r.t. fast property
+
+ // stage 2: dispatch w.r.t. the value kind
+
+ template <typename I, typename W, typename O>
+ void erosion_wrt_value(value::binary_kind, // binary => morphology on sets
+ const Image<I>& input, const Window<W>& win, Image<O>& output)
+ {
+ return impl::erosion_on_set(exact(input), exact(win), output);
+ }
+
+ template <typename K, typename I, typename W, typename O>
+ void erosion_wrt_value(K, // otherwise => morphology on functions
+ const Image<I>& input, const Window<W>& win, Image<O>& output)
+ {
+ return impl::erosion_on_function(exact(input), exact(win), output);
+ }
+
+
+ // stage 1: dispatch w.r.t. the window type
+
+ template <typename I, typename W, typename O> // general case
+ void erosion_wrt_win(const Image<I>& input, const Window<W>& win, Image<O>& output)
+ {
+ erosion_wrt_value(mln_kind(I)(), exact(input), exact(win), output);
+ }
+
+// template <typename I, typename O> // rectangle2d
+// void erosion_wrt_win(const Image<I>& input, const rectangle2d& win, Image<O>& output)
+// {
+// return FIXME;
+// }
+
+
} // end of namespace mln::morpho::impl
// facade
- template <typename I, typename W>
- I erosion(const Image<I>& input, const Window<W>& win)
+ template <typename I, typename W, typename O>
+ void erosion(const Image<I>& input, const Window<W>& win, Image<O>& output)
{
- return impl::erosion(exact(input), exact(win));
+ impl::erosion_wrt_win(input, exact(win), output);
+ if (exact(win).is_centered())
+ mln_postcondition(output <= input);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/level/fill.hh
--- mln/level/fill.hh (revision 1015)
+++ mln/level/fill.hh (working copy)
@@ -34,6 +34,7 @@
*/
# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
namespace mln
@@ -53,6 +54,17 @@
void fill(Image<I>& ima, const mln_value(I)& v);
+ /*! Fill the whole image \p ima with the function \p f.
+ *
+ * \param[in,out] ima The image to be filled.
+ * \param[in] f The function.
+ *
+ * \pre \p ima has to be initialized.
+ */
+ template <typename I, typename F>
+ void fill(Image<I>& ima, const Function_p2v<F>& f);
+
+
/*! Fill the image \p ima by applying the function \p f.
*
* \param[in,out] ima The image to be filled.
@@ -110,6 +122,18 @@
ima(p) = value;
}
+ template <typename I, typename F>
+ void fill(Image<I>& ima_,
+ const Function_p2v<F>& f_)
+ {
+ I& ima = exact(ima_);
+ mln_precondition(ima.has_data());
+ const F& f = exact(f_);
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ ima(p) = f(p);
+ }
+
template <typename I>
void fill(Image<I>& ima_,
mln_value(I) (*f)(const mln_point(I)& p))
Index: mln/arith/minus.hh
--- mln/arith/minus.hh (revision 0)
+++ mln/arith/minus.hh (revision 0)
@@ -0,0 +1,82 @@
+// 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_ARITH_MINUS_HH
+# define MLN_ARITH_MINUS_HH
+
+/*! \file mln/arith/minus.hh
+ *
+ * \brief Point-wise substraction between images.
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace arith
+ {
+
+ /*! Point-wise substraction of images \p lhs and \p rhs.
+ *
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain = \p lhs.domain = \p rhs.domain
+ */
+ template <typename L, typename R, typename O>
+ void minus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L, typename R, typename O>
+ void minus(const Image<L>& lhs_, const Image<R>& rhs_, Image<O>& output_)
+ {
+ const L& lhs = exact(lhs_);
+ const R& rhs = exact(rhs_);
+ O& output = exact(output_);
+
+ mln_precondition(rhs.domain() = lhs.domain());
+ mln_precondition(output.domain() = lhs.domain());
+
+ mln_piter(I) p(output.domain());
+ for_all(p)
+ output(p) = lhs(p) - rhs(p);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::arith
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ARITH_MINUS_HH
Index: mln/norm/infty.hh
--- mln/norm/infty.hh (revision 0)
+++ mln/norm/infty.hh (revision 0)
@@ -0,0 +1,86 @@
+// 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_NORM_INFTY_HH
+# define MLN_NORM_INFTY_HH
+
+/*! \file mln/norm/infty.hh
+ *
+ * \brief Define some infinity-norm related routines.
+ */
+
+# include <cmath>
+
+
+namespace mln
+{
+
+ namespace norm
+ {
+
+ /// Infinity-norm of a vector \p vec.
+ template <unsigned n, typename C>
+ C infty(const C (&vec)[n]);
+
+ /// Infinity-norm distance between vectors \p v1 and \p v2.
+ template <unsigned n, typename C>
+ C infty_distance(const C (&v1)[n], const C (&v2)[n]);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n, typename C>
+ C infty(const C (&vec)[n])
+ {
+ C c = 0;
+ for (unsigned i = 0; i < n; ++i)
+ if (std::abs(vec[i]) > c)
+ c = std::abs(vec[i]);
+ return c;
+ }
+
+ template <unsigned n, typename C>
+ C infty_distance(const C (&v1)[n], const C (&v2)[n])
+ {
+ C d = 0;
+ for (unsigned i = 0; i < n; ++i)
+ {
+ C dd = v2[i] > v1[i] ? v2[i] - v1[i] : v1[i] - v2[i];
+ if (dd > d)
+ d = dd;
+ }
+ return d;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::norm
+
+} // end of namespace mln
+
+
+#endif // ! MLN_NORM_INFTY_HH
Index: mln/accu/min.hh
--- mln/accu/min.hh (revision 0)
+++ mln/accu/min.hh (revision 0)
@@ -0,0 +1,112 @@
+// 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_ACCU_MIN_HH
+# define MLN_ACCU_MIN_HH
+
+/*! \file mln/accu/min.hh
+ *
+ * \brief Define an accumulator that computes a min.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/value/props.hh>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+
+ /*! Generic min accumulator class.
+ *
+ * The parameter \c V is the type of values.
+ */
+ template <typename V>
+ struct min : public Accumulator< min<V> >
+ {
+ typedef V value;
+
+ min();
+ void take(const value& v);
+ void init();
+
+ operator V() const;
+ V to_value() const;
+
+ protected:
+
+ V v_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ min<V>::min()
+ {
+ init();
+ }
+
+ template <typename V>
+ void min<V>::take(const value& v)
+ {
+ if (v < v_)
+ v_ = v;
+ }
+
+ template <typename V>
+ void
+ min<V>::init()
+ {
+ v_ = mln_max(V);
+ }
+
+ template <typename V>
+ min<V>::operator V() const
+ {
+ return v_;
+ }
+
+ template <typename V>
+ V
+ min<V>::to_value() const
+ {
+ return v_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_MIN_HH
Index: mln/accu/sum.hh
--- mln/accu/sum.hh (revision 0)
+++ mln/accu/sum.hh (revision 0)
@@ -0,0 +1,112 @@
+// 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_ACCU_SUM_HH
+# define MLN_ACCU_SUM_HH
+
+/*! \file mln/accu/sum.hh
+ *
+ * \brief Define an accumulator that computes a sum.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+
+ /*! Generic sum accumulator class.
+ *
+ * Parameter \c V is the type of values that we sum. Parameter \c
+ * S is the type to store the sum value; the default type of
+ * \c S is \c V.
+ */
+ template <typename V, typename S = V>
+ struct sum : public Accumulator< sum<V,S> >
+ {
+ typedef V value;
+
+ sum();
+ void take(const value& v);
+ void init();
+
+ operator S() const;
+ S to_value() const;
+
+ protected:
+
+ S sum_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V, typename S>
+ sum<V,S>::sum()
+ {
+ init();
+ }
+
+ template <typename V, typename S>
+ void sum<V,S>::take(const value& v)
+ {
+ sum_ += v;
+ }
+
+ template <typename V, typename S>
+ void
+ sum<V,S>::init()
+ {
+ sum_ = 0;
+ }
+
+ template <typename V, typename S>
+ sum<V,S>::operator S() const
+ {
+ return to_value;
+ }
+
+ template <typename V, typename S>
+ S
+ sum<V,S>::to_value() const
+ {
+ return sum_ / count_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_SUM_HH
Index: mln/accu/max.hh
--- mln/accu/max.hh (revision 0)
+++ mln/accu/max.hh (revision 0)
@@ -0,0 +1,112 @@
+// 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_ACCU_MAX_HH
+# define MLN_ACCU_MAX_HH
+
+/*! \file mln/accu/max.hh
+ *
+ * \brief Define an accumulator that computes a max.
+ */
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/value/props.hh>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+
+ /*! Generic max accumulator class.
+ *
+ * The parameter \c V is the type of values.
+ */
+ template <typename V>
+ struct max : public Accumulator< max<V> >
+ {
+ typedef V value;
+
+ max();
+ void take(const value& v);
+ void init();
+
+ operator V() const;
+ V to_value() const;
+
+ protected:
+
+ V v_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ max<V>::max()
+ {
+ init();
+ }
+
+ template <typename V>
+ void max<V>::take(const value& v)
+ {
+ if (v > v_)
+ v_ = v;
+ }
+
+ template <typename V>
+ void
+ max<V>::init()
+ {
+ v_ = mln_min(V);
+ }
+
+ template <typename V>
+ max<V>::operator V() const
+ {
+ return v_;
+ }
+
+ template <typename V>
+ V
+ max<V>::to_value() const
+ {
+ return v_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_MAX_HH
Index: mln/accu/mean.hh
--- mln/accu/mean.hh (revision 1015)
+++ mln/accu/mean.hh (working copy)
@@ -33,7 +33,8 @@
* \brief Define an accumulator that computes a mean.
*/
-# include <mln/core/concept/accumulator.hh>
+# include <mln/accu/counter.hh>
+# include <mln/accu/sum.hh>
namespace mln
@@ -64,8 +65,8 @@
protected:
- std::size_t count_;
- S sum_;
+ accu::counter<V> count_;
+ accu::sum<V,S> sum_;
};
@@ -81,16 +82,16 @@
template <typename V, typename S, typename M>
void mean<V,S,M>::take(const value& v)
{
- ++count_;
- sum_ += v;
+ count_.take(v);
+ sum_.take(v);
}
template <typename V, typename S, typename M>
void
mean<V,S,M>::init()
{
- count_ = 0;
- sum_ = 0;
+ count_.init();
+ sum_.init();
}
template <typename V, typename S, typename M>
@@ -103,7 +104,7 @@
M
mean<V,S,M>::to_value() const
{
- return sum_ / count_;
+ return sum_.to_value() / count_.to_value();
}
# endif // ! MLN_INCLUDE_ONLY