r3034: Add reconstruction on function

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2008-12-12 Matthieu Garrigues <garrigues@lrde.epita.fr> Add reconstruction on function. * canvas/reconstruction_on_function.hh: New, this canvas is able to compute a reconstruction by dilation or by erosion on a function. * reconstructions_on_function.hh: Using this canvas to implement reconstructions on function. * reconstructions_on_function.cc: New, a test. * canvas/reconstruction.hh: Rename as... * canvas/reconstruction_on_set.hh: ...this. * reconstructions.cc: Rename as... * reconstructions_on_set.cc: ...this. * reconstructions.hh: Rename... * reconstructions_on_set.hh: ...this. --- canvas/reconstruction_on_function.hh | 174 +++++++++++++++++++++++++++ canvas/reconstruction_on_set.hh | 147 +++++++++++++++++++++++ reconstructions_on_function.cc | 63 ++++++++++ reconstructions_on_function.hh | 184 +++++++++++++++++++++++++++++ reconstructions_on_set.cc | 57 +++++++++ reconstructions_on_set.hh | 220 +++++++++++++++++++++++++++++++++++ 6 files changed, 845 insertions(+) Index: trunk/milena/sandbox/garrigues/union_find/reconstructions.hh (deleted) =================================================================== Index: trunk/milena/sandbox/garrigues/union_find/reconstructions.cc (deleted) =================================================================== Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.cc =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.cc (revision 0) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.cc (revision 3034) @@ -0,0 +1,57 @@ +// 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. + +# include "reconstructions_on_set.hh" +# include <mln/core/alias/neighb2d.hh> +# include <mln/core/image/image2d.hh> +# include <mln/io/pbm/load.hh> +# include <mln/io/pbm/save.hh> + +int main(int argc, char** argv) +{ + using namespace mln; + typedef image2d<bool> I; + + image2d<bool> marker; + image2d<bool> mask; + image2d<bool> output; + + if (argc < 2) + { + std::cerr << "Usage: " << argv[0] << " marker.pbm mask.pbm" << std::endl; + return 1; + } + + io::pbm::load(marker, argv[1]); + io::pbm::load(mask, argv[2]); + + io::pbm::save(reconstruction_on_set_by_dilation (marker, mask, c4()), "r1.pbm"); + io::pbm::save(reconstruction_on_set_by_dilation_alt(marker, mask, c4()), "r2.pbm"); + io::pbm::save(reconstruction_on_set_by_erosion (marker, mask, c4()), "r3.pbm"); + io::pbm::save(reconstruction_on_set_by_erosion_alt (marker, mask, c4()), "r4.pbm"); +} Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision 0) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision 3034) @@ -0,0 +1,184 @@ +// 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. + +#ifndef MLN_RECONSTRUCTIONS_ON_FUNCTION_HH +# define MLN_RECONSTRUCTIONS_ON_FUNCTION_HH + +# include <mln/core/image/image2d.hh> +# include <mln/core/alias/neighb2d.hh> +# include <mln/level/fill.hh> +# include <mln/level/compare.hh> +# include <mln/level/paste.hh> +# include <mln/level/sort_psites.hh> +# include <mln/literal/zero.hh> +# include <mln/math/max.hh> +# include <mln/math/min.hh> + +# include "canvas/reconstruction_on_function.hh" + +namespace mln +{ + + namespace impl + { + + template <typename I_, typename J_> + struct reconstruction_on_function_by_dilation_t + { + typedef I_ I; + typedef J_ J; + typedef mln_site(I) P; + typedef p_array<mln_psite(I)> S; + + reconstruction_on_function_by_dilation_t (const I& marker, const J& mask, mln_concrete(I)& output) + : marker(marker), + mask(mask), + output(output), + s(level::sort_psites_decreasing(marker)) + { + } + + bool is_active(const P& p) { return mask(p) >= output(p); } + void set_default_output() { level::fill(output, literal::zero); } + void init(const P& p) { output(p) = marker(p); } + void merge(const P& r, const P& p) { output(p) = math::max(output(p), output(r)); } + void visit_ext_border(const P& n, const P& p) { (void) n; (void) p; } + + void set_output_value(const P& p) + { + if (!is_active(p)) + output(p) = mask(p); + } + + const I& marker; // F + const J& mask; // G + mln_concrete(I)& output; // O + S s; + }; + + + template <typename I_, typename J_> + struct reconstruction_on_function_by_erosion_t + { + typedef I_ I; + typedef J_ J; + typedef mln_site(I) P; + typedef p_array<mln_psite(I)> S; + + reconstruction_on_function_by_erosion_t (const I& marker, const J& mask, mln_concrete(I)& output) + : marker(marker), + mask(mask), + output(output), + s(level::sort_psites_increasing(marker)) + { + } + + bool is_active(const P& p) { return mask(p) <= output(p); } + void set_default_output() { level::fill(output, literal::zero); } + void init(const P& p) { output(p) = marker(p); } + void merge(const P& r, const P& p) { output(p) = math::min(output(p), output(r)); } + void visit_ext_border(const P& n, const P& p) { (void) n; (void) p; } + + void set_output_value(const P& p) + { + if (!is_active(p)) + output(p) = mask(p); + } + + const I& marker; // F + const J& mask; // G + mln_concrete(I)& output; // O + S s; + }; + + + } // end of namespace mln::impl. + + template <typename I, typename J, typename N> + mln_concrete(I) + reconstruction_on_function_by_dilation(const Image<I>& marker_, + const Image<J>& mask_, + const Neighborhood<N>& nbh_) + { + trace::entering("morpho::reconstruction_on_function_by_dilation"); + + const I& marker = exact(marker_); + const J& mask = exact(mask_); + const N& nbh = exact(nbh_); + + mln_precondition(marker.has_data()); + mln_precondition(mask.has_data()); + mln_precondition(mask.domain() == marker.domain()); + + mln_concrete(I) output; + initialize(output, marker); + + typedef impl::reconstruction_on_function_by_dilation_t<I, J> F; + F f(marker, mask, output); + canvas::morpho::reconstruction_on_function(nbh, f); + + mln_precondition(marker <= output && output <= mask); + + trace::exiting("morpho::reconstruction_on_function_by_dilation"); + return output; + } + + + template <typename I, typename J, typename N> + mln_concrete(I) + reconstruction_on_function_by_erosion(const Image<I>& marker_, + const Image<J>& mask_, + const Neighborhood<N>& nbh_) + { + trace::entering("morpho::reconstruction_on_function_by_dilation"); + + const I& marker = exact(marker_); + const J& mask = exact(mask_); + const N& nbh = exact(nbh_); + + mln_precondition(marker.has_data()); + mln_precondition(mask.has_data()); + mln_precondition(mask.domain() == marker.domain()); + + mln_concrete(I) output; + initialize(output, marker); + + typedef impl::reconstruction_on_function_by_erosion_t<I, J> F; + F f(marker, mask, output); + canvas::morpho::reconstruction_on_function(nbh, f); + + mln_precondition(marker >= output && output >= mask); + + trace::exiting("morpho::reconstruction_on_function_by_dilation"); + return output; + } + +} // end of namespace mln. + + +#endif // ! MLN_RECONSTRUCTIONS_ON_FUNCTION_HH Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.cc =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.cc (revision 0) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.cc (revision 3034) @@ -0,0 +1,63 @@ +// 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. + +# include "reconstructions_on_function.hh" +# include <mln/core/alias/neighb2d.hh> +# include <mln/core/image/image2d.hh> +# include <mln/value/int_u8.hh> +# include <mln/io/pgm/load.hh> +# include <mln/io/pgm/save.hh> + +void usage(char** argv) +{ + std::cerr << "Usage: " << argv[0] << " (-dilation|-erosion) marker.pgm mask.pgm" << std::endl; + exit(1); +} + +int main(int argc, char** argv) +{ + using namespace mln; + + if (argc < 2) + usage(argv); + + typedef image2d<value::int_u8> I; + I marker; + I mask; + I output; + + io::pgm::load(marker, argv[2]); + io::pgm::load(mask, argv[3]); + + if (std::string(argv[1]) == "-dilation") + io::pgm::save(reconstruction_on_function_by_dilation(marker, mask, c4()), "r_dilation.pgm"); + else if (std::string(argv[1]) == "-erosion") + io::pgm::save(reconstruction_on_function_by_erosion (marker, mask, c4()), "r_erosion.pgm"); + else + usage(argv); +} Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.hh (revision 0) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.hh (revision 3034) @@ -0,0 +1,220 @@ +// 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. + +#ifndef MLN_RECONSTRUCTIONS_ON_SET_HH +# define MLN_RECONSTRUCTIONS_ON_SET_HH + +# include <mln/core/image/image2d.hh> +# include <mln/core/alias/neighb2d.hh> +# include <mln/level/fill.hh> +# include <mln/level/paste.hh> + +# include "canvas/reconstruction_on_set.hh" + +namespace mln +{ + + namespace impl + { + + struct reconstruction_on_set_by_dilation_t + { + typedef image2d<bool> I; + typedef mln_site_(I) P; + + reconstruction_on_set_by_dilation_t (const I& marker, const I& mask, I& output) + : marker(marker), mask(mask), output(output) + {} + + bool is_in_D(P p) { return mask(p); } + void set_default_output() { level::fill(output, false); } + void init(P p) { output(p) = marker(p); } + void merge(P r, P p) { output(p) = output(p) || output(r); } + void visit_ext_border(P n, P p) { (void) n; (void) p; } + + const I& marker; // F + const I& mask; // G + I& output; // O + }; + + + struct reconstruction_on_set_by_dilation_alt_t + { + typedef image2d<bool> I; + typedef mln_site_(I) P; + + reconstruction_on_set_by_dilation_alt_t (const I& marker, const I& mask, I& output) + : marker(marker), mask(mask), output(output) + {} + + bool is_in_D(P p) { return mask(p) && !marker(p); } + void set_default_output() { level::paste(marker, output); } + void init(P p) { output(p) = false; } + void merge(P r, P p) { output(p) = output(p) || output(r); } + void visit_ext_border(P n, P p) { if (marker(n)) output(p) = true; } + + const I& marker; // F + const I& mask; // G + I& output; // O + }; + + + struct reconstruction_on_set_by_erosion_t + { + typedef image2d<bool> I; + typedef mln_site_(I) P; + + reconstruction_on_set_by_erosion_t (const I& marker, const I& mask, I& output) + : marker(marker), mask(mask), output(output) + {} + + bool is_in_D(P p) { return !mask(p); } + void set_default_output() { level::fill(output, true); } + void init(P p) { output(p) = marker(p); } + void merge(P r, P p) { output(p) = output(p) && output(r); } + void visit_ext_border(P n, P p) { (void) n; (void) p; } + + const I& marker; // F + const I& mask; // G + I& output; // O + }; + + struct reconstruction_on_set_by_erosion_alt_t + { + typedef image2d<bool> I; + typedef mln_site_(I) P; + + reconstruction_on_set_by_erosion_alt_t (const I& marker, const I& mask, I& output) + : marker(marker), mask(mask), output(output) + {} + + bool is_in_D(P p) { return !mask(p) && marker(p); } + void set_default_output() { level::paste(mask, output); } + void init(P p) { output(p) = true; } + void merge(P r, P p) { output(p) = output(p) && output(r); } + void visit_ext_border(P n, P p) { if (!marker(n)) output(p) = false; } + + const I& marker; // F + const I& mask; // G + I& output; // O + }; + + } // end of namespace mln::impl + + + image2d<bool> + reconstruction_on_set_by_dilation(const image2d<bool>& marker, + const image2d<bool>& mask, + const neighb2d& nbh) + { + trace::entering("morpho::reconstruction_on_set_by_dilation"); + + mln_precondition(exact(marker).has_data()); + mln_precondition(exact(mask).has_data()); + + image2d<bool> output; + initialize(output, marker); + + typedef impl::reconstruction_on_set_by_dilation_t F; + F f(marker, mask, output); + canvas::morpho::reconstruction_on_set(nbh, f); + + trace::exiting("morpho::reconstruction_on_set_by_dilation"); + return output; + } + + + image2d<bool> + reconstruction_on_set_by_dilation_alt(const image2d<bool>& marker, + const image2d<bool>& mask, + const neighb2d& nbh) + { + trace::entering("morpho::reconstruction_on_set_by_dilation_alt"); + + mln_precondition(exact(marker).has_data()); + mln_precondition(exact(mask).has_data()); + + image2d<bool> output; + initialize(output, marker); + + typedef impl::reconstruction_on_set_by_dilation_alt_t F; + F f(marker, mask, output); + canvas::morpho::reconstruction_on_set(nbh, f); + + trace::exiting("morpho::reconstruction_on_set_by_dilation_alt"); + return output; + } + + + image2d<bool> + reconstruction_on_set_by_erosion(const image2d<bool>& marker, + const image2d<bool>& mask, + const neighb2d& nbh) + { + trace::entering("morpho::reconstruction_on_set_by_erosion"); + + mln_precondition(exact(marker).has_data()); + mln_precondition(exact(mask).has_data()); + + image2d<bool> output; + initialize(output, marker); + + typedef impl::reconstruction_on_set_by_erosion_t F; + F f(marker, mask, output); + canvas::morpho::reconstruction_on_set(nbh, f); + + trace::exiting("morpho::reconstruction_on_set_by_erosion"); + return output; + } + + + image2d<bool> + reconstruction_on_set_by_erosion_alt(const image2d<bool>& marker, + const image2d<bool>& mask, + const neighb2d& nbh) + { + trace::entering("morpho::reconstruction_on_set_by_erosion_alt"); + + mln_precondition(exact(marker).has_data()); + mln_precondition(exact(mask).has_data()); + + image2d<bool> output; + initialize(output, marker); + + typedef impl::reconstruction_on_set_by_erosion_alt_t F; + F f(marker, mask, output); + canvas::morpho::reconstruction_on_set(nbh, f); + + trace::exiting("morpho::reconstruction_on_set_by_erosion_alt"); + return output; + } + +} // end of namespace mln. + + +#endif // ! MLN_RECONSTRUCTIONS_ON_SET_HH Index: trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction.hh (deleted) =================================================================== Index: trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision 0) +++ trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision 3034) @@ -0,0 +1,174 @@ +// 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. + +#ifndef MLN_RECONSTRUCTION_ON_FUNCTION_HH +# define MLN_RECONSTRUCTION_ON_FUNCTION_HH + +# include <mln/core/image/image2d.hh> +# include <mln/level/fill.hh> +# include <mln/literal/zero.hh> +# include <mln/convert/to_upper_window.hh> +# include <mln/accu/count.hh> +# include <mln/util/pix.hh> + +# include <mln/core/alias/neighb2d.hh> + +# include <mln/io/pbm/save.hh> +# include <mln/io/pbm/load.hh> + +namespace mln +{ + + + namespace canvas + { + + namespace morpho + { + + template <typename I> + static inline + mln_psite(I) + find_root(I& parent, + const mln_psite(I)& x) + { + if (parent(x) == x) + return x; + else + return parent(x) = find_root(parent, parent(x)); + } + + template <typename N, typename F> + inline + void + reconstruction_on_function_tests(const Neighborhood<N>& nbh_, + F& f) + { + // Static tests. + + // Types of f required. + typedef typename F::I I; + typedef Image<I> I_; + typedef typename F::S S; + + // Attributs of f required. + (void) f.s; + (void) f.mask; + (void) f.marker; + (void) f.output; + + + // Method of F required + typedef mln_site(I) P; + + void (F::*m1)() = & F::set_default_output; + m1 = 0; + bool (F::*m2)(const P&) = & F::is_active; + m2 = 0; + void (F::*m3)(const P&) = & F::init; + m3 = 0; + void (F::*m4)(const P&, const P&) = & F::merge; + m4 = 0; + + // Dynamic tests. + mln_precondition(f.mask.domain() == f.output.domain()); + mln_precondition(f.mask.domain() == f.marker.domain()); + } + + template <typename N, typename F> + void + reconstruction_on_function(const Neighborhood<N>& nbh_, + F& f) + { + trace::entering("canvas::morpho::reconstruction_on_function"); + + // Tests. + reconstruction_on_function_tests(nbh_, f); + + const N& nbh = exact(nbh_); + + // Local type. + typedef typename F::I I; + typedef typename F::S S; + typedef mln_site(I) P; + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, P) parent; + + // init + { + initialize(deja_vu, f.mask); + initialize(parent, f.mask); + + mln::level::fill(deja_vu, false); + f.set_default_output(); + } + + // first pass + { + mln_fwd_piter(S) p(f.s); + mln_niter(N) n(nbh, p); + for_all(p) + { + // Make set. + parent(p) = p; + f.init(p); + + for_all(n) if (f.mask.domain().has(n) && deja_vu(n)) + { + //do_union(n, p); + P r = find_root(parent, n); + if (r != p && f.is_active(r)) + { + f.merge(r, p); + parent(r) = p; + } + } + deja_vu(p) = true; + } + } + + // second pass + { + mln_bkd_piter(S) p(f.s); + for_all(p) + f.set_output_value(p); + } + + trace::exiting("canvas::morpho::reconstruction_on_function"); + } + + + } // end of namespace mln::canvas::morpho + + } // end of namespace mln::canvas + +} // end of namespace mln. + +#endif // ! MLN_RECONSTRUCTION_ON_FUNCTION_HH Index: trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_set.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_set.hh (revision 0) +++ trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_set.hh (revision 3034) @@ -0,0 +1,147 @@ +// 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. + +#ifndef MLN_RECONSTRUCTION_ON_SET_HH +# define MLN_RECONSTRUCTION_ON_SET_HH + +# include <mln/core/image/image2d.hh> +# include <mln/level/fill.hh> +# include <mln/literal/zero.hh> +# include <mln/convert/to_upper_window.hh> +# include <mln/accu/count.hh> +# include <mln/util/pix.hh> + +# include <mln/core/alias/neighb2d.hh> + +# include <mln/io/pbm/save.hh> +# include <mln/io/pbm/load.hh> + +namespace mln +{ + + + namespace canvas + { + + namespace morpho + { + + template <typename I> + static inline + mln_psite(I) + find_root(I& parent, + const mln_psite(I)& x) + { + if (parent(x) == x) + return x; + else + return parent(x) = find_root(parent, parent(x)); + } + + template <typename N, typename F> + void + reconstruction_on_set(const Neighborhood<N>& nbh_, + F& f) + { + trace::entering("canvas::morpho::reconstruction_on_set"); + + const N& nbh = exact(nbh_); + + mln_precondition(f.mask.domain() == f.output.domain()); + + // Local type. + typedef typename F::P P; + typedef typename F::I I; + + // Auxiliary data. + mln_ch_value(I, bool) deja_vu; + mln_ch_value(I, P) parent; + + // init + { + initialize(deja_vu, f.mask); + initialize(parent, f.mask); + + mln::level::fill(deja_vu, false); + f.set_default_output(); // Client initialization. + } + + // first pass + { + mln_fwd_piter(I) p(f.mask.domain()); + mln_niter(N) n(nbh, p); + for_all(p) + { + if (f.is_in_D(p)) + { + // Make set. + parent(p) = p; + f.init(p); + + for_all(n) if (f.mask.domain().has(n)) + { + if (deja_vu(n) && f.is_in_D(n)) + { + //do_union(n, p); + P r = find_root(parent, n); + if (r != p) + { + f.merge(r, p); + parent(r) = p; + } + } + else + // Visit boundaries of D. + f.visit_ext_border(n, p); + } + deja_vu(p) = true; + } + + } + } + + // second pass + { + mln_bkd_piter(I) p(f.mask.domain()); + for_all(p) + if (f.is_in_D(p)) + if (parent(p) != p) // if p is not a root. + f.output(p) = f.output(parent(p)); + } + + trace::exiting("canvas::morpho::reconstruction_on_set"); + } + + + } // end of namespace mln::canvas::morpho + + } // end of namespace mln::canvas + +} // end of namespace mln. + +#endif // ! MLN_RECONSTRUCTION_ON_SET_HH
participants (1)
-
Matthieu Garrigues