Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add attribute image computation from a morpho tree.
* mln/morpho/tree/compute_attribute_image.hh: New.
* mln/morpho/tree/all.hh: Update.
* mln/morpho/tree/data.hh (function): New typedef.
(f): New method.
* mln/canvas/labeling.hh: Fix indentation.
Add dispatch.
* tests/morpho/tree/compute_attribute_image.cc: New.
* tests/morpho/tree/Makefile.am: Update.
* doc/examples/tuto_bis.cc (main): Fix missing update.
doc/examples/tuto_bis.cc | 2
mln/canvas/labeling.hh | 93 +++++++++++++++++---
mln/morpho/tree/all.hh | 1
mln/morpho/tree/compute_attribute_image.hh | 124 +++++++++++++++++++++++++++
mln/morpho/tree/data.hh | 9 +
tests/morpho/tree/Makefile.am | 2
tests/morpho/tree/compute_attribute_image.cc | 81 +++++++++++++++++
7 files changed, 299 insertions(+), 13 deletions(-)
Index: tests/morpho/tree/compute_attribute_image.cc
--- tests/morpho/tree/compute_attribute_image.cc (revision 0)
+++ tests/morpho/tree/compute_attribute_image.cc (revision 0)
@@ -0,0 +1,81 @@
+// Copyright (C) 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/morpho/tree/compute_attribute_image.cc
+///
+/// Tests on mln::morpho::tree::compute_attribute_image.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/site_set/p_array.hh>
+#include <mln/level/sort_psites.hh>
+
+#include <mln/debug/println.hh>
+#include <mln/core/var.hh>
+
+#include <mln/morpho/tree/data.hh>
+#include <mln/morpho/tree/compute_attribute_image.hh>
+
+#include <mln/accu/count.hh>
+#include <mln/accu/volume.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ {
+ unsigned vals[] = { 5, 6, 6,
+ 8, 9, 9,
+ 8, 9, 9 };
+
+ typedef image2d<unsigned> I;
+ I f = make::image2d(vals);
+ debug::println(f);
+
+ typedef p_array<point2d> S;
+ S s = level::sort_psites_increasing(f);
+
+ morpho::tree::data<I,S> t(f, s, c4());
+ debug::println(t.parent_image());
+
+ typedef util::pix<I> Px;
+
+ {
+ accu::count<Px> a;
+ image2d<unsigned> area = morpho::tree::compute_attribute_image(a, t);
+ debug::println(area);
+ }
+
+ {
+ accu::volume<I> v;
+ image2d<unsigned> volume = morpho::tree::compute_attribute_image(v, t);
+ debug::println(volume);
+ }
+ }
+
+}
Index: tests/morpho/tree/Makefile.am
--- tests/morpho/tree/Makefile.am (revision 2952)
+++ tests/morpho/tree/Makefile.am (working copy)
@@ -3,10 +3,12 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
+ compute_attribute_image \
compute_tree \
data \
max
+compute_attribute_image_SOURCES = compute_attribute_image.cc
compute_tree_SOURCES = compute_tree.cc
data_SOURCES = data.cc
max_SOURCES = max.cc
Index: doc/examples/tuto_bis.cc
--- doc/examples/tuto_bis.cc (revision 2952)
+++ doc/examples/tuto_bis.cc (working copy)
@@ -223,7 +223,7 @@
image2d<int> ima(3, 5);
mln_VAR(cell, ima | is_cell);
- level::fill(cell, fun::p2v::iota);
+ level::fill(cell, fun::p2v::iota());
debug::println(cell);
// 1 2 3
//
Index: mln/morpho/tree/compute_attribute_image.hh
--- mln/morpho/tree/compute_attribute_image.hh (revision 0)
+++ mln/morpho/tree/compute_attribute_image.hh (revision 0)
@@ -0,0 +1,124 @@
+// Copyright (C) 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.
+
+#ifndef MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
+# define MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
+
+/// \file mln/morpho/tree/compute_attribute_image.hh
+///
+/// Compute a canonized tree from an image.
+///
+/// \todo Specialize for low quant (and try fastest).
+
+# include <mln/core/concept/image.hh>
+# include <mln/util/pix.hh>
+# include <mln/level/fill.hh>
+# include <mln/level/paste.hh>
+
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace tree
+ {
+
+ /// Compute a tree with a parent relationship between sites.
+ ///
+ /// Warning: \p s translates the ordering related to the
+ /// "natural" childhood relationship. The parenthood is thus
+ /// inverted w.r.t. to \p s.
+ ///
+ /// It is very convenient since all processing upon the parent
+ /// tree are performed following \p s (in the default "forward"
+ /// way).
+ ///
+ /// FIXME: Put it more clearly...
+ ///
+ /// The parent result image verifies: \n
+ /// - p is root iff parent(p) == p \n
+ /// - p is a node iff either p is root or f(parent(p)) != f(p).
+
+ template <typename A, typename T>
+ mln_ch_value(typename T::function, mln_result(A))
+ compute_attribute_image(const Accumulator<A>& a, const T& t);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade.
+
+ template <typename A, typename T>
+ inline
+ mln_ch_value(typename T::function, mln_result(A))
+ compute_attribute_image(const Accumulator<A>& a_, const T& t)
+ {
+ trace::entering("morpho::tree::compute_attribute_image");
+
+ const A& a = exact(a_);
+
+ typedef typename T::function I;
+ mln_ch_value(I, A) acc;
+ initialize(acc, t.f());
+
+ {
+ mln_piter(I) p(t.f().domain());
+ for_all(p)
+ acc(p).take_as_init(make::pix(t.f(), p));
+ }
+ {
+ mln_piter(T) p(t.domain());
+ for_all(p)
+ if (! t.is_root(p))
+ acc(t.parent(p)).take(acc(p));
+ }
+
+ typedef typename T::function I;
+ mln_ch_value(I, mln_result(A)) output;
+ initialize(output, acc);
+ // level::fill(output, acc);
+ level::paste(acc, output);
+
+ trace::exiting("morpho::tree::compute_attribute_image");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::tree
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_TREE_COMPUTE_ATTRIBUTE_IMAGE_HH
Index: mln/morpho/tree/all.hh
--- mln/morpho/tree/all.hh (revision 2952)
+++ mln/morpho/tree/all.hh (working copy)
@@ -46,6 +46,7 @@
}
+# include <mln/morpho/tree/compute_attribute_image.hh>
# include <mln/morpho/tree/compute_parent.hh>
# include <mln/morpho/tree/data.hh>
# include <mln/morpho/tree/max.hh>
Index: mln/morpho/tree/data.hh
--- mln/morpho/tree/data.hh (revision 2952)
+++ mln/morpho/tree/data.hh (working copy)
@@ -54,6 +54,10 @@
public:
+ /// Associated type of the function f.
+ typedef I function;
+
+
/// Ctor.
template <typename N>
data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh);
@@ -135,6 +139,11 @@
return nroots_;
}
+ const I& f() const
+ {
+ return f_;
+ }
+
protected:
const I& f_;
Index: mln/canvas/labeling.hh
--- mln/canvas/labeling.hh (revision 2952)
+++ mln/canvas/labeling.hh (working copy)
@@ -56,12 +56,42 @@
# ifndef MLN_INCLUDE_ONLY
+ // Tests.
+
+ namespace internal
+ {
+
+ template <typename I, typename N, typename F, typename L>
+ void
+ labeling_tests(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ const F& f, const L& nlabels)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.has_data());
+ // mln_precondition(nbh.is_valid());
+
+ (void) input;
+ (void) nbh;
+ }
+
+ } // end of namespace mln::canvas::internal
+
+
+
+ // Implementations.
+
+ namespace impl
+ {
+
+ namespace generic
+ {
template <typename I>
static inline
mln_psite(I)
- find_root(I& parent,
- const mln_psite(I)& x)
+ find_root(I& parent, const mln_psite(I)& x)
{
if (parent(x) == x)
return x;
@@ -74,7 +104,7 @@
labeling(const Image<I>& input_, const Neighborhood<N>& nbh_,
F& f, L& nlabels)
{
- trace::entering("canvas::labeling");
+ trace::entering("canvas::impl::generic::labeling");
// FIXME: Test?!
@@ -95,7 +125,6 @@
bool status;
// Initialization.
-
{
initialize(deja_vu, input);
mln::level::fill(deja_vu, false);
@@ -110,18 +139,14 @@
}
// First Pass.
-
{
mln_fwd_piter(S) p(f.s);
mln_niter(N) n(nbh, p);
for_all(p) if (f.handles(p))
{
-
// Make-Set.
- {
parent(p) = p;
f.init_attr(p);
- }
for_all(n)
if (input.domain().has(n) && deja_vu(n))
@@ -143,7 +168,7 @@
}
}
- // Second Pass. pass_2();
+ // Second Pass.
{
mln_bkd_piter(S) p(f.s);
for_all(p) if (f.handles(p))
@@ -164,13 +189,18 @@
output(p) = output(parent(p));
}
status = true;
-
}
- trace::exiting("canvas::labeling");
+ trace::exiting("canvas::impl::generic::labeling");
return output;
}
+ } // end of namespace mln::canvas::impl::generic
+
+ } // end of namespace mln::canvas::impl
+
+
+
@@ -324,9 +354,48 @@
*/
-# endif // ! MLN_INCLUDE_ONLY
+ // Dispatch.
+
+ namespace internal
+ {
+
+ template <typename I, typename N, typename F, typename L>
+ inline
+ mln_ch_value(I, L)
+ labeling_dispatch(const Image<I>& input, const Neighborhood<N>& nbh,
+ F& functor, L& nlabels)
+ {
+ return impl::generic::labeling(input, nbh, functor, nlabels);
+ }
+
+ } // end of namespace mln::canvas::internal
+
+
+
+ // Facade.
+
+ template <typename I, typename N, typename F, typename L>
+ inline
+ mln_ch_value(I, L)
+ labeling(const Image<I>& input, const Neighborhood<N>& nbh,
+ F& functor, L& nlabels)
+ {
+ trace::entering("canvas::labeling");
+
+ internal::labeling_tests(input, nbh, functor, nlabels);
+
+ mln_ch_value(I, L) output;
+ output = internal::labeling_dispatch(input, nbh, functor, nlabels);
+
+ trace::exiting("canvas::labeling");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
} // end of namespace mln::canvas
} // end of namespace mln
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2008-11-26 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Try an auto dual area filter using TUFA.
* garrigues/area_filter_auto_dual.cc: New, the test.
---
area_filter_auto_dual.cc | 268 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 268 insertions(+)
Index: trunk/milena/sandbox/garrigues/area_filter_auto_dual.cc
===================================================================
--- trunk/milena/sandbox/garrigues/area_filter_auto_dual.cc (revision 0)
+++ trunk/milena/sandbox/garrigues/area_filter_auto_dual.cc (revision 2952)
@@ -0,0 +1,268 @@
+// 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.
+
+#ifndef MLN_AREA_FILTER_HH
+# define MLN_AREA_FILTER_HH
+
+# include <mln/core/image/image2d.hh>
+# include <mln/level/fill.hh>
+# include <mln/literal/zero.hh>
+# include <mln/convert/to_upper_window.hh>
+# include <mln/accu/count.hh>
+# include <mln/util/pix.hh>
+
+# include <mln/core/alias/neighb2d.hh>
+
+# include <mln/io/pbm/save.hh>
+# include <mln/io/pbm/load.hh>
+
+namespace mln
+{
+
+
+ template <typename I>
+ static inline
+ mln_psite(I)
+ find_root(I& parent,
+ const mln_psite(I)& x)
+ {
+ if (parent(x) == x)
+ return x;
+ else
+ return parent(x) = find_root(parent, parent(x));
+ }
+
+ template <typename I, typename N, typename F, typename O>
+ void
+ algebraic_union_find(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ F& f,
+ Image<O>& output_)
+ {
+ trace::entering("canvas::morpho::algebraic_union_find");
+
+ // FIXME: Tests?
+
+ typedef typename F::S S;
+ typedef typename F::A A;
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ O& output = exact(output_);
+
+ mln_precondition(output.domain() == input.domain());
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ // Auxiliary data.
+ mln_ch_value(O, bool) deja_vu;
+ mln_ch_value(O, P) parent;
+ mln_ch_value(O, A) data;
+
+ // init
+ {
+ initialize(deja_vu, input);
+ mln::level::fill(deja_vu, false);
+ initialize(parent, input);
+ initialize(data, input);
+ f.init(); // init required.
+ }
+
+ // first pass
+ {
+ mln_fwd_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+
+ if (input(p) == true)
+ // Body for foreground
+ {
+ // Make set.
+ parent(p) = p;
+ data(p).take_as_init(make::pix(input, p));
+
+ for_all(n)
+ if (input.domain().has(n) && input(n) && deja_vu(n))
+ {
+ //do_union(n, p);
+ P r = find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || f.is_active(data(r))) // Equiv(r, p)
+ // Either a flat zone or the component of r is still growing.
+ {
+ // p is now the new root.
+ data(p).take(data(r));
+ parent(r) = p;
+ }
+ else
+ // Stop the growing connected component.
+ f.inactivate(data(p));
+ }
+ }
+ deja_vu(p) = true;
+ }
+ else
+ // Body for background
+ {
+ // Make set.
+ parent(p) = p;
+ data(p).take_as_init(make::pix(input, p));
+
+ for_all(n)
+ if (input.domain().has(n) && !input(n) && deja_vu(n))
+ {
+ //do_union(n, p);
+ P r = find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || f.is_active(data(r))) // Equiv(r, p)
+ // Either a flat zone or the component of r is still growing.
+ {
+ data(p).take(data(r));
+ parent(r) = p;
+ }
+ else
+ f.inactivate(data(p));
+ }
+ }
+ deja_vu(p) = true;
+
+ }
+
+
+ }
+ }
+
+ // second pass
+ {
+ mln_bkd_piter(I) p(input.domain());
+ for_all(p)
+ if (input(p)) // Foreground
+ if (parent(p) == p)
+ output(p) = !f.is_active(data(p));
+ else
+ output(p) = output(parent(p));
+ else // Background.
+ if (parent(p) == p)
+ output(p) = f.is_active(data(p));
+ else
+ output(p) = output(parent(p));
+ }
+
+ trace::exiting("canvas::morpho::algebraic_union_find");
+ }
+
+
+ struct area_filter_t
+ {
+ // requirements from mln::canvas::morpho::algebraic_union_find
+
+ typedef image2d<bool> I;
+ typedef util::pix<I> pix_t;
+ typedef accu::count<pix_t> A;
+ typedef mln_psite_(I) P;
+ typedef p_array<P> S;
+
+ mln_result_(A) lambda;
+
+ inline
+ void init()
+ {
+ }
+
+ inline
+ bool is_active(const A& attr) const
+ {
+ return attr.to_result() < lambda;
+ }
+
+ inline
+ void inactivate(A& attr)
+ {
+ attr.set_value(lambda);
+ }
+
+ // end of requirements
+
+ inline
+ area_filter_t(const image2d<bool>& input, mln_result_(A) lambda)
+ : lambda(lambda)
+ {
+ }
+
+ };
+
+
+
+ template <typename N>
+ inline
+ void area_filter(const image2d<bool>& input,
+ const Neighborhood<N>& nbh, unsigned lambda,
+ image2d<bool>& output)
+ {
+ typedef area_filter_t F;
+ F f(input, lambda);
+ algebraic_union_find(input, nbh, f, output);
+ }
+
+} // end of namespace mln
+
+int main(int argc, char** argv)
+{
+ using namespace mln;
+ image2d<bool> input;
+
+ if (argc < 2)
+ {
+ std::cerr << "Usage: " << argv[0] << " in.pbm area out.pbm" << std::endl;
+ return 1;
+ }
+
+ io::pbm::load(input, argv[1]);
+
+
+ image2d<bool> output1(input.domain());
+ image2d<bool> output2(input.domain());
+ image2d<bool> output3(input.domain());
+ image2d<bool> output4(input.domain());
+
+ area_filter(input, c4(), atoi(argv[2]), output1);
+ area_filter(output1, c4(), atoi(argv[2]), output2);
+ area_filter(output2, c4(), atoi(argv[2]), output3);
+ area_filter(output3, c4(), atoi(argv[2]), output4);
+
+ io::pbm::save(output1, "out1.pgm");
+ io::pbm::save(output2, "out2.pgm");
+ io::pbm::save(output3, "out3.pgm");
+ io::pbm::save(output3, "out4.pgm");
+}
+
+#endif // ! MLN_AREA_FILTER_HH
1
0
25 Nov '08
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2008-11-25 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Test skeletonization with pixel superiority index.
* garrigues/ocr/ocr_with_preprocess.cc: Apply the skeletonisation
using infomation of the grayscale image.
* garrigues/ocr/skeleton.hh: Use the pixel superiority index criteria
to detect crests.
---
ocr_with_preprocess.cc | 75 ++++++++++++++++++++++++-------------------------
skeleton.hh | 10 +++++-
2 files changed, 45 insertions(+), 40 deletions(-)
Index: trunk/milena/sandbox/garrigues/ocr/skeleton.hh
===================================================================
--- trunk/milena/sandbox/garrigues/ocr/skeleton.hh (revision 2950)
+++ trunk/milena/sandbox/garrigues/ocr/skeleton.hh (revision 2951)
@@ -92,6 +92,7 @@
unsigned nb_eq = 0;
unsigned nb_gt = 0;
+ unsigned nb_lt = 0;
for_all(n)
if (input.domain().has(n))
{
@@ -99,10 +100,15 @@
nb_eq++;
else if (dist_map(n) > dist_map(p))
nb_gt++;
+ else
+ nb_lt++;
}
- if ((nb_gt == 1 && nb_eq == 0) ||
- (nb_gt == 0))
+
+// if ((nb_gt == 1 && nb_eq == 0) ||
+// (nb_gt == 0))
+
+ if ((nb_lt + nb_eq) > 5) // Pixel Superiority index
is_crest(p) = true;
}
return is_crest;
Index: trunk/milena/sandbox/garrigues/ocr/ocr_with_preprocess.cc
===================================================================
--- trunk/milena/sandbox/garrigues/ocr/ocr_with_preprocess.cc (revision 2950)
+++ trunk/milena/sandbox/garrigues/ocr/ocr_with_preprocess.cc (revision 2951)
@@ -95,7 +95,6 @@
mln::border::thickness = 0;
io::pbm::load(input, argv[1]);
-// OCR_TEST(input);
// Resize
image2d<int_u8> enlarged = enlarge(logical::not_(input), 2);
@@ -105,64 +104,64 @@
// Blur.
image2d<int_u8> blur = linear::gaussian(enlarged, 2);
-
io::pgm::save(blur, std::string(argv[2]) + "_2_gaussian.pgm");
OCR_TEST(blur);
- // Threshold
- image2d<bool> binary;
- {
- initialize(binary, blur);
- mln_piter_(image2d<int_u8>) p(blur.domain());
- for_all(p)
- binary(p) = blur(p) > 100;
-
- io::pbm::save(binary, std::string(argv[2]) + "_3_threshold.pbm");
- OCR_TEST(binary);
- }
+// // Threshold
+// image2d<bool> binary;
+// {
+// initialize(binary, blur);
+// mln_piter_(image2d<int_u8>) p(blur.domain());
+// for_all(p)
+// binary(p) = blur(p) > 100;
+
+// io::pbm::save(binary, std::string(argv[2]) + "_3_threshold.pbm");
+// OCR_TEST(binary);
+// }
+
+// // Skeleton
+// image2d<bool> skel = skeleton(binary, 4);
+// io::pbm::save(skel, std::string(argv[2]) + "_4_skeleton.pbm");
+// OCR_TEST(skel);
+
+// // Dilation
+// win::octagon2d oct(5);
+// image2d<bool> dilate = morpho::dilation(skel, oct);
+// border::resize(dilate, 0);
+// io::pbm::save(dilate, std::string(argv[2]) + "_5_dilation.pbm");
+// OCR_TEST(dilate);
+
+// // Subsampling
+// image2d<bool> subsampled = subsampling::subsampling(dilate, dpoint2d(1,1), 2);
+// io::pbm::save(subsampled, std::string(argv[2]) + "_6_subsampling.pbm");
+// OCR_TEST(subsampled);
- // Skeleton
- image2d<bool> skel = skeleton(binary, 4);
- io::pbm::save(skel, std::string(argv[2]) + "_4_skeleton.pbm");
- OCR_TEST(skel);
+// io::pbm::save(subsampled, argv[2]);
- // Dilation
- win::octagon2d oct(5);
- image2d<bool> dilate = morpho::dilation(skel, oct);
- border::resize(dilate, 0);
- io::pbm::save(dilate, std::string(argv[2]) + "_5_dilation.pbm");
- OCR_TEST(dilate);
- // Subsampling
- image2d<bool> subsampled = subsampling::subsampling(dilate, dpoint2d(1,1), 2);
- io::pbm::save(subsampled, std::string(argv[2]) + "_6_subsampling.pbm");
- OCR_TEST(subsampled);
-
- io::pbm::save(subsampled, argv[2]);
-
-
- image2d<bool> K = crest(big, blur, c4());
+ image2d<bool> K = crest(big, blur, c8());
OCR_TEST(K);
- io::pbm::save(K, std::string(argv[2]) + "_7_K.pbm");
+ io::pbm::save(K, std::string(argv[2]) + "_6_K.pbm");
- image2d<bool> skel_on_gaussian = skeleton_with_constraint(big, 4, K, arith::revert(blur));
+ image2d<bool> skel_on_gaussian = skeleton_with_constraint(big, 8, K, arith::revert(blur));
OCR_TEST(skel_on_gaussian);
- io::pbm::save(skel_on_gaussian, std::string(argv[2]) + "_8_skeleton_on_blur.pbm");
+ io::pbm::save(skel_on_gaussian, std::string(argv[2]) + "_7_skeleton_on_gaussian.pbm");
// Dilation
+ win::octagon2d oct(5);
image2d<bool> dilate_on_gaussian = morpho::dilation(skel_on_gaussian, oct);
border::resize(dilate_on_gaussian, 0);
- io::pbm::save(dilate_on_gaussian, std::string(argv[2]) + "_9_dilation_on_gaussian.pbm");
+ io::pbm::save(dilate_on_gaussian, std::string(argv[2]) + "_8_dilation_on_gaussian.pbm");
OCR_TEST(dilate_on_gaussian);
// Subsampling
image2d<bool> subsampled_on_gaussian = subsampling::subsampling(dilate_on_gaussian, dpoint2d(1,1), 2);
- io::pbm::save(subsampled_on_gaussian, std::string(argv[2]) + "_91_subsampling_on_gaussian.pbm");
+ io::pbm::save(subsampled_on_gaussian, std::string(argv[2]) + "_9_subsampling_on_gaussian.pbm");
OCR_TEST(subsampled_on_gaussian);
{
float score = 0;
- char* s = tesseract("fra", subsampled, &score);
+ char* s = tesseract("fra", subsampled_on_gaussian, &score);
std::cerr << "Tesseract result: (score " << score << ")" << std::endl;
std::cout << s;
delete[] s;
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Update n_cmpt.
* jardonnet/n_cmpt/Makefile: Add warning.
* jardonnet/n_cmpt/check/test.pgm,
* jardonnet/n_cmpt/check/test2.pgm,
* jardonnet/n_cmpt/check/test3.pgm: New test images.
* jardonnet/n_cmpt/n_cmpt.hh: Go back to last lambda if
not enought components.
Makefile | 4 ++--
n_cmpt.hh | 60 ++++++++++++++++++++++++++++++++++++++++++------------------
2 files changed, 44 insertions(+), 20 deletions(-)
Index: jardonnet/n_cmpt/Makefile
--- jardonnet/n_cmpt/Makefile (revision 2949)
+++ jardonnet/n_cmpt/Makefile (working copy)
@@ -1,5 +1,5 @@
n_cmpt: n_cmpt.hh n_cmpt.cc
- g++ -I../../.. n_cmpt.cc -DNDEBUG -O1 -o n_cmpt
+ g++ -I../../.. -Wall -W -Wextra n_cmpt.cc -DNDEBUG -O1 -o n_cmpt
debug: n_cmpt.hh n_cmpt.cc
- g++ -I../../.. n_cmpt.cc -g -g3 -DNDEBUG -O1 -o n_cmpt
+ g++ -I../../.. -Wall -W -Wextra n_cmpt.cc -g -g3 -DNDEBUG -O1 -o n_cmpt
Index: jardonnet/n_cmpt/check/test.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: jardonnet/n_cmpt/check/test.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: jardonnet/n_cmpt/check/test2.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: jardonnet/n_cmpt/check/test2.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: jardonnet/n_cmpt/check/test3.pgm
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: jardonnet/n_cmpt/check/test3.pgm
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: jardonnet/n_cmpt/n_cmpt.hh
--- jardonnet/n_cmpt/n_cmpt.hh (revision 2949)
+++ jardonnet/n_cmpt/n_cmpt.hh (working copy)
@@ -33,6 +33,8 @@
# include <mln/level/fill.hh>
# include <mln/util/pix.hh>
# include <mln/level/sort_psites.hh>
+# include <mln/accu/count.hh>
+# include <mln/accu/volume.hh>
namespace mln
{
@@ -77,6 +79,7 @@
typedef mln_psite(I) P;
typedef accu::volume<I> A;
+ //typedef accu::count<unsigned> A;
typedef mln_psite(I) P;
typedef p_array<P> S;
@@ -87,8 +90,10 @@
mln_ch_value(O, P) parent;
int n_cmpt = input.domain().nsites();
- int lambda = 10;
- std::cout << "trying lambda = 10" << std::endl;
+
+ std::cout << "Number of sites = " << n_cmpt << std::endl;
+
+ unsigned lambda = 2;
// init
{
@@ -96,61 +101,80 @@
initialize(parent, input);
}
- // first pass
- {
+ bool last = false;
+ // first pass
do {
+ std::cout << "lambda=" << lambda << "-------" << std::endl;
+
+ // init
mln_ch_value(O, A) data;
initialize(data, input);
-
mln::level::fill(deja_vu, false);
-
{
mln_fwd_piter(S) p(s);
for_all(p)
parent(p) = p;
}
+ // process
mln_fwd_piter(S) p(s); // s required.
mln_niter(N) n(nbh, p);
for_all(p)
{
// Make set.
- {
data(p).take_as_init(make::pix(input, p)); // FIXME: algebraic so p!
- }
-
+ //data(p).take_as_init(1);
for_all(n)
+ {
if (input.domain().has(n) && deja_vu(n))
{
//do_union(n, p);
P r = find_root(parent, n);
if (r != p)
{
- if (input(r) == input(p) || (data(p).to_result() < lambda))
+ //std::cout << data(p).to_result() << std::endl;
+ if (input(r) == input(p) || (data(p).to_result() <= lambda))
// Either a flat zone or the component of r is still growing.
{
- data(p).take(data(r));
- parent(r) = p;
- if(--n_cmpt <= limit)
+ if(--n_cmpt < limit)
{
- std::cout << "limit reached at " << n_cmpt << std::endl;
- goto step2;
+ std::cout << "find less than " << limit << " cmpts" << std::endl;
+ std::cout << "Using last lambda" << std::endl;
+ lambda /= 1.5;
+ last = true;
+ goto end;
}
+ data(p).take(data(r));
+ parent(r) = p;
}
else
+ {
data(p).set_value(lambda);
}
+
+ }
+ }
}
deja_vu(p) = true;
}
+
+ if (n_cmpt == limit)
+ {
+ std::cout << "EXACT MATCH. n_cpmt = " << n_cmpt << std::endl;
+ goto step2;
+ }
+
+ if (last)
+ goto step2;
+
+ lambda *= 1.5;
+ end:
n_cmpt = input.domain().nsites();
- lambda *= 1.1;
- std::cout << "trying lambda = " << lambda << std::endl;
}while (1);
- }
step2:
+ std::cout << "FINAL. n_cpmt = " << n_cmpt << std::endl;
// second pass
{
mln_bkd_piter(S) p(s);
1
0
* mln/make/graph.hh: Fix use of label<n>.
* mln/util/edge.hh: cleanup comment.
* mln/util/dual_graph.hh: rename as...
* mln/util/line_graph.hh: ... this. Fiw wrong initialization.
* tests/util/Makefile.am: update.
* tests/util/dual_graph.cc: rename as...
* tests/util/line_graph.cc: ... this. Enable all the tests.
* mln/core/concept/graph.hh,
* mln/util/internal/graph_base.hh,
* mln/util/graph.hh: rename graph_id to id.
---
milena/ChangeLog | 20 +++
milena/mln/core/concept/graph.hh | 24 ++--
milena/mln/make/graph.hh | 2 +-
milena/mln/util/edge.hh | 2 +-
milena/mln/util/graph.hh | 23 +++-
milena/mln/util/internal/graph_base.hh | 6 +-
milena/mln/util/{dual_graph.hh => line_graph.hh} | 152 ++++++++++++++------
milena/tests/util/Makefile.am | 4 +-
milena/tests/util/{dual_graph.cc => line_graph.cc} | 109 +++++++-------
9 files changed, 224 insertions(+), 118 deletions(-)
rename milena/mln/util/{dual_graph.hh => line_graph.hh} (68%)
rename milena/tests/util/{dual_graph.cc => line_graph.cc} (61%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 959337a..cf63c58 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,25 @@
2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix line_graph (formerly dual_graph)
+
+ * mln/make/graph.hh: Fix use of label<n>.
+
+ * mln/util/edge.hh: cleanup comment.
+
+ * mln/util/dual_graph.hh: rename as...
+ * mln/util/line_graph.hh: ... this. Fiw wrong initialization.
+
+ * tests/util/Makefile.am: update.
+
+ * tests/util/dual_graph.cc: rename as...
+ * tests/util/line_graph.cc: ... this. Enable all the tests.
+
+ * mln/core/concept/graph.hh,
+ * mln/util/internal/graph_base.hh,
+ * mln/util/graph.hh: rename graph_id to id.
+
+2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Fix labeling::compute tests.
* mln/labeling/compute.hh: Check if the image is a labeled image and
diff --git a/milena/mln/core/concept/graph.hh b/milena/mln/core/concept/graph.hh
index 8339531..80c2ae2 100644
--- a/milena/mln/core/concept/graph.hh
+++ b/milena/mln/core/concept/graph.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 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
@@ -28,15 +28,15 @@
#ifndef MLN_CORE_CONCEPT_GRAPH_HH
# define MLN_CORE_CONCEPT_GRAPH_HH
-/*! \file mln/core/concept/graph.hh
- * \brief Definition of the concept of mln::Graph.
- */
+/// \file mln/core/concept/graph.hh
+///
+/// Definition of the concept of mln::Graph.
namespace mln
{
- // Fwd decl.
+ // Forward declaration.
template <typename E> struct Graph;
// Graph category flag type.
@@ -46,11 +46,11 @@ namespace mln
typedef Object<void> super;
};
- /*! \brief Base class for implementation of graph classes.
- *
- * \see mln::doc::Graph for a complete documentation of this class
- * contents.
- */
+ /// Base class for implementation of graph classes.
+ ///
+ /// \see mln::doc::Graph for a complete documentation of this class
+ /// contents.
+ ///
template <typename E>
struct Graph : public Object<E>
{
@@ -67,7 +67,7 @@ namespace mln
typedef bkd_piter;
// Misc.
- const E& graph_id() const;
+ const E& id() const;
template<typename G2>
bool is_subgraph_of(const G2& gr) const;
@@ -109,7 +109,7 @@ namespace mln
//typedef mln_bkd_piter(E) bkd_piter;
// Check methods
- const void* (E::*m1)() const = & E::graph_id;
+ const void* (E::*m1)() const = & E::id;
m1 = 0;
unsigned (E::*m2)(unsigned id_e, unsigned id_v) const = & E::v_other;
m2 = 0;
diff --git a/milena/mln/make/graph.hh b/milena/mln/make/graph.hh
index c3ae618..ac232e8 100644
--- a/milena/mln/make/graph.hh
+++ b/milena/mln/make/graph.hh
@@ -88,7 +88,7 @@ namespace mln
const I& iz = exact(iz_);
util::graph g;
- g.add_vertices(nlabels + 1);
+ g.add_vertices(nlabels.next());
mln_piter(I) p(iz.domain());
for_all(p)
diff --git a/milena/mln/util/edge.hh b/milena/mln/util/edge.hh
index ba34a12..0390be4 100644
--- a/milena/mln/util/edge.hh
+++ b/milena/mln/util/edge.hh
@@ -41,7 +41,7 @@ namespace mln
namespace util
{
- /*-------.
+ /*-------.
| Edge. |
`-------*/
diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh
index 7c003a2..a3f5df5 100644
--- a/milena/mln/util/graph.hh
+++ b/milena/mln/util/graph.hh
@@ -231,6 +231,9 @@ namespace mln
};
+ std::ostream&
+ operator<<(std::ostream& ostr, const graph& g);
+
} // end of namespace mln::util
} // end of namespace mln
@@ -480,7 +483,25 @@ namespace mln
bool
graph::is_subgraph_of(const G2& g) const
{
- return g.graph_id() == this->graph_id();
+ return g.id() == this->id();
+ }
+
+ // FIXME: move to graph_Base.
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const graph& g)
+ {
+ mln_vertex_iter_(graph) v(g);
+ mln_vertex_nbh_edge_iter_(graph) e(v);
+ for_all(v)
+ {
+ ostr << "v(" << v << ") : ";
+ for_all(e)
+ ostr << e << " ";
+ ostr << std::endl;
+ }
+
+ return ostr;
}
} // end of namespace mln::util
diff --git a/milena/mln/util/internal/graph_base.hh b/milena/mln/util/internal/graph_base.hh
index f659b54..ac6099e 100644
--- a/milena/mln/util/internal/graph_base.hh
+++ b/milena/mln/util/internal/graph_base.hh
@@ -82,7 +82,7 @@ namespace mln
/// Misc. methods
/// \{
/// Returns the graph id, the "this" pointer.
- const void* graph_id() const;
+ const void* id() const;
/// \}
/// Vertex oriented methods
@@ -158,7 +158,7 @@ namespace mln
template<typename E>
inline
const void*
- graph_base<E>::graph_id() const
+ graph_base<E>::id() const
{
return static_cast<const void*>(data_.ptr_);
}
@@ -248,7 +248,7 @@ namespace mln
operator==(const util::internal::graph_base<E>& lhs,
const util::internal::graph_base<E>& rhs)
{
- return lhs.graph_id() == rhs.graph_id();
+ return lhs.id() == rhs.id();
}
} // end of namespace mln
diff --git a/milena/mln/util/dual_graph.hh b/milena/mln/util/line_graph.hh
similarity index 68%
rename from milena/mln/util/dual_graph.hh
rename to milena/mln/util/line_graph.hh
index 3533e7c..6ae1c5b 100644
--- a/milena/mln/util/dual_graph.hh
+++ b/milena/mln/util/line_graph.hh
@@ -26,10 +26,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_UTIL_DUAL_GRAPH_HH
-# define MLN_UTIL_DUAL_GRAPH_HH
+#ifndef MLN_UTIL_LINE_GRAPH_HH
+# define MLN_UTIL_LINE_GRAPH_HH
-/// \file mln/util/dual_graph.hh
+/// \file mln/util/line_graph.hh
/// Definitions of undirected graphs.
# include <mln/util/internal/graph_base.hh>
@@ -44,7 +44,7 @@ namespace mln
{
/// Fwd declaration.
template <typename G>
- class dual_graph;
+ class line_graph;
}
@@ -53,7 +53,7 @@ namespace mln
/// Data structure for \c mln::image2d<T>.
template <typename G>
- struct data< util::dual_graph<G> >
+ struct data< util::line_graph<G> >
{
typedef std::vector<std::vector<unsigned> > vertices_t;
@@ -76,12 +76,12 @@ namespace mln
namespace util
{
- /// Undirected dual graph of a graph of type \tparam G.
+ /// Undirected line graph of a graph of type \tparam G.
template <typename G>
- class dual_graph : public internal::graph_base< dual_graph<G> >
+ class line_graph : public internal::graph_base< line_graph<G> >
{
/// The super class.
- typedef internal::graph_base< dual_graph<G> > super;
+ typedef internal::graph_base< line_graph<G> > super;
typedef typename super::vertex_t vertex_t;
typedef typename super::edge_t edge_t;
@@ -100,23 +100,52 @@ namespace mln
/// \{
/// Vertex iterators
/// \{
- typedef mln::internal::vertex_fwd_iterator< dual_graph<G> >
+ typedef mln::internal::vertex_fwd_iterator< line_graph<G> >
vertex_fwd_iter;
- typedef mln::internal::vertex_bkd_iterator< dual_graph<G> >
+ typedef mln::internal::vertex_bkd_iterator< line_graph<G> >
vertex_bkd_iter;
typedef vertex_fwd_iter vertex_iter;
+ /// \}
- typedef mln::internal::edge_fwd_iterator< dual_graph<G> >
+ /// Edge iterators
+ /// \{
+ typedef mln::internal::edge_fwd_iterator< line_graph<G> >
edge_fwd_iter;
- typedef mln::internal::edge_bkd_iterator< dual_graph<G> >
+ typedef mln::internal::edge_bkd_iterator< line_graph<G> >
edge_bkd_iter;
typedef edge_fwd_iter edge_iter;
+ /// \}
+
+ /// Edge nbh edge iterators
+ /// \{
+ typedef mln::internal::edge_nbh_edge_fwd_iterator< line_graph<G> >
+ edge_nbh_edge_fwd_iter;
+ typedef mln::internal::edge_nbh_edge_bkd_iterator< line_graph<G> >
+ edge_nbh_edge_bkd_iter;
+ typedef edge_nbh_edge_fwd_iter edge_nbh_edge_iter;
+ /// \}
+
+ /// Vertex nbh vertex iterators
+ /// \{
+ typedef mln::internal::vertex_nbh_vertex_fwd_iterator< line_graph<G> >
+ vertex_nbh_vertex_fwd_iter;
+ typedef mln::internal::vertex_nbh_vertex_bkd_iterator< line_graph<G> >
+ vertex_nbh_vertex_bkd_iter;
+ typedef vertex_nbh_vertex_fwd_iter vertex_nbh_vertex_iter;
+ /// \}
+ /// Vertex nbh edge iterators
+ /// \{
+ typedef mln::internal::vertex_nbh_edge_fwd_iterator< line_graph<G> >
+ vertex_nbh_edge_fwd_iter;
+ typedef mln::internal::vertex_nbh_edge_bkd_iterator< line_graph<G> >
+ vertex_nbh_edge_bkd_iter;
+ typedef vertex_nbh_edge_fwd_iter vertex_nbh_edge_iter;
/// \}
/// \}
- dual_graph();
- dual_graph(const G& g);
+ line_graph();
+ line_graph(const G& g);
/// Vertex oriented.
/// \{
@@ -190,6 +219,10 @@ namespace mln
using super::data_;
};
+ template <typename G>
+ std::ostream&
+ operator<<(std::ostream& ostr, const line_graph<G>& g);
+
} // end of namespace mln::util
} // end of namespace mln
@@ -204,15 +237,18 @@ namespace mln
template <typename G>
inline
- data< util::dual_graph<G> >::data()
+ data< util::line_graph<G> >::data()
{
}
template <typename G>
inline
- data< util::dual_graph<G> >::data(const G& g)
+ data< util::line_graph<G> >::data(const G& g)
{
g_ = g;
+
+ // Initialize vertices and edges.
+ std::set<util::ord_pair<unsigned> > edges_set;
vertices_.resize(g.e_nmax());
mln_edge_iter(G) e(g);
mln_edge_nbh_edge_iter(G) ne(e);
@@ -220,14 +256,20 @@ namespace mln
for_all(e)
for_all(ne)
{
- vertices_[e].push_back(edges_.size());
- edges_.push_back(util::ord_pair<unsigned>(e, ne));
+ util::ord_pair<unsigned> edge(e, ne);
+ if (edges_set.find(edge) == edges_set.end())
+ {
+ vertices_[e].push_back(edges_.size());
+ vertices_[ne].push_back(edges_.size());
+ edges_set.insert(edge);
+ edges_.push_back(edge);
+ }
}
}
template <typename G>
inline
- data< util::dual_graph<G> >::~data()
+ data< util::line_graph<G> >::~data()
{
}
@@ -238,16 +280,16 @@ namespace mln
template <typename G>
inline
- dual_graph<G>::dual_graph()
+ line_graph<G>::line_graph()
{
- this->data_ = new mln::internal::data< util::dual_graph<G> >();
+ this->data_ = new mln::internal::data< util::line_graph<G> >();
}
template <typename G>
inline
- dual_graph<G>::dual_graph(const G& g)
+ line_graph<G>::line_graph(const G& g)
{
- this->data_ = new mln::internal::data< util::dual_graph<G> >(g);
+ this->data_ = new mln::internal::data< util::line_graph<G> >(g);
}
/*---------------.
@@ -256,8 +298,8 @@ namespace mln
template <typename G>
inline
- typename dual_graph<G>::vertex_t
- dual_graph<G>::vertex(unsigned id_v) const
+ typename line_graph<G>::vertex_t
+ line_graph<G>::vertex(unsigned id_v) const
{
mln_assertion(has_v(id_v));
return vertex_t(*this, id_v);
@@ -267,7 +309,7 @@ namespace mln
template <typename G>
inline
size_t
- dual_graph<G>::v_nmax() const
+ line_graph<G>::v_nmax() const
{
return data_->g_.e_nmax();
}
@@ -275,7 +317,7 @@ namespace mln
template <typename G>
inline
bool
- dual_graph<G>::has_v(unsigned id_v) const
+ line_graph<G>::has_v(unsigned id_v) const
{
return data_->g_.has_e(id_v);
}
@@ -284,7 +326,7 @@ namespace mln
template <typename G2>
inline
bool
- dual_graph<G>::has_v(const util::vertex<G2>& v) const
+ line_graph<G>::has_v(const util::vertex<G2>& v) const
{
//FIXME: not sure...
return v.graph().is_subgraph_of(*this) && has_v(v.id());
@@ -293,16 +335,16 @@ namespace mln
template <typename G>
inline
size_t
- dual_graph<G>::v_nmax_nbh_edges(unsigned id_v) const
+ line_graph<G>::v_nmax_nbh_edges(unsigned id_v) const
{
mln_precondition(has_v(id_v));
- return data_->g_.e_nmax_nbh_edges(id_v);
+ return data_->vertices_[id_v].size();
}
template <typename G>
inline
unsigned
- dual_graph<G>::v_ith_nbh_edge(unsigned id_v, unsigned i) const
+ line_graph<G>::v_ith_nbh_edge(unsigned id_v, unsigned i) const
{
mln_precondition(has_v(id_v));
if (i >= v_nmax_nbh_edges(id_v))
@@ -313,7 +355,7 @@ namespace mln
template <typename G>
inline
size_t
- dual_graph<G>::v_nmax_nbh_vertices(unsigned id_v) const
+ line_graph<G>::v_nmax_nbh_vertices(unsigned id_v) const
{
mln_precondition(has_v(id_v));
return v_nmax_nbh_edges(id_v);
@@ -322,7 +364,7 @@ namespace mln
template <typename G>
inline
unsigned
- dual_graph<G>::v_ith_nbh_vertex(unsigned id_v, unsigned i) const
+ line_graph<G>::v_ith_nbh_vertex(unsigned id_v, unsigned i) const
{
mln_precondition(has_v(id_v));
@@ -337,8 +379,8 @@ namespace mln
template <typename G>
inline
- typename dual_graph<G>::edge_t
- dual_graph<G>::edge(unsigned e) const
+ typename line_graph<G>::edge_t
+ line_graph<G>::edge(unsigned e) const
{
mln_assertion(e < e_nmax());
return edge_t(*this, e);
@@ -347,7 +389,7 @@ namespace mln
template <typename G>
inline
size_t
- dual_graph<G>::e_nmax() const
+ line_graph<G>::e_nmax() const
{
return data_->edges_.size();
}
@@ -355,7 +397,7 @@ namespace mln
template <typename G>
inline
bool
- dual_graph<G>::has_e(unsigned id_e) const
+ line_graph<G>::has_e(unsigned id_e) const
{
return id_e < data_->edges_.size();
}
@@ -364,7 +406,7 @@ namespace mln
template <typename G2>
inline
bool
- dual_graph<G>::has_e(const util::edge<G2>& e) const
+ line_graph<G>::has_e(const util::edge<G2>& e) const
{
return e.graph().is_subgraph_of(*this) && has_e(e.id());
}
@@ -372,7 +414,7 @@ namespace mln
template <typename G>
inline
unsigned
- dual_graph<G>::v1(unsigned id_e) const
+ line_graph<G>::v1(unsigned id_e) const
{
mln_precondition(has_e(id_e));
return data_->edges_[id_e].first();
@@ -381,7 +423,7 @@ namespace mln
template <typename G>
inline
unsigned
- dual_graph<G>::v2(unsigned id_e) const
+ line_graph<G>::v2(unsigned id_e) const
{
mln_precondition(has_e(id_e));
return data_->edges_[id_e].second();
@@ -390,7 +432,7 @@ namespace mln
template <typename G>
inline
size_t
- dual_graph<G>::e_nmax_nbh_edges(unsigned id_e) const
+ line_graph<G>::e_nmax_nbh_edges(unsigned id_e) const
{
mln_precondition(has_e(id_e));
return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e));
@@ -399,7 +441,7 @@ namespace mln
template <typename G>
inline
unsigned
- dual_graph<G>::e_ith_nbh_edge(unsigned id_e, unsigned i) const
+ line_graph<G>::e_ith_nbh_edge(unsigned id_e, unsigned i) const
{
mln_precondition(has_e(id_e));
if (i >= e_nmax_nbh_edges(id_e))
@@ -416,9 +458,29 @@ namespace mln
template <typename G2>
inline
bool
- dual_graph<G>::is_subgraph_of(const G2& g) const
+ line_graph<G>::is_subgraph_of(const G2& g) const
+ {
+ return g.id() == this->id();
+ }
+
+ // FIXME: move to graph_base
+ template <typename G>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const line_graph<G>& g)
{
- return g.graph_id() == this->graph_id();
+ typedef line_graph<G> LG;
+ mln_vertex_iter(LG) v(g);
+ mln_vertex_nbh_edge_iter(LG) e(v);
+ for_all(v)
+ {
+ ostr << "v(" << v << ") : ";
+ for_all(e)
+ ostr << e << " ";
+ ostr << std::endl;
+ }
+
+ return ostr;
}
} // end of namespace mln::util
@@ -428,4 +490,4 @@ namespace mln
# endif // ! MLN_INCLUDE_ONLY
-#endif // ! MLN_UTIL_DUAL_GRAPH_HH
+#endif // ! MLN_UTIL_LINE_GRAPH_HH
diff --git a/milena/tests/util/Makefile.am b/milena/tests/util/Makefile.am
index fcfb902..07abfab 100644
--- a/milena/tests/util/Makefile.am
+++ b/milena/tests/util/Makefile.am
@@ -6,7 +6,7 @@ include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
branch_iter \
branch_iter_ind \
- dual_graph \
+ line_graph \
eat \
graph \
lazy_set \
@@ -20,7 +20,7 @@ check_PROGRAMS = \
branch_iter_SOURCES = branch_iter.cc
branch_iter_ind_SOURCES = branch_iter_ind.cc
-dual_graph_SOURCES = dual_graph.cc
+line_graph_SOURCES = line_graph.cc
eat_SOURCES = eat.cc
graph_SOURCES = graph.cc
lazy_set_SOURCES = lazy_set.cc
diff --git a/milena/tests/util/dual_graph.cc b/milena/tests/util/line_graph.cc
similarity index 61%
rename from milena/tests/util/dual_graph.cc
rename to milena/tests/util/line_graph.cc
index ff8c8ad..655007c 100644
--- a/milena/tests/util/dual_graph.cc
+++ b/milena/tests/util/line_graph.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright(C) 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
@@ -25,71 +25,71 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file tests/util/dual_graph.cc
-/// test of mln::util::dual_graph
+/// \file tests/util/line_graph.cc
+/// test of mln::util::line_graph
#include <mln/util/graph.hh>
-#include <mln/util/dual_graph.hh>
+#include <mln/util/line_graph.hh>
#include <iostream>
-int main ()
+int main()
{
using namespace mln;
util::graph g;
- g.add_vertex (); // 0
- g.add_vertex (); // 1
- g.add_vertex (); // 2
- g.add_vertex (); // 3
- g.add_vertex (); // 4
- g.add_vertex (); // 5
- g.add_edge (0, 1);
- g.add_edge (1, 0); // Not inserted twice
- g.add_edge (0, 2);
- g.add_edge (3, 4);
- g.add_edge (4, 5);
- g.add_edge (5, 4); // Not inserted twice
- g.add_edge (5, 3);
- g.add_edge (2, 1);
+ g.add_vertex(); // 0
+ g.add_vertex(); // 1
+ g.add_vertex(); // 2
+ g.add_vertex(); // 3
+ g.add_vertex(); // 4
+ g.add_vertex(); // 5
+ g.add_edge(0, 1);
+ g.add_edge(1, 0); // Not inserted twice
+ g.add_edge(0, 2);
+ g.add_edge(3, 4);
+ g.add_edge(4, 5);
+ g.add_edge(5, 4); // Not inserted twice
+ g.add_edge(5, 3);
+ g.add_edge(2, 1);
- typedef util::dual_graph<util::graph> DG;
- DG dg(g);
+ typedef util::line_graph<util::graph> LG;
+ LG lg(g);
- // Vertex iter and edge iter
+ // Vertex and edge forward iterators.
{
unsigned i = 0;
- mln_vertex_fwd_iter_(DG) v(dg);
+ mln_vertex_fwd_iter_(LG) v(lg);
for_all(v)
- std::cout << v.index() << std::endl;
-// mln_assertion(i++ == v.index());
- //mln_assertion(i != 0);
+ mln_assertion(i++ == v.index());
+ mln_assertion(i != 0);
i = 0;
- mln_edge_fwd_iter_(util::graph) e(g);
+ mln_edge_fwd_iter_(LG) e(lg);
for_all(e)
- std::cout << e << std::endl;
-// mln_assertion(i++ == e.index());
-// mln_assertion(i != 0);*/
+ mln_assertion(i++ == e.index());
+ mln_assertion(i != 0);
}
-/* {
- unsigned i = g.v_nmax() - 1;
- mln_vertex_bkd_iter_(util::graph) v(g);
+
+ // Vertex and edge backward iterators.
+ {
+ unsigned i = lg.v_nmax() - 1;
+ mln_vertex_bkd_iter_(LG) v(lg);
for_all(v)
mln_assertion(i-- == v.index());
- mln_assertion(i != g.v_nmax() - 1);
+ mln_assertion(i != lg.v_nmax() - 1);
- i = g.e_nmax() - 1;
- mln_edge_bkd_iter_(util::graph) e(g);
+ i = lg.e_nmax() - 1;
+ mln_edge_bkd_iter_(LG) e(lg);
for_all(e)
mln_assertion(i-- == e.index());
- mln_assertion(i != g.e_nmax() - 1);
+ mln_assertion(i != lg.e_nmax() - 1);
}
- // vertex iter + Edge nbh iter
+ // Vertex and edge nbh forward iterators
{
- mln_vertex_fwd_iter_(util::graph) v(g);
- mln_vertex_nbh_edge_fwd_iter_(util::graph) n(v);
+ mln_vertex_fwd_iter_(LG) v(lg);
+ mln_vertex_nbh_edge_fwd_iter_(LG) n(v);
for_all(v)
{
unsigned i = 0;
@@ -98,9 +98,11 @@ int main ()
mln_assertion(i != 0);
}
}
+
+ // Vertex and edge nbh backward iterators.
{
- mln_vertex_bkd_iter_(util::graph) v(g);
- mln_vertex_nbh_edge_bkd_iter_(util::graph) e(v);
+ mln_vertex_bkd_iter_(LG) v(lg);
+ mln_vertex_nbh_edge_bkd_iter_(LG) e(v);
for_all(v)
{
unsigned i = v.nmax_nbh_edges();
@@ -109,10 +111,12 @@ int main ()
mln_assertion((v.nmax_nbh_edges() == 0 && i == 0) || i != v.nmax_nbh_edges());
}
}
-
+ std::cout << g << std::endl;
+ std::cout << "----" << std::endl;
+ std::cout << lg << std::endl;
{
- mln_edge_fwd_iter_(util::graph) e(g);
- mln_edge_nbh_edge_fwd_iter_(util::graph) n(e);
+ mln_edge_fwd_iter_(LG) e(lg);
+ mln_edge_nbh_edge_fwd_iter_(LG) n(e);
for_all(e)
{
unsigned i = 0;
@@ -124,8 +128,8 @@ int main ()
}
}
{
- mln_edge_bkd_iter_(util::graph) e(g);
- mln_edge_nbh_edge_bkd_iter_(util::graph) n(e);
+ mln_edge_bkd_iter_(LG) e(lg);
+ mln_edge_nbh_edge_bkd_iter_(LG) n(e);
for_all(e)
{
//std::cout << "== e.id() = " << e.id() << std::endl;
@@ -138,10 +142,9 @@ int main ()
}
}
-
{
- mln_vertex_fwd_iter_(util::graph) v(g);
- mln_vertex_nbh_vertex_fwd_iter_(util::graph) n(v);
+ mln_vertex_fwd_iter_(LG) v(lg);
+ mln_vertex_nbh_vertex_fwd_iter_(LG) n(v);
for_all(v)
{
unsigned i = 0;
@@ -151,8 +154,8 @@ int main ()
}
}
{
- mln_vertex_bkd_iter_(util::graph) v(g);
- mln_vertex_nbh_vertex_bkd_iter_(util::graph) n(v);
+ mln_vertex_bkd_iter_(LG) v(lg);
+ mln_vertex_nbh_vertex_bkd_iter_(LG) n(v);
for_all(v)
{
unsigned i = v.nmax_nbh_vertices();
@@ -160,5 +163,5 @@ int main ()
--i;
mln_assertion(i == 0);
}
- }*/
+ }
}
--
1.5.6.5
1
0
* mln/labeling/compute.hh: Check if the image is a labeled image and
fix a wrong dispatch.
---
milena/ChangeLog | 7 +++++++
milena/mln/labeling/compute.hh | 7 ++++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 4e2cfcb..959337a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix labeling::compute tests.
+
+ * mln/labeling/compute.hh: Check if the image is a labeled image and
+ fix a wrong dispatch.
+
+2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Fix tutorial generation.
* doc/tutorial/Makefile.am
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index dfc95f1..ececa18 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -127,6 +127,7 @@ namespace mln
const mln_value(L)& nlabels)
{
mln_precondition(exact(label).has_data());
+ mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
(void) a;
(void) label;
(void) nlabels;
@@ -143,7 +144,7 @@ namespace mln
{
mln_precondition(exact(input).has_data());
mln_precondition(exact(label).has_data());
-
+ mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
(void) a;
(void) input;
(void) label;
@@ -276,7 +277,7 @@ namespace mln
typedef mln_accu_with(A, mln_value(I)) A_;
A_ a_ = accu::unmeta(exact(a), mln_value(I)());
- return internal::compute_dispatch(a_, input, label, nlabels);
+ return compute(a_, input, label, nlabels);
}
@@ -309,7 +310,7 @@ namespace mln
typedef mln_accu_with(A, mln_psite(L)) A_;
A_ a_ = accu::unmeta(exact(a), mln_psite(L)());
- return internal::compute_dispatch(a_, label, nlabels);
+ return compute(a_, label, nlabels);
}
--
1.5.6.5
1
0
* doc/tutorial/Makefile.am
* doc/Makefile.am: fix wrong variable names.
* doc/tutorial/samples/fill-part-2.cc,
* doc/tutorial/samples/fill-part-3.cc,
* doc/tutorial/samples/ima2d-decl-2-blobs-full.cc,
* doc/tutorial/samples/ima2d-decl-2-blobs.cc,
* doc/tutorial/samples/labeling-compute-full.cc: Use label8 instead of
int_u8.
* doc/tutorial/samples/graph-data-full.cc: Add new example.
---
milena/ChangeLog | 16 ++++
milena/doc/Makefile.am | 10 +-
milena/doc/tutorial/Makefile.am | 10 +-
milena/doc/tutorial/samples/fill-part-2.cc | 7 +-
milena/doc/tutorial/samples/fill-part-3.cc | 7 +-
milena/doc/tutorial/samples/graph-data-full.cc | 82 ++++++++++++++++++++
.../tutorial/samples/ima2d-decl-2-blobs-full.cc | 6 +-
milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc | 4 +-
.../doc/tutorial/samples/labeling-compute-full.cc | 5 +-
9 files changed, 122 insertions(+), 25 deletions(-)
create mode 100644 milena/doc/tutorial/samples/graph-data-full.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 82e1f97..4e2cfcb 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,19 @@
+2008-11-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix tutorial generation.
+
+ * doc/tutorial/Makefile.am
+ * doc/Makefile.am: fix wrong variable names.
+
+ * doc/tutorial/samples/fill-part-2.cc,
+ * doc/tutorial/samples/fill-part-3.cc,
+ * doc/tutorial/samples/ima2d-decl-2-blobs-full.cc,
+ * doc/tutorial/samples/ima2d-decl-2-blobs.cc,
+ * doc/tutorial/samples/labeling-compute-full.cc: Use label8 instead of
+ int_u8.
+
+ * doc/tutorial/samples/graph-data-full.cc: Add new example.
+
2008-11-25 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a morpho tree data structure based on parenthood.
diff --git a/milena/doc/Makefile.am b/milena/doc/Makefile.am
index 039f5dc..bb717f6 100644
--- a/milena/doc/Makefile.am
+++ b/milena/doc/Makefile.am
@@ -14,24 +14,24 @@ complete-doc: html_complete
user-doc: html_user tutorial
-html_complete: tuto_html figures Doxyfile
+html_complete: figures Doxyfile tuto_html
$(DOXYGEN) Doxyfile_complete
-html_user: tuto_html figures Doxyfile
+html_user: figures Doxyfile tuto_html
$(DOXYGEN) Doxyfile_user
figures: all
@failcom='exit 1'; \
- list='${wildcard $(FIGURES_DIR)/*.p*m}'; for img in $$list; do \
+ list='${wildcard $(FIGURES_BUILDDIR)/*.p*m}'; for img in $$list; do \
echo "Converting $$img to png"; \
- convert $$img $(FIGURES_DIR)/`basename $$img .ppm`.png \
+ convert $$img $(FIGURES_BUILDDIR)/`basename $$img .ppm`.png \
|| eval $$failcom; \
done;
tuto_html:
$(MAKE) -C tutorial tuto_html
-tuto: all
+tuto: all figures
$(MAKE) -C tutorial tuto
edit = sed -e "s|@ID@|$$Id|" \
diff --git a/milena/doc/tutorial/Makefile.am b/milena/doc/tutorial/Makefile.am
index 0b70c3e..9bc00e6 100644
--- a/milena/doc/tutorial/Makefile.am
+++ b/milena/doc/tutorial/Makefile.am
@@ -2,15 +2,15 @@ SUBDIRS = samples
.PHONY: tuto
-TUTO_DIR = "milena/doc/tutorial"
-TEXINPUTS = $(top_srcdir)/$(TUTO_DIR):$(top_builddir)/$(TUTO_DIR):
+include $(top_srcdir)/milena/doc/doc.mk
+TEXINPUTS = $(TUTORIAL_SRCDIR):$(TUTORIAL_BUILDDIR):
tuto:
- TEXINPUTS=$(TEXINPUTS) pdflatex $(top_srcdir)/$(TUTO_DIR)/tutorial.tex
+ TEXINPUTS=$(TEXINPUTS) pdflatex $(TUTORIAL_SRCDIR)/tutorial.tex
tuto_html:
- chmod u+x $(top_srcdir)/$(TUTO_DIR)/todoxygen.sh
- $(top_srcdir)/$(TUTO_DIR)/todoxygen.sh $(top_srcdir)/$(TUTO_DIR)/tutorial.tex $(top_builddir)/$(TUTO_DIR)
+ chmod u+x $(TUTORIAL_SRCDIR)/todoxygen.sh
+ $(TUTORIAL_SRCDIR)/todoxygen.sh $(TUTORIAL_SRCDIR)/tutorial.tex $(TUTORIAL_BUILDDIR)
clean-local:
rm -f *.aux *.toc *.log *.bbl *blg *.lot *.out *~
diff --git a/milena/doc/tutorial/samples/fill-part-2.cc b/milena/doc/tutorial/samples/fill-part-2.cc
index 4f69cbc..17335d2 100644
--- a/milena/doc/tutorial/samples/fill-part-2.cc
+++ b/milena/doc/tutorial/samples/fill-part-2.cc
@@ -1,10 +1,9 @@
using namespace mln;
-using value::int_u8;
-using value::rgb8;
+using value::label8;
// Find and label the different components.
-int_u8 nlabels;
-image2d<int_u8> lab = labeling::blobs(ima, c4(), nlabels);
+label8 nlabels;
+image2d<label8> lab = labeling::blobs(ima, c4(), nlabels);
// Store a boolean image. True if the site is part of
// component 2, false otherwise.
diff --git a/milena/doc/tutorial/samples/fill-part-3.cc b/milena/doc/tutorial/samples/fill-part-3.cc
index 29c112a..9082430 100644
--- a/milena/doc/tutorial/samples/fill-part-3.cc
+++ b/milena/doc/tutorial/samples/fill-part-3.cc
@@ -1,10 +1,9 @@
using namespace mln;
-using value::int_u8;
-using value::rgb8;
+using value::label8;
// Find and label the different components.
-int_u8 nlabels;
-image2d<int_u8> lab = labeling::blobs(ima, c4(), nlabels);
+label8 nlabels;
+image2d<label8> lab = labeling::blobs(ima, c4(), nlabels);
// Fill the sites of component 2 with red.
fill(lab.domain(2).rw(), color::red);
diff --git a/milena/doc/tutorial/samples/graph-data-full.cc b/milena/doc/tutorial/samples/graph-data-full.cc
new file mode 100644
index 0000000..60792a3
--- /dev/null
+++ b/milena/doc/tutorial/samples/graph-data-full.cc
@@ -0,0 +1,82 @@
+#include <mln/essential/2d.hh>
+#include <mln/util/graph.hh>
+
+// Part of graph-data.cc
+// \{
+template <typename S>
+struct viota_t : public mln::Function_p2v< viota_t<S> >
+{
+ typedef unsigned result;
+
+ viota_t(unsigned size)
+ {
+ v_.resize(size);
+ for(unsigned i = 0; i < size; ++i)
+ v_[i] = 10 + i;
+ }
+
+ unsigned
+ operator()(const mln_psite(S)& p) const
+ {
+ return v_[p.v().id()];
+ }
+
+ protected:
+ std::vector<result> v_;
+};
+// \}
+
+int main()
+{
+ using namespace mln;
+
+ // Part of graph-add-vertec.cc
+ // \{
+ util::graph g;
+
+ for (unsigned i = 0; i < 5; ++i)
+ g.add_vertex(); // Add vertex 'i';
+ // \}
+
+ // Part of graph-add-edges.cc
+ // \{
+ g.add_edge(0, 1); // Associated to edge 0.
+ g.add_edge(1, 2); // Associated to edge 1.
+ g.add_edge(1, 3); // Associated to edge 2.
+ g.add_edge(3, 4); // Associated to edge 3.
+ g.add_edge(4, 2); // Associated to edge 4.
+ // \}
+
+ // Part of graph-i2v-vertex.cc
+ // \{
+ typedef fun::i2v::array<point2d> F;
+ F f(5); // We need to map 5 vertices.
+ f(0) = point2d(0, 0);
+ f(1) = point2d(2, 2);
+ f(2) = point2d(0, 4);
+ f(3) = point2d(4, 3);
+ f(4) = point2d(4, 4);
+ // \}
+
+ // Part of graph-p-vertices.cc
+ // \{
+ typedef p_vertices<util::graph, F> pv_t;
+ pv_t pv(g, f);
+ // \}
+
+ // Part of graph-data.cc
+ // \{
+
+ // Constructs an image
+ viota_t<pv_t> viota(pv.nsites());
+ mln_VAR(graph_vertices_ima, viota | pv);
+
+ //Prints each vertex and its associated data.
+ mln_piter_(graph_vertices_ima_t) p(graph_vertices_ima.domain());
+ for_all(p)
+ std::cout << "graph_vertices_ima(" << p << ") = "
+ << graph_vertices_ima(p) << std::endl;
+
+ // \}
+}
+
diff --git a/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc b/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc
index 9728ac7..da6fa2b 100644
--- a/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc
+++ b/milena/doc/tutorial/samples/ima2d-decl-2-blobs-full.cc
@@ -2,7 +2,7 @@
int main()
{
using namespace mln;
- using value::int_u8;
+ using value::label8;
bool vals[6][5] = {
{0, 1, 1, 0, 0},
@@ -14,8 +14,8 @@ int main()
};
image2d<bool> ima = make::image(vals);
- int_u8 nlabels;
- image2d<int_u8> lbl = labeling::blobs(ima, c4(), nlabels);
+ label8 nlabels;
+ image2d<label8> lbl = labeling::blobs(ima, c4(), nlabels);
debug::println(lbl);
}
diff --git a/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc b/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc
index 6699982..f69c8c0 100644
--- a/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc
+++ b/milena/doc/tutorial/samples/ima2d-decl-2-blobs.cc
@@ -1,2 +1,2 @@
-int_u8 nlabels;
-image2d<int_u8> lbl = labeling::blobs(ima, c4(), nlabels);
+label8 nlabels;
+image2d<label8> lbl = labeling::blobs(ima, c4(), nlabels);
diff --git a/milena/doc/tutorial/samples/labeling-compute-full.cc b/milena/doc/tutorial/samples/labeling-compute-full.cc
index fa378ca..4996a99 100644
--- a/milena/doc/tutorial/samples/labeling-compute-full.cc
+++ b/milena/doc/tutorial/samples/labeling-compute-full.cc
@@ -3,6 +3,7 @@ int main()
{
using namespace mln;
using value::int_u8;
+ using value::label8;
bool vals[6][5] = {
{0, 1, 1, 0, 0},
@@ -14,8 +15,8 @@ int main()
};
image2d<bool> ima = make::image(vals);
- int_u8 nlabels;
- image2d<int_u8> lbl = labeling::blobs(ima, c4(), nlabels);
+ label8 nlabels;
+ image2d<label8> lbl = labeling::blobs(ima, c4(), nlabels);
util::array<box2d> boxes =
labeling::compute(accu::meta::bbox(),
--
1.5.6.5
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a morpho tree data structure based on parenthood.
* mln/morpho/tree/data.hh: New.
* mln/morpho/tree/all.hh: Update.
* tests/morpho/tree/data.cc: New.
* tests/morpho/tree/Makefile.am: Update.
* mln/morpho/tree/utils.hh (todo): New.
* mln/core/image/safe.hh (init_): New precondition.
Upgrade doc style.
mln/core/image/safe.hh | 17 ++-
mln/morpho/tree/all.hh | 1
mln/morpho/tree/data.hh | 187 ++++++++++++++++++++++++++++++++++++++++++
mln/morpho/tree/utils.hh | 2
tests/morpho/tree/Makefile.am | 6 -
tests/morpho/tree/data.cc | 86 +++++++++++++++++++
6 files changed, 289 insertions(+), 10 deletions(-)
Index: tests/morpho/tree/Makefile.am
--- tests/morpho/tree/Makefile.am (revision 2945)
+++ tests/morpho/tree/Makefile.am (working copy)
@@ -4,9 +4,11 @@
check_PROGRAMS = \
compute_tree \
+ data \
max
-compute_tree_SOURCES = compute_tree_.cc
-max_SOURCES = max_.cc
+compute_tree_SOURCES = compute_tree.cc
+data_SOURCES = data.cc
+max_SOURCES = max.cc
TESTS = $(check_PROGRAMS)
Index: tests/morpho/tree/data.cc
--- tests/morpho/tree/data.cc (revision 0)
+++ tests/morpho/tree/data.cc (revision 0)
@@ -0,0 +1,86 @@
+// Copyright (C) 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/morpho/tree/parent.cc
+///
+/// Tests on mln::morpho::tree::parent.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/pw/image.hh>
+
+#include <mln/debug/println.hh>
+#include <mln/debug/iota.hh>
+#include <mln/morpho/elementary/dilation.hh>
+
+#include <mln/core/site_set/p_array.hh>
+#include <mln/level/sort_psites.hh>
+
+#include <mln/morpho/tree/data.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<unsigned> I;
+ I ima(3, 3);
+ debug::iota(ima);
+
+ ima = morpho::elementary::dilation(ima, c8());
+ debug::println("ima = ", ima);
+
+ typedef p_array<point2d> S;
+ S s = level::sort_psites_increasing(ima);
+
+ typedef morpho::tree::data<I,S> tree_t;
+ tree_t t(ima, s, c4());
+
+ debug::println( "parent = ", t.parent_image() | t.domain() );
+ debug::println( "on node = ", t.parent_image() | t.nodes() );
+
+ {
+ std::cout << "nodes = ";
+ tree_t::nodes_t::piter p(t.nodes());
+ for_all(p)
+ std::cout << p << ' ';
+ std::cout << std::endl
+ << std::endl;
+ }
+
+
+ {
+ image2d<unsigned> area(ima.domain());
+ level::fill(area, 1);
+ tree_t::piter p(t.domain());
+ for_all(p)
+ if (! t.is_root(p))
+ area(t.parent(p)) += area(p);
+ debug::println("area = ", area | t.nodes());
+ }
+
+}
Index: mln/core/image/safe.hh
--- mln/core/image/safe.hh (revision 2945)
+++ mln/core/image/safe.hh (working copy)
@@ -1,4 +1,5 @@
// 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
@@ -28,14 +29,13 @@
#ifndef MLN_CORE_IMAGE_SAFE_HH
# define MLN_CORE_IMAGE_SAFE_HH
-/*!
- * \file mln/core/image/safe.hh
- *
- * \brief Definition of a morpher that makes image become accessible
- * at undefined location.
- *
- * \todo Use 'instant' as the routine safe returns.
- */
+///
+/// \file mln/core/image/safe.hh
+///
+/// \brief Definition of a morpher that makes image become accessible
+/// at undefined location.
+///
+/// \todo Use 'instant' as the routine safe returns.
# include <mln/core/internal/image_identity.hh>
@@ -162,6 +162,7 @@
void
safe_image<I>::init_(I& ima, const mln_value(I)& default_value)
{
+ mln_precondition(! this->has_data());
mln_precondition(ima.has_data());
this->data_ = new internal::data< safe_image<I> >(ima, default_value);
}
Index: mln/morpho/tree/all.hh
--- mln/morpho/tree/all.hh (revision 2945)
+++ mln/morpho/tree/all.hh (working copy)
@@ -47,6 +47,7 @@
# include <mln/morpho/tree/compute_parent.hh>
+# include <mln/morpho/tree/data.hh>
# include <mln/morpho/tree/max.hh>
# include <mln/morpho/tree/utils.hh>
Index: mln/morpho/tree/data.hh
--- mln/morpho/tree/data.hh (revision 0)
+++ mln/morpho/tree/data.hh (revision 0)
@@ -0,0 +1,187 @@
+// Copyright (C) 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.
+
+#ifndef MLN_MORPHO_TREE_DATA_HH
+# define MLN_MORPHO_TREE_DATA_HH
+
+/// \file mln/morpho/tree/data.hh
+///
+/// FIXME: First Attempt.
+
+# include <mln/morpho/tree/compute_parent.hh>
+# include <mln/core/image/sub_image.hh>
+
+
+
+namespace mln
+{
+
+ namespace morpho
+ {
+
+ namespace tree
+ {
+
+ // FIXME: Doc!
+
+ template <typename I, typename S>
+ class data
+ {
+ public:
+
+
+ /// Ctor.
+ template <typename N>
+ data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh);
+
+
+
+ /// \{ Parent-related materials.
+
+ typedef mln_ch_value(I, mln_psite(I)) parent_t;
+
+ const mln_psite(I)& parent(const mln_psite(I)& p) const
+ {
+ mln_precondition(is_valid());
+ mln_precondition(parent_.domain().has(p));
+ return parent_(p);
+ }
+
+ const parent_t& parent_image() const
+ {
+ mln_precondition(is_valid());
+ return parent_;
+ }
+
+ /// \}
+
+
+ /// \{ Tests.
+
+ bool is_valid() const
+ {
+ return parent_.has_data(); // FIXME: and... (?)
+ }
+
+ bool is_root(const mln_psite(I)& p) const
+ {
+ mln_precondition(is_valid());
+ mln_precondition(parent_.domain().has(p));
+ return parent_(p) == p;
+ }
+
+ bool is_a_node(const mln_psite(I)& p) const
+ {
+ mln_precondition(is_valid());
+ mln_precondition(parent_.domain().has(p));
+ return parent_(p) == p || f_(parent_(p)) != f_(p);
+ }
+
+ /// \}
+
+
+ /// \{ Nodes-related materials.
+
+ typedef p_array<mln_psite(I)> nodes_t;
+
+ const p_array<mln_psite(I)>& nodes() const
+ {
+ mln_precondition(is_valid());
+ return nodes_;
+ }
+
+ /// \}
+
+
+ /// \{ How-to iterate on all sites.
+
+ typedef mln_bkd_piter(S) piter;
+ typedef mln_bkd_piter(S) fwd_piter;
+ typedef mln_fwd_piter(S) bkd_piter;
+
+ const S& domain() const
+ {
+ return s_;
+ }
+
+ /// \}
+
+ unsigned nroots() const
+ {
+ return nroots_;
+ }
+
+ protected:
+
+ const I& f_;
+ const S& s_;
+ mln_ch_value(I, mln_psite(I)) parent_;
+ p_array<mln_psite(I)> nodes_;
+ unsigned nroots_;
+ };
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename S>
+ template <typename N>
+ inline
+ data<I,S>::data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh)
+ : f_(exact(f)),
+ s_(exact(s))
+ {
+ const N& nbh_ = exact(nbh);
+
+ // Compute parent image.
+ parent_ = morpho::tree::compute_parent(f_, nbh_, s_);
+
+ // Store tree nodes.
+ nroots_ = 0;
+ mln_bkd_piter(S) p(s_);
+ for_all(p)
+ if (f_(parent_(p)) != f_(p))
+ nodes_.insert(p);
+ else
+ if (parent_(p) == p)
+ {
+ nodes_.insert(p);
+ ++nroots_;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::tree
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_TREE_DATA_HH
Index: mln/morpho/tree/utils.hh
--- mln/morpho/tree/utils.hh (revision 2945)
+++ mln/morpho/tree/utils.hh (working copy)
@@ -31,6 +31,8 @@
/// \file mln/morpho/tree/utils.hh
///
/// Utilities.
+///
+/// \todo Remove this file after ./data.hh is completed!
# include <mln/core/concept/image.hh>
# include <mln/core/site_set/p_array.hh>
1
0
24 Nov '08
* scribo/demat.hh:
- cleanup and refactor.
- Remove too large/small components.
- use a graph to store the text bboxes relationship.
---
milena/sandbox/ChangeLog | 9 +
milena/sandbox/scribo/demat.hh | 402 ++++++++++++++++++++++++++--------------
2 files changed, 269 insertions(+), 142 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 000b312..162aafe 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,12 @@
+2008-11-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ [Scribo] Cleanup and improve removal of unwanted components.
+
+ * scribo/demat.hh:
+ - cleanup and refactor.
+ - Remove too large/small components.
+ - use a graph to store the text bboxes relationship.
+
2008-11-24 Ugo Jardonnet <ugo.jardonnet(a)lrde.epita.fr>
Start /filtering to n components/ procedure.
diff --git a/milena/sandbox/scribo/demat.hh b/milena/sandbox/scribo/demat.hh
index 87e8008..8b59a11 100644
--- a/milena/sandbox/scribo/demat.hh
+++ b/milena/sandbox/scribo/demat.hh
@@ -39,14 +39,13 @@
# include <libgen.h>
# include <sstream>
+# include <queue>
# include <mln/essential/1d.hh>
# include <mln/essential/2d.hh>
# include <mln/morpho/elementary/dilation.hh>
# include <mln/labeling/background.hh>
-# include <mln/transform/influence_zone_geodesic.hh>
-
#include <tesseract/baseapi.h>
namespace scribo
@@ -56,28 +55,42 @@ namespace scribo
{
using namespace mln;
- using value::int_u16;
+ using value::label16;
using value::rgb8;
+
+
struct settings_t
{
settings_t()
{
- bbox_enlarge = 1;
ero_line_width = 51;
- bbox_distance = 25;
+ rank_filter = 6;
+ bbox_enlarge = 1 + ero_line_width / 2 - rank_filter;
+ bbox_distance = 20;
min_comp_size = 5;
+ max_comp_size = 1000;
+ max_dist_lines = 10;
+ max_txt_box_height = 100;
}
unsigned bbox_enlarge;
unsigned ero_line_width;
unsigned bbox_distance;
unsigned min_comp_size;
+ unsigned max_comp_size;
+ unsigned max_dist_lines;
+ int max_txt_box_height;
+ unsigned rank_filter;
};
+
+
settings_t settings;
char *input_file = 0;
+
+
/// Returns a formated output file name.
std::string output_file(const char *name)
{
@@ -126,6 +139,8 @@ namespace scribo
return std::make_pair(p1, p2);
}
+
+
/// Draw a list of bboxes and their center in a RGB8 image.
void draw_component_boxes(image2d<rgb8>& output, const util::array<box2d>& boxes)
{
@@ -137,6 +152,8 @@ namespace scribo
}
}
+
+
/// Colorize and save a labeled image.
template <typename V>
void save_lbl_image(const image2d<V>& lbl, unsigned nlabels,
@@ -147,7 +164,14 @@ namespace scribo
}
+
+
+
+
+
+ //-*****************************************
/// Functions related to Text Recognition.
+ //-*****************************************
/// \{
/// Passes the text bboxes to Tesseract and store the result an image of
@@ -158,7 +182,7 @@ namespace scribo
///
/// FIXME: For each text bbox, we create a new image. We may like to avoid that.
void
- text_recognition(const image2d<bool>& in, const image2d<int_u16>& lbl,
+ text_recognition(const image2d<bool>& in, const image2d<label16>& lbl,
const util::array<box2d>& tboxes)
{
/// Use txt bboxes here with Tesseract
@@ -195,10 +219,18 @@ namespace scribo
io::txt::save(txt, "out.txt");
}
-
/// \}
+ //--------------------------------------------------
+ /// End of functions related to Text Recognition.
+ //--------------------------------------------------
- /// Functions related to the matrix extraction
+
+
+
+
+ //-*********************************************
+ /// Functions related to the table extraction
+ //-*********************************************
/// \{
/// Align table lines bboxes according to a given dimension.
@@ -259,7 +291,7 @@ namespace scribo
for_all_elements(i, lines)
if (lines[i].nelements() == max_nelts)
{
- accu::mean<int_u16> mean;
+ accu::mean<unsigned> mean;
for_all_elements(j, lines[i])
if (box2line[lines[i][j]] == -1)
mean.take(hboxes[lines[i][j]].center()[dim]);
@@ -282,11 +314,45 @@ namespace scribo
return newlines;
}
+
+
+ /// Connect lines if they are close to each other.
+ void
+ connect_lines(const image2d<bool>& in,
+ const util::array<int>& aligned_lines,
+ util::array<box2d>& boxes,
+ unsigned dim)
+ {
+ image1d<int> l(in.nrows());
+ level::fill(l, -1);
+
+ for_all_elements(i, aligned_lines)
+ l.at(aligned_lines[i]) = i;
+
+ for (unsigned i = 0; i < settings.max_dist_lines; ++i)
+ l = morpho::elementary::dilation(l, c2());
+
+ for_all_components(i, boxes)
+ {
+ std::pair<point2d, point2d> cp = central_sites(boxes[i], dim);
+ if (l.at(cp.first[dim]) != -1)
+ boxes[i].pmin()[dim] = aligned_lines[l.at(cp.first[dim])];
+ if (l.at(cp.second[dim]) != -1)
+ boxes[i].pmax()[dim] = aligned_lines[l.at(cp.second[dim])];
+ }
+ }
+
+
+
+ /// Align line bboxes vertically and horizontally. Then, try to join
+ /// vertical and horizontal lines in order to rebuild the table.
image2d<bool>
rebuild_table(const image2d<bool>& in,
std::pair<util::array<box2d>,
util::array<box2d> >& tblboxes)
{
+ std::cout << "Rebuild table" << std::endl;
+
util::array<int> rows = align_lines(in.nrows(), geom::min_row(in),
geom::max_row(in), tblboxes.second,
0);
@@ -294,43 +360,8 @@ namespace scribo
geom::max_col(in), tblboxes.first,
1);
- image1d<int> v(in.nrows());
- image1d<int> h(in.ncols());
- level::fill(v, -1);
- level::fill(h, -1);
-
- for_all_elements(i, rows)
- v.at(rows[i]) = i;
- for_all_elements(i, cols)
- h.at(cols[i]) = i;
-
- for (int i = 0; i < 10; ++i)
- {
- v = morpho::elementary::dilation(v, c2());
- h = morpho::elementary::dilation(h, c2());
- }
-
- util::array<box2d>& vb = tblboxes.first;
- for_all_components(i, vb)
- {
- std::pair<point2d, point2d> cp = central_sites(vb[i], 0);
- if (v.at(cp.first.row()) != -1)
- vb[i].pmin().row() = rows[v.at(cp.first.row())];
- if (v.at(cp.second.row()) != -1)
- vb[i].pmax().row() = rows[v.at(cp.second.row())];
-
- cp = central_sites(vb[i], 0);
- }
-
- util::array<box2d>& hb = tblboxes.second;
- for_all_components(i, hb)
- {
- std::pair<point2d, point2d> cp = central_sites(hb[i], 1);
- if (h.at(cp.first.col()) != -1)
- hb[i].pmin().col() = cols[h.at(cp.first.col())];
- if (h.at(cp.second.col()) != -1)
- hb[i].pmax().col() = cols[h.at(cp.second.col())];
- }
+ connect_lines(in, rows, tblboxes.first, 0);
+ connect_lines(in, cols, tblboxes.second, 1);
image2d<bool> res;
initialize(res, in);
@@ -349,10 +380,12 @@ namespace scribo
draw::box(out, tblboxes.second[i], literal::red);
io::ppm::save(out, output_file("table.ppm"));
# endif
+
return res;
}
+
void draw_line(image2d<rgb8>& ima,
unsigned dim,
const box2d& box,
@@ -363,6 +396,8 @@ namespace scribo
draw::line(ima, cp.first, cp.second, v);
}
+
+
void draw_row(image2d<rgb8>& ima,
unsigned line,
const rgb8& v)
@@ -370,6 +405,8 @@ namespace scribo
draw::line(ima, point2d(line, 0), point2d(line, ima.ncols()), v);
}
+
+
void draw_col(image2d<rgb8>& ima,
unsigned line,
const rgb8& v)
@@ -377,6 +414,7 @@ namespace scribo
draw::line(ima, point2d(0, line), point2d(ima.nrows(), line), v);
}
+/*
void
extract_matrix(const image2d<bool>& in,
std::pair<util::array<box2d>, util::array<box2d> > tboxes)
@@ -437,34 +475,44 @@ namespace scribo
#endif
}
-
+*/
/// \}
+ //-****************************************************
+ /// End of functions related to the table extraction
+ //-****************************************************
+
+
+ //-*****************************************
/// Functions related to the table removal
+ //-*****************************************
/// \{
+
/// Extract the components bboxes.
util::array<box2d>
component_boxes(const image2d<bool>& filter)
{
std::cout << "component boxes" << std::endl;
- int_u16 nlabels = 0;
- image2d<int_u16> lbl = labeling::blobs(filter, c8(), nlabels);
+ label16 nlabels = 0;
+ image2d<label16> lbl = labeling::blobs(filter, c8(), nlabels);
return labeling::compute(accu::meta::bbox(), lbl, nlabels);
}
+
+
/// Remove table bboxes from an image.
void erase_table_boxes(image2d<bool>& output,
util::array<box2d>& boxes,
- unsigned bbox_enlarge, unsigned dim)
+ unsigned dim)
{
for_all_components(i, boxes)
{
- boxes[i].enlarge(dim, bbox_enlarge + settings.bbox_enlarge);
+ boxes[i].enlarge(dim, settings.bbox_enlarge);
boxes[i].crop_wrt(output.domain());
level::paste((pw::cst(false) | boxes[i] |
(pw::value(output) == pw::cst(true))), output);
@@ -472,13 +520,13 @@ namespace scribo
}
+
/// Find table bboxes and remove them from the image.
std::pair<util::array<box2d>,
util::array<box2d> >
- extract_tables(image2d<bool>& in,
- image2d<rgb8>& output)
+ extract_tables(image2d<bool>& in)
{
- typedef image2d<int_u16> I;
+ typedef image2d<label16> I;
typedef accu::bbox<mln_psite_(I)> A;
typedef util::array<mln_result_(A)> boxes_t;
@@ -486,7 +534,7 @@ namespace scribo
// Lignes verticales
std::cout << "Removing vertical lines" << std::endl;
win::vline2d vline(settings.ero_line_width);
- image2d<bool> vfilter = morpho::erosion(in, vline);
+ image2d<bool> vfilter = morpho::rank_filter(in, win_c4p(), settings.rank_filter);
#ifndef NOUT
io::pbm::save(vfilter, output_file("vertical-erosion.pbm"));
@@ -497,7 +545,7 @@ namespace scribo
// Lignes horizontales
std::cout << "Removing horizontal lines" << std::endl;
win::hline2d hline(settings.ero_line_width);
- image2d<bool> hfilter = morpho::erosion(in, hline);
+ image2d<bool> hfilter = morpho::rank_filter(in, hline, settings.rank_filter);
#ifndef NOUT
io::pbm::save(hfilter, output_file("horizontal-erosion.pbm"));
@@ -505,11 +553,11 @@ namespace scribo
boxes_t hboxes = component_boxes(hfilter);
- erase_table_boxes(in, vboxes, (settings.ero_line_width / 2), 0);
- erase_table_boxes(in, hboxes, (settings.ero_line_width / 2), 1);
+ erase_table_boxes(in, vboxes, 0);
+ erase_table_boxes(in, hboxes, 1);
#ifndef NOUT
- image2d<rgb8> tmp = clone(output);
+ image2d<rgb8> tmp = level::convert(rgb8(), in);
draw_component_boxes(tmp, vboxes);
draw_component_boxes(tmp, hboxes);
io::ppm::save(tmp, output_file("vertical-and-horizontal-erosion.ppm"));
@@ -519,79 +567,133 @@ namespace scribo
}
/// \}
+ //--------------------------------------------------
/// End of functions related to the table removal.
+ //--------------------------------------------------
+
+
+
+ //-***************************************
/// Function related to text extraction
+ //-***************************************
/// \{
- inline
- int_u16
- most_left(const fun::i2v::array<int_u16>& left_link, unsigned i)
+ fun::i2v::array<label16>
+ make_relabel_fun(const util::graph& g)
{
- while (left_link(i) != i)
- i = left_link(i);
- return i;
- }
+ fun::i2v::array<label16> fun(g.v_nmax(), mln_max(label16));
- inline
- int_u16
- uncurri_left_link(fun::i2v::array<int_u16>& left_link, unsigned i)
- {
- if (left_link(i) != i)
- left_link(i) = uncurri_left_link(left_link, left_link(i));
- return left_link(i);
+ mln_vertex_iter_(util::graph) v(g);
+ for_all(v)
+ if (fun(v.id()) == mln_max(label16))
+ {
+ std::queue<unsigned> queue;
+ queue.push(v.id());
+ fun(v.id()) = v.id();
+ while (!queue.empty())
+ {
+ util::vertex<util::graph> current_v = g.vertex(queue.front());
+ queue.pop();
+ for (unsigned nv = 0; nv < current_v.nmax_nbh_vertices(); ++nv)
+ if (fun(current_v.ith_nbh_vertex(nv)) == mln_max(label16))
+ {
+ fun(current_v.ith_nbh_vertex(nv)) = v.id();
+ queue.push(current_v.ith_nbh_vertex(nv));
+ }
+ }
+ }
+
+ return fun;
}
- template <typename V>
- void
- remove_small_comps_i2v(image2d<V>& lbl,
- V& nlabels)
+
+
+ template <typename R>
+ struct remove_small_comps
+ : Function_l2b< remove_small_comps<R> >
{
- std::cout << "Removing small components smaller than "
- << settings.min_comp_size << " sites among " << nlabels
- << " components" << std::endl;
+ remove_small_comps(const util::array<R>& nsitecomp)
+ : nsitecomp_(nsitecomp)
+ {
+ }
- typedef accu::count<mln_psite(image2d<V>)> accu_count_t;
+ /// Return false if the components is smaller than a given size.
+ bool operator()(const label16& l) const
+ {
+ return nsitecomp_[l].first >= settings.min_comp_size;
+ }
- util::array<mln_result(accu_count_t)> nsitecomp
- = labeling::compute(accu_count_t(), lbl, nlabels);
+ const util::array<R>& nsitecomp_;
+ };
- V ncomp = 0;
- fun::i2v::array<V> f(nsitecomp.nelements());
- f(0) = 0;
- for_all_ncomponents(i, nlabels)
+ template <typename R>
+ struct remove_smallandlarge_comps
+ : Function_l2b< remove_smallandlarge_comps<R> >
+ {
+ remove_smallandlarge_comps(const util::array<R>& nsitecomp)
+ : nsitecomp_(nsitecomp)
{
- if (nsitecomp[i] < settings.min_comp_size)
- f(i) = 0;
- else
- f(i) = ++ncomp;
}
- lbl = level::transform(lbl, f);
- nlabels = ncomp;
+ /// Return false if the components is smaller than a given size.
+ bool operator()(const label16& l) const
+ {
+ return nsitecomp_[l].first >= settings.min_comp_size
+ && nsitecomp_[l].first < settings.max_comp_size
+ && math::abs(nsitecomp_[l].second.pmax().row()
+ - nsitecomp_[l].second.pmin().row())
+ <= settings.max_txt_box_height;
+ }
-#ifndef NOUT
- save_lbl_image(lbl, nlabels, "lbl-small-comps-removed.pgm");
-#endif
+ const util::array<R>& nsitecomp_;
+ };
+
+
+
+ void
+ cleanup_components(image2d<label16>& lbl,
+ label16& nlabels, bool treat_tables)
+ {
+ std::cout << "Cleanup components..." << std::endl;
+
+ typedef accu::count<mln_psite_(image2d<label16>)> accu_count_t;
+ typedef accu::bbox<mln_psite_(image2d<label16>)> accu_bbox_t;
+ typedef accu::pair<accu_count_t, accu_bbox_t> accu_pair_t;
+ typedef mln_result_(accu_pair_t) accu_res_t;
+ typedef util::array<accu_res_t> nsitecomp_t;
+
+ nsitecomp_t nsitecomp = labeling::compute(accu_pair_t(), lbl, nlabels);
+ if (treat_tables)
+ {
+ remove_small_comps<accu_res_t> fl2b(nsitecomp);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+ } else
+ {
+ remove_smallandlarge_comps<accu_res_t> fl2b(nsitecomp);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+ }
}
+
/// Merge bboxes according to their left box neighbor.
util::array< box2d >
- group_bboxes(fun::i2v::array<int_u16>& left_link, image2d<int_u16>& lbl,
+ group_bboxes(const util::graph& g, image2d<label16>& lbl,
util::array<box2d>& cboxes, unsigned ncomp)
{
- // Currify left_link lookup table and compute text area bboxes.
+ fun::i2v::array<label16> relabel_fun = make_relabel_fun(g);
+
util::array< accu::bbox<point2d> > tboxes;
tboxes.resize(ncomp + 1);
for_all_ncomponents(i, ncomp)
- tboxes[uncurri_left_link(left_link, i)].take(cboxes[i]);
+ tboxes[relabel_fun(i)].take(cboxes[i]);
//Update labels
- lbl = level::transform(lbl, left_link);
+ level::transform_inplace(lbl, relabel_fun);
#ifndef NOUT
save_lbl_image(lbl, ncomp, "lbl-grouped-boxes.pgm");
@@ -606,36 +708,28 @@ namespace scribo
}
+
/// Update the lookup table \p left if a neighbor is found on the right of
/// the current bbox.
- void update_link(fun::i2v::array<int_u16>& left_link, image2d<int_u16>& lbl,
+ void update_link(util::graph& g, image2d<label16>& lbl,
const point2d& p, const point2d& c,
unsigned i, int dmax)
{
if (lbl.domain().has(p) && lbl(p) != 0u && lbl(p) != i
&& (math::abs(p.col() - c.col())) < dmax)
- {
- if (left_link(lbl(p)) == lbl(p) && most_left(left_link, i) != lbl(p))
- left_link(lbl(p)) = i;
-// else
-// left_link(lbl(p)) = 0;//FIXME: should be uncommented? VERY bad results otherwise.
- }
+ g.add_edge(lbl(p), i);
}
/// Map each character bbox to its left bbox neighbor if possible.
/// Iterate to the right but link boxes to the left.
- fun::i2v::array<int_u16>
- link_character_bboxes(image2d<int_u16>& lbl,
+ util::graph
+ link_character_bboxes(image2d<label16>& lbl,
const util::array<box2d>& cboxes,
unsigned ncomp)
{
- fun::i2v::array<int_u16> left_link;
- left_link.resize(ncomp + 1);
-
- for (unsigned i = 0; i <= ncomp; ++i)
- left_link(i) = i;
+ util::graph g(ncomp + 1);
for_all_ncomponents(i, ncomp)
{
@@ -650,33 +744,29 @@ namespace scribo
&& math::abs(p.col() - c.col()) < dmax)
++p.col();
- update_link(left_link, lbl, p, c, i, dmax);
+ update_link(g, lbl, p, c, i, dmax);
}
- return left_link;
+ return g;
}
+
+
util::array<box2d>
extract_text(image2d<bool>& in,
- image2d<int_u16>& lbl,
- image2d<rgb8>& output)
+ image2d<label16>& lbl,
+ const label16& nlabels)
{
+ std::cout << "extract text" << std::endl;
- typedef int_u16 V;
+ typedef label16 V;
typedef image2d<V> I;
typedef util::array<box2d> boxes_t;
- // Find character bboxes.
- V nlabels;
- lbl = labeling::blobs(in, c8(), nlabels);
-
- //Remove small components.
- remove_small_comps_i2v(lbl, nlabels);
-
boxes_t cboxes = labeling::compute(accu::meta::bbox(), lbl, nlabels);
#ifndef NOUT
- image2d<rgb8> tmp = clone(output);
+ image2d<rgb8> tmp = level::convert(rgb8(), in);
draw_component_boxes(tmp, cboxes);
io::ppm::save(tmp, output_file("character-bboxes.ppm"));
#endif
@@ -684,48 +774,57 @@ namespace scribo
//merge_bboxes(cboxes, lbl, nlabels);
//Link character bboxes to their left neighboor if possible.
- fun::i2v::array<int_u16> left =
- link_character_bboxes(lbl, cboxes, nlabels);
+ util::graph g = link_character_bboxes(lbl, cboxes, nlabels);
//Merge character bboxes according to their left neighbor.
- util::array<box2d> tboxes = group_bboxes(left, lbl, cboxes, nlabels);
+ util::array<box2d> tboxes = group_bboxes(g, lbl, cboxes, nlabels);
return tboxes;
}
+
+
void maptext_to_cells(const image2d<bool>& in, const image2d<bool>& table, const util::array<box2d>& tboxes)
{
- int_u16 nlabels;
- image2d<int_u16> tblelbl = labeling::background(table, c8(), nlabels);
- image2d<rgb8> color = debug::colorize<image2d<rgb8>, image2d<int_u16> >(tblelbl, nlabels);
+ std::cout << "map text to cells" << std::endl;
+ label16 nlabels;
+ image2d<label16> tblelbl = labeling::background(table, c8(), nlabels);
+ image2d<rgb8> color = debug::colorize<image2d<rgb8>, image2d<label16> >(tblelbl, nlabels);
# ifndef NOUT
io::ppm::save(color, output_file("cells-labels.ppm"));
-# endif
image2d<rgb8> dbg = level::convert(rgb8(), logical::not_(table));
for_all_elements(i, tboxes)
if (tboxes[i].is_valid())
- {
level::paste(pw::cst(color(tboxes[i].center())) | (tboxes[i] | pw::value(in) == pw::cst(true)),
dbg);
- }
-# ifndef NOUT
io::ppm::save(dbg, output_file("text2cell.ppm"));
# endif
}
+
/// \}
+ //-----------------------------------------------
/// End of functions related to text extraction
+ //-----------------------------------------------
+
+
+
} // end of namespace scribo::internal
+
+
+
+
// Facade
+
void demat(char *argv[], bool treat_tables)
{
using namespace mln;
using value::rgb8;
- using value::int_u16;
+ using value::label16;
border::thickness = 3;
trace::quiet = true;
@@ -738,7 +837,16 @@ namespace scribo
io::pbm::load(in, argv[1]);
logical::not_inplace(in);
- image2d<rgb8> output = level::convert(rgb8(), in);
+#ifndef NOUT
+ image2d<bool> in_bak = clone(in);
+#endif
+
+ internal::settings.max_comp_size = in.ncols() * in.nrows() * 0.05;
+
+ //Label and remove small components.
+ label16 nlabels;
+ image2d<label16> lbl = labeling::blobs(in, c8(), nlabels);
+ internal::cleanup_components(lbl, nlabels, treat_tables);
std::pair<util::array<box2d>,
util::array<box2d> > tblboxes;
@@ -746,20 +854,30 @@ namespace scribo
image2d<bool> table;
if (treat_tables)
{
- tblboxes = internal::extract_tables(in, output);
+ tblboxes = internal::extract_tables(in);
// internal::extract_matrix(in, tblboxes);
table = internal::rebuild_table(in, tblboxes);
+
+ lbl = labeling::blobs(in, c8(), nlabels);
+ internal::cleanup_components(lbl, nlabels, treat_tables);
+
+#ifndef NOUT
+ internal::save_lbl_image(lbl, nlabels, "lbl-small-comps-removed.pgm");
+#endif
}
- image2d<value::int_u16> lbl;
util::array<box2d> tboxes =
- internal::extract_text(in, lbl, output);
+ internal::extract_text(in, lbl, nlabels);
if (treat_tables)
internal::maptext_to_cells(in, table, tboxes);
+#ifndef NOUT
+ std::cout << "Saving output" << std::endl;
+ image2d<rgb8> output = level::convert(rgb8(), in_bak);
internal::draw_component_boxes(output, tboxes);
io::ppm::save(output, internal::output_file("out.ppm"));
+#endif
internal::text_recognition(in, lbl, tboxes);
}
--
1.5.6.5
1
0
* mln/fun/l2l/all.hh
* mln/fun/l2l/essential.hh: new headers.
* mln/value/all.hh,
* mln/accu/bbox.hh: Fix comments.
* mln/fun/i2v/array.hh: add missing constructor implementation.
* mln/value/essential.hh,
* mln/value/aliases.hh,
* mln/level/essential.hh,
* mln/labeling/essential.hh: update includes.
* mln/make/relabelfun.hh: Fix a bug. New component ids were not set
correclty.
* mln/value/label.hh: Fix a duplicate attribute.
* mln/labeling/compute.hh,
* mln/debug/colorize.hh: use label::next() instead of operator '+' to
get the next label.
---
milena/ChangeLog | 26 ++++++++++++++++
milena/mln/accu/bbox.hh | 6 ++--
milena/mln/debug/colorize.hh | 9 ++++--
milena/mln/fun/i2v/array.hh | 7 ++++
milena/mln/{value/aliases.hh => fun/l2l/all.hh} | 34 ++++++++++++++-------
milena/mln/{labeling => fun/l2l}/essential.hh | 18 +++++------
milena/mln/labeling/compute.hh | 6 ++-
milena/mln/labeling/essential.hh | 10 +++---
milena/mln/level/essential.hh | 1 +
milena/mln/make/relabelfun.hh | 3 +-
milena/mln/value/aliases.hh | 19 +++++++++---
milena/mln/value/all.hh | 9 ++---
milena/mln/value/essential.hh | 12 ++++---
milena/mln/value/label.hh | 36 +++++++----------------
14 files changed, 120 insertions(+), 76 deletions(-)
copy milena/mln/{value/aliases.hh => fun/l2l/all.hh} (75%)
copy milena/mln/{labeling => fun/l2l}/essential.hh (78%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index d149788..404e42b 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,31 @@
2008-11-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Various small fixes.
+
+ * mln/fun/l2l/all.hh
+ * mln/fun/l2l/essential.hh: new headers.
+
+ * mln/value/all.hh,
+ * mln/accu/bbox.hh: Fix comments.
+
+ * mln/fun/i2v/array.hh: add missing constructor implementation.
+
+ * mln/value/essential.hh,
+ * mln/value/aliases.hh,
+ * mln/level/essential.hh,
+ * mln/labeling/essential.hh: update includes.
+
+ * mln/make/relabelfun.hh: Fix a bug. New component ids were not set
+ correclty.
+
+ * mln/value/label.hh: Fix a duplicate attribute.
+
+ * mln/labeling/compute.hh,
+ * mln/debug/colorize.hh: use label::next() instead of operator '+' to
+ get the next label.
+
+2008-11-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Update rank_filter.
* mln/accu/rank_bool.hh: Add untake() and remove unnecessary
diff --git a/milena/mln/accu/bbox.hh b/milena/mln/accu/bbox.hh
index 90c2e5d..7c3e35f 100644
--- a/milena/mln/accu/bbox.hh
+++ b/milena/mln/accu/bbox.hh
@@ -45,9 +45,9 @@ namespace mln
/// Generic bbox accumulator class.
- /*!
- * The parameter \c P is the type of points.
- */
+ ///
+ /// The parameter \c P is the type of points.
+ ///
template <typename P>
struct bbox : public mln::accu::internal::base< const box<P>& , bbox<P> >
{
diff --git a/milena/mln/debug/colorize.hh b/milena/mln/debug/colorize.hh
index f764278..cf99383 100644
--- a/milena/mln/debug/colorize.hh
+++ b/milena/mln/debug/colorize.hh
@@ -100,12 +100,15 @@ namespace mln
{
trace::entering("debug::colorize");
mln_precondition(exact(input).has_data());
+ // FIXME: we want to be sure that this is a label.
+ mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
+ unsigned label_count = nlabels.next();
static fun::i2v::array<mln_value(I)> f(0);
- int diff_size = f.size() - (nlabels + 1);
+ int diff_size = f.size() - label_count;
if (diff_size < 0)
{
- f.resize(nlabels + 1);
+ f.resize(label_count);
unsigned i = f.size() + diff_size;
// We want to treat comp 0 differently since it is the background.
if (i == 0)
@@ -116,7 +119,7 @@ namespace mln
for (; i < f.size(); ++i)
f(i) = internal::random_color();
}
- mln_precondition(f.size() == (nlabels + 1));
+ mln_precondition(f.size() == (label_count));
mln_concrete(I) output = level::transform(input, f);
trace::exiting("debug::colorize");
diff --git a/milena/mln/fun/i2v/array.hh b/milena/mln/fun/i2v/array.hh
index ee9b1bb..630675e 100644
--- a/milena/mln/fun/i2v/array.hh
+++ b/milena/mln/fun/i2v/array.hh
@@ -166,6 +166,13 @@ namespace mln
template <typename T>
inline
+ array<T>::array(unsigned n, const T& val)
+ : super_base_(n, val)
+ {
+ }
+
+ template <typename T>
+ inline
array<T>::array(const util::array<T>& from)
: super_base_(from)
{
diff --git a/milena/mln/value/aliases.hh b/milena/mln/fun/l2l/all.hh
similarity index 75%
copy from milena/mln/value/aliases.hh
copy to milena/mln/fun/l2l/all.hh
index c3790b8..c763ca7 100644
--- a/milena/mln/value/aliases.hh
+++ b/milena/mln/fun/l2l/all.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 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
@@ -25,19 +25,31 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_VALUE_ALIASES_HH
-# define MLN_VALUE_ALIASES_HH
+#ifndef MLN_FUN_L2L_ALL_HH
+# define MLN_FUN_L2L_ALL_HH
-/*! \file mln/value/aliases.hh
- *
- * \brief File that includes all aliases of value types.
- */
+/// \file mln/fun/l2l/all.hh
+///
+/// File that includes all functions from index to value.
-# include <mln/value/int_u8.hh>
-# include <mln/value/int_u16.hh>
+namespace mln
+{
-# include <mln/value/int_s8.hh>
+ namespace fun
+ {
+ /// Namespace of functions from label to label.
+ namespace l2l
+ {
+ }
+ }
-#endif // ! MLN_VALUE_ALIASES_HH
+}
+
+
+# include <mln/fun/l2l/relabel.hh>
+
+
+
+#endif // ! MLN_FUN_L2L_ALL_HH
diff --git a/milena/mln/labeling/essential.hh b/milena/mln/fun/l2l/essential.hh
similarity index 78%
copy from milena/mln/labeling/essential.hh
copy to milena/mln/fun/l2l/essential.hh
index 940f2c2..6ca53c0 100644
--- a/milena/mln/labeling/essential.hh
+++ b/milena/mln/fun/l2l/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 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
@@ -25,15 +25,13 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_LABELING_ESSENTIAL_HH
-# define MLN_LABELING_ESSENTIAL_HH
+#ifndef MLN_FUN_L2L_ESSENTIAL_HH
+# define MLN_FUN_L2L_ESSENTIAL_HH
-/*! \file mln/labeling/essential.hh
- *
- * \brief File that includes essential labeling routines.
- */
+/// \file mln/fun/l2l/essential.hh
+///
+/// File that includes essential functions from label to label.
-# include <mln/labeling/blobs.hh>
-# include <mln/labeling/compute.hh>
+# include <mln/fun/l2l/all.hh>
-#endif // ! MLN_LABELING_ESSENTIAL_HH
+#endif // ! MLN_FUN_L2L_ESSENTIAL_HH
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index 6233979..dfc95f1 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -32,6 +32,8 @@
///
/// Compute accumulators onto sites/values of each labeled component
/// of an image.
+///
+/// \todo write fastest version.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/accumulator.hh>
@@ -171,7 +173,7 @@ namespace mln
const A& a = exact(a_);
const L& label = exact(label_);
- util::array<A> accus(nlabels + 1, a);
+ util::array<A> accus(nlabels.next(), a);
mln_piter(L) p(label.domain());
for_all(p)
@@ -197,7 +199,7 @@ namespace mln
const I& input = exact(input_);
const L& label = exact(label_);
- util::array<A> accus (nlabels + 1, a);
+ util::array<A> accus (nlabels.next(), a);
mln_piter(I) p(input.domain());
for_all(p)
diff --git a/milena/mln/labeling/essential.hh b/milena/mln/labeling/essential.hh
index 940f2c2..3a5544d 100644
--- a/milena/mln/labeling/essential.hh
+++ b/milena/mln/labeling/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 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
@@ -28,12 +28,12 @@
#ifndef MLN_LABELING_ESSENTIAL_HH
# define MLN_LABELING_ESSENTIAL_HH
-/*! \file mln/labeling/essential.hh
- *
- * \brief File that includes essential labeling routines.
- */
+/// \file mln/labeling/essential.hh
+///
+/// File that includes essential labeling routines.
# include <mln/labeling/blobs.hh>
# include <mln/labeling/compute.hh>
+# include <mln/labeling/relabel.hh>
#endif // ! MLN_LABELING_ESSENTIAL_HH
diff --git a/milena/mln/level/essential.hh b/milena/mln/level/essential.hh
index f545c0e..e89031e 100644
--- a/milena/mln/level/essential.hh
+++ b/milena/mln/level/essential.hh
@@ -47,6 +47,7 @@
# include <mln/level/replace.hh>
# include <mln/level/saturate.hh>
# include <mln/level/transform.hh>
+# include <mln/level/transform_inplace.hh>
# include <mln/level/update.hh>
# include <mln/level/approx/essential.hh>
diff --git a/milena/mln/make/relabelfun.hh b/milena/mln/make/relabelfun.hh
index d02dd88..abbba80 100644
--- a/milena/mln/make/relabelfun.hh
+++ b/milena/mln/make/relabelfun.hh
@@ -75,8 +75,7 @@ namespace mln
for (label_t i = 1; i <= nlabels; ++i)
if (fl2b(i))
{
- fl2l(i) = i;
- ++tmp_nlabels;
+ fl2l(i) = ++tmp_nlabels;
}
new_nlabels = tmp_nlabels;
trace::exiting("mln::make::relabelfun");
diff --git a/milena/mln/value/aliases.hh b/milena/mln/value/aliases.hh
index c3790b8..8fe2485 100644
--- a/milena/mln/value/aliases.hh
+++ b/milena/mln/value/aliases.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// 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
@@ -28,16 +28,25 @@
#ifndef MLN_VALUE_ALIASES_HH
# define MLN_VALUE_ALIASES_HH
-/*! \file mln/value/aliases.hh
- *
- * \brief File that includes all aliases of value types.
- */
+/// \file mln/value/aliases.hh
+///
+/// File that includes all aliases of value types.
+# include <mln/value/float01_8.hh>
+# include <mln/value/float01_16.hh>
# include <mln/value/int_u8.hh>
# include <mln/value/int_u16.hh>
+# include <mln/value/int_u32.hh>
# include <mln/value/int_s8.hh>
+# include <mln/value/int_s16.hh>
+# include <mln/value/int_s32.hh>
+# include <mln/value/label_8.hh>
+# include <mln/value/label_16.hh>
+
+# include <mln/value/rgb8.hh>
+# include <mln/value/rgb16.hh>
#endif // ! MLN_VALUE_ALIASES_HH
diff --git a/milena/mln/value/all.hh b/milena/mln/value/all.hh
index 2620f21..27ef955 100644
--- a/milena/mln/value/all.hh
+++ b/milena/mln/value/all.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// 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
@@ -28,10 +28,9 @@
#ifndef MLN_VALUE_ALL_HH
# define MLN_VALUE_ALL_HH
-/*! \file mln/value/all.hh
- *
- * \brief File that includes all "value types"-related materials.
- */
+/// \file mln/value/all.hh
+///
+/// File that includes all "value types"-related materials.
namespace mln
diff --git a/milena/mln/value/essential.hh b/milena/mln/value/essential.hh
index e537eff..4d0b97b 100644
--- a/milena/mln/value/essential.hh
+++ b/milena/mln/value/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 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
@@ -28,10 +28,9 @@
#ifndef MLN_VALUE_ESSENTIAL_HH
# define MLN_VALUE_ESSENTIAL_HH
-/*! \file mln/value/essential.hh
- *
- * \brief File that includes essential "value types"-related materials.
- */
+/// \file mln/value/essential.hh
+///
+/// File that includes essential "value types"-related materials.
# include <mln/value/concept/essential.hh>
# include <mln/value/builtin/essential.hh>
@@ -50,6 +49,9 @@
# include <mln/value/int_u16.hh>
# include <mln/value/int_u32.hh>
+# include <mln/value/label_8.hh>
+# include <mln/value/label_16.hh>
+
# include <mln/value/rgb8.hh>
# include <mln/value/rgb16.hh>
diff --git a/milena/mln/value/label.hh b/milena/mln/value/label.hh
index 02eec94..8421133 100644
--- a/milena/mln/value/label.hh
+++ b/milena/mln/value/label.hh
@@ -129,12 +129,6 @@ namespace mln
/// Return the next value.
label<n> next() const;
- /// Conversion to unsigned.
- const enc& to_enc() const;
-
- protected:
-
- enc v_;
};
@@ -165,21 +159,21 @@ namespace mln
inline
label<n>::label(unsigned i)
{
- v_ = enc(i);
+ this->v_ = enc(i);
}
template <unsigned n>
inline
label<n>::label(const literal::zero_t&)
{
- v_ = 0;
+ this->v_ = 0;
}
template <unsigned n>
inline
label<n>::operator unsigned() const
{
- return to_enc();
+ return this->to_enc();
}
template <unsigned n>
@@ -188,7 +182,7 @@ namespace mln
label<n>::operator=(unsigned i)
{
mln_precondition(i <= mln_max(enc));
- v_ = enc(i);
+ this->v_ = enc(i);
return *this;
}
@@ -197,7 +191,7 @@ namespace mln
label<n>&
label<n>::operator=(const literal::zero_t&)
{
- v_ = 0;
+ this->v_ = 0;
return *this;
}
@@ -206,8 +200,8 @@ namespace mln
label<n>&
label<n>::operator++()
{
- mln_precondition(v_ < mln_max(enc));
- ++v_;
+ mln_precondition(this->v_ < mln_max(enc));
+ ++this->v_;
return *this;
}
@@ -216,8 +210,8 @@ namespace mln
label<n>&
label<n>::operator--()
{
- mln_precondition(v_ != 0);
- --v_;
+ mln_precondition(this->v_ != 0);
+ --this->v_;
return *this;
}
@@ -226,22 +220,14 @@ namespace mln
label<n>
label<n>::next() const
{
- return label<n>(v_ + 1);
- }
-
- template <unsigned n>
- inline
- const mln_enc(label<n>)&
- label<n>::to_enc() const
- {
- return v_;
+ return label<n>(this->v_ + 1);
}
template <unsigned n>
inline
std::ostream& operator<<(std::ostream& ostr, const label<n>& i)
{
- return ostr << i.to_enc();
+ return ostr << debug::format(i.to_equiv());
}
# endif // ! MLN_INCLUDE_ONLY
--
1.5.6.5
1
0