URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-02 Guillaume Duhamel <guillaume.duhamel(a)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