
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2008-01-21 Matthieu Garrigues <garrigues@lrde.epita.fr> Add rank filter. * mln/morpho/rank_filter.hh: New, the rank filter. * mln/accu/rank.hh: clear the accu in init(), do a ratio to get the result when the accumulator is not full. * mln/morpho/includes.hh: Add rank.hh include. * tests/morpho/rank_filter.cc: New, tests, compare with erosion and dilatation. --- mln/accu/rank.hh | 8 ++ mln/morpho/includes.hh | 1 mln/morpho/rank_filter.hh | 120 ++++++++++++++++++++++++++++++++++++++++++++ tests/morpho/rank_filter.cc | 93 ++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 1 deletion(-) Index: trunk/milena/tests/morpho/rank_filter.cc =================================================================== --- trunk/milena/tests/morpho/rank_filter.cc (revision 0) +++ trunk/milena/tests/morpho/rank_filter.cc (revision 1676) @@ -0,0 +1,93 @@ +// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// 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/morpho/rank_filter.cc + * + * \brief Test on mln::morpho::rank_filter. + */ + +#include <mln/core/image2d.hh> +#include <mln/win/rectangle2d.hh> +#include <mln/win/octagon2d.hh> +#include <mln/win/diag2d.hh> +#include <mln/win/backdiag2d.hh> +#include <mln/core/window2d.hh> + +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/value/int_u8.hh> +#include <mln/level/fill.hh> +#include <mln/level/compare.hh> +#include <mln/level/median.hh> +#include <mln/morpho/rank_filter.hh> +#include <mln/morpho/dilation.hh> + + +#include <mln/pw/value.hh> +#include <mln/pw/cst.hh> +#include <mln/fun/ops.hh> + +#include <mln/convert/to_p_array.hh> +#include <mln/convert/to_window.hh> + +#include "tests/data.hh" + + +int main() +{ + using namespace mln; + using value::int_u8; + + win::rectangle2d rec(21, 21); + border::thickness = 66; + + image2d<int_u8> lena; + io::pgm::load(lena, MLN_IMG_DIR "/small.pgm"); + + { + win::octagon2d oct(31); + image2d<int_u8> out; + out = morpho::rank_filter(lena, rec, 0); + + image2d<int_u8> ref(lena.domain()); + ref = morpho::erosion(lena, rec); + mln_assertion(ref == out); + } + + + { + win::octagon2d oct(31); + image2d<int_u8> out; + out = morpho::rank_filter(lena, rec, 21 * 21 - 1); + + image2d<int_u8> ref(lena.domain()); + ref = morpho::dilation(lena, rec); + mln_assertion(ref == out); + } + +} Index: trunk/milena/mln/accu/rank.hh =================================================================== --- trunk/milena/mln/accu/rank.hh (revision 1675) +++ trunk/milena/mln/accu/rank.hh (revision 1676) @@ -114,6 +114,7 @@ void rank_<T>::init() { + elts_.clear(); } template <typename T> @@ -148,9 +149,14 @@ T rank_<T>::to_result() const { - mln_assertion(n_ == elts_.size()); + // Fixme : Call to inplace to unconst (*this). inplace(*this).sort(); + + if (n_ == elts_.size()) return elts_[k_]; + else + // FIXME : This alternative is used to handle images edges. + return elts_[(elts_.size() * k_) / n_]; } template <typename T> Index: trunk/milena/mln/morpho/rank_filter.hh =================================================================== --- trunk/milena/mln/morpho/rank_filter.hh (revision 0) +++ trunk/milena/mln/morpho/rank_filter.hh (revision 1676) @@ -0,0 +1,120 @@ +// Copyright (C) 2007, 2008 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_MORPHO_RANK_FILTER_HH +# define MLN_MORPHO_RANK_FILTER_HH + +/*! \file mln/morpho/rank_filter.hh + * + * \brief Morphological rank_filter. + */ + +# include <mln/morpho/includes.hh> +# include <mln/convert/to_p_array.hh> + +namespace mln +{ + + namespace morpho + { + + /*! Morphological rank_filter. + */ + template <typename I, typename W> + mln_concrete(I) + rank_filter(const Image<I>& input, const Window<W>& win); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + namespace generic + { + + // On function. + + template <typename I, typename W> + inline + mln_concrete(I) + rank_filter_(const I& input, const W& win, unsigned k) + { + trace::entering("morpho::impl::generic::rank_filter_"); + + mln_concrete(I) output; + initialize(output, input); + + accu::rank_<mln_value(I)> accu(k, convert::to_p_array(win, mln_point(I)()).npoints()); + mln_piter(I) p(input.domain()); + mln_qiter(W) q(win, p); + for_all(p) + { + accu.init(); + for_all(q) + if (input.has(q)) + accu.take(input(q)); +// else +// accu.take(mln_value(I)(literal::zero)); + output(p) = accu; + } + + trace::exiting("morpho::impl::generic::rank_filter_"); + return output; + } + + } // end of namespace mln::morpho::impl::generic + + } // end of namespace mln::morpho::impl + + + + // Facades. + + template <typename I, typename W> + inline + mln_concrete(I) + rank_filter(const Image<I>& input, const Window<W>& win, unsigned k) + { + trace::entering("morpho::rank_filter"); + mln_precondition(exact(input).has_data()); + mln_precondition(! exact(win).is_empty()); + + mln_concrete(I) output = impl::generic::rank_filter_(exact(input), exact(win), k); + + trace::exiting("morpho::rank_filter"); + return output; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_RANK_FILTER_HH Index: trunk/milena/mln/morpho/includes.hh =================================================================== --- trunk/milena/mln/morpho/includes.hh (revision 1675) +++ trunk/milena/mln/morpho/includes.hh (revision 1676) @@ -44,6 +44,7 @@ # include <mln/accu/max.hh> # include <mln/accu/min_h.hh> # include <mln/accu/max_h.hh> +# include <mln/accu/rank.hh> # include <mln/fun/v2v/saturate.hh>