milena r1083: Median can be processed for any direction

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-09-07 Simon Nivault <simon.nivault@lrde.epita.fr> Median can be processed for any direction * sandbox/nivault/median.hh: . * sandbox/nivault/tests/test.cc: Test on lena for median_dir median.hh | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- tests/test.cc | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 1 deletion(-) Index: trunk/milena/sandbox/nivault/tests/test.cc =================================================================== --- trunk/milena/sandbox/nivault/tests/test.cc (revision 0) +++ trunk/milena/sandbox/nivault/tests/test.cc (revision 1083) @@ -0,0 +1,51 @@ +// 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/level_median.cc + * + * \brief Test on mln::median::median_dir. + */ + +#include <median.hh> +#include <mln/io/load_pgm.hh> +#include <mln/io/save_pgm.hh> +#include <mln/level/paste.hh> +#include <mln/core/win/hline2d.hh> + +int main() +{ + using namespace mln; + + image2d_b< value::int_u8 > + lena = io::load_pgm("lena.pgm"), + out = image2d_b< value::int_u8 >(lena.domain()); + + win::hline2d win(7); + + level::impl::median_dir(lena, win, 0, out); + io::save_pgm(out, "out.pgm"); +} Index: trunk/milena/sandbox/nivault/median.hh =================================================================== --- trunk/milena/sandbox/nivault/median.hh (revision 1082) +++ trunk/milena/sandbox/nivault/median.hh (revision 1083) @@ -38,7 +38,9 @@ # include <mln/core/window2d.hh> # include <mln/core/win/hline2d.hh> +# include <mln/core/win/vline2d.hh> # include <mln/core/t_image.hh> +# include <mln/core/dpoint.hh> # include <mln/accu/median.hh> # include <mln/canvas/sbrowsing.hh> @@ -46,6 +48,8 @@ # include <mln/geom/shift.hh> # include <mln/set/diff.hh> +# include <mln/border/resize.hh> +# include <mln/border/duplicate.hh> namespace mln { @@ -73,6 +77,76 @@ namespace impl { + template <typename I, typename O> + void median_dir(const Image<I>& input_, const win::hline2d& win, unsigned dir, O& output) + { + const unsigned dim = I::point::dim; + mln_precondition(dir < dim); + const I& input = exact(input_); + mln_point(I) + pmin = input.domain().pmin(), + pmax = input.domain().pmax(); + + const unsigned half = win.length() / 2; + + mln_point(I) p; + mln_point(I) pt; + mln_point(I) pu; + + mln_coord(I)& ct = pt[dir]; + mln_coord(I)& cu = pu[dir]; + + accu::median<mln_vset(I)> med(input.values()); + + p = pmin; + do + { + //traitement + pt = pu = p; + + // initialization (before first point of the row) + med.init(); + for (ct = pmin[dir]; ct < pmin[dir] + half; ++ct) + med.take(input(pt)); + + // left columns (just take new points) + for (p[dir] = pmin[dir]; p[dir] <= pmin[dir] + half; ++p[dir], ++ct) + { + med.take(input(pt)); + output(p) = med.to_value(); + } + + // middle columns (both take and untake) + cu = pmin[dir]; + for (; p[dir] <= pmax[dir] - half; ++cu, ++p[dir], ++ct) + { + med.take(input(pt)); + med.untake(input(pu)); + output(p) = med.to_value(); + } + + // right columns (now just untake old points) + for (; p[dir] <= pmax[dir]; ++cu, ++p[dir]) + { + med.untake(input(pu)); + output(p) = med.to_value(); + } + + // next line + for (int c = dim - 1; c >= 0; --c) + { + if (c == dir) + continue; + if (p[c] != pmax[c]) + { + ++p[c]; + break; + } + p[c] = pmin[c]; + } + p[dir] = pmin[dir]; + } while (p != pmin); + } template <typename I, typename O> void median(const Image<I>& input_, const win::hline2d& win, O& output) @@ -183,7 +257,9 @@ } template <typename I, typename O> - void median(const I& input, const win::vline2d& win, O& output) + void median(const I& input, + const win::vline2d& win, + O& output) { t_image<O> swap_output = swap_coords(output, 0, 1); impl::median(swap_coords(input, 0, 1),
participants (1)
-
Simon Nivault