
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Update Laurent's stuff and new code for Fabien. * theo/igr/segment_2d_t.cc: New. * theo/esiee/laurent/ismm09/extinct_attributes.hh (back_propagate_attributes): New. (extinct_attributes): New argument 'f'. augment echo. * theo/esiee/laurent/ismm09/main.cc: Update. esiee/laurent/ismm09/extinct_attributes.hh | 67 +++++++++++---- esiee/laurent/ismm09/main.cc | 68 +++++++++++---- igr/segment_2d_t.cc | 128 +++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 37 deletions(-) Index: theo/igr/segment_2d_t.cc --- theo/igr/segment_2d_t.cc (revision 0) +++ theo/igr/segment_2d_t.cc (revision 0) @@ -0,0 +1,128 @@ +#include <string> + +#include <mln/core/var.hh> +#include <mln/core/image/image2d.hh> +#include <mln/io/dump/load.hh> +#include <mln/io/pgm/save.hh> + +#include <mln/world/inter_pixel/is_separator.hh> +#include <mln/world/inter_pixel/neighb2d.hh> +#include <mln/world/inter_pixel/display_edge.hh> + +#include <mln/debug/println.hh> +#include <mln/estim/min_max.hh> +#include <mln/value/int_u8.hh> +#include <mln/value/int_u12.hh> +#include <mln/value/label.hh> +#include <mln/level/transform.hh> + +#include <mln/morpho/closing/area.hh> +#include <mln/morpho/watershed/flooding.hh> +#include <mln/accu/mean.hh> +#include <mln/labeling/compute.hh> +#include <mln/arith/div.hh> + + +const float saturation = 0.5; + + +namespace mln +{ + + struct int_u12_from_float : Function_v2v< int_u12_from_float > + { + typedef value::int_u12 result; + result operator()(float f) const + { + mln_precondition(f >= 0.f && f <= 1.f); + unsigned i = f / saturation * 4095; + return i > 4095 ? 4095 : i; + } + }; + + template <typename I> + void debug_println(const std::string& name, const I& input) + { + box2d crop( point2d(100, 180), + point2d(109, 189) ); + debug::println(name, + (input.unmorph_() | crop) + | world::inter_pixel::is_separator()); + } + + template <typename I> + void io_save_edges_int_u12(const I& input, + value::int_u8 bg, + const std::string& filename) + { + mlc_equal(mln_value(I), value::int_u12)::check(); + mln_ch_value(I, value::int_u8) output; + initialize(output, input); + arith::div_cst(input, 16, output); + io::pgm::save(world::inter_pixel::display_edge(output.unmorph_(), + bg, + 3), + filename); + } + +} // mln + + + +int main(int argc, char* argv[]) +{ + using namespace mln; + using namespace world::inter_pixel; + using value::int_u12; + using value::int_u8; + + if (argc != 3) + std::abort(); + + unsigned lambda = atoi(argv[2]); + + image2d<float> df_; + io::dump::load(df_, argv[1]); + mln_VAR(df, df_ | is_separator()); + + { + std::cout << df_.domain() << std::endl; + float min, max; + estim::min_max(df, min, max); + std::cout << "min = " << min << " max = " << max << std::endl; + } + + mln_VAR(d, level::transform(df, int_u12_from_float())); + // debug_println("d", d); + io_save_edges_int_u12(d, 0, "d.pgm"); + + mln_VAR(d_clo, morpho::closing::area(d, e2e(), lambda)); + // debug_println("d_clo", d_clo); + io_save_edges_int_u12(d_clo, 0, "d_clo.pgm"); + + typedef value::label<12> L; + L n_basins; + mln_VAR(w, morpho::watershed::flooding(d_clo, e2e(), n_basins)); + std::cout << "n basins = " << n_basins << std::endl; + // debug_println("w", w); + // io_save_edges_int_u12(w, 0, "w.pgm"); + + typedef accu::mean<int_u12,float,int_u12> A; + util::array<int_u12> m = labeling::compute(A(), d, w, n_basins); + + { + util::array<int_u8> m_(n_basins.next()); + m_[0] = 1; // watershed line <=> 1 + for (unsigned l = 1; l <= n_basins; ++l) + { + m_[l] = m[l] / 16; + if (m_[l] < 2) m_[l] == 2; + // basin <=> 2..255 + } + mln_VAR(d_m, level::transform(w, m_)); + mln_VAR(out, world::inter_pixel::display_edge(d_m.unmorph_(), + 0, // background <=> 0 + 3)); + io::pgm::save(out, "d_m.pgm"); + } +} Index: theo/esiee/laurent/ismm09/extinct_attributes.hh --- theo/esiee/laurent/ismm09/extinct_attributes.hh (revision 3797) +++ theo/esiee/laurent/ismm09/extinct_attributes.hh (working copy) @@ -36,8 +36,30 @@ } - // Attribute Extinction. - // --------------------- + // Back Propagation. + // ----------------- + + template <typename T, typename I> + void + back_propagate_attributes(const T& t, // Tree. + I& a) // Attribute image. + { + // Back-propagate attribute from a node to sites of its + // component. Below, p is a non-node component site and + // parent(p) is a node, that is, the site representative of + // the component p belongs to. + mln_up_site_piter(T) p(t); + for_all(p) + if (! t.is_a_node(p)) + { + mln_assertion(t.is_a_node(t.parent(p))); + a(p) = a(t.parent(p)); + } + } + + + // Attribute Extinction (Vachier's version). + // ----------------------------------------- namespace internal { @@ -56,9 +78,6 @@ const T* t; }; - - // Vachier's version. - template <typename T, typename I, typename M> inline mln_value(I) @@ -78,17 +97,17 @@ } // end of internal - // Vachier's version. - - template <typename T, typename I> + template <typename T, typename I, typename J> void extinct_attributes(const T& t, // Tree. I& a, // Attribute image. + const J& f, // Original image to sort pixels. bool echo = false) { if (echo) { - std::cout << "before:" << std::endl; + std::cout << "extinction input:" << std::endl; + debug::println(a); display_tree_attributes(t, a); } @@ -103,15 +122,15 @@ node_only.t = &t; typedef p_array<P> S; - S s = level::sort_psites_increasing(a | node_only); + S s = level::sort_psites_increasing(f | node_only); -// { -// mln_fwd_piter(S) p(s); -// for_all(p) -// std::cout << p << ' ' << a(p) << " - "; -// std::cout << std::endl -// << std::endl; -// } + if (echo) + { + mln_fwd_piter(S) p(s); + for_all(p) + std::cout << f(p) << ":a" << p << '=' << a(p) << " "; + std::cout << std::endl << std::endl; + } mln_invariant(geom::nsites(a | t.nodes()) == s.nsites()); @@ -127,10 +146,22 @@ if (echo) { - std::cout << "after:" << std::endl; + std::cout << "after extinction on nodes and before back-propagation:" + << std::endl; + debug::println(a); + display_tree_attributes(t, a); + } + + back_propagate_attributes(t, a); + + if (echo) + { + std::cout << "extinction output:" << std::endl; + debug::println(a); display_tree_attributes(t, a); } } + } // mln Index: theo/esiee/laurent/ismm09/main.cc --- theo/esiee/laurent/ismm09/main.cc (revision 3797) +++ theo/esiee/laurent/ismm09/main.cc (working copy) @@ -7,12 +7,15 @@ #include <mln/io/pgm/save.hh> #include <mln/debug/println.hh> -#include <mln/morpho/meyer_wst.hh> +#include <mln/morpho/watershed/flooding.hh> +#include <mln/morpho/tree/compute_attribute_image.hh> +#include <mln/morpho/attribute/height.hh> #include <mln/labeling/compute.hh> #include <mln/accu/count.hh> #include "pseudo_tree.hh" #include "cplx2d.hh" +#include "extinct_attributes.hh" @@ -47,21 +50,23 @@ mln_VAR(g, cplx2d::f_to_g(f) ); debug::println("g:", g); + typedef label_16 L; // <--- Type of labels. + L l_max; // w: watershed labeling on edges. - typedef label_16 L; // <--- Type of labels. - L l_max; - mln_VAR( w, morpho::meyer_wst(g, cplx2d::e2e(), l_max) ); + mln_VAR( w, morpho::watershed::flooding(g, cplx2d::e2e(), l_max) ); + std::cout << "l_max = " << l_max << std::endl; debug::println("w:", w); - mln_VAR( is_w_line, pw::value(w) == pw::cst(0) ); - mln_VAR( g_line, g | is_w_line ); - debug::println("g | line:", g_line); +// mln_VAR( is_w_line, pw::value(w) == pw::cst(0) ); +// mln_VAR( g_line, g | is_w_line ); +// debug::println("g | line:", g_line); + mln_VAR(w_ext, cplx2d::extend_w_edges_to_all_faces(w)); - debug::println("w_ext:", w_ext); +// debug::println("w_ext:", w_ext); // e -> (l1, l2) @@ -85,26 +90,51 @@ // a: array "label -> attribute". typedef unsigned A; // <--- Type of attributes. + util::array<A> a(l_max.next(), 0); - util::array<A> a = labeling::compute(accu::meta::count(), - g, // image of values - w, // image of labels - l_max); + { + typedef p_array<point2d> s_t; + s_t s = level::sort_psites_decreasing(g); // min-tree - util::array<L> l_ = sort_by_increasing_attributes(a, l_max); + typedef morpho::tree::data<g_t,s_t> tree_t; + tree_t t(g, s, cplx2d::e2e()); - { - std::cout << "l_:" << std::endl; + morpho::attribute::height<g_t> a_; + mln_VAR(h, morpho::tree::compute_attribute_image(a_, t)); + debug::println("h | nodes:", h | t.nodes()); + + extinct_attributes(t, h, g); + debug::println("he:", h); + debug::println("he | basins:", h | (pw::value(w) != pw::cst(0))); + + mln_invariant(t.leaves().nsites() == l_max); + + mln_leaf_piter_(tree_t) p(t); + for_all(p) + a[w(p)] = h(p); + + std::cout << "a = " << std::endl; for (unsigned i = 1; i <= l_max; ++i) - std::cout << l_[i] << "(" << a[l_[i]] << ") "; - std::cout << std::endl - << std::endl; + std::cout << i << ':' << a[i] << " "; + std::cout << std::endl << std::endl; + } +// util::array<L> l_ = sort_by_increasing_attributes(a, l_max); + +// { +// std::cout << "l_:" << std::endl; +// for (unsigned i = 1; i <= l_max; ++i) +// std::cout << l_[i] << "(" << a[l_[i]] << ") "; +// std::cout << std::endl +// << std::endl; +// } + + // -> pseudo-tree - compute_pseudo_tree(w_ext, g, l_, a, e_to_l1_l2); +// compute_pseudo_tree(w_ext, g, l_, a, e_to_l1_l2); }