r3051: Finalize reconstructions

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2008-12-15 Matthieu Garrigues <garrigues@lrde.epita.fr> Finalize reconstructions. Add the concept of "escape value". * garrigues/union_find/canvas/reconstruction_on_function.hh: . * garrigues/union_find/canvas/self_dual_reconstruction.hh: . * garrigues/union_find/reconstructions_on_function.hh: . * garrigues/union_find/leveling.cc: Rename as... * garrigues/union_find/self_dual_reconstruction.cc: ...this. * garrigues/union_find/self_dual_reconstruction.hh: . --- canvas/reconstruction_on_function.hh | 4 +- canvas/self_dual_reconstruction.hh | 13 ++++--- reconstructions_on_function.hh | 30 ++++++++++++---- self_dual_reconstruction.cc | 62 +++++++++++++++++++++++++++++++++++ self_dual_reconstruction.hh | 51 ++++++++++++++++++---------- 5 files changed, 126 insertions(+), 34 deletions(-) Index: trunk/milena/sandbox/garrigues/union_find/leveling.cc (deleted) =================================================================== Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision 3050) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision 3051) @@ -55,27 +55,32 @@ typedef I_ I; typedef J_ J; typedef mln_site(I) P; + typedef mln_value(I) V; 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(mask)) + s(level::sort_psites_decreasing(mask)), + escape_value(mln_max(V)) { } - bool is_active(const P& p) { return output(p) <= mask(p); } + bool is_active(const P& r, const P& p) { return output(r) <= mask(p); } + void escape(const P& p) { output(p) = escape_value; } void merge(const P& r, const P& p) { if (output(r) > output(p)) output(p) = output(r); } + const I& marker; // F const J& mask; // G mln_concrete(I)& output; // O S s; + const V escape_value; }; @@ -85,23 +90,31 @@ typedef I_ I; typedef J_ J; typedef mln_site(I) P; + typedef mln_value(I) V; 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)) + s(level::sort_psites_increasing(mask)), + escape_value(mln_min(V)) { } - bool is_active(const P& p) { return mask(p) <= output(p); } - void merge(const P& r, const P& p) { output(p) = math::min(output(p), output(r)); } + bool is_active(const P& r, const P& p) { return output(r) >= mask(p); } + void escape(const P& p) { output(p) = escape_value; } + void merge(const P& r, const P& p) + { + if (output(r) < output(p)) + output(p) = output(r); + } const I& marker; // F const J& mask; // G mln_concrete(I)& output; // O S s; + const V escape_value; }; @@ -131,8 +144,8 @@ F f(marker, mask, output); canvas::morpho::reconstruction_on_function(nbh, f); -// mln_postcondition(marker <= output); -// mln_postcondition(output <= mask); + mln_postcondition(marker <= output); + mln_postcondition(output <= mask); trace::exiting("morpho::reconstruction_on_function_by_dilation"); return output; @@ -163,7 +176,8 @@ F f(marker, mask, output); canvas::morpho::reconstruction_on_function(nbh, f); - mln_postcondition(marker >= output && output >= mask); + mln_postcondition(marker >= output); + mln_postcondition(output >= mask); trace::exiting("morpho::reconstruction_on_function_by_erosion"); return output; Index: trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.cc =================================================================== --- trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.cc (revision 0) +++ trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.cc (revision 3051) @@ -0,0 +1,62 @@ +// 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 <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> +# include <mln/linear/gaussian.hh> + +# include "self_dual_reconstruction.hh" + +void usage(char** argv) +{ + std::cerr << "Usage: " << argv[0] << " input.pgm blur" << std::endl; + exit(1); +} + +int main(int argc, char** argv) +{ + using namespace mln; + + if (argc < 2) + usage(argv); + + typedef image2d<value::int_u8> I; + typedef mln_value_(I) V; + + I input = io::pgm::load<V>(argv[1]); + I output; + + output = linear::gaussian(input, atoi(argv[2])); + io::pgm::save(output, "gaussian.pgm"); + + output = self_dual_reconstruction(output, input, c8()); + io::pgm::save(output, "reconstruction.pgm"); +} Index: trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision 3050) +++ trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision 3051) @@ -147,7 +147,7 @@ f.merge(r, p); } else - f.output(p) = mln_max(V); + f.escape(p); } deja_vu(p) = true; @@ -161,7 +161,7 @@ { if (parent(p) == p) // if p is a root. { - if (f.output(p) == mln_max(V)) + if (f.output(p) == f.escape_value) f.output(p) = f.mask(p); } else Index: trunk/milena/sandbox/garrigues/union_find/canvas/self_dual_reconstruction.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/canvas/self_dual_reconstruction.hh (revision 3050) +++ trunk/milena/sandbox/garrigues/union_find/canvas/self_dual_reconstruction.hh (revision 3051) @@ -144,6 +144,7 @@ for_all(n) if (f.mask.domain().has(n) && deja_vu(n)) { + mln_assertion(f.is_in_d1(n)); //do_union(n, p); P r = find_root(parent, n); if (r != p) @@ -153,13 +154,15 @@ f.d1_merge(r, p); } else - f.output(p) = mln_max(V); + f.d1_escape(p); } deja_vu(p) = true; } } + mln::level::fill(deja_vu, false); + // Body of D2. { mln_fwd_piter(S) p(f.d2_s); @@ -171,6 +174,7 @@ for_all(n) if (f.mask.domain().has(n) && deja_vu(n)) { + mln_assertion(f.is_in_d2(n)); //do_union(n, p); P r = find_root(parent, n); if (r != p) @@ -180,8 +184,7 @@ f.d2_merge(r, p); } else - f.output(p) = mln_max(V); - + f.d2_escape(p); } deja_vu(p) = true; @@ -197,7 +200,7 @@ { if (parent(p) == p) // if p is a root. { - if (f.output(p) == mln_max(V)) + if (f.output(p) == f.d1_escape_value) f.output(p) = f.mask(p); } else @@ -211,7 +214,7 @@ { if (parent(p) == p) // if p is a root. { - if (f.output(p) == mln_max(V)) + if (f.output(p) == f.d2_escape_value) f.output(p) = f.mask(p); } else Index: trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.hh (revision 3050) +++ trunk/milena/sandbox/garrigues/union_find/self_dual_reconstruction.hh (revision 3051) @@ -55,55 +55,68 @@ template <typename I_, typename J_> struct self_dual_reconstruction_t { - // d1 : marker(p) < mask(p) - // d2 : marker(p) > mask(p) + // d1 : marker(p) < mask(p) -> dilation + // d2 : marker(p) > mask(p) -> erosion typedef I_ I; typedef J_ J; typedef mln_site(I) P; + typedef mln_value(I) V; typedef p_array<mln_psite(I)> S; self_dual_reconstruction_t (const I& marker, const J& mask, mln_concrete(I)& output) : marker(marker), mask(mask), - output(output) - // d1_s(level::sort_psites_increasing(mask | (pw::value(marker) > pw::value(mask)))), - // d2_s(level::sort_psites_decreasing(mask | (pw::value(marker) > pw::value(mask)))) - { - S d1, d2; - mln_piter(I) p(mask.domain()); - for_all(p) - { - if (is_in_d1(p)) - d1_s.append(p); - else - if (is_in_d2(p)) - d2_s.append(p); + output(output), + d1_s(level::sort_psites_decreasing(mask | (pw::value(marker) < pw::value(mask)))), + d2_s(level::sort_psites_increasing(mask | (pw::value(marker) > pw::value(mask)))), + d1_escape_value(mln_max(V)), + d2_escape_value(mln_min(V)) + { } + bool is_in_d1(const P& p) { return marker(p) < mask(p); } + bool is_in_d2(const P& p) { return marker(p) > mask(p); } + + + + bool d1_is_active(const P& r, const P& p) + { + mln_assertion(is_in_d1(r) && is_in_d1(p)); + return output(r) <= mask(p); } - bool is_in_d1(const P& p) { return marker(p) < mask(p); } - bool d1_is_active(const P& r, const P& p) { return output(r) <= mask(p); } void d1_merge(const P& r, const P& p) { + mln_assertion(is_in_d1(r) && is_in_d1(p)); if (output(r) > output(p)) output(p) = output(r); } - bool is_in_d2(const P& p) { return marker(p) > mask(p); } - bool d2_is_active(const P& r, const P& p) { return output(r) <= mask(p); } + void d1_escape(const P& p) { output(p) = d1_escape_value; } + + + bool d2_is_active(const P& r, const P& p) + { + mln_assertion(is_in_d2(r) && is_in_d2(p)); + return output(r) >= mask(p); + } + void d2_merge(const P& r, const P& p) { + mln_assertion(is_in_d2(r) && is_in_d2(p)); if (output(r) < output(p)) output(p) = output(r); } + void d2_escape(const P& p) { output(p) = d2_escape_value; } + const I& marker; // F const J& mask; // G mln_concrete(I)& output; // O S d1_s, d2_s; + const V d1_escape_value, d2_escape_value; }; } // end of namespace mln::impl.
participants (1)
-
Matthieu Garrigues