1088: Add area opening over its new canvas.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Add area opening over its new canvas. * tests/morpho_opening_area.cc: New. * mln/core/concept/accumulator.hh (take_as_init): New. * mln/morpho/opening_attribute.hh: New. * mln/morpho/opening_area.hh: New. * mln/morpho/includes.hh: Add neighborhood.hh. * mln/canvas/morpho: New. * mln/canvas/morpho/algebraic_union_find.hh: New. * mln/accu/count.hh (result): New. * mln/util: New. * mln/util/pix.hh: New. mln/accu/count.hh | 9 + mln/canvas/morpho/algebraic_union_find.hh | 173 ++++++++++++++++++++++++++++++ mln/core/concept/accumulator.hh | 14 ++ mln/morpho/includes.hh | 1 mln/morpho/opening_area.hh | 71 ++++++++++++ mln/morpho/opening_attribute.hh | 135 +++++++++++++++++++++++ mln/util/pix.hh | 106 ++++++++++++++++++ tests/morpho_opening_area.cc | 55 +++++++++ 8 files changed, 564 insertions(+) Index: tests/morpho_opening_area.cc --- tests/morpho_opening_area.cc (revision 0) +++ tests/morpho_opening_area.cc (revision 0) @@ -0,0 +1,55 @@ +// 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/morpho_opening_area.cc + * + * \brief Test on mln::morpho::opening_area. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/value/int_u8.hh> +#include <mln/core/neighb2d.hh> + +#include <mln/io/load_pgm.hh> +#include <mln/io/save_pgm.hh> + +#include <mln/morpho/opening_area.hh> + + + +int main() +{ + using namespace mln; + using value::int_u8; + + image2d_b<int_u8> + lena = io::load_pgm("../img/lena.pgm"), + out(lena.domain()); + + morpho::opening_area(lena, c4(), 510, out); + io::save_pgm(out, "out.pgm"); +} Index: mln/core/concept/accumulator.hh --- mln/core/concept/accumulator.hh (revision 1087) +++ mln/core/concept/accumulator.hh (working copy) @@ -56,6 +56,11 @@ void take(const value& v); void take(const E& other); */ + + // Default impl. + template <typename T> + void take_as_init(const T& t); // 't' is either value or E. + protected: Accumulator(); }; @@ -90,6 +95,15 @@ } template <typename E> + template <typename T> + void + Accumulator<E>::take_as_init(const T& t) // either value or E + { + exact(this)->init(); + exact(this)->take(t); + } + + template <typename E> E merge(const Accumulator<E>& lhs, const Accumulator<E>& rhs) { E tmp(exact(lhs)); Index: mln/morpho/opening_attribute.hh --- mln/morpho/opening_attribute.hh (revision 0) +++ mln/morpho/opening_attribute.hh (revision 0) @@ -0,0 +1,135 @@ +// 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_MORPHO_OPENING_ATTRIBUTE_HH +# define MLN_MORPHO_OPENING_ATTRIBUTE_HH + +/*! \file mln/morpho/opening_attribute.hh + * + * \brief Morphological attribute opening. + */ + +# include <mln/morpho/includes.hh> +# include <mln/canvas/morpho/algebraic_union_find.hh> +# include <mln/level/sort_points.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological area opening. + */ + template <typename A, + typename I, typename N, typename O> + void opening_attribute(const Image<I>& input, const Neighborhood<N>& nbh, mln_result(A) lambda, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename A_, + typename I_, typename N_, typename O_> + struct opening_attribute_t + { + typedef mln_point(I_) P; + + // requirements from mln::canvas::morpho::algebraic_union_find + + typedef A_ A; + typedef I_ I; + typedef N_ N; + typedef O_ O; + typedef vec_p<P> S; + typedef util::pix_<I> pix_t; + + const I& input; + const N& nbh; + mln_result(A) lambda; + O& output; + + const S s; + + void init() + { + // FIXME: border::fill(input, mln_max(mln_value(I))); + } + + bool is_active(const A& attr) const + { + return attr.to_value() < lambda; + } + + void inactivate(A& attr) + { + attr.set_value(lambda); + } + + // end of requirements + + opening_attribute_t(const I_& input, const N_& nbh, mln_result(A) lambda, O_& output) + : input(input), nbh(nbh), lambda(lambda), output(output), + s(level::sort_points_decreasing(input)) + { + } + + }; + + } // end of namespace mln::morpho::impl + + + template <typename A, + typename I, typename N, typename O> + void opening_attribute(const Image<I>& input_, + const Neighborhood<N>& nbh_, mln_result(A) lambda, + Image<O>& output_) + { + const I& input = exact(input_); + const N& nbh = exact(nbh_); + O& output = exact(output_); + mln_precondition(output.domain() = input.domain()); + + typedef impl::opening_attribute_t<A,I,N,O> F; + F f(input, nbh, lambda, output); + canvas::morpho::algebraic_union_find<F> run(f); + + mln_postcondition(output <= input); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_OPENING_ATTRIBUTE_HH Index: mln/morpho/opening_area.hh --- mln/morpho/opening_area.hh (revision 0) +++ mln/morpho/opening_area.hh (revision 0) @@ -0,0 +1,71 @@ +// 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_MORPHO_OPENING_AREA_HH +# define MLN_MORPHO_OPENING_AREA_HH + +/*! \file mln/morpho/opening_area.hh + * + * \brief Morphological area opening. + */ + +# include <mln/morpho/opening_attribute.hh> +# include <mln/accu/count.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological area opening. + */ + template <typename I, typename N, typename O> + void opening_area(const Image<I>& input, const Neighborhood<N>& nbh, std::size_t lambda, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename N, typename O> + void opening_area(const Image<I>& input, const Neighborhood<N>& nbh, std::size_t lambda, + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + typedef util::pix_<I> pix_t; + opening_attribute< accu::count<pix_t> >(input, nbh, lambda, output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_OPENING_AREA_HH Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 1087) +++ mln/morpho/includes.hh (working copy) @@ -36,6 +36,7 @@ # include <mln/core/concept/image.hh> # include <mln/core/concept/window.hh> +# include <mln/core/concept/neighborhood.hh> # include <mln/accu/min.hh> # include <mln/accu/max.hh> Index: mln/canvas/morpho/algebraic_union_find.hh --- mln/canvas/morpho/algebraic_union_find.hh (revision 0) +++ mln/canvas/morpho/algebraic_union_find.hh (revision 0) @@ -0,0 +1,173 @@ +// 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_MORPHO_ALGEBRAIC_UNION_FIND_HH +# define MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH + +/*! \file mln/canvas/morpho/algebraic_union_find.hh + * + * \brief FIXME: Doc! + */ + +# include <mln/core/concept/image.hh> +# include <mln/core/concept/neighborhood.hh> +# include <mln/level/fill.hh> +# include <mln/util/pix.hh> + + +namespace mln +{ + + namespace canvas + { + + namespace morpho + { + + // General version. + + template <typename F> + struct algebraic_union_find + { + F& f; + + typedef typename F::I I; + typedef typename F::N N; + typedef typename F::O O; + typedef typename F::S S; + typedef typename F::A A; + typedef mln_point(I) point; + + // aux: + mln_ch_value(O, bool) deja_vu; + mln_ch_value(O, point) parent; + mln_ch_value(O, A) data; + + algebraic_union_find(F& f) + : f(f), + deja_vu(f.output.domain()), + parent(f.output.domain()), + data(f.output.domain()) + { + run(); + } + + void run() + { + // init + { + mln::level::fill(deja_vu, false); + f.init(); + } + // first pass + { + mln_fwd_piter(S) p(f.s); + mln_niter(N) n(f.nbh, p); + for_all(p) + { + make_set(p); + for_all(n) + if (f.input.has(n) && deja_vu(n)) + do_union(n, p); + deja_vu(p) = true; + } + } + + // second pass + { + mln_bkd_piter(S) p(f.s); + mln_niter(N) n(f.nbh, p); + for_all(p) + if (is_root(p)) + f.output(p) = f.input(p); + else + f.output(p) = f.output(parent(p)); + } + + /* + Change 2nd pass into: + for_all(p) if (not is_root(p)) f.output(p) = f.output(parent(p)); + and add in init: + mln::level::assign(f.output, f.input); + */ + + } // end of run() + + void make_set(const point& p) + { + parent(p) = p; + data(p).take_as_init(util::pix(f.input, p)); + } + + bool is_root(const point& p) const + { + return parent(p) = p; + } + + point find_root(const point& x) + { + if (parent(x) = x) + return x; + else + return parent(x) = find_root(parent(x)); + } + + bool equiv(const point2d& r, const point2d& p) + { + // Either a flat zone or the component of r is still growing. + return f.input(r) = f.input(p) || f.is_active(data(r)); + } + + void do_union(const point& n, const point& p) + { + point r = find_root(n); + if (r != p) + { + if (equiv(r, p)) + { + data(p).take(data(r)); + parent(r) = p; + } + else + f.inactivate(data(p)); + } + } + + }; + + + // FIXME: Fast version. + + + } // end of namespace mln::canvas::morpho + + } // end of namespace mln::canvas + +} // end of namespace mln + + +#endif // ! MLN_CANVAS_MORPHO_ALGEBRAIC_UNION_FIND_HH Index: mln/accu/count.hh --- mln/accu/count.hh (revision 1087) +++ mln/accu/count.hh (working copy) @@ -49,6 +49,7 @@ struct count : public Accumulator< count<V> > { typedef V value; + typedef std::size_t result; // FIXME: Up in Accumulator. count(); @@ -57,6 +58,7 @@ void take(const count<V>& other); std::size_t to_value() const; + void set_value(std::size_t c); protected: @@ -101,6 +103,13 @@ return count_; } + template <typename V> + void + count<V>::set_value(std::size_t c) + { + count_ = c; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::accu Index: mln/util/pix.hh --- mln/util/pix.hh (revision 0) +++ mln/util/pix.hh (revision 0) @@ -0,0 +1,106 @@ +// 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_UTIL_PIX_HH +# define MLN_UTIL_PIX_HH + +/*! \file mln/util/pix.hh + * + * \brief Definition of an instant pix. + */ + +# include <mln/core/concept/image.hh> + + +namespace mln +{ + + namespace util + { + + /// Pix structure. + template <typename I> + struct pix_ + { + pix_(const Image<I>& ima, const mln_point(I)& p); + const I& ima() const; + const mln_point(I)& p() const; + private: + const I& ima_; + const mln_point(I)& p_; + }; + + + /// Routine to construct a pix on the fly. + template <typename I> + pix_<I> + pix(const Image<I>& ima, const mln_point(I)& p); + + +# ifndef MLN_INCLUDE_ONLY + + // pix_<I> + + template <typename I> + pix_<I>::pix_(const Image<I>& ima, const mln_point(I)& p) + : ima_(exact(ima)), + p_(p) + { + } + + template <typename I> + const I& + pix_<I>::ima() const + { + return ima_; + } + + template <typename I> + const mln_point(I)& + pix_<I>::p() const + { + return p_; + } + + // pix + + template <typename I> + pix_<I> + pix(const Image<I>& ima, const mln_point(I)& p) + { + pix_<I> tmp(ima, p); + return tmp; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::util + +} // end of namespace mln + + +#endif // ! MLN_UTIL_PIX_HH
participants (1)
-
Thierry Geraud