r3041: Fix some bugs in reconstructions

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox ChangeLog: 2008-12-13 Matthieu Garrigues <garrigues@lrde.epita.fr> Fix some bugs in reconstructions. * garrigues/union_find/canvas/reconstruction_on_function.hh: . * garrigues/union_find/reconstructions_on_function.cc: . * garrigues/union_find/reconstructions_on_function.hh: . * garrigues/union_find/reconstructions_on_set.cc: . * garrigues/union_find/reconstructions_on_set.hh: . * garrigues/union_find/reunion_avec_theo: . --- canvas/reconstruction_on_function.hh | 35 ++++++++---- reconstructions_on_function.cc | 7 +- reconstructions_on_function.hh | 97 ++++++++++++++++++++++++++--------- reconstructions_on_set.cc | 33 +++++++---- reconstructions_on_set.hh | 6 +- reunion_avec_theo | 1 6 files changed, 129 insertions(+), 50 deletions(-) Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.cc =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.cc (revision 3040) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.cc (revision 3041) @@ -32,6 +32,12 @@ # include <mln/io/pbm/load.hh> # include <mln/io/pbm/save.hh> +void usage(char** argv) +{ + std::cerr << "Usage: " << argv[0] << " (-dilation|-erosion) marker.pbm mask.pbm" << std::endl; + exit(1); +} + int main(int argc, char** argv) { using namespace mln; @@ -41,17 +47,22 @@ image2d<bool> mask; image2d<bool> output; - if (argc < 2) - { - std::cerr << "Usage: " << argv[0] << " marker.pbm mask.pbm" << std::endl; - return 1; - } + if (argc < 3) + usage(argv); - io::pbm::load(marker, argv[1]); - io::pbm::load(mask, argv[2]); + io::pbm::load(marker, argv[2]); + io::pbm::load(mask, argv[3]); - 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"); + if (std::string(argv[1]) == "-dilation") + { + io::pbm::save(reconstruction_on_set_by_dilation (marker, mask, c4()), "r_dilation.pbm"); + io::pbm::save(reconstruction_on_set_by_dilation_alt(marker, mask, c4()), "r_dilation_alt.pbm"); + } + else if (std::string(argv[1]) == "-erosion") + { + io::pbm::save(reconstruction_on_set_by_erosion (marker, mask, c4()), "r_erosion.pbm"); + io::pbm::save(reconstruction_on_set_by_erosion_alt (marker, mask, c4()), "r_erosion_alt.pbm"); + } + else + usage(argv); } Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision 3040) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.hh (revision 3041) @@ -31,6 +31,7 @@ # include <mln/core/image/image2d.hh> # include <mln/core/alias/neighb2d.hh> +# include <mln/core/routine/clone.hh> # include <mln/level/fill.hh> # include <mln/level/compare.hh> # include <mln/level/paste.hh> @@ -38,6 +39,7 @@ # include <mln/literal/zero.hh> # include <mln/math/max.hh> # include <mln/math/min.hh> +# include <mln/accu/max.hh> # include "canvas/reconstruction_on_function.hh" @@ -63,17 +65,8 @@ { } - 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); } + bool is_active(const P& p) { return output(p) <= mask(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 @@ -99,16 +92,7 @@ } 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 @@ -134,6 +118,7 @@ mln_precondition(marker.has_data()); mln_precondition(mask.has_data()); mln_precondition(mask.domain() == marker.domain()); + mln_precondition(marker <= mask); mln_concrete(I) output; initialize(output, marker); @@ -142,7 +127,8 @@ F f(marker, mask, output); canvas::morpho::reconstruction_on_function(nbh, f); - mln_precondition(marker <= output && output <= mask); +// mln_postcondition(marker <= output); +// mln_postcondition(output <= mask); trace::exiting("morpho::reconstruction_on_function_by_dilation"); return output; @@ -155,7 +141,7 @@ const Image<J>& mask_, const Neighborhood<N>& nbh_) { - trace::entering("morpho::reconstruction_on_function_by_dilation"); + trace::entering("morpho::reconstruction_on_function_by_erosion"); const I& marker = exact(marker_); const J& mask = exact(mask_); @@ -164,6 +150,7 @@ mln_precondition(marker.has_data()); mln_precondition(mask.has_data()); mln_precondition(mask.domain() == marker.domain()); + mln_precondition(marker >= mask); mln_concrete(I) output; initialize(output, marker); @@ -172,12 +159,76 @@ F f(marker, mask, output); canvas::morpho::reconstruction_on_function(nbh, f); - mln_precondition(marker >= output && output >= mask); + mln_postcondition(marker >= output && output >= mask); - trace::exiting("morpho::reconstruction_on_function_by_dilation"); + trace::exiting("morpho::reconstruction_on_function_by_erosion"); return output; } + + template <typename I, typename J, typename N> + mln_concrete(I) + reconstruction_on_function_by_dilation_slow(const Image<I>& marker_, + const Image<J>& mask_, + const Neighborhood<N>& nbh_) + { + trace::entering("morpho::reconstruction_on_function_by_dilation_slow"); + + + 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_precondition(marker <= mask); + + typedef mln_concrete(I) O; + O output = clone(marker); + O output1 = clone(marker); + O* cur = &output; + O* prev = &output1; + + accu::max<mln_value(O)> max; + + mln_piter(I) p(output.domain()); + mln_niter(N) n(nbh, p); + + bool modif = true; + unsigned i = 0; + while (modif) + { + modif = false; + for_all(p) + { + max.take_as_init((*prev)(p)); + for_all(n) + max.take((*prev)(n)); + + (*cur)(p) = (*prev)(p); + if (max.to_result() == (*cur)(p) || (*cur)(p) == mask(p)) + continue; + + modif = true; + if (max.to_result() < mask(p)) + (*cur)(p) = max.to_result(); + else + (*cur)(p) = mask(p); + } + + // swap + O* tmp = cur; + cur = prev; + prev = tmp; + } + + mln_postcondition(marker <= (*cur)); + mln_postcondition((*cur) <= mask); + + trace::exiting("morpho::reconstruction_on_function_by_dilation_slow"); + return output; + } } // end of namespace mln. Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.cc =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.cc (revision 3040) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_function.cc (revision 3041) @@ -43,7 +43,7 @@ { using namespace mln; - if (argc < 2) + if (argc < 3) usage(argv); typedef image2d<value::int_u8> I; @@ -55,7 +55,10 @@ 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"); + { + io::pgm::save(reconstruction_on_function_by_dilation(marker, mask, c8()), "r_dilation.pgm"); +// io::pgm::save(reconstruction_on_function_by_dilation_slow(marker, mask, c8()), "r_dilation_ref.pgm"); + } else if (std::string(argv[1]) == "-erosion") io::pgm::save(reconstruction_on_function_by_erosion (marker, mask, c4()), "r_erosion.pgm"); else Index: trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.hh (revision 3040) +++ trunk/milena/sandbox/garrigues/union_find/reconstructions_on_set.hh (revision 3041) @@ -33,6 +33,7 @@ # include <mln/core/alias/neighb2d.hh> # include <mln/level/fill.hh> # include <mln/level/paste.hh> +# include <mln/level/compare.hh> # include "canvas/reconstruction_on_set.hh" @@ -136,7 +137,7 @@ mln_precondition(exact(marker).has_data()); mln_precondition(exact(mask).has_data()); - + mln_precondition(exact(marker) <= exact(mask)); image2d<bool> output; initialize(output, marker); @@ -158,6 +159,7 @@ mln_precondition(exact(marker).has_data()); mln_precondition(exact(mask).has_data()); + mln_precondition(exact(marker) <= exact(mask)); image2d<bool> output; initialize(output, marker); @@ -180,6 +182,7 @@ mln_precondition(exact(marker).has_data()); mln_precondition(exact(mask).has_data()); + mln_precondition(exact(marker) <= exact(mask)); image2d<bool> output; initialize(output, marker); @@ -202,6 +205,7 @@ mln_precondition(exact(marker).has_data()); mln_precondition(exact(mask).has_data()); + mln_precondition(exact(marker) <= exact(mask)); image2d<bool> output; initialize(output, marker); Index: trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh =================================================================== --- trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision 3040) +++ trunk/milena/sandbox/garrigues/union_find/canvas/reconstruction_on_function.hh (revision 3041) @@ -39,6 +39,7 @@ # include <mln/core/alias/neighb2d.hh> # include <mln/io/pbm/save.hh> +# include <mln/io/pgm/save.hh> # include <mln/io/pbm/load.hh> namespace mln @@ -85,15 +86,10 @@ // Method of F required typedef mln_site(I) P; - - void (F::*m1)() = & F::set_default_output; + bool (F::*m1)(const P&) = & F::is_active; m1 = 0; - bool (F::*m2)(const P&) = & F::is_active; + void (F::*m2)(const P&, const P&) = & F::merge; 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()); @@ -116,6 +112,7 @@ typedef typename F::I I; typedef typename F::S S; typedef mln_site(I) P; + typedef mln_value(I) V; // Auxiliary data. mln_ch_value(I, bool) deja_vu; @@ -127,7 +124,7 @@ initialize(parent, f.mask); mln::level::fill(deja_vu, false); - f.set_default_output(); + level::fill(f.output, f.marker); } // first pass @@ -138,17 +135,22 @@ { // 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)) + if (r != p) + if (f.mask(r) == f.mask(p) or f.is_active(r)) { - f.merge(r, p); parent(r) = p; + // f.merge(r, p); + if (f.output(r) > f.output(p)) + f.output(p) = f.output(r); // increasing criterion } + else + f.output(p) = mln_max(V); + } deja_vu(p) = true; } @@ -158,7 +160,16 @@ { mln_bkd_piter(S) p(f.s); for_all(p) - f.set_output_value(p); + { + if (parent(p) == p) // if p is a root. + { + if (f.output(p) == mln_max(V)) + f.output(p) = f.mask(p); + } + else + f.output(p) = f.output(parent(p)); + + } } trace::exiting("canvas::morpho::reconstruction_on_function"); Index: trunk/milena/sandbox/garrigues/union_find/reunion_avec_theo =================================================================== --- trunk/milena/sandbox/garrigues/union_find/reunion_avec_theo (revision 3040) +++ trunk/milena/sandbox/garrigues/union_find/reunion_avec_theo (revision 3041) @@ -13,7 +13,6 @@ si on est fast ou pas. - * Pour les opérateur auto duaux Coder la reconstruction auto duale (Rapide).
participants (1)
-
Matthieu Garrigues