URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-02-06 Fabien Freling <freling(a)lrde.epita.fr>
Implement labeling_video_fastest.
* fabien/labeling.hh: Implement video_fastest.
* fabien/level.cc: Test file.
* fabien/level.hh: Implement fastest implementation.
---
labeling.hh | 22 +++++++++----------
level.cc | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
level.hh | 48 +++++++++++++----------------------------
3 files changed, 96 insertions(+), 43 deletions(-)
Index: trunk/milena/sandbox/fabien/level.hh
===================================================================
--- trunk/milena/sandbox/fabien/level.hh (revision 3310)
+++ trunk/milena/sandbox/fabien/level.hh (revision 3311)
@@ -36,7 +36,9 @@
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
-# include <mln/canvas/labeling.hh>
+
+# include "labeling.hh"
+
# include <mln/data/fill.hh>
@@ -93,35 +95,10 @@
namespace impl
{
-
- struct labeling_functor_base
- {
- void init() {}
-
- template <typename P>
- bool handles(const P&) const { return true; }
-
- template <typename L, typename R>
- bool equiv(const L&, const R&) const { return false; }
-
- template <typename P>
- bool labels(const P&) const { return true; }
-
- template <typename L, typename R>
- void do_no_union(const L&, const R&) {}
-
- template <typename P>
- void init_attr(const P&) {}
-
- template <typename L, typename R>
- void merge_attr(const L&, const R&) {}
- };
-
-
// Generic functor.
template <typename I>
- struct level_functor : labeling_functor_base
+ struct level_functor
{
typedef mln_psite(I) P;
@@ -138,14 +115,19 @@
bool handles(const P& p) const { return input(p) == val; }
bool equiv(const P& n, const P&) const { return input(n) == val; }
bool labels(const P&) const { return true; }
+ void do_no_union(const P& n, const P& p) {}
+ void init_attr(const P&) {}
+ void merge_attr(const P& r, const P& p) {}
// Fastest implementation
void init_() {}
- bool handles_(const P& p) const { return input.element(p) == val; }
- bool equiv_(const P& n, const P&) const { return input.element(n) == val; }
- bool labels_(const P&) const { return true; }
-
+ bool handles_(unsigned p) const { return input.element(p) == val; }
+ bool equiv_(unsigned n, unsigned) const { return input.element(n) == val; }
+ bool labels_(unsigned) const { return true; }
+ void do_no_union_(unsigned n, unsigned p) {}
+ void init_attr_(unsigned) {}
+ void merge_attr_(unsigned r, unsigned p) {}
// end of Requirements.
@@ -156,6 +138,8 @@
}
};
+ } // end of namespace mln::labeling::impl
+
@@ -171,7 +155,7 @@
internal::level_tests(input, val, nbh, nlabels);
mln_ch_value(I, L) output;
- level_functor<I> f(input, val);
+ impl::level_functor<I> f(input, val);
output = canvas::labeling_video(input, nbh, nlabels, f);
trace::exiting("labeling::level");
Index: trunk/milena/sandbox/fabien/labeling.hh
===================================================================
--- trunk/milena/sandbox/fabien/labeling.hh (revision 3310)
+++ trunk/milena/sandbox/fabien/labeling.hh (revision 3311)
@@ -232,7 +232,7 @@
typename F>
mln_ch_value(I, L)
labeling_video_fastest(const Image<I>& input_, const
Neighborhood<N>& nbh_,
- F& f, L& nlabels)
+ L& nlabels, F& f)
{
trace::entering("canvas::impl::labeling_video_fastest");
@@ -273,27 +273,27 @@
{
mln_pixter(const I) p(input);
mln_nixter(const I, N) n(p, nbh);
- for_all(p) if (f.handles_(p))
+ for_all(p) if (f.handles_(p.offset()))
{
// Make-Set.
- parent.element(p) = p;
- f.init_attr(p);
+ parent(p).val() = p;
+ f.init_attr_(p.offset());
for_all(n)
- if (input.domain().has(n) && deja_vu(n))
+ if (input.has(n) && deja_vu(n))
{
- if (f.equiv_(n, p))
+ if (f.equiv_(n.offset(), p.offset()))
{
// Do-Union.
- unsigned r = find_root_fastest(parent, n);
+ unsigned r = find_root_fastest(parent, n.val());
if (r != p)
{
parent.element(r) = p;
- f.merge_attr_(r, p);
+ f.merge_attr_(r, p.offset());
}
}
else
- f.do_no_union_(n, p);
+ f.do_no_union_(n.offset(), p.offset());
}
deja_vu(p) = true;
}
@@ -306,7 +306,7 @@
{
if (parent.element(p) == p) // if p is root
{
- if (f.labels_(p))
+ if (f.labels_(p.offset()))
{
if (nlabels == mln_max(L))
{
@@ -488,7 +488,7 @@
&&
mln_is_simple_neighborhood(N)::value
};
- return impl::generic::labeling(metal::bool_<test>(), input,
+ return labeling_video(metal::bool_<test>(), input,
nbh, nlabels, functor);
}
Index: trunk/milena/sandbox/fabien/level.cc
===================================================================
--- trunk/milena/sandbox/fabien/level.cc (revision 0)
+++ trunk/milena/sandbox/fabien/level.cc (revision 3311)
@@ -0,0 +1,69 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// 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/level.cc
+///
+/// Test on mln::labeling::level.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/load.hh>
+
+#include <mln/accu/count.hh>
+#include <mln/accu/compute.hh>
+
+#include "level.hh"
+
+#include <mln/pw/all.hh>
+#include <mln/core/image/image_if.hh>
+
+#include <mln/debug/println.hh>
+
+#include <tests/data.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> lena = io::pgm::load<int_u8>(MLN_IMG_DIR
"/tiny.pgm");
+ image2d<bool> lvl(lena.domain());
+
+ unsigned n, npixels = 0;
+ for (unsigned l = 0; l <= 255; ++l)
+ {
+ image2d<unsigned> labels = labeling::level(lena, l, c4(), n);
+ unsigned npix =
+ accu::compute(accu::meta::count(),
+ labels | (pw::value(labels) != pw::cst(0u)));
+ npixels += npix;
+ }
+ mln_assertion(npixels == lena.nsites());
+}