URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-04-16 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Commit my last version of fllt.
* sandbox/garrigues/fllt/compute_level_set_fast.hh: New.
* sandbox/garrigues/fllt/compute_level_set_fast2.hh: New.
* sandbox/garrigues/fllt/debug.hh: .
* sandbox/garrigues/fllt/doc.hh: .
* sandbox/garrigues/fllt/fllt.hh: .
* sandbox/garrigues/fllt/give_confs.cc: New.
* sandbox/garrigues/fllt/local_configurations.hh: New.
* sandbox/garrigues/fllt/lower.hh: .
* sandbox/garrigues/fllt/test.cc: New.
* sandbox/garrigues/fllt/test_fllt2.cc: .
* sandbox/garrigues/fllt/types.hh: .
* sandbox/garrigues/fllt/upper.hh: .
---
compute_level_set_fast.hh | 486 +++++++++++++++++++++++++++++++++++++++++++++
compute_level_set_fast2.hh | 471 +++++++++++++++++++++++++++++++++++++++++++
debug.hh | 83 +++++++
doc.hh | 1
fllt.hh | 49 ----
give_confs.cc | 56 +++++
local_configurations.hh | 144 +++++++++++++
lower.hh | 4
test.cc | 62 +++++
test_fllt2.cc | 4
types.hh | 150 +++++++++++++
upper.hh | 4
12 files changed, 1460 insertions(+), 54 deletions(-)
Index: trunk/milena/sandbox/garrigues/fllt/lower.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/lower.hh (revision 1869)
+++ trunk/milena/sandbox/garrigues/fllt/lower.hh (revision 1870)
@@ -36,6 +36,7 @@
*/
# include <mln/core/neighb2d.hh>
+# include <mln/core/clock_neighb2d.hh>
# include <mln/labeling/regional_minima.hh>
# include <mln/accu/min.hh>
@@ -75,6 +76,9 @@
static const neighb2d& bdr_nbh() { return c8(); }
static const neighb2d& reg_nbh() { return c4(); }
+ static const clock_neighb2d bdr_c_nbh(dpoint2d& dp) { return cc8(dp); }
+ static const clock_neighb2d reg_c_nbh(dpoint2d& dp) { return cc4(dp); }
+
};
} // end of namespace mln::fllt
Index: trunk/milena/sandbox/garrigues/fllt/upper.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/upper.hh (revision 1869)
+++ trunk/milena/sandbox/garrigues/fllt/upper.hh (revision 1870)
@@ -36,6 +36,7 @@
*/
# include <mln/core/neighb2d.hh>
+# include <mln/core/clock_neighb2d.hh>
# include <mln/labeling/regional_maxima.hh>
# include <mln/accu/max.hh>
@@ -74,6 +75,9 @@
static const neighb2d& bdr_nbh() { return c4(); }
static const neighb2d& reg_nbh() { return c8(); }
+
+ static const clock_neighb2d bdr_c_nbh(dpoint2d& dp) { return cc4(dp); }
+ static const clock_neighb2d reg_c_nbh(dpoint2d& dp) { return cc8(dp); }
};
} // end of namespace mln::fllt
Index: trunk/milena/sandbox/garrigues/fllt/types.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/types.hh (revision 1869)
+++ trunk/milena/sandbox/garrigues/fllt/types.hh (revision 1870)
@@ -39,6 +39,12 @@
# include <mln/util/tree.hh>
# include <mln/util/branch_iter_ind.hh>
+
+# define fllt_tree(P, V) mln::util::tree< mln::fllt::fllt_node_elt<P, V> >
+# define fllt_node(P, V) mln::util::tree_node< mln::fllt::fllt_node_elt<P, V>
>
+# define fllt_branch(P, V) mln::util::branch< mln::fllt::fllt_node_elt<P, V>
>
+# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind<
mln::fllt::fllt_node_elt<P, V> >
+
namespace mln
{
namespace fllt
@@ -55,13 +61,147 @@
bool brighter;
};
-# define fllt_tree(P, V) util::tree< fllt_node_elt<P, V> >
-# define fllt_node(P, V) util::tree_node< fllt_node_elt<P, V> >
-# define fllt_branch(P, V) util::branch< fllt_node_elt<P, V> >
-# define fllt_branch_iter_ind(P, V) util::branch_iter_ind< fllt_node_elt<P, V>
>
-
// # define fllt_node(P, V) typename fllt_tree(P, V)::node_t
+
+ class ran_domains
+ {
+ public:
+
+ /// Forward Point_Iterator associated type.
+ typedef mln_fwd_piter_(box2d) fwd_piter;
+
+ /// Backward Point_Iterator associated type.
+ typedef mln_bkd_piter_(box2d) bkd_piter;
+
+ /// Constructor.
+ ran_domains(const box2d& b);
+
+ /// Add a point to a domain.
+ template <char domain>
+ ran_domains& add_to(const point2d& p);
+
+ /// Test if a point belong to a domain.
+ template <char domain>
+ bool belongs_to(const point2d& p) const;
+
+ /// Move a point from a domain to another domain.
+ template <char src, char dest>
+ ran_domains& move_to(const point2d& p);
+
+ /// Clear the image.
+ void clear();
+
+ /// Give the exact bounding box.
+ const box2d& bbox() const;
+
+ /// Give the number of points.
+ unsigned npoints() const;
+
+ /// Hook to the image2d containing the points.
+ sub_image<image2d<value::int_u8>, box2d> image();
+
+ private:
+ image2d<value::int_u8> ima_;
+ unsigned npoints_;
+ accu::bbox<point2d> bb_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ ran_domains::ran_domains(const box2d& b)
+ : ima_(b)
+ {
+ bb_.init();
+ npoints_ = 0;
+
+ level::fill(ima_, false);
+ }
+
+ template <char domain>
+ inline
+ ran_domains&
+ ran_domains::add_to(const point2d& p)
+ {
+ bb_.take(p);
+ ima_(p) = domain;
+ npoints_++;
+ return *this;
+ }
+
+
+ template <char src, char dest>
+ ran_domains&
+ ran_domains::move_to(const point2d& p)
+ {
+ mln_assertion(ima_(p) == src);
+ ima_(p) += dest - src;
+ return *this;
+ }
+
+ template <char domain>
+ inline
+ bool
+ ran_domains::belongs_to(const point2d& p) const
+ {
+ return ima_(p) == domain;
+ }
+
+
+ void
+ ran_domains::clear()
+ {
+ if (npoints_ == 0)
+ return;
+
+ // unsigned bb_nrows = geom::nrows(bb_.to_result());
+ // unsigned ima_nrows = geom::nrows(points_);
+
+ // if (bb_nrows * 3 < ima_nrows * 2)
+ // {
+ // unsigned bb_ncols = geom::ncols(bb_.to_result());
+ // mln_line_piter_(image2d<value::int_u8>) p(bb_.to_result());
+ // for_all(p)
+ // {
+ // level::memset_(ima_, p, false, bb_ncols);
+ // }
+ // }
+ // else
+ level::fill(ima_, false);
+
+ npoints_ = 0;
+ bb_.init();
+ }
+
+
+ inline
+ const box2d&
+ ran_domains::bbox() const
+ {
+ mln_precondition(npoints_ != 0);
+ return bb_.to_result();
+ }
+
+ inline
+ unsigned
+ ran_domains::npoints() const
+ {
+ return npoints_;
+ }
+
+ inline
+ sub_image<image2d<value::int_u8>, box2d>
+ ran_domains::image()
+ {
+ mln_precondition(npoints_ > 0);
+ mln_assertion(ima_.has_data());
+ return ima_ | bb_.to_result();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln::fllt
} // end of namespace mln
Index: trunk/milena/sandbox/garrigues/fllt/doc.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/doc.hh (revision 1869)
+++ trunk/milena/sandbox/garrigues/fllt/doc.hh (revision 1870)
@@ -58,6 +58,7 @@
// gn <- min u(x) x belongs to N.
// R <- R union A
// tag the pixels of A.
+ // Update the number of holes of R.
// 4)
// IF g < gn
Index: trunk/milena/sandbox/garrigues/fllt/compute_level_set_fast2.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/compute_level_set_fast2.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/compute_level_set_fast2.hh (revision 1870)
@@ -0,0 +1,471 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+
+#ifndef MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_FAST_HH
+# define MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_FAST_HH
+
+/*! \file compute_level_set_fast2.hh
+ *
+ * \brief Compute Level Set for Fast level line transform.
+ * Version with one image for A, R, N.
+ *
+ */
+
+# include <mln/core/p_image2d.hh>
+# include <mln/core/image_if_value.hh>
+# include "local_configurations.hh"
+
+# define SET_R 3
+# define SET_A 2
+# define SET_N 1
+
+# define image_sub_if_value image_if_value<const
sub_image<image2d<value::int_u8>, box2d> >
+
+namespace mln
+{
+ namespace fllt_fast
+ {
+ using namespace fllt;
+
+ class fllt::ran_domains;
+
+ template <typename V>
+ void step_fast1 (const image2d<V>& ima,
+ point2d p,
+ V& g,
+ point2d& x0)
+ {
+ //std::cout << "entering step_fast 1" << std::endl;
+ // x0 <- a not tagged local mininum of ima.
+ //std::cout << std::endl << "x0 = " << p <<
std::endl;
+ x0 = p;
+ // g <- u(x0)
+ g = ima(x0);
+ //std::cout << "g = " << g << std::endl;
+ //std::cout << "exiting step_fast 1" << std::endl;
+ }
+
+ void step_fast2 (ran_domains& r_a_n,
+ point2d& x0)
+ {
+ //std::cout << "entering step_fast 2" << std::endl;
+ // R <- {}
+ // N <- {}
+ // A <- {x0}
+ r_a_n.clear();
+ r_a_n.add_to<SET_A>(x0);
+
+
+ //std::cout << "exiting step_fast 2" << std::endl;
+ }
+
+
+ template <typename V, typename F>
+ void step_fast3 (const image2d<V>& u,
+ image2d<bool>& tagged,
+ ran_domains& r_a_n,
+ V& gn,
+ fllt_node(point2d, V)*& current_region,
+ image2d<fllt_node(point2d, V)*>& regions)
+ {
+ static bool finished = false;
+ //std::cout << "entering step_fast 3" << std::endl;
+
+ // Stop the algorithm.
+ if (finished)
+ { finished = false; gn -= 2 * F::inc; return; }
+
+ // N <- N union {x neighbor of a pixel in a\R}
+ //mln_piter(p_image2d<P>) qa(A);
+
+ // p_image2d_fwd_pixter<point2d> qa(A);
+ image_sub_if_value ima(r_a_n.image() | SET_A);
+ mln_assertion(ima.has_data());
+ image_sub_if_value::fwd_piter qa(ima.domain());
+ mln_assertion(ima.has_data());
+ for_all(qa)
+ {
+ mln_assertion(ima.has_data());
+ mln_niter(neighb2d) n(F::reg_nbh(), qa);
+ for_all (n)
+ if (u.has(n) && !r_a_n.belongs_to<SET_R>(n) &&
+ !r_a_n.belongs_to<SET_A>(n))
+ r_a_n.add_to<SET_N>(n);
+ }
+
+ // debug::println(u);
+
+// std::cout << "A :" << A << std::endl;
+// debug::println(A.image());
+// std::cout << "N :" << N << std::endl;
+// debug::println(N.image());
+// std::cout << "R :" << R << std::endl;
+// debug::println(R.image());
+
+ // gn <- min u(x) x belongs to N.
+
+ image_sub_if_value tmp(r_a_n.image() | SET_N);
+ finished = tmp.npoints() == 0;
+
+ if (!finished)
+ gn = level::compute< typename F::accu_for_gn >(u | tmp.domain());
+
+ if (finished)
+ gn += F::inc;
+
+ //std::cout << std::endl << "gN = " << gn <<
std::endl;
+ // R <- R union A
+ // tag the pixels of A.
+
+ for_all(qa)
+ {
+ if (!r_a_n.belongs_to<SET_A>(qa))
+ continue;
+// std::cout << "Added to R" << tmp << std::endl;
+ mln_assertion(!r_a_n.belongs_to<SET_R>(qa));
+ r_a_n.move_to<SET_A, SET_R>(qa);
+ tagged(qa) = true;
+ // Update the number of holes of R.
+ //n_added_holes<point2d, F>(R, qa);
+ }
+
+
+ //std::cout << "exiting step_fast 3" << std::endl;
+ }
+
+
+ template <typename V>
+ void update_set(const image2d<V>& u,
+ ran_domains& r_a_n,
+ V& g)
+ {
+ // A <- {x belongs to N / u(x) == g}
+
+ // This is slow.
+ // A.insert(set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+
+ // N <- N\{x belongs to N / u(x) == g}
+ // N.remove(set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+ // mln_assertion(check_step_4_2(u, N, g));
+
+ // This is faster.
+
+// if (N.npoints() >= 0)
+// {
+ image_sub_if_value tmp(r_a_n.image() | SET_N);
+ image_sub_if_value::fwd_piter qn(tmp.domain());
+ for_all(qn)
+ {
+ if (u(qn) == g)
+ r_a_n.move_to<SET_N, SET_A>(qn);
+ }
+// }
+// else {
+// mln_fwd_piter(p_image2d<P>) p(N);
+// for_all(p)
+// {
+// if (u(p) == g)
+// {
+// A.insert(p);
+// N.remove(p);
+// }
+// }
+// mln_assertion(check_step_4_2(u, N, g));
+// }
+ }
+ /// IF g < gn.
+ template <typename V, typename F>
+ void step_fast4_1 (image2d<V>& u,
+ ran_domains& r_a_n,
+ V& g,
+ V& gn,
+ fllt_node(point2d, V)*& current_region,
+ image2d<fllt_node(point2d, V)*>& regions
+ )
+ {
+// std::cout << "entering step_fast 4_1" << std::endl;
+
+ // If the region is bounded
+ // Create a new conected component.
+ // FIXME : we can make it faster.
+
+ // FIXME : rewrite this test.
+ // if ((R.bbox() < u.domain()) || (R.npoints() == u.domain().npoints()))
+// {
+ image_sub_if_value tmp(r_a_n.image() | SET_R);
+ image_sub_if_value::fwd_piter p(tmp.domain());
+ current_region = new fllt_node(point2d, V)();
+ current_region->elt().brighter = F::parent_is_brighter;
+ current_region->elt().value = g;
+ for_all(p)
+ {
+ current_region->elt().points.insert(p);
+
+ if (regions(p) == 0)
+ {
+ //current_region->elt().points.insert(p);
+ regions(p) = current_region;
+ }
+ else
+ {
+ if (regions(p)->parent() == 0)
+ regions(p)->set_parent(current_region);
+ }
+ }
+
+
+// // Count the number of conected components of the border of R.
+// static image2d<unsigned> tmp(u.domain().to_larger(1));
+// static image2d<bool> border_ima(tmp.domain());
+// level::fill(border_ima, false);
+
+// // level::fill(inplace(border_ima | N), true);
+// // std::cout << "tmp border = " << tmp.border () <<
std::endl;
+// // std::cout << "ima border = " << border_ima.border ()
<< std::endl;
+// mln_piter(p_image2d<P>) z(N);
+// for_all(z)
+// {
+// mln_assertion(border_ima.owns_(z));
+// border_ima(z) = true;
+// }
+// unsigned n;
+// tmp = labeling::level(border_ima, true, F::bdr_nbh(), n);
+
+// // debug::println(border_ima);
+// //std::cout << "nb composantes :" << n << std::endl;
+// // debug::println(tmp);
+// if (n > 1)
+// {
+
+// // IF number of conected components of the border > 1
+// for (int i = 2; i <= n; i++)
+// {
+// // follow each border to find which is the exterior border
+// // and which are the holes. Keep one pixel of each holes.
+
+// // WARNING : We trust labeling::level to label the exterior border with 1.
+// current_region->elt().holes.insert(a_point_of(tmp | pw::value(tmp) ==
pw::cst(i)));
+
+// // FIXME : [optimisation] Remove from N border of holes???.
+// // Recompute gn <- min u(x) x belongs to A
+// }
+// }
+
+
+// }
+
+ g = gn;
+
+ update_set(u, r_a_n, g);
+
+ // std::cout << "A :" << std::endl;
+ // if (A.npoints())
+ // debug::println(u | A);
+ // std::cout << "N :" << std::endl;
+ // if (N.npoints())
+ // debug::println(u | N);
+
+// std::cout << "exiting step_fast 4_1" << std::endl;
+ }
+
+ /// IF g == gn.
+ template <typename V, typename P>
+ void step_fast4_2 (const image2d<V>& u,
+ ran_domains& r_a_n,
+ V& g,
+ fllt_node(P, V)* current_region,
+ image2d<fllt_node(P, V)*>& regions
+ )
+ {
+// std::cout << "entering step_fast 4_2" << std::endl;
+
+ update_set(u,r_a_n,g);
+
+ // std::cout << "A :" << std::endl;
+ // if (A.npoints())
+ // debug::println(u | A);
+ // std::cout << "N :" << std::endl;
+ // if (N.npoints())
+ // debug::println(u | N);
+
+// std::cout << "exiting step_fast 4_2" << std::endl;
+ }
+
+ /// IF g > gn.
+ template <typename V>
+ void step_fast4_3 (image2d<V>& u,
+ const image2d<bool>& tagged,
+ ran_domains& r_a_n,
+ const V& g)
+ {
+// std::cout << "entering step_fast 4_3" << std::endl;
+
+ // set the gray-level of the pixels of R to g.
+ image_sub_if_value tmp(r_a_n.image() | SET_R);
+ image_sub_if_value::fwd_piter p(tmp.domain());
+ for_all(p)
+ {
+ mln_assertion (tagged(p));
+ u (p) = g;
+ }
+// std::cout << "exiting step_fast 4_3" << std::endl;
+
+ }
+
+
+ template <typename V, typename F>
+ fllt_tree(point2d, V)&
+ compute_level_set_fast(const image2d<V>& ima,
+ image2d< fllt_node(point2d, V)* >& regions)
+ {
+ typedef point2d P;
+ typedef image2d<V> I;
+
+ // FIXME: not nice.
+ typedef mln::image_if<
+ mln::image2d<unsigned>,
+ mln::fun::greater_p2b_expr_<mln::pw::value_<mln::image2d<unsigned> >,
+ mln::pw::cst_<int> >
+ > I_IF;
+
+ // Check
+ mln_assertion(ima.domain() == regions.domain());
+
+ // Declarations.
+ ran_domains r_a_n(ima.domain());
+ V g, gn;
+ point2d x0;
+ image2d<unsigned> min_locals(ima.domain());
+ image2d<V> u = clone(ima);
+ border::fill(u, 0);
+
+ //std::cout << "image U:" << std::endl;
+ // debug::println_with_border(u);
+ image2d<bool> tagged(ima.domain());
+ fllt_node(P, V)* current_region;
+
+ // INIT
+ g= 0;
+ gn = 0;
+ current_region = 0;
+
+ level::fill(regions, 0);
+ level::fill(tagged, false);
+
+ // Get the locals extremums
+ unsigned nlabels;
+ min_locals = F::regional_extremum(ima, F::reg_nbh(), nlabels);
+
+ // debug::println(min_locals);
+ // debug::println(min_locals | (pw::value(min_locals) > pw::cst(0)));
+
+ /// Algorithm.
+ {
+ // For all locals extremums
+ I_IF min_locals_list(min_locals | (pw::value(min_locals) > pw::cst(0)));
+ mln_piter(I_IF) p(min_locals_list.domain());
+ int cpt = 0, snapshop = 0;
+ for_all(p)
+ {
+ if (tagged(p))
+ continue;
+
+ //std::cout << "boucle no " << cpt++ << std::endl;
+ step_fast1(ima, p, g, x0);
+ step_fast2(r_a_n, x0);
+ while (1)
+ {
+ // To have a view of the progression of the algotithm.
+#ifdef FLLT_TRACE
+ save_state(ima, r_a_n);
+#endif
+ //std::cout << "g = " << g << std::endl;
+ step_fast3<V, F>(u, tagged, r_a_n, gn, current_region, regions);
+ /// step_fast4.
+ if (F::compare(g, gn))
+ {
+ step_fast4_1<V, F>(u, r_a_n, g, gn, current_region, regions);
+ // GO TO 3)
+ continue;
+ }
+
+
+ if (g == gn)
+ {
+ step_fast4_2(u, r_a_n, g, current_region, regions);
+ // GO TO 3)
+ continue;
+ }
+
+
+ if (!F::compare(g, gn))
+ {
+ step_fast4_3(u, tagged, r_a_n, g);
+ // GO TO 1)
+ break;
+ }
+ }
+ //std::cout << "current_region = " << current_region <<
std::endl;
+ }
+ } // end of Algorithm
+
+ image2d<value::int_u8> output (ima.domain ());
+ fllt_tree(P, V)& tree = *new fllt_tree(P, V)(current_region);
+ util::tree_to_image (tree, output);
+
+ // util::display_tree(ima, tree);
+
+ // debug::println(output);
+ // std::cout << std::endl;
+ // debug::println(ima);
+
+ // if (output != ima)
+ // {
+ // std::cerr << "BUG!!!" << std::endl;
+ // abort();
+ // }
+
+ // io::pgm::save(output, "out.pgm");
+ // std::cout << "out.pgm generate"
+ // << std::endl;
+
+
+ // debug::println(regions);
+ //debug::println(ima | regions(make:defined reference to
`mln::fllt::lower<mln::value::int_u<8u>
>::inc':point2d(-4,-1))->elt().points);
+
+ return (tree);
+
+ } // end of compute_level_set_fast
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_FAST_HH
Index: trunk/milena/sandbox/garrigues/fllt/debug.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/debug.hh (revision 1869)
+++ trunk/milena/sandbox/garrigues/fllt/debug.hh (revision 1870)
@@ -35,6 +35,12 @@
*
*/
+# include <iomanip>
+# include <iostream>
+# include <sstream>
+# include "mln/core/p_image2d.hh"
+# include "mln/literal/all.hh"
+# include "mln/io/ppm/save.hh"
# include "types.hh"
namespace mln
@@ -113,6 +119,83 @@
}
}
+ template <typename P, typename V>
+ void
+ debug(const image2d<V>& ima,
+ fllt_tree(P, V)& result_tree)
+ {
+ std::cout << "4/ Generate outputs." << std::endl;
+
+ image2d<value::int_u8> output (ima.domain ());
+ util::tree_to_image (result_tree, output);
+
+
+ // io::pgm::save(output, "out_final.pgm");
+ // std::cout << "out_final.pgm generate"
+ // << std::endl;
+
+
+ // util::display_tree(ima, lower_tree);
+ draw_tree(ima, result_tree);
+
+ // debug::println(ima);
+ // debug::println(output);
+
+ // if (output != ima)
+ // {
+ // std::cerr << "BUG!!!" << std::endl;
+ // abort();
+ // }
+
+ image2d<value::int_u8> viz(ima.domain());
+ // image2d<value::int_u8> viz2(ima.domain());
+
+ // visualize_deepness(viz, lower_tree);
+ // level::stretch(viz, viz2);
+ // debug::println(viz);
+ // debug::println(viz2);
+ // io::pgm::save(viz2, "fllt.pgm");
+
+ visualize_bounds(viz, result_tree, 200);
+ //debug::println(viz);
+ io::pgm::save(viz, "fllt_bounds_200.pgm");
+
+ visualize_bounds(viz, result_tree, 100);
+ io::pgm::save(viz, "fllt_bounds_100.pgm");
+
+ visualize_bounds(viz, result_tree, 50);
+ io::pgm::save(viz, "fllt_bounds_50.pgm");
+
+ visualize_bounds(viz, result_tree, 20);
+ io::pgm::save(viz, "fllt_bounds_20.pgm");
+
+ }
+
+ template <typename P, typename V>
+ void save_state(const image2d<V>& ima,
+ const p_image2d<P>& R,
+ const p_image2d<P>& A,
+ const p_image2d<P>& N)
+ {
+ static int id = 0;
+ std::stringstream filename;
+ filename << "fllt_trace_" << std::setw(5) <<
std::setfill('0')
+ << std::right << id++ << ".ppm";
+
+ image2d<value::rgb8> out(ima.domain());
+
+ level::fill(out, literal::white);
+
+ if (R.npoints() != 0)
+ level::fill(inplace(out | R), literal::green);
+ if (A.npoints() != 0)
+ level::fill(inplace(out | A), literal::blue);
+ if (N.npoints() != 0)
+ level::fill(inplace(out | N), literal::red);
+
+ io::ppm::save(out, filename.str());
+ }
+
} // end of namespace mln::fllt
} // end of namespace mln
Index: trunk/milena/sandbox/garrigues/fllt/compute_level_set_fast.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/compute_level_set_fast.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/compute_level_set_fast.hh (revision 1870)
@@ -0,0 +1,486 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+
+#ifndef MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_FAST_HH
+# define MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_FAST_HH
+
+/*! \file compute_level_set_fast.hh
+ *
+ * \brief Compute Level Set for Fast level line transform.
+ * Version with three p_image2d for A, R, N.
+ *
+ */
+
+# include <mln/core/p_image2d.hh>
+# include "local_configurations.hh"
+
+namespace mln
+{
+ namespace fllt_fast
+ {
+ using namespace fllt;
+
+ template <typename V>
+ void step_fast1 (const image2d<V>& ima,
+ point2d p,
+ V& g,
+ point2d& x0)
+ {
+ //std::cout << "entering step_fast 1" << std::endl;
+ // x0 <- a not tagged local mininum of ima.
+ //std::cout << std::endl << "x0 = " << p <<
std::endl;
+ x0 = p;
+ // g <- u(x0)
+ g = ima(x0);
+ //std::cout << "g = " << g << std::endl;
+ //std::cout << "exiting step_fast 1" << std::endl;
+ }
+
+ template <typename P>
+ void step_fast2 (p_image2d<P>& A,
+ p_image2d<P>& R,
+ p_image2d<P>& N,
+ point2d& x0)
+ {
+ //std::cout << "entering step_fast 2" << std::endl;
+ // A <- {x0}
+ A.clear();
+ A.insert(x0);
+ // R <- {}
+ R.clear();
+ // N <- {}
+ N.clear();
+ //std::cout << "exiting step_fast 2" << std::endl;
+ }
+
+
+ template <typename V, typename P, typename F>
+ void step_fast3 (const image2d<V>& u,
+ image2d<bool>& tagged,
+ p_image2d<P>& A,
+ p_image2d<P>& R,
+ p_image2d<P>& N,
+ V& gn,
+ fllt_node(P, V)*& current_region,
+ image2d<fllt_node(P, V)*>& regions)
+ {
+ static bool finished = false;
+ //std::cout << "entering step_fast 3" << std::endl;
+
+ // Stop the algorithm.
+ if (finished)
+ { finished = false; gn -= 2 * F::inc; return; }
+
+ // N <- N union {x neighbor of a pixel in a\R}
+ //mln_piter(p_image2d<P>) qa(A);
+
+ // p_image2d_fwd_pixter<point2d> qa(A);
+ p_image2d_fwd_piter_<point2d> qa(A);
+ for_all(qa)
+ {
+ mln_niter(neighb2d) n(F::reg_nbh(), qa);
+ for_all (n)
+ if (u.has(n) && !R.has (n) && !A.has (n))
+ N.insert (n);
+ }
+
+ // debug::println(u);
+
+// std::cout << "A :" << A << std::endl;
+// debug::println(A.image());
+// std::cout << "N :" << N << std::endl;
+// debug::println(N.image());
+// std::cout << "R :" << R << std::endl;
+// debug::println(R.image());
+
+ // gn <- min u(x) x belongs to N.
+
+ finished = N.npoints() == 0;
+
+ if (!finished)
+ gn = level::compute< typename F::accu_for_gn >(u | N);
+ else
+ gn += F::inc;
+
+ //std::cout << std::endl << "gN = " << gn <<
std::endl;
+ // R <- R union A
+ // tag the pixels of A.
+
+ for_all(qa)
+ {
+ point2d tmp = qa;
+// std::cout << "Added to R" << tmp << std::endl;
+ mln_assertion(!R.has(tmp));
+ R.insert(tmp);
+ tagged(tmp) = true;
+ // Update the number of holes of R.
+ //n_added_holes<point2d, F>(R, qa);
+ }
+
+
+ //std::cout << "exiting step_fast 3" << std::endl;
+ }
+
+
+ template <typename V, typename P>
+ void update_set(const image2d<V>& u,
+ p_image2d<P>& A,
+ p_image2d<P>& N,
+ V& g)
+ {
+ // A <- {x belongs to N / u(x) == g}
+ A.clear();
+ mln_assertion(A.is_empty());
+
+ // This is slow.
+ // A.insert(set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+
+ // N <- N\{x belongs to N / u(x) == g}
+ // N.remove(set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+ // mln_assertion(check_step_4_2(u, N, g));
+
+ // This is faster.
+
+// if (N.npoints() >= 0)
+// {
+ p_image2d_fwd_pixter<point2d> pxl(N);
+ for_all(pxl)
+ {
+ point2d tmp = pxl.to_point();
+ if (u(tmp) == g)
+ {
+ A.insert(tmp);
+ N.remove(tmp);
+ }
+ }
+// }
+// else {
+// mln_fwd_piter(p_image2d<P>) p(N);
+// for_all(p)
+// {
+// if (u(p) == g)
+// {
+// A.insert(p);
+// N.remove(p);
+// }
+// }
+// mln_assertion(check_step_4_2(u, N, g));
+// }
+ }
+ /// IF g < gn.
+ template <typename V, typename P, typename F>
+ void step_fast4_1 (image2d<V>& u,
+ p_image2d<P>& A,
+ p_image2d<P>& R,
+ p_image2d<P>& N,
+ V& g,
+ V& gn,
+ fllt_node(P, V)*& current_region,
+ image2d<fllt_node(P, V)*>& regions
+ )
+ {
+// std::cout << "entering step_fast 4_1" << std::endl;
+
+ // If the region is bounded
+ // Create a new conected component.
+ // FIXME : we can make it faster.
+
+ if ((R.bbox() < u.domain()) || (R.npoints() == u.domain().npoints()))
+ {
+ mln_piter(p_image2d<P>) p(R);
+ current_region = new fllt_node(P, V)();
+ current_region->elt().brighter = F::parent_is_brighter;
+ current_region->elt().value = g;
+ for_all(p)
+ {
+ current_region->elt().points.insert(p);
+
+ if (regions(p) == 0)
+ {
+ //current_region->elt().points.insert(p);
+ regions(p) = current_region;
+ }
+ else
+ {
+ if (regions(p)->parent() == 0)
+ regions(p)->set_parent(current_region);
+ }
+ }
+
+
+// // Count the number of conected components of the border of R.
+// static image2d<unsigned> tmp(u.domain().to_larger(1));
+// static image2d<bool> border_ima(tmp.domain());
+// level::fill(border_ima, false);
+
+// // level::fill(inplace(border_ima | N), true);
+// // std::cout << "tmp border = " << tmp.border () <<
std::endl;
+// // std::cout << "ima border = " << border_ima.border ()
<< std::endl;
+// mln_piter(p_image2d<P>) z(N);
+// for_all(z)
+// {
+// mln_assertion(border_ima.owns_(z));
+// border_ima(z) = true;
+// }
+// unsigned n;
+// tmp = labeling::level(border_ima, true, F::bdr_nbh(), n);
+
+// // debug::println(border_ima);
+// //std::cout << "nb composantes :" << n << std::endl;
+// // debug::println(tmp);
+// if (n > 1)
+// {
+
+// // IF number of conected components of the border > 1
+// for (int i = 2; i <= n; i++)
+// {
+// // follow each border to find which is the exterior border
+// // and which are the holes. Keep one pixel of each holes.
+
+// // WARNING : We trust labeling::level to label the exterior border with 1.
+// current_region->elt().holes.insert(a_point_of(tmp | pw::value(tmp) ==
pw::cst(i)));
+
+// // FIXME : [optimisation] Remove from N border of holes???.
+// // Recompute gn <- min u(x) x belongs to A
+// }
+// }
+
+ }
+
+ g = gn;
+
+ update_set(u,A,N,g);
+
+ // std::cout << "A :" << std::endl;
+ // if (A.npoints())
+ // debug::println(u | A);
+ // std::cout << "N :" << std::endl;
+ // if (N.npoints())
+ // debug::println(u | N);
+
+// std::cout << "exiting step_fast 4_1" << std::endl;
+ }
+
+
+ template <typename V, typename P>
+ bool check_step_4_2(const image2d<V>& u,
+ p_image2d<P>& N,
+ V& g)
+ {
+ mln_fwd_piter(p_image2d<P>) p(N);
+ for_all(p)
+ {
+ mln_assertion(u(p) != g);
+ }
+ return true;
+ }
+
+
+ /// IF g == gn.
+ template <typename V, typename P>
+ void step_fast4_2 (const image2d<V>& u,
+ p_image2d<P>& A,
+ p_image2d<P>& N,
+ V& g,
+ fllt_node(P, V)* current_region,
+ image2d<fllt_node(P, V)*>& regions
+ )
+ {
+// std::cout << "entering step_fast 4_2" << std::endl;
+
+ update_set(u,A,N,g);
+
+ // std::cout << "A :" << std::endl;
+ // if (A.npoints())
+ // debug::println(u | A);
+ // std::cout << "N :" << std::endl;
+ // if (N.npoints())
+ // debug::println(u | N);
+
+// std::cout << "exiting step_fast 4_2" << std::endl;
+ }
+
+ /// IF g > gn.
+ template <typename V, typename P>
+ void step_fast4_3 (image2d<V>& u,
+ const image2d<bool>& tagged,
+ const p_image2d<P>& R,
+ const V& g)
+ {
+// std::cout << "entering step_fast 4_3" << std::endl;
+
+ // set the gray-level of the pixels of R to g.
+ mln_piter(p_image2d<P>) p(R);
+ for_all(p)
+ {
+ mln_assertion (tagged(p));
+ u (p) = g;
+ }
+// std::cout << "exiting step_fast 4_3" << std::endl;
+
+ }
+
+
+ template <typename V, typename F>
+ fllt_tree(point2d, V)&
+ compute_level_set_fast(const image2d<V>& ima,
+ image2d< fllt_node(point2d, V)* >& regions)
+ {
+ typedef point2d P;
+ typedef image2d<V> I;
+
+ // FIXME: not nice.
+ typedef mln::image_if<
+ mln::image2d<unsigned>,
+ mln::fun::greater_p2b_expr_<mln::pw::value_<mln::image2d<unsigned> >,
+ mln::pw::cst_<int> >
+ > I_IF;
+
+ // Check
+ mln_assertion(ima.domain() == regions.domain());
+
+ // Declarations.
+ p_image2d<P> R(ima.domain()),
+ N(ima.domain()),
+ A(ima.domain());
+
+ V g, gn;
+ point2d x0;
+ image2d<unsigned> min_locals(ima.domain());
+ image2d<V> u = clone(ima);
+ border::fill(u, 0);
+
+ //std::cout << "image U:" << std::endl;
+ // debug::println_with_border(u);
+ image2d<bool> tagged(ima.domain());
+ fllt_node(P, V)* current_region;
+
+ // INIT
+ R.clear();
+ N.clear();
+ A.clear();
+ g= 0;
+ gn = 0;
+ current_region = 0;
+
+ level::fill(regions, 0);
+ level::fill(tagged, false);
+
+ // Get the locals extremums
+ unsigned nlabels;
+ min_locals = F::regional_extremum(ima, F::reg_nbh(), nlabels);
+
+ // debug::println(min_locals);
+ // debug::println(min_locals | (pw::value(min_locals) > pw::cst(0)));
+
+ /// Algorithm.
+ {
+ // For all locals extremums
+ I_IF min_locals_list(min_locals | (pw::value(min_locals) > pw::cst(0)));
+ mln_piter(I_IF) p(min_locals_list.domain());
+ int cpt = 0, snapshop = 0;
+ for_all(p)
+ {
+ if (tagged(p))
+ continue;
+
+ //std::cout << "boucle no " << cpt++ << std::endl;
+ step_fast1(ima, p, g, x0);
+ step_fast2(A, R, N, x0);
+ mln_assertion(R.is_empty() && N.is_empty());
+ while (1)
+ {
+ // To have a view of the progression of the algotithm.
+#ifdef FLLT_TRACE
+ save_state(ima, R, A, N);
+#endif
+ //std::cout << "g = " << g << std::endl;
+ step_fast3<V, P, F>(u, tagged, A, R, N, gn, current_region, regions);
+ /// step_fast4.
+ if (F::compare(g, gn))
+ {
+ step_fast4_1<V, P, F>(u, A, R, N, g, gn, current_region, regions);
+ // GO TO 3)
+ continue;
+ }
+
+
+ if (g == gn)
+ {
+ step_fast4_2(u, A, N, g, current_region, regions);
+ // GO TO 3)
+ continue;
+ }
+
+
+ if (!F::compare(g, gn))
+ {
+ step_fast4_3(u, tagged, R, g);
+ // GO TO 1)
+ break;
+ }
+ }
+ //std::cout << "current_region = " << current_region <<
std::endl;
+ }
+ } // end of Algorithm
+
+ image2d<value::int_u8> output (ima.domain ());
+ fllt_tree(P, V)& tree = *new fllt_tree(P, V)(current_region);
+ util::tree_to_image (tree, output);
+
+ // util::display_tree(ima, tree);
+
+ // debug::println(output);
+ // std::cout << std::endl;
+ // debug::println(ima);
+
+ // if (output != ima)
+ // {
+ // std::cerr << "BUG!!!" << std::endl;
+ // abort();
+ // }
+
+ // io::pgm::save(output, "out.pgm");
+ // std::cout << "out.pgm generate"
+ // << std::endl;
+
+
+ // debug::println(regions);
+ //debug::println(ima | regions(make:defined reference to
`mln::fllt::lower<mln::value::int_u<8u>
>::inc':point2d(-4,-1))->elt().points);
+
+ return (tree);
+
+ } // end of compute_level_set_fast
+
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_COMPUTE_LEVEL_SET_FAST_HH
Index: trunk/milena/sandbox/garrigues/fllt/fllt.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/fllt.hh (revision 1869)
+++ trunk/milena/sandbox/garrigues/fllt/fllt.hh (revision 1870)
@@ -94,7 +94,7 @@
template <typename V>
// Fixme : return type
- void
+ fllt_tree(point2d, V)
fllt(const image2d<V>& ima)
{
typedef point2d P;
@@ -124,52 +124,7 @@
//fllt_tree(P, V) result_tree = merge_trees(upper_tree, lower_tree, upp_reg,
low_reg, ima);
fllt_tree(P, V) result_tree = merge_trees(lower_tree, upper_tree, low_reg, upp_reg,
ima);
-
- std::cout << "4/ Generate outputs." << std::endl;
-
- image2d<value::int_u8> output (ima.domain ());
- util::tree_to_image (result_tree, output);
-
-
- // io::pgm::save(output, "out_final.pgm");
- // std::cout << "out_final.pgm generate"
- // << std::endl;
-
-
- // util::display_tree(ima, lower_tree);
- draw_tree(ima, result_tree);
-
- // debug::println(ima);
- // debug::println(output);
-
- // if (output != ima)
- // {
- // std::cerr << "BUG!!!" << std::endl;
- // abort();
- // }
-
- image2d<value::int_u8> viz(ima.domain());
- // image2d<value::int_u8> viz2(ima.domain());
-
- // visualize_deepness(viz, lower_tree);
- // level::stretch(viz, viz2);
- // debug::println(viz);
- // debug::println(viz2);
- // io::pgm::save(viz2, "fllt.pgm");
-
- visualize_bounds(viz, result_tree, 200);
- //debug::println(viz);
- io::pgm::save(viz, "fllt_bounds_200.pgm");
-
- visualize_bounds(viz, result_tree, 100);
- io::pgm::save(viz, "fllt_bounds_100.pgm");
-
- visualize_bounds(viz, result_tree, 50);
- io::pgm::save(viz, "fllt_bounds_50.pgm");
-
- visualize_bounds(viz, result_tree, 20);
- io::pgm::save(viz, "fllt_bounds_20.pgm");
-
+ return result_tree;
}
} // end of namespace mln::fllt
Index: trunk/milena/sandbox/garrigues/fllt/local_configurations.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/local_configurations.hh (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/local_configurations.hh (revision 1870)
@@ -0,0 +1,144 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+
+#ifndef MLN_FIXME_FLLT_LOCAL_CONFIGURATIONS_HH
+# define MLN_FIXME_FLLT_LOCAL_CONFIGURATIONS_HH
+
+/*! \file local_configurations.hh
+ *
+ * \brief Stuffs related to local configurations for the FLLT.
+ *
+ */
+
+#include <mln/core/clock_neighb2d.hh>
+#include "upper.hh"
+#include "lower.hh"
+
+namespace mln
+{
+ namespace fllt
+ {
+
+ template <typename V>
+ struct lower;
+
+ template <typename V>
+ struct upper;
+
+ template <typename F>
+ struct added_holes;
+
+ template <typename V>
+ struct added_holes<upper<V> >
+ {
+ // For each possible configuration (of the c8-neighbourghood) of the
+ // added pixel, stock the number of added holes.
+ // ==> region with c8, holes with c4.
+ static char ret[256];
+ };
+
+ template <typename V>
+ char added_holes<upper<V> >::ret[256] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
+ 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
+
+ 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, -1, 0, -1,
+ 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, -1, 0, -1,
+
+ 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0,
+ 1, 1, 2, 1, 1, 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0,
+ 1, 1, 2, 1, 2, 1, 2, 1, 2, 2, 3, 2, 2, 1, 2, 1,
+ 1, 1, 2, 1, 1, 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0,
+
+ 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, -1, 0, -1,
+ 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 1, 0, 0, -1, 0, -1
+ };
+
+ template <typename V>
+ struct added_holes<lower<V> >
+ {
+ // For each possible configuration (of the c4-neighbourghood) of the
+ // added pixel, stock the number of added holes.
+ // ==> region with c4, holes with c8.
+ static char ret[256];
+ };
+
+ template <typename V>
+ char added_holes<lower<V> >::ret[256] =
+ {
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+
+ 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 1, 1, 2, 1, 1,
+ 1, 2, 1, 2, 2, 3, 2, 2, 1, 2, 1, 2, 1, 2, 1, 1,
+ 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 1, 1, 2, 1, 1,
+ 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 1, 2, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+
+ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0,
+ 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0,
+ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1
+ };
+
+ template <typename P, typename F>
+ char n_added_holes(const p_image2d<P>& set, const point2d& p)
+ {
+ unsigned char res = 0;
+ dpoint2d dp(1,1);
+ clock_neighb2d nbh = F::reg_c_nbh(dp);
+ mln_fwd_niter_(clock_neighb2d) n(nbh , p);
+ for_all(n)
+ {
+ res = (res << 1);
+ if (set.has(n))
+ res = res | 1;
+ }
+// std::cout << int(res) << ":" <<
int(added_holes<F>::ret[res]) << " hole added." << std::endl;
+ return added_holes<F>::ret[res];
+ }
+ } // end of namespace mln::fllt
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_FIXME_FLLT_HH
Index: trunk/milena/sandbox/garrigues/fllt/test.cc
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/test.cc (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/test.cc (revision 1870)
@@ -0,0 +1,62 @@
+# include "fllt.hh"
+//# include "compute_level_set.hh"
+
+# include "compute_level_set_fast2.hh"
+
+# include <mln/core/image2d.hh>
+# include <mln/core/cast_image.hh>
+# include <mln/core/clone.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/debug/println.hh>
+# include <mln/convert/to_w_window.hh>
+# include <mln/core/w_window2d_int.hh>
+# include <mln/convert/to_image.hh>
+# include <mln/level/fill.hh>
+# include <mln/io/pgm/load.hh>
+# include <mln/io/pbm/load.hh>
+
+int main()
+{
+
+ using namespace mln;
+
+ typedef point2d P;
+ typedef int V;
+
+ //trace::quiet = false;
+
+// V ws[81] = {5,5,5,5,5,5,5,5,5,
+// 5,5,5,5,5,5,5,5,5,
+// 5,5,5,5,5,5,8,8,5,
+// 5,5,5,9,5,5,8,8,5,
+// 5,5,5,9,5,5,8,8,5,
+// 5,5,5,5,5,5,8,8,5,
+// 5,5,5,5,5,5,8,8,5,
+// 5,5,5,5,5,5,5,5,5,
+// 5,5,5,5,5,5,5,5,5};
+
+// w_window2d_int w_win = make::w_window2d(ws);
+// image2d<V> ima = convert::to_image(w_win);
+
+ image2d<value::int_u8> ima_ =
io::pgm::load<value::int_u8>("small.pgm");
+ image2d<V> ima(ima_.domain());
+
+ level::fill(ima, ima_);
+
+// {
+// image2d<fllt_node(P, V)*> low_reg(ima.domain());
+// fllt_tree(P, V) lower_tree;
+// lower_tree
+// = fllt::compute_level_set<V, fllt::lower<V> >(ima, low_reg);
+// fllt::draw_tree(ima, lower_tree);
+// }
+
+
+ {
+ image2d<fllt_node(P, V)*> low_reg(ima.domain());
+ fllt_tree(P, V) lower_tree;
+ lower_tree
+ = fllt_fast::compute_level_set_fast<V, fllt::upper<V> >(ima, low_reg);
+ //fllt::draw_tree(ima, lower_tree);
+ }
+}
Index: trunk/milena/sandbox/garrigues/fllt/give_confs.cc
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/give_confs.cc (revision 0)
+++ trunk/milena/sandbox/garrigues/fllt/give_confs.cc (revision 1870)
@@ -0,0 +1,56 @@
+#include <mln/core/image2d.hh>
+#include <mln/core/point2d.hh>
+#include <mln/core/p_set.hh>
+#include <mln/core/clock_neighb2d.hh>
+#include <mln/core/neighb2d.hh>
+
+#include <mln/labeling/level.hh>
+#include <mln/level/fill.hh>
+#include <mln/debug/println.hh>
+#include <iomanip>
+
+int main()
+{
+ using namespace mln;
+ using namespace mln::value;
+
+ image2d<bool> ima(3,3);
+ point2d p(1,1);
+ dpoint2d dp(-1,0);
+ clock_neighb2d nbh = cc8(dp);
+ int n_holes = 0;
+
+ bool tab[8][8];
+ for (int i = 0; i < 256; i++)
+ {
+ level::fill(ima, false);
+ int_u8 tmp = i;
+
+ mln_fwd_niter_(clock_neighb2d) n(nbh , p);
+ for_all(n)
+ {
+ if (tmp % 2)
+ ima(n) = true;
+ tmp = tmp >> 1;
+ }
+
+
+ int x, y;
+ labeling::level(ima, false, c8(), x);
+
+
+ ima(p) = true;
+ labeling::level(ima, false, c8(), y);
+
+// std::cout << "----- conf no " << i <<
"------" << std::endl;
+// debug::println(ima);
+// std::cout << "----- " << x << " holes
before------" << std::endl;
+// std::cout << "----- " << y << " holes
after------" << std::endl;
+// std::cout << "----- " << y - x << " holes
added------" << std::endl << std::endl;
+
+ std::cout << std::setw(2) << y - x << ", ";
+ if (! ((i + 1) % 4)) std::cout << " ";
+ if (! ((i + 1) % 16)) std::cout << std::endl;
+ if (! ((i + 1) % 64)) std::cout << std::endl;
+ }
+}
Index: trunk/milena/sandbox/garrigues/fllt/test_fllt2.cc
===================================================================
--- trunk/milena/sandbox/garrigues/fllt/test_fllt2.cc (revision 1869)
+++ trunk/milena/sandbox/garrigues/fllt/test_fllt2.cc (revision 1870)
@@ -1,4 +1,4 @@
-# include "fllt_optimized.hh"
+# include "fllt.hh"
# include <mln/core/image2d.hh>
# include <mln/core/clone.hh>
# include <mln/value/int_u8.hh>
@@ -29,5 +29,5 @@
image2d<int> ima = convert::to_image(w_win);
fllt_tree(point2d, int) t = fllt::fllt(ima);
- fllt::debug(ima, t);
+ fllt::draw_tree(ima, t);
}