URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-01-21 Matthieu Garrigues <garrigues(a)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>