
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Update segmentation code. * theo/color/segment.cc: Rename as... * theo/color/segment_rgb_edges.cc: ...this. Update. * theo/color/segment_debase.cc: Rename as... * theo/color/segment_gl_pixels.cc: ...this. Update. * theo/color/segment.hh (filter): Add change_kind. * theo/color/change_attributes.hh (extinct_attributes, move_down_attributes): Use echo. (fuse_down_attributes): Use echo. change_attributes.hh | 94 +++++++++++++++++++++++++++++++++++++-------------- segment.hh | 27 +++++++++++++- segment_gl_pixels.cc | 32 ++++++++++++----- segment_rgb_edges.cc | 66 ++++++++++++++++++++--------------- 4 files changed, 154 insertions(+), 65 deletions(-) Index: theo/color/segment.hh --- theo/color/segment.hh (revision 3312) +++ theo/color/segment.hh (working copy) @@ -329,8 +329,11 @@ mln_concrete(F) filter(const F& f, // a "gradient" of color image const N& nbh, + const A& a_, // an attribute + unsigned change_kind, bool do_extinction, + unsigned n_objects, bool echo = false) { @@ -350,8 +353,25 @@ debug::println("a = ", a); } + switch (change_kind) + { + case 0: + break; + case 1: + std::cout << "move down attributes" << std::endl; + move_down_attributes(t, a, echo); + break; + case 2: + std::cout << "fuse up attributes" << std::endl; + fuse_down_attributes(t, a, echo); + break; + } + if (do_extinction) - extinct_attributes(t, a); + { + std::cout << "do extinction" << std::endl; + extinct_attributes(t, a, echo); + } if (echo) debug::println("a' =", a | t.nodes()); @@ -362,10 +382,13 @@ less, lambda, // output echo); - if (do_extinction == false) + if (do_extinction == false && change_kind == 0) + { + std::cout << "testing filter result v. classical method" << std::endl; test_filter(a_, lambda, f, g, nbh, n_objects, less, echo); + } return g; } Index: theo/color/segment_rgb_edges.cc --- theo/color/segment_rgb_edges.cc (revision 3312) +++ theo/color/segment_rgb_edges.cc (working copy) @@ -22,10 +22,11 @@ #include <mln/morpho/dilation.hh> #include <mln/morpho/erosion.hh> #include <mln/morpho/meyer_wst.hh> - +#include <mln/labeling/compute.hh> #include <mln/accu/count.hh> #include <mln/accu/volume.hh> +#include <mln/accu/mean.hh> #include "sum_pix.hh" @@ -241,8 +242,9 @@ void usage(char* argv[]) { - std::cerr << "usage: " << argv[0] << " input.ppm n extinction output.ppm echo" << std::endl; + std::cerr << "usage: " << argv[0] << " input.ppm n change extinction echo output.ppm" << std::endl; std::cerr << " n >= 2" << std::endl; + std::cerr << " change = 0 (none), 1 (move-down), or 2 (fuse-up)" << std::endl; std::cerr << " extinction = 0 (none) or 1 (effective)" << std::endl; std::cerr << " echo = 0 (mute) or 1 (verbose)" << std::endl; abort(); @@ -256,12 +258,10 @@ using value::int_u8; using value::rgb8; - if (argc != 6) + if (argc != 7) usage(argv); - { - // Color version. // -------------- @@ -269,9 +269,17 @@ image2d<rgb8> input; io::ppm::load(input, argv[1]); + unsigned n_objects = atoi(argv[2]); - bool do_extinction = atoi(argv[3]); + int change_kind = atoi(argv[3]); + if (change_kind < 0 || change_kind > 2) + usage(argv); + + int do_extinction = atoi(argv[4]); + if (do_extinction != 0 && do_extinction != 1) + usage(argv); + bool echo = atoi(argv[5]); @@ -295,7 +303,8 @@ accu::blen_pix<I> a_; f_t g = filter(f, e2e(), - a_, do_extinction, + a_, + change_kind, do_extinction, n_objects, echo); @@ -324,7 +333,7 @@ } image2d<L> w_all = w.unmorph_(); - { + // edges -> squares mln_VAR(w_squares, w_all | is_square); data::paste(morpho::dilation(extend(w_squares, pw::value(w_all)), @@ -335,38 +344,37 @@ data::paste(morpho::erosion(extend(w_points, pw::value(w_all)), c4().win()), w_all); - } - io::pgm::save( level::transform(w_all, convert::to_fun(L_to_int_u8)), - "temp_w_all.pgm" ); - } -// { -// // Gray-level version. + // Outputing. + // ---------- -// image2d<int_u8> f_; -// io::pgm::load(f_, argv[1]); -// unsigned n_objects = atoi(argv[2]); + typedef algebra::vec<3,float> vec3f; -// mln_VAR(f, f_ | is_edge); -// typedef f_t I; + util::array<vec3f> m_3f = labeling::compute(accu::mean<rgb8>(), + input, + full2image(w_all), + nbasins); + m_3f[0] = vec3f::zero; -// typedef p_array<point2d> S; -// S s = level::sort_psites_decreasing(f); + util::array<rgb8> m; + convert::from_to(m_3f, m); -// typedef morpho::tree::data<I,S> tree_t; -// tree_t t(f, s, e2e()); + io::ppm::save( level::transform(w_all, + convert::to< fun::i2v::array<rgb8> >(m) ), + argv[6] ); -// accu::count< util::pix<I> > a_; -// mln_VAR(a, compute_attribute_on_nodes(a_, t)); -// f_t g = filter(a, t, e2e(), n_objects); +// debug::println("input_", input_); +// debug::println("w_squares", w_squares); -// unsigned nbasins; -// debug::println("wst =", morpho::meyer_wst(g, e2e(), nbasins)); -// } +// FIXME: The code below does not work! +// util::array<vec3f> m_3f = labeling::compute(accu::mean<rgb8>(), +// input_, +// w_squares, +// nbasins); } Index: theo/color/change_attributes.hh --- theo/color/change_attributes.hh (revision 3312) +++ theo/color/change_attributes.hh (working copy) @@ -96,25 +96,6 @@ } - // Modified version. - - template <typename T, typename I, typename M> - inline - mln_value(I) - extinct_rec__(const T& t, // tree - const I& a, // original attribute image - I& ea, // extincted attribute image - M& mark, - const mln_psite(I)& p) - { - mln_invariant(mark(p) == false); - mark(p) = true; - if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop. - return a(t.parent(p)); // The parent attribute! - return ea(p) = extinct_rec__(t, a, ea, mark, t.parent(p)); - } - - } // end of internal @@ -123,8 +104,15 @@ template <typename T, typename I> void extinct_attributes(const T& t, // Tree. - I& a) // Attribute image. + I& a, // Attribute image. + bool echo = false) + { + if (echo) { + std::cout << "before:" << std::endl; + display_tree_attributes(t, a); + } + typedef mln_site(I) P; typedef mln_value(I) A; // Type of attributes. @@ -148,15 +136,47 @@ } // debug::println(mark | t.nodes()); + + if (echo) + { + std::cout << "after:" << std::endl; + display_tree_attributes(t, a); + } } + /* // Modified version. + // + // The extinction moves down the parent attribute. With the 1st + // experiments, that does not work. Yet, it is better to first modify + // the attributes (move down the parent values) the classically extinct. + + namespace internal + { + + template <typename T, typename I, typename M> + inline + mln_value(I) + extinct_rec__(const T& t, // tree + const I& a, // original attribute image + I& ea, // extincted attribute image + M& mark, + const mln_psite(I)& p) + { + mln_invariant(mark(p) == false); + mark(p) = true; + if (t.parent(p) == p || mark(t.parent(p)) == true) // Stop. + return a(t.parent(p)); // The parent attribute! + return ea(p) = extinct_rec__(t, a, ea, mark, t.parent(p)); + } + + } // end of internal template <typename T, typename I> void - extinct_attributes__(const T& t, // Tree. + extinct_attributes_new(const T& t, // Tree. I& a) // Attribute image. { typedef mln_site(I) P; @@ -188,23 +208,36 @@ // debug::println(mark | t.nodes()); } + */ // Move down. // ---------- - template <typename A, typename T> + template <typename T, typename A> inline void - move_down_attributes(A& a, const T& t) + move_down_attributes(const T& t, A& a, bool echo = false) + { + if (echo) { + std::cout << "before:" << std::endl; + display_tree_attributes(t, a); + } typedef typename T::nodes_t N; mln_fwd_piter(N) n(t.nodes()); for_all(n) a(n) = a(t.parent(n)); + // Test. for_all(n) mln_invariant(a(n) <= a(t.parent(n))); + + if (echo) + { + std::cout << "after:" << std::endl; + display_tree_attributes(t, a); + } } @@ -213,11 +246,16 @@ // Fuse down. // ---------- - template <typename A, typename T> + template <typename T, typename A> inline void - fuse_down_attributes(A& a, const T& t) + fuse_down_attributes(const T& t, A& a, bool echo = false) { + if (echo) + { + std::cout << "before:" << std::endl; + display_tree_attributes(t, a); + } typedef typename T::nodes_t N; mln_fwd_piter(N) n(t.nodes()); for_all(n) @@ -225,6 +263,12 @@ for_all(n) mln_invariant(a(n) <= a(t.parent(n))); + + if (echo) + { + std::cout << "after:" << std::endl; + display_tree_attributes(t, a); + } } Index: theo/color/segment_gl_pixels.cc --- theo/color/segment_gl_pixels.cc (revision 3312) +++ theo/color/segment_gl_pixels.cc (working copy) @@ -17,8 +17,7 @@ #include <mln/morpho/elementary/gradient.hh> #include <mln/morpho/meyer_wst.hh> -#include <mln/accu/volume.hh> -#include "sum_pix.hh" +#include <mln/accu/height.hh> #include "segment.hh" @@ -28,8 +27,10 @@ void usage(char* argv[]) { - std::cerr << "usage: " << argv[0] << " input.pgm n extinction output.ppm echo" << std::endl; + std::cerr << "usage: " << argv[0] << " input.pgm n change extinction echo output.ppm" << std::endl; + std::cerr << "gray-level version on pixels (without edges)" << std::endl; std::cerr << " n >= 2" << std::endl; + std::cerr << " change = 0 (none), 1 (move-down), or 2 (fuse)" << std::endl; std::cerr << " extinction = 0 (none) or 1 (effective)" << std::endl; std::cerr << " echo = 0 (mute) or 1 (verbose)" << std::endl; abort(); @@ -45,20 +46,29 @@ using value::rgb8; - if (argc != 6) + if (argc != 7) usage(argv); // Gray-level debase version. // -------------------------- + typedef image2d<int_u8> I; I input; io::pgm::load(input, argv[1]); unsigned n_objects = atoi(argv[2]); - bool do_extinction = atoi(argv[3]); + + int change_kind = atoi(argv[3]); + if (change_kind < 0 || change_kind > 2) + usage(argv); + + int do_extinction = atoi(argv[4]); + if (do_extinction != 0 && do_extinction != 1) + usage(argv); + bool echo = atoi(argv[5]); @@ -69,7 +79,6 @@ // Changing input into 'f'. I f = morpho::elementary::gradient(input, c4()); - io::pgm::save(f, "temp_f.pgm"); // // granulometry: @@ -79,10 +88,15 @@ // accu::count< util::pix<I> > a_; // accu::sum_pix< util::pix<I> > a_; - accu::volume<I> a_; + // accu::volume<I> a_; + accu::height<I> a_; + + // It seems that both extinction and changing attributes only + // properly works for the 'height' attribute. I g = filter(f, c4(), - a_, do_extinction, + a_, + change_kind, do_extinction, n_objects, echo); @@ -99,5 +113,5 @@ image2d<rgb8> output = level::convert(rgb8(), input); data::fill((output | (pw::value(w) == 0)).rw(), literal::red); - io::ppm::save(output, argv[4]); + io::ppm::save(output, argv[6]); }