https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add labeling routines.
* tests/sort_points.cc: Rename as...
* tests/level_sort_points.cc: ...this.
Augment.
* tests/labeling.cc: Rename as...
* tests/labeling_foreground.cc: ...this.
Update.
* tests/labeling_regional_maxima.cc: New.
* mln/convert/to_vec_p.hh: New.
* mln/pw/image.hh (change_value): Use fixme.
* mln/core/vec_p.hh (reserve, hook_): New.
* mln/core/vec_p_piter.hh (vec_p_bkd_piter_): Code.
* mln/level/sort_points.hh (sort_points): Rename as...
(sort_points_increasing): ...this.
(sort_points_decreasing): New.
* mln/level/fill.hh: Add & to the C function arg; that fixes
the behavior of icpc when calling fill with the literal 0.
* mln/level/labeling.hh: Remove; obsolete because of
labeling::level.
* mln/linear/sobel.hh: Add FIXME.
* mln/canvas/labeling.hh: New.
* mln/labeling/flat_zones.hh: New.
* mln/labeling/+foreground.hh: Remove.
* mln/labeling/level.hh: New.
* mln/labeling/foreground.hh: New.
* mln/labeling/regional_minima.hh: New.
* mln/labeling/base.hh: New.
* mln/labeling/regional_maxima.hh: New.
* mln/labeling/background.hh: New.
mln/canvas/labeling.hh | 157 ++++++++++++++++++++++++++++++++++++++
mln/convert/to_vec_p.hh | 71 +++++++++++++++++
mln/core/vec_p.hh | 20 ++++
mln/core/vec_p_piter.hh | 121 ++++++++++++++++++++++++++++-
mln/labeling/background.hh | 79 +++++++++++++++++++
mln/labeling/base.hh | 94 ++++++++++++++++++++++
mln/labeling/flat_zones.hh | 111 ++++++++++++++++++++++++++
mln/labeling/foreground.hh | 79 +++++++++++++++++++
mln/labeling/level.hh | 118 ++++++++++++++++++++++++++++
mln/labeling/regional_maxima.hh | 120 +++++++++++++++++++++++++++++
mln/labeling/regional_minima.hh | 120 +++++++++++++++++++++++++++++
mln/level/fill.hh | 5 -
mln/level/sort_points.hh | 110 ++++++++++++++++++++------
mln/linear/sobel.hh | 2
mln/pw/image.hh | 2
tests/labeling_foreground.cc | 45 ++--------
tests/labeling_regional_maxima.cc | 57 +++++++++++++
tests/level_sort_points.cc | 15 ++-
18 files changed, 1254 insertions(+), 72 deletions(-)
Index: tests/level_sort_points.cc
--- tests/level_sort_points.cc (revision 1067)
+++ tests/level_sort_points.cc (working copy)
@@ -47,10 +47,13 @@
image2d_b<int_u8> ima(3, 3);
debug::iota(ima);
- std::vector<point2d> vec = level::sort_points(ima);
-
- std::copy(vec.begin(), vec.end(),
- std::ostream_iterator<point2d>(std::cout, " "));
- std::cout << std::endl;
-
+ vec_p<point2d> vec;
+ {
+ vec = level::sort_points_increasing(ima);
+ std::cout << vec << std::endl;
+ }
+ {
+ vec = level::sort_points_decreasing(ima);
+ std::cout << vec << std::endl;
+ }
}
Index: tests/labeling_foreground.cc
--- tests/labeling_foreground.cc (revision 1067)
+++ tests/labeling_foreground.cc (working copy)
@@ -25,54 +25,33 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/labeling.cc
+/*! \file tests/labeling_foreground.cc
*
- * \brief Tests on mln::level::labeling.
+ * \brief Test on mln::labeling::foreground.
*/
#include <mln/core/image2d_b.hh>
#include <mln/core/neighb2d.hh>
-
#include <mln/value/int_u8.hh>
-#include <mln/value/label.hh>
-
-#include <mln/pw/value.hh>
-#include <mln/pw/cst.hh>
-#include <mln/fun/ops.hh>
+#include <mln/pw/all.hh>
#include <mln/io/load_pgm.hh>
#include <mln/io/save_pgm.hh>
-
-#include <mln/level/fill.hh>
-#include <mln/level/labeling.hh>
-#include <mln/level/to_enc.hh>
-
+#include <mln/labeling/foreground.hh>
int main()
{
using namespace mln;
using value::int_u8;
- using value::label;
- image2d_b<int_u8> lena = io::load_pgm("../img/lena.pgm");
-
- image2d_b<bool> bin(lena.domain());
- level::fill(bin, pw::value(lena) > pw::cst(127));
-
- {
- image2d_b<int_u8> lab(lena.domain());
- level::labeling(bin, c4(), lab);
- io::save_pgm(lab, "lab.pgm");
- }
-
- {
- image2d_b< label<8> > lab(lena.domain());
- level::labeling(bin, c4(), lab);
-
- image2d_b< int_u8 > out(lena.domain());
- level::to_enc(lab, out);
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/tiny.pgm"),
+ out(lena.domain());
+
+ unsigned n;
+ labeling::foreground((pw::value(lena) > pw::cst(127)) | lena.domain(),
+ c4(), out, n);
io::save_pgm(out, "out.pgm");
- }
-
+ mln_assertion(n = 14);
}
Index: tests/labeling_regional_maxima.cc
--- tests/labeling_regional_maxima.cc (revision 0)
+++ tests/labeling_regional_maxima.cc (revision 0)
@@ -0,0 +1,57 @@
+// 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.
+
+/*! \file tests/labeling_regional_maxima.cc
+ *
+ * \brief Test on mln::labeling::regional_maxima.
+ */
+
+#include <mln/core/image2d_b.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+
+#include <mln/io/load_pgm.hh>
+#include <mln/io/save_pgm.hh>
+
+#include <mln/labeling/regional_maxima.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d_b<int_u8>
+ lena = io::load_pgm("../img/lena.pgm"),
+ out(lena.domain());
+
+ unsigned n;
+ labeling::regional_maxima(lena, c4(), out, n);
+ mln_assertion(n = 255);
+
+ io::save_pgm(out, "out.pgm");
+}
Index: mln/convert/to_vec_p.hh
--- mln/convert/to_vec_p.hh (revision 0)
+++ mln/convert/to_vec_p.hh (revision 0)
@@ -0,0 +1,71 @@
+// 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_CONVERT_TO_VEC_P_HH
+# define MLN_CONVERT_TO_VEC_P_HH
+
+/*! \file mln/convert/to_vec_p.hh
+ *
+ * \brief Conversions to mln::vec_p.
+ */
+
+# include <mln/core/vec_p.hh>
+
+
+namespace mln
+{
+
+ namespace convert
+ {
+
+ /// Convert a point set \p pset into a vec_p (point set vector).
+ template <typename S>
+ vec_p<mln_point(S)> to_vec_p(const Point_Set<S>& pset);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename S>
+ vec_p<mln_point(S)> to_vec_p(const Point_Set<S>& pset_)
+ {
+ const S& pset = exact(pset_);
+ vec_p<mln_point(S)> v;
+ v.reserve(pset.npoints());
+ mln_fwd_piter(S) p(pset);
+ for_all(p)
+ v.append(p);
+ return v;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::convert
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CONVERT_TO_VEC_P_HH
Index: mln/pw/image.hh
--- mln/pw/image.hh (revision 1067)
+++ mln/pw/image.hh (working copy)
@@ -109,7 +109,7 @@
template <typename U>
struct change_value
{
- typedef void ret;
+ typedef internal::fixme ret;
};
protected:
Index: mln/core/vec_p.hh
--- mln/core/vec_p.hh (revision 1067)
+++ mln/core/vec_p.hh (working copy)
@@ -79,6 +79,9 @@
/// Constructor from a vector \p vect.
vec_p(const std::vector<P>& vect);
+ /// Reserve \p n cells.
+ void reserve(std::size_t n);
+
/// Test is \p p belongs to this point set.
bool has(const P& p) const;
@@ -100,6 +103,9 @@
/// Return the \p i-th point.
const P& operator[](unsigned i) const;
+ /// Hook to data.
+ std::vector<P>& hook_();
+
protected:
std::vector<P> vect_;
@@ -129,6 +135,20 @@
template <typename P>
void
+ vec_p<P>::reserve(std::size_t n)
+ {
+ vect_.reserve(n);
+ }
+
+ template <typename P>
+ std::vector<P>&
+ vec_p<P>::hook_()
+ {
+ return vect_;
+ }
+
+ template <typename P>
+ void
vec_p<P>::update_bb_() const
{
bb_.init();
Index: mln/core/vec_p_piter.hh
--- mln/core/vec_p_piter.hh (revision 1067)
+++ mln/core/vec_p_piter.hh (working copy)
@@ -92,15 +92,63 @@
- // FIXME:
+ /*! \brief Backward iterator on points of a vec_p<P>.
+ *
+ */
template <typename P>
- struct vec_p_bkd_piter_ : internal::fixme
- {};
+ struct vec_p_bkd_piter_ : public Point_Iterator< vec_p_bkd_piter_<P> >
+ {
+ enum { dim = P::dim };
+
+ /// Point_Site associated type.
+ typedef P psite;
+
+ /// Point associated type.
+ typedef P point;
+
+ /// Dpoint associated type.
+ typedef mln_dpoint(P) dpoint;
+
+ /// Coordinate associated type.
+ typedef mln_coord(P) coord;
+
+ /// Coordinate associated type.
+ template <typename S>
+ vec_p_bkd_piter_(const Point_Set<S>& s);
+
+ /// Give a hook to the point address.
+ const P* pointer_() const;
+
+ /// Read-only access to the \p i-th coordinate.
+ coord operator[](unsigned i) const;
+
+ /// Test if the iterator is valid.
+ bool is_valid() const;
+
+ /// Invalidate the iterator.
+ void invalidate();
+
+ /// Start an iteration.
+ void start();
+
+ /// Go to the next point.
+ void next_();
+
+ /// Convert the iterator into a point.
+ operator P() const;
+
+ protected:
+ const std::vector<P>& vect_;
+ int i_;
+ P p_;
+ };
# ifndef MLN_INCLUDE_ONLY
+ // vec_p_fwd_piter_<P>
+
template <typename P>
template <typename S>
vec_p_fwd_piter_<P>::vec_p_fwd_piter_(const Point_Set<S>& s)
@@ -153,6 +201,7 @@
vec_p_fwd_piter_<P>::next_()
{
++i_;
+ if (is_valid())
p_ = vect_[i_];
}
@@ -163,6 +212,72 @@
return p_;
}
+
+ // vec_p_bkd_piter_<P>
+
+ template <typename P>
+ template <typename S>
+ vec_p_bkd_piter_<P>::vec_p_bkd_piter_(const Point_Set<S>& s)
+ : vect_(exact(s).vect())
+ {
+ invalidate();
+ }
+
+ template <typename P>
+ const P*
+ vec_p_bkd_piter_<P>::pointer_() const
+ {
+ return & p_;
+ }
+
+ template <typename P>
+ mln_coord(P)
+ vec_p_bkd_piter_<P>::operator[](unsigned i) const
+ {
+ mln_precondition(i < dim);
+ mln_precondition(is_valid());
+ return p_[i];
+ }
+
+ template <typename P>
+ bool
+ vec_p_bkd_piter_<P>::is_valid() const
+ {
+ return i_ >= 0;
+ }
+
+ template <typename P>
+ void
+ vec_p_bkd_piter_<P>::invalidate()
+ {
+ i_ = -1;
+ }
+
+ template <typename P>
+ void
+ vec_p_bkd_piter_<P>::start()
+ {
+ i_ = vect_.size() - 1;
+ if (is_valid())
+ p_ = vect_[i_];
+ }
+
+ template <typename P>
+ void
+ vec_p_bkd_piter_<P>::next_()
+ {
+ --i_;
+ if (is_valid())
+ p_ = vect_[i_];
+ }
+
+ template <typename P>
+ vec_p_bkd_piter_<P>::operator P() const
+ {
+ mln_precondition(is_valid());
+ return p_;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/level/sort_points.hh
--- mln/level/sort_points.hh (revision 1067)
+++ mln/level/sort_points.hh (working copy)
@@ -31,13 +31,14 @@
/*! \file mln/level/sort_points.hh
*
* \brief Sort_Points the contents of an image into another one.
+ *
+ * \todo Factor code + optimize.
*/
-# include <vector>
-# include <utility>
# include <algorithm>
# include <mln/core/concept/image.hh>
+# include <mln/convert/to_vec_p.hh>
# include <mln/histo/compute.hh>
@@ -55,7 +56,7 @@
* \pre \p input.has_data
*/
template <typename I>
- std::vector<mln_point(I)> sort_points(const Image<I>& input);
+ vec_p<mln_point(I)> sort_points_increasing(const Image<I>& input);
# ifndef MLN_INCLUDE_ONLY
@@ -63,6 +64,8 @@
namespace impl
{
+ // utility
+
template <typename I>
struct value_point_less_
{
@@ -82,31 +85,40 @@
};
template <typename I>
- std::vector<mln_point(I)>
- sort_points(metal::false_, // general case
- const Image<I>& input_)
+ struct value_point_greater_
{
- const I& input = exact(input_);
+ const I& ima_;
- std::vector<mln_point(I)> vec;
- vec.reserve(input.npoints());
+ value_point_greater_(const I& ima)
+ : ima_(ima)
+ {
+ }
- mln_fwd_piter(I) p(input.domain());
- for_all(p)
- vec.push_back(p);
+ bool operator()(const mln_point(I)& lhs,
+ const mln_point(I)& rhs) const
+ {
+ return ima_(lhs) > ima_(rhs) || (ima_(lhs) = ima_(rhs)
+ && lhs > rhs);
+ }
+ };
- std::sort(vec.begin(), vec.end(),
+
+ // increasing
+
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_increasing_(metal::false_, const I& input) // general case
+ {
+ vec_p<mln_point(I)> v = convert::to_vec_p(input.domain());
+ std::sort(v.hook_().begin(), v.hook_().end(),
value_point_less_<I>(input));
- return vec;
+ return v;
}
template <typename I>
- std::vector<mln_point(I)>
- sort_points(metal::true_, // low quantization
- const Image<I>& input_)
+ vec_p<mln_point(I)>
+ sort_points_increasing_(metal::true_, const I& input) // low quantization
{
- const I& input = exact(input_);
-
typedef mln_vset(I) S;
const S& vset = input.values();
const unsigned n = vset.nvalues();
@@ -120,12 +132,46 @@
for (unsigned i = 1; i != n; ++i)
loc[i] = loc[i-1] + h[i-1];
- /*
- MEMO. Decreasing case is:
+ // computing output data
+ std::vector<mln_point(I)> vec(input.npoints());
+ mln_fwd_piter(I) p(input.domain());
+ for_all(p)
+ vec[loc[vset.index_of(input(p))]++] = p;
+
+ vec_p<mln_point(I)> v;
+ v.hook_() = vec;
+ return v;
+ }
+
+
+ // decreasing
+
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_decreasing_(metal::false_, const I& input) // general case
+ {
+ vec_p<mln_point(I)> v = convert::to_vec_p(input.domain());
+ std::sort(v.hook_().begin(), v.hook_().end(),
+ value_point_greater_<I>(input));
+ return v;
+ }
+
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_decreasing_(metal::true_, const I& input) // low quantization
+ {
+ typedef mln_vset(I) S;
+ const S& vset = input.values();
+ const unsigned n = vset.nvalues();
+
+ // h
+ histo::data<S> h = histo::compute(input);
+
+ // preparing output data
+ std::vector<unsigned> loc(vset.nvalues());
loc[n-1] = 0;
for (unsigned i = n - 2; i != 0; --i)
loc[i] = loc[i+1] + h[i+1];
- */
// computing output data
std::vector<mln_point(I)> vec(input.npoints());
@@ -133,20 +179,32 @@
for_all(p)
vec[loc[vset.index_of(input(p))]++] = p;
- return vec;
+ vec_p<mln_point(I)> v;
+ v.hook_() = vec;
+ return v;
}
+
} // end of namespace mln::level::impl
+ // Facades.
+
template <typename I>
- std::vector<mln_point(I)>
- sort_points(const Image<I>& input)
+ vec_p<mln_point(I)>
+ sort_points_increasing(const Image<I>& input)
{
mln_precondition(exact(input).has_data());
- return impl::sort_points(mln_is_value_lowq(I)(), exact(input));
+ return impl::sort_points_increasing_(mln_is_value_lowq(I)(), exact(input));
}
+ template <typename I>
+ vec_p<mln_point(I)>
+ sort_points_decreasing(const Image<I>& input)
+ {
+ mln_precondition(exact(input).has_data());
+ return impl::sort_points_decreasing_(mln_is_value_lowq(I)(), exact(input));
+ }
# endif // ! MLN_INCLUDE_ONLY
Index: mln/level/fill.hh
--- mln/level/fill.hh (revision 1067)
+++ mln/level/fill.hh (working copy)
@@ -86,7 +86,7 @@
* \todo Take benefit from quantization when possible.
*/
template <typename I>
- void fill(Image<I>& ima, mln_value(I) (*f)(const mln_point(I)& p));
+ void fill(Image<I>& ima, mln_value(I) (*(&f))(const mln_point(I)&
p));
/*! Fill the image \p ima with the values given by the array \p arr.
@@ -191,8 +191,9 @@
template <typename I>
void fill(Image<I>& ima_,
- mln_value(I) (*f)(const mln_point(I)& p))
+ mln_value(I) (*(&f))(const mln_point(I)& p))
{
+ mln_precondition(f != 0);
I& ima = exact(ima_);
mln_precondition(ima.has_data());
mln_piter(I) p(ima.domain());
Index: mln/linear/sobel.hh
--- mln/linear/sobel.hh (revision 1067)
+++ mln/linear/sobel.hh (working copy)
@@ -102,7 +102,7 @@
O temp(exact(input).domain());
sobel_v(input, temp);
// output
- arith::plus_inplace(output, temp);
+ arith::plus_inplace(output, temp); // FIXME: abs before plus!!!
level::abs_inplace(output);
}
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 0)
+++ mln/canvas/labeling.hh (revision 0)
@@ -0,0 +1,157 @@
+// 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_CANVAS_LABELING_HH
+# define MLN_CANVAS_LABELING_HH
+
+/*! \file mln/canvas/labeling.hh
+ *
+ * \brief Connected component labeling of the object part in a binary
+ * image.
+ */
+
+# include <mln/level/fill.hh>
+# include <mln/level/sort_points.hh>
+
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ template <typename F>
+ struct labeling
+ {
+ F& f;
+
+ typedef typename F::I I;
+ typedef typename F::N N;
+ typedef typename F::O O;
+ typedef typename F::S S;
+ typedef mln_point(I) point;
+
+ // aux:
+ mln_ch_value(O, bool) deja_vu;
+ mln_ch_value(O, point) parent;
+
+ labeling(F& f)
+ : f(f),
+ deja_vu(f.output.domain()),
+ parent(f.output.domain())
+ {
+ run();
+ }
+
+ void run()
+ {
+ // init
+ {
+ f.nlabels = 0;
+ mln::level::fill(deja_vu, false);
+ f.init();
+ }
+ // first pass
+ {
+ mln_fwd_piter(S) p(f.s);
+ mln_niter(N) n(f.nbh, p);
+ for_all(p) if (f.handles(p))
+ {
+ make_set(p);
+ for_all(n)
+ if (f.input.has(n) && deja_vu(n))
+ if (f.equiv(n, p))
+ do_union(n, p);
+ else
+ f.do_no_union(n, p);
+ deja_vu(p) = true;
+ }
+ }
+
+ // second pass
+ {
+ mln_bkd_piter(S) p(f.s);
+ mln_niter(N) n(f.nbh, p);
+ for_all(p) if (f.handles(p))
+ {
+ if (is_root(p))
+ {
+ if (f.labels(p))
+ {
+ if (f.nlabels = mln_max(mln_value(O)))
+ {
+ f.status = false;
+ return;
+ }
+ f.output(p) = ++f.nlabels;
+ }
+ }
+ else
+ f.output(p) = f.output(parent(p));
+ }
+ f.status = true;
+ }
+
+ } // end of run()
+
+ void make_set(const point& p)
+ {
+ parent(p) = p;
+ f.init_attr(p);
+ }
+
+ bool is_root(const point& p) const
+ {
+ return parent(p) = p;
+ }
+
+ point find_root(const point& x)
+ {
+ if (parent(x) = x)
+ return x;
+ else
+ return parent(x) = find_root(parent(x));
+ }
+
+ void do_union(const point& n, const point& p)
+ {
+ point r = find_root(n);
+ if (r != p)
+ {
+ parent(r) = p;
+ f.merge_attr(r, p);
+ }
+ }
+
+ };
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_LABELING_HH
Index: mln/labeling/flat_zones.hh
--- mln/labeling/flat_zones.hh (revision 0)
+++ mln/labeling/flat_zones.hh (revision 0)
@@ -0,0 +1,111 @@
+// 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_LABELING_FLAT_ZONES_HH
+# define MLN_LABELING_FLAT_ZONES_HH
+
+/*! \file mln/labeling/flat_zones.hh
+ *
+ * \brief Connected component labeling of the flat zones of an image.
+ */
+
+# include <mln/labeling/base.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the flat zones of an image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool flat_zones(const Image<I>& input, const Neighborhood<N>&
nbh,
+ Image<O>& output,
+ unsigned& nlabels);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct flat_zones_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef mln_pset(I_) S;
+ const S& s;
+ mln_value(O) nlabels;
+ bool status;
+
+ bool equiv(const P& n, const P&) const { return input(n) = input(p); }
+
+ // end of requirements
+
+ flat_zones_(const I_& input, const N_& nbh, O_& output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(input.domain())
+ {}
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool flat_zones(const Image<I>& input, const Neighborhood<N>&
nbh,
+ Image<O>& output,
+ unsigned& nlabels)
+ {
+ typedef impl::flat_zones_<I,N,O> F;
+ F f(exact(input), exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_FLAT_ZONES_HH
Index: mln/labeling/level.hh
--- mln/labeling/level.hh (revision 0)
+++ mln/labeling/level.hh (revision 0)
@@ -0,0 +1,118 @@
+// 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_LABELING_LEVEL_HH
+# define MLN_LABELING_LEVEL_HH
+
+/*! \file mln/labeling/level.hh
+ *
+ * \brief Connected component labeling of the image objects at a given
+ * level.
+ */
+
+# include <mln/labeling/base.hh>
+# include <mln/level/fill.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the image objects at a given
+ * level.
+ *
+ * \param[in] input The input image.
+ * \param[in] val The level to consider for the labeling.
+ * \param[in] nbh The neighborhood.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return Succeed or not.
+ */
+ template <typename I, typename N, typename O>
+ bool level(const Image<I>& input, const mln_value(I)& val, const
Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct level_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef mln_pset(I_) S;
+ const S& s;
+
+ void init() { mln::level::fill(this->output, 0); }
+ bool handles(const P& p) const { return input(p) = val; }
+ bool equiv(const P& n, const P&) const { return input(n) = val; }
+
+ // end of requirements
+
+ const mln_value(I_)& val;
+
+ level_(const I_& input, const mln_value(I_)& val, const N_& nbh, O_&
output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(input.domain()),
+ val(val)
+ {}
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool level(const Image<I>& input, const mln_value(I)& val, const
Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels)
+ {
+ mln_precondition(exact(output).domain() = exact(input).domain());
+ typedef impl::level_<I,N,O> F;
+ F f(exact(input), val, exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_LEVEL_HH
Index: mln/labeling/foreground.hh
--- mln/labeling/foreground.hh (revision 0)
+++ mln/labeling/foreground.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_LABELING_FOREGROUND_HH
+# define MLN_LABELING_FOREGROUND_HH
+
+/*! \file mln/labeling/foreground.hh
+ *
+ * \brief Connected component labeling of the object part in a binary
+ * image.
+ */
+
+# include <mln/labeling/level.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the object part in a binary
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool foreground(const Image<I>& input, const Neighborhood<N>&
nbh,
+ Image<O>& output,
+ unsigned& nlabels);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename N, typename O>
+ bool foreground(const Image<I>& input, const Neighborhood<N>&
nbh,
+ Image<O>& output,
+ unsigned& nlabels)
+ {
+ return labeling::level(input, true, nbh, output, nlabels);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_FOREGROUND_HH
Index: mln/labeling/regional_minima.hh
--- mln/labeling/regional_minima.hh (revision 0)
+++ mln/labeling/regional_minima.hh (revision 0)
@@ -0,0 +1,120 @@
+// 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_LABELING_REGIONAL_MINIMA_HH
+# define MLN_LABELING_REGIONAL_MINIMA_HH
+
+/*! \file mln/labeling/regional_minima.hh
+ *
+ * \brief Connected component labeling of the regional minima of an
+ * image.
+ */
+
+# include <mln/labeling/base.hh>
+# include <mln/level/sort_points.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the regional minima of an
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool regional_minima(const Image<I>& input, const
Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct regional_minima_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef vec_p<P> S;
+ S s;
+
+ void init() { mln::level::fill(this->output, 0);
+ level::fill(attr, true); }
+ bool labels(const P& p) const { return attr(p); }
+ bool equiv(const P& n, const P& p) const { return input(n) = input(p); }
+ void do_no_union(const P& n, const P& p) { mln_invariant(input(n) <
input(p));
+ attr(p) = false; }
+ void merge_attr(const P& r, const P& p) { attr(p) = attr(p) && attr(r);
}
+
+ // end of requirements
+
+ mln_ch_value(O_, bool) attr;
+
+ regional_minima_(const I_& input, const N_& nbh, O_& output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(level::sort_points_increasing(input)),
+ attr(output.domain())
+ {
+ }
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool regional_minima(const Image<I>& input, const
Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels)
+ {
+ typedef impl::regional_minima_<I,N,O> F;
+ F f(exact(input), exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_REGIONAL_MINIMA_HH
Index: mln/labeling/base.hh
--- mln/labeling/base.hh (revision 0)
+++ mln/labeling/base.hh (revision 0)
@@ -0,0 +1,94 @@
+// 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_LABELING_BASE_HH
+# define MLN_LABELING_BASE_HH
+
+/*! \file mln/labeling/base.hh
+ *
+ * \brief Base class for labeling functors.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/canvas/labeling.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ /// Base class for labeling functors.
+ template <typename I_, typename N_, typename O_>
+ struct base_
+ {
+ typedef I_ I;
+ typedef N_ N;
+ typedef O_ O;
+ typedef mln_point(I_) P;
+
+ const I& input;
+ const N& nbh;
+ O& output;
+
+ mln_value(O_) nlabels;
+ bool status;
+
+ base_(const I_& input, const N_& nbh, O_& output)
+ : input(input),
+ nbh(nbh),
+ output(output)
+ {
+ }
+
+ // Defaults.
+
+ bool handles(const P&) const { return true; }
+ bool labels(const P&) const { return true; }
+ void init() {}
+ void do_no_union(const P&, const P&) {}
+ void init_attr(const P&) {}
+ void merge_attr(const P&, const P&) {}
+ };
+
+ } // end of namespace mln::labeling::impl
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_BASE_HH
Index: mln/labeling/regional_maxima.hh
--- mln/labeling/regional_maxima.hh (revision 0)
+++ mln/labeling/regional_maxima.hh (revision 0)
@@ -0,0 +1,120 @@
+// 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_LABELING_REGIONAL_MAXIMA_HH
+# define MLN_LABELING_REGIONAL_MAXIMA_HH
+
+/*! \file mln/labeling/regional_maxima.hh
+ *
+ * \brief Connected component labeling of the regional maxima of an
+ * image.
+ */
+
+# include <mln/labeling/base.hh>
+# include <mln/level/sort_points.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the regional maxima of an
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool regional_maxima(const Image<I>& input, const
Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ template <typename I_, typename N_, typename O_>
+ struct regional_maxima_ : base_<I_,N_,O_>
+ {
+ typedef mln_point(I_) P;
+
+ // requirements from mln::canvas::labeling:
+
+ typedef vec_p<P> S;
+ S s;
+
+ void init() { mln::level::fill(this->output, 0);
+ level::fill(attr, true); }
+ bool labels(const P& p) const { return attr(p); }
+ bool equiv(const P& n, const P& p) const { return input(n) = input(p); }
+ void do_no_union(const P& n, const P& p) { mln_invariant(input(n) >
input(p));
+ attr(p) = false; }
+ void merge_attr(const P& r, const P& p) { attr(p) = attr(p) && attr(r);
}
+
+ // end of requirements
+
+ mln_ch_value(O_, bool) attr;
+
+ regional_maxima_(const I_& input, const N_& nbh, O_& output)
+ : base_<I_,N_,O_>(input, nbh, output),
+ s(level::sort_points_decreasing(input)),
+ attr(output.domain())
+ {
+ }
+ };
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N, typename O>
+ bool regional_maxima(const Image<I>& input, const
Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels)
+ {
+ typedef impl::regional_maxima_<I,N,O> F;
+ F f(exact(input), exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_REGIONAL_MAXIMA_HH
Index: mln/labeling/background.hh
--- mln/labeling/background.hh (revision 0)
+++ mln/labeling/background.hh (revision 0)
@@ -0,0 +1,79 @@
+// 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_LABELING_BACKGROUND_HH
+# define MLN_LABELING_BACKGROUND_HH
+
+/*! \file mln/labeling/background.hh
+ *
+ * \brief Connected component labeling of the background in a binary
+ * image.
+ */
+
+# include <mln/labeling/level.hh>
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /*! Connected component labeling of the background in a binary
+ * image.
+ *
+ * \param[in] input The input image.
+ * \param[in] nbh The neighborhood to consider.
+ * \param[out] output The label image.
+ * \param[out] nlabels The number of labels.
+ *
+ * \return The number of labels.
+ */
+ template <typename I, typename N, typename O>
+ bool background(const Image<I>& input, const Neighborhood<N>&
nbh,
+ Image<O>& output,
+ unsigned& nlabels);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename N, typename O>
+ bool background(const Image<I>& input, const Neighborhood<N>&
nbh,
+ Image<O>& output,
+ unsigned& nlabels)
+ {
+ return labeling::level(input, false, nbh, output, nlabels);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_BACKGROUND_HH