From: Maxime van Noppen <yabo(a)lrde.epita.fr>
To: olena-patches(a)lrde.epita.fr
Subject: r2704: Work on a new classification method based on max_trees
URL:
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena/sandbox
ChangeLog:
2008-10-27 Maxime van Noppen <yabo(a)lrde.epita.fr>
Work on a new classification method based on max_trees.
* max_tree.hh: New.
* v2.cc: New.
---
max_tree.hh | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
v2.cc | 80 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 197 insertions(+)
Index: branches/cleanup-2008/milena/sandbox/classif/max_tree.hh
===================================================================
--- branches/cleanup-2008/milena/sandbox/classif/max_tree.hh (revision 0)
+++ branches/cleanup-2008/milena/sandbox/classif/max_tree.hh (revision 2704)
@@ -0,0 +1,117 @@
+#ifndef MAX_TREE_HH_
+# define MAX_TREE_HH_
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/level/fill.hh>
+# include <mln/util/pix.hh>
+# include <mln/morpho/includes.hh>
+# include <mln/level/sort_psites.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/io/pgm/load.hh>
+# include <mln/core/site_set/p_array.hh>
+
+using namespace mln;
+
+template <typename I, typename N>
+struct max_tree_
+{
+ typedef mln_site(I) point;
+ typedef p_array<point> S;
+
+ // in:
+ const I& f;
+ const N& nbh;
+
+ // aux:
+ S s;
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, point) parent;
+ mln_ch_value(I, point) zpar;
+
+ max_tree_(const I& f, const N& nbh)
+ : f(f),
+ nbh(nbh)
+ {
+ run();
+ }
+
+ void run()
+ {
+ // init
+ {
+ initialize(deja_vu, f);
+ mln::level::fill(deja_vu, false);
+ initialize(parent, f);
+ initialize(zpar, f);
+ s = level::sort_psites_decreasing(f);
+ }
+
+ // first pass
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ make_set(p);
+ for_all(n)
+ if (f.has(n) && deja_vu(n))
+ do_union(n, p);
+ deja_vu(p) = true;
+ }
+ }
+
+ // second pass: canonization
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ {
+ point q = parent(p);
+ if (f(parent(q)) == f(q))
+ parent(p) = parent(q);
+ }
+ }
+
+ } // end of run()
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ zpar(p) = p;
+ }
+
+ bool is_root(const point& p) const
+ {
+ return parent(p) == p;
+ }
+
+ bool is_node(const point& p) const
+ {
+ return is_root(p) || f(parent(p)) != f(p);
+ }
+
+ point find_root(const point& x)
+ {
+ if (zpar(x) == x)
+ return x;
+ else
+ return zpar(x) = find_root(zpar(x));
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ parent(r) = p;
+ zpar(r) = p;
+ }
+ }
+
+};
+
+
+#endif /* !MAX_TREE_HH_ */
Index: branches/cleanup-2008/milena/sandbox/classif/v2.cc
===================================================================
--- branches/cleanup-2008/milena/sandbox/classif/v2.cc (revision 0)
+++ branches/cleanup-2008/milena/sandbox/classif/v2.cc (revision 2704)
@@ -0,0 +1,80 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/histo/data.hh>
+
+#include <mln/value/all.hh>
+
+#include <mln/level/fill.hh>
+#include <mln/geom/all.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/arith/revert.hh>
+#include <mln/core/alias/neighb3d.hh>
+
+#include "min_tree.hh"
+
+using namespace mln;
+
+template <typename I>
+mln::image3d<unsigned>
+fill_histo(const I& ima, int f)
+{
+ const value::int_u8 v = 255 / f; // FIXME
+ image3d<unsigned> histo(v,v,v);
+ level::fill(histo, 0);
+ unsigned i = 0;
+
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ point3d p3(ima(p).red() / f, ima(p).green() / f, ima(p).blue() / f);
+ histo(p3)++;
+ }
+ return histo;
+}
+
+template <typename I, typename N>
+unsigned
+compute_min_tree(const I& ima, const N& nbh)
+{
+ min_tree_<I,N> run(ima, nbh);
+
+ mln_piter(I) p(ima.domain());
+ unsigned nnodes = 0;
+ for_all(p)
+ if (run.is_node(p))
+ ++nnodes;
+
+ return nnodes;
+}
+
+bool usage(int argc, char ** argv)
+{
+ if (argc != 3)
+ {
+ std::cout << "usage: " << argv[0] << " image
div_factor" << std::endl;
+ return false;
+ }
+ return true;
+}
+
+int main(int argc, char* argv[])
+{
+ if (not usage(argc, argv))
+ return 1;
+ image2d<value::rgb8> ima;
+ ima = io::ppm::load<value::rgb8>(argv[1]);
+ const int div_factor = atoi(argv[2]);
+
+ //make histo
+ image3d<unsigned> histo = fill_histo(ima,div_factor);
+
+ //revert histo
+ image3d<unsigned> rhisto = arith::revert(histo);
+
+ // Compute min_tree
+ compute_min_tree(rhisto, c6());
+}