URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-23 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Update fllt.
* mln/core/a_point_of.hh: New, give a point of an image
* mln/util/abr.hh: (abr::set_parent) New,
(abr::get_parent) New,
(abr::content) New.
* sandbox/garrigues/fllt.hh: Update fllt.
* sandbox/garrigues/test_fllt.cc: Update.
---
mln/core/a_point_of.hh | 63 +++++++++++++++++++++++
mln/util/abr.hh | 40 +++++++++++++-
sandbox/garrigues/fllt.hh | 110 ++++++++++++++++++++++++++++++++++++-----
sandbox/garrigues/test_fllt.cc | 8 +-
4 files changed, 201 insertions(+), 20 deletions(-)
Index: trunk/milena/mln/core/a_point_of.hh
===================================================================
--- trunk/milena/mln/core/a_point_of.hh (revision 0)
+++ trunk/milena/mln/core/a_point_of.hh (revision 1380)
@@ -0,0 +1,63 @@
+// Copyright (C) 2007 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_CORE_A_POINT_OF_HH
+# define MLN_CORE_A_POINT_OF_HH
+
+/*! \file mln/core/a_point_oft.hh
+ *
+ * \brief Give a point of an image.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/exact.hh>
+
+namespace mln
+{
+
+ /// Give a point of an image.
+ template <typename I>
+ mln_point(I) a_point_of(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ mln_point(I) a_point_of(const Image<I>& ima_)
+ {
+ const I& ima = exact(ima_);
+ mln_piter(I) p(ima.domain());
+ p.start();
+ return p;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_A_POINT_OF_HH
Index: trunk/milena/mln/util/abr.hh
===================================================================
--- trunk/milena/mln/util/abr.hh (revision 1379)
+++ trunk/milena/mln/util/abr.hh (revision 1380)
@@ -49,13 +49,17 @@
abr();
abr(T& elt);
+ T& content();
+ const T& content() const;
void add_child(T& elt);
+ void set_parent(abr<T>* parent);
+ abr<T>* get_parent();
void print_rec(int n) const;
void print(void) const;
int search_rec(abr<T>** res, T& elt);
abr<T>* search(T& elt);
- T& elt_;
+ T elt_;
abr<T>* parent_;
std::vector< abr<T>* > child_;
};
@@ -65,8 +69,7 @@
template <typename T>
abr<T>::abr()
- : elt_ (0),
- parent_ (0)
+ : parent_ (0)
{
}
@@ -78,6 +81,20 @@
}
template <typename T>
+ const T&
+ abr<T>::content() const
+ {
+ return elt_;
+ }
+
+ template <typename T>
+ T&
+ abr<T>::content()
+ {
+ return elt_;
+ }
+
+ template <typename T>
void
abr<T>::add_child(T& elt)
{
@@ -88,6 +105,23 @@
}
template <typename T>
+ void
+ abr<T>::set_parent(abr<T>* parent)
+ {
+ mln_assertion(parent != 0);
+ parent_ = parent;
+ parent->child_.push_back(this);
+ }
+
+
+ template <typename T>
+ abr<T>*
+ abr<T>::get_parent()
+ {
+ return parent_;
+ }
+
+ template <typename T>
int
abr<T>::search_rec(abr<T>** res, T& elt)
{
Index: trunk/milena/sandbox/garrigues/fllt.hh
===================================================================
--- trunk/milena/sandbox/garrigues/fllt.hh (revision 1379)
+++ trunk/milena/sandbox/garrigues/fllt.hh (revision 1380)
@@ -44,6 +44,7 @@
# include <mln/core/sub_image.hh>
# include <mln/core/image_if.hh>
# include <mln/core/clone.hh>
+# include <mln/core/a_point_of.hh>
# include <mln/debug/println.hh>
# include <mln/convert/to_image.hh>
@@ -56,6 +57,8 @@
# include <mln/set/diff.hh>
# include <mln/set/inter.hh>
+# include <mln/util/abr.hh>
+
# include <mln/labeling/regional_minima.hh>
# include <mln/labeling/level.hh>
@@ -65,6 +68,19 @@
namespace mln
{
+ namespace fllt
+ {
+
+ template <typename P>
+ struct fllt_node
+ {
+ set_p<P> points;
+ set_p<P> holes;
+ };
+
+ # define fllt_node(P) util::abr< fllt_node<P> >
+
+
// LOWER LEVEL SET : region = c4, border = c8
// UPPER LEVEL SET : region = c8, border = c4
@@ -145,7 +161,13 @@
set_p<P>& N,
V& gn)
{
+ static bool finished = false;
std::cout << "entering step 3" << std::endl;
+
+ // Stop the algorithm.
+ if (finished)
+ { gn = 0; return; }
+
// N <- N union {x neighbor of a pixel in a\R}
mln_piter(set_p<P>) qa(A);
for_all(qa)
@@ -167,8 +189,13 @@
debug::println(u | R);
// gn <- min u(x) x belongs to N.
+ if ((u | set::inter(N, u.domain())).npoints() > 0)
gn = level::compute<accu::min>(u | set::inter(N, u.domain()));
-
+ else
+ {
+ finished = true;
+ gn++;
+ }
std::cout << std::endl << "gN = " << gn <<
std::endl;
// R <- R union A
// tag the pixels of A.
@@ -186,12 +213,36 @@
template <typename V, typename P>
void step4_1 (image2d<V>& u,
set_p<P>& A,
-// set_p<P>& R,
+ set_p<P>& R,
set_p<P>& N,
V& g,
- V& gn)
+ V& gn,
+ fllt_node(P)* current_region,
+ image2d<fllt_node(P)*>& regions
+ )
{
std::cout << "entering step 4_1" << std::endl;
+
+ // Create a new conected component.
+ // FIXME : we can make it faster.
+ //mln_piter(S) p(set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+ mln_piter(set_p<P>) p(R);
+ current_region = new fllt_node(P)();
+ for_all(p)
+ {
+ if (regions(p) == 0)
+ {
+ current_region->content().points.insert(p);
+ regions(p) = current_region;
+ }
+ else
+ {
+ if (regions(p)->get_parent() == 0)
+ regions(p)->set_parent(current_region);
+ }
+ }
+
+
// Count the number of conected components of the border of R.
image2d<int> tmp(u.domain().to_larger(1));
image2d<bool> border_ima(u.domain().to_larger(1));
@@ -208,13 +259,18 @@
{
// 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.
-// Remove from N border of holes???.
+ // WARNING : We trust labeling::level to label the exterior border with 1.
+ current_region->content().holes.insert(a_point_of(tmp | pw::value(tmp) ==
pw::cst(n)));
+
+ // FIXME : [optimisation] Remove from N border of holes???.
// Recompute gn <- min u(x) x belongs to A
}
+ }
g = gn;
// A <- {x belongs to N / u(x) == g}
@@ -239,7 +295,10 @@
void step4_2 (const image2d<V>& u,
set_p<P>& A,
set_p<P>& N,
- V& g)
+ V& g,
+ fllt_node(P)* current_region,
+ image2d<fllt_node(P)*>& regions
+ )
{
std::cout << "entering step 4_2" << std::endl;
@@ -248,6 +307,21 @@
// N <- N\{x belongs to N / u(x) == g}
N = set::diff(N, N | pw::value(u) == pw::cst(g));
+// // FIXME
+// typedef mln::pset_if<
+// mln::set_p<mln::point_<mln::grid::square, int> >,
+// mln::fun::eq_p2b_expr_<mln::pw::value_<mln::image2d<int> >,
+// mln::pw::cst_<int> > > S;
+
+// // Update the current region
+// //mln_piter(S) p(set::inter(N, u.domain()) | pw::value(u) == pw::cst(g));
+// mln_piter(set_p<P>) p(A);
+// for_all(p)
+// {
+// if (regions(p) == 0)
+// regions(p) = current_region;
+// }
+
std::cout << "A :" << std::endl;
if (A.npoints())
debug::println(u | A);
@@ -280,14 +354,12 @@
}
-
-
-
template <typename V>
void compute_level_set(const image2d<V>& ima)
{
typedef point2d P;
typedef image2d<V> I;
+ // FIXME
typedef mln::image_if<
mln::image2d<V>,
mln::fun::greater_p2b_expr_<mln::pw::value_<mln::image2d<V> >,
@@ -302,6 +374,10 @@
image2d<V> u = clone(ima);
image2d<bool> tagged(ima.domain());
+ fllt_node(P)* current_region;
+ image2d<fllt_node(P)*> regions(ima.domain());
+ level::fill(regions, 0);
+
unsigned nlabels;
labeling::regional_minima(ima, c4(), min_locals, nlabels);
@@ -329,7 +405,7 @@
/// step4.
if (g < gn)
{
- step4_1(u, A, N, g, gn);
+ step4_1(u, A, R, N, g, gn, current_region, regions);
// GO TO 3)
continue;
}
@@ -337,7 +413,7 @@
if (g == gn)
{
- step4_2(u, A, N, g);
+ step4_2(u, A, N, g, current_region, regions);
// GO TO 3)
continue;
}
@@ -351,8 +427,16 @@
}
}
}
- }
- }
+ } // end of Algorithm
+ std::cout << "END OF ALGORITHM" << std::endl;
+
+
+ debug::println(regions);
+ debug::println(ima | regions(make::point2d(-4,-1))->content().points);
+
+ } // end of compute_level_set
+
+ } // end of namespace mln::fllt
} // end of namespace mln
Index: trunk/milena/sandbox/garrigues/test_fllt.cc
===================================================================
--- trunk/milena/sandbox/garrigues/test_fllt.cc (revision 1379)
+++ trunk/milena/sandbox/garrigues/test_fllt.cc (revision 1380)
@@ -14,9 +14,9 @@
2,1,3,4,4,4,4,5,5,
2,3,4,2,3,3,2,4,4,
1,4,2,1,1,2,1,2,2,
- 1,2,4,2,1,2,1,1,1,
- 1,3,3,4,2,3,2,1,1,
- 1,3,3,4,2,3,2,1,1,
+ 1,2,4,2,1,2,1,9,1,
+ 1,3,3,4,2,3,2,9,1,
+ 1,3,3,4,2,3,2,9,1,
1,3,3,4,2,3,2,1,1,
1,3,3,4,2,3,2,1,1};
@@ -25,5 +25,5 @@
image2d<int> ima = convert::to_image(w_win);
debug::println(ima);
- compute_level_set(ima);
+ fllt::compute_level_set(ima);
}