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
01 Sep '09
* mln/core/box_runstart_piter.hh,
* mln/core/dpsites_piter.hh,
* mln/core/image/complex_window_piter.hh: Add new init_() member.
* mln/core/image/graph_elt_mixed_neighborhood.hh,
* mln/core/image/graph_elt_mixed_window.hh,
* mln/core/mixed_neighb.hh: New.
* mln/core/image/graph_elt_neighborhood.hh,
* mln/core/image/graph_elt_window.hh: Get rid of a template
parameter.
* mln/core/image/graph_window_piter.hh: Add a selector for
do_start_() implementation.
* mln/core/image/vertex_image.hh: Add a new include.
* mln/core/internal/neighb_base.hh: New neighborhood base class.
* mln/core/internal/neighb_niter_base.hh: New neiborhood iterator
base class.
* mln/core/internal/neighb_niter_impl.hh: Add a new specialization
for graph_elt_mixed_window.
* mln/core/neighb.hh: Make inherit from neighb_base.
* mln/core/window.hh: Update header.
* tests/core/image/vertex_and_edge_image.cc: Use a
graph_elt_mixed_window.
---
milena/ChangeLog | 36 +++
milena/mln/core/box_runstart_piter.hh | 12 +
milena/mln/core/dpsites_piter.hh | 17 ++-
milena/mln/core/image/complex_window_piter.hh | 30 +++
...hborhood.hh => graph_elt_mixed_neighborhood.hh} | 20 +-
...aph_elt_window.hh => graph_elt_mixed_window.hh} | 55 ++---
milena/mln/core/image/graph_elt_neighborhood.hh | 11 +-
milena/mln/core/image/graph_elt_window.hh | 58 ++---
milena/mln/core/image/graph_window_piter.hh | 123 +++++++++--
milena/mln/core/image/vertex_image.hh | 1 +
milena/mln/core/internal/neighb_base.hh | 128 +++++++++++
milena/mln/core/internal/neighb_niter_base.hh | 148 ++++++++++++
milena/mln/core/internal/neighb_niter_impl.hh | 24 ++-
milena/mln/core/mixed_neighb.hh | 240 ++++++++++++++++++++
milena/mln/core/neighb.hh | 218 +++---------------
milena/mln/core/window.hh | 3 +-
milena/tests/core/image/vertex_and_edge_image.cc | 3 +-
17 files changed, 824 insertions(+), 303 deletions(-)
copy milena/mln/core/image/{graph_elt_neighborhood.hh => graph_elt_mixed_neighborhood.hh} (76%)
copy milena/mln/core/image/{graph_elt_window.hh => graph_elt_mixed_window.hh} (73%)
create mode 100644 milena/mln/core/internal/neighb_base.hh
create mode 100644 milena/mln/core/internal/neighb_niter_base.hh
create mode 100644 milena/mln/core/mixed_neighb.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index c996afc..d9a3461 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,41 @@
2009-08-24 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Introduce mixed windows and neighborhood for graph images.
+
+ * mln/core/box_runstart_piter.hh,
+ * mln/core/dpsites_piter.hh,
+ * mln/core/image/complex_window_piter.hh: Add new init_() member.
+
+ * mln/core/image/graph_elt_mixed_neighborhood.hh,
+ * mln/core/image/graph_elt_mixed_window.hh,
+ * mln/core/mixed_neighb.hh: New.
+
+ * mln/core/image/graph_elt_neighborhood.hh,
+ * mln/core/image/graph_elt_window.hh: Get rid of a template
+ parameter.
+
+ * mln/core/image/graph_window_piter.hh: Add a selector for
+ do_start_() implementation.
+
+ * mln/core/image/vertex_image.hh: Add a new include.
+
+ * mln/core/internal/neighb_base.hh: New neighborhood base class.
+
+ * mln/core/internal/neighb_niter_base.hh: New neiborhood iterator
+ base class.
+
+ * mln/core/internal/neighb_niter_impl.hh: Add a new specialization
+ for graph_elt_mixed_window.
+
+ * mln/core/neighb.hh: Make inherit from neighb_base.
+
+ * mln/core/window.hh: Update header.
+
+ * tests/core/image/vertex_and_edge_image.cc: Use a
+ graph_elt_mixed_window.
+
+2009-08-24 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Small fixes in Milena.
* mln/canvas/labeling/blobs.hh,
diff --git a/milena/mln/core/box_runstart_piter.hh b/milena/mln/core/box_runstart_piter.hh
index d58bc89..a777d1e 100644
--- a/milena/mln/core/box_runstart_piter.hh
+++ b/milena/mln/core/box_runstart_piter.hh
@@ -63,6 +63,9 @@ namespace mln
*/
box_runstart_piter(const box<P>& b);
+ /// Delayed initialization.
+ void init_(const box<P>& b);
+
box_runstart_piter();
/// Test the iterator validity.
@@ -101,9 +104,18 @@ namespace mln
inline
box_runstart_piter<P>::box_runstart_piter(const box<P>& b)
{
+ init_(b);
+ }
+
+ template <typename P>
+ inline
+ void
+ box_runstart_piter<P>::init_(const box<P>& b)
+ {
this->change_target(b);
}
+
template <typename P>
inline
bool
diff --git a/milena/mln/core/dpsites_piter.hh b/milena/mln/core/dpsites_piter.hh
index 0af9d9a..970fe0e 100644
--- a/milena/mln/core/dpsites_piter.hh
+++ b/milena/mln/core/dpsites_piter.hh
@@ -1,4 +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 Olena.
//
@@ -56,6 +57,10 @@ namespace mln
template <typename P>
dpsites_fwd_piter(const V& v, const P& c);
+ /// Delayed initialization.
+ template <typename P>
+ void init_(const V& v, const P& c);
+
/// Constructor without argument.
dpsites_fwd_piter();
@@ -139,10 +144,20 @@ namespace mln
inline
dpsites_fwd_piter<V>::dpsites_fwd_piter(const V& v, const P& c)
{
+ init_(v, c);
+ }
+
+ template <typename V>
+ template <typename P>
+ inline
+ void
+ dpsites_fwd_piter<V>::init_(const V& v, const P& c)
+ {
this->change_target(v);
this->center_at(c);
}
+
template <typename V>
inline
bool
diff --git a/milena/mln/core/image/complex_window_piter.hh b/milena/mln/core/image/complex_window_piter.hh
index 309f083..b723ec6 100644
--- a/milena/mln/core/image/complex_window_piter.hh
+++ b/milena/mln/core/image/complex_window_piter.hh
@@ -72,6 +72,10 @@ namespace mln
complex_window_fwd_piter(const Window<W>& win, const Pref& p_ref);
/// \}
+ /// Delayed initialization.
+ template <typename Pref>
+ void init_(const Window<W>& win, const Pref& p_ref);
+
/// Manipulation.
/// \{
/// Test if the iterator is valid.
@@ -138,6 +142,10 @@ namespace mln
complex_window_bkd_piter(const Window<W>& win, const Pref& p_ref);
/// \}
+ /// Delayed initialization.
+ template <typename Pref>
+ void init_(const Window<W>& win, const Pref& p_ref);
+
/// Manipulation.
/// \{
/// Test if the iterator is valid.
@@ -196,11 +204,22 @@ namespace mln
complex_window_fwd_piter<I, G, W>::complex_window_fwd_piter(const Window<W>& win,
const Pref& p_ref)
{
+ init_(win, p_ref);
+ }
+
+ template <typename I, typename G, typename W>
+ template <typename Pref>
+ inline
+ void
+ complex_window_fwd_piter<I, G, W>::init_(const Window<W>& win,
+ const Pref& p_ref)
+ {
this->change_target(exact(win));
center_at(p_ref);
mln_postcondition(!this->is_valid());
}
+
template <typename I, typename G, typename W>
inline
bool
@@ -293,11 +312,22 @@ namespace mln
complex_window_bkd_piter<I, G, W>::complex_window_bkd_piter(const Window<W>& win,
const Pref& p_ref)
{
+ init_(win, p_ref);
+ }
+
+ template <typename I, typename G, typename W>
+ template <typename Pref>
+ inline
+ void
+ complex_window_bkd_piter<I, G, W>::init_(const Window<W>& win,
+ const Pref& p_ref)
+ {
this->change_target(exact(win));
center_at(p_ref);
mln_postcondition(!this->is_valid());
}
+
template <typename I, typename G, typename W>
inline
bool
diff --git a/milena/mln/core/image/graph_elt_neighborhood.hh b/milena/mln/core/image/graph_elt_mixed_neighborhood.hh
similarity index 76%
copy from milena/mln/core/image/graph_elt_neighborhood.hh
copy to milena/mln/core/image/graph_elt_mixed_neighborhood.hh
index a1a739f..40245ce 100644
--- a/milena/mln/core/image/graph_elt_neighborhood.hh
+++ b/milena/mln/core/image/graph_elt_mixed_neighborhood.hh
@@ -24,15 +24,15 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_CORE_IMAGE_GRAPH_ELT_NEIGHBORHOOD_HH
-# define MLN_CORE_IMAGE_GRAPH_ELT_NEIGHBORHOOD_HH
+#ifndef MLN_CORE_IMAGE_GRAPH_ELT_MIXED_NEIGHBORHOOD_HH
+# define MLN_CORE_IMAGE_GRAPH_ELT_MIXED_NEIGHBORHOOD_HH
/// \file
///
/// Definition of the elementary ``neighborhood'' on a graph.
# include <mln/core/neighb.hh>
-# include <mln/core/image/graph_elt_window.hh>
+# include <mln/core/image/graph_elt_mixed_window.hh>
namespace mln
@@ -44,13 +44,13 @@ namespace mln
/// \tparam S is a site set type.
/// \tparam S2 is the site set type of the neighbors.
//
- template <typename G, typename S, typename S2 = S>
- struct graph_elt_neighborhood
- : public neighb< graph_elt_window<G,S,S2> >
+ template <typename G, typename S, typename S2>
+ struct graph_elt_mixed_neighborhood
+ : public neighb< graph_elt_mixed_window<G,S,S2> >
{
- typedef neighb< graph_elt_window<G,S,S2> > super_;
+ typedef neighb< graph_elt_mixed_window<G,S,S2> > super_;
- graph_elt_neighborhood();
+ graph_elt_mixed_neighborhood();
};
@@ -60,7 +60,7 @@ namespace mln
template <typename G, typename S, typename S2>
inline
- graph_elt_neighborhood<G,S,S2>::graph_elt_neighborhood()
+ graph_elt_mixed_neighborhood<G,S,S2>::graph_elt_mixed_neighborhood()
{
}
@@ -69,4 +69,4 @@ namespace mln
}
-#endif // ! MLN_CORE_IMAGE_GRAPH_ELT_NEIGHBORHOOD_HH
+#endif // ! MLN_CORE_IMAGE_GRAPH_ELT_MIXED_NEIGHBORHOOD_HH
diff --git a/milena/mln/core/image/graph_elt_window.hh b/milena/mln/core/image/graph_elt_mixed_window.hh
similarity index 73%
copy from milena/mln/core/image/graph_elt_window.hh
copy to milena/mln/core/image/graph_elt_mixed_window.hh
index 867a7bd..6ece878 100644
--- a/milena/mln/core/image/graph_elt_window.hh
+++ b/milena/mln/core/image/graph_elt_mixed_window.hh
@@ -1,5 +1,4 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,12 +23,13 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_CORE_IMAGE_GRAPH_ELT_WINDOW_HH
-# define MLN_CORE_IMAGE_GRAPH_ELT_WINDOW_HH
+#ifndef MLN_CORE_IMAGE_GRAPH_ELT_MIXED_WINDOW_HH
+# define MLN_CORE_IMAGE_GRAPH_ELT_MIXED_WINDOW_HH
/// \file
///
-/// Definition of the elementary ``window'' on a graph.
+/// Definition of the elementary ``window'' on a graph where elements
+/// are in a different site set from the center's.
# include <mln/core/concept/window.hh>
# include <mln/core/internal/neighborhood_base.hh>
@@ -41,7 +41,7 @@ namespace mln
{
/// Forward declaration
- template <typename G, typename S, typename S2> class graph_elt_window;
+ template <typename G, typename S, typename S2> class graph_elt_mixed_window;
template <typename G, typename F> struct p_edges;
template <typename G, typename F> struct p_vertices;
namespace util
@@ -55,8 +55,8 @@ namespace mln
{
template <typename G, typename S, typename S2, typename E>
- struct neighborhood_impl<graph_elt_window<G,S,S2>,E>
- : public neighborhood_extra_impl<graph_elt_window<G,S,S2>,E>
+ struct neighborhood_impl<graph_elt_mixed_window<G,S,S2>,E>
+ : public neighborhood_extra_impl<graph_elt_mixed_window<G,S,S2>,E>
{
};
@@ -70,29 +70,10 @@ namespace mln
/// extracted.
//
template <typename G, typename S, typename S2>
- struct graph_window_iter_dispatch;
-
- template <typename G, typename F>
- struct graph_window_iter_dispatch<G, p_edges<G,F>, p_edges<G,F> >
- {
- typedef mln_edge_nbh_edge_fwd_iter(G) nbh_fwd_iter_;
- typedef mln_edge_nbh_edge_bkd_iter(G) nbh_bkd_iter_;
-
- typedef p_edges<G,F> target;
- };
-
- template <typename G, typename F>
- struct graph_window_iter_dispatch<G, p_vertices<G,F>, p_vertices<G,F> >
- {
- typedef mln_vertex_nbh_vertex_fwd_iter(G) nbh_fwd_iter_;
- typedef mln_vertex_nbh_vertex_bkd_iter(G) nbh_bkd_iter_;
-
- typedef p_vertices<G,F> target;
- };
-
+ struct graph_mixed_window_iter_dispatch;
template <typename G, typename F, typename F2>
- struct graph_window_iter_dispatch<G, p_vertices<G,F>, p_edges<G,F2> >
+ struct graph_mixed_window_iter_dispatch<G, p_vertices<G,F>, p_edges<G,F2> >
{
typedef mln_vertex_nbh_edge_fwd_iter(G) nbh_fwd_iter_;
typedef mln_vertex_nbh_edge_bkd_iter(G) nbh_bkd_iter_;
@@ -108,7 +89,7 @@ namespace mln
{
template <typename G, typename S, typename S2>
- struct window_< mln::graph_elt_window<G,S,S2> >
+ struct window_< mln::graph_elt_mixed_window<G,S,S2> >
{
typedef trait::window::size::unknown size;
typedef trait::window::support::irregular support;
@@ -124,14 +105,14 @@ namespace mln
/// \p S2 is an image site set from where the neighbors are
/// extracted.
//
- template <typename G, typename S, typename S2 = S>
- class graph_elt_window
+ template <typename G, typename S, typename S2>
+ class graph_elt_mixed_window
: public graph_window_base<mln_result(S2::fun_t),
- graph_elt_window<G,S,S2> >,
- public internal::graph_window_iter_dispatch<G,S,S2>
+ graph_elt_mixed_window<G,S,S2> >,
+ public internal::graph_mixed_window_iter_dispatch<G,S,S2>
{
- typedef graph_elt_window<G,S,S2> self_;
- typedef internal::graph_window_iter_dispatch<G,S,S2> super_;
+ typedef graph_elt_mixed_window<G,S,S2> self_;
+ typedef internal::graph_mixed_window_iter_dispatch<G,S,S2> super_;
typedef typename super_::nbh_fwd_iter_ nbh_fwd_iter_;
typedef typename super_::nbh_bkd_iter_ nbh_bkd_iter_;
@@ -166,4 +147,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_CORE_IMAGE_GRAPH_ELT_WINDOW_HH
+#endif // ! MLN_CORE_IMAGE_GRAPH_ELT_MIXED_WINDOW_HH
diff --git a/milena/mln/core/image/graph_elt_neighborhood.hh b/milena/mln/core/image/graph_elt_neighborhood.hh
index a1a739f..b946067 100644
--- a/milena/mln/core/image/graph_elt_neighborhood.hh
+++ b/milena/mln/core/image/graph_elt_neighborhood.hh
@@ -42,13 +42,12 @@ namespace mln
///
/// \tparam G is a graph type.
/// \tparam S is a site set type.
- /// \tparam S2 is the site set type of the neighbors.
//
- template <typename G, typename S, typename S2 = S>
+ template <typename G, typename S>
struct graph_elt_neighborhood
- : public neighb< graph_elt_window<G,S,S2> >
+ : public neighb< graph_elt_window<G,S> >
{
- typedef neighb< graph_elt_window<G,S,S2> > super_;
+ typedef neighb< graph_elt_window<G,S> > super_;
graph_elt_neighborhood();
};
@@ -58,9 +57,9 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
- template <typename G, typename S, typename S2>
+ template <typename G, typename S>
inline
- graph_elt_neighborhood<G,S,S2>::graph_elt_neighborhood()
+ graph_elt_neighborhood<G,S>::graph_elt_neighborhood()
{
}
diff --git a/milena/mln/core/image/graph_elt_window.hh b/milena/mln/core/image/graph_elt_window.hh
index 867a7bd..b39c44e 100644
--- a/milena/mln/core/image/graph_elt_window.hh
+++ b/milena/mln/core/image/graph_elt_window.hh
@@ -41,7 +41,7 @@ namespace mln
{
/// Forward declaration
- template <typename G, typename S, typename S2> class graph_elt_window;
+ template <typename G, typename S> class graph_elt_window;
template <typename G, typename F> struct p_edges;
template <typename G, typename F> struct p_vertices;
namespace util
@@ -54,9 +54,9 @@ namespace mln
namespace internal
{
- template <typename G, typename S, typename S2, typename E>
- struct neighborhood_impl<graph_elt_window<G,S,S2>,E>
- : public neighborhood_extra_impl<graph_elt_window<G,S,S2>,E>
+ template <typename G, typename S, typename E>
+ struct neighborhood_impl<graph_elt_window<G,S>,E>
+ : public neighborhood_extra_impl<graph_elt_window<G,S>,E>
{
};
@@ -66,49 +66,32 @@ namespace mln
///
/// \p G is the graph type.
/// \p S is an image site set from where the center is extracted.
- /// \p S2 is an image site set from where the neighbors are
- /// extracted.
//
- template <typename G, typename S, typename S2>
+ template <typename G, typename S>
struct graph_window_iter_dispatch;
template <typename G, typename F>
- struct graph_window_iter_dispatch<G, p_edges<G,F>, p_edges<G,F> >
+ struct graph_window_iter_dispatch<G, p_edges<G,F> >
{
typedef mln_edge_nbh_edge_fwd_iter(G) nbh_fwd_iter_;
typedef mln_edge_nbh_edge_bkd_iter(G) nbh_bkd_iter_;
-
- typedef p_edges<G,F> target;
};
template <typename G, typename F>
- struct graph_window_iter_dispatch<G, p_vertices<G,F>, p_vertices<G,F> >
+ struct graph_window_iter_dispatch<G, p_vertices<G,F> >
{
typedef mln_vertex_nbh_vertex_fwd_iter(G) nbh_fwd_iter_;
typedef mln_vertex_nbh_vertex_bkd_iter(G) nbh_bkd_iter_;
-
- typedef p_vertices<G,F> target;
};
-
- template <typename G, typename F, typename F2>
- struct graph_window_iter_dispatch<G, p_vertices<G,F>, p_edges<G,F2> >
- {
- typedef mln_vertex_nbh_edge_fwd_iter(G) nbh_fwd_iter_;
- typedef mln_vertex_nbh_edge_bkd_iter(G) nbh_bkd_iter_;
-
- typedef p_edges<G,F2> target;
- };
-
-
} // end of namespace mln::internal
namespace trait
{
- template <typename G, typename S, typename S2>
- struct window_< mln::graph_elt_window<G,S,S2> >
+ template <typename G, typename S>
+ struct window_< mln::graph_elt_window<G,S> >
{
typedef trait::window::size::unknown size;
typedef trait::window::support::irregular support;
@@ -124,14 +107,14 @@ namespace mln
/// \p S2 is an image site set from where the neighbors are
/// extracted.
//
- template <typename G, typename S, typename S2 = S>
+ template <typename G, typename S>
class graph_elt_window
- : public graph_window_base<mln_result(S2::fun_t),
- graph_elt_window<G,S,S2> >,
- public internal::graph_window_iter_dispatch<G,S,S2>
+ : public graph_window_base<mln_result(S::fun_t),
+ graph_elt_window<G,S> >,
+ public internal::graph_window_iter_dispatch<G,S>
{
- typedef graph_elt_window<G,S,S2> self_;
- typedef internal::graph_window_iter_dispatch<G,S,S2> super_;
+ typedef graph_elt_window<G,S> self_;
+ typedef internal::graph_window_iter_dispatch<G,S> super_;
typedef typename super_::nbh_fwd_iter_ nbh_fwd_iter_;
typedef typename super_::nbh_bkd_iter_ nbh_bkd_iter_;
@@ -139,23 +122,24 @@ namespace mln
public:
/// Associated types.
/// \{
- typedef typename super_::target target;
+ typedef S target;
+
/// The type of psite corresponding to the window.
- typedef mln_psite(target) psite;
+ typedef mln_psite(S) psite;
/// Type of the window center element.
typedef mln_psite(S) center_t;
/// Type of the graph element pointed by this iterator.
- typedef mln_graph_element(target) graph_element;
+ typedef mln_graph_element(S) graph_element;
/// Site_Iterator type to browse the psites of the window
/// w.r.t. the ordering of vertices.
- typedef graph_window_piter<target,self_,nbh_fwd_iter_> fwd_qiter;
+ typedef graph_window_piter<S,self_,nbh_fwd_iter_> fwd_qiter;
/// Site_Iterator type to browse the psites of the window
/// w.r.t. the reverse ordering of vertices.
- typedef graph_window_piter<target,self_,nbh_bkd_iter_> bkd_qiter;
+ typedef graph_window_piter<S,self_,nbh_bkd_iter_> bkd_qiter;
/// The default qiter type.
typedef fwd_qiter qiter;
diff --git a/milena/mln/core/image/graph_window_piter.hh b/milena/mln/core/image/graph_window_piter.hh
index 7812767..8ea77db 100644
--- a/milena/mln/core/image/graph_window_piter.hh
+++ b/milena/mln/core/image/graph_window_piter.hh
@@ -30,6 +30,9 @@
/// \file
///
/// Definition of a graph element iterator on a graph window.
+///
+/// \fixme Split into graph_window_piter, graph_mixed_window_piter and
+/// graph_window_piter_base.
# include <mln/core/concept/site_set.hh>
# include <mln/core/concept/window.hh>
@@ -42,6 +45,59 @@ namespace mln
// Forward declaration.
template <typename S, typename I> class p_graph_piter;
+
+ namespace internal
+ {
+
+ /// The window center and the window elements are part of
+ /// different site sets.
+ template <typename C, typename P, typename E>
+ struct impl_selector
+ {
+ E& exact()
+ {
+ return internal::force_exact<E>(*this);
+ }
+
+ void do_start_()
+ {
+ exact().iter_.start();
+ // Nothing else to do. A pointer to the window element's site
+ // set has been already stored in the constructor.
+ }
+
+ };
+
+ /// The window center and the window elements are part of the same
+ /// site set.
+ template <typename C, typename E>
+ struct impl_selector<C,C,E>
+ {
+ E& exact()
+ {
+ return internal::force_exact<E>(*this);
+ }
+
+ void do_start_()
+ {
+ exact().iter_.start();
+
+ // We need to store a pointer on the site set of the window
+ // center.
+ // We cannot do this in the constructor since the center may
+ // not be initialized.
+ // Here we suppose that if we start this iterator, the
+ // potential iterator used as center has been started just
+ // before calling this method.
+ //
+ exact().change_target_site_set(exact().center().site_set());
+ }
+
+ };
+
+ } // end of namespace mln::internal
+
+
/// Forward iterator on line graph window.
///
/// \tparam S is the site set type.
@@ -52,11 +108,17 @@ namespace mln
class graph_window_piter
: public internal::site_relative_iterator_base< W,
graph_window_piter<S,W,I>,
- typename W::center_t >
+ typename W::center_t >,
+ public internal::impl_selector<typename W::center_t, mln_psite(W),
+ graph_window_piter<S,W,I> >
{
typedef graph_window_piter<S,W,I> self_;
typedef
internal::site_relative_iterator_base<W,self_,mln_psite(S)> super_;
+ typedef
+ internal::impl_selector<typename W::center_t, mln_psite(W),
+ graph_window_piter<S,W,I> > super_impl_;
+
public:
/// Associated types
@@ -103,6 +165,17 @@ namespace mln
const Pref& p_ref);
/// \}
+ /// Delayed initialization.
+ /// \{
+ template <typename Pref>
+ void init_(const Window<W>& win, const Pref& p_ref);
+
+ template <typename Pref>
+ void init_(const Window<W>& win,
+ const Site_Set<S>& target_site_set,
+ const Pref& p_ref);
+ /// \}
+
/// Manipulation.
/// \{
/// Test if the iterator is valid.
@@ -110,8 +183,6 @@ namespace mln
/// Invalidate the iterator.
void invalidate_();
- /// Start an iteration.
- void do_start_();
/// Go to the next point.
void do_next_();
@@ -139,6 +210,11 @@ namespace mln
void change_target_site_set(const S& s);
const S& target_site_set() const;
+ using super_impl_::do_start_;
+
+ friend class internal::impl_selector<typename W::center_t, mln_psite(W),
+ graph_window_piter<S,W,I> > ;
+
private:
I iter_;
const S* s_;
@@ -166,12 +242,7 @@ namespace mln
// Center and neighbor sites have the same type and belong to
// the same site set.
mlc_is(center_t, mln_psite(W))::check();
-
- this->center_at(p_ref);
- this->change_target(exact(win));
- change_target_site_set(this->center().site_set());
-
- mln_postcondition(!this->is_valid());
+ init_(win, p_ref);
}
@@ -186,14 +257,36 @@ namespace mln
// Center and neighbors sites do not have the same type and do
// not belong to the same site set.
mlc_is_not(center_t, mln_psite(W))::check();
+ init_(win, target_site_set, p_ref);
+ }
+ template <typename S, typename W, typename I>
+ template <typename Pref>
+ inline
+ void
+ graph_window_piter<S,W,I>::init_(const Window<W>& win,
+ const Pref& p_ref)
+ {
this->center_at(p_ref);
this->change_target(exact(win));
- change_target_site_set(exact(target_site_set));
mln_postcondition(!this->is_valid());
}
+ template <typename S, typename W, typename I>
+ template <typename Pref>
+ inline
+ void
+ graph_window_piter<S,W,I>::init_(const Window<W>& win,
+ const Site_Set<S>& target_site_set,
+ const Pref& p_ref)
+ {
+ this->center_at(p_ref);
+ this->change_target(exact(win));
+ change_target_site_set(exact(target_site_set));
+ mln_postcondition(!this->is_valid());
+ }
+
template <typename S, typename W, typename I>
inline
@@ -214,14 +307,6 @@ namespace mln
template <typename S, typename W, typename I>
inline
void
- graph_window_piter<S,W,I>::do_start_()
- {
- iter_.start();
- }
-
- template <typename S, typename W, typename I>
- inline
- void
graph_window_piter<S,W,I>::do_next_()
{
iter_.next();
@@ -234,7 +319,6 @@ namespace mln
graph_window_piter<S, W, I>::center_at_(const Pref& c)
{
iter_.center_at(c.p_hook_());
- //FIXME: should we update target site set?
}
template <typename S, typename W, typename I>
@@ -244,7 +328,6 @@ namespace mln
graph_window_piter<S, W, I>::center_at_(const p_graph_piter<S2, I2>& c)
{
iter_.center_at(c.hook_elt_());
- //FIXME: should we update target site set?
}
template <typename S, typename W, typename I>
diff --git a/milena/mln/core/image/vertex_image.hh b/milena/mln/core/image/vertex_image.hh
index fd7d2eb..3ce7ed5 100644
--- a/milena/mln/core/image/vertex_image.hh
+++ b/milena/mln/core/image/vertex_image.hh
@@ -33,6 +33,7 @@
# include <mln/core/concept/graph.hh>
# include <mln/core/image/graph_elt_window.hh>
# include <mln/core/image/graph_elt_neighborhood.hh>
+# include <mln/core/image/graph_elt_mixed_neighborhood.hh>
# include <mln/core/site_set/p_vertices.hh>
# include <mln/pw/internal/image_base.hh>
# include <mln/fun/i2v/array.hh>
diff --git a/milena/mln/core/internal/neighb_base.hh b/milena/mln/core/internal/neighb_base.hh
new file mode 100644
index 0000000..bfb499a
--- /dev/null
+++ b/milena/mln/core/internal/neighb_base.hh
@@ -0,0 +1,128 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_CORE_INTERNAL_NEIGHB_BASE_HH
+# define MLN_CORE_INTERNAL_NEIGHB_BASE_HH
+
+/// \file
+///
+/// Base implementation for neighborhood classes.
+
+# include <mln/core/internal/neighborhood_base.hh>
+# include <mln/core/internal/site_relative_iterator_base.hh>
+# include <mln/core/internal/neighb_niter_impl.hh>
+
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+
+ /// Adapter class from window to neighborhood.
+ ///
+ /// \tparam W The underlying window type.
+ /// \tparam E The exact neighborhood type.
+ //
+ template <typename W, typename E>
+ class neighb_base
+ : public internal::neighborhood_base< W, E >,
+ private mlc_is_a(W, Window)::check_t
+ {
+ public:
+
+ /// Constructor without argument.
+ neighb_base();
+
+ /// Constructor from a window \p win.
+ neighb_base(const W& win);
+
+ /// Get the corresponding window.
+ const W& win() const;
+
+ /// Change the corresponding window.
+ void change_window(const W& new_win);
+
+
+ /// \internal Hook to the window.
+ W& hook_win_();
+
+ private:
+
+ W win_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // neighb<W,E>
+
+ template <typename W, typename E>
+ inline
+ neighb_base<W,E>::neighb_base()
+ {
+ }
+
+ template <typename W, typename E>
+ inline
+ neighb_base<W,E>::neighb_base(const W& win)
+ {
+ change_window(win);
+ }
+
+ template <typename W, typename E>
+ inline
+ const W&
+ neighb_base<W,E>::win() const
+ {
+ return win_;
+ }
+
+ template <typename W, typename E>
+ inline
+ void
+ neighb_base<W,E>::change_window(const W& new_win)
+ {
+ mln_precondition(new_win.is_neighbable_());
+ win_ = new_win;
+ }
+
+ template <typename W, typename E>
+ inline
+ W&
+ neighb_base<W,E>::hook_win_()
+ {
+ return win_;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_NEIGHB_BASE_HH
diff --git a/milena/mln/core/internal/neighb_niter_base.hh b/milena/mln/core/internal/neighb_niter_base.hh
new file mode 100644
index 0000000..6aba054
--- /dev/null
+++ b/milena/mln/core/internal/neighb_niter_base.hh
@@ -0,0 +1,148 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_CORE_INTERNAL_NEIGHB_NITER_BASE_HH
+# define MLN_CORE_INTERNAL_NEIGHB_NITER_BASE_HH
+
+/// \file
+///
+/// Base implementation for neighborhood iterators.
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ // neighb_niter_base<W,I,E>
+
+ template <typename W, typename N, typename I, typename E>
+ class neighb_niter_base
+ : public internal::site_relative_iterator_base< N,
+ E,
+ mln_psite(N) >,
+ public internal::neighb_niter_impl<W,E>
+ {
+ public:
+
+ /// Constructor without argument.
+ neighb_niter_base();
+
+ template <typename P>
+ neighb_niter_base(const N& nbh, const P& c);
+
+ /// Test the iterator validity.
+ bool is_valid_() const;
+
+ /// Invalidate the iterator.
+ void invalidate_();
+
+ /// Start an iteration.
+ void do_start_();
+
+ /// Go to the next point.
+ void do_next_();
+
+ /// Compute the current psite.
+ mln_psite(W) compute_p_() const;
+
+ protected:
+
+ I i_;
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // neighb_niter_base<W,N,I,E>
+
+ template <typename W, typename N, typename I, typename E>
+ inline
+ neighb_niter_base<W,N,I,E>::neighb_niter_base()
+ {
+ }
+
+ template <typename W, typename N, typename I, typename E>
+ template <typename P>
+ inline
+ neighb_niter_base<W,N,I,E>::neighb_niter_base(const N& nbh, const P& c)
+ {
+ this->change_target(nbh);
+ this->center_at(c);
+
+ }
+
+ template <typename W, typename N, typename I, typename E>
+ inline
+ bool
+ neighb_niter_base<W,N,I,E>::is_valid_() const
+ {
+ return i_.is_valid();
+ }
+
+ template <typename W, typename N, typename I, typename E>
+ inline
+ void
+ neighb_niter_base<W,N,I,E>::invalidate_()
+ {
+ i_.invalidate();
+ }
+
+ template <typename W, typename N, typename I, typename E>
+ inline
+ void
+ neighb_niter_base<W,N,I,E>::do_start_()
+ {
+ i_.start();
+ }
+
+ template <typename W, typename N, typename I, typename E>
+ inline
+ void
+ neighb_niter_base<W,N,I,E>::do_next_()
+ {
+ i_.next();
+ }
+
+ template <typename W, typename N, typename I, typename E>
+ inline
+ mln_psite(W)
+ neighb_niter_base<W,N,I,E>::compute_p_() const
+ {
+ return i_.compute_p_();
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::internal
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_INTERNAL_NEIGHB_NITER_BASE_HH
diff --git a/milena/mln/core/internal/neighb_niter_impl.hh b/milena/mln/core/internal/neighb_niter_impl.hh
index ea44822..f2c8ee0 100644
--- a/milena/mln/core/internal/neighb_niter_impl.hh
+++ b/milena/mln/core/internal/neighb_niter_impl.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -39,7 +40,8 @@ namespace mln
// Forward declaration.
template <typename P, typename W> class graph_window_base;
- template <typename G, typename F, typename Q> class graph_elt_window;
+ template <typename G, typename S> class graph_elt_window;
+ template <typename G, typename S, typename S2> class graph_elt_mixed_window;
template <typename G, typename F, typename I> class graph_elt_window_if;
template <typename G, typename F> class line_graph_elt_window;
namespace util
@@ -124,10 +126,10 @@ namespace mln
/// Add more implementation for neighborhoods made from a
/// graph_window_piter.
- template <typename G, typename S, typename Q, typename E>
- struct neighb_niter_impl<graph_elt_window<G,S,Q>, E>
+ template <typename G, typename S, typename E>
+ struct neighb_niter_impl<graph_elt_window<G,S>, E>
: public neighb_niter_impl< graph_window_base< mln_result(S::fun_t),
- graph_elt_window<G,S,Q> >,
+ graph_elt_window<G,S> >,
E >
{
@@ -157,6 +159,18 @@ namespace mln
};
+ /// Add more implementation for neighborhoods made from a
+ /// graph_window_piter.
+ template <typename G, typename S, typename S2, typename E>
+ struct neighb_niter_impl<graph_elt_mixed_window<G,S,S2>, E>
+ : public neighb_niter_impl< graph_window_base< mln_result(S2::fun_t),
+ graph_elt_mixed_window<G,S,S2> >,
+ E >
+ {
+
+ };
+
+
} // end of namespace mln::internal
} // end of namespace mln
diff --git a/milena/mln/core/mixed_neighb.hh b/milena/mln/core/mixed_neighb.hh
new file mode 100644
index 0000000..377bab1
--- /dev/null
+++ b/milena/mln/core/mixed_neighb.hh
@@ -0,0 +1,240 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_CORE_MIXED_NEIGHB_HH
+# define MLN_CORE_MIXED_NEIGHB_HH
+
+/// \file
+///
+/// Definition of a window-to-neighborhood adapter.
+///
+/// Works for windows and neighborhoods having the elements' site set
+/// different from the center's site set.
+///
+///
+/// \todo See if the impl of from_to is fine. What about removing the
+/// origin? etc.
+
+# include <mln/core/internal/neighb_base.hh>
+# include <mln/core/internal/neighb_niter_base.hh>
+# include <mln/core/internal/site_relative_iterator_base.hh>
+# include <mln/core/internal/neighb_niter_impl.hh>
+
+
+namespace mln
+{
+
+ // Forward declarations.
+ template <typename W> class mixed_neighb_fwd_niter;
+ template <typename W> class mixed_neighb_bkd_niter;
+ template <typename W> class mixed_neighb;
+
+
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ template <typename W>
+ void
+ from_to_(const mln::mixed_neighb<W>& from, W& to);
+
+ template <typename W>
+ void
+ from_to_(const W& from, mln::mixed_neighb<W>& to);
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+
+
+
+ /// Adapter class from window to neighborhood.
+
+ template <typename W>
+ class mixed_neighb
+ : public internal::neighb_base<W,mixed_neighb<W> >,
+ private mlc_is_a(W, Window)::check_t
+ {
+ typedef internal::neighb_base<W,mixed_neighb<W> > super_;
+
+ public:
+
+ /// Forward site iterator associated type.
+ typedef mixed_neighb_fwd_niter<W> fwd_niter;
+
+ /// Backward site iterator associated type.
+ typedef mixed_neighb_bkd_niter<W> bkd_niter;
+
+ /// Site iterator associated type.
+ typedef fwd_niter niter;
+
+
+ /// Constructor without argument.
+ mixed_neighb();
+
+ /// Constructor from a window \p win.
+ mixed_neighb(const W& win);
+
+ };
+
+
+ // mixed_neighb_fwd_niter<W>
+
+ template <typename W>
+ class mixed_neighb_fwd_niter
+ : public internal::neighb_niter_base<W,mixed_neighb<W>,
+ mln_fwd_qiter(W),neighb_fwd_niter<W> >
+ {
+ typedef
+ internal::neighb_niter_base<W,mixed_neighb<W>,
+ mln_fwd_qiter(W),neighb_fwd_niter<W> > super_;
+
+ public:
+ mixed_neighb_fwd_niter();
+
+ template <typename P>
+ mixed_neighb_fwd_niter(const mixed_neighb<W>& nbh, const P& c);
+
+ };
+
+
+
+ // mixed_neighb_bkd_niter<W,E>
+
+ template <typename W>
+ class mixed_neighb_bkd_niter
+ : public internal::neighb_niter_base<W,mixed_neighb<W>,
+ mln_bkd_qiter(W),neighb_bkd_niter<W> >
+ {
+ typedef
+ internal::neighb_niter_base<W,mixed_neighb<W>,
+ mln_bkd_qiter(W),neighb_bkd_niter<W> > super_;
+
+ public:
+ mixed_neighb_bkd_niter();
+
+ template <typename P>
+ mixed_neighb_bkd_niter(const mixed_neighb<W>& nbh, const P& c);
+
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // mixed_neighb<W>
+
+ template <typename W>
+ inline
+ mixed_neighb<W>::mixed_neighb()
+ {
+ }
+
+ template <typename W>
+ inline
+ mixed_neighb<W>::mixed_neighb(const W& win)
+ : super_(win)
+ {
+ }
+
+
+ // mln::convert::from_to
+
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ template <typename W>
+ void
+ from_to_(const mln::mixed_neighb<W>& from, W& to)
+ {
+ to = from.win();
+ }
+
+ template <typename W>
+ void
+ from_to_(const W& from, mln::mixed_neighb<W>& to)
+ {
+ to.change_window(from);
+ }
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+
+
+
+
+ // mixed_neighb_fwd_niter<W>
+
+ template <typename W>
+ inline
+ mixed_neighb_fwd_niter<W>::mixed_neighb_fwd_niter()
+ {
+ }
+
+ template <typename W>
+ template <typename P>
+ inline
+ mixed_neighb_fwd_niter<W>::mixed_neighb_fwd_niter(const mixed_neighb<W>& nbh,
+ const mln_target(W)& nbh_site_set,
+ const P& c)
+ : super_(nbh, c)
+ {
+ this->i_.init_(nbh.win(), nbh_site_set, c);
+ }
+
+
+
+ // mixed_neighb_bkd_niter<W>
+
+ template <typename W>
+ inline
+ mixed_neighb_bkd_niter<W>::mixed_neighb_bkd_niter()
+ {
+ }
+
+ template <typename W>
+ template <typename P>
+ inline
+ mixed_neighb_bkd_niter<W>::mixed_neighb_bkd_niter(const mixed_neighb<W>& nbh,
+ const mln_target(W)& nbh_site_set,
+ const P& c)
+ : super_(nbh, c)
+ {
+ this->i_.init_(nbh.win(), nbh_site_set, c);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_MIXED_NEIGHB_HH
diff --git a/milena/mln/core/neighb.hh b/milena/mln/core/neighb.hh
index 8ce148e..db31bea 100644
--- a/milena/mln/core/neighb.hh
+++ b/milena/mln/core/neighb.hh
@@ -35,7 +35,8 @@
/// \todo See if the impl of from_to is fine. What about removing the
/// origin? etc.
-# include <mln/core/internal/neighborhood_base.hh>
+# include <mln/core/internal/neighb_base.hh>
+# include <mln/core/internal/neighb_niter_base.hh>
# include <mln/core/internal/site_relative_iterator_base.hh>
# include <mln/core/internal/neighb_niter_impl.hh>
@@ -72,9 +73,11 @@ namespace mln
/// Adapter class from window to neighborhood.
template <typename W>
- class neighb : public internal::neighborhood_base< W, neighb<W> >,
- private mlc_is_a(W, Window)::check_t
+ class neighb
+ : public internal::neighb_base<W,neighb<W> >
{
+ typedef internal::neighb_base<W,neighb<W> > super_;
+
public:
/// Forward site iterator associated type.
@@ -93,98 +96,48 @@ namespace mln
/// Constructor from a window \p win.
neighb(const W& win);
- /// Get the corresponding window.
- const W& win() const;
-
- /// Change the corresponding window.
- void change_window(const W& new_win);
-
-
- /// \internal Hook to the window.
- W& hook_win_();
-
- private:
-
- W win_;
};
-
// neighb_fwd_niter<W>
template <typename W>
class neighb_fwd_niter
- : public internal::site_relative_iterator_base< neighb<W>,
- neighb_fwd_niter<W>,
- mln_psite(neighb<W>) >,
- public internal::neighb_niter_impl<W, neighb_fwd_niter<W> >
+ : public internal::neighb_niter_base<W,neighb<W>,
+ mln_fwd_qiter(W),neighb_fwd_niter<W> >
{
- public:
+ typedef
+ internal::neighb_niter_base<W,neighb<W>,
+ mln_fwd_qiter(W),neighb_fwd_niter<W> > super_;
- /// Constructor without argument.
+ public:
neighb_fwd_niter();
template <typename P>
neighb_fwd_niter(const neighb<W>& nbh, const P& c);
- /// Test the iterator validity.
- bool is_valid_() const;
-
- /// Invalidate the iterator.
- void invalidate_();
-
- /// Start an iteration.
- void do_start_();
-
- /// Go to the next point.
- void do_next_();
-
- /// Compute the current psite.
- mln_psite(W) compute_p_() const;
-
- protected:
-
- mln_fwd_qiter(W) i_;
};
-// neighb_bkd_niter<W>
-
-template <typename W>
-class neighb_bkd_niter
- : public internal::site_relative_iterator_base< neighb<W>,
- neighb_bkd_niter<W>,
- mln_psite(neighb<W>)>,
- public internal::neighb_niter_impl<W, neighb_fwd_niter<W> >
-{
-public:
-
- /// Constructor without argument.
- neighb_bkd_niter();
-
- template <typename P>
- neighb_bkd_niter(const neighb<W>& nbh, const P& c);
-
- /// Test the iterator validity.
- bool is_valid_() const;
-
- /// Invalidate the iterator.
- void invalidate_();
-
- /// Start an iteration.
- void do_start_();
+ // neighb_bkd_niter<W,E>
- /// Go to the next point.
- void do_next_();
+ template <typename W>
+ class neighb_bkd_niter
+ : public internal::neighb_niter_base<W,neighb<W>,
+ mln_bkd_qiter(W),neighb_bkd_niter<W> >
+ {
+ typedef
+ internal::neighb_niter_base<W,neighb<W>,
+ mln_bkd_qiter(W),neighb_bkd_niter<W> > super_;
- /// Compute the current psite.
- mln_psite(W) compute_p_() const;
+ public:
+ neighb_bkd_niter();
-protected:
+ template <typename P>
+ neighb_bkd_niter(const neighb<W>& nbh, const P& c);
- mln_bkd_qiter(W) i_;
-};
+ };
@@ -201,33 +154,8 @@ protected:
template <typename W>
inline
neighb<W>::neighb(const W& win)
+ : super_(win)
{
- change_window(win);
- }
-
- template <typename W>
- inline
- const W&
- neighb<W>::win() const
- {
- return win_;
- }
-
- template <typename W>
- inline
- void
- neighb<W>::change_window(const W& new_win)
- {
- mln_precondition(new_win.is_neighbable_());
- win_ = new_win;
- }
-
- template <typename W>
- inline
- W&
- neighb<W>::hook_win_()
- {
- return win_;
}
@@ -258,6 +186,8 @@ protected:
} // end of namespace mln::convert
+
+
// neighb_fwd_niter<W>
template <typename W>
@@ -270,52 +200,11 @@ protected:
template <typename P>
inline
neighb_fwd_niter<W>::neighb_fwd_niter(const neighb<W>& nbh, const P& c)
+ : super_(nbh, c)
{
- this->change_target(nbh);
- this->center_at(c);
- i_.center_at(c); // Always before change_target for this kind of iter.
- i_.change_target(nbh.win());
- }
-
- template <typename W>
- inline
- bool
- neighb_fwd_niter<W>::is_valid_() const
- {
- return i_.is_valid();
- }
-
- template <typename W>
- inline
- void
- neighb_fwd_niter<W>::invalidate_()
- {
- i_.invalidate();
- }
-
- template <typename W>
- inline
- void
- neighb_fwd_niter<W>::do_start_()
- {
- i_.start();
- }
-
- template <typename W>
- inline
- void
- neighb_fwd_niter<W>::do_next_()
- {
- i_.next();
+ this->i_.init_(nbh.win(), c);
}
- template <typename W>
- inline
- mln_psite(W)
- neighb_fwd_niter<W>::compute_p_() const
- {
- return i_.compute_p_();
- }
// neighb_bkd_niter<W>
@@ -330,52 +219,11 @@ protected:
template <typename P>
inline
neighb_bkd_niter<W>::neighb_bkd_niter(const neighb<W>& nbh, const P& c)
+ : super_(nbh, c)
{
- this->change_target(nbh);
- this->center_at(c);
- i_.center_at(c); // Always before change_target for this kind of iter.
- i_.change_target(nbh.win());
+ this->i_.init_(nbh.win(), c);
}
- template <typename W>
- inline
- bool
- neighb_bkd_niter<W>::is_valid_() const
- {
- return i_.is_valid();
- }
-
- template <typename W>
- inline
- void
- neighb_bkd_niter<W>::invalidate_()
- {
- i_.invalidate();
- }
-
- template <typename W>
- inline
- void
- neighb_bkd_niter<W>::do_start_()
- {
- i_.start();
- }
-
- template <typename W>
- inline
- void
- neighb_bkd_niter<W>::do_next_()
- {
- i_.next();
- }
-
- template <typename W>
- inline
- mln_psite(W)
- neighb_bkd_niter<W>::compute_p_() const
- {
- return i_.compute_p_();
- }
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/core/window.hh b/milena/mln/core/window.hh
index af8d079..87f1940 100644
--- a/milena/mln/core/window.hh
+++ b/milena/mln/core/window.hh
@@ -1,4 +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 Olena.
//
diff --git a/milena/tests/core/image/vertex_and_edge_image.cc b/milena/tests/core/image/vertex_and_edge_image.cc
index 60a4609..05aa059 100644
--- a/milena/tests/core/image/vertex_and_edge_image.cc
+++ b/milena/tests/core/image/vertex_and_edge_image.cc
@@ -25,6 +25,7 @@
#include <vector>
+#include <mln/core/image/graph_elt_mixed_window.hh>
#include <mln/core/image/vertex_image.hh>
#include <mln/core/image/edge_image.hh>
#include <mln/fun/i2v/array.hh>
@@ -123,7 +124,7 @@ int main()
mln_piter_(v_ima_t) v(v_ima.domain());
- typedef graph_elt_window<util::graph,
+ typedef graph_elt_mixed_window<util::graph,
v_ima_t::domain_t,
e_ima_t::domain_t> edge_win_t;
edge_win_t win;
--
1.5.6.5
2
1
* levillain/double.cc, levillain/min-max.cc: New.
* levillain/Makefile: New.
---
milena/sandbox/ChangeLog | 7 +++++
milena/sandbox/levillain/.gitignore | 2 +
milena/sandbox/levillain/double.cc | 47 ++++++++++++++++++++++++++++++++++
milena/sandbox/levillain/min-max.cc | 48 +++++++++++++++++++++++++++++++++++
4 files changed, 104 insertions(+), 0 deletions(-)
create mode 100644 milena/sandbox/levillain/.gitignore
create mode 100644 milena/sandbox/levillain/double.cc
create mode 100644 milena/sandbox/levillain/min-max.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index dfba024..95e28a5 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,10 @@
+2009-08-31 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Add some examples for Laurent.
+
+ * levillain/double.cc, levillain/min-max.cc: New.
+ * levillain/Makefile: New.
+
2009-08-31 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Write the kmean main loop.
diff --git a/milena/sandbox/levillain/.gitignore b/milena/sandbox/levillain/.gitignore
new file mode 100644
index 0000000..627984b
--- /dev/null
+++ b/milena/sandbox/levillain/.gitignore
@@ -0,0 +1,2 @@
+double
+min-max
diff --git a/milena/sandbox/levillain/double.cc b/milena/sandbox/levillain/double.cc
new file mode 100644
index 0000000..67e931c
--- /dev/null
+++ b/milena/sandbox/levillain/double.cc
@@ -0,0 +1,47 @@
+#include <mln/value/int_u8.hh>
+#include <mln/core/image/image2d.hh>
+
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+
+int main()
+{
+ using namespace mln;
+ using mln::value::int_u8;
+
+ image2d<int_u8> ima(5, 5);
+ debug::iota(ima);
+ debug::println(ima);
+ /* ima =
+
+ 1 2 3 4 5
+ 6 7 8 9 10
+ 11 12 13 14 15
+ 16 17 18 19 20
+ 21 22 23 24 25 */
+
+ image2d<int_u8> ima_x2 (10, 10);
+ mln_piter_(image2d<int_u8>) p(ima_x2.domain());
+ for_all(p)
+ {
+ /* This conversion from ``piter'' to ``point'' is required, since
+ an iterator does not expose the interface of the underlying
+ point (among which the methods row(), col(), etc.). */
+ point2d p_ = p;
+ point2d q(p_.row() / 2, p_.col() / 2);
+ ima_x2(p) = ima(q);
+ }
+ debug::println(ima_x2);
+ /* ima_x2 =
+
+ 1 1 2 2 3 3 4 4 5 5
+ 1 1 2 2 3 3 4 4 5 5
+ 6 6 7 7 8 8 9 9 10 10
+ 6 6 7 7 8 8 9 9 10 10
+ 11 11 12 12 13 13 14 14 15 15
+ 11 11 12 12 13 13 14 14 15 15
+ 16 16 17 17 18 18 19 19 20 20
+ 16 16 17 17 18 18 19 19 20 20
+ 21 21 22 22 23 23 24 24 25 25
+ 21 21 22 22 23 23 24 24 25 25 */
+}
diff --git a/milena/sandbox/levillain/min-max.cc b/milena/sandbox/levillain/min-max.cc
new file mode 100644
index 0000000..d9c473a
--- /dev/null
+++ b/milena/sandbox/levillain/min-max.cc
@@ -0,0 +1,48 @@
+#include <iostream>
+
+#include <mln/value/int_u8.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+
+#include <mln/accu/stat/min_max.hh>
+
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+
+#include <mln/core/var.hh>
+
+int main()
+{
+ using namespace mln;
+ using mln::value::int_u8;
+
+ image2d<int_u8> ima(5, 5);
+ debug::iota(ima);
+ /* ima =
+
+ 1 2 3 4 5
+ 6 7 8 9 10
+ 11 12 13 14 15
+ 16 17 18 19 20
+ 21 22 23 24 25 */
+
+ // A region delimited by a box (could also be something more complicated).
+ point2d x(1, 1);
+ point2d y(3, 4);
+ box2d region(x, y);
+
+ // These lines are not really portable, because of `mln_VAR'...
+ mln_VAR(sub_ima, ima | region);
+ mln_piter_(sub_ima_t) p(sub_ima.domain());
+ /* ...and are a shortcut for this (portable) code:
+
+ typedef sub_image< image2d<int_u8>, box2d > sub_ima_t;
+ mln_piter_(sub_ima_t) p((ima | region).domain());
+
+ */
+ accu::stat::min_max<int_u8> accu;
+ for_all(p)
+ accu.take(ima(p));
+ std::cout << "min = " << accu.first() << std::endl;
+ std::cout << "max = " << accu.second() << std::endl;
+}
--
1.6.3.1
1
0
31 Aug '09
* green/k_mean/k_mean.hh (get_distance) : New accessor method.
* green/k_mean/k_mean.hh (get_group) : New accessor method.
* green/k_mean/k_mean.hh (get_variance) : New accessor method.
* green/k_mean/k_mean.hh (update_variance) : New compute method.
* green/k_mean/k_mean.hh (div_col) : New tool method.
* green/k_mean/k_mean.hh (sum_row) : New tool method.
* green/k_mean/k_mean.hh (k_mean) : Add variance code.
* green/k_mean/k_mean.hh (~k_mean) : Add variance code.
* green/k_mean/k_mean.hh (update_center) : Fix bugs.
* green/k_mean/k_mean.hh (update_distance) : New debugging code.
* green/k_mean/k_mean.cc (#define) : New macros.
* green/k_mean/k_mean.cc (rgb8_to_4colors) : Comment debugging code.
* green/k_mean/k_mean.cc (is_equivalent) : Adapt the signature.
* green/k_mean/k_mean.cc (test_init_point) : Adapt the k_mean call.
* green/k_mean/k_mean.cc (is_equal) : Remove old function.
* green/k_mean/k_mean.cc (set_point) : New assignment func.
* green/k_mean/k_mean.cc (fake_init_point) : New initializat° func.
* green/k_mean/k_mean.cc (is_equal) : New predicate.
* green/k_mean/k_mean.cc (test_init_center) : New unitary test.
* green/k_mean/k_mean.cc (set_center) : New assignment func.
* green/k_mean/k_mean.cc (fake_init_center) : New initializat° func.
* green/k_mean/k_mean.cc (dist) : New distance function.
* green/k_mean/k_mean.cc (test_update_distance): New unitary test.
* green/k_mean/k_mean.cc (set_distance) : New assignment func.
* green/k_mean/k_mean.cc (fake_init_distance) : New initializat° func.
* green/k_mean/k_mean.cc (test_update_group) : New unitary test.
* green/k_mean/k_mean.cc (set_group) : New assignment func.
* green/k_mean/k_mean.cc (fake_update_group) : New initializat° func.
* green/k_mean/k_mean.cc (test_update_center) : New unitary test.
* green/k_mean/k_mean.cc (test_row) : Remove old function.
* green/k_mean/k_mean.cc (test_col) : Remove old function.
* green/k_mean/k_mean.cc (test_update_var) : New unitary test.
* green/k_mean/k_mean.cc (main) : New test calls.
---
trunk/milena/sandbox/ChangeLog | 38 +++
trunk/milena/sandbox/green/k_mean/k_mean.cc | 340 ++++++++++++++++++++------
trunk/milena/sandbox/green/k_mean/k_mean.hh | 123 +++++++++-
3 files changed, 414 insertions(+), 87 deletions(-)
diff --git a/trunk/milena/sandbox/ChangeLog b/trunk/milena/sandbox/ChangeLog
index 2375914..4ba03a5 100644
--- a/trunk/milena/sandbox/ChangeLog
+++ b/trunk/milena/sandbox/ChangeLog
@@ -1,3 +1,41 @@
+2009-08-28 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Improve and continue testing the kmean clustering code.
+
+ * green/k_mean/k_mean.hh (get_distance) : New accessor method.
+ * green/k_mean/k_mean.hh (get_group) : New accessor method.
+ * green/k_mean/k_mean.hh (get_variance) : New accessor method.
+ * green/k_mean/k_mean.hh (update_variance) : New compute method.
+ * green/k_mean/k_mean.hh (div_col) : New tool method.
+ * green/k_mean/k_mean.hh (sum_row) : New tool method.
+ * green/k_mean/k_mean.hh (k_mean) : Add variance code.
+ * green/k_mean/k_mean.hh (~k_mean) : Add variance code.
+ * green/k_mean/k_mean.hh (update_center) : Fix bugs.
+ * green/k_mean/k_mean.hh (update_distance) : New debugging code.
+ * green/k_mean/k_mean.cc (#define) : New macros.
+ * green/k_mean/k_mean.cc (rgb8_to_4colors) : Comment debugging code.
+ * green/k_mean/k_mean.cc (is_equivalent) : Adapt the signature.
+ * green/k_mean/k_mean.cc (test_init_point) : Adapt the k_mean call.
+ * green/k_mean/k_mean.cc (is_equal) : Remove old function.
+ * green/k_mean/k_mean.cc (set_point) : New assignment func.
+ * green/k_mean/k_mean.cc (fake_init_point) : New initializat� func.
+ * green/k_mean/k_mean.cc (is_equal) : New predicate.
+ * green/k_mean/k_mean.cc (test_init_center) : New unitary test.
+ * green/k_mean/k_mean.cc (set_center) : New assignment func.
+ * green/k_mean/k_mean.cc (fake_init_center) : New initializat� func.
+ * green/k_mean/k_mean.cc (dist) : New distance function.
+ * green/k_mean/k_mean.cc (test_update_distance): New unitary test.
+ * green/k_mean/k_mean.cc (set_distance) : New assignment func.
+ * green/k_mean/k_mean.cc (fake_init_distance) : New initializat� func.
+ * green/k_mean/k_mean.cc (test_update_group) : New unitary test.
+ * green/k_mean/k_mean.cc (set_group) : New assignment func.
+ * green/k_mean/k_mean.cc (fake_update_group) : New initializat� func.
+ * green/k_mean/k_mean.cc (test_update_center) : New unitary test.
+ * green/k_mean/k_mean.cc (test_row) : Remove old function.
+ * green/k_mean/k_mean.cc (test_col) : Remove old function.
+ * green/k_mean/k_mean.cc (test_update_var) : New unitary test.
+ * green/k_mean/k_mean.cc (main) : New test calls.
+
2009-08-27 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Improve and test the kmean clustering code.
diff --git a/trunk/milena/sandbox/green/k_mean/k_mean.cc b/trunk/milena/sandbox/green/k_mean/k_mean.cc
index abef129..91c68d5 100644
--- a/trunk/milena/sandbox/green/k_mean/k_mean.cc
+++ b/trunk/milena/sandbox/green/k_mean/k_mean.cc
@@ -29,6 +29,31 @@
#include <mln/trait/value/print.hh>
#include <mln/trait/image/print.hh>
+#define SIZE_IMAGE 512
+#define SIZE_SAMPLE1 (512*512)
+#define SIZE_SAMPLE2 4
+#define NB_CENTER 2
+#define DIM_POINT 3
+#define TYPE_POINT double
+#define MAT_POINT1 mln::algebra::mat<SIZE_SAMPLE1, DIM_POINT, TYPE_POINT>
+#define MAT_POINT2 mln::algebra::mat<SIZE_SAMPLE2, DIM_POINT, TYPE_POINT>
+#define MAT_CENTER mln::algebra::mat<NB_CENTER, DIM_POINT, TYPE_POINT>
+#define MAT_DISTANCE1 mln::algebra::mat<SIZE_SAMPLE1, NB_CENTER, TYPE_POINT>
+#define MAT_DISTANCE2 mln::algebra::mat<SIZE_SAMPLE2, NB_CENTER, TYPE_POINT>
+#define MAT_GROUP1 mln::algebra::mat<SIZE_SAMPLE1, NB_CENTER, TYPE_POINT>
+#define MAT_GROUP2 mln::algebra::mat<SIZE_SAMPLE2, NB_CENTER, TYPE_POINT>
+#define VEC_VAR mln::algebra::vec<NB_CENTER, TYPE_POINT>
+
+
+void test_instantiation()
+{
+ mln::clustering::k_mean<SIZE_SAMPLE2,NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
+
+ // test the compilation
+
+ std::cout << "test instantiation : ok" << std::endl;
+}
+
struct rgb8_to_4colors : mln::Function_v2v<rgb8_to_4colors>
{
typedef mln::value::rgb8 result;
@@ -67,22 +92,14 @@ void fill_image_with_4colors(mln::image2d<mln::value::rgb8>& img)
img = mln::data::transform(img, rgb8_to_4colors());
- print_color(lime);
- print_color(brown);
- print_color(teal);
- print_color(purple);
+ //print_color(lime);
+ //print_color(brown);
+ //print_color(teal);
+ //print_color(purple);
}
-#define SIZE_IMAGE 512
-#define SIZE_SAMPLE (512*512)
-#define NB_CENTER 2
-#define DIM_POINT 3
-#define TYPE_POINT double
-#define MAT_POINT mln::algebra::mat<SIZE_SAMPLE, DIM_POINT, TYPE_POINT>
-#define MAT_CENTER mln::algebra::mat<NB_CENTER, DIM_POINT, TYPE_POINT>
-
bool is_equivalent(const mln::image2d<mln::value::rgb8>& img,
- const MAT_POINT& point)
+ const MAT_POINT1& point)
{
mln_piter_(mln::image2d<mln::value::rgb8>) pi(img.domain());
bool result = true;
@@ -123,7 +140,7 @@ void test_init_point()
typedef mln::value::rgb8 rgb8;
mln::image2d<rgb8> img_ref;
- mln::clustering::k_mean<SIZE_SAMPLE,NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
+ mln::clustering::k_mean<SIZE_SAMPLE1,NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
mln::io::ppm::load(img_ref, "/usr/local/share/olena/images/lena.ppm");
//mln::io::ppm::save(img_ref, "verif.ppm");
@@ -133,117 +150,282 @@ void test_init_point()
mln_assertion(true == is_equivalent(img_ref, kmean.get_point()));
- std::cout << "Test init point : ok" << std::endl;
+ std::cout << "Test init point : ok" << std::endl;
}
-bool is_equal(const mln::value::rgb8& ref, const MAT_CENTER& center, unsigned i)
+void set_point(MAT_POINT2& point,
+ const unsigned index,
+ const mln::value::rgb8& color)
{
- bool result = true;
-
- result = result && (ref.red() == center(i, 0));
- result = result && (ref.green() == center(i, 1));
- result = result && (ref.blue() == center(i, 2));
+ point(index,0) = color.red();
+ point(index,1) = color.green();
+ point(index,2) = color.blue();
+}
- return result;
+void fake_init_point(MAT_POINT2& point,
+ const mln::value::rgb8& point1,
+ const mln::value::rgb8& point2,
+ const mln::value::rgb8& point3,
+ const mln::value::rgb8& point4)
+{
+ set_point(point, 0, point1);
+ set_point(point, 1, point2);
+ set_point(point, 2, point3);
+ set_point(point, 3, point4);
}
-bool is_center_initialized(const MAT_CENTER& center)
+bool is_equal(const mln::value::rgb8& ref,
+ const MAT_CENTER& center,
+ const unsigned i)
{
- typedef mln::value::rgb8 rgb8;
- const rgb8 lime = mln::literal::lime;
- const rgb8 brown = mln::literal::brown;
- const rgb8 teal = mln::literal::teal;
- const rgb8 purple = mln::literal::purple;
- bool result = false;
+ bool result = true;
- for (unsigned i = 0; i < NB_CENTER; ++i)
- {
- result = result || is_equal(lime, center, i);
- result = result || is_equal(brown, center, i);
- result = result || is_equal(teal, center, i);
- result = result || is_equal(purple, center, i);
- }
+ result = result && (center(i, 0) - ref.red() < 1.0);
+ result = result && (center(i, 1) - ref.green() < 1.0);
+ result = result && (center(i, 2) - ref.blue() < 1.0);
return result;
}
void test_init_center()
{
- typedef mln::value::rgb8 rgb8;
- mln::image2d<rgb8> img_ref;
+ mln::clustering::k_mean<SIZE_SAMPLE2, NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
- mln::clustering::k_mean<SIZE_SAMPLE,NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
+ const mln::value::rgb8 lime = mln::literal::lime;
+ const mln::value::rgb8 brown = mln::literal::brown;
+ const mln::value::rgb8 teal = mln::literal::teal;
+ const mln::value::rgb8 purple = mln::literal::purple;
+
+ fake_init_point(kmean.get_point(), lime, brown, teal, purple);
+ kmean.init_center();
+
+ mln_assertion(is_equal(lime, kmean.get_center(), 0) ||
+ is_equal(brown, kmean.get_center(), 0) ||
+ is_equal(teal, kmean.get_center(), 0) ||
+ is_equal(purple, kmean.get_center(), 0));
- mln::io::ppm::load(img_ref, "/usr/local/share/olena/images/lena.ppm");
+ mln_assertion(is_equal(lime, kmean.get_center(), 1) ||
+ is_equal(brown, kmean.get_center(), 1) ||
+ is_equal(teal, kmean.get_center(), 1) ||
+ is_equal(purple, kmean.get_center(), 1));
- fill_image_with_4colors(img_ref);
- kmean.init_point(img_ref);
- kmean.init_center();
+ std::cout << "Test init center : ok" << std::endl;
+}
- mln_assertion(true == is_center_initialized(kmean.get_center()));
- std::cout << "Test init center : ok" << std::endl;
+void set_center(MAT_CENTER& center,
+ const unsigned index,
+ const mln::value::rgb8& color)
+{
+ center(index,0) = color.red();
+ center(index,1) = color.green();
+ center(index,2) = color.blue();
}
-void test_instantiation()
+void fake_init_center(MAT_CENTER& center,
+ const mln::value::rgb8 center1,
+ const mln::value::rgb8 center2)
{
- std::cout << "test_instantiation" << std::endl;
-
- mln::trace::entering("safe");
- // typedef mln::value::int_u8 int_u8;
- typedef mln::value::rgb8 rgb8;
- const unsigned SIZE = 512*512;
+ set_center(center, 0, center1);
+ set_center(center, 1, center2);
+}
- //mln::image2d<int_u8> img_ref;
- mln::image2d<rgb8> img_ref;
- mln::io::ppm::load(img_ref, "/usr/local/share/olena/images/lena.ppm");
+double dist(mln::value::rgb8 color1, mln::value::rgb8 color2)
+{
+ double red = color1.red() - color2.red();
+ double green = color1.green() - color2.green();
+ double blue = color1.blue() - color2.blue();
+ double result= red * red + green * green + blue * blue;
+
+ return result;
+}
- mln::trace::exiting("safe");
- mln::trace::entering("clustering");
- mln::clustering::k_mean<SIZE,2,3,double> kmean;
+void test_update_distance()
+{
+ mln::clustering::k_mean<SIZE_SAMPLE2, NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
- std::cout << img_ref.domain() << std::endl;
- kmean.init_point(img_ref);
- kmean.init_center();
+ const mln::value::rgb8 lime = mln::literal::lime;
+ const mln::value::rgb8 brown = mln::literal::brown;
+ const mln::value::rgb8 teal = mln::literal::teal;
+ const mln::value::rgb8 purple = mln::literal::purple;
+ const mln::value::rgb8 c1 = lime;
+ const mln::value::rgb8 c2 = purple;
+ const MAT_DISTANCE2& dist_v = kmean.get_distance();
+
+ fake_init_point(kmean.get_point(), lime, brown, teal, purple);
+ fake_init_center(kmean.get_center(), c1, c2);
kmean.update_distance();
- kmean.update_group();
- kmean.update_center();
- mln::trace::exiting("clustering");
+
+ mln_assertion(dist(lime, c1) == dist_v(0,0));
+ mln_assertion(dist(lime, c2) == dist_v(0,1));
+ mln_assertion(dist(brown, c1) == dist_v(1,0));
+ mln_assertion(dist(brown, c2) == dist_v(1,1));
+ mln_assertion(dist(teal, c1) == dist_v(2,0));
+ mln_assertion(dist(teal, c2) == dist_v(2,1));
+ mln_assertion(dist(purple, c1) == dist_v(3,0));
+ mln_assertion(dist(purple, c2) == dist_v(3,1));
+
+ std::cout << "Test update distance : ok" << std::endl;
+}
+
+void set_distance(MAT_DISTANCE2& distance,
+ const unsigned index,
+ const double d1,
+ const double d2)
+{
+ distance(index,0) = d1;
+ distance(index,1) = d2;
+}
+
+void fake_update_distance(MAT_DISTANCE2& distance,
+ const mln::value::rgb8& point1,
+ const mln::value::rgb8& point2,
+ const mln::value::rgb8& point3,
+ const mln::value::rgb8& point4,
+ const mln::value::rgb8& center1,
+ const mln::value::rgb8& center2)
+{
+ set_distance(distance, 0, dist(point1, center1), dist(point1, center2));
+ set_distance(distance, 1, dist(point2, center1), dist(point2, center2));
+ set_distance(distance, 2, dist(point3, center1), dist(point3, center2));
+ set_distance(distance, 3, dist(point4, center1), dist(point4, center2));
+
/*
- int_u8 val;
+ for (int i = 0; i < SIZE_SAMPLE2; ++i)
+ for (int j = 0; j < NB_CENTER; ++j)
+ std::cout << "d(" << i << "," << j << ") = " << distance(i,j) <<std::endl;
*/
- /*
- mln::trait::value::print<mln::value::int_u8>(std::cout);
- mln::trait::image::print<mln::image2d<int_u8> >();
+}
- mln::image2d<int_u8> img_out;
+void test_update_group()
+{
+ mln::clustering::k_mean<SIZE_SAMPLE2, NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
+
+ const mln::value::rgb8 lime = mln::literal::lime;
+ const mln::value::rgb8 brown = mln::literal::brown;
+ const mln::value::rgb8 teal = mln::literal::teal;
+ const mln::value::rgb8 purple = mln::literal::purple;
+ const mln::value::rgb8 c1 = lime;
+ const mln::value::rgb8 c2 = purple;
+ const unsigned point1_min= 0; // lime near lime (c1)
+ const unsigned point2_min= 1; // brown near purple (c2)
+ const unsigned point3_min= 1; // teal near purple (c2)
+ const unsigned point4_min= 1; // purple near purple (c2)
+ const MAT_GROUP2& group = kmean.get_group();
+
+ fake_init_point(kmean.get_point(), lime, brown, teal, purple);
+ fake_init_center(kmean.get_center(), c1, c2);
+ fake_update_distance(kmean.get_distance(), lime, brown, teal, purple, c1, c2);
+ kmean.update_group();
+ mln_assertion(0.0 == group(0, 1 - point1_min));
+ mln_assertion(1.0 == group(0, point1_min));
+ mln_assertion(0.0 == group(1, 1 - point2_min));
+ mln_assertion(1.0 == group(1, point2_min));
+ mln_assertion(0.0 == group(2, 1 - point3_min));
+ mln_assertion(1.0 == group(2, point3_min));
+ mln_assertion(0.0 == group(3, 1 - point4_min));
+ mln_assertion(1.0 == group(3, point4_min));
- //mln::io::pgm::load(img_ref, "mp00082c_50p.pgm");
- mln::trace::exiting("image");
-
+ std::cout << "Test update group : ok" << std::endl;
+}
- mln::trace::entering("test");
+void set_group(MAT_GROUP2& group,
+ const unsigned index,
+ const unsigned min)
+{
+ group(index, min) = 1.0;
+ group(index, 1-min) = 0.0;
+}
- mln::trace::exiting("test");
- // k_mean.distance();
- */
+
+void fake_update_group(MAT_GROUP2& group,
+ const unsigned& point1_min,
+ const unsigned& point2_min,
+ const unsigned& point3_min,
+ const unsigned& point4_min)
+{
+ set_group(group, 0, point1_min);
+ set_group(group, 1, point2_min);
+ set_group(group, 2, point3_min);
+ set_group(group, 3, point4_min);
}
-void test_col()
+void test_update_center()
{
+ mln::clustering::k_mean<SIZE_SAMPLE2, NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
+
+ const mln::value::rgb8 lime = mln::literal::lime;
+ const mln::value::rgb8 brown = mln::literal::brown;
+ const mln::value::rgb8 teal = mln::literal::teal;
+ const mln::value::rgb8 purple = mln::literal::purple;
+ const mln::value::rgb8 c1 = lime;
+ const mln::value::rgb8 c2 = purple;
+ const unsigned pt1_min = 0; // lime near lime (c1)
+ const unsigned pt2_min = 1; // brown near purple (c2)
+ const unsigned pt3_min = 1; // teal near purple (c2)
+ const unsigned pt4_min = 1; // purple near purple (c2)
+ const mln::value::rgb8 mean_c1 = lime;
+ const mln::value::rgb8 mean_c2 = (brown+teal+purple)/3;
+
+ fake_init_point(kmean.get_point(), lime, brown, teal, purple);
+ fake_init_center(kmean.get_center(), c1, c2);
+ fake_update_distance(kmean.get_distance(), lime, brown, teal, purple, c1, c2);
+ fake_update_group(kmean.get_group(), pt1_min, pt2_min, pt3_min, pt4_min);
+ kmean.update_center();
+
+ mln_assertion(is_equal(mean_c1, kmean.get_center(), 0));
+ mln_assertion(is_equal(mean_c2, kmean.get_center(), 1));
+
+ std::cout << "Test update center : ok" << std::endl;
}
-void test_row()
+void test_update_var()
{
+ mln::clustering::k_mean<SIZE_SAMPLE2, NB_CENTER, DIM_POINT, TYPE_POINT> kmean;
+
+ const mln::value::rgb8 lime = mln::literal::lime;
+ const mln::value::rgb8 brown = mln::literal::brown;
+ const mln::value::rgb8 teal = mln::literal::teal;
+ const mln::value::rgb8 purple = mln::literal::purple;
+ const mln::value::rgb8 c1 = lime;
+ const mln::value::rgb8 c2 = purple;
+ const unsigned pt1_min = 0; // lime near lime (c1)
+ const unsigned pt2_min = 1; // brown near purple (c2)
+ const unsigned pt3_min = 1; // teal near purple (c2)
+ const unsigned pt4_min = 1; // purple near purple (c2)
+ const double v1 = 0;
+ const double v2 = dist(purple, brown) + dist(purple, teal);
+ const mln::value::rgb8 mean_c2 = (brown+teal+purple)/3;
+ const VEC_VAR& var = kmean.get_variance();
+
+ fake_init_point(kmean.get_point(), lime, brown, teal, purple);
+ fake_init_center(kmean.get_center(), c1, c2);
+ fake_update_distance(kmean.get_distance(), lime, brown, teal, purple, c1, c2);
+ fake_update_group(kmean.get_group(), pt1_min, pt2_min, pt3_min, pt4_min);
+ kmean.update_variance();
+
+ mln_assertion(v1 == var[0]);
+ mln_assertion(v2 == var[1]);
+
+ std::cout << "Test update variance: ok" << std::endl;
}
+
int main()
{
- //test_instantiation();
+ test_instantiation();
test_init_point();
test_init_center();
+ test_update_distance();
+ test_update_group();
+ test_update_center();
+ test_update_var();
+
+ // mln::trace::quiet = false;
+
+ test_update_center();
return 0;
}
diff --git a/trunk/milena/sandbox/green/k_mean/k_mean.hh b/trunk/milena/sandbox/green/k_mean/k_mean.hh
index 89547ce..7e295bf 100644
--- a/trunk/milena/sandbox/green/k_mean/k_mean.hh
+++ b/trunk/milena/sandbox/green/k_mean/k_mean.hh
@@ -52,6 +52,7 @@
#include <mln/trace/exiting.hh>
#include <mln/core/contract.hh>
+#include <mln/trait/value_.hh>
#include <mln/algebra/mat.hh>
#include <mln/algebra/vec.hh>
@@ -99,6 +100,9 @@ namespace mln
algebra::mat<n, p, T>& get_point();
algebra::mat<k, p, T>& get_center();
+ algebra::mat<n, k, T>& get_distance();
+ algebra::mat<n, k, T>& get_group();
+ algebra::vec<k, T>& get_variance();
k_mean();
~k_mean();
@@ -106,6 +110,7 @@ namespace mln
void update_distance();
void update_group();
void update_center();
+ void update_variance();
template <unsigned q, typename M>
M min(const algebra::vec<q, M>& x) const;
@@ -138,6 +143,15 @@ namespace mln
algebra::vec<q,T> col(const algebra::mat<r, q, T>& m,
const unsigned _col) const;
+ template <unsigned q, unsigned r>
+ void div_col(algebra::mat<r, q, T>& m,
+ const unsigned _col,
+ const T value);
+
+ template <unsigned q, unsigned r>
+ mln_sum(T) sum_row(const algebra::mat<r, q, T>& m,
+ const unsigned _row) const;
+
private:
/// \brief _points contains the concatenation of every data points.
///
@@ -163,6 +177,8 @@ namespace mln
/// _center is a matrix KxP where K is the number of centers and P is the
/// number of attributes.
algebra::mat<k, p, T>* _center;
+
+ algebra::vec<k, T>* _variance;
};
#ifndef MLN_INCLUDE_ONLY
@@ -190,6 +206,39 @@ namespace mln
}
template <unsigned n, unsigned k, unsigned p, typename T>
+ inline
+ algebra::mat<n, k, T>&
+ k_mean<n,k,p,T>::get_distance()
+ {
+ trace::entering("mln::clustering::k_mean::get_distance");
+ trace::exiting("mln::clustering::k_mean::get_distance");
+
+ return *_distance;
+ }
+
+ template <unsigned n, unsigned k, unsigned p, typename T>
+ inline
+ algebra::mat<n, k, T>&
+ k_mean<n,k,p,T>::get_group()
+ {
+ trace::entering("mln::clustering::k_mean::get_group");
+ trace::exiting("mln::clustering::k_mean::get_group");
+
+ return *_group;
+ }
+
+ template <unsigned n, unsigned k, unsigned p, typename T>
+ inline
+ algebra::vec<k, T>&
+ k_mean<n,k,p,T>::get_variance()
+ {
+ trace::entering("mln::clustering::k_mean::get_variance");
+ trace::exiting("mln::clustering::k_mean::get_variance");
+
+ return *_variance;
+ }
+
+ template <unsigned n, unsigned k, unsigned p, typename T>
k_mean<n,k,p,T>::k_mean()
{
trace::entering("mln::clustering::k_mean::k_mean");
@@ -198,11 +247,13 @@ namespace mln
_distance = new algebra::mat<n, k, mln_sum_product(T,T)>();
_group = new algebra::mat<n, k, T>();
_center = new algebra::mat<k, p, T>();
+ _variance = new algebra::vec<k,T>();
mln_postcondition(_point != 0);
mln_postcondition(_distance != 0);
mln_postcondition(_group != 0);
mln_postcondition(_center != 0);
+ mln_postcondition(_variance != 0);
trace::exiting("mln::clustering::k_mean::k_mean");
}
@@ -216,6 +267,7 @@ namespace mln
delete _distance;
delete _group;
delete _center;
+ delete _variance;
trace::exiting("mln::clustering::k_mean::~k_mean");
}
@@ -273,7 +325,7 @@ namespace mln
center(i,j) = point(random, j);
}
- std::cout << "center(" << i << ")" << col(center, i) << std::endl;
+ //std::cout << "center(" << i << ")" << col(center, i) << std::endl;
}
trace::exiting("mln::clustering::k_mean<n,k,p,T>::init_center");
@@ -329,12 +381,33 @@ namespace mln
algebra::mat<k, p, T>& center = *_center;
algebra::mat<n, k, T>& group = *_group;
- center = (group.t() * point) / n;
+ center = (group.t() * point);
+
+ for (unsigned i = 0; i < k; ++i)
+ div_col(center, i, sum_row(group, i));
- // mln_postcondition(sum(col(distance(i,j)) == 1) Vi
trace::exiting("mln::clustering::k_mean<n,k,p,T>::update_center");
}
+ template <unsigned n, unsigned k, unsigned p, typename T>
+ inline
+ void k_mean<n,k,p,T>::update_variance()
+ {
+ trace::entering("mln::clustering::k_mean<n,k,p,T>::update_variance");
+
+ algebra::vec<k, T>& variance = *_variance;
+ algebra::mat<n, k, T>& distance = *_distance;
+ algebra::mat<n, k, T>& group = *_group;
+
+ // BUG HERE
+ // separate the n group in n vectors
+ // separate the n distance in n vectors
+ // compute the n scalar product (group, distance)
+ // sum the n scalar product to obtain the within variance
+ variance = (group.t() * distance).t();
+
+ trace::exiting("mln::clustering::k_mean<n,k,p,T>::update_variance");
+ }
/*
@@ -352,7 +425,40 @@ namespace mln
}
*/
- //vec<q, T> k_mean<n,k,p,T>::col(const mat<r, q, T>& m, unsigned _col) const
+ template <unsigned n, unsigned k, unsigned p, typename T>
+ template <unsigned q, unsigned r>
+ inline
+ mln_sum(T) k_mean<n,k,p,T>::sum_row(const algebra::mat<r, q, T>& m,
+ const unsigned _row) const
+ {
+ trace::entering("mln::clustering::k_mean::sum_row");
+ mln_precondition(q > _row);
+
+ mln_sum(T) result;
+
+ for (unsigned j = 0; j < r; ++j)
+ result += m(j, _row);
+
+ trace::exiting("mln::clustering::k_mean::sum_row");
+ return result;
+ }
+
+ template <unsigned n, unsigned k, unsigned p, typename T>
+ template <unsigned q, unsigned r>
+ inline
+ void k_mean<n,k,p,T>::div_col(algebra::mat<r, q, T>& m,
+ const unsigned _col,
+ const T value)
+ {
+ trace::entering("mln::clustering::k_mean::div_col");
+ mln_precondition(r > _col);
+
+ for (unsigned j = 0; j < q; ++j)
+ m(_col, j) /= value;
+
+ trace::exiting("mln::clustering::k_mean::div_col");
+ }
+
template <unsigned n, unsigned k, unsigned p, typename T>
template <unsigned q, unsigned r>
inline
@@ -390,8 +496,9 @@ namespace mln
inline
void k_mean<n,k,p,T>::update_distance()
{
- trace::entering("mln::clustering::k_mean::distance");
- mln::trace::quiet = true;
+ trace::entering("mln::clustering::k_mean::update_distance");
+ //mln::trace::quiet = true;
+
// the result is stored in _distance matrix.
algebra::mat<n, p, T>& point = *_point;
algebra::mat<n, k, T>& distance = *_distance;
@@ -406,8 +513,8 @@ namespace mln
distance(i,j) = euclidian_distance(col(point,i),col(center,j));
}
}
- mln::trace::quiet = false;
- trace::exiting("mln::clustering::k_mean::distance");
+ //mln::trace::quiet = false;
+ trace::exiting("mln::clustering::k_mean::update_distance");
}
#endif // ! MLN_INCLUDE_ONLY
--
1.5.6.5
1
0
* binarization/sauvola.hh,
* debug/decision_image.hh,
* debug/save_linked_bboxes_image.hh,
* draw/bounding_box_links.hh,
* filter/object_links_bbox_overlap.hh: Add missing includes.
* src/text_in_photo_invert.cc: Update use of some routines.
* tests/unit_test/unit-tests.mk: Regen.
---
scribo/ChangeLog | 14 ++++++++++
scribo/binarization/sauvola.hh | 1 +
scribo/debug/decision_image.hh | 2 +
scribo/debug/save_linked_bboxes_image.hh | 1 +
scribo/draw/bounding_box_links.hh | 1 +
scribo/filter/object_links_bbox_overlap.hh | 2 +
scribo/src/text_in_photo_invert.cc | 38 ++++++++++++---------------
scribo/tests/unit_test/unit-tests.mk | 16 +++++++++++
8 files changed, 54 insertions(+), 21 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 7d541ff..e8bbe11 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,17 @@
+2009-08-31 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
+ Fix compilation issues in Scribo.
+
+ * binarization/sauvola.hh,
+ * debug/decision_image.hh,
+ * debug/save_linked_bboxes_image.hh,
+ * draw/bounding_box_links.hh,
+ * filter/object_links_bbox_overlap.hh: Add missing includes.
+
+ * src/text_in_photo_invert.cc: Update use of some routines.
+
+ * tests/unit_test/unit-tests.mk: Regen.
+
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
* tests/table/extract_lines_with_rank.cc: Fix a test in Scribo.
diff --git a/scribo/binarization/sauvola.hh b/scribo/binarization/sauvola.hh
index a726665..9b719e1 100644
--- a/scribo/binarization/sauvola.hh
+++ b/scribo/binarization/sauvola.hh
@@ -36,6 +36,7 @@
# include <mln/core/image/image2d.hh>
# include <mln/value/rgb8.hh>
# include <mln/value/int_u.hh>
+# include <mln/value/int_u8.hh>
# include <mln/data/transform.hh>
# include <mln/pw/all.hh>
diff --git a/scribo/debug/decision_image.hh b/scribo/debug/decision_image.hh
index 46fbcff..1652f8e 100644
--- a/scribo/debug/decision_image.hh
+++ b/scribo/debug/decision_image.hh
@@ -33,8 +33,10 @@
# include <mln/core/concept/image.hh>
# include <mln/data/convert.hh>
# include <mln/value/rgb8.hh>
+# include <mln/literal/colors.hh>
# include <mln/util/array.hh>
+# include <scribo/core/object_groups.hh>
# include <scribo/draw/bounding_boxes.hh>
diff --git a/scribo/debug/save_linked_bboxes_image.hh b/scribo/debug/save_linked_bboxes_image.hh
index 6ce0ad0..364f06e 100644
--- a/scribo/debug/save_linked_bboxes_image.hh
+++ b/scribo/debug/save_linked_bboxes_image.hh
@@ -39,6 +39,7 @@
# include <mln/util/array.hh>
# include <mln/io/ppm/save.hh>
+# include <scribo/core/object_links.hh>
# include <scribo/core/object_image.hh>
# include <scribo/draw/bounding_boxes.hh>
# include <scribo/draw/bounding_box_links.hh>
diff --git a/scribo/draw/bounding_box_links.hh b/scribo/draw/bounding_box_links.hh
index 9a2919e..47a4f0a 100644
--- a/scribo/draw/bounding_box_links.hh
+++ b/scribo/draw/bounding_box_links.hh
@@ -36,6 +36,7 @@
# include <mln/canvas/browsing/depth_first_search.hh>
# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
# include <scribo/primitive/internal/is_link_valid.hh>
namespace scribo
diff --git a/scribo/filter/object_links_bbox_overlap.hh b/scribo/filter/object_links_bbox_overlap.hh
index ff65e92..83b5dfc 100644
--- a/scribo/filter/object_links_bbox_overlap.hh
+++ b/scribo/filter/object_links_bbox_overlap.hh
@@ -32,6 +32,8 @@
/// overlapping too much.
+# include <mln/math/min.hh>
+# include <mln/math/max.hh>
# include <mln/util/array.hh>
# include <scribo/core/macros.hh>
diff --git a/scribo/src/text_in_photo_invert.cc b/scribo/src/text_in_photo_invert.cc
index 81a0e91..71baee6 100644
--- a/scribo/src/text_in_photo_invert.cc
+++ b/scribo/src/text_in_photo_invert.cc
@@ -48,17 +48,22 @@
#include <mln/labeling/superpose.hh>
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/group/apply.hh>
+
#include <scribo/primitive/link/with_single_left_link.hh>
#include <scribo/primitive/link/with_single_right_link.hh>
+
+#include <scribo/primitive/group/apply.hh>
#include <scribo/primitive/group/from_double_link.hh>
#include <scribo/primitive/group/from_single_link.hh>
+
#include <scribo/filter/objects_small.hh>
#include <scribo/filter/objects_thin.hh>
#include <scribo/filter/objects_thick.hh>
#include <scribo/filter/object_groups_small.hh>
#include <scribo/make/debug_filename.hh>
+
+#include <scribo/debug/decision_image.hh>
#include <scribo/debug/save_bboxes_image.hh>
#include <scribo/debug/save_linked_bboxes_image.hh>
@@ -129,28 +134,20 @@ namespace mln
groups = primitive::group::from_double_link(filtered_objects,
left_link, right_link);
- // Remove objects part of groups with less than 3 objects.
- util::array<bool>
- to_be_kept = filter::object_groups_small(groups, 3);
-
+ // Remove objects part of groups with strictly less than 3 objects.
+ object_groups<L> filtered_groups = filter::object_groups_small(groups, 3);
-
- // FOR DEBUGGING PURPOSE.
#ifndef NOUT
- image2d<value::rgb8> decision_image = data::convert(value::rgb8(), input);
-
-
- for (unsigned i = 1; i < to_be_kept.size(); ++i)
- {
- if (!to_be_kept(i))
- mln::draw::box(decision_image, filtered_objects.bbox(i), literal::red);
- else
- mln::draw::box(decision_image, filtered_objects.bbox(i), literal::green);
- }
-#endif // ! NOUT
+ image2d<value::rgb8>
+ decision_image = scribo::debug::decision_image(input,
+ groups, filtered_groups);
+#endif
- filtered_objects.relabel(to_be_kept);
+ /// Apply grouping in the object image.
+ object_image(L)
+ grouped_objects = primitive::group::apply(filtered_objects,
+ filtered_groups);
// Objects have been removed we need to update object links again.
@@ -164,8 +161,7 @@ namespace mln
// Grouping objects again.
groups = primitive::group::from_single_link(filtered_objects, left_link);
- object_image(L)
- grouped_objects = primitive::group::apply(filtered_objects, groups);
+ grouped_objects = primitive::group::apply(filtered_objects, groups);
#ifndef NOUT
for (unsigned i = 1; i <= grouped_objects.nlabels(); ++i)
diff --git a/scribo/tests/unit_test/unit-tests.mk b/scribo/tests/unit_test/unit-tests.mk
index 89c72d9..51a7da1 100644
--- a/scribo/tests/unit_test/unit-tests.mk
+++ b/scribo/tests/unit_test/unit-tests.mk
@@ -2,6 +2,7 @@
check_PROGRAMS = \
scribo_all \
+scribo_binarization_sauvola \
scribo_binarization_simple \
scribo_core_all \
scribo_core_central_sites \
@@ -11,6 +12,7 @@ scribo_core_object_groups \
scribo_core_object_image \
scribo_core_object_links \
scribo_debug_all \
+scribo_debug_decision_image \
scribo_debug_save_bboxes_image \
scribo_debug_save_label_image \
scribo_debug_save_linked_bboxes_image \
@@ -21,7 +23,13 @@ scribo_draw_bounding_box_links \
scribo_draw_bounding_boxes \
scribo_filter_all \
scribo_filter_object_groups_small \
+scribo_filter_object_links_bbox_h_ratio \
+scribo_filter_object_links_bbox_overlap \
+scribo_filter_object_links_bbox_ratio \
+scribo_filter_object_links_bbox_w_ratio \
+scribo_filter_object_links_bottom_aligned \
scribo_filter_object_links_non_aligned \
+scribo_filter_object_links_non_aligned_simple \
scribo_filter_object_links_non_h_aligned \
scribo_filter_object_links_non_v_aligned \
scribo_filter_objects_large \
@@ -96,6 +104,7 @@ scribo_util_all \
scribo_util_text
scribo_all_SOURCES = scribo_all.cc
+scribo_binarization_sauvola_SOURCES = scribo_binarization_sauvola.cc
scribo_binarization_simple_SOURCES = scribo_binarization_simple.cc
scribo_core_all_SOURCES = scribo_core_all.cc
scribo_core_central_sites_SOURCES = scribo_core_central_sites.cc
@@ -105,6 +114,7 @@ scribo_core_object_groups_SOURCES = scribo_core_object_groups.cc
scribo_core_object_image_SOURCES = scribo_core_object_image.cc
scribo_core_object_links_SOURCES = scribo_core_object_links.cc
scribo_debug_all_SOURCES = scribo_debug_all.cc
+scribo_debug_decision_image_SOURCES = scribo_debug_decision_image.cc
scribo_debug_save_bboxes_image_SOURCES = scribo_debug_save_bboxes_image.cc
scribo_debug_save_label_image_SOURCES = scribo_debug_save_label_image.cc
scribo_debug_save_linked_bboxes_image_SOURCES = scribo_debug_save_linked_bboxes_image.cc
@@ -115,7 +125,13 @@ scribo_draw_bounding_box_links_SOURCES = scribo_draw_bounding_box_links.cc
scribo_draw_bounding_boxes_SOURCES = scribo_draw_bounding_boxes.cc
scribo_filter_all_SOURCES = scribo_filter_all.cc
scribo_filter_object_groups_small_SOURCES = scribo_filter_object_groups_small.cc
+scribo_filter_object_links_bbox_h_ratio_SOURCES = scribo_filter_object_links_bbox_h_ratio.cc
+scribo_filter_object_links_bbox_overlap_SOURCES = scribo_filter_object_links_bbox_overlap.cc
+scribo_filter_object_links_bbox_ratio_SOURCES = scribo_filter_object_links_bbox_ratio.cc
+scribo_filter_object_links_bbox_w_ratio_SOURCES = scribo_filter_object_links_bbox_w_ratio.cc
+scribo_filter_object_links_bottom_aligned_SOURCES = scribo_filter_object_links_bottom_aligned.cc
scribo_filter_object_links_non_aligned_SOURCES = scribo_filter_object_links_non_aligned.cc
+scribo_filter_object_links_non_aligned_simple_SOURCES = scribo_filter_object_links_non_aligned_simple.cc
scribo_filter_object_links_non_h_aligned_SOURCES = scribo_filter_object_links_non_h_aligned.cc
scribo_filter_object_links_non_v_aligned_SOURCES = scribo_filter_object_links_non_v_aligned.cc
scribo_filter_objects_large_SOURCES = scribo_filter_objects_large.cc
--
1.5.6.5
1
0
28 Aug '09
---
scribo/ChangeLog | 4 ++++
scribo/tests/table/extract_lines_with_rank.cc | 23 +++++++++++++----------
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 0cda464..7d541ff 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ * tests/table/extract_lines_with_rank.cc: Fix a test in Scribo.
+
+2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
* src/text_in_doc.cc: New full example extracting text in
documents.
diff --git a/scribo/tests/table/extract_lines_with_rank.cc b/scribo/tests/table/extract_lines_with_rank.cc
index e7f13df..29d35b4 100644
--- a/scribo/tests/table/extract_lines_with_rank.cc
+++ b/scribo/tests/table/extract_lines_with_rank.cc
@@ -43,6 +43,7 @@
#include <scribo/tests/data.hh>
+
int main(int argc, char *argv[])
{
using namespace mln;
@@ -62,11 +63,11 @@ int main(int argc, char *argv[])
vboxes,
hboxes;
vboxes.append(make::box2d(0,0, 59,59));
- vboxes.append(make::box2d(0,28, 25, 32));
- vboxes.append(make::box2d(33,28, 59,32));
+ vboxes.append(make::box2d(0,28, 27, 32));
+ vboxes.append(make::box2d(31,28, 59,32));
hboxes.append(make::box2d(0,0, 59,59));
- hboxes.append(make::box2d(27,0, 31, 24));
- hboxes.append(make::box2d(27,36, 31,59));
+ hboxes.append(make::box2d(27,0, 31, 26));
+ hboxes.append(make::box2d(27,34, 31,59));
value::label_8 nbboxes;
@@ -79,11 +80,13 @@ int main(int argc, char *argv[])
lbl_t
vlbl = scribo::primitive::extract::lines_v_discontinued(input, c8(),
nbboxes, 11, 2);
+ mln_assertion(hlbl.nlabels() == 2);
+ mln_assertion(vlbl.nlabels() == 2);
+ // Background values are meaningless, we skip them.
+ for (unsigned i = 1; i < 3; ++i)
+ {
+ mln_assertion(hlbl.bbox(i) == hboxes(i));
+ mln_assertion(vlbl.bbox(i) == vboxes(i));
+ }
- // Background values are meaningless, we set them to an arbitrary value.
- hboxes(0) = hlbl.bbox(0);
- vboxes(0) = vlbl.bbox(0);
-
- mln_assertion(hlbl.bboxes() == hboxes);
- mln_assertion(vlbl.bboxes() == vboxes);
}
--
1.5.6.5
1
0
4414: src/text_in_doc.cc: New full example extracting text in documents.
by Guillaume Lazzara 28 Aug '09
by Guillaume Lazzara 28 Aug '09
28 Aug '09
---
scribo/ChangeLog | 5 +
scribo/src/Makefile.am | 10 ++
scribo/src/text_in_doc.cc | 276 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 291 insertions(+), 0 deletions(-)
create mode 100644 scribo/src/text_in_doc.cc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 47ca131..0cda464 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,10 @@
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ * src/text_in_doc.cc: New full example extracting text in
+ documents.
+
+2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
* src/text_in_photo.cc: Improve text detection in pictures.
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
diff --git a/scribo/src/Makefile.am b/scribo/src/Makefile.am
index 7f39191..3b6a435 100644
--- a/scribo/src/Makefile.am
+++ b/scribo/src/Makefile.am
@@ -68,5 +68,15 @@ if HAVE_TIFF
$(TIFF_LDFLAGS) \
-lpthread
+ bin_PROGRAMS += text_in_doc
+ text_in_doc_SOURCES = text_in_doc.cc
+ text_in_doc_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(TESSERACT_CPPFLAGS) \
+ $(TIFF_CPPFLAGS)
+ text_in_doc_LDFLAGS = $(AM_LDFLAGS) \
+ $(TESSERACT_LDFLAGS) \
+ $(TIFF_LDFLAGS) \
+ -lpthread
+
endif HAVE_TIFF
endif HAVE_TESSERACT
diff --git a/scribo/src/text_in_doc.cc b/scribo/src/text_in_doc.cc
new file mode 100644
index 0000000..81219c4
--- /dev/null
+++ b/scribo/src/text_in_doc.cc
@@ -0,0 +1,276 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+
+#include <libgen.h>
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/logical/not.hh>
+
+#include <mln/labeling/colorize.hh>
+
+#include <mln/io/pbm/all.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/math/min.hh>
+
+#include <mln/literal/colors.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/value/label_16.hh>
+
+#include <mln/draw/box.hh>
+
+#include <scribo/table/erase.hh>
+
+#include <scribo/draw/bounding_boxes.hh>
+
+#include <scribo/primitive/extract/objects.hh>
+#include <scribo/primitive/extract/lines_h_discontinued.hh>
+#include <scribo/primitive/extract/lines_v_discontinued.hh>
+
+#include <scribo/primitive/link/merge_double_link.hh>
+#include <scribo/primitive/link/with_single_left_link.hh>
+#include <scribo/primitive/link/with_single_right_link.hh>
+
+#include <scribo/primitive/group/apply.hh>
+#include <scribo/primitive/group/from_double_link.hh>
+#include <scribo/primitive/group/from_single_link.hh>
+
+#include <scribo/filter/object_links_bottom_aligned.hh>
+#include <scribo/filter/object_links_bbox_h_ratio.hh>
+#include <scribo/filter/object_links_bbox_overlap.hh>
+
+#include <scribo/filter/objects_small.hh>
+#include <scribo/filter/objects_thin.hh>
+#include <scribo/filter/objects_thick.hh>
+
+#include <scribo/filter/object_groups_small.hh>
+
+#include <scribo/text/recognition.hh>
+
+#include <scribo/debug/decision_image.hh>
+#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/debug/save_bboxes_image.hh>
+#include <scribo/debug/save_linked_bboxes_image.hh>
+
+#include <scribo/debug/usage.hh>
+
+#include <scribo/make/debug_filename.hh>
+
+
+
+const char *args_desc[][2] =
+{
+ { "input.pbm", "A binary image. 'False' for objects, 'True'\
+for the background." },
+ { "out.txt", "A text file with all the recognized text" },
+ {0, 0}
+};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace scribo;
+ using namespace mln;
+
+ if (argc != 4)
+ return scribo::debug::usage(argv,
+ "Find text in a binarized photo.",
+ "input.pbm out.txt output_dir",
+ args_desc,
+ "Debug outputs. The recognized text is printed in the standard output.");
+
+ scribo::make::internal::debug_filename_prefix = argv[3];
+
+ trace::entering("main");
+
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ logical::not_inplace(input);
+
+ typedef image2d<value::label_16> L;
+
+ /// Extracting vertical and horizontal lines.
+ value::label_16 nhlines, nvlines;
+ object_image(L)
+ lbl_v = primitive::extract::lines_v_discontinued(input, c8(),
+ nvlines, 51, 8);
+ object_image(L)
+ lbl_h = primitive::extract::lines_h_discontinued(input, c8(),
+ nhlines, 51, 6);
+ /// Reconstruct and erase tables.
+ image2d<bool> input_notables
+ = scribo::table::erase(input, lbl_h, lbl_v);
+
+
+ /// Finding objects.
+ value::label_16 nobjects;
+ object_image(L)
+ objects = scribo::primitive::extract::objects(input_notables,
+ c8(),
+ nobjects);
+
+
+ /// First filtering.
+ object_image(L) filtered_objects
+ = scribo::filter::objects_small(objects, 6);
+
+ filtered_objects
+ = scribo::filter::objects_thin(filtered_objects, 2);
+
+// filtered_objects
+// = scribo::filter::objects_thick(filtered_objects,
+// math::min(input.ncols(), input.nrows()) / 5);
+
+
+
+ /// Grouping potential objects
+ object_links<L> left_link
+ = primitive::link::with_single_left_link(filtered_objects, 30);
+ object_links<L> right_link
+ = primitive::link::with_single_right_link(filtered_objects, 30);
+
+
+#ifndef NOUT
+ std::cout << "BEFORE - nobjects = " << nobjects << std::endl;
+ scribo::debug::save_linked_bboxes_image(input,
+ filtered_objects,
+ left_link, right_link,
+ literal::red, literal::cyan,
+ literal::yellow,
+ literal::green,
+ scribo::make::debug_filename("links.ppm"));
+#endif
+
+
+ // Validating left and right links.
+ object_links<L>
+ merged_links = primitive::link::merge_double_link(filtered_objects,
+ left_link,
+ right_link);
+
+
+
+
+ // Remove links if bboxes have too different sizes.
+ object_links<L> bottom_filtered_links
+ = filter::object_links_bottom_aligned(filtered_objects,
+ merged_links,
+ 5);
+
+
+
+#ifndef NOUT
+ image2d<value::rgb8>
+ bottom_decision_image = scribo::debug::decision_image(input,
+ merged_links,
+ bottom_filtered_links);
+
+ io::ppm::save(bottom_decision_image,
+ scribo::make::debug_filename("bottom_links_decision_image.ppm"));
+#endif
+
+
+
+
+
+ // Remove links if bboxes have too different sizes.
+ object_links<L> hratio_filtered_links
+ = filter::object_links_bbox_h_ratio(filtered_objects,
+ bottom_filtered_links,
+ 0.6f);
+
+
+
+
+#ifndef NOUT
+ image2d<value::rgb8>
+ hratio_decision_image = scribo::debug::decision_image(input,
+ bottom_filtered_links,
+ hratio_filtered_links);
+ io::ppm::save(hratio_decision_image,
+ scribo::make::debug_filename("hratio_links_decision_image.ppm"));
+#endif
+
+
+
+
+ //Remove links if bboxes overlap too much.
+ object_links<L> overlap_filtered_links
+ = filter::object_links_bbox_overlap(filtered_objects,
+ hratio_filtered_links,
+ 0.80f);
+
+
+
+
+#ifndef NOUT
+ image2d<value::rgb8> overlap_decision_image
+ = scribo::debug::decision_image(input,
+ hratio_filtered_links,
+ overlap_filtered_links);
+ io::ppm::save(overlap_decision_image,
+ scribo::make::debug_filename("overlap_links_decision_image.ppm"));
+#endif
+
+
+
+
+ object_groups<L>
+ groups = primitive::group::from_single_link(filtered_objects,
+ overlap_filtered_links);
+
+
+// // Remove objects part of groups with strictly less than 3 objects.
+// object_groups<L> filtered_groups = filter::object_groups_small(groups, 3);
+
+
+// #ifndef NOUT
+// image2d<value::rgb8>
+// decision_image = scribo::debug::decision_image(input,
+// groups, filtered_groups);
+// #endif
+
+ object_image(L)
+ grouped_objects = primitive::group::apply(filtered_objects, groups);
+
+
+#ifndef NOUT
+ io::ppm::save(mln::labeling::colorize(value::rgb8(),
+ grouped_objects,
+ grouped_objects.nlabels()),
+ scribo::make::debug_filename("out.ppm"));
+#endif
+
+
+ text::recognition(grouped_objects, "fra", argv[2]);
+
+ trace::exiting("main");
+}
--
1.5.6.5
1
0
28 Aug '09
---
scribo/ChangeLog | 4 +
scribo/src/text_in_photo.cc | 133 +++++++++++++++++++++++++++++++-----------
2 files changed, 102 insertions(+), 35 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 06940eb..47ca131 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ * src/text_in_photo.cc: Improve text detection in pictures.
+
+2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
New filters in Scribo.
* filter/object_links_bbox_h_ratio.hh,
diff --git a/scribo/src/text_in_photo.cc b/scribo/src/text_in_photo.cc
index 1cf90b5..152e9b2 100644
--- a/scribo/src/text_in_photo.cc
+++ b/scribo/src/text_in_photo.cc
@@ -42,23 +42,37 @@
#include <mln/draw/box.hh>
+
+#include <scribo/draw/bounding_boxes.hh>
+
#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/group/apply.hh>
+
+#include <scribo/primitive/link/merge_double_link.hh>
#include <scribo/primitive/link/with_single_left_link.hh>
#include <scribo/primitive/link/with_single_right_link.hh>
+
+#include <scribo/primitive/group/apply.hh>
#include <scribo/primitive/group/from_double_link.hh>
#include <scribo/primitive/group/from_single_link.hh>
+
+#include <scribo/filter/object_links_bbox_h_ratio.hh>
+#include <scribo/filter/object_links_bbox_overlap.hh>
+
#include <scribo/filter/objects_small.hh>
#include <scribo/filter/objects_thin.hh>
#include <scribo/filter/objects_thick.hh>
+
#include <scribo/filter/object_groups_small.hh>
-#include <scribo/make/debug_filename.hh>
+#include <scribo/debug/decision_image.hh>
+#include <scribo/debug/save_bboxes_image.hh>
#include <scribo/debug/save_bboxes_image.hh>
#include <scribo/debug/save_linked_bboxes_image.hh>
#include <scribo/debug/usage.hh>
+#include <scribo/make/debug_filename.hh>
+
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. 'True' for objects, 'False'\
@@ -72,8 +86,6 @@ int main(int argc, char* argv[])
using namespace scribo;
using namespace mln;
- scribo::make::internal::debug_filename_prefix = argv[2];
-
if (argc != 3)
return scribo::debug::usage(argv,
"Find text in a binarized photo.",
@@ -82,6 +94,8 @@ int main(int argc, char* argv[])
"A color image where the text is \
highlighted.");
+ scribo::make::internal::debug_filename_prefix = argv[2];
+
trace::entering("main");
image2d<bool> input;
@@ -94,7 +108,6 @@ highlighted.");
object_image(L)
objects = scribo::primitive::extract::objects(input, c8(), nobjects);
-
/// First filtering.
object_image(L) filtered_objects
= scribo::filter::objects_small(objects, 6);
@@ -102,9 +115,10 @@ highlighted.");
filtered_objects
= scribo::filter::objects_thin(filtered_objects, 1);
- filtered_objects
- = scribo::filter::objects_thick(filtered_objects,
- math::min(input.ncols(), input.nrows()) / 5);
+// filtered_objects
+// = scribo::filter::objects_thick(filtered_objects,
+// math::min(input.ncols(), input.nrows()) / 5);
+
/// Grouping potential objects
object_links<L> left_link
@@ -113,6 +127,9 @@ highlighted.");
= primitive::link::with_single_right_link(filtered_objects, 30);
+
+
+
#ifndef NOUT
std::cout << "BEFORE - nobjects = " << nobjects << std::endl;
scribo::debug::save_linked_bboxes_image(input,
@@ -124,57 +141,103 @@ highlighted.");
scribo::make::debug_filename("links.ppm"));
#endif
- // Trying to group objects
+
+
+ // Validating left and right links.
+ object_links<L>
+ merged_links = primitive::link::merge_double_link(filtered_objects,
+ left_link,
+ right_link);
+ // Remove links if bboxes have too different sizes.
+ object_links<L>
+ hratio_filtered_links = filter::object_links_bbox_h_ratio(filtered_objects,
+ merged_links,
+ 0.7f);
+
+
+
+
+#ifndef NOUT
+ image2d<value::rgb8>
+ hratio_decision_image = scribo::debug::decision_image(input,
+ merged_links,
+ hratio_filtered_links);
+ io::ppm::save(hratio_decision_image,
+ scribo::make::debug_filename("hratio_links_decision_image.ppm"));
+#endif
+
+
+
+
+ //Remove links if bboxes overlap too much.
+ object_links<L> overlap_filtered_links
+ = filter::object_links_bbox_overlap(filtered_objects,
+ hratio_filtered_links,
+ 0.80f);
+
+
+
+
+#ifndef NOUT
+ image2d<value::rgb8> overlap_decision_image
+ = scribo::debug::decision_image(input,
+ hratio_filtered_links,
+ overlap_filtered_links);
+ io::ppm::save(overlap_decision_image,
+ scribo::make::debug_filename("overlap_links_decision_image.ppm"));
+#endif
+
+
+
+
object_groups<L>
- groups = primitive::group::from_double_link(filtered_objects,
- left_link, right_link);
+ groups = primitive::group::from_single_link(filtered_objects,
+ overlap_filtered_links);
+
- // Remove objects part of groups with less than 3 objects.
- mln::util::array<bool>
- to_be_kept = filter::object_groups_small(groups, 3);
+ // Remove objects part of groups with strictly less than 3 objects.
+ object_groups<L> filtered_groups = filter::object_groups_small(groups, 3);
- // FOR DEBUGGING PURPOSE.
- image2d<value::rgb8> decision_image = data::convert(value::rgb8(), input);
- for (unsigned i = 1; i < to_be_kept.size(); ++i)
- {
- if (!to_be_kept(i))
- mln::draw::box(decision_image, filtered_objects.bbox(i), literal::red);
- else
- mln::draw::box(decision_image, filtered_objects.bbox(i), literal::green);
- }
- // END OF DEBUG
+#ifndef NOUT
+ image2d<value::rgb8>
+ decision_image = scribo::debug::decision_image(input,
+ groups, filtered_groups);
+#endif
+
- filtered_objects.relabel(to_be_kept);
+ /// Apply grouping in the object image.
+ object_image(L)
+ grouped_objects = primitive::group::apply(filtered_objects,
+ filtered_groups);
- /// Objects have been removed we need to update object links again.
+ /// Objects have been grouped. We try to link groups together.
/// This time a single link is enough since non-wanted objects have
/// been removed.
left_link
- = primitive::link::with_single_left_link(filtered_objects, 30);
+ = primitive::link::with_single_left_link(grouped_objects, 30);
+ /// Grouping groups.
+ groups = primitive::group::from_single_link(grouped_objects, left_link);
+
+ grouped_objects = primitive::group::apply(grouped_objects, groups);
- /// Grouping objects again.
- groups = primitive::group::from_single_link(filtered_objects, left_link);
- object_image(L)
- grouped_objects = primitive::group::apply(filtered_objects, groups);
#ifndef NOUT
- /// FOR DEBUG PURPOSE.
- for (unsigned i = 1; i <= grouped_objects.nlabels(); ++i)
- mln::draw::box(decision_image, grouped_objects.bbox(i), literal::blue);
+ scribo::draw::bounding_boxes(decision_image, grouped_objects, literal::blue);
io::ppm::save(decision_image, scribo::make::debug_filename("decision_image.ppm"));
-
std::cout << "AFTER - nobjects = " << grouped_objects.nlabels() << std::endl;
#endif
+
+
io::ppm::save(mln::labeling::colorize(value::rgb8(),
grouped_objects,
grouped_objects.nlabels()),
--
1.5.6.5
1
0
* filter/object_links_bbox_h_ratio.hh,
* filter/object_links_bbox_overlap.hh,
* filter/object_links_bbox_ratio.hh,
* filter/object_links_bbox_w_ratio.hh,
* filter/object_links_bottom_aligned.hh,
* filter/object_links_non_aligned_simple.hh: New.
---
scribo/ChangeLog | 11 ++
scribo/filter/object_links_bbox_h_ratio.hh | 97 ++++++++++++++
scribo/filter/object_links_bbox_overlap.hh | 131 +++++++++++++++++++
scribo/filter/object_links_bbox_ratio.hh | 111 ++++++++++++++++
scribo/filter/object_links_bbox_w_ratio.hh | 97 ++++++++++++++
scribo/filter/object_links_bottom_aligned.hh | 115 ++++++++++++++++
scribo/filter/object_links_non_aligned_simple.hh | 151 ++++++++++++++++++++++
7 files changed, 713 insertions(+), 0 deletions(-)
create mode 100644 scribo/filter/object_links_bbox_h_ratio.hh
create mode 100644 scribo/filter/object_links_bbox_overlap.hh
create mode 100644 scribo/filter/object_links_bbox_ratio.hh
create mode 100644 scribo/filter/object_links_bbox_w_ratio.hh
create mode 100644 scribo/filter/object_links_bottom_aligned.hh
create mode 100644 scribo/filter/object_links_non_aligned_simple.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 1b40996..06940eb 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,16 @@
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ New filters in Scribo.
+
+ * filter/object_links_bbox_h_ratio.hh,
+ * filter/object_links_bbox_overlap.hh,
+ * filter/object_links_bbox_ratio.hh,
+ * filter/object_links_bbox_w_ratio.hh,
+ * filter/object_links_bottom_aligned.hh,
+ * filter/object_links_non_aligned_simple.hh: New.
+
+2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
* debug/decision_image.hh: New debug routine.
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
diff --git a/scribo/filter/object_links_bbox_h_ratio.hh b/scribo/filter/object_links_bbox_h_ratio.hh
new file mode 100644
index 0000000..6ced8e6
--- /dev/null
+++ b/scribo/filter/object_links_bbox_h_ratio.hh
@@ -0,0 +1,97 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_OBJECT_LINKS_BBOX_H_RATIO_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_BBOX_H_RATIO_HH
+
+/// \file
+///
+/// Invalidate links between two objects with too different height or
+/// width.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/filter/object_links_bbox_ratio.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two objects with too different
+ height.
+
+ \param[in] objects An object image.
+ \param[in] links Link objects information.
+ \param[in] min_h_ratio The minimum height ratio of two linked
+ bounding boxes.
+
+ \result A filtered object link information.
+ */
+ template <typename L>
+ object_links<L>
+ object_links_bbox_h_ratio(const object_image(L)& objects,
+ const object_links<L>& links,
+ float min_h_ratio);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_bbox_h_ratio(const object_image(L)& objects,
+ const object_links<L>& links,
+ float min_h_ratio)
+ {
+ trace::entering("scribo::filter::object_links_bbox_h_ratio");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+
+ object_links<L>
+ output = object_links_bbox_ratio(objects, links, 0, min_h_ratio);
+
+ trace::exiting("scribo::filter::object_links_bbox_h_ratio");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_BBOX_H_RATIO_HH
diff --git a/scribo/filter/object_links_bbox_overlap.hh b/scribo/filter/object_links_bbox_overlap.hh
new file mode 100644
index 0000000..ff65e92
--- /dev/null
+++ b/scribo/filter/object_links_bbox_overlap.hh
@@ -0,0 +1,131 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_OBJECT_LINKS_BBOX_OVERLAP_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_BBOX_OVERLAP_HH
+
+/// \file
+///
+/// Invalidate links between two objects having their bounding box
+/// overlapping too much.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/filter/object_links_bbox_ratio.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two objects having their bounding box
+ overlapping too much.
+
+ \param[in] objects An object image.
+ \param[in] links Link objects information.
+ \param[in] max_overlap_ratio The maximum ratio of the overlapping
+ areas.
+
+ \result A filtered object link information.
+ */
+ template <typename L>
+ object_links<L>
+ object_links_bbox_overlap(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_overlap_ratio);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_bbox_overlap(const object_image(L)& objects,
+ const object_links<L>& links,
+ float max_overlap_ratio)
+ {
+ trace::entering("scribo::filter::object_links_bbox_overlap");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+ mln_precondition(objects.id_() == links.objects_id_());
+
+ typedef typename object_image(L)::bbox_t bbox_t;
+ const mln::util::array<bbox_t>& bboxes = objects.bboxes();
+ object_links<L> output(links);
+
+ for_all_components(i, objects.bboxes())
+ if (links(i) != i)
+ {
+ bool has_intersection = true;
+ mln_site(L) pmin, pmax;
+ for (unsigned dim = 0; dim < mln_site_(L)::dim; ++dim)
+ {
+ pmin[dim] = math::max(bboxes(i).pmin()[dim],
+ bboxes(links[i]).pmin()[dim]);
+ pmax[dim] = math::min(bboxes(i).pmax()[dim],
+ bboxes(links[i]).pmax()[dim]);
+
+ if (pmin[dim] > pmax[dim])
+ {
+ has_intersection = false;
+ break;
+ }
+ }
+
+ if (!has_intersection)
+ continue;
+
+ mln_box(L) interbbox(pmin, pmax);
+ float
+ ratio_i = interbbox.nsites() /(float)bboxes(i).nsites(),
+ ratio_link_i = interbbox.nsites() /(float)bboxes(links(i)).nsites();
+
+ if (ratio_i >= max_overlap_ratio
+ || ratio_link_i >= max_overlap_ratio)
+ output[i] = i;
+ }
+
+ trace::exiting("scribo::filter::object_links_bbox_overlap");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_BBOX_OVERLAP_HH
diff --git a/scribo/filter/object_links_bbox_ratio.hh b/scribo/filter/object_links_bbox_ratio.hh
new file mode 100644
index 0000000..3cd0c7e
--- /dev/null
+++ b/scribo/filter/object_links_bbox_ratio.hh
@@ -0,0 +1,111 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_OBJECT_LINKS_BBOX_RATIO_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_BBOX_RATIO_HH
+
+/// \file
+///
+/// Invalidate links between two objects with too different height or
+/// width.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two objects with too different
+ height or width.
+
+ \param[in] objects An object image.
+ \param[in] links Link objects information.
+ \param[in] dim The dimension to use to compare bbox length.
+ \param[in] min_ratio The minimum length ratio of two linked
+ bounding boxes.
+
+ \result A filtered object link information.
+ */
+ template <typename L>
+ object_links<L>
+ object_links_bbox_ratio(const object_image(L)& objects,
+ const object_links<L>& links,
+ unsigned dim,
+ float min_ratio);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_bbox_ratio(const object_image(L)& objects,
+ const object_links<L>& links,
+ unsigned dim,
+ float min_ratio)
+ {
+ trace::entering("scribo::filter::object_links_bbox_ratio");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+
+ object_links<L> output(links);
+ for (unsigned i = 1; i < links.size(); ++i)
+ {
+ float
+ lmin = objects.bbox(i).pmax()[dim] - objects.bbox(i).pmin()[dim],
+ lmax = objects.bbox(links(i)).pmax()[dim]
+ - objects.bbox(links(i)).pmin()[dim];
+
+ if (lmin > lmax)
+ std::swap(lmin, lmax);
+
+ if (lmin / lmax < min_ratio)
+ output(i) = i;
+ }
+
+ trace::exiting("scribo::filter::object_links_bbox_ratio");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_BBOX_RATIO_HH
diff --git a/scribo/filter/object_links_bbox_w_ratio.hh b/scribo/filter/object_links_bbox_w_ratio.hh
new file mode 100644
index 0000000..7cc99c3
--- /dev/null
+++ b/scribo/filter/object_links_bbox_w_ratio.hh
@@ -0,0 +1,97 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_OBJECT_LINKS_BBOX_W_RATIO_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_BBOX_W_RATIO_HH
+
+/// \file
+///
+/// Invalidate links between two objects with too different height or
+/// width.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+# include <scribo/filter/object_links_bbox_ratio.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two objects with too different
+ width.
+
+ \param[in] objects An object image.
+ \param[in] links Link objects information.
+ \param[in] min_w_ratio The minimum width ratio of two linked
+ bounding boxes.
+
+ \result A filtered object link information.
+ */
+ template <typename L>
+ object_links<L>
+ object_links_bbox_w_ratio(const object_image(L)& objects,
+ const object_links<L>& links,
+ float min_w_ratio);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_bbox_w_ratio(const object_image(L)& objects,
+ const object_links<L>& links,
+ float min_w_ratio)
+ {
+ trace::entering("scribo::filter::object_links_bbox_w_ratio");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+
+ object_links<L>
+ output = object_links_bbox_ratio(objects, links, 1, min_w_ratio);
+
+ trace::exiting("scribo::filter::object_links_bbox_w_ratio");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_BBOX_W_RATIO_HH
diff --git a/scribo/filter/object_links_bottom_aligned.hh b/scribo/filter/object_links_bottom_aligned.hh
new file mode 100644
index 0000000..0846203
--- /dev/null
+++ b/scribo/filter/object_links_bottom_aligned.hh
@@ -0,0 +1,115 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_OBJECT_LINKS_BOTTOM_ALIGNED_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_BOTTOM_ALIGNED_HH
+
+/// \file
+///
+/// Invalidate links between two objects if their bottom are not
+/// aligned.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+
+# include <scribo/filter/object_links_non_aligned_simple.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two objects if their bottom are not
+ aligned.
+
+ \param[in] objects An object image.
+ \param[in] links Object links information.
+ \param[in] dim Choose the dimension on which applying the
+ filter.
+ \param[in] max_delta Maximum delta.
+
+ \verbatim
+
+ ------
+ | |
+ ------ | |
+ | | | |
+ | x------------x |
+ | | | | v
+ ------ ~ ~ ~ |~ ~ | ~ ~ ~
+ object1 | | | => delta, must be < to max_delta
+ ------ ~ ~ ~
+ object2 ^
+
+ \endverbatim
+
+ */
+ template <typename L>
+ object_links<L>
+ object_links_bottom_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ unsigned max_delta);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_bottom_aligned(const object_image(L)& objects,
+ const object_links<L>& links,
+ unsigned max_delta)
+ {
+ trace::entering("scribo::filter::object_links_bottom_aligned");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+
+ object_links<L>
+ output = object_links_non_aligned_simple(objects, links,
+ 1, 1,
+ max_delta);
+
+ trace::exiting("scribo::filter::object_links_bottom_aligned");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_NON_ALIGNED_SIMPLE_HH
diff --git a/scribo/filter/object_links_non_aligned_simple.hh b/scribo/filter/object_links_non_aligned_simple.hh
new file mode 100644
index 0000000..e302fcf
--- /dev/null
+++ b/scribo/filter/object_links_non_aligned_simple.hh
@@ -0,0 +1,151 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_OBJECT_LINKS_NON_ALIGNED_SIMPLE_HH
+# define SCRIBO_FILTER_OBJECT_LINKS_NON_ALIGNED_SIMPLE_HH
+
+/// \file
+///
+/// Invalidate links between two non aligned objects.
+
+
+# include <mln/util/array.hh>
+
+# include <scribo/core/macros.hh>
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_image.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+ /*! \brief Invalidate links between two non aligned objects.
+ Alignment is based on a given edge of object bounding boxes.
+
+ \param[in] objects An object image.
+ \param[in] links Object links information.
+ \param[in] dim Choose the dimension on which applying the
+ filter.
+ \param[in] max_delta Maximum delta.
+
+
+ Exemple with dim == 1 and edge == 1 (bottom
+ horizontal filter):
+
+ \verbatim
+
+ ------
+ | |
+ ------ | |
+ | | | |
+ | x------------x |
+ | | | | v
+ ------ ~ ~ ~ |~ ~ | ~ ~ ~
+ object1 | | | => delta, must be < to max_delta
+ ------ ~ ~ ~
+ object2 ^
+
+ \endverbatim
+
+ */
+ template <typename L>
+ object_links<L>
+ object_links_non_aligned_simple(const object_image(L)& objects,
+ const object_links<L>& links,
+ unsigned dim,
+ unsigned edge,
+ unsigned max_delta);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ object_links<L>
+ object_links_non_aligned_simple(const object_image(L)& objects,
+ const object_links<L>& links,
+ unsigned dim,
+ unsigned edge,
+ unsigned max_delta)
+ {
+ trace::entering("scribo::filter::object_links_non_aligned_simple");
+
+ mln_precondition(objects.is_valid());
+ mln_precondition(links.is_valid());
+
+ typedef typename object_image(L)::bbox_t bbox_t;
+ const mln::util::array<bbox_t>& bboxes = objects.bboxes();
+ object_links<L> output(links);
+ unsigned delta;
+
+
+ if (edge == 0)
+ {
+ for_all_components(i, objects.bboxes())
+ if (links[i] != i)
+ {
+ delta = bboxes[i].pmin()[dim] - bboxes[i].pmin()[dim];
+
+ if (delta > max_delta)
+ output[i] = i;
+ }
+ }
+ else if (edge == 1)
+ for_all_components(i, objects.bboxes())
+ {
+ if (links[i] != i)
+ {
+ delta = bboxes[i].pmax()[dim] - bboxes[i].pmax()[dim];
+
+ if (delta > max_delta)
+ output[i] = i;
+ }
+ }
+ else
+ {
+ trace::warning("Invalid edge value...");
+ trace::exiting("scribo::filter::object_links_non_aligned_simple");
+ return output;
+ }
+
+
+ trace::exiting("scribo::filter::object_links_non_aligned_simple");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_OBJECT_LINKS_NON_ALIGNED_SIMPLE_HH
--
1.5.6.5
1
0
---
scribo/ChangeLog | 4 +
scribo/debug/decision_image.hh | 174 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 178 insertions(+), 0 deletions(-)
create mode 100644 scribo/debug/decision_image.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 1a26e66..1b40996 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ * debug/decision_image.hh: New debug routine.
+
+2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Small fixes in Scribo.
* core/object_links.hh,
diff --git a/scribo/debug/decision_image.hh b/scribo/debug/decision_image.hh
new file mode 100644
index 0000000..46fbcff
--- /dev/null
+++ b/scribo/debug/decision_image.hh
@@ -0,0 +1,174 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_DEBUG_DECISION_IMAGE_HH
+# define SCRIBO_DEBUG_DECISION_IMAGE_HH
+
+/// \file
+///
+/// Save a color image showing the difference between to object groups.
+
+# include <mln/core/concept/image.hh>
+# include <mln/data/convert.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/draw/bounding_boxes.hh>
+
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+
+ /*! \brief Save a color image showing the difference between to
+ object groups.
+
+ \input[in] input An image. It's value type must be convertible
+ towards rgb8.
+ \input[in] groups Object groups information.
+ \input[in] filtered_groups A copy of \p groups which have been
+ filtered.
+
+ \return A color image. Objects part of a validated group are
+ drawn in green with their bounding box. Otherwise,
+ they are drawn in red.
+ */
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ decision_image(const Image<I>& input_,
+ const object_groups<L>& groups,
+ const object_groups<L>& filtered_groups);
+
+ /*! \brief Save a color image showing the difference between to
+ object links.
+
+ \input[in] input An image. It's value type must be convertible
+ towards rgb8.
+ \input[in] links Object links information.
+ \input[in] filtered_links A copy of \p links which have been
+ filtered.
+
+ \return A color image. Non filtered links are drawn in
+ green. Others are drawn in red.
+ */
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ decision_image(const Image<I>& input_,
+ const object_groups<L>& groups,
+ const object_groups<L>& filtered_groups)
+ {
+ trace::entering("scribo::debug::decision_image");
+ const I& input = exact(input_);
+
+ const object_image(L)& objects = groups.object_image_();
+
+ mln_precondition(input.is_valid());
+ mln_precondition(groups.is_valid());
+ mln_precondition(filtered_groups.is_valid());
+ mln_precondition(groups.size() == filtered_groups.size());
+ mln_precondition(groups.objects_id() != filtered_groups.objects_id());
+ /// Fixme: check that objects has been computed from input.
+
+ image2d<value::rgb8>
+ decision_image = data::convert(value::rgb8(), input);
+
+ for (unsigned i = 1; i < groups.size(); ++i)
+ if (groups(i) != filtered_groups(i))
+ mln::draw::box(decision_image, objects.bbox(i), literal::red);
+ else
+ mln::draw::box(decision_image, objects.bbox(i), literal::green);
+
+ trace::exiting("scribo::debug::decision_image");
+ return decision_image;
+ }
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ decision_image(const Image<I>& input_,
+ const object_links<L>& links,
+ const object_links<L>& filtered_links)
+ {
+ trace::entering("scribo::debug::decision_image");
+ const I& input = exact(input_);
+
+ const object_image(L)& objects = links.object_image_();
+
+ mln_precondition(input.is_valid());
+ mln_precondition(links.is_valid());
+ mln_precondition(filtered_links.is_valid());
+ mln_precondition(links.size() == filtered_links.size());
+ mln_precondition(links.objects_id() != filtered_links.objects_id());
+ /// Fixme: check that objects has been computed from input.
+
+ image2d<value::rgb8>
+ decision_image = data::convert(value::rgb8(), input);
+
+ for_all_components(i, objects.bboxes())
+ mln::draw::box(decision_image, objects.bbox(i), literal::blue);
+
+ for (unsigned i = 1; i < links.size(); ++i)
+ {
+
+ if (links[i] != i)
+ {
+ value::rgb8 value = literal::green;
+ if (links[i] != filtered_links[i])
+ value = literal::red;
+ mln::draw::line(decision_image,
+ objects.bbox(i).center(),
+ objects.bbox(links[i]).center(),
+ value);
+ }
+ }
+
+ trace::exiting("scribo::debug::decision_image");
+ return decision_image;
+ }
+
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEBUG_DECISION_IMAGE_HH
--
1.5.6.5
1
0
* core/object_links.hh,
* core/object_groups.hh: Add default constructor and is_valid
member.
* debug/save_linked_bboxes_image.hh,
* draw/bounding_box_links.hh: Update arguments type.
* draw/bounding_boxes.hh: Add a new overload.
* filter/object_groups_small.hh: Make it return an object_groups.
* filter/object_links_non_aligned.hh: Do not do anything if a box
does not have any link.
* src/table/erase.cc: Add comments.
---
scribo/ChangeLog | 20 ++++++++++
scribo/core/object_groups.hh | 15 ++++++++
scribo/core/object_links.hh | 16 ++++++++
scribo/debug/save_linked_bboxes_image.hh | 22 ++++++------
scribo/draw/bounding_box_links.hh | 56 ++++++++++++++--------------
scribo/draw/bounding_boxes.hh | 19 ++++++++++
scribo/filter/object_groups_small.hh | 28 ++++++++-------
scribo/filter/object_links_non_aligned.hh | 32 ++++++++--------
scribo/src/table/erase.cc | 2 +
9 files changed, 142 insertions(+), 68 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 5dc8c5e..1a26e66 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,25 @@
2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Small fixes in Scribo.
+
+ * core/object_links.hh,
+ * core/object_groups.hh: Add default constructor and is_valid
+ member.
+
+ * debug/save_linked_bboxes_image.hh,
+ * draw/bounding_box_links.hh: Update arguments type.
+
+ * draw/bounding_boxes.hh: Add a new overload.
+
+ * filter/object_groups_small.hh: Make it return an object_groups.
+
+ * filter/object_links_non_aligned.hh: Do not do anything if a box
+ does not have any link.
+
+ * src/table/erase.cc: Add comments.
+
+2009-08-28 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Add Sauvola's binarization.
* binarization/sauvola.hh: New routine.
diff --git a/scribo/core/object_groups.hh b/scribo/core/object_groups.hh
index 3e49942..15e2004 100644
--- a/scribo/core/object_groups.hh
+++ b/scribo/core/object_groups.hh
@@ -52,6 +52,7 @@ namespace scribo
typedef mln::util::array<unsigned> super_t;
public:
+ object_groups();
object_groups(const object_image(L)& objects);
object_groups(const object_image(L)& objects, unsigned n);
object_groups(const object_image(L)& objects, unsigned n, unsigned value);
@@ -61,6 +62,8 @@ namespace scribo
void init_(const object_links<L>& links);
+ bool is_valid() const;
+
private:
object_image(L) objects_;
};
@@ -69,6 +72,11 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
template <typename L>
+ object_groups<L>::object_groups()
+ {
+ }
+
+ template <typename L>
object_groups<L>::object_groups(const object_image(L)& objects)
: objects_(objects)
{
@@ -115,6 +123,13 @@ namespace scribo
this->hook_std_vector_() = links.std_vector();
}
+ template <typename L>
+ bool
+ object_groups<L>::is_valid() const
+ {
+ return objects_.is_valid() && objects_.nlabels() == (this->size() - 1);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/core/object_links.hh b/scribo/core/object_links.hh
index aa70bf8..1c020dd 100644
--- a/scribo/core/object_links.hh
+++ b/scribo/core/object_links.hh
@@ -51,6 +51,7 @@ namespace scribo
typedef mln::util::array<unsigned> super_t;
public:
+ object_links();
object_links(const object_image(L)& objects);
object_links(const object_image(L)& objects, unsigned n);
object_links(const object_image(L)& objects, unsigned n, unsigned value);
@@ -59,6 +60,8 @@ namespace scribo
const void* objects_id_() const;
const object_image(L)& object_image_() const;
+ bool is_valid() const;
+
private:
object_image(L) objects_;
};
@@ -67,6 +70,11 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
template <typename L>
+ object_links<L>::object_links()
+ {
+ }
+
+ template <typename L>
object_links<L>::object_links(const object_image(L)& objects)
: objects_(objects)
{
@@ -105,6 +113,14 @@ namespace scribo
}
+ template <typename L>
+ bool
+ object_links<L>::is_valid() const
+ {
+ return objects_.is_valid() && objects_.nlabels() == (this->size() - 1);
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/debug/save_linked_bboxes_image.hh b/scribo/debug/save_linked_bboxes_image.hh
index ed35622..6ce0ad0 100644
--- a/scribo/debug/save_linked_bboxes_image.hh
+++ b/scribo/debug/save_linked_bboxes_image.hh
@@ -65,7 +65,7 @@ namespace scribo
void
save_linked_bboxes_image(const Image<I>& input,
const object_image(L)& objects,
- const mln::util::array<unsigned>& link_array,
+ const object_links<L>& array,
const value::rgb8& box_value,
const value::rgb8& link_value,
const std::string& filename);
@@ -83,8 +83,8 @@ namespace scribo
void
save_linked_bboxes_image(const Image<I>& input,
const object_image(L)& objects,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const value::rgb8& box_value,
const value::rgb8& link_value,
const std::string& filename);
@@ -106,8 +106,8 @@ namespace scribo
void
save_linked_bboxes_image(const Image<I>& input,
const object_image(L)& objects,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const value::rgb8& box_value,
const value::rgb8& left_link_value,
const value::rgb8& right_link_value,
@@ -141,7 +141,7 @@ namespace scribo
void
save_linked_bboxes_image(const Image<I>& input,
const object_image(L)& objects,
- const mln::util::array<unsigned>& link_array,
+ const object_links<L>& array,
const value::rgb8& box_value,
const value::rgb8& link_value,
const std::string& filename)
@@ -157,7 +157,7 @@ namespace scribo
objects.nlabels());
draw::bounding_boxes(tmp, objects.bboxes(), box_value);
- draw::bounding_box_links(tmp, mass_center, link_array, link_value);
+ draw::bounding_box_links(tmp, mass_center, array, link_value);
io::ppm::save(tmp, filename);
@@ -170,8 +170,8 @@ namespace scribo
void
save_linked_bboxes_image(const Image<I>& input,
const object_image(L)& objects,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const value::rgb8& box_value,
const value::rgb8& value,
const std::string& filename)
@@ -202,8 +202,8 @@ namespace scribo
void
save_linked_bboxes_image(const Image<I>& input,
const object_image(L)& objects,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const value::rgb8& box_value,
const value::rgb8& left_link_value,
const value::rgb8& right_link_value,
diff --git a/scribo/draw/bounding_box_links.hh b/scribo/draw/bounding_box_links.hh
index 15e7260..9a2919e 100644
--- a/scribo/draw/bounding_box_links.hh
+++ b/scribo/draw/bounding_box_links.hh
@@ -51,13 +51,13 @@ namespace scribo
///
/// \param[in,out] input_ An image where to draw.
/// \param[in] bboxes Bounding boxes.
- /// \param[in] link_array Bounding box links.
+ /// \param[in] links Bounding box links.
/// \param[in] value Value used to draw links.
- template <typename I>
+ template <typename I, typename L>
void
bounding_box_links(Image<I>& input_,
const mln::util::array< box<mln_site(I)> >& bboxes,
- const mln::util::array<unsigned>& link_array,
+ const object_links<L>& link,
const mln_value(I)& value);
@@ -65,14 +65,14 @@ namespace scribo
///
/// \param[in,out] input_ An image where to draw.
/// \param[in] mass_centers Bounding boxes mass centers.
- /// \param[in] link_array Bounding box links.
+ /// \param[in] links Bounding box links.
/// \param[in] value Value used to draw links.
- template <typename I>
+ template <typename I, typename L>
inline
void
bounding_box_links(Image<I>& input_,
const mln::util::array<mln_site(I)::vec>& mass_centers,
- const mln::util::array<unsigned>& link_array,
+ const object_links<L>& link,
const mln_value(I)& value);
@@ -86,13 +86,13 @@ namespace scribo
/// \param[in] left_link_value Value used to draw left links.
/// \param[in] right_link_value Value used to draw right links.
/// \param[in] validated_link_value Value used to draw validated links.
- template <typename I>
+ template <typename I, typename L>
inline
void
bounding_box_links(Image<I>& input_,
const mln::util::array< box<mln_site(I)> >& bboxes,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value,
const mln_value(I)& validated_link_value);
@@ -108,13 +108,13 @@ namespace scribo
/// \param[in] left_link_value Value used to draw left links.
/// \param[in] right_link_value Value used to draw right links.
/// \param[in] validated_link_value Value used to draw validated links.
- template <typename I>
+ template <typename I, typename L>
inline
void
bounding_box_links(Image<I>& input_,
const mln::util::array<mln_site(I)::vec>& mass_centers,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value,
const mln_value(I)& validated_link_value);
@@ -231,12 +231,12 @@ namespace scribo
} // end of namespace scribo::draw::internal
- template <typename I>
+ template <typename I, typename L>
inline
void
bounding_box_links(Image<I>& input_,
const mln::util::array< box<mln_site(I)> >& bboxes,
- const mln::util::array<unsigned>& link_array,
+ const object_links<L>& links,
const mln_value(I)& value)
{
trace::entering("scribo::draw::bounding_box_links");
@@ -245,22 +245,22 @@ namespace scribo
mln_precondition(input.is_valid());
- for_all_components(i, link_array)
- if (link_array[i] != i)
+ for_all_components(i, links)
+ if (links[i] != i)
mln::draw::line(input,
bboxes[i].center(),
- bboxes[link_array[i]].center(),
+ bboxes[links[i]].center(),
value);
trace::exiting("scribo::draw::bounding_box_links");
}
- template <typename I>
+ template <typename I, typename L>
inline
void
bounding_box_links(Image<I>& input_,
const mln::util::array<mln_site(I)::vec>& mass_centers,
- const mln::util::array<unsigned>& link_array,
+ const object_links<L>& links,
const mln_value(I)& value)
{
trace::entering("scribo::draw::bounding_box_links");
@@ -269,12 +269,12 @@ namespace scribo
mln_precondition(input.is_valid());
- for_all_components(i, link_array)
+ for_all_components(i, links)
{
- if (link_array[i] != i)
+ if (links[i] != i)
mln::draw::line(input,
mass_centers[i],
- mass_centers[link_array[i]],
+ mass_centers[links[i]],
value);
input(mass_centers[i]) = value;
}
@@ -283,13 +283,13 @@ namespace scribo
}
- template <typename I>
+ template <typename I, typename L>
inline
void
bounding_box_links(Image<I>& input_,
const mln::util::array<mln_site(I)::vec>& mass_centers,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value,
const mln_value(I)& validated_link_value)
@@ -338,13 +338,13 @@ namespace scribo
trace::exiting("scribo::draw::bounding_box_links");
}
- template <typename I>
+ template <typename I, typename L>
inline
void
bounding_box_links(Image<I>& input_,
const mln::util::array< box<mln_site(I)> >& bboxes,
- const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ const object_links<L>& left_link,
+ const object_links<L>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value,
const mln_value(I)& validated_link_value)
diff --git a/scribo/draw/bounding_boxes.hh b/scribo/draw/bounding_boxes.hh
index 6cbc6d9..2fe2cd3 100644
--- a/scribo/draw/bounding_boxes.hh
+++ b/scribo/draw/bounding_boxes.hh
@@ -35,6 +35,7 @@
# include <mln/util/array.hh>
# include <scribo/core/macros.hh>
+# include <scribo/core/object_image.hh>
namespace scribo
{
@@ -52,6 +53,13 @@ namespace scribo
const mln_value(I)& value);
+ /// Draw object bounding boxes and their associated mass center.
+ template <typename I, typename L>
+ void
+ bounding_boxes(Image<I>& input_,
+ const object_image(L)& objects,
+ const mln_value(I)& value);
+
# ifndef MLN_INCLUDE_ONLY
@@ -80,6 +88,17 @@ namespace scribo
}
+ template <typename I, typename L>
+ inline
+ void
+ bounding_boxes(Image<I>& input,
+ const object_image(L)& objects,
+ const mln_value(I)& value)
+ {
+ bounding_boxes(input, objects.bboxes(), value);
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::draw
diff --git a/scribo/filter/object_groups_small.hh b/scribo/filter/object_groups_small.hh
index fdfec6a..1e6c636 100644
--- a/scribo/filter/object_groups_small.hh
+++ b/scribo/filter/object_groups_small.hh
@@ -50,12 +50,11 @@ namespace scribo
\param[in] groups Information about object groups.
\param[in] n_links The minimum number of links per group.
- \return A function mapping an object id to a bool. It is set to
- true if an object is part of a group with more than \p n_links
- links.
+ \return A copy of object group in which small groups have been
+ removed.
*/
template <typename L>
- mln::util::array<bool>
+ object_groups<L>
object_groups_small(const object_groups<L>& groups,
unsigned n_links);
@@ -65,21 +64,24 @@ namespace scribo
template <typename L>
inline
- mln::util::array<bool>
- object_groups_small(const object_groups<L>& parent_link,
+ object_groups<L>
+ object_groups_small(const object_groups<L>& groups,
unsigned n_links)
{
+ mln_precondition(groups.is_valid());
+
// Counting the number of objects per group.
- mln::util::array<unsigned> group_size(parent_link.size(), 0);
+ mln::util::array<unsigned> group_size(groups.size(), 0);
for (unsigned i = 1; i < group_size.size(); ++i)
- ++group_size[parent_link[i]];
+ ++group_size[groups[i]];
- mln::util::array<bool> f(parent_link.size());
- f(0) = true;
- for (unsigned i = 1; i < f.size(); ++i)
- f(i) = (group_size[parent_link[i]] >= n_links);
+ object_groups<L> output(groups);
+ output(0) = 0;
+ for (unsigned i = 1; i < output.size(); ++i)
+ if (group_size[groups[i]] < n_links)
+ output(i) = 0;
- return f;
+ return output;
}
diff --git a/scribo/filter/object_links_non_aligned.hh b/scribo/filter/object_links_non_aligned.hh
index 46a425e..5d7e99a 100644
--- a/scribo/filter/object_links_non_aligned.hh
+++ b/scribo/filter/object_links_non_aligned.hh
@@ -101,25 +101,25 @@ namespace scribo
object_links<L> output(links);
for_all_components(i, objects.bboxes())
- {
-
- unsigned
- lnbh = bboxes(links[i]).pmax()[dim] - bboxes(links[i]).pmin()[dim],
- lcurrent = bboxes(i).pmax()[dim] - bboxes(i).pmin()[dim],
- hmin = i,
- hmax = links[i];
-
- if (lnbh < lcurrent)
+ if (links[i] != i)
{
- hmin = links[i];
- hmax = i;
+ unsigned
+ lnbh = bboxes(links[i]).pmax()[dim] - bboxes(links[i]).pmin()[dim],
+ lcurrent = bboxes(i).pmax()[dim] - bboxes(i).pmin()[dim],
+ hmin = i,
+ hmax = links[i];
+
+ if (lnbh < lcurrent)
+ {
+ hmin = links[i];
+ hmax = i;
+ }
+
+ if ((bboxes[hmin].pmin()[dim] - (float)bboxes[hmax].pmin()[dim]) > max_delta
+ || (bboxes[hmin].pmax()[dim] - (float) bboxes[hmax].pmax()[dim]) > max_delta)
+ output[i] = i;
}
- if ((bboxes[hmin].pmin()[dim] - (float)bboxes[hmax].pmin()[dim]) > max_delta
- || (bboxes[hmin].pmax()[dim] - (float) bboxes[hmax].pmax()[dim]) > max_delta)
- output[i] = i;
- }
-
trace::exiting("scribo::filter::object_links_non_aligned");
return output;
}
diff --git a/scribo/src/table/erase.cc b/scribo/src/table/erase.cc
index 671296a..29546bb 100644
--- a/scribo/src/table/erase.cc
+++ b/scribo/src/table/erase.cc
@@ -68,6 +68,7 @@ int main(int argc, char* argv[])
typedef image2d<label_16> lbl_t;
+ /// Extracting vertical and horizontal lines.
label_16 nhlines, nvlines;
object_image(lbl_t)
lbl_v = primitive::extract::lines_v_discontinued(input, c8(),
@@ -76,6 +77,7 @@ int main(int argc, char* argv[])
lbl_h = primitive::extract::lines_h_discontinued(input, c8(),
nhlines, 51, 6);
+ /// Reconstruct and erase tables.
image2d<bool> input_notables
= scribo::table::erase(input, lbl_h, lbl_v);
--
1.5.6.5
1
0