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
milena r3552: Optimize propagations and add component processing functions
by Edwin Carlinet 19 Mar '09
by Edwin Carlinet 19 Mar '09
19 Mar '09
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-03-19 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Optimize propagations and add component processing functions.
* mln/morpho/tree/data.hh: Add optimization about preorder
iterator.
* tests/morpho/tree/data.cc: Update test file.
* sandbox/edwin/tree/accumulator/arg_max.hh: New accumulator
that returns site having the max value.
* sandbox/edwin/tree/accumulator/max.hh: Remove.
* sandbox/edwin/tree/propagate.hh: Make clean.
* sandbox/edwin/tree/propagate_if.hh: Functions performing
different propagations on nodes matching a predicate.
* sandbox/edwin/tree/propagate_node.hh: Basic ascendant and
descendant propagations computation.
* sandbox/edwin/tree/propagation.cc: Test file for propagations.
* sandbox/edwin/tree/routines.hh: Remove.
* sandbox/edwin/tree/run.hh: Methods to apply accumulator on
tree nodes, and to perform object component research with a
criteria (treshold...).
* sandbox/edwin/tree/test.cc: New.
---
mln/morpho/tree/data.hh | 134 ++++++++++--
sandbox/edwin/tree/Makefile | 6
sandbox/edwin/tree/accumulator/arg_max.hh | 160 +++++++++++++++
sandbox/edwin/tree/propagate.hh | 102 ---------
sandbox/edwin/tree/propagate_if.hh | 320 ++++++++++++++++++++++++++++++
sandbox/edwin/tree/propagate_node.hh | 46 ++--
sandbox/edwin/tree/propagation.cc | 82 ++++---
sandbox/edwin/tree/run.hh | 272 +++++++++++++++++++++++++
sandbox/edwin/tree/test.cc | 98 +++++++++
tests/morpho/tree/data.cc | 14 +
10 files changed, 1052 insertions(+), 182 deletions(-)
Index: trunk/milena/tests/morpho/tree/data.cc
===================================================================
--- trunk/milena/tests/morpho/tree/data.cc (revision 3551)
+++ trunk/milena/tests/morpho/tree/data.cc (revision 3552)
@@ -65,11 +65,18 @@
/* Check site and node up order */
tree_t::up_node_piter n(t);
tree_t::up_site_piter s(t);
+ tree_t::up_leaf_piter l(t);
n.start();
+ l.start();
for_all(s)
if (t.is_a_node(s))
{
mln_assertion(s == n);
+ if (t.is_a_leaf(n))
+ {
+ mln_assertion(l == n);
+ l.next();
+ }
n.next();
}
mln_assertion(!n.is_valid());
@@ -79,11 +86,18 @@
/* Check site and node up order */
tree_t::dn_node_piter n(t);
tree_t::dn_site_piter s(t);
+ tree_t::dn_leaf_piter l(t);
n.start();
+ l.start();
for_all(s)
if (t.is_a_node(s))
{
mln_assertion(s == n);
+ if (t.is_a_leaf(n))
+ {
+ mln_assertion(l == n);
+ l.next();
+ }
n.next();
}
mln_assertion(!n.is_valid());
Index: trunk/milena/mln/morpho/tree/data.hh
===================================================================
--- trunk/milena/mln/morpho/tree/data.hh (revision 3551)
+++ trunk/milena/mln/morpho/tree/data.hh (revision 3552)
@@ -47,12 +47,16 @@
# define mln_dn_site_piter(T) typename T::dn_site_piter
# define mln_up_node_piter(T) typename T::up_node_piter
# define mln_dn_node_piter(T) typename T::dn_node_piter
+# define mln_up_leaf_piter(T) typename T::up_leaf_piter
+# define mln_dn_leaf_piter(T) typename T::dn_leaf_piter
# define mln_preorder_piter(T) typename T::preorder_piter
# define mln_up_site_piter_(T) T::up_site_piter
# define mln_dn_site_piter_(T) T::dn_site_piter
# define mln_up_node_piter_(T) T::up_node_piter
# define mln_dn_node_piter_(T) T::dn_node_piter
+# define mln_up_leaf_piter_(T) T::up_leaf_piter
+# define mln_dn_leaf_piter_(T) T::dn_leaf_piter
# define mln_preorder_piter_(T) T::preorder_piter
namespace mln
@@ -78,6 +82,12 @@
/// Iterate on tree's nodes (component representants) from leaves to roots.
template <typename T> struct dn_node_piter;
+ /// Iterate on tree's leaves in the same way of up_node_piter.
+ template <typename T> struct up_leaf_piter;
+
+ /// Iterate on tree's leaves in the same way of dn_node_piter.
+ template <typename T> struct dn_leaf_piter;
+
/// Preorder tree traversal iterator.
template <typename T> struct preorder_piter;
@@ -101,8 +111,10 @@
typedef mln_site(I) site;
/// Site set associated type.
typedef S sites_t;
- /// Node list associated type.
+ /// Node set associated type.
typedef p_array<mln_psite(I)> nodes_t;
+ /// Leaf set associated type.
+ typedef p_array<mln_psite(I)> leaves_t;
/// Parent image associated type.
typedef mln_ch_value(I, mln_psite(I)) parent_t;
@@ -115,6 +127,10 @@
typedef mln::morpho::tree::up_node_piter<self_> up_node_piter;
typedef mln::morpho::tree::dn_node_piter<self_> dn_node_piter;
+ // Iterate on leaves only.
+ typedef mln::morpho::tree::up_leaf_piter<self_> up_leaf_piter;
+ typedef mln::morpho::tree::dn_leaf_piter<self_> dn_leaf_piter;
+
typedef mln::morpho::tree::preorder_piter<self_> preorder_piter;
// typedef mln_bkd_piter(S) piter;
@@ -123,7 +139,7 @@
/// Constructor.
template <typename N>
- explicit data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh);
+ data(const Image<I>& f, const Site_Set<S>& s, const Neighborhood<N>& nbh);
@@ -134,32 +150,46 @@
/// \}
+ /// \{ Child-related materials.
+
const p_array<mln_psite(I)>& children(const mln_psite(I)& p) const;
const mln_ch_value(I, nodes_t)& children_image() const;
- /// \{ Tests.
+ /// \}
- bool is_valid() const;
- bool is_root(const mln_psite(I)& p) const;
- bool is_a_node(const mln_psite(I)& p) const;
- bool is_a_non_root_node(const mln_psite(I)& p) const;
- bool is_a_leaf(const mln_psite(I)& p) const;
+ /// \{ Nodes materials.
- /// \}
+ const p_array<mln_psite(I)>& nodes() const;
+ /// \}
- /// \{ Nodes-related materials.
+ /// \{ Leaves materials.
- const p_array<mln_psite(I)>& nodes() const;
+ const p_array<mln_psite(I)>& leaves() const;
/// \}
- /// \{ Sites-related materials.
+ /// \{ Sites materials.
const S& domain() const;
/// \}
+
+
+ /// \{ Tests.
+
+ bool is_valid() const;
+ bool is_root(const mln_psite(I)& p) const;
+ bool is_a_node(const mln_psite(I)& p) const;
+ bool is_a_non_root_node(const mln_psite(I)& p) const;
+ bool is_a_leaf(const mln_psite(I)& p) const;
+
+ /// \}
+
+
+
+
unsigned nroots() const;
@@ -175,10 +205,13 @@
mln_ch_value(I, mln_psite(I)) parent_; // Parent image.
mln_ch_value(I, nodes_t) children_; // Children image.
nodes_t nodes_;
+ leaves_t leaves_;
unsigned nroots_;
};
+ /* Iterators */
+
template <typename T>
struct up_site_piter
: public mln::internal::piter_identity_< typename T::sites_t::bkd_piter, // Adaptee.
@@ -227,7 +260,7 @@
up_node_piter<T> > // Exact.
{
private:
- typedef typename T::sites_t::fwd_piter Pi_;
+ typedef typename T::nodes_t::fwd_piter Pi_;
typedef mln::internal::piter_identity_< Pi_, up_node_piter<T> > super_;
public:
@@ -248,7 +281,7 @@
dn_node_piter<T> > // Exact.
{
private:
- typedef typename T::sites_t::bkd_piter Pi_;
+ typedef typename T::nodes_t::bkd_piter Pi_;
typedef mln::internal::piter_identity_< Pi_, dn_node_piter<T> > super_;
public:
@@ -264,6 +297,48 @@
};
template <typename T>
+ struct up_leaf_piter
+ : public mln::internal::piter_identity_< typename T::leaves_t::fwd_piter, // Adaptee.
+ up_leaf_piter<T> > // Exact.
+ {
+ private:
+ typedef typename T::leaves_t::fwd_piter Pi_;
+ typedef mln::internal::piter_identity_< Pi_, up_leaf_piter<T> > super_;
+
+ public:
+ up_leaf_piter(const T& t)
+ {
+ this->change_target(t.leaves());
+ }
+
+ up_leaf_piter(const Pi_& pi)
+ : super_(pi)
+ {
+ }
+ };
+
+ template <typename T>
+ struct dn_leaf_piter
+ : public mln::internal::piter_identity_< typename T::leaves_t::bkd_piter, // Adaptee.
+ dn_leaf_piter<T> > // Exact.
+ {
+ private:
+ typedef typename T::leaves_t::bkd_piter Pi_;
+ typedef mln::internal::piter_identity_< Pi_, dn_leaf_piter<T> > super_;
+
+ public:
+ dn_leaf_piter(const T& t)
+ {
+ this->change_target(t.leaves());
+ }
+
+ dn_leaf_piter(const Pi_& pi)
+ : super_(pi)
+ {
+ }
+ };
+
+ template <typename T>
class preorder_piter
: public mln::internal::site_set_iterator_base< T, preorder_piter<T> >
{
@@ -294,6 +369,9 @@
/// Go to the next point.
void next_();
+ /// Skip current point children. Next call to next() goes to the brother point.
+ void skip_children();
+
protected:
using super_::p_;
using super_::s_;
@@ -328,11 +406,14 @@
{
nodes_.insert(p);
children_(parent_(p)).insert(p);
+ if (is_a_leaf(p))
+ leaves_.insert(p);
}
- else
- if (parent_(p) == p)
+ else if (parent_(p) == p) //it's a root.
{
nodes_.insert(p);
+ if (is_a_leaf(p)) // One pixel image...
+ leaves_.insert(p);
++nroots_;
}
}
@@ -418,6 +499,15 @@
template <typename I, typename S>
inline
+ const p_array<mln_psite(I)>&
+ data<I,S>::leaves() const
+ {
+ mln_precondition(is_valid());
+ return leaves_;
+ }
+
+ template <typename I, typename S>
+ inline
const S&
data<I,S>::domain() const
{
@@ -490,6 +580,7 @@
const mln_psite(T::function)& p)
: root_ (&p)
{
+ mln_assertion(t.is_a_node(p));
this->change_target(t);
}
@@ -522,7 +613,7 @@
else
{
mln_dn_node_piter(T) n(*s_);
- int roots = 0;
+ unsigned roots = 0;
for (n.start(); n.is_valid() && roots < s_->nroots(); n.next())
if (s_->is_root(n))
{
@@ -548,6 +639,15 @@
stack_.push_back(child);
}
+ template <typename T>
+ inline
+ void
+ preorder_piter<T>::skip_children()
+ {
+ while (stack_.size() != 1 && s_->parent(stack_.back()) == p_)
+ stack_.pop_back();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
Index: trunk/milena/sandbox/edwin/tree/routines.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/edwin/tree/accumulator/max.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/edwin/tree/accumulator/arg_max.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/accumulator/arg_max.hh (revision 0)
+++ trunk/milena/sandbox/edwin/tree/accumulator/arg_max.hh (revision 3552)
@@ -0,0 +1,160 @@
+// Copyright (C) 2007, 2008, 2009 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_ACCUMULATOR_ARG_MAX_HH_
+# define MLN_MORPHO_TREE_ACCUMULATOR_ARG_MAX_HH_
+
+/// \file mln/morpho/tree/accumulator/arg_max.hh
+///
+/// Define an accumulator that performs arg max.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/accu/internal/base.hh>
+# include <mln/util/pix.hh>
+
+namespace mln {
+ namespace accumulator {
+
+ template <typename I>
+ class arg_max : public mln::accu::internal::base<const mln_psite(I)&, arg_max<I> >
+ {
+ typedef mln::accu::internal::base<const mln_psite(I)&, arg_max<I> > super_;
+
+ public:
+ typedef typename util::pix<I> argument;
+
+ /// Constructor
+ arg_max(const Image<I>& ima);
+ /// Destructor
+ ~arg_max();
+
+ /// Manipulators.
+ /// \{
+ void init();
+
+ void take(const argument& pix);
+ void take(const arg_max<I>& other);
+
+ void take_as_init(const argument& pix);
+ /// \}
+
+ /// Get the value of the accumulator.
+ const mln_psite(I)& to_result() const;
+
+ /// Check whether the accumulator is able to give a result.
+ bool is_valid() const;
+
+ private:
+ const I& ima_;
+ mln_psite(I)* p_;
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ inline
+ arg_max<I>::arg_max(const Image<I>& ima) :
+ ima_ (exact(ima)),
+ p_ (0)
+ {
+ }
+
+ template <typename I>
+ inline
+ arg_max<I>::~arg_max()
+ {
+ delete p_;
+ }
+
+
+ template <typename I>
+ inline
+ void
+ arg_max<I>::init()
+ {
+ }
+
+ template <typename I>
+ inline
+ void
+ arg_max<I>::take(const argument& pix)
+ {
+ if (!is_valid())
+ {
+ take_as_init(pix);
+ return;
+ }
+
+ if (pix.v() > ima_(*p_))
+ *p_ = pix.p();
+ }
+
+ template <typename I>
+ inline
+ void
+ arg_max<I>::take(const arg_max<I>& other)
+ {
+ mln_invariant(other.is_valid());
+
+ if (other.ima_(*other.p_) > ima_(*p_))
+ *p_ = *other.p_;
+ }
+
+ template <typename I>
+ inline
+ void
+ arg_max<I>::take_as_init(const argument& pix)
+ {
+ p_ = new mln_psite(I)(pix.p());
+ }
+
+ template <typename I>
+ inline
+ const mln_psite(I)&
+ arg_max<I>::to_result() const
+ {
+ mln_invariant(p_ != 0);
+ return *p_;
+ }
+
+ template <typename I>
+ inline
+ bool
+ arg_max<I>::is_valid() const
+ {
+ return p_ != 0;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accumulator
+ } // end of namespace mln
+
+#endif /* ! MLN_MORPHO_TREE_ACCUMULATOR_ARG_MAX_HH_ */
Index: trunk/milena/sandbox/edwin/tree/propagate.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagate.hh (revision 3551)
+++ trunk/milena/sandbox/edwin/tree/propagate.hh (revision 3552)
@@ -46,7 +46,7 @@
propagate_representant(const T& t, Image<A>& a_)
{
A a = exact(a_);
- mln_fwd_piter(T) p(t.domain());
+ mln_up_site_piter(T) p(t);
for_all(p)
if (! t.is_a_node(p))
{
@@ -55,106 +55,6 @@
}
}
-
-
-
-
- /// Dans le cas des images binaires...
- /// Propagate a tagged node's value to its subbranches.
- template <typename T, typename A>
- void
- propagate_to_childhood(const T& t, A& a)
- {
- mln_bkd_piter(T::nodes_t) n(t.nodes());
- for_all(n)
- {
- if (a(t.parent(n)))
- {
- mln_assertion(t.is_a_node(t.parent(n)));
- a(n) = a(t.parent(n));
- }
- }
- }
-
-
- /// Propagate a tagged node's value to its direct children.
- template <typename T, typename A>
- void
- propagate_to_children(const T& t, A& a)
- {
- mln_fwd_piter(T::nodes_t) n(t.nodes());
- for_all(n)
- {
- if (a(t.parent(n)))
- {
- mln_assertion(t.is_a_node(t.parent(n)));
- a(n) = a(t.parent(n));
- }
- }
- }
-
- /// Propagate a tagged node's value to its ancestors.
- template <typename T, typename A>
- void
- propagate_to_ancestors(const T& t, A& a)
- {
- mln_fwd_piter(T::nodes_t) n(t.nodes());
- for_all(n)
- {
- if (a(n))
- {
- mln_assertion(t.is_a_node(t.parent(n)));
- a(t.parent(n)) = a(n);
- }
- }
- }
-
- /// Propagate a tagged node's value to its direct parents.
- template <typename T, typename A>
- void
- propagate_to_parent(const T& t, A& a)
- {
- mln_bkd_piter(T::nodes_t) n(t.nodes());
- for_all(n)
- {
- mln_assertion(t.is_a_node(n));
- if (a(n))
- {
- mln_assertion(t.is_a_node(t.parent(n)));
- a(t.parent(n)) = a(n);
- }
- }
- }
-
- /// Propagate a tagged leaf's value to its ancestors.
- /// In others words, tag the branch which the tagged leaf belongs to.
- /// At the end, the tree should get this property:
- /// for all n
- /// a(n) is true iff there exits an l in tree's leaves such that
- /// n <== l and a(l) is true.
- /// TODO: post-condition which checks this property.
-
-
- template <typename T, typename A>
- void
- propagate_leaf_to_ancestors(const T& t, A& a)
- {
-
- mln_fwd_piter(T::leaves_t) l(t.leaves());
- for_all(l)
- a(t.parent(l)) = 0;
-
-
- mln_fwd_piter(T::nodes_t) n(t.nodes());
- for_all(n)
- {
- mln_assertion(t.is_a_node(t.parent(n)));
- a(t.parent(n)) = a(t.parent(n)) || a(n);
- }
- }
-
-
-
} // end of namespace mln::morpho::tree
} // end of namespace mln::morpho
} // end of namespace mln
Index: trunk/milena/sandbox/edwin/tree/run.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/run.hh (revision 0)
+++ trunk/milena/sandbox/edwin/tree/run.hh (revision 3552)
@@ -0,0 +1,272 @@
+// Copyright (C) 2007, 2008, 2009 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_PROPAGATE_RUN_HH_
+# define MLN_MORPHO_TREE_PROPAGATE_RUN_HH_
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/function.hh>
+
+# include <mln/core/site_set/p_array.hh>
+# include <mln/util/pix.hh>
+
+# include "propagate_node.hh"
+
+namespace mln {
+ namespace morpho {
+ namespace tree {
+
+
+ /**
+ ** Traverse component tree \p tree and provide tree nodes values
+ ** to accumulator \p accu_. (Alias to "map")
+ **
+ ** @param tree Component tree used to perform accumulation.
+ ** @param a_ Attributed image.
+ ** @accu_ Accumulator that will be applied on tree nodes.
+ **
+ ** @return The result of accumulation.
+ */
+ template <typename T, typename A, typename I>
+ mln_result(A)
+ run(const T& tree,
+ const Image<I>& a_,
+ Accumulator<A>& accu_);
+
+ /**
+ ** Apply accumulator \accu on tree nodes. If the resulting node of
+ ** accumulation checks predicate \p pred, the node is inserted
+ ** into resulting array, then ascendant and descendant zero-fill
+ ** propagations are performed from the node. These operations
+ ** are repeated until the node won't check predicate.
+ **
+ ** @param tree Component tree used for propagation.
+ ** @param a Attributed image where values are propagated.
+ ** @param accu_ Accumulator to apply on tree.
+ ** @param pred Predicate that must check the result of
+ ** accumulator to propagate the node.
+ **
+ ** @return Array of propagated nodes.
+ */
+ template <typename T, typename A, typename ACC, typename P2B>
+ p_array< mln_psite(A) >
+ run_while(const T& tree,
+ Image<A>& a,
+ Accumulator<ACC>& accu_,
+ Function_p2b<P2B>& pred);
+
+
+ /**
+ ** Apply accumulator \accu on tree nodes values n times.
+ ** Each time, the result of accumulator is inserted
+ ** into the returned array, then ascendant and descendant zero-fill
+ ** propagations are performed from the node.
+ ** (This function is a shorcut of run_while with a cardinality predicate).
+ **
+ ** @param tree Component tree used for propagation.
+ ** @param a Attributed image where values are propagated.
+ ** @param accu_ Accumulator to apply on tree.
+ ** @param n The repetition number.
+ **
+ ** @return Array of propagated nodes.
+ */
+ template <typename T, typename A, typename ACC>
+ inline
+ p_array< mln_psite(A) >
+ run_ntimes(const T& tree,
+ Image<A>& a,
+ Accumulator<ACC>& acc,
+ unsigned n);
+
+ /**
+ ** Apply accumulator \accu on tree nodes value until the value
+ ** accumulated by \p acc get lesser than the treshold \p n.
+ ** Each time, the result of accumulator is inserted
+ ** into the returned array, then ascendant and descendant zero-fill
+ ** propagations are performed from the node.
+ ** (This function is a shorcut of run_while with a treshold predicate).
+ **
+ ** @param tree Component tree used for propagation.
+ ** @param a Attributed image where values are propagated.
+ ** @param accu_ Accumulator to apply on tree.
+ ** @param n Treshold.
+ **
+ ** @return Array of propagated nodes.
+ */
+ template <typename T, typename A, typename ACC>
+ inline
+ p_array< mln_psite(A) >
+ run_while_treshold(const T& tree,
+ Image<A>& a,
+ Accumulator<ACC>& acc,
+ mln_value(A) n);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ template <typename T, typename A, typename ACC, typename P2B>
+ p_array< mln_psite(A) >
+ run_while(const T& tree,
+ A& a,
+ ACC& accu,
+ P2B& pred)
+ {
+ mln_psite(A) p;
+ p_array< mln_psite(A) > arr_sites;
+ util::array< mln_value(A) > arr_values;
+
+ do {
+ p = morpho::tree::run(tree, a, accu);
+ if (a(p) == 0) //there's no more objects.
+ break;
+ arr_sites.insert(p);
+ arr_values.append(a(p));
+ morpho::tree::propagate_node_to_descendants(p, tree, a, 0);
+ morpho::tree::propagate_node_to_ancestors(p, tree, a, 0);
+ a(p) = 0;
+ } while (pred(accu.to_result()));
+ for (unsigned i = 0; i < arr_sites.nsites(); i++)
+ a(arr_sites[i]) = arr_values[i];
+ return arr_sites;
+ }
+
+ struct ncard : Function_p2b< ncard >
+ {
+ typedef bool result;
+
+ ncard(unsigned n)
+ : n_ (n)
+ {
+ }
+
+ template <typename P>
+ bool operator()(const P& p)
+ {
+ (void)p;
+ return (n_-- > 0);
+ }
+
+ private:
+ unsigned n_;
+ };
+
+ template <typename I>
+ struct treshold : Function_p2b< treshold<I> >
+ {
+ typedef bool result;
+
+ treshold(const Image<I>& ima,
+ const mln_value(I)& treshold)
+ : ima_ (exact(ima)),
+ treshold_ (treshold)
+ {
+ }
+
+ bool operator()(const mln_psite(I)& p) const
+ {
+ return (ima_(p) > treshold_);
+ }
+
+ private:
+ const I& ima_;
+ const mln_value(I) treshold_;
+ };
+
+
+ } // end of namespace mln::morpho::tree::internal
+
+ template <typename T, typename A, typename ACC, typename P2B>
+ inline
+ p_array< mln_psite(A) >
+ run_while(const T& tree,
+ Image<A>& a_,
+ Accumulator<ACC>& acc,
+ Function_p2b<P2B>& pred)
+ {
+ A& a = exact(a_);
+
+ mln_precondition(tree.f().domain() == a.domain());
+ mln_precondition(a.is_valid());
+
+ return internal::run_while(tree, a, exact(acc), exact(pred));
+ }
+
+ template <typename T, typename A, typename ACC>
+ inline
+ p_array< mln_psite(A) >
+ run_ntimes(const T& tree,
+ Image<A>& a,
+ Accumulator<ACC>& acc,
+ unsigned n)
+ {
+ internal::ncard predicate(n - 1);
+ return run_while(tree, a, acc, predicate);
+ }
+
+
+ template <typename T, typename A, typename ACC>
+ inline
+ p_array< mln_psite(A) >
+ run_while_treshold(const T& tree,
+ Image<A>& a,
+ Accumulator<ACC>& acc,
+ mln_value(A) n)
+ {
+ internal::treshold<A> predicate(a, n);
+ return run_while(tree, a, acc, predicate);
+ }
+
+ template <typename T, typename A, typename I>
+ mln_result(A)
+ run(const T& tree,
+ const Image<I>& a_,
+ Accumulator<A>& accu_)
+ {
+ A& accu = exact(accu_);
+ const I& a = exact(a_);
+
+ mln_precondition(tree.f().domain() == a.domain());
+ mln_precondition(a.is_valid());
+
+ mln_up_node_piter(T) n(tree);
+ for_all(n)
+ accu.take(make::pix(a, n));
+ return (accu.to_result());
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::morpho::tree
+ } // end of namespace mln::morpho
+} // end of namespace mln
+
+#endif /* !MLN_MORPHO_TREE_PROPAGATE_RUN_HH_ */
Index: trunk/milena/sandbox/edwin/tree/test.cc
===================================================================
--- trunk/milena/sandbox/edwin/tree/test.cc (revision 0)
+++ trunk/milena/sandbox/edwin/tree/test.cc (revision 3552)
@@ -0,0 +1,98 @@
+/* mln core */
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/var.hh>
+
+/* Site set */
+#include <mln/core/site_set/p_array.hh>
+#include <mln/level/sort_psites.hh>
+
+/* Component trees */
+#include <mln/morpho/tree/data.hh>
+#include <mln/morpho/tree/compute_attribute_image.hh>
+#include "propagate.hh"
+#include "run.hh"
+#include "accumulator/arg_max.hh"
+
+/* Attributes */
+#include <mln/morpho/attribute/sharpness.hh>
+
+/* io */
+#include <mln/io/pgm/load.hh>
+#include <../../theo/color/change_attributes.hh>
+#include <iostream>
+
+/* std */
+#include <string>
+
+bool mydebug = false;
+
+
+void usage(char** argv)
+{
+ std::cerr << "usage: " << argv[0] << " input [--debug]" << std::endl;
+ abort();
+}
+
+void dsp(const char* str)
+{
+ std::cout << std::endl
+ << "*********************" << std::endl
+ << "** " << str << std::endl
+ << "*********************" << std::endl;
+}
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc < 2)
+ usage(argv);
+
+ mydebug = (argc >= 3 && std::string(argv[2]) == "--debug");
+
+
+ /* Image loadin' */
+ typedef image2d<int_u8> I;
+
+ I input;
+ io::pgm::load(input, argv[1]);
+
+ /* Component tree creation */
+ typedef p_array< mln_site_(I) > S;
+ typedef morpho::tree::data<I,S> tree_t;
+
+ S sorted_sites = level::sort_psites_decreasing(input);
+ tree_t tree(input, sorted_sites, c4());
+
+ /* Compute Attribute On Image */
+ typedef morpho::attribute::sharpness<I> accu_t;
+ typedef mln_ch_value_(tree_t::function, mln_result_(accu_t)) A;
+
+ A a = morpho::tree::compute_attribute_image(accu_t (), tree);
+ morpho::tree::propagate_representant(tree, a);
+
+ if (mydebug) {
+ dsp("Image attribute"); display_tree_attributes(tree, a);
+ }
+
+ /* Run max accumulator, looking for 5 objects */
+ accumulator::arg_max<A> argmax(a);
+ p_array< mln_psite_(A) > obj_array; // Array of object components.
+ obj_array = morpho::tree::run_ntimes(tree, a, argmax, 5);
+
+ if (mydebug) {
+ dsp("Run max accumulator, lk 4 5 objs"); display_tree_attributes(tree, a);
+ }
+
+ /* Print them */
+ if (mydebug) {
+ dsp("Image Filtered Components");
+ mln_fwd_piter_(p_array< mln_psite_(I) >) c(obj_array);
+ for_all(c)
+ std::cout << c;
+ }
+
+
+}
Index: trunk/milena/sandbox/edwin/tree/propagate_node.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagate_node.hh (revision 3551)
+++ trunk/milena/sandbox/edwin/tree/propagate_node.hh (revision 3552)
@@ -41,41 +41,42 @@
namespace morpho {
namespace tree {
-
/**
- ** Propagate a value to a node and its descendants.
+ ** Propagate a value \v from a node \n to its descendants.
**
- ** @param n The root of subtree which value propagates in.
- ** @param t The reference to components tree.
- ** @param a_ The reference to image.
- ** @param v The value to propagate. Default is a_(n).
+ ** @param n Node to propagate.
+ ** @param t Component tree used for propagation.
+ ** @param a_ Attributed image where values are propagated.
+ ** @param v Value to propagate.
*/
template <typename T, typename A>
void
propagate_node_to_descendants(mln_psite(A) n,
const T& t,
Image<A>& a_,
- mln_value(A) v);
+ const mln_value(A)& v);
/**
** Propagate the node's value to its descendants.
**
- ** @param n The root of subtree which value propagates in.
- ** @param t The reference to components tree.
- ** @param a_ The reference to image.
+ ** @param n Node to propagate.
+ ** @param t Component tree used for propagation.
+ ** @param a_ Attributed image where values are propagated.
*/
template <typename T, typename A>
+ inline
void
propagate_node_to_descendants(mln_psite(A)& n,
const T& t,
Image<A>& a_);
+
/**
- ** Propagate a value from a node to its ancestors.
+ ** Propagate a value \v from a node \n to its ancestors.
**
- ** @param n Forward iterator related to the node.
- ** @param t Reference to components tree.
- ** @param a_ Reference to image.
+ ** @param n Node to propagate.
+ ** @param t Component tree used for propagation.
+ ** @param a_ Attributed image where values are propagated.
** @param v Value to propagate.
*/
template <typename T, typename A>
@@ -83,23 +84,24 @@
propagate_node_to_ancestors(mln_psite(A) n,
const T& t,
Image<A>& a_,
- mln_value(A) v);
+ const mln_value(A)& v);
/**
** Propagate the node's value to its ancestors.
**
- ** @param n Forward iterator related to the node.
- ** @param t Reference to components tree.
- ** @param a_ Reference to image.
+ ** @param n Node to propagate.
+ ** @param t Component tree used for propagation.
+ ** @param a_ Attributed image where values are propagated.
*/
template <typename T, typename A>
+ inline
void
propagate_node_to_ancestors(mln_psite(A) n,
const T& t,
Image<A>& a_);
-# ifndef MLN_INCLUDE_ONLY
+ //# ifndef MLN_INCLUDE_ONLY
/* Descendants propagation */
@@ -109,7 +111,7 @@
propagate_node_to_descendants(mln_psite(A) n,
const T& t,
Image<A>& a_,
- mln_value(A) v)
+ const mln_value(A)& v)
{
A& a = exact(a_);
mln_precondition(a.is_valid());
@@ -148,7 +150,7 @@
propagate_node_to_ancestors(mln_psite(A) n,
const T& t,
Image<A>& a_,
- mln_value(A) v)
+ const mln_value(A)& v)
{
A& a = exact(a_);
mln_precondition(a.is_valid());
@@ -180,7 +182,7 @@
propagate_node_to_ancestors(n, t, a, a(n));
}
-# endif // ! MLN_INCLUDE_ONLY
+ //# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho::tree
} // end of namespace mln::morpho
Index: trunk/milena/sandbox/edwin/tree/propagation.cc
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagation.cc (revision 3551)
+++ trunk/milena/sandbox/edwin/tree/propagation.cc (revision 3552)
@@ -1,9 +1,15 @@
#include <iostream>
+
+#include <mln/accu/max.hh>
+#include <mln/util/pix.hh>
+
#include <mln/core/image/image2d.hh>
#include <mln/core/alias/neighb2d.hh>
#include <mln/core/alias/point2d.hh>
#include <mln/core/routine/duplicate.hh>
+#include <mln/core/concept/function.hh>
+
#include <mln/value/int_u8.hh>
#include <mln/io/pgm/load.hh>
@@ -12,12 +18,14 @@
#include <mln/level/sort_psites.hh>
#include <mln/morpho/tree/data.hh>
-
#include <../../theo/color/change_attributes.hh>
+
+
+
#include "propagate_node.hh"
-#include "propagate_value.hh"
+#include "propagate_if.hh"
+#include "accumulator/arg_max.hh"
#include "run.hh"
-#include "accumulator/max.hh"
void usage(char** argv)
{
@@ -46,6 +54,9 @@
print(img, it);
}
+using namespace mln;
+
+
int main(int argc, char* argv[])
{
using namespace mln;
@@ -90,53 +101,46 @@
dsp("Propagate node to descendants : (point2d(0, 2), tree, dup)");
display_tree_attributes(tree, dup);
- // dup = duplicate(input);
-// morpho::tree::propagate_value_to_ancestors(117, tree, dup, 0);
-// dsp("Propagate value to ancestors : (117, tree, dup, 0)");
-// display_tree_attributes(tree, dup);
-// dup = duplicate(input);
-// morpho::tree::propagate_value_to_ancestors(117, tree, dup);
-// dsp("Propagate value to ancestors : (117, tree, dup)");
-// display_tree_attributes(tree, dup);
-
-// dup = duplicate(input);
-// morpho::tree::propagate_value_to_descendants(117, tree, dup, 0);
-// dsp("Propagate value to descendants : (117, tree, dup, 0)");
-// display_tree_attributes(tree, dup);
-
-// dup = duplicate(input);
-// morpho::tree::propagate_value_to_descendants(117, tree, dup);
-// dsp("Propagate value to descendants : (117, tree, dup)");
-// display_tree_attributes(tree, dup);
+ dup = duplicate(input);
+ morpho::tree::propagate_if_value(tree, dup, morpho::tree::asc_propagation (), 117, 0);
+ dsp("Propagate value to ancestors : (117, tree, dup, 0)");
+ display_tree_attributes(tree, dup);
+ dup = duplicate(input);
+ morpho::tree::propagate_if_value(tree, dup, morpho::tree::asc_propagation (), 117);
+ dsp("Propagate value to ancestors : (117, tree, dup)");
+ display_tree_attributes(tree, dup);
+ dup = duplicate(input);
+ morpho::tree::propagate_if_value(tree, dup, morpho::tree::desc_propagation (), 117, 0);
+ dsp("Propagate value to descendants : (117, tree, dup, 0)");
+ display_tree_attributes(tree, dup);
dup = duplicate(input);
+ morpho::tree::propagate_if_value(tree, dup, morpho::tree::desc_propagation (), 117);
+ dsp("Propagate value to descendants : (117, tree, dup)");
+ display_tree_attributes(tree, dup);
+
- typedef morpho::tree::accumulator::max<tree_t, I> A;
- A accu(dup);
- morpho::tree::run_bkd(tree, accu);
+ accumulator::arg_max<I> mmax;
+ p_array< mln_psite_(I) > tabmax;
+ mln_fwd_piter_(p_array< mln_psite_(I) >) pit(tabmax);
- mln_bkd_piter_(tree_t::nodes_t) it_max = accu.to_result();
- morpho::tree::propagate_node_to_descendants(it_max, tree, dup, 69);
- dsp("Propagate value to descendants : (it_max, tree, dup, 69)");
+ dup = duplicate(input);
+ tabmax = morpho::tree::run_ntimes(tree, dup, mmax, 5);
+ for_all(pit)
+ std::cout << pit << std::endl;
+ dsp("Run ntimes : (tree, dup, max, 5)");
display_tree_attributes(tree, dup);
-// mln_dn_node_piter_(tree_t) n(tree);
-// n.start();
-// print(tree.children_image(), n);
- std::cout << "\n";
- mln_preorder_piter_(tree_t) pit(tree);
- mln_psite_(I) parent;
+ dup = duplicate(input);
+ tabmax = morpho::tree::run_while_treshold(tree, dup, mmax, 20);
for_all(pit)
- {
- if (parent != tree.parent(pit))
- std::cout << std::endl;
- std::cout << pit << " -> ";
- parent = pit;
- }
+ std::cout << pit << std::endl;
+ dsp("Run with treshold : (tree, dup, max, 20)");
+ display_tree_attributes(tree, dup);
}
Index: trunk/milena/sandbox/edwin/tree/Makefile
===================================================================
--- trunk/milena/sandbox/edwin/tree/Makefile (revision 3551)
+++ trunk/milena/sandbox/edwin/tree/Makefile (revision 3552)
@@ -1,11 +1,11 @@
-TARGET=propagation
-SRC=propagation.cc
+TARGET=test
+SRC=test.cc
OBJS=${SRC:.cc=.o}
OLENADIR=$(MLN_DIR)/..
MILENADIR=$(OLENADIR)/milena
-CXXFLAGS=-I$(MILENADIR) -I./
+CXXFLAGS=-I$(MILENADIR) -I./ -W -Wall
CXXFLAGS += -g -ggdb
#CXXFLAGS += -DNDEBUG -O1
Index: trunk/milena/sandbox/edwin/tree/propagate_if.hh
===================================================================
--- trunk/milena/sandbox/edwin/tree/propagate_if.hh (revision 0)
+++ trunk/milena/sandbox/edwin/tree/propagate_if.hh (revision 3552)
@@ -0,0 +1,320 @@
+// Copyright (C) 2007, 2008, 2009 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_PROPAGATE_IF_HH_
+# define MLN_MORPHO_TREE_PROPAGATE_IF_HH_
+
+/**
+** @file mln/morpho/tree/propagate_if.hh
+**
+** @brief Methods to handle propagation startegies
+** in component trees.
+**
+*/
+
+# include <mln/morpho/tree/data.hh>
+# include "propagate_node.hh"
+
+namespace mln {
+ namespace morpho {
+ namespace tree {
+
+ template <typename WP>
+ struct way_of_propagation : Object< WP > { protected: way_of_propagation() {}; };
+ struct desc_propagation : way_of_propagation <desc_propagation> {};
+ struct asc_propagation : way_of_propagation <asc_propagation> {};
+
+ /**
+ ** Propagate nodes checking the predicate \p pred in the way
+ ** defined by \p way_of_propagation.
+ **
+ ** @param tree Component tree used for propagation.
+ ** @param a_ Attributed image where values are propagated.
+ ** @param way_of_propagation Propagate node in acsendant or
+ ** descendant way.
+ ** @param pred Predicate that node must check to be propagated.
+ ** @param v Value to be propagated. (By default \v is the value
+ ** at the node being propagated).
+ */
+ template <typename T, typename A, class P, typename WP>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const way_of_propagation<WP>&,
+ const P& pred,
+ const mln_value(A)& v);
+
+ template <typename T, typename A, class P, typename WP>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const way_of_propagation<WP>&,
+ const P& pred);
+
+ /**
+ ** Propagate nodes having the value v in the way
+ ** defined by \p way_of_propagation.
+ **
+ ** @param tree Component tree used for propagation.
+ ** @param a_ Attributed image where values are propagated.
+ ** @param way_of_propagation Propagate node in acsendant or
+ ** descendant way.
+ ** @param v Value that node must have to be propagated.
+ ** @param v_prop Value to propagate (By default it is the value
+ ** at the node being propagated).
+ */
+ template <typename T, typename A, class P, typename WP>
+ inline
+ void
+ propagate_if_value(const T& tree,
+ Image<A>& a_,
+ const way_of_propagation<WP>&,
+ const mln_value(A)& v,
+ const mln_value(A)& v_prop);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ template <typename I>
+ struct pred_value_eq : public mln::Function_p2b< pred_value_eq<I> >
+ {
+ typedef bool result;
+
+ pred_value_eq(const I& a, const mln_value(I)& v)
+ : a_ (a),
+ v_ (v)
+ {
+ mln_invariant(a_.is_valid());
+ }
+
+ bool operator() (const mln_psite(I)& p) const
+ {
+ mln_invariant(a_.domain().has(p));
+ return (v_ == a_(p));
+ }
+
+ private:
+ const I& a_;
+ const mln_value(I) v_;
+ };
+
+
+ template <typename T, typename A>
+ bool check_propagate_value(const T& t,
+ const A& a,
+ const asc_propagation& prop,
+ const mln_value(A)& v)
+ {
+ (void) prop;
+ mln_up_node_piter(T) n(t);
+ for_all(n)
+ if (a(n) == v && a(t.parent(n)) != v)
+ return false;
+ return true;
+ }
+
+ template <typename T, typename A>
+ bool check_propagate_value(const T& t,
+ const A& a,
+ const desc_propagation& prop,
+ const mln_value(A)& v)
+ {
+ (void) prop;
+ mln_up_node_piter(T) n(t);
+ for_all(n)
+ if (a(n) != v && a(t.parent(n)) == v)
+ return false;
+ return true;
+ }
+
+
+ template <typename T, typename A, class P>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const desc_propagation& prop,
+ const P& pred,
+ const mln_value(A)& v)
+ {
+ const A& a = exact(a_);
+ (void) prop;
+
+ mln_precondition(a.is_valid());
+ mln_precondition(tree.f().domain() == a.domain());
+
+ mln_preorder_piter(T) n(tree);
+ for_all(n)
+ if (pred(n))
+ {
+ propagate_node_to_descendants(n, tree, a_, v);
+ n.skip_children();
+ }
+ }
+
+ template <typename T, typename A, class P>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const desc_propagation& prop,
+ const P& pred)
+ {
+ const A& a = exact(a_);
+ (void) prop;
+
+ mln_precondition(a.is_valid());
+ mln_precondition(tree.f().domain() == a.domain());
+
+ mln_preorder_piter(T) n(tree);
+ for_all(n)
+ if (pred(n))
+ {
+ propagate_node_to_descendants(n, tree, a_);
+ n.skip_children();
+ }
+ }
+
+ template <typename T, typename A, class P>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const asc_propagation& prop,
+ const P& pred,
+ const mln_value(A)& v)
+ {
+ const A& a = exact(a_);
+ (void) prop;
+
+ mln_precondition(a.is_valid());
+ mln_precondition(tree.f().domain() == a.domain());
+
+ mln_up_node_piter(T) n(tree);
+ for_all(n)
+ if (pred(n))
+ propagate_node_to_ancestors(n, tree, a_, v);
+ }
+
+ template <typename T, typename A, class P>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const asc_propagation& prop,
+ const P& pred)
+ {
+ const A& a = exact(a_);
+ (void) prop;
+
+ mln_precondition(a.is_valid());
+ mln_precondition(tree.f().domain() == a.domain());
+
+ mln_up_node_piter(T) n(tree);
+ for_all(n)
+ if (pred(n))
+ propagate_node_to_ancestors(n, tree, a_, a(n));
+ }
+
+ } // end of namespace mln::morpho::tree::internal
+
+
+ /* Facades */
+
+ template <typename T, typename A, typename WP>
+ inline
+ void
+ propagate_if_value(const T& tree,
+ Image<A>& a_,
+ const way_of_propagation<WP>& prop_,
+ const mln_value(A)& v,
+ const mln_value(A)& v_prop)
+ {
+ A& a = exact(a_);
+ const WP& prop = exact(prop_);
+ internal::pred_value_eq<A> pred(a, v);
+
+ internal::propagate_if(tree, a_, prop, pred, v_prop);
+ }
+
+
+ template <typename T, typename A, typename WP>
+ inline
+ void
+ propagate_if_value(const T& tree,
+ Image<A>& a_,
+ const way_of_propagation<WP>& prop_,
+ const mln_value(A)& v)
+ {
+ const A& a = exact(a_);
+ const WP& prop = exact(prop_);
+ internal::pred_value_eq<A> pred(a, v);
+
+ internal::propagate_if(tree, a_, prop, pred);
+ mln_postcondition(internal::check_propagate_value(tree, a, prop, v));
+ }
+
+ template <typename T, typename A, class P, typename WP>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const way_of_propagation<WP>& prop_,
+ const P& pred,
+ const mln_value(A)& v)
+ {
+ const WP& prop = exact(prop_);
+ internal::propagate_if(tree, a_, prop, pred, v);
+ }
+
+ template <typename T, typename A, class P, typename WP>
+ inline
+ void
+ propagate_if(const T& tree,
+ Image<A>& a_,
+ const way_of_propagation<WP>& prop_,
+ const P& pred)
+ {
+ const WP& prop = exact(prop_);
+ internal::propagate_if(tree, a_, prop, pred);
+ }
+
+#endif /* !MLN_INCLUDE_ONLY */
+
+
+ } // end of namespace mln::morpho::tree
+ } // end of namespace mln::morpho
+} // end of namespace mln
+
+#endif /* !MLN_MORPHO_TREE_PROPAGATE_IF_HH_ */
1
0
* scribo/Makefile: add new targets.
* scribo/core/central_sites.hh,
* scribo/core/component_bboxes.hh: add more assertions.
* scribo/text/recognition.hh,
* scribo/text/grouping/internal/find_root.hh,
* scribo/text/grouping/internal/init_link_array.hh,
* scribo/text/grouping/group_from_double_link.hh,
* scribo/text/grouping/group_from_multiple_links.hh,
* scribo/text/grouping/group_from_single_link.hh,
* scribo/text/grouping/group_with_multiple_links.hh,
* scribo/text/grouping/group_with_single_left_link.hh,
* scribo/text/grouping/group_with_single_right_link.hh,
* scribo/text/extract_bboxes.hh,
* scribo/src/extract_text_double_link.cc,
* scribo/src/extract_text_multiple_links.cc,
* scribo/src/extract_text_single_link.cc,
* scribo/debug/save_linked_textbboxes_image.hh,
* scribo/debug/save_table_image.hh,
* scribo/debug/save_textbboxes_image.hh,
* scribo/draw/bounding_box_links.hh,
* scribo/draw/bounding_boxes.hh: make use of util::text.
* scribo/filter/large_components.hh,
* scribo/filter/small_components.hh,
* scribo/filter/thin_bboxes.hh: new filters.
* scribo/make/debug_filename.hh: improve.
* scribo/make/text.hh: Construct a text class.
* scribo/src/dmap.cc,
* scribo/src/morpho.cc,
* scribo/src/table_extract.cc,
* scribo/src/table_rebuild.cc,
* scribo/src/thin_bboxes.cc: new sample code.
* scribo/src/table.cc: fix include.
* scribo/table/internal/align_lines.hh,
* scribo/table/align_lines_horizontaly.hh,
* scribo/table/align_lines_verticaly.hh,
* scribo/table/connect_horizontal_lines.hh,
* scribo/table/connect_vertical_lines.hh: add more parameters.
* scribo/table/extract.hh: new routine to extract document tables.
* scribo/table/extract_lines_with_opening.hh: new routine to extract
document tables.
* scribo/table/extract_lines_with_rank.hh: fix missing bbox.enlarge.
* scribo/table/internal/connect_lines.hh: make it compile.
* scribo/table/internal/repair_lines.hh: make it work.
* scribo/table/rebuild.hh: new routine to rebuild document tables.
* scribo/core/erase_bboxes.hh,
* scribo/table/repair_horizontal_lines.hh: revamp.
* scribo/tests/filter/small_and_large_bboxes.cc,
* scribo/tests/table/extract_lines_with_rank.cc,
* scribo/tests/table/repair_lines.cc: new tests.
* scribo/text/extract_lines.hh: new routine to extract text
automatically.
* scribo/text/grouping/internal/update_link_array.hh,
* scribo/text/grouping/internal/update_link_graph.hh: fix conditions.
* scribo/util/text.hh: new object to represent text components.
---
milena/sandbox/ChangeLog | 80 ++++++++-
milena/sandbox/scribo/Makefile | 27 ++-
milena/sandbox/scribo/core/central_sites.hh | 2 +-
milena/sandbox/scribo/core/component_bboxes.hh | 19 ++-
milena/sandbox/scribo/core/erase_bboxes.hh | 4 +-
.../scribo/debug/save_linked_textbboxes_image.hh | 49 +++---
milena/sandbox/scribo/debug/save_table_image.hh | 65 +++++--
.../sandbox/scribo/debug/save_textbboxes_image.hh | 7 +-
milena/sandbox/scribo/draw/bounding_box_links.hh | 26 ++--
milena/sandbox/scribo/draw/bounding_boxes.hh | 4 +-
milena/sandbox/scribo/filter/large_components.hh | 196 ++++++++++++++++++
milena/sandbox/scribo/filter/small_components.hh | 207 ++++++++++++++++++++
milena/sandbox/scribo/filter/thin_bboxes.hh | 165 ++++++++++++++++
milena/sandbox/scribo/make/debug_filename.hh | 33 +++-
.../{text/extract_bboxes.hh => make/text.hh} | 81 +++++---
milena/sandbox/scribo/src/dmap.cc | 26 +++
.../sandbox/scribo/src/extract_text_double_link.cc | 69 ++++----
.../scribo/src/extract_text_multiple_links.cc | 34 ++--
.../sandbox/scribo/src/extract_text_single_link.cc | 72 ++++---
milena/sandbox/scribo/src/morpho.cc | 64 ++++++
milena/sandbox/scribo/src/table.cc | 2 +-
...act_text_multiple_links.cc => table_extract.cc} | 37 ++---
...act_text_multiple_links.cc => table_rebuild.cc} | 45 +++--
milena/sandbox/scribo/src/thin_bboxes.cc | 32 +++
.../scribo/table/align_lines_horizontaly.hh | 18 ++-
.../sandbox/scribo/table/align_lines_verticaly.hh | 15 +-
.../scribo/table/connect_horizontal_lines.hh | 14 +-
.../sandbox/scribo/table/connect_vertical_lines.hh | 14 +-
.../{text/extract_bboxes.hh => table/extract.hh} | 73 ++++----
..._with_rank.hh => extract_lines_with_opening.hh} | 67 ++++---
.../scribo/table/extract_lines_with_rank.hh | 27 ++-
.../sandbox/scribo/table/internal/align_lines.hh | 9 +-
.../sandbox/scribo/table/internal/connect_lines.hh | 17 ++-
.../sandbox/scribo/table/internal/repair_lines.hh | 67 +++++--
milena/sandbox/scribo/table/rebuild.hh | 147 ++++++++++++++
.../scribo/table/repair_horizontal_lines.hh | 6 +-
.../filter/small_and_large_bboxes.cc} | 13 ++-
.../scribo/tests/table/extract_lines_with_rank.cc | 36 ++++
milena/sandbox/scribo/tests/table/repair_lines.cc | 45 +++++
milena/sandbox/scribo/text/extract_bboxes.hh | 15 +-
milena/sandbox/scribo/text/extract_lines.hh | 133 +++++++++++++
.../scribo/text/grouping/group_from_double_link.hh | 65 +++++--
.../text/grouping/group_from_multiple_links.hh | 63 ++++---
.../scribo/text/grouping/group_from_single_link.hh | 43 +++--
.../text/grouping/group_with_multiple_links.hh | 37 ++---
.../text/grouping/group_with_single_left_link.hh | 47 ++---
.../text/grouping/group_with_single_right_link.hh | 49 ++---
.../scribo/text/grouping/internal/find_root.hh | 4 +-
.../text/grouping/internal/init_link_array.hh | 7 +-
.../text/grouping/internal/update_link_array.hh | 7 +-
.../text/grouping/internal/update_link_graph.hh | 6 +-
milena/sandbox/scribo/text/recognition.hh | 19 +-
milena/sandbox/scribo/util/text.hh | 189 ++++++++++++++++++
53 files changed, 2087 insertions(+), 511 deletions(-)
create mode 100644 milena/sandbox/scribo/filter/large_components.hh
create mode 100644 milena/sandbox/scribo/filter/small_components.hh
create mode 100644 milena/sandbox/scribo/filter/thin_bboxes.hh
copy milena/sandbox/scribo/{text/extract_bboxes.hh => make/text.hh} (56%)
create mode 100644 milena/sandbox/scribo/src/dmap.cc
create mode 100644 milena/sandbox/scribo/src/morpho.cc
copy milena/sandbox/scribo/src/{extract_text_multiple_links.cc => table_extract.cc} (61%)
copy milena/sandbox/scribo/src/{extract_text_multiple_links.cc => table_rebuild.cc} (61%)
create mode 100644 milena/sandbox/scribo/src/thin_bboxes.cc
copy milena/sandbox/scribo/{text/extract_bboxes.hh => table/extract.hh} (55%)
copy milena/sandbox/scribo/table/{extract_lines_with_rank.hh => extract_lines_with_opening.hh} (67%)
create mode 100644 milena/sandbox/scribo/table/rebuild.hh
copy milena/sandbox/scribo/{src/extract_text_multiple_links.cc => tests/filter/small_and_large_bboxes.cc} (87%)
create mode 100644 milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc
create mode 100644 milena/sandbox/scribo/tests/table/repair_lines.cc
create mode 100644 milena/sandbox/scribo/text/extract_lines.hh
create mode 100644 milena/sandbox/scribo/util/text.hh
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 8c7681f..7137a4d 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,4 +1,82 @@
-2009-03-16 Guillaume Lazzara <z(a)lrde.epita.fr>
+2009-03-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Update Scribo's code.
+
+ * scribo/Makefile: add new targets.
+
+ * scribo/core/central_sites.hh,
+ * scribo/core/component_bboxes.hh: add more assertions.
+
+ * scribo/text/recognition.hh,
+ * scribo/text/grouping/internal/find_root.hh,
+ * scribo/text/grouping/internal/init_link_array.hh,
+ * scribo/text/grouping/group_from_double_link.hh,
+ * scribo/text/grouping/group_from_multiple_links.hh,
+ * scribo/text/grouping/group_from_single_link.hh,
+ * scribo/text/grouping/group_with_multiple_links.hh,
+ * scribo/text/grouping/group_with_single_left_link.hh,
+ * scribo/text/grouping/group_with_single_right_link.hh,
+ * scribo/text/extract_bboxes.hh,
+ * scribo/src/extract_text_double_link.cc,
+ * scribo/src/extract_text_multiple_links.cc,
+ * scribo/src/extract_text_single_link.cc,
+ * scribo/debug/save_linked_textbboxes_image.hh,
+ * scribo/debug/save_table_image.hh,
+ * scribo/debug/save_textbboxes_image.hh,
+ * scribo/draw/bounding_box_links.hh,
+ * scribo/draw/bounding_boxes.hh: make use of util::text.
+
+ * scribo/filter/large_components.hh,
+ * scribo/filter/small_components.hh,
+ * scribo/filter/thin_bboxes.hh: new filters.
+
+ * scribo/make/debug_filename.hh: improve.
+
+ * scribo/make/text.hh: Construct a text class.
+
+ * scribo/src/dmap.cc,
+ * scribo/src/morpho.cc,
+ * scribo/src/table_extract.cc,
+ * scribo/src/table_rebuild.cc,
+ * scribo/src/thin_bboxes.cc: new sample code.
+
+ * scribo/src/table.cc: fix include.
+
+ * scribo/table/internal/align_lines.hh,
+ * scribo/table/align_lines_horizontaly.hh,
+ * scribo/table/align_lines_verticaly.hh,
+ * scribo/table/connect_horizontal_lines.hh,
+ * scribo/table/connect_vertical_lines.hh: add more parameters.
+
+ * scribo/table/extract.hh: new routine to extract document tables.
+
+ * scribo/table/extract_lines_with_opening.hh: new routine to extract
+ document tables.
+
+ * scribo/table/extract_lines_with_rank.hh: fix missing bbox.enlarge.
+
+ * scribo/table/internal/connect_lines.hh: make it compile.
+
+ * scribo/table/internal/repair_lines.hh: make it work.
+
+ * scribo/table/rebuild.hh: new routine to rebuild document tables.
+
+ * scribo/core/erase_bboxes.hh,
+ * scribo/table/repair_horizontal_lines.hh: revamp.
+
+ * scribo/tests/filter/small_and_large_bboxes.cc,
+ * scribo/tests/table/extract_lines_with_rank.cc,
+ * scribo/tests/table/repair_lines.cc: new tests.
+
+ * scribo/text/extract_lines.hh: new routine to extract text
+ automatically.
+
+ * scribo/text/grouping/internal/update_link_array.hh,
+ * scribo/text/grouping/internal/update_link_graph.hh: fix conditions.
+
+ * scribo/util/text.hh: new object to represent text components.
+
+2009-03-19 Guillaume Lazzara <z(a)lrde.epita.fr>
Add a buggy sample case.
diff --git a/milena/sandbox/scribo/Makefile b/milena/sandbox/scribo/Makefile
index cbb462b..09a3a2d 100644
--- a/milena/sandbox/scribo/Makefile
+++ b/milena/sandbox/scribo/Makefile
@@ -1,28 +1,41 @@
+CXX_FLAGS = -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG # -ggdb #-O1 -DNDEBUG
+
all: table photo
tabledbg: demat.hh
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -g src/table.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table.out
+ g++ -Wextra -Wall -I../.. -I../ -I. -I$(HOME)/local/include -O1 -g src/table.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table.out
table: demat.hh
- g++ -Wextra -Wall -I../.. -I. -I.. -I$(HOME)/local/include -O1 -DNDEBUG src/table.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table.out
+ g++ $(CXX_FLAGS) src/table.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table.out
oldtable: demat.old.hh
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG src/table_old.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table_old.out
+ g++ $(CXX_FLAGS) src/table_old.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table_old.out
photo: demat.hh
- g++ -Wextra -Wall -I../.. -I. -I.. -I$(HOME)/local/include -O1 -DNDEBUG src/photo.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/photo.out
+ g++ $(CXX_FLAGS) src/photo.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/photo.out
+
+dmap:
+ g++ $(CXX_FLAGS) src/dmap.cc -o bin/dmap.out
extract_text_single_link:
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG src/extract_text_single_link.cc -o bin/extract_text_single_link.out
+ g++ $(CXX_FLAGS) src/extract_text_single_link.cc -o bin/extract_text_single_link.out
extract_text_double_link:
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG src/extract_text_double_link.cc -o bin/extract_text_double_link.out
+ g++ $(CXX_FLAGS) src/extract_text_double_link.cc -o bin/extract_text_double_link.out
extract_text_multiple_links:
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG src/extract_text_multiple_links.cc -o bin/extract_text_multiple_links.out
+ g++ $(CXX_FLAGS) src/extract_text_multiple_links.cc -o bin/extract_text_multiple_links.out
+
+table_rebuild:
+ g++ $(CXX_FLAGS) src/table_rebuild.cc -o bin/table_rebuild.out
+
+table_extract:
+ g++ $(CXX_FLAGS) src/table_extract.cc -o bin/table_extract.out
+thin_bboxes:
+ g++ $(CXX_FLAGS) src/thin_bboxes.cc -o bin/thin_bboxes.out
clean:
rm *.ppm *.pgm *.pbm
diff --git a/milena/sandbox/scribo/core/central_sites.hh b/milena/sandbox/scribo/core/central_sites.hh
index fe47625..80686f8 100644
--- a/milena/sandbox/scribo/core/central_sites.hh
+++ b/milena/sandbox/scribo/core/central_sites.hh
@@ -86,7 +86,7 @@ namespace scribo
p2[dim] += n / 2;
trace::exiting("scribo::central_sites");
- return make::couple(p1, p2);
+ return mln::make::couple(p1, p2);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/core/component_bboxes.hh b/milena/sandbox/scribo/core/component_bboxes.hh
index 5af99fc..16b6fa0 100644
--- a/milena/sandbox/scribo/core/component_bboxes.hh
+++ b/milena/sandbox/scribo/core/component_bboxes.hh
@@ -43,23 +43,28 @@
# include <mln/util/array.hh>
+# include <mln/debug/println.hh>
namespace scribo
{
+ using namespace mln;
+
/// Extract the components bboxes.
template <typename I, typename N, typename V>
- util::array< box<mln_site(I)> >
+ util::couple<util::array< box<mln_site(I)> >, mln_ch_value(I,V)>
component_bboxes(const Image<I>& input,
- const Neighborhood<N>& nbh, const V& label_type);
+ const Neighborhood<N>& nbh,
+ V& nbboxes);
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename N, typename V>
inline
- util::array< box<mln_site(I)> >
+ util::couple<util::array< box<mln_site(I)> >, mln_ch_value(I,V)>
component_bboxes(const Image<I>& input,
- const Neighborhood<N>& nbh, const V&)
+ const Neighborhood<N>& nbh,
+ V& nbboxes)
{
trace::entering("scribo::component_bboxes");
@@ -68,13 +73,15 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
- V nbboxes;
mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nbboxes);
+ mln_assertion(exact(lbl).is_valid());
+
typedef util::array< box<mln_site(I)> > bboxes_t;
bboxes_t bboxes = labeling::compute(accu::meta::bbox(), lbl, nbboxes);
+ mln_postcondition(bboxes.nelements() == nbboxes.next());
trace::exiting("scribo::component_bboxes");
- return bboxes;
+ return mln::make::couple(bboxes, lbl);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/core/erase_bboxes.hh b/milena/sandbox/scribo/core/erase_bboxes.hh
index cea998b..f4b2392 100644
--- a/milena/sandbox/scribo/core/erase_bboxes.hh
+++ b/milena/sandbox/scribo/core/erase_bboxes.hh
@@ -44,6 +44,8 @@
namespace scribo
{
+ using namespace mln;
+
/// Remove the content of bounding boxes from an image.
template <typename I>
void
@@ -68,7 +70,7 @@ namespace scribo
for_all_components(i, bboxes)
data::paste((pw::cst(false) | bboxes[i] |
- (pw::value(input) == true)), input);
+ (pw::value(input) == true)), input);
trace::exiting("scribo::erase_bboxes");
}
diff --git a/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh b/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh
index a7f8927..4012c05 100644
--- a/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh
+++ b/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh
@@ -42,6 +42,7 @@
# include <scribo/draw/bounding_boxes.hh>
# include <scribo/draw/bounding_box_links.hh>
+# include <scribo/util/text.hh>
namespace scribo
@@ -54,32 +55,32 @@ namespace scribo
/// Save the bounding box links image.
- template <typename I>
+ template <typename I, typename L>
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& link_array,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& link_array,
const value::rgb8& box_value,
const value::rgb8& link_value,
const std::string& filename);
- template <typename I>
+ template <typename I, typename L>
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_array,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_array,
const value::rgb8& box_value,
const value::rgb8& left_link_value,
const value::rgb8& right_link_value,
const std::string& filename);
- template <typename I, typename G>
+ template <typename I, typename L, typename G>
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const scribo::util::text<L>& text,
const Graph<G>& g,
const value::rgb8& box_value,
const value::rgb8& link_value,
@@ -89,12 +90,12 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
- template <typename I>
+ template <typename I, typename L>
inline
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& link_array,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& link_array,
const value::rgb8& box_value,
const value::rgb8& link_value,
const std::string& filename)
@@ -103,21 +104,21 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
- draw::bounding_boxes(tmp, textbboxes, box_value);
- draw::bounding_box_links(tmp, textbboxes, link_array, link_value);
+ draw::bounding_boxes(tmp, text.bboxes(), box_value);
+ draw::bounding_box_links(tmp, text.bboxes(), link_array, link_value);
io::ppm::save(tmp, filename);
trace::exiting("scribo::debug::save_linked_textbboxes_image");
}
- template <typename I>
+ template <typename I, typename L>
inline
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_link,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link,
const value::rgb8& box_value,
const value::rgb8& left_value,
const value::rgb8& right_value,
@@ -127,8 +128,8 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
- draw::bounding_boxes(tmp, textbboxes, box_value);
- draw::bounding_box_links(tmp, textbboxes,
+ draw::bounding_boxes(tmp, text.bboxes(), box_value);
+ draw::bounding_box_links(tmp, text.bboxes(),
left_link, right_link,
left_value, right_value);
io::ppm::save(tmp, filename);
@@ -137,11 +138,11 @@ namespace scribo
}
- template <typename I, typename G>
+ template <typename I, typename L, typename G>
inline
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const scribo::util::text<L>& text,
const Graph<G>& g,
const value::rgb8& box_value,
const value::rgb8& link_value,
@@ -152,8 +153,8 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
- draw::bounding_boxes(tmp, textbboxes, box_value);
- draw::bounding_box_links(tmp, textbboxes, g, link_value);
+ draw::bounding_boxes(tmp, text.bboxes(), box_value);
+ draw::bounding_box_links(tmp, text.bboxes(), g, link_value);
io::ppm::save(tmp, filename);
trace::exiting("scribo::debug::save_linked_textbboxes_image");
diff --git a/milena/sandbox/scribo/debug/save_table_image.hh b/milena/sandbox/scribo/debug/save_table_image.hh
index b170420..4ed0a68 100644
--- a/milena/sandbox/scribo/debug/save_table_image.hh
+++ b/milena/sandbox/scribo/debug/save_table_image.hh
@@ -36,7 +36,9 @@
# include <string>
# include <mln/core/concept/image.hh>
+# include <mln/core/image/image2d.hh>
# include <mln/data/fill.hh>
+# include <mln/level/convert.hh>
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
# include <mln/value/rgb8.hh>
@@ -50,16 +52,29 @@ namespace scribo
namespace debug
{
- /// Save lines bounding boxes in an image filled with \p bg_color.
+ using namespace mln;
+
+ /// Save lines bounding boxes in a copy of \p input_.
/// Bounding boxes are displayed with \p bbox_color.
template <typename I>
void
- save_table(const Image<I>& input_,
- util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const value::rgb8& bg_color,
- const value::rgb8& bbox_color,
- const std::string& filename);
+ save_table_image(const Image<I>& input_,
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > > tableboxes,
+ const value::rgb8& bbox_color,
+ const std::string& filename);
+
+ /// Save lines bounding boxes in an image defined on \p input_domain
+ /// filled with \p bg_color.
+ /// Bounding boxes are displayed with \p bbox_color.
+ template <typename S>
+ void
+ save_table_image(const Site_Set<S>& input_domain,
+ util::couple<util::array<box<mln_site(S)> >,
+ util::array<box<mln_site(S)> > > tableboxes,
+ const value::rgb8& bg_color,
+ const value::rgb8& bbox_color,
+ const std::string& filename);
# ifndef MLN_INCLUDE_ONLY
@@ -67,18 +82,40 @@ namespace scribo
template <typename I>
void
- save_table(const Image<I>& input_,
- util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const value::rgb8& bg_color,
- const value::rgb8& bbox_color,
- const std::string& filename)
+ save_table_image(const Image<I>& input_,
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > > tableboxes,
+ const value::rgb8& bbox_color,
+ const std::string& filename)
{
trace::entering("scribo::debug::save_table_image");
+// mlc_converts_to(mln_value(I), value::rgb8)::check();
const I& input = exact(input_);
mln_precondition(input.is_valid());
- mln_ch_value(I,value::rgb8) out2(exact(input).domain());
+ mln_ch_value(I,value::rgb8) out2 = level::convert(value::rgb8(), input);
+ draw::bounding_boxes(out2, tableboxes.first(), bbox_color);
+ draw::bounding_boxes(out2, tableboxes.second(), bbox_color);
+ io::ppm::save(out2, filename);
+
+ trace::exiting("scribo::internal::save_table");
+ }
+
+
+ template <typename S>
+ void
+ save_table_image(const Site_Set<S>& input_domain_,
+ util::couple<util::array<box<mln_site(S)> >,
+ util::array<box<mln_site(S)> > > tableboxes,
+ const value::rgb8& bg_color,
+ const value::rgb8& bbox_color,
+ const std::string& filename)
+ {
+ trace::entering("scribo::debug::save_table_image");
+ const S& input_domain = exact(input_domain_);
+ mln_precondition(input_domain.is_valid());
+
+ image2d<value::rgb8> out2(input_domain);
data::fill(out2, bg_color);
draw::bounding_boxes(out2, tableboxes.first(), bbox_color);
draw::bounding_boxes(out2, tableboxes.second(), bbox_color);
diff --git a/milena/sandbox/scribo/debug/save_textbboxes_image.hh b/milena/sandbox/scribo/debug/save_textbboxes_image.hh
index b210b39..86a8b3f 100644
--- a/milena/sandbox/scribo/debug/save_textbboxes_image.hh
+++ b/milena/sandbox/scribo/debug/save_textbboxes_image.hh
@@ -40,6 +40,7 @@
# include <mln/io/ppm/save.hh>
# include <scribo/draw/bounding_boxes.hh>
+# include <scribo/make/debug_filename.hh>
namespace scribo
@@ -55,7 +56,7 @@ namespace scribo
template <typename I>
void
save_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const mln::util::array< box<mln_site(I)> >& textbboxes,
const value::rgb8& value,
const std::string& filename);
@@ -66,7 +67,7 @@ namespace scribo
inline
void
save_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const mln::util::array< box<mln_site(I)> >& textbboxes,
const value::rgb8& value,
const std::string& filename)
{
@@ -75,7 +76,7 @@ namespace scribo
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
draw::bounding_boxes(tmp, textbboxes, value);
- io::ppm::save(tmp, filename);
+ io::ppm::save(tmp, scribo::make::debug_filename(filename));
trace::exiting("scribo::debug::save_textbboxes_image");
}
diff --git a/milena/sandbox/scribo/draw/bounding_box_links.hh b/milena/sandbox/scribo/draw/bounding_box_links.hh
index 7cf57ac..e33da38 100644
--- a/milena/sandbox/scribo/draw/bounding_box_links.hh
+++ b/milena/sandbox/scribo/draw/bounding_box_links.hh
@@ -52,17 +52,17 @@ namespace scribo
template <typename I>
void
bounding_box_links(Image<I>& input_,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& link_array,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& link_array,
const mln_value(I)& value);
template <typename I>
void
bounding_box_links(Image<I>& input,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_link,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value);
@@ -78,7 +78,7 @@ namespace scribo
{
draw_graph_edges_functor(I& ima,
- const util::array<box<mln_site(I)> >& textbboxes,
+ const mln::util::array<box<mln_site(I)> >& textbboxes,
const mln_value(I)& value)
: ima_(ima), textbboxes_(textbboxes), value_(value)
{}
@@ -114,7 +114,7 @@ namespace scribo
{ return to_be_treated(id); }
I& ima_;
- const util::array<box<mln_site(I)> >& textbboxes_;
+ const mln::util::array<box<mln_site(I)> >& textbboxes_;
mln_value(I) value_;
unsigned current_vertex;
std::vector<bool> deja_vu;
@@ -127,8 +127,8 @@ namespace scribo
inline
void
bounding_box_links(Image<I>& input_,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& link_array,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& link_array,
const mln_value(I)& value)
{
trace::entering("scribo::draw::bounding_box_links");
@@ -152,9 +152,9 @@ namespace scribo
inline
void
bounding_box_links(Image<I>& input,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_link,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value)
{
@@ -172,7 +172,7 @@ namespace scribo
inline
void
bounding_box_links(Image<I>& input,
- const util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
const Graph<G>& g,
const mln_value(I)& link_value)
{
diff --git a/milena/sandbox/scribo/draw/bounding_boxes.hh b/milena/sandbox/scribo/draw/bounding_boxes.hh
index 0db60a4..bfebaf3 100644
--- a/milena/sandbox/scribo/draw/bounding_boxes.hh
+++ b/milena/sandbox/scribo/draw/bounding_boxes.hh
@@ -51,7 +51,7 @@ namespace scribo
template <typename I>
void
bounding_boxes(Image<I>& input_,
- const util::array< box<mln_site(I)> >& boxes,
+ const mln::util::array< box<mln_site(I)> >& boxes,
const mln_value(I)& value);
@@ -63,7 +63,7 @@ namespace scribo
inline
void
bounding_boxes(Image<I>& input_,
- const util::array< box<mln_site(I)> >& boxes,
+ const mln::util::array< box<mln_site(I)> >& boxes,
const mln_value(I)& value)
{
trace::entering("scribo::draw::bounding_boxes");
diff --git a/milena/sandbox/scribo/filter/large_components.hh b/milena/sandbox/scribo/filter/large_components.hh
new file mode 100644
index 0000000..9ea4e02
--- /dev/null
+++ b/milena/sandbox/scribo/filter/large_components.hh
@@ -0,0 +1,196 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_FILTER_LARGE_COMPONENTS_HH
+# define SCRIBO_FILTER_LARGE_COMPONENTS_HH
+
+/// \file scribo/filter/large_components.hh
+///
+/// Remove large components in a binary image.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/relabel.hh>
+
+# include <mln/util/array.hh>
+# include <mln/value/label_16.hh>
+
+# include <mln/pw/all.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Remove large components in a binary image.
+ /// Set to 'false' all the removed components.
+ ///
+ /// \param[in] input_ A binary image.
+ /// \param[in] nbh_ A neighborhood used for labeling \p input_.
+ /// \param[in] label_type The label type used for labeling.
+ /// \param[in] max_size The minimum cardinality of a component.
+ ///
+ /// \return A binary image without large components.
+ template <typename I, typename N, typename V>
+ mln_concrete(I)
+ large_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_size);
+
+
+ /// Remove large bboxes in a binary image.
+ /// Set to 'false' all the removed bboxes.
+ ///
+ /// \param[in] input_ A binary image.
+ /// \param[in] bboxes Bounding boxes of components extracted from \p
+ /// input_.
+ /// \param[in] max_size The minimum cardinality of a component.
+ ///
+ /// \return A binary image without large bboxes.
+ template <typename P>
+ util::array< box<P> >
+ large_components(const util::array< box<P> >& bboxes,
+ unsigned max_size);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+
+ /// Filter Functor. Return false for all components which are too
+ /// large.
+ template <typename R>
+ struct filter_large_components_functor
+ : Function_l2b< filter_large_and_large_functor<R> >
+ {
+ filter_large_components_functor(const util::array<R>& nsitecomp,
+ unsigned max_size)
+ : nsitecomp_(nsitecomp), max_size_(max_size)
+ {
+ }
+
+
+ /// Return false if the components area is strictly inferior to
+ /// \p max_size_.
+ bool operator()(const value::label_16& l) const
+ {
+ return nsitecomp_[l] <= max_size_;
+ }
+
+
+ const util::array<R>& nsitecomp_;
+ unsigned max_size_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ large_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_size)
+ {
+ trace::entering("scribo::filter::large_components");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ V nlabels;
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nlabels);
+
+ typedef accu::count<mln_psite(I)> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef util::array<accu_count_res_t> nsitecomp_t;
+ nsitecomp_t nsitecomp = labeling::compute(accu_count_t(), lbl, nlabels);
+
+ typedef internal::filter_large_and_large_functor<accu_count_res_t> func_t;
+ func_t fl2b(nsitecomp, max_size);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | pw::value(lbl) == literal::zero).rw(), false);
+
+ trace::exiting("scribo::filter::large_components");
+ return output;
+ }
+
+
+ template <typename P>
+ inline
+ util::array< box<P> >
+ large_components(const util::array< box<P> >& bboxes,
+ unsigned max_size)
+ {
+ trace::entering("scribo::filter::large_components");
+
+ mln_precondition(input.is_valid());
+
+ typedef accu::count<P> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef util::array<accu_count_res_t> nsitecomp_t;
+
+ util::array<box<P> > result;
+ result.append(box<P>());
+ for_all_components(i, bboxes)
+ {
+ accu_count_res_t count = set::compute(accu_count_t(), bboxes[i]);
+ if (count <= max_size)
+ result.append(bboxes[i]);
+ }
+
+ trace::exiting("scribo::filter::large_components");
+ return result;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_LARGE_COMPONENTS_HH
diff --git a/milena/sandbox/scribo/filter/small_components.hh b/milena/sandbox/scribo/filter/small_components.hh
new file mode 100644
index 0000000..8cb6858
--- /dev/null
+++ b/milena/sandbox/scribo/filter/small_components.hh
@@ -0,0 +1,207 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_FILTER_SMALL_COMPONENTS_HH
+# define SCRIBO_FILTER_SMALL_COMPONENTS_HH
+
+/// \file scribo/filter/small_components.hh
+///
+/// Remove small components in a binary image.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/relabel.hh>
+
+# include <mln/util/array.hh>
+# include <mln/value/label_16.hh>
+
+# include <mln/pw/all.hh>
+
+# include <scribo/util/text.hh>
+# include <scribo/make/text.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Remove small components in a binary image.
+ /// Set to 'false' all the removed components.
+ ///
+ /// \param[in] input_ A binary image.
+ /// \param[in] nbh_ A neighborhood used for labeling \p input_.
+ /// \param[in] label_type The label type used for labeling.
+ /// \param[in] min_size The minimum cardinality of a component.
+ ///
+ /// \return A binary image without small components.
+ template <typename I, typename N, typename V>
+ mln_concrete(I)
+ small_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned min_size);
+
+
+ /// Remove too small text components.
+ ///
+ /// \param[in] text Text data.
+ /// \param[in] min_size The minimum cardinality of a component.
+ ///
+ /// \return updated text data.
+ template <typename I>
+ scribo::util::text<I>
+ small_components(const scribo::util::text<I>& text,
+ unsigned min_size);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+
+ /// Filter Functor. Return false for all components which are too
+ /// small.
+ template <typename R>
+ struct filter_small_components_functor
+ : Function_l2b< filter_small_components_functor<R> >
+ {
+ filter_small_components_functor(const mln::util::array<R>& nsitecomp,
+ unsigned min_size)
+ : nsitecomp_(nsitecomp), min_size_(min_size)
+ {
+ }
+
+
+ /// Return false if the components area is strictly inferior to
+ /// \p min_size_.
+ bool operator()(const value::label_16& l) const
+ {
+ return nsitecomp_[l] >= min_size_;
+ }
+
+
+ const mln::util::array<R>& nsitecomp_;
+ unsigned min_size_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ small_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned min_size)
+ {
+ trace::entering("scribo::filter::small_components");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ V nlabels;
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nlabels);
+
+ typedef accu::count<mln_psite(I)> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef mln::util::array<accu_count_res_t> nsitecomp_t;
+ nsitecomp_t nsitecomp = labeling::compute(accu_count_t(), lbl, nlabels);
+
+ typedef internal::filter_small_components_functor<accu_count_res_t> func_t;
+ func_t fl2b(nsitecomp, min_size);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | pw::value(lbl) == literal::zero).rw(), false);
+
+ trace::exiting("scribo::filter::small_components");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ scribo::util::text<I>
+ small_components(const scribo::util::text<I>& text,
+ unsigned min_size)
+ {
+ trace::entering("scribo::filter::small_components");
+
+ mln_precondition(text.is_valid());
+
+ typedef mln_site(I) P;
+ typedef accu::count<P> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef mln::util::array<accu_count_res_t> nsitecomp_t;
+
+ fun::i2v::array<bool> f(text.nbboxes().next(), false);
+ f(0) = true;
+ mln::util::array<box<P> > bresult;
+ bresult.append(box<P>());
+ for_all_components(i, text.bboxes())
+ {
+ accu_count_res_t count = set::compute(accu_count_t(), text.bbox(i));
+ if (count >= min_size)
+ {
+ bresult.append(text.bbox(i));
+ f(i) = true;
+ }
+ }
+
+ mln_value(I) new_nbboxes;
+ I new_lbl = labeling::relabel(text.label_image(), text.nbboxes(),
+ new_nbboxes, f);
+
+ trace::exiting("scribo::filter::small_components");
+ return scribo::make::text(bresult, new_lbl, new_nbboxes);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_SMALL_COMPONENTS_HH
diff --git a/milena/sandbox/scribo/filter/thin_bboxes.hh b/milena/sandbox/scribo/filter/thin_bboxes.hh
new file mode 100644
index 0000000..de99242
--- /dev/null
+++ b/milena/sandbox/scribo/filter/thin_bboxes.hh
@@ -0,0 +1,165 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_FILTER_THIN_BBOXES_HH
+# define SCRIBO_FILTER_THIN_BBOXES_HH
+
+/// \file scribo/filter/thin_bboxes.hh
+///
+/// Remove too thin bboxes.
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/util/text.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+
+ /// Filter Functor. Return false for all components which are too
+ /// large.
+ template <typename R>
+ struct filter_too_thin_component_functor
+ : Function_l2b< filter_too_thin_component_functor<R> >
+ {
+ filter_too_thin_component_functor(const mln::util::array<R>& compbboxes,
+ unsigned min_thickness)
+ : compbboxes_(compbboxes), min_thickness_(min_thickness)
+ {
+ }
+
+
+ /// Return false if the components is thinner than
+ /// \p min_thickness_.
+ bool operator()(const value::label_16& l) const
+ {
+ return compbboxes_[l].nrows() > min_thickness_
+ && compbboxes_[l].ncols() > min_thickness_;
+ }
+
+
+ const mln::util::array<R>& compbboxes_;
+ unsigned min_thickness_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ thin_bboxes(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned min_thickness)
+ {
+ trace::entering("scribo::filter::thin_bboxes");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ V nlabels;
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nlabels);
+
+ typedef accu::bbox<mln_psite(I)> accu_bbox_t;
+ typedef mln_result(accu_bbox_t) accu_bbox_res_t;
+ typedef mln::util::array<accu_bbox_res_t> compbboxes_t;
+ compbboxes_t compbboxes = labeling::compute(accu_bbox_t(), lbl, nlabels);
+
+ typedef internal::filter_too_thin_component_functor<accu_bbox_res_t> func_t;
+ func_t fl2b(compbboxes, min_thickness);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | pw::value(lbl) == literal::zero).rw(), false);
+
+ trace::exiting("scribo::filter::thin_bboxes");
+ return output;
+ }
+
+
+ template <typename L>
+ inline
+ scribo::util::text<L>
+ thin_bboxes(const scribo::util::text<L>& text,
+ unsigned min_thickness)
+ {
+ trace::entering("scribo::filter::thin_bboxes");
+
+ mln_precondition(text.is_valid());
+
+ typedef mln_site(L) P;
+ typedef accu::bbox<P> accu_bbox_t;
+ typedef mln_result(accu_bbox_t) accu_bbox_res_t;
+ typedef mln::util::array<accu_bbox_res_t> nsitecomp_t;
+
+ typedef internal::filter_too_thin_component_functor<accu_bbox_res_t> func_t;
+ func_t is_not_too_thin(text.bboxes(), min_thickness);
+
+ fun::i2v::array<bool> f(text.nbboxes().next(), false);
+ f(0) = true;
+ mln::util::array<box<P> > bresult;
+ bresult.append(box<P>());
+ for_all_components(i, text.bboxes())
+ if (is_not_too_thin(i))
+ {
+ bresult.append(text.bbox(i));
+ f(i) = true;
+ }
+
+ mln_value(L) new_nbboxes;
+ L new_lbl = labeling::relabel(text.label_image(), text.nbboxes(),
+ mln::make::relabelfun(f, text.nbboxes(), new_nbboxes));
+
+ mln_assertion(new_nbboxes.next() == bresult.nelements());
+
+ trace::exiting("scribo::filter::thin_bboxes");
+ return scribo::make::text(bresult, new_lbl, new_nbboxes);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_THIN_BBOXES_HH
diff --git a/milena/sandbox/scribo/make/debug_filename.hh b/milena/sandbox/scribo/make/debug_filename.hh
index b159328..5a9728c 100644
--- a/milena/sandbox/scribo/make/debug_filename.hh
+++ b/milena/sandbox/scribo/make/debug_filename.hh
@@ -35,6 +35,7 @@
/// Construct and returns a formated output file name.
# include <sstream>
+# include <mln/trace/all.hh>
namespace scribo
@@ -46,25 +47,43 @@ namespace scribo
/// Construct and returns a formated output file name:
///
/// `input_filename`_`id`_`name`
+ /// \sa scribo::make::internal::debug_filename_prefix
std::string
- debug_filename(const char *input_filename,
- const char *name);
+ debug_filename(const std::string& name);
+ namespace internal
+ {
+
+ /// Set the default debug filename prefix.
+ extern char *debug_filename_prefix;
+
+ } // end of namespace scribo::make::internal
+
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ char *debug_filename_prefix = 0;
+
+ } // end of namespace scribo::make::internal
+
+
inline
std::string
- debug_filename(const char *input_filename,
- const char *name)
+ debug_filename(const std::string& name)
{
static int file_id = 1;
std::ostringstream os;
- os << "./"
- << input_filename
- << "_";
+
+ if (internal::debug_filename_prefix != 0)
+ os << internal::debug_filename_prefix << "_";
+ else
+ mln::trace::warning("You may like to set a default filename prefix.");
if (file_id < 10)
os << "0";
diff --git a/milena/sandbox/scribo/text/extract_bboxes.hh b/milena/sandbox/scribo/make/text.hh
similarity index 56%
copy from milena/sandbox/scribo/text/extract_bboxes.hh
copy to milena/sandbox/scribo/make/text.hh
index 0c88880..3c32ad0 100644
--- a/milena/sandbox/scribo/text/extract_bboxes.hh
+++ b/milena/sandbox/scribo/make/text.hh
@@ -1,5 +1,4 @@
// Copyright (C) 2009 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
@@ -26,13 +25,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
+#ifndef SCRIBO_MAKE_TEXT_HH
+# define SCRIBO_MAKE_TEXT_HH
-#ifndef SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-# define SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-
-/// \file scribo/text/grouping/group_with_single_link.hh
+/// \file scribo/make/text.hh
///
-/// Extract text bounding boxes from a binary image.
+/// Construct a util::text.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -40,56 +38,77 @@
# include <mln/labeling/blobs.hh>
# include <mln/labeling/compute.hh>
# include <mln/util/array.hh>
+# include <scribo/util/text.hh>
-# include <scribo/core/component_bboxes.hh>
namespace scribo
{
- namespace text
+ namespace make
{
- using namespace mln;
- /// Extract text bounding boxes from a binary image.
- ///
- /// \param[in] input_ A binary image.
- ///
- /// \return an array of bounding boxes. The first bounding box is
- /// the background's.
+ template <typename L>
+ scribo::util::text<L>
+ text(const mln::util::array<box<mln_site(L)> >& bboxes,
+ const Image<L>& lbl,
+ mln_value(L)& nbboxes);
+
+
template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes);
+ scribo::util::text<mln_ch_value(I,V)>
+ text(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ V& nbboxes);
+
# ifndef MLN_INCLUDE_ONLY
+ template <typename L>
+ scribo::util::text<L>
+ text(const mln::util::array<box<mln_site(L)> >& bboxes,
+ const Image<L>& lbl,
+ mln_value(L)& nbboxes)
+ {
+ trace::entering("scribo::make::text");
+
+ mln_precondition(exact(lbl).is_valid());
+
+ scribo::util::text<L> result = scribo::util::text<L>(bboxes, lbl,
+ nbboxes);
+
+ trace::exiting("scribo::make::text");
+ return result;
+ }
+
+
template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes)
+ scribo::util::text<mln_ch_value(I,V)>
+ text(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ V& nbboxes)
{
- trace::entering("scribo::text::extract_bboxes");
+ trace::entering("scribo::make::text");
const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
- mlc_equal(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ typedef mln::util::array< box<mln_site(I)> > boxes_t;
+
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nbboxes);
- typedef util::array< box<mln_site(I)> > bboxes_t;
- bboxes_t bboxes = component_bboxes(input, nbh, nbboxes);
+ boxes_t cboxes = labeling::compute(accu::meta::bbox(), lbl, nbboxes);
- trace::exiting("scribo::text::extract_bboxes");
- return bboxes;
+ trace::exiting("scribo::make::text");
+ return make::text(cboxes, lbl, nbboxes);
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::text
+ } // end of namespace scribo::make
} // end of namespace scribo
-#endif // ! SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
+#endif // ! SCRIBO_MAKE_TEXT_HH
diff --git a/milena/sandbox/scribo/src/dmap.cc b/milena/sandbox/scribo/src/dmap.cc
new file mode 100644
index 0000000..dac40ba
--- /dev/null
+++ b/milena/sandbox/scribo/src/dmap.cc
@@ -0,0 +1,26 @@
+#include <mln/essential/2d.hh>
+#include <mln/core/var.hh>
+#include <mln/fun/l2l/wrap.hh>
+#include <mln/transform/distance_and_influence_zone_geodesic.hh>
+
+int main(int, char *argv[])
+{
+ using namespace mln;
+
+ using value::int_u16;
+ using value::label_16;
+ using value::label_8;
+ using value::rgb8;
+
+ image2d<bool> ima;
+ io::pbm::load(ima, argv[1]);
+
+ label_16 nlabels;
+ image2d<label_16> lbl = labeling::blobs(ima, c8(), nlabels);
+
+ mln_VAR(res, transform::distance_and_influence_zone_geodesic(lbl, c8(), mln_max(unsigned)));
+
+ io::pgm::save(level::transform(res.first(), fun::l2l::wrap<label_8>()), "dmap.pgm");
+ io::ppm::save(debug::colorize(value::rgb8(), res.second(), nlabels), "iz.ppm");
+
+}
diff --git a/milena/sandbox/scribo/src/extract_text_double_link.cc b/milena/sandbox/scribo/src/extract_text_double_link.cc
index 26fccff..ea4b2b8 100644
--- a/milena/sandbox/scribo/src/extract_text_double_link.cc
+++ b/milena/sandbox/scribo/src/extract_text_double_link.cc
@@ -28,6 +28,7 @@
#include <iostream>
#include <mln/essential/2d.hh>
+#include <mln/debug/colorize.hh>
#include <scribo/text/extract_bboxes.hh>
#include <scribo/text/grouping/group_with_single_left_link.hh>
@@ -44,17 +45,6 @@ int usage(const char *name)
}
-namespace scribo { namespace text { namespace grouping
-{
- using namespace mln;
-
- template <typename I>
- util::array< box<mln_site(I)> >
- group_from_double_link(const util::array< box<mln_site(I)> >& textbboxes,
- util::array<unsigned>& left_link,
- util::array<unsigned>& right_link);
-}}}
-
int main(int argc, char* argv[])
{
using namespace scribo;
@@ -63,47 +53,56 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = "extract_text_double_link";
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ scribo::util::text<image2d<value::label_16> > text
+ = text::extract_bboxes(input, c8(), nbboxes);
- util::array<unsigned> left_link
- = text::grouping::group_with_single_left_link(input,
- c8(), nbboxes,
- textbboxes, 30);
- util::array<unsigned> right_link
- = text::grouping::group_with_single_right_link(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::array<unsigned> left_link
+ = text::grouping::group_with_single_left_link(text, 30);
+ mln::util::array<unsigned> right_link
+ = text::grouping::group_with_single_right_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl;
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, left_link,
- literal::red, literal::cyan,
- "test_double_link_left_linked.ppm");
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, right_link,
- literal::red, literal::cyan,
- "test_double_link_right_linked.ppm");
+// scribo::debug::save_linked_textbboxes_image(input,
+// text, left_link,
+// literal::red, literal::cyan,
+// scribo::make::debug_filename("left_linked.ppm"));
+// scribo::debug::save_linked_textbboxes_image(input,
+// text, right_link,
+// literal::red, literal::cyan,
+// scribo::make::debug_filename("right_linked.ppm"));
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, left_link, right_link,
+ text, left_link, right_link,
literal::red, literal::cyan,
literal::yellow,
- "test_double_link_double_linked.ppm");
+ scribo::make::debug_filename("links.ppm"));
+
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
// With validation.
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_double_link(textbboxes, left_link, right_link);
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_double_link(text, left_link, right_link);
+
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("label_color.ppm"));
- std::cout << "AFTER double grouping - nbboxes = " << grouped_textbboxes.nelements() << std::endl;
+ std::cout << "AFTER double grouping - nbboxes = " << grouped_text.bboxes().nelements() << std::endl;
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_double_link_grouped_text.ppm");
+ scribo::make::debug_filename("bboxes.ppm"));
}
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc b/milena/sandbox/scribo/src/extract_text_multiple_links.cc
index 9b181e6..0c8c624 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/src/extract_text_multiple_links.cc
@@ -50,29 +50,39 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = "extract_text_multiple_links";
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ scribo::util::text<image2d<value::label_16> > text
+ = text::extract_bboxes(input, c8(), nbboxes);
- util::graph g = text::grouping::group_with_multiple_links(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::graph g = text::grouping::group_with_multiple_links(text, 30);
- std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl;
+ std::cout << "BEFORE - nbboxes = " << nbboxes.next() << std::endl;
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, g,
+ text, g,
literal::red, literal::cyan,
- "test_multiple_links_left_linked.ppm");
+ scribo::make::debug_filename("left_linked.ppm"));
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_multiple_links(textbboxes, g);
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_multiple_links(text, g);
- std::cout << "AFTER - nbboxes = " << grouped_textbboxes.nelements() << std::endl;
+ std::cout << "AFTER - nbboxes = " << grouped_text.bboxes().nelements() << std::endl;
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_multiple_links_grouped_text.ppm");
+ scribo::make::debug_filename("grouped_text.ppm"));
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("label_color.ppm"));
+
}
diff --git a/milena/sandbox/scribo/src/extract_text_single_link.cc b/milena/sandbox/scribo/src/extract_text_single_link.cc
index 5b4e248..1dee956 100644
--- a/milena/sandbox/scribo/src/extract_text_single_link.cc
+++ b/milena/sandbox/scribo/src/extract_text_single_link.cc
@@ -51,56 +51,70 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = "extract_text_single_link";
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ scribo::util::text<image2d<value::label_16> > text
+ = text::extract_bboxes(input, c8(), nbboxes);
{
std::cout << "* Left grouping" << std::endl;
- util::array<unsigned> left_link
- = text::grouping::group_with_single_left_link(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::array<unsigned> left_link
+ = text::grouping::group_with_single_left_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl;
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, left_link,
+ text, left_link,
literal::red, literal::cyan,
- "test_single_left_link_linked.ppm");
-
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_single_link(textbboxes, left_link);
-
- std::cout << "AFTER - nbboxes = " << grouped_textbboxes.nelements() << std::endl;
-
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::make::debug_filename("left_links.ppm"));
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
+
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_single_link(text, left_link);
+
+ std::cout << "AFTER - nbboxes = " << grouped_text.bboxes().nelements() << std::endl;
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("left_label_color.ppm"));
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_single_left_link_grouped_text.ppm");
+ scribo::make::debug_filename("left_bboxes.ppm"));
}
{
std::cout << "* Left grouping" << std::endl;
- util::array<unsigned> right_link
- = text::grouping::group_with_single_right_link(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::array<unsigned> right_link
+ = text::grouping::group_with_single_right_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl;
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, right_link,
+ text, right_link,
literal::red, literal::cyan,
- "test_single_right_link_linked.ppm");
-
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_single_link(textbboxes, right_link);
-
- std::cout << "AFTER - nbboxes = " << grouped_textbboxes.nelements() << std::endl;
-
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::make::debug_filename("right_links.ppm"));
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
+
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_single_link(text, right_link);
+
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("right_label_color.ppm"));
+ std::cout << "AFTER - nbboxes = " << grouped_text.bboxes().nelements() << std::endl;
+
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_single_right_link_grouped_text.ppm");
+ scribo::make::debug_filename("right_bboxes.ppm"));
}
diff --git a/milena/sandbox/scribo/src/morpho.cc b/milena/sandbox/scribo/src/morpho.cc
new file mode 100644
index 0000000..a527a3d
--- /dev/null
+++ b/milena/sandbox/scribo/src/morpho.cc
@@ -0,0 +1,64 @@
+#include <mln/essential/2d.hh>
+#include <mln/transform/distance_and_influence_zone_geodesic.hh>
+#include <mln/core/var.hh>
+#include <mln/fun/l2l/wrap.hh>
+#include <mln/win/hline2d.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/morpho/watershed/superpose.hh>
+
+#include <scribo/make/debug_filename.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ using value::int_u16;
+ using value::label_16;
+ using value::label_8;
+ using value::rgb8;
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ scribo::make::internal::debug_filename_prefix = "morpho";
+
+ label_16 nlabels;
+ image2d<label_16> lbl = labeling::blobs(input, c8(), nlabels);
+
+ mln_VAR(res, transform::distance_and_influence_zone_geodesic(lbl, c8(), mln_max(unsigned)));
+
+ io::pgm::save(level::transform(res.first(), fun::l2l::wrap<label_8>()), "dmap.pgm");
+ io::ppm::save(debug::colorize(rgb8(), res.second(), nlabels), "iz.ppm");
+
+ image2d<unsigned>& dmap = res.first();
+ {
+ image2d<unsigned> clo = morpho::closing::structural(dmap, win::hline2d(51));
+ io::pgm::save(clo, scribo::make::debug_filename("clo_line_51.pgm"));
+ label_16 nlabels;
+ image2d<label_16> wsd = morpho::watershed::flooding(clo, c8(), nlabels);
+
+ io::ppm::save(morpho::watershed::superpose(input, wsd),
+ scribo::make::debug_filename("wsd_line_51.ppm"));
+ }
+
+ {
+ image2d<unsigned> clo = morpho::closing::structural(dmap, win::rectangle2d(11, 101));
+ io::pgm::save(clo, scribo::make::debug_filename("clo_rectangle_11_101.pgm"));
+ label_16 nlabels;
+ image2d<label_16> wsd = morpho::watershed::flooding(clo, c8(), nlabels);
+
+ io::ppm::save(morpho::watershed::superpose(input, wsd),
+ scribo::make::debug_filename("wsd_rectangle_11_101.ppm"));
+ }
+
+ {
+ image2d<unsigned> clo = morpho::closing::structural(dmap, win::disk2d(51));
+ io::pgm::save(clo, scribo::make::debug_filename("clo_disk_51.pgm"));
+ label_16 nlabels;
+ image2d<label_16> wsd = morpho::watershed::flooding(clo, c8(), nlabels);
+
+ io::ppm::save(morpho::watershed::superpose(input, wsd),
+ scribo::make::debug_filename("wsd_disk_51.ppm"));
+ }
+
+???
diff --git a/milena/sandbox/scribo/src/table.cc b/milena/sandbox/scribo/src/table.cc
index 3472599..3a12c57 100644
--- a/milena/sandbox/scribo/src/table.cc
+++ b/milena/sandbox/scribo/src/table.cc
@@ -26,7 +26,7 @@
// Public License.
-#include "demat.hh"
+#include <demat.hh>
int main(int argc, char*argv[])
{
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc b/milena/sandbox/scribo/src/table_extract.cc
similarity index 61%
copy from milena/sandbox/scribo/src/extract_text_multiple_links.cc
copy to milena/sandbox/scribo/src/table_extract.cc
index 9b181e6..36142a2 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/src/table_extract.cc
@@ -28,13 +28,10 @@
#include <iostream>
#include <mln/essential/2d.hh>
+#include <mln/io/dump/save.hh>
-#include <scribo/text/extract_bboxes.hh>
-#include <scribo/text/grouping/group_with_multiple_links.hh>
-#include <scribo/text/grouping/group_from_multiple_links.hh>
+#include <scribo/table/extract.hh>
-#include <scribo/debug/save_textbboxes_image.hh>
-#include <scribo/debug/save_linked_textbboxes_image.hh>
int usage(const char *name)
{
@@ -42,6 +39,7 @@ int usage(const char *name)
return 1;
}
+
int main(int argc, char* argv[])
{
using namespace scribo;
@@ -50,29 +48,20 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = argv[0];
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
+ logical::not_inplace(input);
- value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
-
- util::graph g = text::grouping::group_with_multiple_links(input,
- c8(), nbboxes,
- textbboxes, 30);
+ trace::quiet = false;
- std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl;
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, g,
- literal::red, literal::cyan,
- "test_multiple_links_left_linked.ppm");
+ value::label_16 ncells;
+ image2d<value::label_16> tables = scribo::table::extract(input, ncells);
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_multiple_links(textbboxes, g);
+ std::cout << "ncells (including background) = " << ncells << std::endl;
+ io::ppm::save(mln::debug::colorize(value::rgb8(), tables, ncells),
+ scribo::make::debug_filename("table_cells.ppm"));
- std::cout << "AFTER - nbboxes = " << grouped_textbboxes.nelements() << std::endl;
-
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
- literal::red,
- "test_multiple_links_grouped_text.ppm");
+ io::dump::save(tables, scribo::make::debug_filename("table_cells.dump"));
}
-
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc b/milena/sandbox/scribo/src/table_rebuild.cc
similarity index 61%
copy from milena/sandbox/scribo/src/extract_text_multiple_links.cc
copy to milena/sandbox/scribo/src/table_rebuild.cc
index 9b181e6..d195b5b 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/src/table_rebuild.cc
@@ -29,12 +29,11 @@
#include <mln/essential/2d.hh>
-#include <scribo/text/extract_bboxes.hh>
-#include <scribo/text/grouping/group_with_multiple_links.hh>
-#include <scribo/text/grouping/group_from_multiple_links.hh>
+#include <scribo/table/rebuild.hh>
+#include <scribo/table/erase.hh>
+#include <scribo/table/extract_lines_with_rank.hh>
+#include <scribo/make/debug_filename.hh>
-#include <scribo/debug/save_textbboxes_image.hh>
-#include <scribo/debug/save_linked_textbboxes_image.hh>
int usage(const char *name)
{
@@ -42,6 +41,7 @@ int usage(const char *name)
return 1;
}
+
int main(int argc, char* argv[])
{
using namespace scribo;
@@ -50,29 +50,30 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = argv[0];
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
+ logical::not_inplace(input);
- value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ typedef util::couple<util::array<box2d>,util::array<box2d> > tblboxes_t;
- util::graph g = text::grouping::group_with_multiple_links(input,
- c8(), nbboxes,
- textbboxes, 30);
+ win::vline2d vline(51);
+ win::hline2d hline(51);
+ tblboxes_t lineboxes
+ = table::extract_lines_with_rank(input, c8(), value::label_16(),
+ vline, hline, 6, 6);
- std::cout << "BEFORE - nbboxes = " << nbboxes << std::endl;
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, g,
- literal::red, literal::cyan,
- "test_multiple_links_left_linked.ppm");
+ value::label_8 ncells;
+ image2d<value::label_8> tables = scribo::table::rebuild(input, lineboxes, 30, ncells);
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_multiple_links(textbboxes, g);
- std::cout << "AFTER - nbboxes = " << grouped_textbboxes.nelements() << std::endl;
+ std::cout << "ncells (including background) = " << ncells << std::endl;
+ io::ppm::save(mln::debug::colorize(value::rgb8(), tables, ncells),
+ scribo::make::debug_filename("table_cells.ppm"));
+ io::pgm::save(tables, scribo::make::debug_filename("table_cells.pgm"));
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
- literal::red,
- "test_multiple_links_grouped_text.ppm");
+ image2d<bool> in_wo_tables = table::erase(input, lineboxes);
+ io::pbm::save(in_wo_tables,
+ scribo::make::debug_filename("input_wo_tables.pbm"));
}
-
diff --git a/milena/sandbox/scribo/src/thin_bboxes.cc b/milena/sandbox/scribo/src/thin_bboxes.cc
new file mode 100644
index 0000000..77b158b
--- /dev/null
+++ b/milena/sandbox/scribo/src/thin_bboxes.cc
@@ -0,0 +1,32 @@
+#include <mln/essential/2d.hh>
+#include <scribo/text/extract_lines.hh>
+#include <scribo/filter/thin_bboxes.hh>
+
+int usage(const char *name)
+{
+ std::cout << "Usage: " << name << " <input.pbm> " << std::endl;
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc < 1)
+ return usage(argv[0]);
+
+ scribo::make::internal::debug_filename_prefix = "thin_bboxes";
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ value::label_16 nlines;
+ typedef scribo::util::text<image2d<value::label_16> > text_t;
+ text_t lines = scribo::text::extract_lines(input, c8(), nlines);
+
+ text_t filtered_lines = scribo::filter::thin_bboxes(lines, 5);
+
+ scribo::debug::save_textbboxes_image(input, filtered_lines.bboxes(),
+ literal::red,
+ scribo::make::debug_filename("thickness_filter"));
+}
diff --git a/milena/sandbox/scribo/table/align_lines_horizontaly.hh b/milena/sandbox/scribo/table/align_lines_horizontaly.hh
index e75f2f2..4828cfe 100644
--- a/milena/sandbox/scribo/table/align_lines_horizontaly.hh
+++ b/milena/sandbox/scribo/table/align_lines_horizontaly.hh
@@ -38,8 +38,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/site_set/box.hh>
# include <mln/geom/nrows.hh>
-# include <mln/geom/min_nrow.hh>
-# include <mln/geom/max_nrow.hh>
+# include <mln/geom/min_row.hh>
+# include <mln/geom/max_row.hh>
# include <mln/util/array.hh>
@@ -52,18 +52,24 @@ namespace scribo
namespace table
{
+ using namespace mln;
+
/// Align line bounding boxes horizontaly.
///
/// \param[in] input Image from which the line bboxes are
/// extracted from.
/// \param[in, out] lines_bboxes horizontal lines bounding boxes.
+ /// \param[in] max_alignment_diff max space between two lines to
+ /// consider they are potentialy on the
+ /// same line.
///
/// \return A list of the resulting aligned rows. Each integer is actually
/// a row number.
template <typename I>
util::array<int>
align_lines_horizontaly(const Image<I>& input,
- util::array<box<mln_site(I)> >& lines_bboxes);
+ util::array<box<mln_site(I)> >& lines_bboxes,
+ unsigned max_alignment_diff);
# ifndef MLN_INCLUDE_ONLY
@@ -72,7 +78,8 @@ namespace scribo
template <typename I>
util::array<int>
align_lines_horizontaly(const Image<I>& input,
- util::array<box<mln_site(I)> >& lines_bboxes)
+ util::array<box<mln_site(I)> >& lines_bboxes,
+ max_alignment_diff)
{
trace::entering("scribo::table::align_lines_horizontaly");
@@ -80,7 +87,8 @@ namespace scribo
util::array<int> res = internal::align_lines(geom::nrows(input),
geom::min_row(input),
geom::max_row(input),
- lines_bboxes, 0);
+ lines_bboxes, 0,
+ max_alignment_diff);
trace::exiting("scribo::table::align_lines_horizontaly");
return res;
diff --git a/milena/sandbox/scribo/table/align_lines_verticaly.hh b/milena/sandbox/scribo/table/align_lines_verticaly.hh
index 7e860d0..e4d04ba 100644
--- a/milena/sandbox/scribo/table/align_lines_verticaly.hh
+++ b/milena/sandbox/scribo/table/align_lines_verticaly.hh
@@ -38,8 +38,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/site_set/box.hh>
# include <mln/geom/ncols.hh>
-# include <mln/geom/min_ncol.hh>
-# include <mln/geom/max_ncol.hh>
+# include <mln/geom/min_col.hh>
+# include <mln/geom/max_col.hh>
# include <mln/util/array.hh>
@@ -53,18 +53,24 @@ namespace scribo
namespace table
{
+ using namespace mln;
+
/// Align line bounding boxes verticaly.
///
/// \param[in] input Image from which the line bboxes are
/// extracted from.
/// \param[in, out] lines_bboxes vertical lines bounding boxes.
+ /// \param[in] max_alignment_diff max space between two lines to
+ /// consider they are potentialy on the
+ /// same line.
///
/// \return A list of the resulting aligned cols. Each integer is actually
/// a col number.
template <typename I>
util::array<int>
align_lines_verticaly(const Image<I>& input,
- util::array<box<mln_site(I)> >& lines_bboxes);
+ util::array<box<mln_site(I)> >& lines_bboxes,
+ unsigned max_alignment_diff);
# ifndef MLN_INCLUDE_ONLY
@@ -81,7 +87,8 @@ namespace scribo
util::array<int> res = internal::align_lines(geom::ncols(input),
geom::min_col(input),
geom::max_col(input),
- lines_bboxes, 1);
+ lines_bboxes, 1,
+ max_alignment_diff);
trace::exiting("scribo::table::align_lines_horizontaly");
return res;
diff --git a/milena/sandbox/scribo/table/connect_horizontal_lines.hh b/milena/sandbox/scribo/table/connect_horizontal_lines.hh
index 7dcf638..c1d3bd6 100644
--- a/milena/sandbox/scribo/table/connect_horizontal_lines.hh
+++ b/milena/sandbox/scribo/table/connect_horizontal_lines.hh
@@ -55,12 +55,15 @@ namespace scribo
/// bounding boxes.
/// \param[in] input The image from where the lines are
/// extracted.
+ /// \param[in] max_distance max distance allowed between a vertical
+ /// and horizontal lines.
template <typename I>
void
connect_vertical_lines(const util::array<int>& aligned_rows,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance);
# ifndef MLN_INCLUDE_ONLY
@@ -70,14 +73,15 @@ namespace scribo
void
connect_horizontal_lines(const util::array<int>& aligned_cols,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance)
{
trace::entering("scribo::table::connect_horizontal_lines");
mln_precondition(exact(input).is_valid());
internal::connect_lines(aligned_cols, tableboxes.second(),
- 1, exact(input).ncols());
+ 1, exact(input).ncols(), max_distance);
trace::exiting("scribo::table::connect_horizontal_lines");
}
diff --git a/milena/sandbox/scribo/table/connect_vertical_lines.hh b/milena/sandbox/scribo/table/connect_vertical_lines.hh
index 98c39f7..2ab4990 100644
--- a/milena/sandbox/scribo/table/connect_vertical_lines.hh
+++ b/milena/sandbox/scribo/table/connect_vertical_lines.hh
@@ -55,12 +55,15 @@ namespace scribo
/// bounding boxes.
/// \param[in] input The image from where the lines are
/// extracted.
+ /// \param[in] max_distance max distance allowed between a vertical
+ /// and horizontal lines.
template <typename I>
void
connect_vertical_lines(const util::array<int>& aligned_rows,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance);
# ifndef MLN_INCLUDE_ONLY
@@ -71,14 +74,15 @@ namespace scribo
void
connect_vertical_lines(const util::array<int>& aligned_rows,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance)
{
trace::entering("scribo::table::connect_vertical_lines");
mln_precondition(exact(input).is_valid());
internal::connect_lines(aligned_rows, tableboxes.first(),
- 0, exact(input).nrows());
+ 0, exact(input).nrows(), max_distance);
trace::exiting("scribo::table::connect_vertical_lines");
}
diff --git a/milena/sandbox/scribo/text/extract_bboxes.hh b/milena/sandbox/scribo/table/extract.hh
similarity index 55%
copy from milena/sandbox/scribo/text/extract_bboxes.hh
copy to milena/sandbox/scribo/table/extract.hh
index 0c88880..06520c9 100644
--- a/milena/sandbox/scribo/text/extract_bboxes.hh
+++ b/milena/sandbox/scribo/table/extract.hh
@@ -26,70 +26,69 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
+#ifndef SCRIBO_TABLE_EXTRACT_HH
+# define SCRIBO_TABLE_EXTRACT_HH
-#ifndef SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-# define SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-
-/// \file scribo/text/grouping/group_with_single_link.hh
+/// \file scribo/table/extract.hh
///
-/// Extract text bounding boxes from a binary image.
+/// Extract tables from a binary image.
+/// Use arbitrary criterions.
# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/core/site_set/box.hh>
-# include <mln/labeling/blobs.hh>
-# include <mln/labeling/compute.hh>
+# include <mln/util/couple.hh>
# include <mln/util/array.hh>
-# include <scribo/core/component_bboxes.hh>
+# include <scribo/table/rebuild.hh>
+# include <scribo/table/erase.hh>
+# include <scribo/table/extract_lines_with_rank.hh>
+
+# include <scribo/make/debug_filename.hh>
+
namespace scribo
{
- namespace text
+ namespace table
{
- using namespace mln;
+ template <typename I, typename V>
+ mln_ch_value(I,V)
+ extract(const Image<I>& input_, V& ncells);
- /// Extract text bounding boxes from a binary image.
- ///
- /// \param[in] input_ A binary image.
- ///
- /// \return an array of bounding boxes. The first bounding box is
- /// the background's.
- template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes);
# ifndef MLN_INCLUDE_ONLY
-
- template <typename I, typename N, typename V>
+ template <typename I, typename V>
inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes)
+ mln_ch_value(I,V)
+ extract(const Image<I>& input_, V& ncells)
{
- trace::entering("scribo::text::extract_bboxes");
+ trace::entering("scribo::table::extract");
const I& input = exact(input_);
-
- mlc_equal(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
+ mlc_equal(mln_value(I), bool)::check();
+
+ typedef util::array< box<mln_site(I)> > boxarray_t;
+ typedef util::couple<boxarray_t, boxarray_t> tblboxes_t;
+
+ win::line<mln_grid(I::site), 0, mln_coord(I::site)> vline(51);
+ win::line<mln_grid(I::site), 1, mln_coord(I::site)> hline(51);
+ tblboxes_t lineboxes
+ = table::extract_lines_with_rank(input, c8(), V(),
+ vline, hline, 6, 6);
- typedef util::array< box<mln_site(I)> > bboxes_t;
- bboxes_t bboxes = component_bboxes(input, nbh, nbboxes);
+ image2d<V> tables
+ = scribo::table::rebuild(input, lineboxes, 30, ncells);
- trace::exiting("scribo::text::extract_bboxes");
- return bboxes;
+ trace::exiting("scribo::table::extract");
+ return tables;
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::text
+ } // end of namespace scribo::table
} // end of namespace scribo
-#endif // ! SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
+#endif // ! SCRIBO_TABLE_EXTRACT_HH
diff --git a/milena/sandbox/scribo/table/extract_lines_with_rank.hh b/milena/sandbox/scribo/table/extract_lines_with_opening.hh
similarity index 67%
copy from milena/sandbox/scribo/table/extract_lines_with_rank.hh
copy to milena/sandbox/scribo/table/extract_lines_with_opening.hh
index 242dc30..55fd77f 100644
--- a/milena/sandbox/scribo/table/extract_lines_with_rank.hh
+++ b/milena/sandbox/scribo/table/extract_lines_with_opening.hh
@@ -27,12 +27,12 @@
// Public License.
-#ifndef SCRIBO_TABLE_EXTRACT_LINES_WITH_RANK_HH
-# define SCRIBO_TABLE_EXTRACT_LINES_WITH_RANK_HH
+#ifndef SCRIBO_TABLE_EXTRACT_LINES_WITH_OPENING_HH
+# define SCRIBO_TABLE_EXTRACT_LINES_WITH_OPENING_HH
-/// \file scribo/table/extract_lines_with_rank.hh
+/// \file scribo/table/extract_lines_with_opening.hh
///
-/// Extract table lines using a rank filter.
+/// Extract table lines using a morphological opening filter.
# include <mln/core/concept/image.hh>
@@ -40,14 +40,14 @@
# include <mln/core/concept/neighborhood.hh>
# include <mln/core/site_set/box.hh>
-# include <mln/morpho/rank_filter.hh>
+# include <mln/morpho/erosion.hh>
# include <mln/accu/bbox.hh>
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
-
+# include <scribo/core/macros.hh>
# include <scribo/core/component_bboxes.hh>
namespace scribo
@@ -56,18 +56,18 @@ namespace scribo
namespace table
{
- /// Find table bboxes thanks to a rank filter.
+ using namespace mln;
+
+ /// Find table bboxes thanks to a opening filter.
/*!
*
* \param[in] input_ A binary image.
* \param[in] nbh_ The neighborhood used for labeling image components.
* \param[in] label_type The type used to store the labels.
- * \param[in] vwin Window used to extract the vertical lines in the rank
- * filter.
- * \param[in] hwin Window used to extract the horizontal lines in the rank
- * filter.
- * \param[in] vrank_k Rank used for vertical lines filtering.
- * \param[in] hrank_k Rank used for horizontal lines filtering.
+ * \param[in] vwin Window used to extract the vertical lines in a morphological
+ * opening
+ * \param[in] hwin Window used to extract the horizontal lines in a morphological
+ * opening
*
* \return pair of array of bounding boxes. The first array holds the
* vertical lines bounding boxes and the second one the
@@ -76,45 +76,58 @@ namespace scribo
template <typename I, typename N, typename V, typename HW, typename VW>
util::couple<util::array<box<mln_site(I)> >,
util::array<box<mln_site(I)> > >
- extract_lines_with_rank(const Image<I>& input_,
- const Neighborhood<N>& nbh_, const V& label_type,
- const Window<HW>& vwin, const Window<VW>& hwin,
- unsigned vrank_k, unsigned hrank_k);
+ extract_lines_with_opening(const Image<I>& input_,
+ const Neighborhood<N>& nbh_, const V& label_type,
+ const Window<HW>& vwin, const Window<VW>& hwin);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V, typename HW, typename VW>
+ template <typename I, typename N, typename V, typename VW, typename HW>
inline
util::couple<util::array<box<mln_site(I)> >,
util::array<box<mln_site(I)> > >
- extract_lines_with_rank(const Image<I>& input_,
+ extract_lines_with_opening(const Image<I>& input_,
const Neighborhood<N>& nbh_, const V& label_type,
- const Window<HW>& vwin, const Window<VW>& hwin,
- unsigned vrank_k, unsigned hrank_k)
+ const Window<VW>& vwin_, const Window<HW>& hwin_);
{
- trace::entering("scribo::table::extract_lines_with_rank");
+ trace::entering("scribo::table::extract_lines_with_opening");
mlc_equal(mln_value(I),bool)::check();
mlc_is_a(V, mln::value::Symbolic)::check();
+
const I& input = exact(input_);
const N& nbh = exact(nbh_);
+ const VW& vwin = exact(vwin_);
+ const HW& hwin = exact(hwin_);
+
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
- mln_precondition(exact(vwin).is_valid());
- mln_precondition(exact(hwin).is_valid());
+ mln_precondition(vwin.is_valid());
+ mln_precondition(hwin.is_valid());
typedef accu::bbox<mln_psite(I)> A;
typedef util::array<mln_result(A)> boxes_t;
// Vertical lines
- mln_ch_value(I,bool) vfilter = morpho::rank_filter(input, vwin, vrank_k);
+ mln_ch_value(I,bool) vfilter = morpho::erosion(input, vwin);
boxes_t vboxes = component_bboxes(vfilter, nbh, label_type);
+ for_all_components(i, vboxes)
+ {
+ vboxes[i].enlarge(0, vwin.length() / 2);
+ vboxes[i].crop_wrt(input.domain());
+ }
// Horizontal lines.
- mln_ch_value(I,bool) hfilter = morpho::rank_filter(input, hwin, hrank_k);
+ mln_ch_value(I,bool) hfilter = morpho::erosion(input, hwin);
boxes_t hboxes = component_bboxes(hfilter, nbh, label_type);
+ for_all_components(i, hboxes)
+ {
+ hboxes[i].enlarge(1, hwin.length() / 2);
+ hboxes[i].crop_wrt(input.domain());
+ }
+ trace::exiting("scribo::table::extract_lines_with_opening");
return mln::make::couple(vboxes, hboxes);
}
@@ -124,4 +137,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_TABLE_EXTRACT_LINES_WITH_RANK_HH
+#endif // ! SCRIBO_TABLE_EXTRACT_LINES_WITH_OPENING_HH
diff --git a/milena/sandbox/scribo/table/extract_lines_with_rank.hh b/milena/sandbox/scribo/table/extract_lines_with_rank.hh
index 242dc30..63c90b1 100644
--- a/milena/sandbox/scribo/table/extract_lines_with_rank.hh
+++ b/milena/sandbox/scribo/table/extract_lines_with_rank.hh
@@ -47,7 +47,7 @@
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
-
+# include <scribo/core/macros.hh>
# include <scribo/core/component_bboxes.hh>
namespace scribo
@@ -56,6 +56,8 @@ namespace scribo
namespace table
{
+ using namespace mln;
+
/// Find table bboxes thanks to a rank filter.
/*!
*
@@ -84,25 +86,29 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V, typename HW, typename VW>
+ template <typename I, typename N, typename V, typename VW, typename HW>
inline
util::couple<util::array<box<mln_site(I)> >,
util::array<box<mln_site(I)> > >
extract_lines_with_rank(const Image<I>& input_,
const Neighborhood<N>& nbh_, const V& label_type,
- const Window<HW>& vwin, const Window<VW>& hwin,
+ const Window<VW>& vwin_, const Window<HW>& hwin_,
unsigned vrank_k, unsigned hrank_k)
{
trace::entering("scribo::table::extract_lines_with_rank");
mlc_equal(mln_value(I),bool)::check();
mlc_is_a(V, mln::value::Symbolic)::check();
+
const I& input = exact(input_);
const N& nbh = exact(nbh_);
+ const VW& vwin = exact(vwin_);
+ const HW& hwin = exact(hwin_);
+
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
- mln_precondition(exact(vwin).is_valid());
- mln_precondition(exact(hwin).is_valid());
+ mln_precondition(vwin.is_valid());
+ mln_precondition(hwin.is_valid());
typedef accu::bbox<mln_psite(I)> A;
typedef util::array<mln_result(A)> boxes_t;
@@ -110,11 +116,22 @@ namespace scribo
// Vertical lines
mln_ch_value(I,bool) vfilter = morpho::rank_filter(input, vwin, vrank_k);
boxes_t vboxes = component_bboxes(vfilter, nbh, label_type);
+ for_all_components(i, vboxes)
+ {
+ vboxes[i].enlarge(0, vwin.length() / 2);
+ vboxes[i].crop_wrt(input.domain());
+ }
// Horizontal lines.
mln_ch_value(I,bool) hfilter = morpho::rank_filter(input, hwin, hrank_k);
boxes_t hboxes = component_bboxes(hfilter, nbh, label_type);
+ for_all_components(i, hboxes)
+ {
+ hboxes[i].enlarge(1, hwin.length() / 2);
+ hboxes[i].crop_wrt(input.domain());
+ }
+ trace::exiting("scribo::table::extract_lines_with_rank");
return mln::make::couple(vboxes, hboxes);
}
diff --git a/milena/sandbox/scribo/table/internal/align_lines.hh b/milena/sandbox/scribo/table/internal/align_lines.hh
index aaad9fa..202b2dd 100644
--- a/milena/sandbox/scribo/table/internal/align_lines.hh
+++ b/milena/sandbox/scribo/table/internal/align_lines.hh
@@ -51,6 +51,8 @@ namespace scribo
namespace internal
{
+ using namespace mln;
+
/// Align table lines bboxes according to a given dimension.
///
/// \return A list of the resulting aligned cols. Each integer is actually
@@ -102,7 +104,8 @@ namespace scribo
int min_coord,
int max_coord,
util::array<box<P> >& line_boxes,
- unsigned dim)
+ unsigned dim,
+ unsigned max_alignment_diff)
{
trace::entering("scribo::internal::align_lines");
@@ -114,9 +117,9 @@ namespace scribo
// Map components with actual lines.
for_all_components(i, line_boxes)
{
- int minline = line_boxes[i].pmin()[dim] - 5;
+ int minline = line_boxes[i].pmin()[dim] - max_alignment_diff;
minline = (minline < min_coord ? min_coord : minline);
- int maxline = line_boxes[i].pmax()[dim] + 5;
+ int maxline = line_boxes[i].pmax()[dim] + max_alignment_diff;
maxline = (maxline > max_coord ? max_coord : maxline);
for (int line = minline;
diff --git a/milena/sandbox/scribo/table/internal/connect_lines.hh b/milena/sandbox/scribo/table/internal/connect_lines.hh
index d510fe2..08f395f 100644
--- a/milena/sandbox/scribo/table/internal/connect_lines.hh
+++ b/milena/sandbox/scribo/table/internal/connect_lines.hh
@@ -35,6 +35,7 @@
/// Connect vertical lines with aligned rows.
# include <mln/core/image/image1d.hh>
+# include <mln/core/alias/neighb1d.hh>
# include <mln/data/fill.hh>
@@ -45,7 +46,7 @@
# include <mln/opt/at.hh>
# include <scribo/core/macros.hh>
-
+# include <scribo/core/central_sites.hh>
namespace scribo
{
@@ -56,6 +57,8 @@ namespace scribo
namespace internal
{
+ using namespace mln;
+
/// Connect vertical and horizontal lines if they are close to each other.
///
/// ------ ------
@@ -70,7 +73,8 @@ namespace scribo
connect_lines(const util::array<int>& aligned_lines,
util::array< box<P> >& boxes,
unsigned dim,
- unsigned dim_size);
+ unsigned dim_size,
+ unsigned max_distance);
# ifndef MLN_INCLUDE_ONLY
@@ -81,7 +85,8 @@ namespace scribo
connect_lines(const util::array<int>& aligned_lines,
util::array< box<P> >& boxes,
unsigned dim,
- unsigned dim_size)
+ unsigned dim_size,
+ unsigned max_distance)
{
trace::entering("scribo::table::internal::connect_lines");
@@ -91,12 +96,12 @@ namespace scribo
for_all_elements(i, aligned_lines)
opt::at(l, aligned_lines[i]) = i;
- for (unsigned i = 0; i < settings.max_dist_lines; ++i)
+ for (unsigned i = 0; i < max_distance; ++i)
l = morpho::elementary::dilation(l, c2());
for_all_components(i, boxes)
{
- util::couple<point2d, point2d> cp = central_sites(boxes[i], dim);
+ util::couple<P,P> cp = central_sites(boxes[i], dim);
if (opt::at(l, cp.first()[dim]) != -1)
boxes[i].pmin()[dim] = aligned_lines[opt::at(l, cp.first()[dim])];
if (opt::at(l, cp.second()[dim]) != -1)
@@ -110,6 +115,8 @@ namespace scribo
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace scribo::table::internal
+
} // end of namespace scribo::table
} // end of namespace scribo
diff --git a/milena/sandbox/scribo/table/internal/repair_lines.hh b/milena/sandbox/scribo/table/internal/repair_lines.hh
index 87f0933..cf21564 100644
--- a/milena/sandbox/scribo/table/internal/repair_lines.hh
+++ b/milena/sandbox/scribo/table/internal/repair_lines.hh
@@ -41,10 +41,17 @@
# include <mln/data/fill.hh>
# include <mln/util/couple.hh>
# include <mln/util/array.hh>
+# include <mln/util/ord.hh>
# include <mln/win/line.hh>
# include <mln/pw/all.hh>
+# include <mln/debug/colorize.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/value/label_16.hh>
+# include <scribo/make/debug_filename.hh>
+
# include <scribo/core/central_sites.hh>
+# include <scribo/core/macros.hh>
# include <scribo/table/internal/repair_lines.hh>
@@ -57,15 +64,23 @@ namespace scribo
namespace internal
{
+ /// Repair lines which have small discontinuities.
+ /// FIXME: buggy. Sometimes few lines move or shrink!
+ template <unsigned axis, typename I>
+ void
+ repair_lines(const Image<I>& input_,
+ util::array<box<mln_site(I)> >& tableboxes,
+ unsigned max_discontinuity);
+
# ifndef MLN_INCLUDE_ONLY
- /// Repair lines which have small discontinuities.
- /// FIXME: buggy. Sometimes few lines move or shrink!
+
template <unsigned axis, typename I>
void
repair_lines(const Image<I>& input_,
- util::array<box<mln_site(I)> >& tableboxes)
+ util::array<box<mln_site(I)> >& tableboxes,
+ unsigned max_discontinuity)
{
trace::entering("scribo::table::internal::repair_lines");
@@ -76,7 +91,7 @@ namespace scribo
typedef win::line<mln_grid(P), axis, mln_coord(P)> line_t;
// Initialization
- mln_ch_value(I,unsigned) l(input.domain());
+ mln_ch_value(I,value::label_16) l(input.domain());
data::fill(l, literal::zero);
for_all_components(i, tableboxes)
{
@@ -86,28 +101,52 @@ namespace scribo
}
// Repair
- extension_val<mln_ch_value(I,unsigned)> l_ext(l, literal::zero);
+ extension_val<mln_ch_value(I,value::label_16)> l_ext(l, literal::zero);
util::array<box<P> > result;
std::vector<bool> to_keep(tableboxes.nelements(), true);
- mln_VAR(tbb_ima, extend(l | pw::value(l) != literal::zero, l));
+ mln_VAR(tbb_ima, extend(l | pw::value(l) != pw::cst(literal::zero), l));
//FIXME: use a half window, just the bottom of the vertical line.
- line_t vl(settings.repair_max_dist);
+ line_t vl(max_discontinuity);
mln_piter(tbb_ima_t) p(tbb_ima.domain());
mln_qiter(line_t) q(vl, p);
for_all(p)
+ {
+ util::couple<P,P> cp_p = central_sites(tableboxes[l_ext(p)], axis);
for_all(q)
if (l_ext(q) != literal::zero && l_ext(q) != l_ext(p))
{
- to_keep[l_ext(q)] = false;
-
- tableboxes[l_ext(p)].pmax() = tableboxes[l_ext(q)].pmax();
-
- util::couple<P,P> cp = central_sites(tableboxes[l_ext(q)], axis);
- l_ext(cp.first()) = l_ext(p);
- l_ext(cp.second()) = l_ext(p);
+ if (util::ord_strict(tableboxes[l_ext(p)].pmax(),
+ tableboxes[l_ext(q)].pmax()))
+ {
+ tableboxes[l_ext(p)].pmax() = tableboxes[l_ext(q)].pmax();
+ to_keep[l_ext(q)] = false;
+ }
+
+ if (util::ord_strict(tableboxes[l_ext(q)].pmin(),
+ tableboxes[l_ext(p)].pmin()))
+ {
+ tableboxes[l_ext(p)].pmin() = tableboxes[l_ext(q)].pmin();
+ to_keep[l_ext(q)] = false;
+ }
+
+ if (!to_keep[l_ext(q)])
+ {
+ util::couple<P,P> cp_q = central_sites(tableboxes[l_ext(q)], axis);
+ l_ext(cp_q.first()) = literal::zero;
+ l_ext(cp_q.second()) = literal::zero;
+
+ unsigned p_i = l_ext(p);
+ l_ext(cp_p.first()) = literal::zero;
+ l_ext(cp_p.second()) = literal::zero;
+
+ util::couple<P,P> new_cp_p = central_sites(tableboxes[p_i], axis);
+ l_ext(new_cp_p.first()) = p_i;
+ l_ext(new_cp_p.second()) = p_i;
+ }
}
+ }
// Remove merged boxes.
diff --git a/milena/sandbox/scribo/table/rebuild.hh b/milena/sandbox/scribo/table/rebuild.hh
new file mode 100644
index 0000000..b78112d
--- /dev/null
+++ b/milena/sandbox/scribo/table/rebuild.hh
@@ -0,0 +1,147 @@
+// Copyright (C) 2009 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 SCRIBO_TABLE_REBUILD_HH
+# define SCRIBO_TABLE_REBUILD_HH
+
+/// \file scribo/table/rebuild.hh
+///
+/// Rebuild a table from its line bounding boxes.
+
+# include <mln/core/concept/image.hh>
+# include <mln/labeling/background.hh>
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+# include <mln/value/label_8.hh>
+
+# include <scribo/table/align_lines_verticaly.hh>
+# include <scribo/table/align_lines_horizontaly.hh>
+# include <scribo/table/connect_vertical_lines.hh>
+# include <scribo/table/connect_horizontal_lines.hh>
+# include <scribo/table/repair_horizontal_lines.hh>
+# include <scribo/table/repair_vertical_lines.hh>
+
+# include <scribo/debug/save_table_image.hh>
+
+
+
+namespace scribo
+{
+
+ namespace table
+ {
+
+ template <typename I, typename V>
+ mln_ch_value(I,V)
+ rebuild(const Image<I>& in_,
+ const util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > >& lineboxes,
+ unsigned max_dist_lines,
+ V& ncells);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename V>
+ mln_ch_value(I,V)
+ rebuild(const Image<I>& in_,
+ const util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > >& lineboxes,
+ unsigned max_dist_lines,
+ V& ncells)
+ {
+ trace::entering("scribo::table::rebuild");
+ const I& in = exact(in_);
+
+ mlc_equal(mln_value(I), bool)::check();
+ mln_precondition(in.is_valid());
+
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > > tblboxes = lineboxes;
+
+//# ifndef SCRIBO_NDEBUG
+// scribo::debug::save_table_image(in, tblboxes,
+// literal::red, "table.ppm");
+//# endif
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-raw.ppm");
+
+ util::array<int> rows = align_lines_horizontaly(in, tblboxes.second(), 5);
+ util::array<int> cols = align_lines_verticaly(in, tblboxes.first(), 5);
+
+# ifndef SCRIBO_NDEBUG
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-aligned.ppm");
+# endif
+
+ repair_vertical_lines(in, tblboxes, 30);
+ repair_horizontal_lines(in, tblboxes, 30);
+
+# ifndef SCRIBO_NDEBUG
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-repaired.ppm");
+# endif
+
+ // Connect vertical lines with horizontal lines.
+ connect_vertical_lines(rows, tblboxes, in, max_dist_lines);
+ connect_horizontal_lines(cols, tblboxes, in, max_dist_lines);
+
+# ifndef SCRIBO_NDEBUG
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-connected.ppm");
+# endif
+
+
+ mln_ch_value(I,bool) res;
+ initialize(res, in);
+ data::fill(res, false);
+ for_all_components(i, tblboxes.first())
+ mln::draw::box(res, tblboxes.first()[i], true);
+ for_all_components(i, tblboxes.second())
+ mln::draw::box(res, tblboxes.second()[i], true);
+
+ mln_ch_value(I,V) lbl = labeling::background(res, c8(), ncells);
+
+//# ifndef SCRIBO_NDEBUG
+// scribo::debug::save_table_image(in, tblboxes,
+// literal::red, "table-connected.ppm");
+//# endif
+
+ trace::exiting("scribo::table::rebuild");
+ return lbl;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::table
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_TABLE_REBUILD_HH
diff --git a/milena/sandbox/scribo/table/repair_horizontal_lines.hh b/milena/sandbox/scribo/table/repair_horizontal_lines.hh
index 7c1edbd..e871480 100644
--- a/milena/sandbox/scribo/table/repair_horizontal_lines.hh
+++ b/milena/sandbox/scribo/table/repair_horizontal_lines.hh
@@ -59,9 +59,9 @@ namespace scribo
template <typename I>
void
repair_horizontal_lines(const Image<I>& input,
- util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > >& tableboxes,
- unsigned max_discontinuity);
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > >& tableboxes,
+ unsigned max_discontinuity);
# ifndef MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc b/milena/sandbox/scribo/tests/filter/small_and_large_bboxes.cc
similarity index 87%
copy from milena/sandbox/scribo/src/extract_text_multiple_links.cc
copy to milena/sandbox/scribo/tests/filter/small_and_large_bboxes.cc
index 9b181e6..2cf7ebc 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/tests/filter/small_and_large_bboxes.cc
@@ -32,6 +32,7 @@
#include <scribo/text/extract_bboxes.hh>
#include <scribo/text/grouping/group_with_multiple_links.hh>
#include <scribo/text/grouping/group_from_multiple_links.hh>
+#include <scribo/filter/small_components.hh>
#include <scribo/debug/save_textbboxes_image.hh>
#include <scribo/debug/save_linked_textbboxes_image.hh>
@@ -50,6 +51,8 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = argv[0];
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
@@ -66,7 +69,7 @@ int main(int argc, char* argv[])
literal::red, literal::cyan,
"test_multiple_links_left_linked.ppm");
- util::array< box<point2d> > grouped_textbboxes
+ util::array<box2d> grouped_textbboxes
= text::grouping::group_from_multiple_links(textbboxes, g);
std::cout << "AFTER - nbboxes = " << grouped_textbboxes.nelements() << std::endl;
@@ -74,5 +77,13 @@ int main(int argc, char* argv[])
scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
literal::red,
"test_multiple_links_grouped_text.ppm");
+
+ util::array<box2d> filtered_textbboxes
+ = scribo::filter::small_components(grouped_textbboxes, 6);
+
+ scribo::debug::save_textbboxes_image(input, filtered_textbboxes,
+ literal::red,
+ "test_multiple_links_filtered_text.ppm");
+
}
diff --git a/milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc b/milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc
new file mode 100644
index 0000000..ed5ce3c
--- /dev/null
+++ b/milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc
@@ -0,0 +1,36 @@
+#include <mln/essential/2d.hh>
+#include <scribo/table/extract_lines_with_rank.hh>
+#include <scribo/debug/save_table_image.hh>
+#include <mln/util/couple.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc < 2)
+ {
+ std::cout << "Usage: " << argv[0] << " <image.pbm>" << std::endl;
+ return 1;
+ }
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ typedef util::couple<util::array<box2d>,
+ util::array<box2d> > tblboxes_t;
+
+ tblboxes_t lineboxes;
+ lineboxes.first().append(make::box2d(0,0, 59,59));
+ lineboxes.first().append(make::box2d(0,28, 27, 32));
+ lineboxes.first().append(make::box2d(31,28, 59,32));
+ lineboxes.second().append(make::box2d(0,0, 59,59));
+ lineboxes.second().append(make::box2d(27,0, 31, 26));
+ lineboxes.second().append(make::box2d(27,34, 31,59));
+
+
+ tblboxes_t lineboxes_test = scribo::table::extract_lines_with_rank(input, c8(),
+ value::label_16(), win::vline2d(11),
+ win::hline2d(11), 2, 2);
+
+ mln_assertion(lineboxes == lineboxes_test);
+}
diff --git a/milena/sandbox/scribo/tests/table/repair_lines.cc b/milena/sandbox/scribo/tests/table/repair_lines.cc
new file mode 100644
index 0000000..ff5551c
--- /dev/null
+++ b/milena/sandbox/scribo/tests/table/repair_lines.cc
@@ -0,0 +1,45 @@
+#include <mln/essential/2d.hh>
+#include <scribo/table/repair_vertical_lines.hh>
+#include <scribo/table/repair_horizontal_lines.hh>
+#include <scribo/table/extract_lines_with_rank.hh>
+#include <scribo/debug/save_table_image.hh>
+#include <mln/util/couple.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc < 2)
+ {
+ std::cout << "Usage: " << argv[0] << " <image.pbm>" << std::endl;
+ return 1;
+ }
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ typedef util::couple<util::array<box2d>,
+ util::array<box2d> > tblboxes_t;
+
+ tblboxes_t lineboxes;
+ lineboxes.first().append(make::box2d(0,0, 1,1)); // Dummy value for component 0.
+ lineboxes.first().append(make::box2d(0,28, 27, 32));
+ lineboxes.first().append(make::box2d(31,28, 59,32));
+ lineboxes.second().append(make::box2d(0,0, 1,1)); // Dummy value for component 0.
+ lineboxes.second().append(make::box2d(27,0, 31, 26));
+ lineboxes.second().append(make::box2d(27,34, 31,59));
+
+
+// tblboxes_t lineboxes = scribo::table::extract_lines_with_rank(input, c8(), value::label_16(), win::vline2d(11), win::hline2d(11), 2, 2);
+//
+// std::cout << lineboxes.first() << std::endl;
+// std::cout << lineboxes.second() << std::endl;
+
+ scribo::table::repair_vertical_lines(input, lineboxes, 31);
+ scribo::table::repair_horizontal_lines(input, lineboxes, 31);
+
+ mln_assertion(lineboxes.first().nelements() == 2);
+ mln_assertion(lineboxes.second().nelements() == 2);
+ mln_assertion(lineboxes.first()[1] == make::box2d(0,28, 59,32));
+ mln_assertion(lineboxes.second()[1] == make::box2d(27,0, 31,59));
+}
diff --git a/milena/sandbox/scribo/text/extract_bboxes.hh b/milena/sandbox/scribo/text/extract_bboxes.hh
index 0c88880..4a936b5 100644
--- a/milena/sandbox/scribo/text/extract_bboxes.hh
+++ b/milena/sandbox/scribo/text/extract_bboxes.hh
@@ -42,6 +42,8 @@
# include <mln/util/array.hh>
# include <scribo/core/component_bboxes.hh>
+# include <scribo/util/text.hh>
+# include <scribo/make/text.hh>
namespace scribo
{
@@ -58,8 +60,7 @@ namespace scribo
/// \return an array of bounding boxes. The first bounding box is
/// the background's.
template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
+ scribo::util::text<mln_ch_value(I,V)>
extract_bboxes(const Image<I>& input_,
const Neighborhood<N>& nbh, V& nbboxes);
@@ -68,7 +69,7 @@ namespace scribo
template <typename I, typename N, typename V>
inline
- util::array< box<mln_site(I)> >
+ scribo::util::text<mln_ch_value(I,V)>
extract_bboxes(const Image<I>& input_,
const Neighborhood<N>& nbh, V& nbboxes)
{
@@ -79,11 +80,13 @@ namespace scribo
mlc_equal(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
- typedef util::array< box<mln_site(I)> > bboxes_t;
- bboxes_t bboxes = component_bboxes(input, nbh, nbboxes);
+ typedef mln::util::array< box<mln_site(I)> > bboxes_t;
+ typedef mln::util::couple<bboxes_t, mln_ch_value(I,V)> bboxes_and_lbl_t;
+ bboxes_and_lbl_t bboxes_and_lbl = component_bboxes(input, nbh, nbboxes);
trace::exiting("scribo::text::extract_bboxes");
- return bboxes;
+ return scribo::make::text(bboxes_and_lbl.first(),
+ bboxes_and_lbl.second(), nbboxes);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/text/extract_lines.hh b/milena/sandbox/scribo/text/extract_lines.hh
new file mode 100644
index 0000000..6be2e37
--- /dev/null
+++ b/milena/sandbox/scribo/text/extract_lines.hh
@@ -0,0 +1,133 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_TEXT_EXTRACT_LINES_HH
+# define SCRIBO_TEXT_EXTRACT_LINES_HH
+
+/// \file scribo/text/extract_lines.hh
+///
+/// Extract line of text bounding boxes.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/site_set/box.hh>
+
+# include <mln/data/fill.hh>
+
+# include <mln/accu/bbox.hh>
+
+# include <mln/draw/box.hh>
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/compute.hh>
+
+# include <mln/util/array.hh>
+# include <mln/util/graph.hh>
+# include <mln/value/label_16.hh>
+
+# include <scribo/text/grouping/group_with_multiple_links.hh>
+# include <scribo/text/grouping/group_from_multiple_links.hh>
+# include <scribo/filter/small_components.hh>
+# include <scribo/util/text.hh>
+
+# include <scribo/debug/save_textbboxes_image.hh>
+# include <scribo/debug/save_linked_textbboxes_image.hh>
+
+namespace scribo
+{
+
+ namespace text
+ {
+
+ using namespace mln;
+
+
+ template <typename I, typename N, typename V>
+ scribo::util::text<mln_ch_value(I,V)>
+ extract_lines(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ V& nbboxes);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename N, typename V>
+ scribo::util::text<mln_ch_value(I,V)>
+ extract_lines(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ V& nbboxes)
+ {
+ trace::entering("scribo::text::extract_lines");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ scribo::util::text<mln_ch_value(I,V)> text
+ = scribo::make::text(input, nbh, nbboxes);
+
+# ifndef SCRIBO_NDEBUG
+ debug::save_textbboxes_image(input, text.bboxes(), literal::red,
+ scrib::make::debug_filename("character-bboxes.ppm"));
+# endif // ! SCRIBO_NDEBUG
+
+ //Link character bboxes to their left neighboor if possible.
+ mln::util::graph g
+ = text::grouping::group_with_multiple_links(text, 30);
+# ifndef SCRIBO_NDEBUG
+ debug::save_linked_textbboxes_image(input,
+ text, g,
+ literal::red, literal::cyan,
+ scribo::make::debug_filename("multiple_links_left_linked.ppm"));
+# endif // ! SCRIBO_NDEBUG
+
+ //Merge character bboxes through a graph.
+ scribo::util::text<mln_ch_value(I,V)> grouped_text
+ = text::grouping::group_from_multiple_links(text, g);
+
+# ifndef SCRIBO_NDEBUG
+ debug::save_textbboxes_image(input, grouped_text.bboxes(),
+ literal::red,
+ scribo::make::debug_filename("multiple_links_grouped_text.ppm"));
+# endif // ! SCRIBO_NDEBUG
+
+
+ trace::exiting("scribo::text::extract_lines");
+ return grouped_text;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::text
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_TEXT_EXTRACT_LINES_HH
+
diff --git a/milena/sandbox/scribo/text/grouping/group_from_double_link.hh b/milena/sandbox/scribo/text/grouping/group_from_double_link.hh
index d178a80..582abcd 100644
--- a/milena/sandbox/scribo/text/grouping/group_from_double_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_from_double_link.hh
@@ -41,10 +41,14 @@
# include <mln/util/array.hh>
+# include <mln/fun/l2l/relabel.hh>
+
# include <scribo/text/grouping/internal/find_root.hh>
# include <scribo/core/macros.hh>
+# include <scribo/util/text.hh>
+
namespace scribo
{
@@ -56,42 +60,67 @@ namespace scribo
{
/// FIXME: Add much more doc!
- template <typename P>
- util::array< box<P> >
- group_from_double_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& left_link,
- util::array<unsigned>& right_link);
+ template <typename I>
+ scribo::util::text<I>
+ group_from_double_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link);
# ifndef MLN_INCLUDE_ONLY
- template <typename P>
+ template <typename I>
inline
- util::array< box<P> >
- group_from_double_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& left_link,
- util::array<unsigned>& right_link)
+ scribo::util::text<I>
+ group_from_double_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link)
{
trace::entering("scribo::text::grouping::group_from_double_link");
mln_precondition(left_link.nelements() == right_link.nelements());
- util::array< accu::bbox<P> > tboxes;
- tboxes.resize(textbboxes.nelements());
- for_all_components(i, textbboxes)
+ mln::util::array< accu::bbox<mln_site(I)> > tboxes;
+ tboxes.resize(text.bboxes().nelements());
+
+ mln::util::array<unsigned> left_parent = left_link;
+ for_all_components(i, left_parent)
+ left_parent[i] = internal::find_root(left_parent, i);
+
+ fun::i2v::array<mln_value(I)> f(text.bboxes().nelements(),
+ literal::zero);
+ for_all_components(i, text.bboxes())
{
unsigned nbh = right_link[left_link[i]];
if (nbh == i)
- tboxes[left_link[i]].take(textbboxes[i]);
+ {
+ tboxes[left_parent[i]].take(text.bbox(i));
+ f(i) = left_parent[left_link[i]];
+ }
else
- tboxes[i].take(textbboxes[i]);
+ {
+ f(i) = i;
+ tboxes[i].take(text.bbox(i));
+ }
}
- util::array< box<P> > result;
+ // Update bounding boxes information.
+ mln::util::array< box<mln_site(I)> > bresult;
// component 0, the background, has an invalid box.
- result.append(box<P>());
+ bresult.append(box<mln_site(I)>());
for_all_components(i, tboxes)
if (tboxes[i].is_valid())
- result.append(tboxes[i]);
+ bresult.append(tboxes[i]);
+
+ // Update label image.
+ mln_value(I) new_nbboxes;
+ I new_lbl = labeling::relabel(text.label_image(),
+ text.nbboxes(),
+ mln::make::relabelfun(f, text.nbboxes(),
+ new_nbboxes));
+
+ mln_assertion(bresult.nelements() == new_nbboxes.next());
+
+ scribo::util::text<I> result(bresult, new_lbl, new_nbboxes);
trace::exiting("scribo::text::grouping::group_from_double_link");
return result;
diff --git a/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh b/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh
index 612fb87..059fa22 100644
--- a/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh
+++ b/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh
@@ -47,6 +47,9 @@
# include <mln/util/array.hh>
# include <scribo/core/macros.hh>
+# include <scribo/util/text.hh>
+# include <scribo/make/text.hh>
+
namespace scribo
{
@@ -58,9 +61,9 @@ namespace scribo
{
/// FIXME: Add much more doc!
- template <typename G, typename P>
- util::array<box<P> >
- group_from_multiple_links(util::array<box<P> >& textbboxes,
+ template <typename I, typename G>
+ scribo::util::text<I>
+ group_from_multiple_links(const scribo::util::text<I>& text,
const Graph<G>& g_);
# ifndef MLN_INCLUDE_ONLY
@@ -71,14 +74,15 @@ namespace scribo
/// Functor to be passed to depth_first_search.
/// Map each component vertex with its representative vertex id.
+ template <typename V>
struct map_vertex_to_component_id_functor
{
- template <typename G>
- void init(const Graph<G>& g)
- {
- vertextocomp.resize(exact(g).v_nmax(), mln_max(unsigned));
- ncomp = 0;
- }
+ template <typename G>
+ void init(const Graph<G>& g)
+ {
+ vertextocomp.resize(exact(g).v_nmax(), mln_max(V));
+ ncomp = 0;
+ }
void final()
{}
@@ -96,23 +100,23 @@ namespace scribo
{}
bool to_be_treated(unsigned id)
- { return vertextocomp(id) == mln_max(unsigned); }
+ { return vertextocomp(id) == mln_max(V); }
bool to_be_queued(unsigned id)
{ return to_be_treated(id); }
unsigned ncomp;
- fun::i2v::array<unsigned> vertextocomp;
+ fun::l2l::relabel<V> vertextocomp;
};
} // end of namespace scribo::text::grouping::internal
- template <typename G, typename P>
+ template <typename I, typename G>
inline
- util::array<box<P> >
- group_from_multiple_links(util::array<box<P> >& textbboxes,
+ scribo::util::text<I>
+ group_from_multiple_links(const scribo::util::text<I>& text,
const Graph<G>& g_)
{
trace::entering("scribo::text::grouping::group_from_multiple_links");
@@ -121,25 +125,34 @@ namespace scribo
mln_assertion(g.is_valid());
- internal::map_vertex_to_component_id_functor f;
+ internal::map_vertex_to_component_id_functor<mln_value(I)> f;
canvas::browsing::depth_first_search(g, f);
- util::array< accu::bbox<P> > tboxes;
- tboxes.resize(textbboxes.nelements());
- for_all_components(i, textbboxes)
- tboxes[f.vertextocomp(i)].take(textbboxes[i]);
+ mln::util::array< accu::bbox<mln_site(I)> > tboxes;
+ tboxes.resize(text.nbboxes().next());
+ for_all_components(i, text.bboxes())
+ tboxes[f.vertextocomp(i)].take(text.bbox(i));
- util::array< box<P> > result;
+ // Update bounding boxes.
+ mln::util::array<box<mln_site(I)> > bresult;
// Component 0 - the background has not valid bboxes.
- result.append(box<P>());
- for_all_components(i, textbboxes)
+ bresult.append(box<mln_site(I)>());
+ for_all_components(i, text.bboxes())
if (tboxes[i].is_valid())
- result.append(tboxes[i].to_result());
+ bresult.append(tboxes[i].to_result());
+
+ mln_assertion(bresult.nelements() == f.ncomp);
+
+ // Update label image.
+ mln_value(I) new_nbboxes;
+ I new_lbl = labeling::relabel(text.label_image(),
+ text.nbboxes(),
+ f.vertextocomp);
- mln_assertion(result.nelements() == f.ncomp);
+ mln_assertion(new_nbboxes.next() == bresult.nelements());
trace::exiting("scribo::text::grouping::group_from_multiple_links");
- return result;
+ return scribo::make::text(bresult, new_lbl, new_nbboxes);
}
diff --git a/milena/sandbox/scribo/text/grouping/group_from_single_link.hh b/milena/sandbox/scribo/text/grouping/group_from_single_link.hh
index eccde96..43bb7b1 100644
--- a/milena/sandbox/scribo/text/grouping/group_from_single_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_from_single_link.hh
@@ -44,6 +44,7 @@
# include <scribo/text/grouping/internal/find_root.hh>
# include <scribo/core/macros.hh>
+# include <scribo/util/text.hh>
namespace scribo
@@ -56,38 +57,46 @@ namespace scribo
{
/// FIXME: Add much more doc!
- template <typename P>
- util::array< box<P> >
- group_from_single_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& link_array);
+ template <typename I>
+ scribo::util::text<I>
+ group_from_single_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& link_array);
# ifndef MLN_INCLUDE_ONLY
- template <typename P>
+ template <typename I>
inline
- util::array< box<P> >
- group_from_single_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& link_array)
+ scribo::util::text<I>
+ group_from_single_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& link_array)
{
trace::entering("scribo::text::grouping::group_from_single_link");
- for (unsigned i = 0; i < link_array.nelements(); ++i)
- link_array[i] = internal::find_root(link_array, i);
+ mln_precondition(text.is_valid());
+ mln_precondition(link_array.nelements() == text.nbboxes().next());
+ mln_precondition(link_array.nelements() == text.bboxes().nelements());
- util::array< accu::bbox<P> > tboxes;
- tboxes.resize(textbboxes.nelements());
- for_all_components(i, textbboxes)
- tboxes[link_array[i]].take(textbboxes[i]);
+ mln::util::array<unsigned> parent_array = link_array;
+ for_all_components(i, parent_array)
+ internal::find_root(parent_array, i);
- util::array< box<P> > result;
+ mln::util::array< accu::bbox<mln_site(I)> > tboxes;
+ tboxes.resize(text.nbboxes().next());
+ for_all_components(i, text.bboxes())
+ tboxes[parent_array[i]].take(text.bbox(i));
+
+ mln::util::array< box<mln_site(I)> > result;
// component 0, the background, has an invalid box.
- result.append(box<P>());
+ result.append(box<mln_site(I)>());
for_all_components(i, tboxes)
if (tboxes[i].is_valid())
result.append(tboxes[i]);
+ I lbl = labeling::relabel(text.label_image(), text.nbboxes(),
+ convert::to<fun::l2l::relabel<mln_value(I)> >(parent_array));
+ mln_value(I) new_nbboxes = result.nelements() - 1;
trace::exiting("scribo::text::grouping::group_from_single_link");
- return result;
+ return scribo::make::text(result, lbl, new_nbboxes);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh b/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh
index 2f769fc..236cf16 100644
--- a/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh
+++ b/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh
@@ -43,6 +43,7 @@
# include <scribo/core/macros.hh>
# include <scribo/text/grouping/internal/init_link_array.hh>
# include <scribo/text/grouping/internal/update_link_graph.hh>
+# include <scribo/util/text.hh>
namespace scribo
{
@@ -55,44 +56,34 @@ namespace scribo
/// Group character bounding boxes with multiple links.
/// Look up for neighbors on the left of each box.
- template <typename I, typename N, typename V>
- util::graph
- group_with_multiple_links(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array<box<mln_site(I)> >& textbboxes,
+ template <typename I>
+ mln::util::graph
+ group_with_multiple_links(const scribo::util::text<I>& text,
unsigned neighb_max_distance);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V>
- util::graph
- group_with_multiple_links(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array<box<mln_site(I)> >& textbboxes,
+ template <typename I>
+ inline
+ mln::util::graph
+ group_with_multiple_links(const scribo::util::text<I>& text,
unsigned neighb_max_distance)
{
trace::entering("scribo::text::grouping::group_with_multiple_links");
- const I& input = exact(input_);
+ mln::util::graph g(text.nbboxes().next());
- mlc_equal(mln_value(I), bool)::check();
- mln_assertion(input.is_valid());
-
- typedef mln_ch_value(I,V) lbl_t;
- lbl_t lbl = labeling::blobs(input, nbh, nbboxes);
-
- util::graph g(nbboxes.next());
-
- for_all_ncomponents(i, nbboxes)
+ for_all_ncomponents(i, text.nbboxes())
{
- unsigned midcol = (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ unsigned midcol = (text.bbox(i).pmax().col()
+ - text.bbox(i).pmin().col()) / 2;
int dmax = midcol + neighb_max_distance;
- mln_site(I) c = textbboxes[i].center();
+ mln_site(I) c = text.bbox(i).center();
/// First site on the right of the central site
mln_site(I) p = c + right;
+ const I& lbl = text.label_image();
while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i)
&& math::abs(p.col() - c.col()) < dmax)
++p.col();
diff --git a/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh b/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh
index f1a3013..ca1a8da 100644
--- a/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh
@@ -46,6 +46,8 @@
# include <scribo/core/macros.hh>
# include <scribo/text/grouping/internal/init_link_array.hh>
# include <scribo/text/grouping/internal/update_link_array.hh>
+# include <scribo/text/grouping/internal/find_root.hh>
+# include <scribo/util/text.hh>
//FIXME: not generic.
# include <mln/core/alias/dpoint2d.hh>
@@ -63,46 +65,34 @@ namespace scribo
/// if possible.
/// Iterate to the right but link boxes to the left.
///
- /// \return an util::array. Map a bounding box to its left neighbor.
- template <typename I, typename N, typename V>
+ /// \return an mln::util::array. Map a bounding box to its left neighbor.
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_left_link(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_left_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V>
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_left_link(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_left_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance)
{
trace::entering("scribo::text::grouping::group_with_single_left_link");
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
+ mln_precondition(text.is_valid());
- mlc_equal(mln_value(I), bool)::check();
- mln_assertion(input.is_valid());
- mln_precondition(nbh.is_valid());
-
- typedef mln_ch_value(I,V) lbl_t;
- lbl_t lbl = labeling::blobs(input, nbh, nbboxes);
-
- util::array<unsigned> left_link(nbboxes.next());
+ mln::util::array<unsigned> left_link(text.nbboxes().next());
internal::init_link_array(left_link);
- for_all_ncomponents(i, nbboxes)
+ for_all_ncomponents(i, text.nbboxes())
{
- unsigned midcol = (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ unsigned midcol = (text.bbox(i).pmax().col()
+ - text.bbox(i).pmin().col()) / 2;
int dmax = midcol + neighb_max_distance;
- mln_site(I) c = textbboxes[i].center();
+ mln_site(L) c = text.bbox(i).center();
///
/// Find a neighbor on the right
@@ -110,14 +100,15 @@ namespace scribo
///FIXME: the following code is not generic...
/// First site on the right of the central site
- mln_site(I) p = c + right;
+ mln_site(L) p = c + right;
- while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i)
+ const L& lbl = text.label_image();
+ while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i ||
+ left_link[i] == lbl(p))
&& math::abs(p.col() - c.col()) < dmax)
++p.col();
internal::update_link_array(lbl, left_link, p, c, i, dmax);
-
}
trace::exiting("scribo::text::grouping::group_with_single_left_link");
diff --git a/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh b/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh
index 7f1eeac..5740b09 100644
--- a/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh
@@ -46,6 +46,8 @@
# include <scribo/core/macros.hh>
# include <scribo/text/grouping/internal/init_link_array.hh>
# include <scribo/text/grouping/internal/update_link_array.hh>
+# include <scribo/text/grouping/internal/find_root.hh>
+# include <scribo/util/text.hh>
//FIXME: not generic.
# include <mln/core/alias/dpoint2d.hh>
@@ -63,46 +65,34 @@ namespace scribo
/// if possible.
/// Iterate to the right but link boxes to the right.
///
- /// \return an util::array. Map a bounding box to its right neighbor.
- template <typename I, typename N, typename V>
+ /// \return an mln::util::array. Map a bounding box to its right neighbor.
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_right_link(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_right_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V>
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_right_link(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_right_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance)
{
trace::entering("scribo::text::grouping::group_with_single_right_link");
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
+ mln_precondition(text.is_valid());
- mlc_equal(mln_value(I), bool)::check();
- mln_assertion(input.is_valid());
- mln_precondition(nbh.is_valid());
-
- typedef mln_ch_value(I,V) lbl_t;
- lbl_t lbl = labeling::blobs(input, nbh, nbboxes);
-
- util::array<unsigned> right_link(nbboxes.next());
+ mln::util::array<unsigned> right_link(text.nbboxes().next());
internal::init_link_array(right_link);
- for_all_ncomponents(i, nbboxes)
+ for_all_ncomponents(i, text.nbboxes())
{
- unsigned midcol = (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ unsigned midcol = (text.bbox(i).pmax().col()
+ - text.bbox(i).pmin().col()) / 2;
int dmax = midcol + neighb_max_distance;
- mln_site(I) c = textbboxes[i].center();
+ mln_site(L) c = text.bbox(i).center();
///
/// Find a neighbor on the left
@@ -110,14 +100,15 @@ namespace scribo
///FIXME: the following code is not generic...
/// First site on the left of the central site
- mln_site(I) p = c + left;
+ mln_site(L) p = c + left;
- while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i)
- && math::abs(p.col() - c.col()) < dmax)
+ const L& lbl = text.label_image();
+ while (lbl.domain().has(p) && (lbl(p) == literal::zero
+ || lbl(p) == i || right_link[i] == lbl(p))
+ && math::abs(p.col() - c.col()) < dmax)
--p.col();
internal::update_link_array(lbl, right_link, p, c, i, dmax);
-
}
trace::exiting("scribo::text::grouping::group_with_single_right_link");
diff --git a/milena/sandbox/scribo/text/grouping/internal/find_root.hh b/milena/sandbox/scribo/text/grouping/internal/find_root.hh
index 0b1e307..9e3eedf 100644
--- a/milena/sandbox/scribo/text/grouping/internal/find_root.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/find_root.hh
@@ -52,13 +52,13 @@ namespace scribo
/// Find root in a parent array arrays.
unsigned
- find_root(util::array<unsigned>& parent, unsigned x);
+ find_root(mln::util::array<unsigned>& parent, unsigned x);
# ifndef MLN_INCLUDE_ONLY
inline
unsigned
- find_root(util::array<unsigned>& parent, unsigned x)
+ find_root(mln::util::array<unsigned>& parent, unsigned x)
{
if (parent[x] == x)
return x;
diff --git a/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh b/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh
index ba197f9..7e4f751 100644
--- a/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh
@@ -41,6 +41,8 @@
namespace scribo
{
+ using namespace mln;
+
namespace text
{
@@ -51,13 +53,14 @@ namespace scribo
{
/// Initialize a link array.
- void init_link_array(util::array<unsigned>& link_array);
+ void
+ init_link_array(mln::util::array<unsigned>& link_array);
# ifndef MLN_INCLUDE_ONLY
inline
void
- init_link_array(util::array<unsigned>& link_array)
+ init_link_array(mln::util::array<unsigned>& link_array)
{
for (unsigned i = 0; i < link_array.nelements(); ++i)
link_array[i] = i;
diff --git a/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh b/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh
index 242d18f..501d6f2 100644
--- a/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh
@@ -56,7 +56,7 @@ namespace scribo
/// on the right of the current bbox.
template <typename I>
void
- update_link_array(const Image<I>& lbl, util::array<unsigned>& link_array,
+ update_link_array(const Image<I>& lbl, mln::util::array<unsigned>& link_array,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax);
@@ -65,7 +65,7 @@ namespace scribo
template <typename I>
inline
void
- update_link_array(const Image<I>& lbl_, util::array<unsigned>& link_array,
+ update_link_array(const Image<I>& lbl_, mln::util::array<unsigned>& link_array,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax)
{
@@ -75,7 +75,8 @@ namespace scribo
mln_assertion(lbl.is_valid());
if (lbl.domain().has(p) && lbl(p) != literal::zero && lbl(p) != i
- && (math::abs(p.col() - c.col())) < dmax && link_array[lbl(p)] == lbl(p))
+ && (math::abs(p.col() - c.col())) < dmax && link_array[lbl(p)] == lbl(p)
+ && link_array[i] != lbl(p))
link_array[lbl(p)] = i;
}
diff --git a/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh b/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh
index e31c5e8..f572a47 100644
--- a/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh
@@ -52,7 +52,7 @@ namespace scribo
/// Update graph edges if a valid neighbor is found.
template <typename I>
void
- update_link_graph(Image<I>& lbl_, util::graph& g,
+ update_link_graph(const Image<I>& lbl_, mln::util::graph& g,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax);
@@ -63,7 +63,7 @@ namespace scribo
template <typename I>
inline
void
- update_link_graph(Image<I>& lbl_, util::graph& g,
+ update_link_graph(const Image<I>& lbl_, mln::util::graph& g,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax)
{
@@ -72,7 +72,7 @@ namespace scribo
mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
mln_precondition(exact(lbl).is_valid());
- if (lbl.domain().has(p) && lbl(p) != 0u && lbl(p) != i
+ if (lbl.domain().has(p) && lbl(p) != literal::zero && lbl(p) != i
&& (math::abs(p.col() - c.col())) < dmax)
g.add_edge(lbl(p), i);
}
diff --git a/milena/sandbox/scribo/text/recognition.hh b/milena/sandbox/scribo/text/recognition.hh
index 98c3b67..c11ed54 100644
--- a/milena/sandbox/scribo/text/recognition.hh
+++ b/milena/sandbox/scribo/text/recognition.hh
@@ -54,6 +54,8 @@ namespace scribo
namespace text
{
+ using namespace mln;
+
/// Passes the text bboxes to Tesseract (OCR) and store the result in
/// an image of characters.
///
@@ -71,8 +73,8 @@ namespace scribo
template <typename I, typename N, typename V>
mln_ch_value(I,char)
text_recognition(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const Neighborhood<N>& nbh_, const V& label_type,
+ const scribo::util::text_bboxes<mln_ch_value(I,V)>& textbboxes,
const char *language);
@@ -81,8 +83,8 @@ namespace scribo
template <typename I, typename N, typename V>
mln_ch_value(I,char)
text_recognition(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const Neighborhood<N>& nbh_, const V& label_type,
+ const scribo::util::text_bboxes<mln_ch_value(I,V)>& textbboxes,
const char *language)
{
trace::entering("scribo::text::recognition");
@@ -93,6 +95,7 @@ namespace scribo
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
+ V nbboxes;
mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nbboxes);
/// Use text bboxes with Tesseract
@@ -104,7 +107,7 @@ namespace scribo
{
if (textbboxes[i].is_valid())
{
- mln_ch_value(I,bool) b(textbboxes[i], 0);
+ mln_ch_value(I,bool) b(textbboxes.bboxes()[i], 0);
data::fill(b, false);
data::fill((b | (pw::value(lbl) == pw::cst(i))).rw(), true);
@@ -119,9 +122,9 @@ namespace scribo
- mln_site(I) p = textbboxes[i].center();
- p.col() -= (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ mln_site(I) p = textbboxes.bboxes[i].center();
+ p.col() -= (textbboxes.bboxes()[i].pmax().col()
+ - textbboxes.bboxes()[i].pmin().col()) / 2;
if (s != 0)
debug::put_word(txt, p, s);
free(s);
diff --git a/milena/sandbox/scribo/util/text.hh b/milena/sandbox/scribo/util/text.hh
new file mode 100644
index 0000000..2619a79
--- /dev/null
+++ b/milena/sandbox/scribo/util/text.hh
@@ -0,0 +1,189 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_UTIL_TEXT_HH
+# define SCRIBO_UTIL_TEXT_HH
+
+/// \file scribo/util/text.hh
+///
+/// A class representing text bounding boxes and their associated
+/// labeled image.
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/concept/proxy.hh>
+# include <mln/core/site_set/box.hh>
+# include <mln/value/label_16.hh>
+# include <mln/util/couple.hh>
+# include <mln/util/array.hh>
+
+namespace scribo
+{
+
+ using namespace mln;
+
+ namespace util
+ {
+
+ /// Store text bounding boxes and their associated labeled image.
+ template <typename L>
+ class text
+ {
+ public:
+ typedef mln_site(L) site;
+ typedef mln::util::array<box<site> > boxes_t;
+
+ text();
+ text(const mln::util::array<box<mln_site(L)> >& bboxes,
+ const Image<L>& lbl,
+ const mln_value(L)& nbboxes);
+
+ const L& label_image() const;
+ L& label_image();
+
+ const mln_value(L)& nbboxes() const;
+ mln_value(L)& nbboxes();
+
+ const boxes_t& bboxes() const;
+ boxes_t& bboxes();
+
+ const box<mln_site(L)>& bbox(unsigned i) const;
+ box<mln_site(L)>& bbox(unsigned i);
+
+ bool is_valid() const;
+
+ private:
+ boxes_t bboxes_;
+ L lbl_;
+ mln_value(L) nbboxes_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ inline
+ text<L>::text()
+ {
+ }
+
+ template <typename L>
+ inline
+ text<L>::text(const mln::util::array<box<mln_site(L)> >& bboxes,
+ const Image<L>& lbl,
+ const mln_value(L)& nbboxes)
+ : bboxes_(bboxes), lbl_(exact(lbl)), nbboxes_(nbboxes)
+ {
+ mln_assertion(bboxes.nelements() == nbboxes.next());
+ }
+
+ template <typename L>
+ inline
+ const L&
+ text<L>::label_image() const
+ {
+ mln_precondition(lbl_.is_valid());
+ return lbl_;
+ }
+
+ template <typename L>
+ inline
+ L&
+ text<L>::label_image()
+ {
+ return lbl_;
+ }
+
+ template <typename L>
+ inline
+ const mln_value(L)&
+ text<L>::nbboxes() const
+ {
+ return nbboxes_;
+ }
+
+ template <typename L>
+ inline
+ mln_value(L)&
+ text<L>::nbboxes()
+ {
+ return nbboxes_;
+ }
+
+ template <typename L>
+ inline
+ const typename text<L>::boxes_t&
+ text<L>::bboxes() const
+ {
+ mln_precondition(bboxes_.nelements() == nbboxes_.next());
+ return bboxes_;
+ }
+
+ template <typename L>
+ inline
+ typename text<L>::boxes_t&
+ text<L>::bboxes()
+ {
+ return bboxes_;
+ }
+
+ template <typename L>
+ inline
+ const box<mln_site(L)>&
+ text<L>::bbox(unsigned i) const
+ {
+ mln_precondition(bboxes_.nelements() == nbboxes_.next());
+ mln_precondition(i < bboxes_.nelements());
+ return bboxes_[i];
+ }
+
+ template <typename L>
+ inline
+ box<mln_site(L)>&
+ text<L>::bbox(unsigned i)
+ {
+ mln_precondition(bboxes_.nelements() == nbboxes_.next());
+ mln_precondition(i < bboxes_.nelements());
+ return bboxes_[i];
+ }
+
+ template <typename L>
+ inline
+ bool
+ text<L>::is_valid() const
+ {
+ return lbl_.is_valid() && bboxes_.nelements() == nbboxes_.next();
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::util
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_UTIL_TEXT_HH
--
1.5.6.5
1
0
---
ChangeLog | 4 ++++
configure.ac | 1 +
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 58297c6..076c1f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-03-19 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
+ * configure.ac: configure tests/accu/site_set.
+
2009-03-18 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
* configure.ac: configure tests/accu/image.
diff --git a/configure.ac b/configure.ac
index 118ce2b..3eac78d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -185,6 +185,7 @@ AC_CONFIG_FILES([
milena/tests/Makefile
milena/tests/accu/Makefile
milena/tests/accu/image/Makefile
+ milena/tests/accu/site_set/Makefile
milena/tests/algebra/Makefile
milena/tests/arith/Makefile
milena/tests/binarization/Makefile
--
1.5.6.5
1
0
* mln/accu/all.hh,
* mln/accu/essential.hh,
* mln/accu/image/essential.hh,
* mln/accu/site_set/all.hh,
* mln/accu/site_set/essential.hh: update all and essential includes.
* mln/accu/site_set/rectangularity.hh: new accumulator.
* tests/accu/Makefile.am,
* tests/accu/site_set/Makefile.am,
* tests/accu/site_set/rectangularity.cc: add associated test.
---
milena/ChangeLog | 16 +++
milena/mln/accu/all.hh | 1 +
milena/mln/accu/essential.hh | 5 +-
milena/mln/accu/{ => image}/essential.hh | 25 +---
milena/mln/accu/{essential.hh => site_set/all.hh} | 26 +---
milena/mln/accu/{ => site_set}/essential.hh | 25 +---
milena/mln/accu/site_set/rectangularity.hh | 132 ++++++++++++++++++++
milena/tests/accu/Makefile.am | 4 +
milena/tests/accu/site_set/Makefile.am | 10 ++
.../accu/site_set/rectangularity.cc} | 54 +++++----
10 files changed, 218 insertions(+), 80 deletions(-)
copy milena/mln/accu/{ => image}/essential.hh (67%)
copy milena/mln/accu/{essential.hh => site_set/all.hh} (67%)
copy milena/mln/accu/{ => site_set}/essential.hh (67%)
create mode 100644 milena/mln/accu/site_set/rectangularity.hh
create mode 100644 milena/tests/accu/site_set/Makefile.am
copy milena/{mln/accu/essential.hh => tests/accu/site_set/rectangularity.cc} (63%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index be240e1..c68b693 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,21 @@
2009-03-19 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Add accu::site_set::rectangularity.
+
+ * mln/accu/all.hh,
+ * mln/accu/essential.hh,
+ * mln/accu/image/essential.hh,
+ * mln/accu/site_set/all.hh,
+ * mln/accu/site_set/essential.hh: update all and essential includes.
+
+ * mln/accu/site_set/rectangularity.hh: new accumulator.
+
+ * tests/accu/Makefile.am,
+ * tests/accu/site_set/Makefile.am,
+ * tests/accu/site_set/rectangularity.cc: add associated test.
+
+2009-03-19 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Add accu::couple.
* mln/accu/internal/couple.hh: new class.
diff --git a/milena/mln/accu/all.hh b/milena/mln/accu/all.hh
index 5b4e761..0e4d72d 100644
--- a/milena/mln/accu/all.hh
+++ b/milena/mln/accu/all.hh
@@ -96,6 +96,7 @@ namespace mln
// Sub-directories
# include <mln/accu/image/all.hh>
+# include <mln/accu/site_set/all.hh>
#endif // ! MLN_ACCU_ALL_HH
diff --git a/milena/mln/accu/essential.hh b/milena/mln/accu/essential.hh
index e8c57cc..c69540d 100644
--- a/milena/mln/accu/essential.hh
+++ b/milena/mln/accu/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 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
@@ -46,5 +46,8 @@
# include <mln/accu/rank.hh>
# include <mln/accu/sum.hh>
+# include <mln/accu/image/essential.hh>
+# include <mln/accu/site_set/essential.hh>
+
#endif // !MLN_ACCU_ESSENTIAL_HH_
diff --git a/milena/mln/accu/essential.hh b/milena/mln/accu/image/essential.hh
similarity index 67%
copy from milena/mln/accu/essential.hh
copy to milena/mln/accu/image/essential.hh
index e8c57cc..9a72225 100644
--- a/milena/mln/accu/essential.hh
+++ b/milena/mln/accu/image/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 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,26 +25,13 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_ESSENTIAL_HH_
-# define MLN_ACCU_ESSENTIAL_HH_
+#ifndef MLN_ACCU_IMAGE_ESSENTIAL_HH_
+# define MLN_ACCU_IMAGE_ESSENTIAL_HH_
-/// \file mln/accu/essential.hh
+/// \file mln/accu/image/essential.hh
///
-/// File that includes the most useful accumulator types.
+/// File that includes the most useful accumulator types working on images.
-# include <mln/accu/bbox.hh>
-# include <mln/accu/center.hh>
-# include <mln/accu/count.hh>
-# include <mln/accu/histo.hh>
-# include <mln/accu/max.hh>
-# include <mln/accu/max_h.hh>
-# include <mln/accu/mean.hh>
-# include <mln/accu/median_h.hh>
-# include <mln/accu/min.hh>
-# include <mln/accu/min_h.hh>
-# include <mln/accu/min_max.hh>
-# include <mln/accu/rank.hh>
-# include <mln/accu/sum.hh>
-#endif // !MLN_ACCU_ESSENTIAL_HH_
+#endif // !MLN_ACCU_IMAGE_ESSENTIAL_HH_
diff --git a/milena/mln/accu/essential.hh b/milena/mln/accu/site_set/all.hh
similarity index 67%
copy from milena/mln/accu/essential.hh
copy to milena/mln/accu/site_set/all.hh
index e8c57cc..03c8dae 100644
--- a/milena/mln/accu/essential.hh
+++ b/milena/mln/accu/site_set/all.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 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,26 +25,14 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_ESSENTIAL_HH_
-# define MLN_ACCU_ESSENTIAL_HH_
+#ifndef MLN_ACCU_SITE_SET_ALL_HH_
+# define MLN_ACCU_SITE_SET_ALL_HH_
-/// \file mln/accu/essential.hh
+/// \file mln/accu/site_set/all.hh
///
-/// File that includes the most useful accumulator types.
+/// File that includes all accumulator types working on site sets.
-# include <mln/accu/bbox.hh>
-# include <mln/accu/center.hh>
-# include <mln/accu/count.hh>
-# include <mln/accu/histo.hh>
-# include <mln/accu/max.hh>
-# include <mln/accu/max_h.hh>
-# include <mln/accu/mean.hh>
-# include <mln/accu/median_h.hh>
-# include <mln/accu/min.hh>
-# include <mln/accu/min_h.hh>
-# include <mln/accu/min_max.hh>
-# include <mln/accu/rank.hh>
-# include <mln/accu/sum.hh>
+# include <mln/accu/site_set/rectangularity.hh>
-#endif // !MLN_ACCU_ESSENTIAL_HH_
+#endif // !MLN_ACCU_SITE_SET_ALL_HH_
diff --git a/milena/mln/accu/essential.hh b/milena/mln/accu/site_set/essential.hh
similarity index 67%
copy from milena/mln/accu/essential.hh
copy to milena/mln/accu/site_set/essential.hh
index e8c57cc..feb5a97 100644
--- a/milena/mln/accu/essential.hh
+++ b/milena/mln/accu/site_set/essential.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 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,26 +25,13 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_ESSENTIAL_HH_
-# define MLN_ACCU_ESSENTIAL_HH_
+#ifndef MLN_ACCU_SITE_SET_ESSENTIAL_HH_
+# define MLN_ACCU_SITE_SET_ESSENTIAL_HH_
-/// \file mln/accu/essential.hh
+/// \file mln/accu/site_set/essential.hh
///
-/// File that includes the most useful accumulator types.
+/// File that includes the most useful accumulator types working on site sets.
-# include <mln/accu/bbox.hh>
-# include <mln/accu/center.hh>
-# include <mln/accu/count.hh>
-# include <mln/accu/histo.hh>
-# include <mln/accu/max.hh>
-# include <mln/accu/max_h.hh>
-# include <mln/accu/mean.hh>
-# include <mln/accu/median_h.hh>
-# include <mln/accu/min.hh>
-# include <mln/accu/min_h.hh>
-# include <mln/accu/min_max.hh>
-# include <mln/accu/rank.hh>
-# include <mln/accu/sum.hh>
-#endif // !MLN_ACCU_ESSENTIAL_HH_
+#endif // !MLN_ACCU_SITE_SET_ESSENTIAL_HH_
diff --git a/milena/mln/accu/site_set/rectangularity.hh b/milena/mln/accu/site_set/rectangularity.hh
new file mode 100644
index 0000000..fef5b21
--- /dev/null
+++ b/milena/mln/accu/site_set/rectangularity.hh
@@ -0,0 +1,132 @@
+// Copyright (C) 2009 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_ACCU_SITE_SET_RECTANGULARITY_HH
+# define MLN_ACCU_SITE_SET_RECTANGULARITY_HH
+
+/// \file mln/accu/site_set/rectangularity.hh
+///
+/// Compute the rectangularity of a site set.
+
+# include <mln/accu/internal/couple.hh>
+# include <mln/accu/bbox.hh>
+# include <mln/accu/count.hh>
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+ namespace site_set
+ {
+
+ /// Compute the rectangularity of a site set.
+ template <typename P>
+ class rectangularity
+ : public accu::internal::couple<accu::bbox<P>,
+ accu::count<P>,
+ float,
+ rectangularity<P> >
+ {
+
+ public:
+
+ typedef accu::internal::couple<accu::bbox<P>,
+ accu::count<P>,
+ float,
+ rectangularity<P> > super_;
+
+ typedef accu::bbox<P> A1;
+ typedef accu::count<P> A2;
+
+ typedef float result;
+
+ /// Constructor
+ rectangularity();
+
+ /// Return the site set bounding box.
+ mln_result(A1) bbox() const;
+ /// Return the site set area.
+ mln_result(A2) area() const;
+
+ /// Return the rectangularity value.
+ result to_result() const;
+
+ protected:
+ using super_::a1_;
+ using super_::a2_;
+
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename P>
+ inline
+ rectangularity<P>::rectangularity()
+ {
+ }
+
+ template <typename P>
+ inline
+ mln_result(rectangularity<P>::A1)
+ rectangularity<P>::bbox() const
+ {
+ mln_precondition(a1_.is_valid());
+ return a1_.to_result();
+ }
+
+ template <typename P>
+ inline
+ mln_result(rectangularity<P>::A2)
+ rectangularity<P>::area() const
+ {
+ mln_precondition(a2_.is_valid());
+ return a2_.to_result();
+ }
+
+ template <typename P>
+ inline
+ mln_result(rectangularity<P>)
+ rectangularity<P>::to_result() const
+ {
+ mln_precondition(this->is_valid());
+ // Force division return type.
+ return static_cast<result>(a2_.to_result()) / a1_.to_result().nsites();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu::site_set
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+#endif // ! MLN_ACCU_SITE_SET_RECTANGULARITY_HH
diff --git a/milena/tests/accu/Makefile.am b/milena/tests/accu/Makefile.am
index fafbec1..7aca2bd 100644
--- a/milena/tests/accu/Makefile.am
+++ b/milena/tests/accu/Makefile.am
@@ -2,6 +2,10 @@
include $(top_srcdir)/milena/tests/tests.mk
+SUBDIRS = \
+ image \
+ site_set
+
check_PROGRAMS = \
all_accus \
bbox \
diff --git a/milena/tests/accu/site_set/Makefile.am b/milena/tests/accu/site_set/Makefile.am
new file mode 100644
index 0000000..042cf00
--- /dev/null
+++ b/milena/tests/accu/site_set/Makefile.am
@@ -0,0 +1,10 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+include $(top_srcdir)/milena/tests/tests.mk
+
+check_PROGRAMS = \
+ rectangularity
+
+rectangularity_SOURCES = rectangularity.cc
+
+TESTS = $(check_PROGRAMS)
diff --git a/milena/mln/accu/essential.hh b/milena/tests/accu/site_set/rectangularity.cc
similarity index 63%
copy from milena/mln/accu/essential.hh
copy to milena/tests/accu/site_set/rectangularity.cc
index e8c57cc..22e1e3e 100644
--- a/milena/mln/accu/essential.hh
+++ b/milena/tests/accu/site_set/rectangularity.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,26 +25,36 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_ESSENTIAL_HH_
-# define MLN_ACCU_ESSENTIAL_HH_
-
-/// \file mln/accu/essential.hh
+/// \file tests/accu/site_set/rectangularity.hh
///
-/// File that includes the most useful accumulator types.
-
-# include <mln/accu/bbox.hh>
-# include <mln/accu/center.hh>
-# include <mln/accu/count.hh>
-# include <mln/accu/histo.hh>
-# include <mln/accu/max.hh>
-# include <mln/accu/max_h.hh>
-# include <mln/accu/mean.hh>
-# include <mln/accu/median_h.hh>
-# include <mln/accu/min.hh>
-# include <mln/accu/min_h.hh>
-# include <mln/accu/min_max.hh>
-# include <mln/accu/rank.hh>
-# include <mln/accu/sum.hh>
-
-#endif // !MLN_ACCU_ESSENTIAL_HH_
+/// Tests on mln::accu::site_set::rectangularity.
+
+
+#include <mln/core/alias/point2d.hh>
+#include <mln/core/alias/box2d.hh>
+
+#include <mln/accu/site_set/rectangularity.hh>
+
+int main()
+{
+ using namespace mln;
+
+ {
+ accu::site_set::rectangularity<point2d> accu;
+ accu.take_as_init(point2d(0,0));
+ accu.take(point2d(0,1));
+ accu.take(point2d(1,0));
+ accu.take(point2d(1,1));
+
+ mln_assertion(accu.to_result() == 1);
+ }
+
+ {
+ accu::site_set::rectangularity<point2d> accu;
+ accu.take(point2d(0,0));
+ accu.take(point2d(1,1));
+ std::cout << accu << std::endl;
+ mln_assertion(accu.to_result() == 0.5f);
+ }
+}
--
1.5.6.5
1
0
* mln/accu/internal/couple.hh: new class.
---
milena/ChangeLog | 6 +
milena/mln/accu/internal/couple.hh | 184 ++++++++++++++++++++++++++++++++++++
2 files changed, 190 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/accu/internal/couple.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 5944d9b..be240e1 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,9 @@
+2009-03-19 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
+ Add accu::couple.
+
+ * mln/accu/internal/couple.hh: new class.
+
2009-03-18 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
Add transform::distance_and_influence_zone_geodesic.
diff --git a/milena/mln/accu/internal/couple.hh b/milena/mln/accu/internal/couple.hh
new file mode 100644
index 0000000..d4678a6
--- /dev/null
+++ b/milena/mln/accu/internal/couple.hh
@@ -0,0 +1,184 @@
+// Copyright (C) 2009 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_ACCU_INTERNAL_COUPLE_HH
+# define MLN_ACCU_INTERNAL_COUPLE_HH
+
+/// \file mln/accu/couple.hh
+///
+/// Base implementation of a couple of accumulators.
+
+# include <utility>
+
+# include <mln/core/concept/accumulator.hh>
+# include <mln/accu/internal/base.hh>
+
+# include <mln/metal/equal.hh>
+
+
+namespace mln
+{
+
+ namespace accu
+ {
+
+ namespace internal
+ {
+
+ /// Base implementation of a couple of accumulators.
+ ///
+ /// The parameter \c T is the type of values.
+ ///
+ /// \todo Check that, when T is not provided, A1 and A2 have the same value.
+ template <typename A1, typename A2, typename R, typename E>
+ struct couple
+ : base<R,E>,
+ mlc_equal(mln_argument(A1), mln_argument(A2))::check_t
+ {
+ typedef mln_argument(A1) argument;
+
+ /// Manipulators.
+ /// \{
+ void init();
+ void take_as_init(const argument& t);
+ void take(const argument& t);
+ void take(const E& other);
+ /// \}
+
+ /// Check whether this accu is able to return a result.
+ /// Always true here.
+ bool is_valid() const;
+
+ A1& first();
+ A2& second();
+ const A1& first() const;
+ const A2& second() const;
+
+ protected:
+ couple();
+
+ A1 a1_;
+ A2 a2_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ couple<A1,A2,R,E>::couple()
+ {
+ init();
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ void
+ couple<A1,A2,R,E>::init()
+ {
+ a1_.init();
+ a2_.init();
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ void
+ couple<A1,A2,R,E>::take_as_init(const argument& t)
+ {
+ a1_.take_as_init(t);
+ a2_.take_as_init(t);
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ void
+ couple<A1,A2,R,E>::take(const argument& t)
+ {
+ a1_.take(t);
+ a2_.take(t);
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ void
+ couple<A1,A2,R,E>::take(const E& other)
+ {
+ a1_.take(other.a1_);
+ a2_.take(other.a2_);
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ bool
+ couple<A1,A2,R,E>::is_valid() const
+ {
+ return a1_.is_valid() && a2_.is_valid();
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ A1&
+ couple<A1,A2,R,E>::first()
+ {
+ return a1_;
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ const A1&
+ couple<A1,A2,R,E>::first() const
+ {
+ return a1_;
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ A2&
+ couple<A1,A2,R,E>::second()
+ {
+ return a2_;
+ }
+
+ template <typename A1, typename A2, typename R, typename E>
+ inline
+ const A2&
+ couple<A1,A2,R,E>::second() const
+ {
+ return a2_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::accu::internal
+
+ } // end of namespace mln::accu
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ACCU_INTERNAL_COUPLE_HH
--
1.5.6.5
1
0
* bugs/concept_and_assignment.cc: sample code of what should not
be done while assigning an image to another.
---
milena/sandbox/ChangeLog | 7 ++
milena/sandbox/bugs/concept_and_assignment.cc | 84 +++++++++++++++++++++++++
2 files changed, 91 insertions(+), 0 deletions(-)
create mode 100644 milena/sandbox/bugs/concept_and_assignment.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 0512bfc..8c7681f 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,10 @@
+2009-03-16 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add a buggy sample case.
+
+ * bugs/concept_and_assignment.cc: sample code of what should not
+ be done while assigning an image to another.
+
2009-03-19 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add a new file translating IGR Matlab code.
diff --git a/milena/sandbox/bugs/concept_and_assignment.cc b/milena/sandbox/bugs/concept_and_assignment.cc
new file mode 100644
index 0000000..379d17d
--- /dev/null
+++ b/milena/sandbox/bugs/concept_and_assignment.cc
@@ -0,0 +1,84 @@
+/*
+** We do NOT want to pass images as reference.
+**
+** Assigning an image to an image concept will compile but
+** will not perform anything. This is ERROR PRONE.
+**
+** Thus, if the image passed as reference is not initialized it will remain
+** uninitialized and an assertion will raised. The problem is if the image is
+** already initialized. It will FAIL SILENTLY and give wrong image values.
+**
+** Always prefer returning images.
+*/
+
+#include <mln/essential/2d.hh>
+
+namespace mln
+{
+
+ template <typename I>
+ mln_ch_value(I,value::label_8)
+ bar(const Image<I>& ima)
+ {
+ value::label_8 n;
+
+ mln_ch_value(I,value::label_8) lbl;
+ initialize(lbl, ima);
+
+ lbl = labeling::blobs(ima, c8(),n);
+ mln_assertion(lbl.is_valid());
+
+ return lbl;
+ }
+
+ // DO NOT WORK!
+ template <typename I>
+ void foo_template_and_concept(Image<I>& lbl)
+ {
+ mln_ch_value(I,bool) ima(3,4);
+
+ /// The difference is here!
+ lbl = bar(ima);
+
+ mln_assertion(exact(lbl).is_valid());
+ }
+
+ // WORK
+ template <typename I>
+ void foo_template_concept_and_exact(Image<I>& lbl)
+ {
+ mln_ch_value(I,bool) ima(3,4);
+
+ /// The difference is here!
+ exact(lbl) = bar(ima);
+
+ mln_assertion(exact(lbl).is_valid());
+ }
+
+}
+
+
+
+int main(int, char*argv[])
+{
+ using namespace mln;
+
+ image2d<bool> ima(3,4);
+
+ // WORK
+ {
+ std::cout << "template with I + concept + exact" << std::endl;
+ image2d<value::label_8> lbl;
+ foo_template_concept_and_exact(lbl);
+ mln_assertion(lbl.is_valid());
+ }
+
+ // DO NOT WORK
+ {
+ std::cout << "template with I + concept" << std::endl;
+ image2d<value::label_8> lbl;
+ foo_template_and_concept(lbl);
+ mln_assertion(lbl.is_valid());
+ }
+
+}
--
1.5.6.5
1
0
19 Mar '09
* mln/transform/all.hh: include new file.
* mln/transform/distance_and_influence_zone_geodesic.hh: new routine.
---
milena/ChangeLog | 8 ++
milena/mln/transform/all.hh | 4 +-
.../distance_and_influence_zone_geodesic.hh | 96 ++++++++++++++++++++
3 files changed, 107 insertions(+), 1 deletions(-)
create mode 100644 milena/mln/transform/distance_and_influence_zone_geodesic.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 2d33b38..5944d9b 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,11 @@
+2009-03-18 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
+ Add transform::distance_and_influence_zone_geodesic.
+
+ * mln/transform/all.hh: include new file.
+
+ * mln/transform/distance_and_influence_zone_geodesic.hh: new routine.
+
2009-03-19 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add meta-code to access component types of value types.
diff --git a/milena/mln/transform/all.hh b/milena/mln/transform/all.hh
index 4967197..7d6ef27 100644
--- a/milena/mln/transform/all.hh
+++ b/milena/mln/transform/all.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 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
@@ -43,6 +44,7 @@ namespace mln
# include <mln/transform/distance_and_closest_point_geodesic.hh>
+# include <mln/transform/distance_and_influence_zone_geodesic.hh>
# include <mln/transform/distance_front.hh>
# include <mln/transform/distance_geodesic.hh>
# include <mln/transform/influence_zone_front.hh>
diff --git a/milena/mln/transform/distance_and_influence_zone_geodesic.hh b/milena/mln/transform/distance_and_influence_zone_geodesic.hh
new file mode 100644
index 0000000..f461d30
--- /dev/null
+++ b/milena/mln/transform/distance_and_influence_zone_geodesic.hh
@@ -0,0 +1,96 @@
+// Copyright (C) 2008, 2009 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_TRANSFORM_DISTANCE_AND_INFLUENCE_ZONE_GEODESIC_HH
+# define MLN_TRANSFORM_DISTANCE_AND_INFLUENCE_ZONE_GEODESIC_HH
+
+/// \file mln/transform/distance_and_influence_zone_geodesic.hh
+///
+/// Distance and geodesic closest point transform.
+
+# include <mln/canvas/distance_geodesic.hh>
+# include <mln/transform/internal/influence_zone_functor.hh>
+
+# include <mln/data/fill.hh>
+# include <mln/util/couple.hh>
+
+
+namespace mln
+{
+
+ namespace transform
+ {
+
+ /// Discrete geodesic distance transform
+ ///
+ /// \param[in] input Image from which the geodesic distance is computed.
+ /// \param[in] nbh Neighborhood
+ /// \param[in] max Max distance of propagation.
+ ///
+ /// \return a couple of images. The first one is the distance map and the
+ /// second one is the closest point image. The closest point image
+ /// contains sites.
+ ///
+ /// \post The returned images have the same domain as \p input.
+ template <typename I, typename N, typename D>
+ util::couple<mln_ch_value(I,D), I>
+ distance_and_influence_zone_geodesic(const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ D max);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename N, typename D>
+ inline
+ util::couple<mln_ch_value(I,D), I>
+ distance_and_influence_zone_geodesic(const Image<I>& input,
+ const Neighborhood<N>& nbh,
+ D max)
+ {
+ trace::entering("transform::distance_influence_zone_geodesic");
+
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(nbh).is_valid());
+
+ internal::influence_zone_functor<I> f;
+ mln_ch_value(I,D) dmap = mln::canvas::distance_geodesic(input, nbh,
+ max, f);
+
+ trace::exiting("transform::distance_and_influence_zone_geodesic");
+ return make::couple(dmap, f.output);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::transform
+
+} // end of namespace mln
+
+
+#endif // ! MLN_TRANSFORM_DISTANCE_AND_INFLUENCE_ZONE_GEODESIC_HH
--
1.5.6.5
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-19 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add a new file translating IGR Matlab code.
* fabien/bin/dump2pbm.cc: Minor fix.
* fabien/igr/Makefile: Update.
* fabien/igr/check.sh: Update.
* fabien/igr/matlab.cc: New file translating matlab code.
* fabien/igr/med.cc: Update.
* fabien/igr/thres.cc: Update.
* fabien/magick/load.hh: Moved to mln/io/magick.
* fabien/magick/magick.cc: Update.
---
TODO | 12 +++--
bin/dump2pbm.cc | 28 +++++++++---
igr/Makefile | 3 +
igr/check.sh | 10 ++--
igr/matlab.cc | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
igr/med.cc | 47 ++++++++++++++++++++
igr/thres.cc | 7 ++-
magick/magick.cc | 9 +++
8 files changed, 223 insertions(+), 19 deletions(-)
Index: trunk/milena/sandbox/fabien/igr/matlab.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/matlab.cc (revision 0)
+++ trunk/milena/sandbox/fabien/igr/matlab.cc (revision 3545)
@@ -0,0 +1,126 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/image_if.hh>
+#include <mln/core/image/cast_image.hh>
+#include <mln/core/image/slice_image.hh>
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/value/int_u12.hh>
+
+#include <mln/io/dicom/load.hh>
+
+#include <mln/accu/count.hh>
+#include <mln/accu/mean.hh>
+#include <mln/accu/sum.hh>
+#include <mln/accu/image/all.hh>
+#include <mln/arith/minus.hh>
+#include <mln/data/fill.hh>
+#include <mln/data/paste.hh>
+#include <mln/level/compute.hh>
+#include <mln/math/abs.hh>
+#include <mln/pw/all.hh>
+#include <mln/trait/concrete.hh>
+#include <mln/util/array.hh>
+
+#include <cmath>
+
+using namespace mln;
+
+
+inline
+image2d<float> mean_slices(util::array<image2d<float> >& arr_ima, int first, int last)
+{
+ image2d<accu::mean<float> > result;
+
+ mln_precondition(first >=0 && first < arr_ima.nelements());
+ mln_precondition(last >=0 && last < arr_ima.nelements());
+
+ accu::image::init(result);
+ for (int i = first; i < last; ++i)
+ accu::image::take(result, arr_ima[i]);
+
+ return accu::image::to_result(result);
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << "input" << std::endl;
+ return 1;
+ }
+
+ image3d<value::int_u12> input;
+ io::dicom::load(input, argv[1]);
+ util::array<image2d<float> > arr_ima;
+ for (int i = 0; i < input.nslices(); ++i)
+ arr_ima.append(duplicate(cast_image<float>(slice(input, i))));
+
+ int acqui = 3; // durée acqui et temps interimages; en secondes
+ int fseuil = 4; // ratio entre signaux trop faibles, éliminés, et bruit de fond mesuré sur l image
+ int ini = 9; // nombre images ligne de base
+ int ini2 = 20; // a la fin de la montée vasculaire, à la dixieme image post injection: lissage des images par trois
+
+ // Calcul signal initialmoyen : 8 images de 2 à 9 moyennées=ligne de base
+ image2d<float> imageini = mean_slices(arr_ima, 1, 8);
+
+ int dim1 = imageini.nrows();
+ int dim2 = imageini.ncols();
+ int dim3 = arr_ima.nelements();
+
+ // Calcul auc aire sous la courbe
+ util::array<image2d<float> > arr_sous;
+ for (int k = 0; k < arr_ima.nelements(); ++k)
+ arr_sous.append(arr_ima[k] - imageini);
+
+ // Mesure bruit de fond pour seuiller
+ // calculé sur la première image
+ image2d<bool> roi_noise; // FIXME: init this ROI, should be a domain
+ accu::count<bool> accu_nbrpix1;
+ unsigned nbrpix1 = level::compute(accu_nbrpix1, roi_noise);
+ image2d<float> datasli = arr_ima[0];
+
+ image2d<float> prodsignal1;
+ data::fill(prodsignal1, 0.0);
+ data::paste(datasli | pw::value(roi_noise) == pw::cst(true), prodsignal1);
+
+ // moyenne
+ accu::mean<float> accu_mean;
+ float moysignal1 = level::compute(accu_mean, prodsignal1 | pw::value(roi_noise) == pw::cst(true));
+ // ecart type
+ int som1 = 0;
+ int kk = 0;
+ mln_piter_(image2d<float>) p(datasli.domain());
+ for_all(p)
+ {
+ if (roi_noise(p))
+ som1 += std::pow(math::abs(datasli(p) - moysignal1), 2);
+ }
+ float ectys = std::sqrt(som1 / (nbrpix1 - 1));
+ float seuil = fseuil * ectys;
+
+ // Calcul du masque
+ image2d<bool> masque; // FIXME: init this ROI, should be a domain
+ initialize(masque, datasli);
+ data::fill(masque, false)
+ data::fill(masque | pw::value(datasli) > pw::cst(seuil), true);
+ // si on a choisi une région avec roi2
+ if (nargin>2)
+ masque=masque.*roi2;
+
+ //on applique le masque sur image et imasoustraite
+
+ for k=2:dim3
+ for i=1:dim1
+ for j=1:dim2
+ if(masque(i,j)==0)
+ image(i,j,k)=0;
+ imasoustraite(i,j,k)=0;
+ end;
+ end;
+ end;
+ end;
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/igr/check.sh
===================================================================
--- trunk/milena/sandbox/fabien/igr/check.sh (revision 3544)
+++ trunk/milena/sandbox/fabien/igr/check.sh (revision 3545)
@@ -15,11 +15,11 @@
echo " nbasins = $nbasins"
../bin/dumpl32_to_colorize wst.dump $dim $nbasins results/colorize_${3}_${lambda_closing}.ppm
median=`./med wst.dump $dim $input $nbasins`
- echo " median = $median"
+#echo " median = $median"
threshold=$(($median / 2))
../bin/dumpi12_to_pgm med.dump $dim results/median_${3}_${lambda_closing}.pgm
./thres med.dump $dim $threshold
- mv result.pbm results/result_${3}_${lambda_closing}.pbm
+ ../bin/dump2pbm result.dump $dim results/result_${3}_${lambda_closing}.pbm
#if [ $2 -eq 2 ]; then
# if [ ${lambda_closing} -eq 100 ]; then
@@ -39,8 +39,8 @@
}
process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0049.dcm" 2 "49"
-#process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0052.dcm" 3 "52"
+process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0052.dcm" 3 "52"
process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0055.dcm" 2 "55"
process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0058.dcm" 2 "58"
-#process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0061.dcm" 3 "61"
-#process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0064.dcm" 3 "64"
+process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0061.dcm" 3 "61"
+process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0064.dcm" 3 "64"
Index: trunk/milena/sandbox/fabien/igr/med.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/med.cc (revision 3544)
+++ trunk/milena/sandbox/fabien/igr/med.cc (revision 3545)
@@ -63,6 +63,8 @@
}
unsigned median = 0;
+ int bg = 0;
+ int fg = 0;
if (dim == 2)
{
@@ -88,14 +90,57 @@
accu::median_h<int_u12> accu_med;
median = level::compute(accu_med, ima_histo | pw::value(ima_histo) != pw::cst(0));
+ for (int i = 0; i < histogram.nvalues(); ++i)
+ {
+ if (histogram[i])
+ {
+ if (histogram[i] > median / 2)
+ ++fg;
+ else ++bg;
+ }
+ }
+
io::dump::save(wst_mean, "med.dump");
}
else
{
- // FIXME
+ image3d<L> labels;
+ io::dump::load(labels, argv[1]);
+ image3d<int_u12> dcm;
+ io::dicom::load(dcm, argv[3]);
+
+ mln_VAR(wst_dilate, morpho::elementary::dilation(extend(labels | (pw::value(labels) == 0u), labels), c26()));
+ data::fill((labels | (pw::value(labels) == 0u)).rw(), wst_dilate);
+ mln_VAR(wst_mean, labeling::mean_values(dcm, labels, nbasins));
+
+ histo::array<int_u12> histogram = histo::compute(wst_mean);
+ int j = 0;
+ int k = 0;
+ for (int i = 0; i < histogram.nvalues(); ++i)
+ {
+ if (histogram[i])
+ histogram[i] = i;
+ }
+ image1d<unsigned> ima_histo;
+ convert::from_to(histogram, ima_histo);
+ accu::median_h<int_u12> accu_med;
+ median = level::compute(accu_med, ima_histo | pw::value(ima_histo) != pw::cst(0));
+
+ for (int i = 0; i < histogram.nvalues(); ++i)
+ {
+ if (histogram[i])
+ {
+ if (histogram[i] > median / 2)
+ ++fg;
+ else ++bg;
+ }
+ }
+
+ io::dump::save(wst_mean, "med.dump");
}
std::cout << median << std::endl;
+ std::cerr << " [ " << bg << " <" << median / 2 << "> " << fg << " ]" << std::endl;
return 0;
}
Index: trunk/milena/sandbox/fabien/igr/thres.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/thres.cc (revision 3544)
+++ trunk/milena/sandbox/fabien/igr/thres.cc (revision 3545)
@@ -56,11 +56,14 @@
image2d<int_u12> input;
io::dump::load(input, argv[1]);
image2d<bool> bin_result = binarization::threshold(input, threshold);
- io::pbm::save(bin_result, "result.pbm");
+ io::dump::save(bin_result, "result.dump");
}
else
{
- // FIXME
+ image3d<int_u12> input;
+ io::dump::load(input, argv[1]);
+ image3d<bool> bin_result = binarization::threshold(input, threshold);
+ io::dump::save(bin_result, "result.dump");
}
return 0;
Index: trunk/milena/sandbox/fabien/igr/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/igr/Makefile (revision 3544)
+++ trunk/milena/sandbox/fabien/igr/Makefile (revision 3545)
@@ -48,5 +48,8 @@
thres: thres.cc
g++ -I../../../ ${CXXFLAGS} $^ -o thres
+matlab: matlab.cc
+ g++ -I../../../ ${DICOM_INC} ${DICOM_LIBS} ${CXXFLAGS} -lm $^ -o matlab
+
clean:
rm -rf *.dump *.p?m *.plot *.log *.csv *.dSYM
Index: trunk/milena/sandbox/fabien/TODO
===================================================================
--- trunk/milena/sandbox/fabien/TODO (revision 3544)
+++ trunk/milena/sandbox/fabien/TODO (revision 3545)
@@ -30,7 +30,13 @@
[X] Test 3D workflow on 2D images
[X] Create colorized colors for graph
[X] Diff with %
-[ ] Find biggest dark regions (threshold value or median accu - median / 2 - )
- [ ] Learn regions value
- [ ] Threshold
+[X] Find biggest dark regions (threshold value or median accu - median / 2 - )
+ [X] Learn regions value
+ [X] Threshold
+ [X] 3D
+ [X] Print nb bg regions // nb fg objets
[ ] Profile for performance
+[ ] ImageMagick support
+[ ] Integrate external libraries (GDCM, IM)
+[ ] Send result images to lrde account
+[ ] Translate Matlab code
Index: trunk/milena/sandbox/fabien/bin/dump2pbm.cc
===================================================================
--- trunk/milena/sandbox/fabien/bin/dump2pbm.cc (revision 3544)
+++ trunk/milena/sandbox/fabien/bin/dump2pbm.cc (revision 3545)
@@ -1,5 +1,6 @@
-
#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/slice_image.hh>
#include <mln/make/image3d.hh>
#include <mln/debug/slices_2d.hh>
@@ -12,7 +13,7 @@
void usage(char* argv[])
{
- std::cerr << "usage: " << argv[0] << " input.dump output.pbm" << std::endl;
+ std::cerr << "usage: " << argv[0] << " input.dump dim output.pbm" << std::endl;
abort();
}
@@ -23,13 +24,28 @@
using namespace mln;
using value::int_u16;
- if (argc != 3)
+ if (argc != 4)
usage(argv);
+ unsigned dim = atoi(argv[2]);
+ if (dim != 2 && dim != 3)
+ {
+ std::cout << "dimensions invalid" << std::endl;
+ return 1;
+ }
+
+ if (dim == 2)
+ {
+ image2d<bool> ima;
+ io::dump::load(ima, argv[1]);
+ io::pbm::save(ima, argv[3]);
+ }
+ else
+ {
image3d<bool> vol;
io::dump::load(vol, argv[1]);
- int_u16 bg = 0;
- image2d<bool> ima = debug::slices_2d(vol, 1.f, bg);
- io::pbm::save(ima, argv[2]);
+ image2d<bool> ima = debug::slices_2d(vol, 1.f, false);
+ io::pbm::save(ima, argv[3]);
+ }
}
Index: trunk/milena/sandbox/fabien/magick/load.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/fabien/magick/magick.cc
===================================================================
--- trunk/milena/sandbox/fabien/magick/magick.cc (revision 3544)
+++ trunk/milena/sandbox/fabien/magick/magick.cc (revision 3545)
@@ -1,11 +1,15 @@
#include <mln/core/image/image2d.hh>
+#include <mln/value/int_u8.hh>
#include <mln/value/rgb8.hh>
-#include "load.hh"
+#include <mln/io/magick/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/pbm/save.hh>
int main(int argc, char* argv[])
{
using namespace mln;
+ using value::int_u8;
using value::rgb8;
if (argc != 2)
@@ -14,9 +18,10 @@
return 1;
}
- image2d<rgb8> lena;
+ image2d<bool> lena;
io::magick::load(lena, argv[1]);
+ io::pbm::save(lena, "result.pbm");
return 0;
}
1
0
19 Mar '09
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add meta-code to access component types of value types.
* mln/trait/value/internal: New directory.
* mln/trait/value/internal/all.hh: New.
* mln/trait/value/internal/comp.hh: New.
* mln/trait/value/comp.hh: New.
* mln/trait/value/all.hh: Update.
* mln/trait/value_.hh,
* mln/trait/value/nature.hh: Upgrade doc style.
* mln/value/builtin/symbolics.hh,
* mln/value/builtin/floatings.hh,
* mln/value/builtin/integers.hh (trait_): Add dim.
* mln/value/builtin/carrays.hh: New.
* mln/value/builtin/all.hh: Update.
* mln/algebra/vec.hh (trait_): Add dim and comp.
* tests/trait/value/comp.cc: New.
* tests/trait/value/Makefile.am: Update.
mln/algebra/vec.hh | 7 +
mln/trait/value/all.hh | 14 ++-
mln/trait/value/comp.hh | 46 ++++++++++++
mln/trait/value/internal/all.hh | 39 ++++++++++
mln/trait/value/internal/comp.hh | 127 ++++++++++++++++++++++++++++++++++
mln/trait/value/nature.hh | 10 +-
mln/trait/value_.hh | 4 -
mln/value/builtin/all.hh | 13 +--
mln/value/builtin/carrays.hh | 83 ++++++++++++++++++++++
mln/value/builtin/floatings.hh | 12 ++-
mln/value/builtin/integers.hh | 5 -
mln/value/builtin/symbolics.hh | 5 -
tests/trait/value/Makefile.am | 2
tests/trait/value/comp.cc | 142 +++++++++++++++++++++++++++++++++++++++
14 files changed, 482 insertions(+), 27 deletions(-)
Index: mln/trait/value_.hh
--- mln/trait/value_.hh (revision 3543)
+++ mln/trait/value_.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
Index: mln/trait/value/all.hh
--- mln/trait/value/all.hh (revision 3543)
+++ mln/trait/value/all.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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 +29,9 @@
#ifndef MLN_TRAIT_VALUE_ALL_HH
# define MLN_TRAIT_VALUE_ALL_HH
-/*! \file mln/trait/value/all.hh
- *
- * \brief FIXME
- */
+/// \file mln/trait/value/all.hh
+///
+/// Include all value traits.
namespace mln
@@ -54,5 +54,9 @@
# include <mln/trait/value/kind.hh>
# include <mln/trait/value/quant.hh>
+// Sub-directory.
+
+# include <mln/trait/value/internal/all.hh>
+
#endif // ! MLN_TRAIT_VALUE_ALL_HH
Index: mln/trait/value/nature.hh
--- mln/trait/value/nature.hh (revision 3543)
+++ mln/trait/value/nature.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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 +29,9 @@
#ifndef MLN_TRAIT_VALUE_NATURE_HH
# define MLN_TRAIT_VALUE_NATURE_HH
-/*! \file mln/trait/value/nature.hh
- *
- * \brief Nature of values (for use in images).
- */
+/// \file mln/trait/value/nature.hh
+///
+/// Nature of values (for use in images).
# include <string>
Index: mln/trait/value/internal/all.hh
--- mln/trait/value/internal/all.hh (revision 0)
+++ mln/trait/value/internal/all.hh (revision 0)
@@ -0,0 +1,39 @@
+// Copyright (C) 2009 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_TRAIT_VALUE_INTERNAL_ALL_HH
+# define MLN_TRAIT_VALUE_INTERNAL_ALL_HH
+
+/// \file mln/trait/value/internal/all.hh
+///
+/// Include all internals for value traits.
+
+
+# include <mln/trait/value/internal/comp.hh>
+
+
+#endif // ! MLN_TRAIT_VALUE_INTERNAL_ALL_HH
Index: mln/trait/value/internal/comp.hh
--- mln/trait/value/internal/comp.hh (revision 0)
+++ mln/trait/value/internal/comp.hh (revision 0)
@@ -0,0 +1,127 @@
+// Copyright (C) 2009 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_TRAIT_VALUE_INTERNAL_COMP_HH
+# define MLN_TRAIT_VALUE_INTERNAL_COMP_HH
+
+/// \file mln/trait/value/internal/comp.hh
+///
+/// Include all internals for value traits.
+
+# include <mln/metal/bool.hh>
+# include <mln/metal/if.hh>
+
+
+
+# define mln_trait_value_comp(T, i) typename mln::trait::value::internal::comp< T, i >::ret
+
+
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+
+ // Forward declaration.
+ template <typename V> struct value_;
+
+
+ namespace value
+ {
+
+ namespace internal
+ {
+
+ // bind_comp< T, i >
+
+ template <typename Tr, unsigned i>
+ struct bind_comp;
+
+ template <typename Tr> struct bind_comp< Tr, 0 > { typedef typename Tr::comp_0 ret; };
+ template <typename Tr> struct bind_comp< Tr, 1 > { typedef typename Tr::comp_1 ret; };
+ template <typename Tr> struct bind_comp< Tr, 2 > { typedef typename Tr::comp_2 ret; };
+ template <typename Tr> struct bind_comp< Tr, 3 > { typedef typename Tr::comp_3 ret; };
+ template <typename Tr> struct bind_comp< Tr, 4 > { typedef typename Tr::comp_4 ret; };
+ template <typename Tr> struct bind_comp< Tr, 5 > { typedef typename Tr::comp_5 ret; };
+ template <typename Tr> struct bind_comp< Tr, 6 > { typedef typename Tr::comp_6 ret; };
+ template <typename Tr> struct bind_comp< Tr, 7 > { typedef typename Tr::comp_7 ret; };
+ template <typename Tr> struct bind_comp< Tr, 8 > { typedef typename Tr::comp_8 ret; };
+ template <typename Tr> struct bind_comp< Tr, 9 > { typedef typename Tr::comp_9 ret; };
+
+
+ // get_comp< T, i, dim >
+
+ template <typename C, typename Tr, unsigned i>
+ struct get_comp_helper
+ {
+ typedef C ret;
+ };
+
+ template <typename Tr, unsigned i>
+ struct get_comp_helper< void, Tr, i >
+ {
+ typedef typename bind_comp<Tr, i>::ret ret;
+ };
+
+ template <typename T, unsigned i, unsigned dim>
+ struct get_comp
+ {
+ typedef mln::trait::value_<T> Tr;
+ typedef typename Tr::comp C;
+ typedef typename get_comp_helper<C, Tr, i>::ret ret;
+ };
+
+ template <typename T>
+ struct get_comp< T, 0, 1 >
+ {
+ typedef T ret;
+ };
+
+
+ // comp< T, i >
+
+ template <typename T, unsigned i>
+ struct comp
+ : private metal::bool_< (i < mln::trait::value_<T>::dim) >::check_t
+ {
+ enum { dim = mln::trait::value_<T>::dim };
+ typedef typename get_comp<T, i, dim>::ret ret;
+ };
+
+ } // end of namespace mln::trait::value::internal
+
+ } // end of namespace mln::trait::value
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+
+#endif // ! MLN_TRAIT_VALUE_INTERNAL_COMP_HH
Index: mln/trait/value/comp.hh
--- mln/trait/value/comp.hh (revision 0)
+++ mln/trait/value/comp.hh (revision 0)
@@ -0,0 +1,46 @@
+// Copyright (C) 2009 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_TRAIT_VALUE_COMP_HH
+# define MLN_TRAIT_VALUE_COMP_HH
+
+/// \file mln/trait/value/comp.hh
+///
+/// Access to the i-th component type of a given type.
+
+# include <mln/trait/value/internal/comp.hh>
+
+
+
+# define mln_trait_value_comp(T, i) \
+ \
+ typename mln::trait::value::internal::comp< T, i >::ret
+
+
+
+
+#endif // ! MLN_TRAIT_VALUE_COMP_HH
Index: mln/value/builtin/symbolics.hh
--- mln/value/builtin/symbolics.hh (revision 3543)
+++ mln/value/builtin/symbolics.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 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
@@ -59,13 +60,13 @@
typedef value::kind::binary kind;
enum {
+ dim = 1,
nbits = 1,
card = 2
};
typedef value::quant::low quant;
static const char* name() { return "bool"; }
-
};
} // end of namespace mln::trait
Index: mln/value/builtin/carrays.hh
--- mln/value/builtin/carrays.hh (revision 0)
+++ mln/value/builtin/carrays.hh (revision 0)
@@ -0,0 +1,83 @@
+// Copyright (C) 2009 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_VALUE_BUILTIN_CARRAYS_HH
+# define MLN_VALUE_BUILTIN_CARRAYS_HH
+
+/// \file mln/value/builtin/carrays.hh
+///
+/// Traits definition for C arrays.
+
+# include <sstream>
+
+# include <mln/value/concept/built_in.hh>
+# include <mln/value/concept/vectorial.hh>
+# include <mln/trait/value_.hh>
+
+
+namespace mln
+{
+
+
+ template <unsigned n, typename T>
+ struct category< T[n] >
+ {
+ typedef value::Built_In< value::Vectorial<void> > ret;
+ };
+
+
+ namespace trait
+ {
+
+ template <unsigned n, typename T>
+ struct value_< T[n] >
+ {
+ enum {
+ dim = n,
+ nbits = n * value_<T>::nbits,
+ card = n * value_<T>::card
+ };
+ typedef T comp;
+
+ typedef value::nature::vectorial nature;
+ typedef mln_trait_value_kind(T) kind;
+ typedef value::quant::high quant;
+
+ static const char* name()
+ {
+ std::ostringstream s;
+ s << value_<T>::name() << '[' << n << ']';
+ return s.str();
+ }
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_BUILTIN_CARRAYS_HH
Index: mln/value/builtin/floatings.hh
--- mln/value/builtin/floatings.hh (revision 3543)
+++ mln/value/builtin/floatings.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -60,10 +60,14 @@
namespace trait
{
+
+ // float.
+
template <>
struct value_< float >
{
enum {
+ dim = 1,
nbits = 8 * sizeof(float),
card = 0
};
@@ -95,10 +99,14 @@
};
+
+ // double.
+
template <>
struct value_< double >
{
enum {
+ dim = 1,
nbits = 8 * sizeof(double),
card = 0
};
Index: mln/value/builtin/all.hh
--- mln/value/builtin/all.hh (revision 3543)
+++ mln/value/builtin/all.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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 +29,15 @@
#ifndef MLN_VALUE_BUILTIN_ALL_HH
# define MLN_VALUE_BUILTIN_ALL_HH
-/*! \file mln/value/builtin/all.hh
- *
- * \brief File that includes all materials related to built-in types.
- */
+/// \file mln/value/builtin/all.hh
+///
+/// File that includes all materials related to built-in types.
-# include <mln/value/builtin/symbolics.hh>
+# include <mln/value/builtin/carrays.hh>
# include <mln/value/builtin/integers.hh>
# include <mln/value/builtin/floatings.hh>
+# include <mln/value/builtin/symbolics.hh>
# include <mln/value/builtin/promotions.hh>
# include <mln/value/builtin/ops.hh>
Index: mln/value/builtin/integers.hh
--- mln/value/builtin/integers.hh (revision 3543)
+++ mln/value/builtin/integers.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -73,6 +73,7 @@
public:
enum {
+ dim = 1,
nbits = n,
card = mln_value_card_from_(n)
};
Index: mln/algebra/vec.hh
--- mln/algebra/vec.hh (revision 3543)
+++ mln/algebra/vec.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2006, 2008, 2009 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
@@ -81,11 +81,12 @@
typedef trait::value::kind::data kind;
enum {
+ dim = n,
nbits = n * mln_nbits(T),
card = n * mln_card(T)
};
+ typedef T comp;
typedef mln_value_quant_from_(card) quant;
-
typedef algebra::vec<n, mln_sum(T)> sum;
};
Index: tests/trait/value/comp.cc
--- tests/trait/value/comp.cc (revision 0)
+++ tests/trait/value/comp.cc (revision 0)
@@ -0,0 +1,142 @@
+// Copyright (C) 2009 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/trait/value/comp.cc
+///
+/// Tests on mln_trait_value_comp.
+///
+/// \todo Add tests on some actual heterogeneous types.
+
+#include <mln/trait/value/comp.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/algebra/vec.hh>
+
+
+
+
+template <typename T, unsigned i, typename C>
+void check_equal()
+{
+ mlc_equal(mln_trait_value_comp(T, i), C)::check();
+}
+
+
+template <typename T>
+void check_scalar()
+{
+ mlc_equal(mln_trait_value_comp(T, 0), T)::check();
+}
+
+
+template <typename T, typename C>
+void check_homogeneous()
+{
+ mlc_equal(mln_trait_value_comp(T, 0), C)::check();
+}
+
+
+namespace mln
+{
+
+ template <typename R, typename G, typename B>
+ struct my_rgb;
+
+ namespace trait
+ {
+
+ template <typename R, typename G, typename B>
+ struct value_< my_rgb<R,G,B> >
+ {
+ enum { dim = 3 };
+ typedef void comp;
+ typedef R comp_0;
+ typedef G comp_1;
+ typedef B comp_2;
+ };
+
+ } // mln::trait
+
+} // mln
+
+
+
+template <typename T,
+ typename C0, typename C1, typename C2>
+void check_heterogeneous()
+{
+ mlc_equal(mln_trait_value_comp(T, 0), C0)::check();
+ mlc_equal(mln_trait_value_comp(T, 1), C1)::check();
+ mlc_equal(mln_trait_value_comp(T, 2), C2)::check();
+}
+
+
+
+int main()
+{
+ using namespace mln;
+
+
+ // Scalars.
+
+ {
+ typedef mln::value::int_u8 T;
+ check_scalar<T>();
+ check_equal<T, 0, T>();
+ }
+ {
+ typedef int T;
+ check_scalar<T>();
+ check_equal<T, 0, T>();
+ }
+
+
+ // Homogeneous vectors.
+
+ {
+ typedef float C;
+ typedef algebra::vec<2, C> T;
+ check_homogeneous< T, C >();
+ check_equal< T, 0, C >();
+ check_equal< T, 1, C >();
+ }
+ {
+ typedef double C;
+ typedef C T[2];
+ check_homogeneous< T, C >();
+ check_equal< T, 0, C >();
+ check_equal< T, 1, C >();
+ }
+
+
+ // Heterogeneous types.
+
+ {
+ check_heterogeneous< my_rgb< bool, unsigned, float* >,
+ bool, unsigned, float* >();
+ }
+}
Index: tests/trait/value/Makefile.am
--- tests/trait/value/Makefile.am (revision 3543)
+++ tests/trait/value/Makefile.am (working copy)
@@ -3,8 +3,10 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
+ comp \
values
+comp_SOURCES = comp.cc
values_SOURCES = values.cc
TESTS = $(check_PROGRAMS)
1
0
---
ChangeLog | 4 ++++
configure.ac | 1 +
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 35f0ba0..58297c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-03-18 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
+ * configure.ac: configure tests/accu/image.
+
2009-03-18 Roland Levillain <roland(a)lrde.epita.fr>
* configure.ac: Always configure directory external/trimesh/.
diff --git a/configure.ac b/configure.ac
index 0b05502..118ce2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -184,6 +184,7 @@ AC_CONFIG_FILES([milena/tests/data.hh])
AC_CONFIG_FILES([
milena/tests/Makefile
milena/tests/accu/Makefile
+ milena/tests/accu/image/Makefile
milena/tests/algebra/Makefile
milena/tests/arith/Makefile
milena/tests/binarization/Makefile
--
1.5.6.5
1
0