1023: Fix pixel iterators on sets of dpoints.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@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; }
participants (1)
-
Thierry Geraud