https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix pixel iterators on sets of dpoints.
* tests/fast_median.cc (test): New.
* tests/naive_median.cc: Update.
* mln/debug/iota.hh: New.
* mln/core/pixel.hh (value_ptr_): New.
* mln/core/dpoints_piter.hh (center_point): New.
(update_p_): Rename as...
(update): ...this.
* mln/core/concept/genpixel.hh: Inactivate some code.
* mln/core/dpoints_pixter.hh: Update.
* mln/core/internal/pixel_iterator_base.hh: Clean-up.
* mln/level/was.hmedian.hh (hmedian): Move...
* mln/level/was.median.hh: ...here.
* mln/level/was.hmedian.hh: Remove.
* mln/level/fast_median.hh: Clean-up.
Contents
mln/core/concept/genpixel.hh | 36 +++--
mln/core/dpoints_piter.hh | 40 ++++-
mln/core/dpoints_pixter.hh | 120 +++++++++++++---
mln/core/internal/pixel_iterator_base.hh | 223 +++++++++++++++++--------------
mln/core/pixel.hh | 20 --
mln/debug/iota.hh | 69 +++++++++
mln/level/fast_median.hh | 15 --
mln/level/was.median.hh | 61 ++++++++
tests/fast_median.cc | 47 ++++++
tests/naive_median.cc | 4
10 files changed, 468 insertions(+), 167 deletions(-)
Index: tests/fast_median.cc
--- tests/fast_median.cc (revision 1022)
+++ tests/fast_median.cc (working copy)
@@ -37,9 +37,40 @@
#include <mln/io/save_pgm.hh>
#include <mln/value/int_u.hh>
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
#include <mln/level/fast_median.hh>
-#include <mln/level/approx/median.hh>
+#include <mln/core/dpoints_pixter.hh>
+#include <mln/core/pixel.hh>
+
+
+namespace mln
+{
+
+ template <typename I, typename W>
+ void test(I& input, const W& win)
+ {
+ mln_point(I) p;
+ p.row() = p.col() = 1;
+
+ {
+ mln_qixter(I) qix(win, p, input);
+ for_all(qix)
+ std::cout << *qix << ' ';
+ std::cout << " : " << qix.center_value() <<
std::endl;
+ }
+
+ {
+ pixel<I> pix(input, p);
+ mln_qixter(I) qix(win, pix, input);
+ for_all(qix)
+ std::cout << *qix << ' ';
+ std::cout << " : " << qix.center_value() <<
std::endl;
+ }
+ }
+
+}
@@ -48,6 +79,17 @@
using namespace mln;
using value::int_u8;
+// {
+// rectangle2d rect(3, 3);
+// border::thickness = 4;
+// image2d_b<int_u8> ima(3, 3);
+// debug::iota(ima);
+// debug::println(ima);
+// test(ima, rect);
+// }
+
+
+ {
rectangle2d rect(51, 51);
border::thickness = 52;
@@ -57,7 +99,6 @@
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/naive_median.cc
--- tests/naive_median.cc (revision 1022)
+++ tests/naive_median.cc (working copy)
@@ -46,8 +46,8 @@
int main()
{
- rectangle2d rec(8, 8);
- border::thickness = 9;
+ rectangle2d rec(51, 51);
+ border::thickness = 52;
image2d_b<int_u8>
lena = io::load_pgm("../img/lena.pgm"),
Index: mln/debug/iota.hh
--- mln/debug/iota.hh (revision 0)
+++ mln/debug/iota.hh (revision 0)
@@ -0,0 +1,69 @@
+// 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_DEBUG_IOTA_HH
+# define MLN_DEBUG_IOTA_HH
+
+/*! \file mln/debug/iota.hh
+ *
+ * \brief FIXME
+ */
+
+# include <mln/core/concept/image.hh>
+
+
+namespace mln
+{
+
+ namespace debug
+ {
+
+ /// FIXME
+ template <typename I>
+ void iota(Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ void iota(Image<I>& input_)
+ {
+ unsigned i = 0;
+ I& input = exact(input_);
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ input(p) = ++i;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::debug
+
+} // end of namespace mln
+
+
+#endif // ! MLN_DEBUG_IOTA_HH
Index: mln/core/pixel.hh
--- mln/core/pixel.hh (revision 1022)
+++ mln/core/pixel.hh (working copy)
@@ -76,15 +76,15 @@
psite& site();
mln_rvalue(I) operator*() const;
- typename pixel_lvalue<I>::ret operator*();
+ mln_lvalue(I) operator*();
- const value* address() const;
- value* address();
+ value** address() const;
protected:
I& ima_;
psite p_;
+ value* value_ptr_;
};
@@ -101,6 +101,7 @@
: ima_(image),
p_(p)
{
+ value_ptr_ = & ima_(p);
}
template <typename I>
@@ -132,24 +133,17 @@
}
template <typename I>
- typename pixel_lvalue<I>::ret
+ mln_lvalue(I)
pixel<I>::operator*()
{
return ima_(p_);
}
template <typename I>
- const mln_value(I)*
+ mln_value(I)**
pixel<I>::address() const
{
- return & ima_(p_);
- }
-
- template <typename I>
- mln_value(I)*
- pixel<I>::address()
- {
- return & ima_(p_);
+ return (mln_value(I)**)(& this->value_ptr_);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/dpoints_piter.hh
--- mln/core/dpoints_piter.hh (revision 1022)
+++ mln/core/dpoints_piter.hh (working copy)
@@ -71,13 +71,13 @@
* \param[in] p_ref Center point to iterate around.
*/
template <typename Dps, typename Pref>
- dpoints_fwd_piter(const Dps& dps,
+ dpoints_fwd_piter(const Dps& dps, // FIXME: explicitly set_of_<D>?
const GenPoint<Pref>& p_ref);
/// Convertion to point.
operator mln_point(D) () const;
- /// Address of the point.
+ /// Address of the point this iterator designates.
const point* pointer() const;
/// Test the iterator validity.
@@ -95,13 +95,20 @@
/// Give the i-th coordinate.
coord operator[](unsigned i) const;
+ /// The point around which this iterator moves.
+ const point& center_point() const;
+
+ /// Force this iterator to update its location to take into
+ /// account that its center point may have moved.
+ void update();
+
private:
const std::vector<D>& dps_;
- const point& p_ref_;
+ const point& p_ref_; // reference point (or "center point")
unsigned i_;
- point p_;
- void update_p_();
+ point p_; // location of this iterator; p_ makes this iterator be
+ // itself a potential center point (Cf. the pointer() method).
};
@@ -120,7 +127,7 @@
template <typename D>
dpoints_fwd_piter<D>::operator mln_point(D) () const
{
- assert(is_valid());
+ mln_precondition(is_valid());
return p_;
}
@@ -150,7 +157,7 @@
dpoints_fwd_piter<D>::start()
{
i_ = 0;
- update_p_();
+ update();
}
template <typename D>
@@ -158,12 +165,19 @@
dpoints_fwd_piter<D>::next_()
{
++i_;
- update_p_();
+ update();
+ }
+
+ template <typename D>
+ const mln_point(D)&
+ dpoints_fwd_piter<D>::center_point() const
+ {
+ return p_ref_;
}
template <typename D>
void
- dpoints_fwd_piter<D>::update_p_()
+ dpoints_fwd_piter<D>::update()
{
if (is_valid())
p_ = p_ref_ + dps_[i_];
@@ -173,6 +187,14 @@
mln_coord(D)
dpoints_fwd_piter<D>::operator[](unsigned i) const
{
+ mln_precondition(is_valid());
+
+ // below we test that no update is required
+ // meaning that p_ref_ has not moved or that
+ // the user has explicitly called update()
+ mln_precondition(p_ref_ + dps_[i_] = p_);
+ // FIXME: Explain this issue in the class documentation...
+
return p_[i];
}
Index: mln/core/concept/genpixel.hh
--- mln/core/concept/genpixel.hh (revision 1022)
+++ mln/core/concept/genpixel.hh (working copy)
@@ -60,17 +60,22 @@
{
/*
- typedef ima; // not const!
- typede psite;
typedef rvalue;
typedef value;
+ // FIXME: lvalue?
- const ima& image() const;
- const psite& site() const; // FIXME ou cpy
+
+ // FIXME: Inactivated:
+ // typedef ima; // not const!
+ // typedef psite;
+ // const ima& image() const;
+ // const psite& site() const; // FIXME ou cpy
+ // value* address();
rvalue operator*() const;
+ lvalue operator*();
- const value* address() const;
+ const value*& address() const;
*/
protected:
@@ -89,7 +94,7 @@
* \relates mln::GenPixel
*/
template <typename P>
- std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>&
p);
+ std::ostream& operator<<(std::ostream& ostr, const GenPixel<P>&
pxl);
@@ -101,17 +106,20 @@
{
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;
+ // FIXME: Inactivated:
+
+// 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;
+// const value *const & (E::*m4)() const = & E::address;
+// m4 = 0;
}
Index: mln/core/dpoints_pixter.hh
--- mln/core/dpoints_pixter.hh (revision 1022)
+++ mln/core/dpoints_pixter.hh (working copy)
@@ -35,6 +35,7 @@
namespace mln
{
+
/*! \brief A generic forward iterator on image pixel of a windows and of
* neighborhoods.
*
@@ -45,6 +46,7 @@
{
typedef typename internal::pixel_iterator_base_< I, dpoints_pixter<I> >
super;
public:
+
/// Image pixel value
typedef mln_value(I) value;
/// Image pixel rvalue
@@ -58,73 +60,149 @@
* \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::psite& p_ref,I& ima);
+ template <typename Dps, typename Pref>
+ dpoints_pixter(const Dps& dps,
+ const GenPoint<Pref>& p_ref,
+ I& image);
+
+ template <typename Dps, typename Pref>
+ dpoints_pixter(const Dps& dps,
+ const GenPixel<Pref>& p_ref,
+ I& image);
- /// Set the iterator at the start.
+ /// Start an iteration.
void start();
+
/// Go to the next pixel.
void next_();
+
/// Invalidate the iterator.
void invalidate();
- /// Is the iterator valid?
+
+ /// Test the iterator validity.
bool is_valid() const;
+ /// Force this iterator to update its location to take into
+ /// account that its center point may have moved.
+ void update();
+
+ /// The value around which this iterator moves.
+ const value& center_value() const;
+
private:
+
/// offset of each dpoints
std::vector<int> offset_;
+
/// current offset
- std::vector<int>::iterator i_;
- /// reference pixel in the image
- value* pixref_;
+ int i_;
+
+ /// reference pixel / point in the image
+ value** value_ref_;
+ // or:
+ const mln_point(I)* p_ref_;
+
+
+ template <typename Dps>
+ void init_(const Dps& dps);
};
#ifndef MLN_INCLUDE_ONLY
template <typename I>
+ template <typename Dps, typename Pref>
+ dpoints_pixter<I>::dpoints_pixter(const Dps& dps,
+ const GenPoint<Pref>& p_ref,
+ I& image)
+ : super(image)
+ {
+ p_ref_ = internal::force_exact<Pref>(p_ref).pointer();
+ value_ref_ = 0;
+ init_(dps);
+ }
+
+
+ template <typename I>
+ template <typename Dps, typename Pref>
+ dpoints_pixter<I>::dpoints_pixter(const Dps& dps,
+ const GenPixel<Pref>& p_ref,
+ I& image)
+ : super(image)
+ {
+ p_ref_ = 0;
+ value_ref_ = internal::force_exact<Pref>(p_ref).address();
+ init_(dps);
+ }
+
+ template <typename I>
+ const mln_value(I)&
+ dpoints_pixter<I>::center_value() const
+ {
+ mln_invariant(value_ref_ != 0 || p_ref_ != 0);
+ if (p_ref_)
+ return image_(*p_ref_);
+ else
+ return ** value_ref_;
+ }
+
+ template <typename I>
template <typename Dps>
- dpoints_pixter<I>::dpoints_pixter(const Dps& dps, const typename
I::psite& ref, I& ima) : super(ima)
+ void
+ dpoints_pixter<I>::init_(const Dps& dps)
{
- this->p_ = ref;
- pixref_ = &ima(ref);
- for (typename std::vector<typename I::dpoint>::const_iterator it =
dps.vec().begin();
- it != dps.vec().end();
- ++it)
- offset_.push_back(ima.offset(*it));
+ for (unsigned i = 0; i < dps.nelements(); ++i)
+ offset_.push_back(this->image_.offset(dps.element(i)));
+
+ if (dps.nelements() > 1)
+ for (unsigned i = dps.nelements() - 1; i > 0; --i)
+ offset_[i] -= offset_[i - 1];
+
+ // offset_[0] is absolute; other offsets are relative.
+ invalidate();
}
+ template <typename I>
+ void dpoints_pixter<I>::update()
+ {
+ if (is_valid())
+ {
+ if (p_ref_)
+ this->value_ptr_ = & image_(*p_ref_) + offset_[i_];
+ else
+ this->value_ptr_ = * value_ref_ + offset_[i_];
+ }
+ }
template <typename I>
void dpoints_pixter<I>::start()
{
- pixref_ = &ima_(this->p_);
- i_ = offset_.begin();
- this->current_value_ = pixref_ + *i_;
+ i_ = 0;
+ update();
}
template <typename I>
void dpoints_pixter<I>::next_()
{
++i_;
- this->current_value_ = pixref_ + *i_;
+ this->value_ptr_ += offset_[i_];
}
template <typename I>
bool dpoints_pixter<I>::is_valid() const
{
- return i_ != offset_.end();
+ return i_ != offset_.size();
}
template <typename I>
void dpoints_pixter<I>::invalidate()
{
- i_ = offset_.end();
+ i_ = offset_.size();
}
#endif // ! MLN_INCLUDE_ONLY
-}
+} // end of namespace mln
#endif // MLN_CORE_DPOINTS_PIXTER_HH
Index: mln/core/internal/pixel_iterator_base.hh
--- mln/core/internal/pixel_iterator_base.hh (revision 1022)
+++ mln/core/internal/pixel_iterator_base.hh (working copy)
@@ -28,10 +28,9 @@
#ifndef MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
# define MLN_CORE_INTERNAL_PIXEL_ITERATOR_BASE_HH
-/*! \file mln/core/internal/fast_iterator_base.hh
+/*! \file mln/core/internal/pixel_iterator_base.hh
*
- * \brief Base class for Fast_Iterator concept implementation.
- * Usefull for code factorisation
+ * \brief Base class for Pixel_Iterator concept implementation classes.
*/
# include <mln/core/concept/pixel_iterator.hh>
@@ -44,126 +43,158 @@
{
/*! \brief pixel_iterator_base_ class
+ *
*/
- template <typename Image, typename Exact>
- class pixel_iterator_base_ : public Pixel_Iterator<Exact>
+ template <typename I, typename E>
+ class pixel_iterator_base_ : public Pixel_Iterator<E>
{
public:
- /// Image type.
- typedef Image ima;
+
/// Image value type.
- typedef mln_value(Image) value;
+ typedef mln_value(I) value;
+
/// Image lvalue type.
- typedef mln_lvalue(Image) lvalue;
+ typedef mln_lvalue(I) lvalue;
+
/// Image rvalue type.
- typedef mln_rvalue(Image) rvalue;
- /// Image psite type.
- typedef mln_psite(Image) psite;
+ typedef mln_rvalue(I) rvalue;
+
- /// 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();
+ value** address() const;
+
+
+ // FIXME: Inactivated:
- /// psite associated to the iterator.
- const psite& site() const;
- /// psite associated to the iterator.
- psite& site();
+// /// I type.
+// typedef I ima;
+
+// /// Image psite type.
+// typedef mln_psite(I) psite;
+
+// /// Get the image associated to the current pixel iterator.
+// const ima& image() const;
+
+// /// psite associated to the iterator.
+// const psite& site() const;
+
+// /// psite associated to the iterator.
+// psite& site();
+
+// /// Address of the current iterator value/pixel.
+// value* address();
protected:
- /// Current pixel value
- value* current_value_;
+
+ /// Current pixel / value
+ value* value_ptr_;
+
/// Image associated to the iterator
- ima& ima_;
- /// Psite of the pixel
- psite p_;
+ I& image_;
+
+ // FIXME: Inactivated:
- pixel_iterator_base_(ima& source);
+// /// Psite of the pixel
+// psite p_;
+
+ pixel_iterator_base_(I& image);
};
#ifndef MLN_INCLUDE_ONLY
- template <typename Image, typename Exact>
- pixel_iterator_base_<Image, Exact>::pixel_iterator_base_(ima& source) :
- ima_(source)
+ template <typename I, typename E>
+ pixel_iterator_base_<I, E>::pixel_iterator_base_(I& image) :
+ image_(image),
+ value_ptr_(0)
{
}
- template <typename Image, typename Exact>
- const typename pixel_iterator_base_<Image, Exact>::ima&
- pixel_iterator_base_<Image, Exact>::image() const
- {
- return ima_;
- }
+// template <typename I, typename E>
+// const typename pixel_iterator_base_<I, E>::ima&
+// pixel_iterator_base_<I, E>::image() const
+// {
+// return ima_;
+// }
- template <typename Image, typename Exact>
- typename pixel_iterator_base_<Image, Exact>::lvalue
- pixel_iterator_base_<Image, Exact>::operator* ()
+ template <typename I, typename E>
+ mln_lvalue(I)
+ pixel_iterator_base_<I, E>::operator* ()
{
- assert(exact(this)->is_valid());
- return *current_value_;
+ mln_precondition(exact(this)->is_valid());
+ mln_precondition(value_ptr_ != 0);
+ return *value_ptr_;
}
- template <typename Image, typename Exact>
- typename pixel_iterator_base_<Image, Exact>::rvalue
- pixel_iterator_base_<Image, Exact>::operator* () const
+ template <typename I, typename E>
+ mln_rvalue(I)
+ pixel_iterator_base_<I, E>::operator* () const
{
- assert(exact(this)->is_valid());
- return *current_value_;
+ mln_precondition(exact(this)->is_valid());
+ mln_precondition(value_ptr_ != 0);
+ return *value_ptr_;
}
- template <typename Image, typename Exact>
- const typename pixel_iterator_base_<Image, Exact>::value*
- pixel_iterator_base_<Image, Exact>::address() const
+ template <typename I, typename E>
+ mln_value(I) **
+ pixel_iterator_base_<I, E>::address() const
{
- assert(exact(this)->is_valid());
- return current_value_;
+ mln_precondition(exact(this)->is_valid());
+ mln_precondition(value_ptr_ != 0);
+ return & (mln_value(I)*)(value_ptr_);
}
- 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 I, typename E>
+// mln_value(I)*
+// pixel_iterator_base_<I, E>::address()
+// {
+// mln_precondition(exact(this)->is_valid());
+// return value_ptr_;
+// }
+
+// template <typename I, typename E>
+// const typename pixel_iterator_base_<I, E>::psite&
+// pixel_iterator_base_<I, E>::site() const
+// {
+// //FIXME: update psite
+// return p_;
+// }
+
+// template <typename I, typename E>
+// typename pixel_iterator_base_<I, E>::psite&
+// pixel_iterator_base_<I, E>::site()
+// {
+// //FIXME: update psite
+// return p_;
+// }
+
- 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>
+// template <typename E, typename I>
+// class pixel_iterator_base_ : public Pixel_Iterator<E>
// {
// 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;
+// /// 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();
@@ -193,46 +224,46 @@
// #ifndef MLN_INCLUDE_ONLY
-// template <typename Exact, typename Image>
-// pixel_iterator_base_<Exact, Image>::pixel_iterator_base_()
+// template <typename E, typename I>
+// pixel_iterator_base_<E,I>::pixel_iterator_base_()
// {
// }
-// template <typename Exact, typename Image>
-// void pixel_iterator_base_<Exact, Image>::start()
+// template <typename E, typename I>
+// void pixel_iterator_base_<E,I>::start()
// {
// current_ = start_;
// }
-// template <typename Exact, typename Image>
-// void pixel_iterator_base_<Exact, Image>::next_()
+// template <typename E, typename I>
+// void pixel_iterator_base_<E,I>::next_()
// {
// ++current_;
// }
-// template <typename Exact, typename Image>
-// void pixel_iterator_base_<Exact, Image>::invalidate()
+// template <typename E, typename I>
+// void pixel_iterator_base_<E,I>::invalidate()
// {
// current_ = eoi_;
// }
-// template <typename Exact, typename Image>
-// bool pixel_iterator_base_<Exact, Image>::is_valid() const
+// template <typename E, typename I>
+// bool pixel_iterator_base_<E,I>::is_valid() const
// {
// return (current_ != eoi_);
// }
-// template <typename Exact, typename Image>
-// typename pixel_iterator_base_<Exact, Image>::rvalue
-// pixel_iterator_base_<Exact, Image>::operator*()
+// template <typename E, typename I>
+// typename pixel_iterator_base_<E,I>::rvalue
+// pixel_iterator_base_<E,I>::operator*()
// {
// return *current_;
// }
-// template <typename Exact, typename Image>
-// typename pixel_iterator_base_<Exact, Image>::lvalue
-// pixel_iterator_base_<Exact, Image>::operator*() const
+// template <typename E, typename I>
+// typename pixel_iterator_base_<E,I>::lvalue
+// pixel_iterator_base_<E,I>::operator*() const
// {
// return *current_;
// }
Index: mln/level/was.median.hh
--- mln/level/was.median.hh (revision 1022)
+++ mln/level/was.median.hh (working copy)
@@ -30,7 +30,7 @@
/*! \file mln/level/was.median.hh
*
- * \brief Obsolete routine for the median filter.
+ * \brief Obsolete routines for median filtering.
*/
@@ -43,6 +43,9 @@
namespace impl
{
+
+ // prefer using a canvas
+
template <typename I, typename W, typename O>
void median_as_procedure(const I& input,
const W& win,
@@ -126,6 +129,62 @@
}
+
+ // horizontal median
+
+ 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 hmedian
+
+
+
} // end of namespace mln::level::impl
} // end of namespace mln::level
Index: mln/level/fast_median.hh
--- mln/level/fast_median.hh (revision 1022)
+++ mln/level/fast_median.hh (working copy)
@@ -103,7 +103,7 @@
med.init();
{
mln_qixter(I) q(win, p, input);
- for_all(q) //if (input.has(q))
+ for_all(q)
med.take(*q);
}
@@ -118,10 +118,10 @@
{
// "go down"
- for_all(q_top) //if (input.has(q_top))
+ for_all(q_top)
med.untake(*q_top);
- for_all(q_bot) //if (input.has(q_bot))
+ for_all(q_bot)
med.take(*q_bot);
output(p) = med;
@@ -130,11 +130,10 @@
// 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))
+ for_all(q_fm)
med.untake(*q_fm);
- for_all(q_fp) //if (input.has(q_fp))
+ for_all(q_fp)
med.take(*q_fp);
output(p) = med;
}
@@ -143,9 +142,9 @@
while (col > min_col)
{
--col;
- for_all(q_bm) //if (input.has(q_bm))
+ for_all(q_bm)
med.untake(*q_bm);
- for_all(q_bp) //if (input.has(q_bp))
+ for_all(q_bp)
med.take(*q_bp);
output(p) = med;
}