URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-09-18 Guillaume Duhamel <guillaume.duhamel(a)lrde.epita.fr>
Add labeling and update border.
* canvas_labeling.hh: Copy from mln/canvas/labeling.hh.
* labeling_level.hh: Specialize with fast image.
* border_duplicate.cc,
* border_duplicate.hh,
* border_fill.cc,
* border_fill.hh: Update.
---
border_duplicate.cc | 22 ++--
border_duplicate.hh | 1
border_fill.cc | 2
border_fill.hh | 8 +
canvas_labeling.hh | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++
labeling_level.hh | 147 +++++++++++++++++++++++++++
6 files changed, 441 insertions(+), 14 deletions(-)
Index: trunk/milena/sandbox/duhamel/border_fill.hh
===================================================================
--- trunk/milena/sandbox/duhamel/border_fill.hh (revision 1124)
+++ trunk/milena/sandbox/duhamel/border_fill.hh (revision 1125)
@@ -42,6 +42,7 @@
#include <mln/core/image2d_b.hh>
#include <mln/core/image2d_b.hh>
#include <mln/core/pixel.hh>
+#include <mln/core/line_piter.hh>
namespace mln
{
@@ -83,11 +84,14 @@
point2d p = ima.bbox ().pmin ();
// FIXME : REMOVE THIS LOOP BY MEMSET
- for (std::size_t i = 0; i < border * (2 * (border + 1) + nbcols); ++i)
+
+ std::size_t s = border * (2 * (border + 1) + nbcols);
+ for (std::size_t i = 0; i < s; ++i)
const_cast<I&>(ima)[i] = v;
// ACCESS TO RIGHT UP CORNER
- for (std::size_t i = 0; i < nbcols + 1; ++i)
+ s = nbcols + 1;
+ for (std::size_t i = 0; i < s; ++i)
p = p + right;
// FILL BORDER
Index: trunk/milena/sandbox/duhamel/border_duplicate.cc
===================================================================
--- trunk/milena/sandbox/duhamel/border_duplicate.cc (revision 1124)
+++ trunk/milena/sandbox/duhamel/border_duplicate.cc (revision 1125)
@@ -41,21 +41,21 @@
int
main (void)
{
- image2d_b<value::int_u8> i1(5, 7);
+ image2d_b<value::int_u8> i1(10000, 1000);
// Fill with randomized value.
- for (unsigned int i = 0; i < i1.ncells (); ++i)
- i1[i] = i;//(i * 4452) % 10;
- std::cout << "before duplicate"
- << std::endl
- << std::endl;
- debug::println_with_border(i1);
+// for (unsigned int i = 0; i < i1.ncells (); ++i)
+// i1[i] = i;//(i * 4452) % 10;
+// std::cout << "before duplicate"
+// << std::endl
+// << std::endl;
+// debug::println_with_border(i1);
border::duplicate (i1);
- std::cout << "after duplicate"
- << std::endl
- << std::endl;
- debug::println_with_border(i1);
+// std::cout << "after duplicate"
+// << std::endl
+// << std::endl;
+// debug::println_with_border(i1);
}
Index: trunk/milena/sandbox/duhamel/labeling_level.hh
===================================================================
--- trunk/milena/sandbox/duhamel/labeling_level.hh (revision 0)
+++ trunk/milena/sandbox/duhamel/labeling_level.hh (revision 1125)
@@ -0,0 +1,147 @@
+// 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
+ {
+
+ // Functors.
+
+ template <typename I_, typename N_, typename O_>
+ struct level_t : 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_t(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)
+ {}
+ };
+
+ // Routines.
+
+ 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)
+ {
+ typedef impl::level_t<I,N,O> F;
+ F f(exact(input), val, exact(nbh), exact(output));
+ canvas::labeling<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+ // FIXME: Add fast versions.
+
+ // FIXME (ADD)
+ //
+ template <typename I, typename N, typename O>
+ bool level_(const Fast_Image<I>& input, const mln_value(I)& val,
const Neighborhood<N>& nbh,
+ Image<O>& output, unsigned& nlabels)
+ {
+ typedef impl::level_t<I,N,O> F;
+ F f(exact(input), val, exact(nbh), exact(output));
+ canvas::labeling_fast<F> run(f);
+ nlabels = f.nlabels;
+ return f.status;
+ }
+
+ //
+ //END FIXME (ADD)
+
+ } // 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());
+ return impl::level_(exact(input), val, nbh, output, nlabels);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_LEVEL_HH
Index: trunk/milena/sandbox/duhamel/border_duplicate.hh
===================================================================
--- trunk/milena/sandbox/duhamel/border_duplicate.hh (revision 1124)
+++ trunk/milena/sandbox/duhamel/border_duplicate.hh (revision 1125)
@@ -79,6 +79,7 @@
std::size_t real_nbcols = (nbcols + 1) + 2 * border;
std::size_t start = real_nbcols * border + border;
std::size_t s = start;
+
// duplicate top left corner
for (std::size_t i = 0; i < border + 1; ++i)
for (std::size_t j = 0; j < border + 1; ++j)
Index: trunk/milena/sandbox/duhamel/canvas_labeling.hh
===================================================================
--- trunk/milena/sandbox/duhamel/canvas_labeling.hh (revision 0)
+++ trunk/milena/sandbox/duhamel/canvas_labeling.hh (revision 1125)
@@ -0,0 +1,275 @@
+// 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>
+
+# include <mln/convert/to_window.hh>
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ // General version.
+
+ 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);
+ 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);
+ }
+ }
+
+ };
+
+
+ // FIXME: Fast version.
+
+ // FIXME (ADD)
+ //
+ template <typename F>
+ struct labeling_fast
+ {
+ 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;
+
+ labeling_fast(F& f)
+ : f(f)
+ {
+ run();
+ }
+
+ void run()
+ {
+ // init
+ {
+ f.nlabels = 0;
+ f.init();
+ }
+ // first pass
+ {
+ typedef mln_dpoint(N) DP;
+ typedef mln_point(N) P;
+ typedef window<DP> W;
+
+ mln_fwd_pixter(const I) pix_input(f.input);
+ W win = convert::to_window(f.nbh);
+
+ mln_qiter(W) q_input(win, P::zero);
+
+ for_all(pix_input)
+ {
+// if (f.handles(pix_input))
+// {
+ const point p = pix_input;
+ make_set(p);
+ for_all(q_input)
+ {
+// const point q;
+// if (f.equiv(q, p))
+// do_union(q, p);
+// else
+// f.do_no_union(q, p);
+ }
+// }
+ }
+ }
+
+// // second pass
+// {
+// mln_bkd_piter(S) p(f.s);
+// 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 FIXME (ADD)
+
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_LABELING_HH
Index: trunk/milena/sandbox/duhamel/border_fill.cc
===================================================================
--- trunk/milena/sandbox/duhamel/border_fill.cc (revision 1124)
+++ trunk/milena/sandbox/duhamel/border_fill.cc (revision 1125)
@@ -41,7 +41,7 @@
int
main (void)
{
- image2d_b<value::int_u8> i1(9, 7);
+ image2d_b<value::int_u8> i1(9, 6);
border::fill (i1, 8);
debug::println_with_border(i1);