milena r1223: Add lebeling algo in sandbox

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-10-02 Guillaume Duhamel <guillaume.duhamel@lrde.epita.fr> Add lebeling algo in sandbox. * labeling_algo.cc: Test file. * labeling_algo.hh: Convert a binary image into mesh_image. --- labeling_algo.cc | 32 ++++-- labeling_algo.hh | 293 +++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 291 insertions(+), 34 deletions(-) Index: trunk/milena/sandbox/duhamel/labeling_algo.cc =================================================================== --- trunk/milena/sandbox/duhamel/labeling_algo.cc (revision 1222) +++ trunk/milena/sandbox/duhamel/labeling_algo.cc (revision 1223) @@ -35,9 +35,13 @@ # include <mln/core/neighb2d.hh> # include <mln/value/int_u8.hh> # include <mln/level/fill.hh> +# include <mln/level/saturate.hh> +# include <mln/border/fill.hh> # include <mln/io/pbm/load.hh> +# include <mln/io/pgm/save.hh> # include <mln/labeling/foreground.hh> # include <mln/debug/println.hh> +# include <mln/debug/println_with_border.hh> # include "labeling_algo.hh" int main() @@ -45,18 +49,34 @@ using namespace mln; using value::int_u8; - image2d_b<bool> in = io::pbm::load("../../img/toto.pbm"); + // image2d_b<bool> in = io::pbm::load("../../img/toto.pbm"); + image2d_b<bool> in = io::pbm::load("toto.pbm"); + image2d_b<unsigned> lab(in.domain()); - image2d_b<unsigned> out(in.domain()); + image2d_b<unsigned> inte(in.domain()); + image2d_b<int_u8> out(in.domain()); unsigned n; labeling::foreground(in, c4(), lab, n); - std::cout << n << std::endl; + std::cout << "number of labels = " << n << std::endl; + std::vector<int_u8> vec; image2d_b<int> input(in.domain()); level::fill(input, lab); - debug::println(lab | make::box2d(50, 30)); - out = make_algo (lab, c4 ()); - debug::println(out | make::box2d(50, 30)); + inte = make_algo(lab, c4 ()); + border::fill (inte, 0); + + image2d_b<int_u8> inte2(inte.domain()); + + level::saturate(inte, 1, 255, inte2); + io::pgm::save(inte2, "inte.pgm"); + debug::println_with_border(inte2); + + mesh_p<point2d> m = make::graph_with_no_border(inte2, c4()); + std::cout << "OK" << std::endl; + draw::mesh (out, m, 255, 128); + + debug::println(out); + io::pgm::save(out, "out.pgm"); } Index: trunk/milena/sandbox/duhamel/labeling_algo.hh =================================================================== --- trunk/milena/sandbox/duhamel/labeling_algo.hh (revision 1222) +++ trunk/milena/sandbox/duhamel/labeling_algo.hh (revision 1223) @@ -1,8 +1,138 @@ # include <mln/core/queue_p.hh> # include <mln/core/clone.hh> +# include <mln/debug/println.hh> + + +#include <mln/core/image2d_b.hh> +#include <mln/core/sub_image.hh> +#include <mln/core/neighb2d.hh> +#include <mln/value/int_u8.hh> +#include <mln/io/pgm/load.hh> +#include <mln/debug/println.hh> +#include <mln/util/graph.hh> +#include <mln/core/mesh_p.hh> +#include <mln/core/mesh_psite.hh> +#include <mln/draw/mesh.hh> +#include <mln/core/mesh_image.hh> +#include <mln/accu/mean.hh> +#include <mln/estim/min_max.hh> +#include <algorithm> +#include <utility> +#include <map> +#include <mln/metal/vec.hh> namespace mln { + +// namespace util +// { +// template <typename T> +// struct pair +// { +// pair (T t1, T t2) : +// t1_ (t1), +// t2_ (t2) +// { +// } + +// T t1_; +// T t2_; +// }; + +// template <typename T> +// bool operator == (const pair<T> lhs, const pair<T> rhs) +// { +// if ((lhs.t1_ == rhs.t1_) && (lhs.t2_ == rhs.t2_)) +// return true; +// if ((lhs.t1_ == rhs.t2_) && (lhs.t2_ == rhs.t1_)) +// return true; +// return false; +// } + +// template <typename T> +// bool operator < (const pair<T> lhs, const pair<T> rhs) +// { +// if ((lhs.t1_ + lhs.t2_ * 10 < rhs.t1_ + rhs.t2_ * 10))// && (lhs.t2_ < rhs.t2_)) +// return true; +// return false; +// } + +// } // end of mln::util + + namespace make + { + template <typename I, typename N> + mesh_p<mln_psite(I)> + graph_with_no_border (Image<I>& ima_, + const Neighborhood<N>& nbh) + { + typedef metal::vec<2,float> X; + + typedef mln_value(I) V; + typedef mln_psite(I) P; + + I& ima = exact(ima_); + util::graph<void> gr; + + V min, max; + estim::min_max (ima, min, max); + unsigned nb = max - min + 1; + std::vector<P> v(nb); + std::vector< accu::mean_< metal::vec<2,float> > > tab_mean (nb); + + std::cout << "nb = " << nb << std::endl; + + std::map<std::pair<V, V>, bool> m; + + mln_piter(I) p(ima.domain()); + mln_niter(N) n(nbh, p); + + for_all(p) + { + X x = mln_point(I)(p); + tab_mean[ima(p) - min].take(x); + for_all (n) if (ima.has(n)) + if (ima(p) != ima(n)) + m[std::pair<V, V>(ima(p) - min, ima(n) - min)] = true; + } + + std::cout << "center[0] = " << tab_mean[0].to_result() << std::endl; + std::cout << "center[1] = " << tab_mean[1].to_result() << std::endl; + +// /// test +// v[0] = (make::point2d (0, 0)); +// v[1] = (make::point2d (5, 1)); +// v[2] = (make::point2d (9, 2)); +// v[3] = (make::point2d (0, 6)); +// v[4] = (make::point2d (6, 5)); +// v[5] = (make::point2d (8, 7)); + + + for (unsigned i = min; i <= max; ++i) + { + gr.add_node (); +// std::cout << tab_mean[i].to_result ()[0] +// << std::endl; + v[i - min] = make::point2d ((unsigned)tab_mean[i].to_result ()[1], (unsigned)tab_mean[i].to_result ()[0]); + } + + typename std::map<std::pair<V, V>, bool>::const_iterator it = m.begin (); + for (; it != m.end (); ++it) + { +// gr.print_debug (); +// std::cout << "t1 = " << (*it).first.first << std::endl +// << "t2 = " << (*it).first.second << std::endl +// << std::endl; + + gr.add_edge((*it).first.first, (*it).first.second); + } + + mesh_p<P> res(gr, v); + return res; + } + } // end of mln::make + + template <typename I, typename N> I make_algo (Image<I>& ima_, @@ -10,54 +140,161 @@ { I& ima = exact(ima_); I out = clone(ima_); - queue_p<mln_point (I)> q; - int i; + queue_p<mln_psite(I)> q; - // init + // Init. { - mln_fwd_piter(I) p(ima.domain()); + mln_piter(I) p(ima.domain()); mln_niter(N) n(nbh, p); - for_all (p) - { - if (ima(p) == 0) - for_all(n) - if (ima(n) != 0) + for_all(p) if (ima(p) == 0) + for_all(n) if (ima(n) != 0) { q.push (p); - goto end; + break; } - end: - i = 0; + } + +// // Body. +// { +// while (! q.empty()) +// { +// mln_psite(I) p = q.front(); +// q.pop(); +// mln_invariant(ima(p) == 0); + +// mln_niter(N) n(nbh, p); +// for_all(n) if (ima.has(n)) +// if (out(n) != 0) +// out(p) = out(n); +// else +// if (! q.has(n)) +// q.push(n); +// } +// } + + // Body: alternative version. + { + while (! q.empty()) + { + mln_psite(I) p = q.front(); + q.pop(); + if (out(p) != 0) // p has already been processed so ignore + continue; + + mln_niter(N) n(nbh, p); + for_all(n) if (ima.has(n)) + if (out(n) != 0) + out(p) = out(n); + else + q.push_force(n); // n may already be in the queue, + // yet we then queue again this psite } } - std::cout << "q points = " - << q.npoints () - << std::endl; - //body + return out; + } + + template <typename I, typename N> + I + make_algo_debug (Image<I>& ima_, + const Neighborhood<N>& nbh) { - while (q.npoints ()) + I& ima = exact(ima_); + I out = clone(ima_); + queue_p<mln_psite(I)> q; + + // Init. { + mln_piter(I) p(ima.domain()); + mln_niter(N) n(nbh, p); - mln_point (I) po = q.front (); - q.pop (); - mln_invariant (ima(po) == 0); + for_all(p) if (ima(p) == 0) + for_all(n) if (ima(n) != 0) + { + std::cout << "push : " << p << std::endl; + q.push(p); + break; + } + std::cout << "init => q has " << q.npoints() << " points" + << std::endl; + } - mln_niter(N) ne(nbh, po); - for_all (ne) + // Body. { - if (ima.has(ne)) + while (! q.empty()) { - if (out(ne) != 0) - out(po) = out (ne); + debug::println(out); + mln_psite(I) p = q.front(); + std::cout << "pop : " << p << std::endl; + q.pop(); + mln_invariant(ima(p) == 0); + + mln_niter(N) n(nbh, p); + for_all(n) if (ima.has(n)) + if (out(n) != 0) + out(p) = out(n); else - if (!q.has (ne)) - q.push (ne); - } + if (! q.has(n)) + { + std::cout << "push : " << n << std::endl; + q.push(n); } } } return out; } + + template <typename I, typename N> + I + make_algo_debug2 (Image<I>& ima_, + const Neighborhood<N>& nbh) + { + I& ima = exact(ima_); + I out = clone(ima_); + queue_p<mln_psite(I)> q; + + // Init. + { + mln_piter(I) p(ima.domain()); + mln_niter(N) n(nbh, p); + + for_all(p) if (ima(p) == 0) + for_all(n) if (ima(n) != 0) + { + std::cout << "push : " << p << std::endl; + q.push(p); + break; } + std::cout << "init => q has " << q.npoints() << " points" + << std::endl; + } + + + // Body. + { + while (! q.empty()) + { + debug::println(out); + mln_psite(I) p = q.front(); + std::cout << "pop : " << p << std::endl; + q.pop(); + mln_invariant(ima(p) == 0); + + mln_niter(N) n(nbh, p); + for_all(n) if (ima.has(n)) + if (out(n) != 0) + out(p) = out(n); + else + if (! q.has(n)) + { + std::cout << "push : " << n << std::endl; + q.push(n); + } + } + } + return out; + } + + +} // end of mln
participants (1)
-
Guillaume Duhamel