
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-12-17 Guillaume Duhamel <guillaume.duhamel@lrde.epita.fr> Review chamfer and labeling in canvas. * mln/canvas/chamfer.hh, * mln/canvas/labeling.hh: Review this files split declaration and implementation, fix typo. Tests. * tests/chamfer.cc: Remove ... * tests/canvas/chamfer.cc: ... replace it and modify tests. --- mln/canvas/chamfer.hh | 29 +++++++-- mln/canvas/labeling.hh | 151 +++++++++++++++++++++++++++++++++--------------- tests/canvas/chamfer.cc | 128 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 256 insertions(+), 52 deletions(-) Index: trunk/milena/tests/chamfer.cc (deleted) =================================================================== Index: trunk/milena/tests/canvas/chamfer.cc =================================================================== --- trunk/milena/tests/canvas/chamfer.cc (revision 0) +++ trunk/milena/tests/canvas/chamfer.cc (revision 1615) @@ -0,0 +1,128 @@ +// 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/canvas/chamfer.cc + * + * \brief Tests on mln::geom::chamfer. + */ + +#include <mln/core/image2d.hh> +#include <mln/core/sub_image.hh> +#include <mln/core/image_if_value.hh> +#include <mln/core/inplace.hh> + +#include <mln/level/fill.hh> +#include <mln/debug/println.hh> +#include <mln/core/w_window2d_int.hh> +#include <mln/core/w_window2d_float.hh> +#include <mln/core/image_if_interval.hh> + +#include <mln/make/win_chamfer.hh> +#include <mln/geom/chamfer.hh> +#include <mln/level/compare.hh> + + +int main() +{ + using namespace mln; + unsigned max = 51; + + image2d<bool> ima(9, 9); + + { + level::fill(ima, false); + ima.at(4,4) = true; + const w_window2d_int& w_win = make::mk_chamfer_3x3_int<2, 0> (); + image2d<unsigned> out = geom::chamfer(ima, w_win, max); + unsigned r[9][9] = + { + {16, 14, 12, 10, 8, 10, 12, 14, 16}, + {14, 12, 10, 8, 6, 8, 10, 12, 14}, + {12, 10, 8, 6, 4, 6, 8, 10, 12}, + {10, 8, 6, 4, 2, 4, 6, 8, 10}, + { 8, 6, 4, 2, 0, 2, 4, 6, 8}, + {10, 8, 6, 4, 2, 4, 6, 8, 10}, + {12, 10, 8, 6, 4, 6, 8, 10, 12}, + {14, 12, 10, 8, 6, 8, 10, 12, 14}, + {16, 14, 12, 10, 8, 10, 12, 14, 16} + }; + + image2d<unsigned> ref (make::image2d(r)); + mln_assertion (out == ref); + } + + { + level::fill(ima, false); + ima.at(4,4) = true; + const w_window2d_int& w_win = make::mk_chamfer_3x3_int<2, 3> (); + image2d<unsigned> out = geom::chamfer(ima, w_win, max); + + unsigned r[9][9] = + { + {12, 11, 10, 9, 8, 9, 10, 11, 12}, + {11, 9, 8, 7, 6, 7, 8, 9, 11}, + {10, 8, 6, 5, 4, 5, 6, 8, 10}, + { 9, 7, 5, 3, 2, 3, 5, 7, 9}, + { 8, 6, 4, 2, 0, 2, 4, 6, 8}, + { 9, 7, 5, 3, 2, 3, 5, 7, 9}, + {10, 8, 6, 5, 4, 5, 6, 8, 10}, + {11, 9, 8, 7, 6, 7, 8, 9, 11}, + {12, 11, 10, 9, 8, 9, 10, 11, 12} + }; + + image2d<unsigned> ref (make::image2d(r)); + mln_assertion (out == ref); + } + + { + level::fill(ima, false); + ima.at(4,4) = true; + const w_window2d_int& w_win = make::mk_chamfer_5x5_int<4, 6, 9> (); + image2d<unsigned> out = geom::chamfer(ima, w_win, max); + image2d<unsigned>::fwd_piter p(out.domain()); + for_all(p) + out(p) = out(p) / 2; + + unsigned r[9][9] = + { + {12, 10, 9, 8, 8, 8, 9, 10, 12}, + {10, 9, 7, 6, 6, 6, 7, 9, 10}, + { 9, 7, 6, 4, 4, 4, 6, 7, 9}, + { 8, 6, 4, 3, 2, 3, 4, 6, 8}, + { 8, 6, 4, 2, 0, 2, 4, 6, 8}, + { 8, 6, 4, 3, 2, 3, 4, 6, 8}, + { 9, 7, 6, 4, 4, 4, 6, 7, 9}, + {10, 9, 7, 6, 6, 6, 7, 9, 10}, + {12, 10, 9, 8, 8, 8, 9, 10, 12} + }; + + image2d<unsigned> ref (make::image2d(r)); + mln_assertion (out == ref); + + } + +} Index: trunk/milena/mln/canvas/chamfer.hh =================================================================== --- trunk/milena/mln/canvas/chamfer.hh (revision 1614) +++ trunk/milena/mln/canvas/chamfer.hh (revision 1615) @@ -38,23 +38,40 @@ namespace canvas { + /*! + * \brief Compute chamfer distance. + * + */ template <typename F> struct chamfer { - F& f; - typedef typename F::I I; typedef typename F::W W; typedef mln_point(I) point; - chamfer(F& f) + F& f; + + chamfer(F& f); + + void run(); + }; + +# ifndef MLN_INCLUDE_ONLY + + template<typename F> + inline + chamfer<F>::chamfer(F& f) : f(f) { run(); } - void run() + template<typename F> + inline + void + chamfer<F>::run() { + /// Init. { f.init(); @@ -86,9 +103,9 @@ f.output(p) = f.output(q) + q.w(); f.status = true; } - } - }; + +# endif // ! MLN_INCLUDE_ONLY } // end of mln::canvas Index: trunk/milena/mln/canvas/labeling.hh =================================================================== --- trunk/milena/mln/canvas/labeling.hh (revision 1614) +++ trunk/milena/mln/canvas/labeling.hh (revision 1615) @@ -71,7 +71,69 @@ bool status; // Ctor. - labeling(F& f) + labeling(F& f); + + void init(); + + void pass_1(); + + void pass_2(); + + + // Auxiliary methods. + + void make_set(const point& p); + + bool is_root(const point& p) const; + + point find_root(const point& x); + + void do_union(const point& n, const point& p); + + }; + + + template <typename F> + struct labeling_fastest + { + // Functor. + F& f; + + typedef typename F::I I; + typedef typename F::N N; + typedef typename F::L L; + + // Auxiliary data. + mln_ch_value(I, unsigned) parent; + + // Output. + mln_ch_value(I, L) output; + L nlabels; + bool status; + + // Ctor. + labeling_fastest(F& f); + + void init(); + + void pass_1(); + + void pass_2(); + + // Auxiliary methods. + + bool is_root(unsigned p) const; + + unsigned find_root(unsigned x); + + void do_union(unsigned n, unsigned p); + + }; + +# ifndef MLN_INCLUDE_ONLY + + template <typename F> + labeling<F>::labeling(F& f) : f(f) { trace::entering("canvas::labeling"); @@ -84,8 +146,9 @@ trace::exiting("canvas::labeling"); } - - void init() + template <typename F> + void + labeling<F>::init() { initialize(deja_vu, f.input); mln::level::fill(deja_vu, false); @@ -95,7 +158,9 @@ nlabels = 0; } - void pass_1() + template <typename F> + void + labeling<F>::pass_1() { mln_fwd_piter(S) p(f.s); mln_niter(N) n(f.nbh, p); @@ -112,7 +177,9 @@ } } - void pass_2() + template <typename F> + void + labeling<F>::pass_2() { mln_bkd_piter(S) p(f.s); for_all(p) if (f.handles(p)) @@ -135,21 +202,24 @@ status = true; } - - // Auxiliary methods. - - void make_set(const point& p) + template <typename F> + void + labeling<F>::make_set(const point& p) { parent(p) = p; f.init_attr(p); } - bool is_root(const point& p) const + template <typename F> + bool + labeling<F>::is_root(const point& p) const { return parent(p) == p; } - point find_root(const point& x) + template <typename F> + typename labeling<F>::point + labeling<F>::find_root(const point& x) { if (parent(x) == x) return x; @@ -157,7 +227,9 @@ return parent(x) = find_root(parent(x)); } - void do_union(const point& n, const point& p) + template <typename F> + void + labeling<F>::do_union(const point& n, const point& p) { point r = find_root(n); if (r != p) @@ -167,31 +239,8 @@ } } - }; - - - - template <typename F> - struct labeling_fastest - { - // Functor. - F& f; - - typedef typename F::I I; - typedef typename F::N N; - typedef typename F::L L; - - // Auxiliary data. - mln_ch_value(I, unsigned) parent; - - // Output. - mln_ch_value(I, L) output; - L nlabels; - bool status; - - // Ctor. - labeling_fastest(F& f) + labeling_fastest<F>::labeling_fastest(F& f) : f(f) { trace::entering("canvas::labeling_fastest"); @@ -204,8 +253,9 @@ trace::exiting("canvas::labeling_fastest"); } - - void init() + template <typename F> + void + labeling_fastest<F>::init() { initialize(parent, f.input); for (unsigned p = 0; p < parent.ncells(); ++p) @@ -215,7 +265,9 @@ nlabels = 0; } - void pass_1() + template <typename F> + void + labeling_fastest<F>::pass_1() { mln_bkd_pixter(const I) p(f.input); @@ -234,7 +286,9 @@ } } - void pass_2() + template <typename F> + void + labeling_fastest<F>::pass_2() { mln_fwd_pixter(const I) p(f.input); @@ -258,14 +312,16 @@ status = true; } - // Auxiliary methods. - - bool is_root(unsigned p) const + template <typename F> + bool + labeling_fastest<F>::is_root(unsigned p) const { return parent[p] == p; } - unsigned find_root(unsigned x) + template <typename F> + unsigned + labeling_fastest<F>::find_root(unsigned x) { if (parent[x] == x) return x; @@ -273,7 +329,9 @@ return parent[x] = find_root(parent[x]); } - void do_union(unsigned n, unsigned p) + template <typename F> + void + labeling_fastest<F>::do_union(unsigned n, unsigned p) { unsigned r = find_root(n); if (r != p) @@ -283,7 +341,8 @@ } } - }; + +# endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::canvas