milena r1086: New canvas for line processing, and median_dir use it now

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-09-07 Simon Nivault <simon.nivault@lrde.epita.fr> New canvas for line processing, and median_dir use it now * sandbox/nivault/dirbrowsing.hh: New. * sandbox/nivault/median.hh: Use dirbrowsing.hh dirbrowsing.hh | 98 ++++++++++++++++++++++++++++++++++++ median.hh | 154 ++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 217 insertions(+), 35 deletions(-) Index: trunk/milena/sandbox/nivault/dirbrowsing.hh =================================================================== --- trunk/milena/sandbox/nivault/dirbrowsing.hh (revision 0) +++ trunk/milena/sandbox/nivault/dirbrowsing.hh (revision 1086) @@ -0,0 +1,98 @@ +// 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_CANVAS_DIRBROWSING_HH +# define MLN_CANVAS_DIRBROWSING_HH + +/*! \file mln/canvas/dirbrowsing.hh + * + * \brief Directional browsing of an image. + */ + +namespace mln +{ + + namespace canvas + { + + /*! FIXME : DOC + * F shall features : \n + * { \n + * --- as types: \n + * point; \n + * --- as attributes: \n + * dim; \n + * dir; // and test dir < dim \n + * input; \n + * win; \n + * --- as methods: \n + * void init(); \n + * void process() + * } \n + * + */ + template <typename F> + void dirbrowsing(F& f); + +# ifndef MLN_INCLUDE_ONLY + + template <typename F> + void dirbrowsing(F& f) + { + mln_point(F::point) + pmin = f.input.domain().pmin(), + pmax = f.input.domain().pmax(); + + mln_point(F::point) p = pmin; + + f.init(); + + do + { + f.process(p); + + for (int c = f.dim - 1; c >= 0; --c) + { + if (c == f.dir) + continue; + if (p[c] != pmax[c]) + { + ++p[c]; + break; + } + p[c] = pmin[c]; + } + } while (p != pmin); + } + +# endif // ! MLN_INCLUDE_ONLY + + } //end of namespace mln::canvas + +} // end of namespace mln + +#endif // ! MLN_CANVAS_DIRBROWSING_HH Index: trunk/milena/sandbox/nivault/median.hh =================================================================== --- trunk/milena/sandbox/nivault/median.hh (revision 1085) +++ trunk/milena/sandbox/nivault/median.hh (revision 1086) @@ -51,6 +51,8 @@ # include <mln/border/resize.hh> # include <mln/border/duplicate.hh> +# include <dirbrowsing.hh> + namespace mln { @@ -78,39 +80,54 @@ { template <typename I, typename O> - void median_dir(const Image<I>& input_, const win::hline2d& win, unsigned dir, O& output) + struct median_dir_functor { - 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(); + // type + typedef mln_point(I) point; - const unsigned half = win.length() / 2; + // i/o + const I& input; + O& output; + unsigned dir; + int dim; + const win::hline2d& win; + accu::median<mln_vset(I)> med; - mln_point(I) p; - mln_point(I) pt; - mln_point(I) pu; - - mln_coord(I)& ct = pt[dir]; - mln_coord(I)& cu = pu[dir]; + // ctor + median_dir_functor(const Image<I>& input_, const win::hline2d& win_, unsigned dir_, O& output_) + : + input(exact(input_)), + output(exact(output_)), + dir(dir_), + dim(I::point::dim), + win(win_), + med(input.values()) + { + } - accu::median<mln_vset(I)> med(input.values()); + //parts + void init() + { + } - p = pmin; - do + void process(mln_point(I) p) { - //traitement - pt = pu = p; + mln_point(I) + pmin = input.domain().pmin(), + pmax = input.domain().pmax(), + pt = p, + pu = p; + + mln_coord(I)& ct = pt[dir]; + mln_coord(I)& cu = pu[dir]; // initialization (before first point of the row) med.init(); - for (ct = pmin[dir]; ct < pmin[dir] + half; ++ct) + for (ct = pmin[dir]; ct < pmin[dir] + (win.length() / 2); ++ct) med.take(input(pt)); // left columns (just take new points) - for (p[dir] = pmin[dir]; p[dir] <= pmin[dir] + half; ++p[dir], ++ct) + for (p[dir] = pmin[dir]; p[dir] <= pmin[dir] + (win.length() / 2); ++p[dir], ++ct) { med.take(input(pt)); output(p) = med.to_value(); @@ -118,7 +135,7 @@ // middle columns (both take and untake) cu = pmin[dir]; - for (; p[dir] <= pmax[dir] - half; ++cu, ++p[dir], ++ct) + for (; p[dir] <= pmax[dir] - (win.length() / 2); ++cu, ++p[dir], ++ct) { med.take(input(pt)); med.untake(input(pu)); @@ -131,23 +148,90 @@ 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]) + template <typename I, typename O> + void median_dir(const Image<I>& input_, const win::hline2d& win, unsigned dir, O& output) { - ++p[c]; - break; - } - p[c] = pmin[c]; - } - p[dir] = pmin[dir]; - } while (p != pmin); + struct median_dir_functor<I,O> func(input_, win, dir, output); + canvas::dirbrowsing(func); } + +// // median_dir monolythique + +// 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) {
participants (1)
-
Simon Nivault