Olena-patches
Threads by month
- ----- 2025 -----
- 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
March 2010
- 4 participants
- 277 discussions
11 Mar '10
* text/merging.hh: Change merge rules and improve integration with
Scribo line structures.
---
scribo/ChangeLog | 7 +
scribo/text/merging.hh | 550 ++++++++++++++++++++++++++++++------------------
2 files changed, 354 insertions(+), 203 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f0f0ec3..f5deefc 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,12 @@
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Improve text line merging algorithm.
+
+ * text/merging.hh: Change merge rules and improve integration with
+ Scribo line structures.
+
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add a reconstruction algorithm.
* primitive/internal/rd.hh: New.
diff --git a/scribo/text/merging.hh b/scribo/text/merging.hh
index 2dba26c..e509475 100644
--- a/scribo/text/merging.hh
+++ b/scribo/text/merging.hh
@@ -1,3 +1,36 @@
+// Copyright (C) 2010 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_TEXT_MERGING_HH
+# define SCRIBO_TEXT_MERGING_HH
+
+/// \file
+///
+/// \brief Merge text component in order to reconstruct text lines.
+
+
#include <iostream>
#include <fstream>
#include <sstream>
@@ -16,6 +49,12 @@
#include <mln/make/box2d.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/draw/box.hh>
+#include <mln/data/stretch.hh>
+#include <mln/data/wrap.hh>
#include <mln/util/timer.hh>
@@ -26,6 +65,25 @@ namespace scribo
namespace text
{
+
+ /// \brief Merge text component in order to reconstruct text lines.
+ ///
+ /// \param[in] lines A line set.
+ ///
+ /// \return A new line set. Line ids are preserved and merged
+ /// lines (not valid anymore) are tagged with line::Merged. The
+ /// lines produced with this algorithm (valid lines) are tagged
+ /// with line::None. Line type is also set either with line::Text
+ /// or line::Punctuation.
+ //
+ template <typename L>
+ line_set<L>
+ merging(const scribo::line_set<L>& lines);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
namespace internal
{
@@ -33,13 +91,6 @@ namespace scribo
using value::int_u8;
- template <typename L>
- inline
- int delta_of_line(const scribo::line_info<L>& l)
- {
- return l.char_width() + l.char_space();
- }
-
template <typename L>
inline
@@ -54,58 +105,6 @@ namespace scribo
}
- /*!
-
- */
- template <typename L>
- struct group_data_t
- {
- group_data_t()
- : info(0)
- {
- }
-
- group_data_t(const scribo::line_info<L>& info_)
- : info(&info_)
- {
- finalize();
- }
-
- const scribo::line_info<L>* info;
-
- // deduced:
- int meanline;
- bool looks_like_a_line;
- unsigned delta;
- box2d ebox;
-
- void finalize()
- {
- if (info->x_height() == 0)
- std::cerr << "oops" << std::endl;
-
- meanline = info->baseline() - int(info->x_height()) + 1;
-
- looks_like_a_line = looks_like_a_text_line(*info);
-
- // delta = looks_like_a_line ? char_space + char_width : 0;
- delta = delta_of_line(*info);
- // FIXME: choose between:
- // char_width + char_space
- // 2 * char_width
- // char_width + 2 * char_space
-
- int A = info->a_height() - info->x_height(), D = - info->d_height();
- if (A <= 2 && D > 2)
- A = D;
- if (D <= 2 && A > 2)
- D = A;
- ebox = mln::make::box2d(meanline - A, info->bbox().pmin().col() - delta,
- info->baseline() + D, info->bbox().pmax().col() + delta);
- }
-
- };
-
template <typename T, typename T2>
void draw_box(image2d<T>& input, const box2d& b, T2 l)
{
@@ -126,6 +125,7 @@ namespace scribo
+
template <typename T, typename T2>
void draw_box(image2d<T>& input,
int pmin_row, int pmin_col,
@@ -160,6 +160,7 @@ namespace scribo
+
unsigned my_find_root(util::array<unsigned>& parent, unsigned x)
{
if (parent[x] == x)
@@ -167,6 +168,7 @@ namespace scribo
return parent[x] = my_find_root(parent, parent[x]);
}
+
void swap_ordering(unsigned l1, unsigned l2)
{
if (l2 > l1)
@@ -177,19 +179,9 @@ namespace scribo
}
- box2d union_of(const box2d& b1, const box2d& b2)
- {
- box2d b(point2d(std::min(b1.pmin().row(), b2.pmin().row()),
- std::min(b1.pmin().col(), b2.pmin().col())),
- point2d(std::max(b1.pmax().row(), b2.pmax().row()),
- std::max(b1.pmax().col(), b2.pmax().col())));
- return b;
- }
-
template <typename L>
- unsigned do_union(util::array<group_data_t<L> >& dta,
- scribo::line_set<L>& lines,
+ unsigned do_union(scribo::line_set<L>& lines,
unsigned l1,
unsigned l2,
util::array<unsigned>& parent)
@@ -197,7 +189,10 @@ namespace scribo
l1 = my_find_root(parent, l1);
l2 = my_find_root(parent, l2);
if (l1 == l2)
- return l1;
+ {
+ std::cerr << "what! in'do_union': already merged!!!" << std::endl;
+ return l1;
+ }
swap_ordering(l1, l2);
parent[l2] = l1; // The smallest label value is root.
@@ -213,12 +208,11 @@ namespace scribo
// not used directly in merge process so its tag cannot be
// updated automatically.
lines(l2).update_tag(line::Merged);
+ lines(l2).set_hidden(true);
}
else
lines(l1).fast_merge(lines(l2));
- dta[l1].finalize();
-
// l1's tag is automatically set to line::Needs_Precise_Stats_Update
// l2's tag is automatically set to line::Merged
@@ -226,6 +220,8 @@ namespace scribo
}
+
+
box2d enlarge(const box2d& b, int delta)
{
box2d b_(point2d(b.pmin().row(), b.pmin().col() - delta),
@@ -235,13 +231,34 @@ namespace scribo
template <typename L>
- void draw_enlarged_box(image2d<unsigned>& output,
- const util::array<group_data_t<L> >& dta,
- unsigned l)
+ bool between_separators(const scribo::line_info<L>& l1,
+ const scribo::line_info<L>& l2)
{
- box2d b = dta[l].ebox;
- b.crop_wrt(output.domain());
- draw_box(output, b, l);
+ unsigned
+ col1 = l1.bbox().pcenter().col(),
+ col2 = l2.bbox().pcenter().col();
+ const mln_ch_value(L, bool)&
+ separators = l1.holder().components().separators();
+
+ typedef const bool* sep_ptr_t;
+ sep_ptr_t sep_ptr, end;
+
+ if (col1 < col2)
+ {
+ sep_ptr = &separators(l1.bbox().pcenter());
+ end = sep_ptr + col2 - col1;
+ }
+ else
+ {
+ sep_ptr = &separators(l2.bbox().pcenter());
+ end = sep_ptr + col1 - col2;
+ }
+
+ // If sep_ptr is true, then a separator is reached.
+ while (!*sep_ptr && sep_ptr != end)
+ ++sep_ptr;
+
+ return *sep_ptr;
}
@@ -279,12 +296,25 @@ namespace scribo
col1 = l1.bbox().pcenter().col(),
col2 = l2.bbox().pcenter().col();
if (col1 < col2)
- return col1 + l1.bbox().width() / 4 < col2 - l2.bbox().width() / 4;
+ {
+ if ((col1 + l1.bbox().width() / 4) >= (col2 - l2.bbox().width() / 4))
+ return false;
+ }
else
- return col2 + l2.bbox().width() / 4 < col1 - l1.bbox().width() / 4;
+ if ((col2 + l2.bbox().width() / 4) >= (col1 - l1.bbox().width() / 4))
+ return false;
+
+
+ // Check that there is no separator in between.
+ if (l1.holder().components().has_separators())
+ return ! between_separators(l1, l2);
+
+ return true;
}
+
+
template <typename L>
int horizontal_distance(const scribo::line_info<L>& l1,
const scribo::line_info<L>& l2)
@@ -296,7 +326,9 @@ namespace scribo
}
- /*! \brief Check whether a non line component and a line can merge.
+
+
+ /*! \brief Check whether a non text line and a text line can merge.
Criterions:
- Small height (c.height < l.x_height)
@@ -312,24 +344,24 @@ namespace scribo
*/
template <typename L>
- bool non_line_and_line_can_merge(const scribo::line_info<L>& l_cur,
- const group_data_t<L>& dta_cur, // current
- const scribo::line_info<L>& l_ted,
- const group_data_t<L>& dta_ted) // touched
+ bool non_text_and_text_can_merge(const scribo::line_info<L>& l_cur, // current
+ const scribo::line_info<L>& l_ted) // touched
{
- if (dta_cur.looks_like_a_line || ! dta_ted.looks_like_a_line)
+ if (l_cur.type() == line::Text || l_ted.type() != line::Text)
return false;
// the current object is a NON-textline
// the background (touched) object is a textline
- // FIXME: THERE IS A BUG
- // The second condition should be replaced by the commented one.
- //
+ // Check that there is no separator in between.
+ if (l_cur.holder().components().has_separators()
+ && between_separators(l_cur, l_ted))
+ return false;
+
+
// General case (for tiny components like --> ',:."; <--):
if (l_cur.bbox().height() < l_ted.x_height()
- && float(l_cur.char_width()) / float(l_cur.card()) < l_ted.char_width())
-// && float(l_cur.bbox().width()) / float(l_cur.card()) < l_ted.char_width())
+ && float(l_cur.bbox().width()) / float(l_cur.card()) < l_ted.char_width())
return true;
@@ -339,9 +371,9 @@ namespace scribo
// // not so long width:
&& l_cur.bbox().width() < 5 * l_ted.char_width()
// align with the 'x' center:
- && std::abs((l_ted.baseline() + dta_ted.meanline) / 2 - l_cur.bbox().pcenter().row()) < 7
+ && std::abs((l_ted.baseline() + l_ted.meanline()) / 2 - l_cur.bbox().pcenter().row()) < 7
// tiny spacing:
- && horizontal_distance(l_cur, l_ted) < 5
+ && unsigned(horizontal_distance(l_cur, l_ted)) < l_ted.char_width()
)
{
return true;
@@ -350,30 +382,52 @@ namespace scribo
// Special case
-// // FIXME: Box are aligned; the main problem is that we can have multiple valid box
-// // depending on the presence of descent and/or ascent!
-// if (std::abs(dta_cur.box.pmin().row() - dta_ted.box.pmin().row()) < 5 // top
-// && std::abs(dta_cur.box.pmax().row() - dta_ted.box.pmax().row()) < 5 // bot
-// && ((dta_ted.box.pcenter().col() < dta_cur.box.pcenter().col() && dta_cur.box.pmin().col() - dta_ted.box.pmax().col() < 10) // small distance when cur is at right
-// || (dta_cur.box.pcenter().col() < dta_ted.box.pcenter().col() && dta_ted.box.pmin().col() - dta_cur.box.pmax().col() < 10)) // or when is at left.
-// )
-// return true;
-
+ // Looking for alignement.
+ def::coord
+ top_row = l_cur.bbox().pmin().row(),
+ bot_row = l_cur.bbox().pmax().row();
+
+
+// std::cout << "top_row = " << top_row << " - bot_row = " << bot_row << std::endl;
+// std::cout << std::abs(bot_row - l_ted.baseline())
+// << " - d "
+// << std::abs(bot_row - l_ted.descent())
+// << " - dd "
+// << std::abs(bot_row - l_ted.ebbox().pmax().row())
+// << " - "
+// << std::abs(top_row - l_ted.meanline())
+// << " - a "
+// << std::abs(top_row - l_ted.ascent())
+// << " - aa "
+// << std::abs(top_row - l_ted.ebbox().pmin().row())
+// << " - "
+// << l_ted.ascent()
+// << " - "
+// << l_ted.descent()
+// << std::endl;
+
+ if ((std::abs(bot_row - l_ted.baseline()) < 5
+ || std::abs(bot_row - l_ted.ebbox().pmax().row()) < 5)
+ &&
+ (std::abs(top_row - l_ted.meanline()) < 5
+ || std::abs(top_row - l_ted.ebbox().pmin().row()) < 5))
+ {
+ return true;
+ }
return false;
-
- // The unused criterion below is too restrictive; it does not work
- // for ending '-', and neither for ',' when there's no descent.
- // dta_ted.box.has(dta_cur.box.pcenter())
}
+
+
+
/*! \brief Merge text lines.
This algorithm iterates over all the components ordered by size.
It uses a 2d labeled image, tmp_box, to draw component bounding
boxes and uses that image to check bounding box collisions.
- Depending on that collisions and whether the component looks like
+ Depending on that collisions and whether the lines looks like
a text line or not, bounding boxes are merged.
\verbatim
@@ -396,22 +450,22 @@ namespace scribo
If label.card == 1
l = label.get(0);
If l != background
- If looks_like_a_line(cur)
- If looks_like_a_line(l)
+ If looks_like_a_text_line(cur)
+ If looks_like_a_text_line(l)
// Error case: a line is included in a line.
else
// Line cur is included in a frame or a drawing.
draw_enlarged_box(l)
end
else
- If looks_like_a_line(l)
+ If looks_like_a_text_line(l)
// Component cur is a punctuation overlapping with line l.
l_ <- do_union(cur, l)
draw_enlarged_box(l_)
end
end
else
- If looks_like_a_line(cur)
+ If looks_like_a_text_line(cur)
// Component cur is a new line.
draw_enlarged_box(l)
end
@@ -428,8 +482,8 @@ namespace scribo
continue
end
- If !looks_like_a_line(cur) and looks_like_a_line(l)
- If non_line_and_line_can_merge(cur, l)
+ If !looks_like_a_text_line(cur) and looks_like_a_text_line(l)
+ If non_text_and_text_can_merge(cur, l)
// A punctuation merge with a line
l_ <- do_union(cur, l)
draw_enlarged_box(l_)
@@ -449,27 +503,26 @@ namespace scribo
// Important note: after merging two lines, we draw the
// merged line over the existing one; we have to ensure that we
// cover the previous rectangle (otherwise we have a label in
- // 'output' that is not used anymore! and it can mix up the
+ // 'billboard' that is not used anymore! and it can mix up the
// detection of upcoming merges...) so this delta has to remain
// the same during one pass. Another solution (yet more costly)
// could be of erasing the previous rectangle before re-drawing...
//
template <typename L>
- image2d<unsigned>
+ void
one_merge_pass(unsigned ith_pass,
const box2d& domain,
std::vector<scribo::line_id_t>& v,
scribo::line_set<L>& lines,
- util::array<group_data_t<L> >& dta,
util::array<unsigned>& parent)
{
- image2d<unsigned> output(domain);
- data::fill(output, 0);
+ image2d<unsigned> billboard(domain);
+ data::fill(billboard, 0);
image2d<value::int_u8> log(domain);
data::fill(log, 0);
- const unsigned n = dta.nelements() - 1;
+ const unsigned n = v.size();
unsigned l_;
unsigned
@@ -493,11 +546,7 @@ namespace scribo
unsigned tl, tr, ml, mc, mr, bl, br;
{
- box2d b_;
-
- b_ = enlarge(lines(l).bbox(), dta[l].delta);
- b_.crop_wrt(output.domain());
-
+ box2d b_ = lines(l).ebbox();
/*
tl tr
@@ -513,13 +562,13 @@ namespace scribo
*/
- tl = output(b_.pmin());
- tr = output.at_(b_.pmin().row(), b_.pmax().col());
- ml = output.at_(b_.pcenter().row(), b_.pmin().col());
- mc = output.at_(b_.pcenter().row(), b_.pcenter().col());
- mr = output.at_(b_.pcenter().row(), b_.pmax().col());
- bl = output.at_(b_.pmax().row(), b_.pmin().col());
- br = output(b_.pmax());
+ tl = billboard(b_.pmin());
+ tr = billboard.at_(b_.pmin().row(), b_.pmax().col());
+ ml = billboard.at_(b_.pcenter().row(), b_.pmin().col());
+ mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col());
+ mr = billboard.at_(b_.pcenter().row(), b_.pmax().col());
+ bl = billboard.at_(b_.pmax().row(), b_.pmin().col());
+ br = billboard(b_.pmax());
}
typedef std::set<unsigned> set_t;
@@ -534,56 +583,103 @@ namespace scribo
labels.insert(br);
- if (labels.size() == 1) // Same behavior for all ancors.
+ for (set_t::const_iterator it = labels.begin();
+ it != labels.end();
+ ++it)
+ {
+ if (*it == 0)
+ continue;
+
+ if (lines(*it).type() != line::Text)
+ std::cerr << "outch: we have hit, so drawn, a non-text..." << std::endl;
+ }
+
+
+ if (labels.size() == 1) // Same behavior for all anchors.
{
if (mc != 0)
{
// Main case: it is an "included" box (falling in an already drawn box)
- if (dta[l].looks_like_a_line)
+ if (lines(l).type() == line::Text) // the current object IS a text line
{
- if (dta[mc].looks_like_a_line)
+ if (lines(mc).type() == line::Text) // included in a text line => weird
{
++count_txtline_IN_txtline;
std::cout << "weird: inclusion of a txt_line in a txt_line!" << std::endl;
+
+ /// Merge is perform if the current line is a
+ /// petouille considered as a line.
+// if ((std::abs(lines(l).ascent() - lines(mc).ascent()) >= 5)
+// || (std::abs(lines(l).descent() - lines(mc).descent()) >= 5))
+// continue;
+
+// // FIXME: Is it valid?
+// // A text line is included in another text line.
+// // They are merged.
+// //
+// l_ = do_union(lines, mc, l, parent);
+// draw_box(billboard, lines(l_).ebbox(), l_);
+
+ // Log:
+ draw_box(log, b, 126);
+
}
- else
+
+ else // FIXME: Remove! since included in a non-text-line, so not drawn, so inclusion impossible!!!!!!!!!!
{
+ std::cout << "error: should NOT happen (a text line included in a NON-text-line (so not drawn!!!)" << std::endl;
++count_txtline_IN_junk;
- // a non-line (probably a drawing or a frame) includes a line
- draw_enlarged_box(output, dta, l);
+ // a non-text-line (probably a drawing or a frame) includes a text line
+ draw_box(billboard, lines(l).ebbox(), l);
// Log:
draw_box(log, b, 100);
}
+
}
- else // the current object is NOT a line
+ else // the current object is NOT a text line
{
- if (dta[mc].looks_like_a_line)
+ if (lines(mc).type() == line::Text) // included in a text line
{
++count_comp_IN_txtline;
- // FIXME: critere petouille a ajouter ici
- // Merge non-line #l into line #mc.
- l_ = do_union(dta, lines, mc, l, parent);
- // We have to re-draw the original largest line since
+ // The current object is supposed to be punctuation
+ // since it is fully included in the bbox of a line
+ // of text, so we always want to merge this object
+ // with the line.
+ //
+ // However, in case of a bad quality document, we
+ // may not always want to merge since this object
+ // could be noise or garbage... So adding new
+ // criterions could fix this issue.
+ //
+ //if (!non_text_and_text_can_merge(lines(l), lines(mc)))
+ // continue;
+
+ // Mark current line as punctuation.
+ lines(l).update_type(line::Punctuation);
+
+ // Merge non-text-line #l into text line #mc.
+ l_ = do_union(lines, mc, l, parent);
+ // We have to re-draw the original largest text line since
// it may change of label (take the one of the included line).
- draw_enlarged_box(output, dta, l_);
+ draw_box(billboard, lines(l_).ebbox(), l_);
// Log:
draw_box(log, b, 128);
}
}
}
- else
+ else // mc == 0
{
// Main case: it is a "new" box, that might be drawn in the background.
// we only draw this box if it is a text-line!!!
- if (dta[l].looks_like_a_line)
+ if (lines(l).type() == line::Text)
{
++count_new_txtline;
- draw_enlarged_box(output, dta, l);
+ draw_box(billboard, lines(l).ebbox(), l);
// Log:
draw_box(log, b, 127);
}
@@ -593,6 +689,8 @@ namespace scribo
}
else
{
+ l_ = l; // current label.
+
// Particular cases.
for (set_t::const_iterator it = labels.begin();
it != labels.end();
@@ -603,26 +701,44 @@ namespace scribo
if (lcand == 0) // Skip background.
continue;
- if (lines_can_merge(lines(l), lines(lcand)))
+ if (lines(lcand).type() != line::Text)
+ std::cerr << "again!" << std::endl;
+
+
+ if (lines(l_).type() == line::Text)
{
- ++count_two_lines_merge;
- l_ = do_union(dta, lines, l, lcand, parent);
- draw_enlarged_box(output, dta, l_);
- // Log:
- draw_box(log, b, 151);
- continue;
- }
+ // l_ and lcand look like text line chunks.
+ if (lines_can_merge(lines(l_), lines(lcand)))
+ {
+ ++count_two_lines_merge;
+ l_ = do_union(lines, l_, lcand, parent);
+ draw_box(billboard, lines(l_).ebbox(), l_);
+ // Log:
+ draw_box(log, b, 151);
+ continue;
+ }
+ else
+ {
+ ++count_WTF;
+ // Log:
+ draw_box(log, b, 255);
- if (! dta[l].looks_like_a_line && dta[lcand].looks_like_a_line)
+ // (*) SEE BELOW
+ draw_box(billboard, lines(l_).ebbox(), l_);
+ }
+ }
+ else
{
+ // l_ does NOT looks like a text line chunk.
++count_comp_HITS_txtline;
- if (non_line_and_line_can_merge(lines(l), dta[l], lines(lcand), dta[lcand]))
+ if (non_text_and_text_can_merge(lines(l_), lines(lcand)))
// a petouille merges with a text line?
{
++count_comp_HITS_txtline;
- l_ = do_union(dta, lines, l, lcand, parent);
- draw_enlarged_box(output, dta, l_);
+ l_ = do_union(lines, l_, lcand, parent);
+ draw_box(billboard, lines(l_).ebbox(), l_);
+
// Log:
draw_box(log, b, 169);
continue;
@@ -633,12 +749,39 @@ namespace scribo
draw_box(log, b, 254);
}
}
- else
- {
- ++count_WTF;
- // Log:
- draw_box(log, b, 255);
- }
+
+
+ /* (*) Text lines verticaly overlap.
+
+ --------------------------
+ | l |
+ | |
+ --------------------------
+ | lcand |
+ | |
+ --------------------------
+
+ or
+
+ --------------------------
+ | l |
+ | |
+ |---------------------------
+ |------------------------- |
+ | lcand |
+ ----------------------------
+
+ or
+
+ --------------------------
+ | lcand |
+ | |
+ |---------------------------
+ |------------------------- |
+ | l |
+ ----------------------------
+
+ */
}
}
@@ -657,28 +800,26 @@ namespace scribo
(void) ith_pass;
-// if (ith_pass == 1)
-// {
-// mln::io::pgm::save(log, "log_1.pgm");
-// mln::io::pgm::save(data::wrap(int_u8(), output), "log_1e.pgm");
-// }
-// else if (ith_pass == 2)
-// {
-// mln::io::pgm::save(log, "log_2.pgm");
-// mln::io::pgm::save(data::wrap(int_u8(), output), "log_2e.pgm");
-// }
-// else if (ith_pass == 3)
-// {
-// mln::io::pgm::save(log, "log_3.pgm");
-// mln::io::pgm::save(data::wrap(int_u8(), output), "log_3e.pgm");
-// }
-
- return output;
-
+ if (ith_pass == 1)
+ {
+ mln::io::pgm::save(log, "log_1.pgm");
+ mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_1e.pgm");
+ }
+ else if (ith_pass == 2)
+ {
+ mln::io::pgm::save(log, "log_2.pgm");
+ mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_2e.pgm");
+ }
+ else if (ith_pass == 3)
+ {
+ mln::io::pgm::save(log, "log_3.pgm");
+ mln::io::pgm::save(data::wrap(int_u8(), billboard), "log_3e.pgm");
+ }
}
+
template <typename L>
struct order_lines_id
{
@@ -698,7 +839,6 @@ namespace scribo
};
-
template <typename L>
scribo::line_set<L>
draw_boxes(const box2d& input_domain,
@@ -725,37 +865,37 @@ namespace scribo
// Sort lines by bbox.nelements() and ids.
std::sort(v.begin(), v.end(), func);
- image2d<unsigned> canvas;
util::timer t;
- // Caching line temporary data.
- util::array<group_data_t<L> >
- dta;
- dta.reserve(unsigned(lines.nelements()) + 1);
- dta.append(group_data_t<L>());
+ // Setting lines as text lines according to specific criterions.
for_all_lines(l, lines)
- dta.append(group_data_t<L>(lines(l)));
+ if (looks_like_a_text_line(lines(l)))
+ lines(l).update_type(line::Text);
+
// First pass
t.start();
- one_merge_pass(1, input_domain, v, lines, dta, parent);
+ one_merge_pass(1, input_domain, v, lines, parent);
float ts = t.stop();
std::cout << "time " << ts << std::endl;
+
+// lines.force_stats_update();
+
+ // Sort lines by bbox.nelements() and ids again!
+ // line may have grown differently since the first pass.
+ std::sort(v.begin(), v.end(), func);
+
+
// Second pass
t.start();
- canvas = one_merge_pass(2, input_domain, v, lines, dta, parent); // <- last pass
+ one_merge_pass(2, input_domain, v, lines, parent); // <- last pass
ts = t.stop();
std::cout << "time " << ts << std::endl;
-// using value::int_u8;
- //io::pgm::save(data::wrap(int_u8(), canvas), "merge_result.pgm");
-
-// mln::io::ppm::save(labeling::colorize(value::rgb8(), canvas),
-// "merge_result.ppm");
-
+ lines.force_stats_update();
return lines;
}
@@ -768,22 +908,26 @@ namespace scribo
template <typename L>
line_set<L>
- merging(const box2d& input_domain,
- const scribo::line_set<L>& lines)
+ merging(const scribo::line_set<L>& lines)
{
using namespace mln;
util::timer t;
t.start();
- scribo::line_set<L> output = internal::draw_boxes(input_domain, lines);
+ scribo::line_set<L> output
+ = internal::draw_boxes(lines.components().labeled_image().domain(),
+ lines);
float ts = t.stop();
std::cout << ts << std::endl;
return output;
}
+# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::text
} // end of namespace scribo
+
+#endif // ! SCRIBO_TEXT_MERGING_HH
--
1.5.6.5
1
0
11 Mar '10
* primitive/internal/rd.hh: New.
---
scribo/ChangeLog | 6 +
scribo/primitive/internal/rd.hh | 192 +++++++++++++++++++++++++++++++++++++++
2 files changed, 198 insertions(+), 0 deletions(-)
create mode 100644 scribo/primitive/internal/rd.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 97eb271..f0f0ec3 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,11 @@
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a reconstruction algorithm.
+
+ * primitive/internal/rd.hh: New.
+
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Small fixes.
* binarization/sauvola_ms.hh: Add a missing include.
diff --git a/scribo/primitive/internal/rd.hh b/scribo/primitive/internal/rd.hh
new file mode 100644
index 0000000..7b8f069
--- /dev/null
+++ b/scribo/primitive/internal/rd.hh
@@ -0,0 +1,192 @@
+// Copyright (C) 2010 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_PRIMITIVE_INTERNAL_RD_HH
+# define SCRIBO_PRIMITIVE_INTERNAL_RD_HH
+
+/// \file
+///
+/// \brief Tolerant constrained reconstruction algorithm.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/border/equalize.hh>
+#include <mln/border/fill.hh>
+
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/util/timer.hh>
+
+
+namespace scribo
+{
+
+ namespace primitive
+ {
+
+ namespace internal
+ {
+
+ using namespace mln;
+
+ /// \brief Tolerant constrained reconstruction algorithm.
+ template <typename I, typename J>
+ mln_concrete(I)
+ rd(const Image<I>& ima, const Image<J>& constraint);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename Par>
+ inline
+ unsigned
+ Rd_find_root_(Par& parent, unsigned x)
+ {
+ if (parent.element(x) == x)
+ return x;
+ else
+ return parent.element(x) = Rd_find_root_(parent, parent.element(x));
+ }
+
+ template <typename I, typename J, typename N>
+ inline
+ mln_concrete(I)
+ Rd(const Image<I>& f_, const Image<J>& g_, const Neighborhood<N>& nbh_)
+ {
+ trace::entering("Rd");
+
+ const I& f = exact(f_);
+ const J& g = exact(g_);
+ const N& nbh = exact(nbh_);
+
+ typedef mln_psite(I) P;
+ typedef mln_value(I) V;
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, unsigned) parent;
+ mln_concrete(I) output;
+
+ // Initialization.
+ {
+ border::equalize(f, g, nbh.delta());
+ mln::border::fill(g, false);
+
+ initialize(output, f);
+ mln::data::fill(output, false);
+
+ initialize(parent, f);
+ }
+
+ util::array<int> dp = negative_offsets_wrt(f, nbh);
+ const unsigned n_nbhs = dp.nelements();
+
+ // First pass.
+ {
+ mln_fwd_pixter(const I) pxl_g(g);
+ for_all(pxl_g)
+ {
+ if (pxl_g.val() == false)
+ continue;
+
+ unsigned p = pxl_g.offset();
+
+ // Make-Set.
+ parent.element(p) = p;
+ // Init.
+ output.element(p) = f.element(p);
+
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (g.element(n) == true)
+ {
+ mln_invariant(f.domain().has(f.point_at_index(n)));
+ // Do-Union.
+ unsigned r = Rd_find_root_(parent, n);
+ if (r != p)
+ {
+ // Set-Parent:
+ parent.element(r) = p;
+ // Merge:
+ output.element(p) = output.element(p) || output.element(r);
+ }
+ }
+ }
+ }
+ }
+
+ // Second pass.
+ {
+ mln_bkd_pixter(const I) pxl_g(g);
+ for_all(pxl_g)
+ {
+ if (pxl_g.val() == false)
+ continue;
+ unsigned p = pxl_g.offset();
+ output.element(p) = output.element(parent.element(p));
+ }
+ }
+
+ trace::exiting("Rd");
+ return output;
+ }
+
+
+
+
+ template <typename I, typename J>
+ mln_concrete(I)
+ rd(const Image<I>& ima, const Image<J>& constraint)
+ {
+ trace::entering("scribo::primitive::internal::rd");
+
+ mln_precondition(exact(ima).is_valid());
+ mln_precondition(exact(constraint).is_valid());
+
+ using namespace mln;
+
+ // FIXME: not generic.
+ neighb2d nbh = c4();
+
+ mln_concrete(I) output = Rd(ima, constraint, nbh);
+
+ trace::exiting("scribo::primitive::internal::rd");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::primitive::internal
+
+ } // end of namespace scribo::primitive
+
+} // end of namespace scribo
+
+
+
+
+#endif // ! SCRIBO_PRIMITIVE_INTERNAL_RD_HH
--
1.5.6.5
1
0
* binarization/sauvola_ms.hh: Add a missing include.
* binarization/sauvola_threshold.hh: Remove debug and useless
comments.
* preprocessing/unskew.hh: Fix invalid guards.
* primitive/extract/components.hh: Fill image extension.
* primitive/extract/lines_pattern.hh: Adjust and fill image
extension.
* primitive/extract/lines_v_thick.hh: Fix traces.
---
scribo/ChangeLog | 18 ++++++++++++++
scribo/binarization/sauvola_ms.hh | 4 +++
scribo/binarization/sauvola_threshold.hh | 37 ++++++----------------------
scribo/preprocessing/unskew.hh | 6 ++--
scribo/primitive/extract/components.hh | 7 ++++-
scribo/primitive/extract/lines_pattern.hh | 23 +++++++++++-------
scribo/primitive/extract/lines_v_thick.hh | 4 +-
7 files changed, 55 insertions(+), 44 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 8b4c4d7..97eb271 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,23 @@
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Small fixes.
+
+ * binarization/sauvola_ms.hh: Add a missing include.
+
+ * binarization/sauvola_threshold.hh: Remove debug and useless
+ comments.
+
+ * preprocessing/unskew.hh: Fix invalid guards.
+
+ * primitive/extract/components.hh: Fill image extension.
+
+ * primitive/extract/lines_pattern.hh: Adjust and fill image
+ extension.
+
+ * primitive/extract/lines_v_thick.hh: Fix traces.
+
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new preprocessing routines.
* preprocessing/denoise.hh,
diff --git a/scribo/binarization/sauvola_ms.hh b/scribo/binarization/sauvola_ms.hh
index 858a1d3..7bbd9f8 100644
--- a/scribo/binarization/sauvola_ms.hh
+++ b/scribo/binarization/sauvola_ms.hh
@@ -40,6 +40,8 @@
# include <mln/core/box_runend_piter.hh>
+# include <mln/util/couple.hh>
+
# include <scribo/subsampling/integral_single_image.hh>
# include <scribo/core/macros.hh>
@@ -63,6 +65,8 @@ namespace scribo
namespace internal
{
+ using namespace mln;
+
template <typename V>
V my_find_root(image2d<V>& parent, const V& x)
{
diff --git a/scribo/binarization/sauvola_threshold.hh b/scribo/binarization/sauvola_threshold.hh
index 01bd1b0..940b7cd 100644
--- a/scribo/binarization/sauvola_threshold.hh
+++ b/scribo/binarization/sauvola_threshold.hh
@@ -46,6 +46,8 @@
# include <mln/fun/v2v/rgb_to_int_u.hh>
+# include <mln/debug/println.hh>
+
# include <scribo/core/init_integral_image.hh>
namespace scribo
@@ -187,38 +189,9 @@ namespace scribo
double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
-
-// if (p == point2d(3,3))// || p == point2d(4,4) || p == point2d(1,1))
-// {
-// // std::cout << "p" << p << " - A(" << row_min << ", " << col_min
-// // << ") = " << simple.at_(row_min, col_min)
-
-// << " - B(" << row_min << ", " << col_max
-// << ") = " << simple.at_(row_min, col_max)
-
-// << " - C(" << row_max << ", " << col_min
-// << ") = " << simple.at_(row_max, col_min)
-
-// << " - D(" << row_max << ", " << col_max
-// << ") = " << simple.at_(row_max, col_max)
-// << " - n = " << wh
-// << std::endl;
-
-// << std::endl;
-// }
-
// Thresholding.
double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, k, R);
-
-// std::cout << p
-// << " - m = " << m_x_y
-// << " - s = " << s_x_y
-// << " - t = " << t_x_y
-// << " - sum = " << m_x_y_tmp
-// << " - sum_2 = " << s_x_y_tmp
-// << std::endl;
-
return t_x_y;
}
@@ -487,6 +460,12 @@ namespace scribo
simple = init_integral_image(input, scribo::internal::identity_),
squared = init_integral_image(input, scribo::internal::square_);
+// debug::println(input);
+// std::cout << "============" << std::endl;
+// // debug::println(simple);
+// // std::cout << "============" << std::endl;
+// // debug::println(squared);
+
return sauvola_threshold(input, window_size, simple, squared);
}
diff --git a/scribo/preprocessing/unskew.hh b/scribo/preprocessing/unskew.hh
index 3b90d8a..a01cae3 100644
--- a/scribo/preprocessing/unskew.hh
+++ b/scribo/preprocessing/unskew.hh
@@ -23,8 +23,8 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_UNSKEW_HOUGH_HH
-# define SCRIBO_UNSKEW_HOUGH_HH
+#ifndef SCRIBO_PREPROCESSING_UNSKEW_HH
+# define SCRIBO_PREPROCESSING_UNSKEW_HH
/// \file
///
@@ -112,4 +112,4 @@ namespace scribo
} // end of namespace mln
-# endif // SCRIBO_UNSKEW_HOUGH_HH
+# endif // SCRIBO_PREPROCESSING_UNSKEW_HH
diff --git a/scribo/primitive/extract/components.hh b/scribo/primitive/extract/components.hh
index f13904f..3363331 100644
--- a/scribo/primitive/extract/components.hh
+++ b/scribo/primitive/extract/components.hh
@@ -43,6 +43,8 @@
# include <mln/util/array.hh>
+# include <mln/extension/fill.hh>
+
# include <scribo/core/component_set.hh>
@@ -88,7 +90,7 @@ namespace scribo
const Neighborhood<N>& nbh, V& ncomponents)
{
mlc_equal(mln_value(I),bool)::check();
- mlc_is_a(V, mln::value::Symbolic)::check();
+// mlc_is_a(V, mln::value::Symbolic)::check();
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
(void) input;
@@ -115,6 +117,9 @@ namespace scribo
typedef mln::accu::center<mln_site(L)> center_accu_t;
typedef mln::accu::pair<bbox_accu_t, center_accu_t> pair_accu_t;
+ // Setting extension value.
+ extension::fill(input, 0);
+
util::couple<L,
util::couple<util::array<mln_result(pair_accu_t)>,
util::array<pair_accu_t> > >
diff --git a/scribo/primitive/extract/lines_pattern.hh b/scribo/primitive/extract/lines_pattern.hh
index 57958ec..18cb784 100644
--- a/scribo/primitive/extract/lines_pattern.hh
+++ b/scribo/primitive/extract/lines_pattern.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -36,6 +37,8 @@
# include <mln/core/alias/window2d.hh>
# include <mln/core/routine/duplicate.hh>
+# include <mln/extension/adjust_fill.hh>
+
# include <mln/accu/transform_line.hh>
# include <mln/accu/count_value.hh>
@@ -77,13 +80,16 @@ namespace scribo
lines_pattern(const Image<I>& input_, unsigned length,
unsigned dir, const Window<W>& win_)
{
- trace::entering("mln::lines_pattern");
+ trace::entering("scribo::primitive::extract::lines_pattern");
const I& input = exact(input_);
const W& win = exact(win_);
mlc_is(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
+ // Adjusting extension.
+ extension::adjust_fill(input, length / 2, 0);
+
accu::count_value<bool> accu(true);
mln_ch_value(I,unsigned)
tmp = accu::transform_line(accu, input, length, dir);
@@ -100,18 +106,18 @@ namespace scribo
// If the foreground part of the pattern has more than 20%
// of background pixels, the current pixel is considered as
// background pixel.
- if (length - tmp(p) > (0.2f * length))
+ if (length - tmp(p) > unsigned(0.2f * length) + 1)
{
output(p) = false;
continue;
}
- // If the background parts of the pattern have less than 95%
- // of foreground pixels, the current pixel is considered as
- // part of the background.
+ // If the background parts of the pattern have exactly or
+ // less than 95% of background pixels, the current pixel is
+ // considered as part of the background.
is_foreground = true;
for_all(q)
- if ((length - tmp(q)) < (length * 0.95f))
+ if ((length - tmp(q)) < unsigned(length * 0.95f) + 1)
{
is_foreground = false;
break;
@@ -120,8 +126,7 @@ namespace scribo
output(p) = is_foreground;
}
-
- trace::exiting("mln::lines_pattern");
+ trace::exiting("scribo::primitive::extract::lines_pattern");
return output;
}
diff --git a/scribo/primitive/extract/lines_v_thick.hh b/scribo/primitive/extract/lines_v_thick.hh
index e1cecee..2ee09dd 100644
--- a/scribo/primitive/extract/lines_v_thick.hh
+++ b/scribo/primitive/extract/lines_v_thick.hh
@@ -104,7 +104,7 @@ namespace scribo
const Neighborhood<N>& nbh, V& nlines,
unsigned line_length)
{
- trace::entering("scribo::primitive::lines_v_thick");
+ trace::entering("scribo::primitive::extract::lines_v_thick");
internal::lines_v_thick_tests(input, nbh, nlines,
line_length);
@@ -114,7 +114,7 @@ namespace scribo
object_image(mln_ch_value(I,V))
output = lines_thick(input, nbh, nlines, win);
- trace::exiting("scribo::primitive::lines_v_thick");
+ trace::exiting("scribo::primitive::extract::lines_v_thick");
return output;
}
--
1.5.6.5
1
0
last-svn-commit-57-ga8aeee1 Update code according to last changes in Scribo core classes.
by Guillaume Lazzara 11 Mar '10
by Guillaume Lazzara 11 Mar '10
11 Mar '10
* draw/bounding_box_links.hh,
* primitive/internal/init_link_array.hh,
* primitive/internal/is_link_valid.hh,
* primitive/link/internal/link_single_dmax_base.hh,
* src/afp/link.hh: Update the use of object_link class.
* draw/bounding_boxes.hh,
* filter/objects_with_holes.hh,
* src/afp/regroup.hh: Update for_all macro.
* estim/object_groups_v_thickness.hh,
* filter/object_groups_small.hh,
* filter/object_groups_v_thickness.hh,
* text/recognition.hh: Update access to component_set.
* filter/object_links_bbox_h_ratio.hh,
* filter/object_links_bbox_overlap.hh,
* filter/object_links_bbox_ratio.hh,
* filter/object_links_bottom_aligned.hh,
* filter/object_links_non_aligned_simple.hh,
* filter/object_links_top_aligned.hh,
* primitive/group/apply.hh,
* primitive/group/from_single_link.hh,
* primitive/link/merge_double_link.hh,
* primitive/link/with_single_right_link_bottom.hh,
* primitive/link/with_single_right_link_dmax_ratio.hh,
* primitive/link/with_single_right_link_top.hh: Improve routine
prototypes.
* primitive/link/internal/link_functor_base.hh: Make use of
separators if exist.
---
scribo/ChangeLog | 36 ++++++++++++
scribo/draw/bounding_box_links.hh | 20 +++---
scribo/draw/bounding_boxes.hh | 2 +-
scribo/estim/object_groups_v_thickness.hh | 2 +-
scribo/filter/object_groups_small.hh | 2 +-
scribo/filter/object_groups_v_thickness.hh | 2 +-
scribo/filter/object_links_bbox_h_ratio.hh | 10 +--
scribo/filter/object_links_bbox_overlap.hh | 18 ++----
scribo/filter/object_links_bbox_ratio.hh | 14 ++---
scribo/filter/object_links_bottom_aligned.hh | 12 +---
scribo/filter/object_links_non_aligned_simple.hh | 60 ++++++++++----------
scribo/filter/object_links_top_aligned.hh | 13 +---
scribo/filter/objects_with_holes.hh | 4 +-
scribo/primitive/group/apply.hh | 33 ++++-------
scribo/primitive/group/from_single_link.hh | 27 ++++-----
scribo/primitive/internal/init_link_array.hh | 6 +-
scribo/primitive/internal/is_link_valid.hh | 14 +++--
.../primitive/link/internal/link_functor_base.hh | 19 +++++--
.../link/internal/link_single_dmax_base.hh | 4 +-
scribo/primitive/link/merge_double_link.hh | 19 +++----
.../link/with_single_right_link_bottom.hh | 28 +++++-----
.../link/with_single_right_link_dmax_ratio.hh | 30 +++++++++-
.../primitive/link/with_single_right_link_top.hh | 17 +++---
scribo/src/afp/link.hh | 12 ++--
scribo/src/afp/regroup.hh | 2 +-
scribo/text/recognition.hh | 2 +-
26 files changed, 218 insertions(+), 190 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 54d5f0d..74cef68 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,41 @@
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Update code according to last changes in Scribo core classes.
+
+ * draw/bounding_box_links.hh,
+ * primitive/internal/init_link_array.hh,
+ * primitive/internal/is_link_valid.hh,
+ * primitive/link/internal/link_single_dmax_base.hh,
+ * src/afp/link.hh: Update the use of object_link class.
+
+ * draw/bounding_boxes.hh,
+ * filter/objects_with_holes.hh,
+ * src/afp/regroup.hh: Update for_all macro.
+
+ * estim/object_groups_v_thickness.hh,
+ * filter/object_groups_small.hh,
+ * filter/object_groups_v_thickness.hh,
+ * text/recognition.hh: Update access to component_set.
+
+ * filter/object_links_bbox_h_ratio.hh,
+ * filter/object_links_bbox_overlap.hh,
+ * filter/object_links_bbox_ratio.hh,
+ * filter/object_links_bottom_aligned.hh,
+ * filter/object_links_non_aligned_simple.hh,
+ * filter/object_links_top_aligned.hh,
+ * primitive/group/apply.hh,
+ * primitive/group/from_single_link.hh,
+ * primitive/link/merge_double_link.hh,
+ * primitive/link/with_single_right_link_bottom.hh,
+ * primitive/link/with_single_right_link_dmax_ratio.hh,
+ * primitive/link/with_single_right_link_top.hh: Improve routine
+ prototypes.
+
+ * primitive/link/internal/link_functor_base.hh: Make use of
+ separators if exist.
+
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Improve debug routines in Scribo.
* debug/bboxes_enlarged_image.hh,
diff --git a/scribo/draw/bounding_box_links.hh b/scribo/draw/bounding_box_links.hh
index b2c425a..2ee5173 100644
--- a/scribo/draw/bounding_box_links.hh
+++ b/scribo/draw/bounding_box_links.hh
@@ -245,13 +245,13 @@ namespace scribo
mln_precondition(input.is_valid());
- const component_set<L>& comp_set = links.component_set_();
- for_all_components(i, links)
- if (links[i] != i && links[i] != 0)
+ const component_set<L>& comp_set = links.components();
+ for_all_links(i, links)
+ if (links(i) != i && links(i) != 0)
{
mln_site(L)
p1 = primitive::link::internal::compute_anchor(comp_set, i, anchor),
- p2 = primitive::link::internal::compute_anchor(comp_set, links[i], anchor);
+ p2 = primitive::link::internal::compute_anchor(comp_set, links(i), anchor);
mln::draw::line(input, p1, p2, value);
}
@@ -293,19 +293,19 @@ namespace scribo
dleft[0] = 2;
mln_dpsite(P) dright = literal::zero;
dright[0] = -2;
- for_all_components(i, left_link)
+ for_all_links(i, left_link)
{
mln::draw::line(input,
internal::shift_site(input, mass_centers[i], dleft),
internal::shift_site(input,
- mass_centers[left_link[i]],
+ mass_centers[left_link(i)],
dleft),
left_link_value);
mln::draw::line(input,
internal::shift_site(input, mass_centers[i], dright),
internal::shift_site(input,
- mass_centers[right_link[i]],
+ mass_centers[right_link(i)],
dright),
right_link_value);
@@ -347,16 +347,16 @@ namespace scribo
dleft[0] = 2;
mln_site(I)::vec dright = literal::origin;
dright[0] = -2;
- for_all_components(i, left_link)
+ for_all_links(i, left_link)
{
mln::draw::line(input,
bboxes[i].center() + dleft,
- bboxes[left_link[i]].center() + dleft,
+ bboxes[left_link(i)].center() + dleft,
left_link_value);
mln::draw::line(input,
bboxes[i].center() + dright,
- bboxes[right_link[i]].center() + dright,
+ bboxes[right_link(i)].center() + dright,
right_link_value);
mln::util::couple<bool, unsigned>
diff --git a/scribo/draw/bounding_boxes.hh b/scribo/draw/bounding_boxes.hh
index 3dce077..93f4067 100644
--- a/scribo/draw/bounding_boxes.hh
+++ b/scribo/draw/bounding_boxes.hh
@@ -77,7 +77,7 @@ namespace scribo
mln_precondition(input.is_valid());
- for_all_components(i, boxes)
+ for_all_comp_data(i, boxes)
if (boxes[i].is_valid())
mln::draw::box(input, boxes[i], value);
diff --git a/scribo/estim/object_groups_v_thickness.hh b/scribo/estim/object_groups_v_thickness.hh
index 6d74f2c..b626243 100644
--- a/scribo/estim/object_groups_v_thickness.hh
+++ b/scribo/estim/object_groups_v_thickness.hh
@@ -69,7 +69,7 @@ namespace scribo
mln_precondition(groups.is_valid());
- const component_set<L>& components = groups.component_set_();
+ const component_set<L>& components = groups.components();
//FIXME: remove when object_groups will store the number of
//elements per group.
diff --git a/scribo/filter/object_groups_small.hh b/scribo/filter/object_groups_small.hh
index b2662c0..60f8753 100644
--- a/scribo/filter/object_groups_small.hh
+++ b/scribo/filter/object_groups_small.hh
@@ -81,7 +81,7 @@ namespace scribo
output(0) = 0;
for_all_groups(i, output)
if (group_size[groups(i)] < n_links
- || !groups.component_set_()(i).is_valid())
+ || !groups.components()(i).is_valid())
output(i) = 0;
trace::exiting("scribo::filter::object_groups_small");
diff --git a/scribo/filter/object_groups_v_thickness.hh b/scribo/filter/object_groups_v_thickness.hh
index a4c5277..caac765 100644
--- a/scribo/filter/object_groups_v_thickness.hh
+++ b/scribo/filter/object_groups_v_thickness.hh
@@ -78,7 +78,7 @@ namespace scribo
object_groups<L> output(groups);
output(0) = 0;
for (unsigned i = 1; i < output.nelements(); ++i)
- if (groups.component_set_()(i).is_valid()
+ if (groups.components()(i).is_valid()
&& group_thickness[groups(i)] < thickness)
output(i) = 0;
diff --git a/scribo/filter/object_links_bbox_h_ratio.hh b/scribo/filter/object_links_bbox_h_ratio.hh
index 261fbcb..5573f16 100644
--- a/scribo/filter/object_links_bbox_h_ratio.hh
+++ b/scribo/filter/object_links_bbox_h_ratio.hh
@@ -52,7 +52,6 @@ namespace scribo
/*! \brief Invalidate links between two components with too different
height.
- \param[in] components A component set.
\param[in] links Link objects information.
\param[in] max_h_ratio The maximum height ratio of two linked
bounding boxes.
@@ -61,8 +60,7 @@ namespace scribo
*/
template <typename L>
object_links<L>
- object_links_bbox_h_ratio(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bbox_h_ratio(const object_links<L>& links,
float max_h_ratio);
@@ -71,17 +69,15 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_bbox_h_ratio(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bbox_h_ratio(const object_links<L>& links,
float max_h_ratio)
{
trace::entering("scribo::filter::object_links_bbox_h_ratio");
- mln_precondition(components.is_valid());
mln_precondition(links.is_valid());
object_links<L>
- output = object_links_bbox_ratio(components, links, 0, max_h_ratio);
+ output = object_links_bbox_ratio(links, 0, max_h_ratio);
trace::exiting("scribo::filter::object_links_bbox_h_ratio");
return output;
diff --git a/scribo/filter/object_links_bbox_overlap.hh b/scribo/filter/object_links_bbox_overlap.hh
index d2d9376..ffcbb6c 100644
--- a/scribo/filter/object_links_bbox_overlap.hh
+++ b/scribo/filter/object_links_bbox_overlap.hh
@@ -53,7 +53,6 @@ namespace scribo
/*! \brief Invalidate links between two components having their bounding box
overlapping too much.
- \param[in] components A component set.
\param[in] links Link components information.
\param[in] max_overlap_ratio The maximum ratio of the overlapping
areas.
@@ -62,8 +61,7 @@ namespace scribo
*/
template <typename L>
object_links<L>
- object_links_bbox_overlap(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bbox_overlap(const object_links<L>& links,
float max_overlap_ratio);
@@ -72,19 +70,17 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_bbox_overlap(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bbox_overlap(const object_links<L>& links,
float max_overlap_ratio)
{
trace::entering("scribo::filter::object_links_bbox_overlap");
- mln_precondition(components.is_valid());
mln_precondition(links.is_valid());
- mln_precondition(components.id_() == links.components_id_());
+ const component_set<L>& components = links.components();
object_links<L> output(links);
- for_all_components(i, components)
+ for_all_comps(i, components)
if (components(i).is_valid() && links(i) != i)
{
bool has_intersection = true;
@@ -92,9 +88,9 @@ namespace scribo
for (unsigned dim = 0; dim < mln_site_(L)::dim; ++dim)
{
pmin[dim] = math::max(components(i).bbox().pmin()[dim],
- components(links[i]).bbox().pmin()[dim]);
+ components(links(i)).bbox().pmin()[dim]);
pmax[dim] = math::min(components(i).bbox().pmax()[dim],
- components(links[i]).bbox().pmax()[dim]);
+ components(links(i)).bbox().pmax()[dim]);
if (pmin[dim] > pmax[dim])
{
@@ -113,7 +109,7 @@ namespace scribo
if (ratio_i >= max_overlap_ratio
|| ratio_link_i >= max_overlap_ratio)
- output[i] = i;
+ output(i) = i;
}
trace::exiting("scribo::filter::object_links_bbox_overlap");
diff --git a/scribo/filter/object_links_bbox_ratio.hh b/scribo/filter/object_links_bbox_ratio.hh
index bc5523c..d1c01dd 100644
--- a/scribo/filter/object_links_bbox_ratio.hh
+++ b/scribo/filter/object_links_bbox_ratio.hh
@@ -49,7 +49,6 @@ namespace scribo
/*! \brief Invalidate links between two components with too different
height or width.
- \param[in] components An object image.
\param[in] links Link components information.
\param[in] dim The dimension to use to compare bbox length.
\param[in] max_ratio The maximum length ratio of two linked
@@ -59,8 +58,7 @@ namespace scribo
*/
template <typename L>
object_links<L>
- object_links_bbox_ratio(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bbox_ratio(const object_links<L>& links,
unsigned dim,
float max_ratio);
@@ -70,19 +68,19 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_bbox_ratio(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bbox_ratio(const object_links<L>& links,
unsigned dim,
float max_ratio)
{
trace::entering("scribo::filter::object_links_bbox_ratio");
- mln_precondition(components.is_valid());
mln_precondition(links.is_valid());
+ const component_set<L>& components = links.components();
+
object_links<L> output(links);
- for (unsigned i = 1; i < links.size(); ++i)
- if (links[i] != i)
+ for (unsigned i = 1; i < links.nelements(); ++i)
+ if (links(i) != i)
{
float
lmin = components(i).bbox().pmax()[dim]
diff --git a/scribo/filter/object_links_bottom_aligned.hh b/scribo/filter/object_links_bottom_aligned.hh
index ce6f6af..f1816d4 100644
--- a/scribo/filter/object_links_bottom_aligned.hh
+++ b/scribo/filter/object_links_bottom_aligned.hh
@@ -37,7 +37,6 @@
# include <scribo/core/macros.hh>
# include <scribo/core/object_links.hh>
-# include <scribo/core/component_set.hh>
# include <scribo/filter/object_links_non_aligned_simple.hh>
@@ -52,7 +51,6 @@ namespace scribo
/*! \brief Invalidate links between two components if their bottom are not
aligned.
- \param[in] components A component set.
\param[in] links Object links information.
\param[in] max_alpha Maximum angle value (degrees).
@@ -82,8 +80,7 @@ namespace scribo
*/
template <typename L>
object_links<L>
- object_links_bottom_aligned(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bottom_aligned(const object_links<L>& links,
float max_alpha);
@@ -92,18 +89,15 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_bottom_aligned(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_bottom_aligned(const object_links<L>& links,
float max_alpha)
{
trace::entering("scribo::filter::object_links_bottom_aligned");
- mln_precondition(components.is_valid());
mln_precondition(links.is_valid());
object_links<L>
- output = object_links_non_aligned_simple(components, links,
- 2, max_alpha);
+ output = object_links_non_aligned_simple(links, 2, max_alpha);
trace::exiting("scribo::filter::object_links_bottom_aligned");
return output;
diff --git a/scribo/filter/object_links_non_aligned_simple.hh b/scribo/filter/object_links_non_aligned_simple.hh
index c27bea5..5ecba0f 100644
--- a/scribo/filter/object_links_non_aligned_simple.hh
+++ b/scribo/filter/object_links_non_aligned_simple.hh
@@ -38,7 +38,6 @@
# include <scribo/core/macros.hh>
# include <scribo/core/object_links.hh>
-# include <scribo/core/object_image.hh>
namespace scribo
{
@@ -51,7 +50,6 @@ namespace scribo
/*! \brief Invalidate links between two non aligned components.
Alignment is based on a given edge of object bounding boxes.
- \param[in] components A component set.
\param[in] links Object links information.
\param[in] max_alpha Maximum angle value (degrees).
@@ -91,8 +89,7 @@ namespace scribo
*/
template <typename L>
object_links<L>
- object_links_non_aligned_simple(const component_set<L>& components,
- const object_links<L>& links,
+ object_links_non_aligned_simple(const object_links<L>& links,
unsigned edge,
float max_alpha);
@@ -102,16 +99,17 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_non_aligned_simple(const component_set<L>& comps,
- const object_links<L>& links,
+ object_links_non_aligned_simple(const object_links<L>& links,
unsigned edge,
float max_alpha)
{
trace::entering("scribo::filter::object_links_non_aligned_simple");
- mln_precondition(comps.is_valid());
mln_precondition(links.is_valid());
+
+ const component_set<L>& comps = links.components();
+
object_links<L> output(links);
float dr, dc;
@@ -123,81 +121,81 @@ namespace scribo
{
for_all_comps(i, comps)
{
- if (links[i] != i)
+ if (links(i) != i)
{
dr = math::abs(comps(i).bbox().pcenter().row()
- - comps(links[i]).bbox().pcenter().row());
+ - comps(links(i)).bbox().pcenter().row());
dc = math::abs(comps(i).bbox().pcenter().col()
- - comps(links[i]).bbox().pcenter().col());
+ - comps(links(i)).bbox().pcenter().col());
if (std::atan(dr / dc) > max_alpha_rad)
- output[i] = i;
+ output(i) = i;
}
}
}
// Top
else if (edge == 1)
{
- for_all_comps(i, comps.bboxes())
- if (links[i] != i)
+ for_all_comps(i, comps)
+ if (links(i) != i)
{
dr = math::abs(comps(i).bbox().pmin().row()
- - comps(links[i]).bbox().pmin().row());
+ - comps(links(i)).bbox().pmin().row());
dc = math::abs(comps(i).bbox().pcenter().col()
- - comps(links[i]).bbox().pcenter().col());
+ - comps(links(i)).bbox().pcenter().col());
if (std::atan(dr / dc) > max_alpha_rad)
- output[i] = i;
+ output(i) = i;
}
}
// Bottom
else if (edge == 2)
{
- for_all_comps(i, comps.bboxes())
+ for_all_comps(i, comps)
{
- if (links[i] != i)
+ if (links(i) != i)
{
dr = math::abs(comps(i).bbox().pmax().row()
- - comps(links[i]).bbox().pmax().row());
+ - comps(links(i)).bbox().pmax().row());
dc = math::abs(comps(i).bbox().pcenter().col()
- - comps(links[i]).bbox().pcenter().col());
+ - comps(links(i)).bbox().pcenter().col());
if (std::atan(dr / dc) > max_alpha_rad)
- output[i] = i;
+ output(i) = i;
}
}
}
// Left
else if (edge == 3)
{
- for_all_comps(i, comps.bboxes())
+ for_all_comps(i, comps)
{
- if (links[i] != i)
+ if (links(i) != i)
{
dr = math::abs(comps(i).bbox().pcenter().row()
- - comps(links[i]).bbox().pcenter().row());
+ - comps(links(i)).bbox().pcenter().row());
dc = math::abs(comps(i).bbox().pmin().col()
- - comps(links[i]).bbox().pmin().col());
+ - comps(links(i)).bbox().pmin().col());
if (std::atan(dc / dr) > max_alpha_rad)
- output[i] = i;
+ output(i) = i;
}
}
}
// Right
else if (edge == 4)
{
- for_all_comps(i, comps.bboxes())
+ for_all_comps(i, comps)
{
- if (links[i] != i)
+ if (links(i) != i)
{
dr = math::abs(comps(i).bbox().pcenter().row()
- - comps(links[i]).bbox().pcenter().row());
+ - comps(links(i)).bbox().pcenter().row());
dc = math::abs(comps(i).bbox().pmax().col()
- - comps(links[i]).bbox().pmax().col());
+ - comps(links(i)).bbox().pmax().col());
if (std::atan(dc / dr) > max_alpha_rad)
- output[i] = i;
+ output(i) = i;
}
}
}
diff --git a/scribo/filter/object_links_top_aligned.hh b/scribo/filter/object_links_top_aligned.hh
index 4a92c96..de5ab3b 100644
--- a/scribo/filter/object_links_top_aligned.hh
+++ b/scribo/filter/object_links_top_aligned.hh
@@ -36,7 +36,6 @@
# 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>
@@ -51,7 +50,6 @@ namespace scribo
/*! \brief Invalidate links between two objects if their top are not
aligned.
- \param[in] objects An object image.
\param[in] links Object links information.
\param[in] max_alpha Maximum angle value (degrees).
@@ -81,8 +79,7 @@ namespace scribo
*/
template <typename L>
object_links<L>
- object_links_top_aligned(const object_image(L)& objects,
- const object_links<L>& links,
+ object_links_top_aligned(const object_links<L>& links,
float max_alpha);
@@ -91,19 +88,15 @@ namespace scribo
template <typename L>
object_links<L>
- object_links_top_aligned(const object_image(L)& objects,
- const object_links<L>& links,
+ object_links_top_aligned(const object_links<L>& links,
float max_alpha)
{
trace::entering("scribo::filter::object_links_top_aligned");
- mln_precondition(objects.is_valid());
mln_precondition(links.is_valid());
object_links<L>
- output = object_links_non_aligned_simple(objects, links,
- 1,
- max_alpha);
+ output = object_links_non_aligned_simple(links, 1, max_alpha);
trace::exiting("scribo::filter::object_links_top_aligned");
return output;
diff --git a/scribo/filter/objects_with_holes.hh b/scribo/filter/objects_with_holes.hh
index dc72383..9e781fa 100644
--- a/scribo/filter/objects_with_holes.hh
+++ b/scribo/filter/objects_with_holes.hh
@@ -532,7 +532,7 @@ namespace scribo
true);
bool to_remove = false;
- for_all_components(i, components)
+ for_all_comps(i, components)
if (components(i).tag() != component::Ignored)
{
mln_domain(L) b = components(i).bbox();
@@ -549,7 +549,7 @@ namespace scribo
c8(), nlabels,
accu_t()).second();
unsigned nholes = 0;
- for_all_components(j, counts)
+ for_all_comp_data(j, counts)
if (counts(j) > 4u)
++nholes;
diff --git a/scribo/primitive/group/apply.hh b/scribo/primitive/group/apply.hh
index 26903fe..aff9a95 100644
--- a/scribo/primitive/group/apply.hh
+++ b/scribo/primitive/group/apply.hh
@@ -53,21 +53,18 @@ namespace scribo
/*! \brief Apply grouping in an object image.
- \param components A component set.
\param groups An object group structure.
\return A copy of \p components with grouped components.
*/
template <typename L>
component_set<L>
- apply(const component_set<L>& components,
- const object_groups<L>& groups);
+ apply(const object_groups<L>& groups);
/// \overload
template <typename L>
component_set<L>
- apply(const component_set<L>& components,
- const object_links<L>& links);
+ apply(const object_links<L>& links);
@@ -76,16 +73,14 @@ namespace scribo
template <typename L>
component_set<L>
- apply(const component_set<L>& components,
- const object_groups<L>& groups)
+ apply(const object_groups<L>& groups)
{
trace::entering("scribo::primitive::group::apply");
- mln_precondition(components.is_valid());
- mln_precondition(groups.nelements() == components.nlabels().next());
- mln_precondition(groups.nelements() == components.bboxes().nelements());
- mln_precondition(groups.components_id_() == components.id_());
+ mln_precondition(groups.is_valid());
+
+ const component_set<L>& components = groups.components();
L labeled_image = duplicate(components.labeled_image());
@@ -94,7 +89,7 @@ namespace scribo
packed_relabel_fun = mln::make::relabelfun(groups.comp_to_group(),
components.nelements(),
new_nlabels);
- new_nlabels = components.nelements();
+
labeling::relabel_inplace(labeled_image, new_nlabels,
packed_relabel_fun);
@@ -107,21 +102,15 @@ namespace scribo
template <typename L>
component_set<L>
- apply(const component_set<L>& components,
- const object_links<L>& links)
+ apply(const object_links<L>& links)
{
trace::entering("scribo::primitive::group::apply");
- mln_precondition(components.is_valid());
- mln_precondition(links.nelements() == components.nlabels().next());
- mln_precondition(links.nelements() == components.bboxes().nelements());
- mln_precondition(links.components_id_() == components.id_());
-
-
- object_groups<L> group = group::from_single_link(components, links);
+ mln_precondition(links.is_valid());
- component_set<L> output = apply(components, links);
+ object_groups<L> group = group::from_single_link(links);
+ component_set<L> output = apply(group);
trace::exiting("scribo::primitive::group::apply");
return output;
diff --git a/scribo/primitive/group/from_single_link.hh b/scribo/primitive/group/from_single_link.hh
index 128af6c..ffb2938 100644
--- a/scribo/primitive/group/from_single_link.hh
+++ b/scribo/primitive/group/from_single_link.hh
@@ -61,15 +61,13 @@ namespace scribo
\brief Link text components with their neighbor line if they
have one.
- \param[in] components A component set.
- \param[in] link_array The neighbor line of each line.
+ \param[in] links The neighbor line of each line.
\return Object groups information.
*/
template <typename L>
object_groups<L>
- from_single_link(const component_set<L>& components,
- const object_links<L>& link_array);
+ from_single_link(const object_links<L>& links);
# ifndef MLN_INCLUDE_ONLY
@@ -77,26 +75,23 @@ namespace scribo
template <typename L>
inline
object_groups<L>
- from_single_link(const component_set<L>& components,
- const object_links<L>& link_array)
+ from_single_link(const object_links<L>& links)
{
trace::entering("scribo::primitive::group::from_single_link");
- mln_precondition(components.is_valid());
- mln_precondition(link_array.nelements() == components.nelements().next());
- mln_precondition(link_array.components_id_() == components.id_());
+ mln_precondition(links.is_valid());
- object_groups<L> parent_array(components);
- parent_array.init_(link_array);
+ object_groups<L> parent(links);
+ parent.init_(links);
- for_all_components(i, parent_array)
- if (!components(i).is_valid())
- parent_array(i) = 0;
+ for_all_groups(i, parent)
+ if (!links.components()(i).is_valid())
+ parent(i) = 0;
else
- primitive::internal::find_root(parent_array, i);
+ primitive::internal::find_root(parent, i);
trace::exiting("scribo::primitive::group::from_single_link");
- return parent_array;
+ return parent;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/primitive/internal/init_link_array.hh b/scribo/primitive/internal/init_link_array.hh
index aa85175..2b46ad5 100644
--- a/scribo/primitive/internal/init_link_array.hh
+++ b/scribo/primitive/internal/init_link_array.hh
@@ -58,12 +58,12 @@ namespace scribo
void
init_link_array(object_links<L>& link_array)
{
- const component_set<L>& comp_set = link_array.component_set_();
+ const component_set<L>& comp_set = link_array.components();
for (unsigned i = 0; i < link_array.nelements(); ++i)
if (comp_set(i).tag() == component::Ignored)
- link_array[i] = 0;
+ link_array(i) = 0;
else
- link_array[i] = i;
+ link_array(i) = i;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/primitive/internal/is_link_valid.hh b/scribo/primitive/internal/is_link_valid.hh
index 34c27b8..5510699 100644
--- a/scribo/primitive/internal/is_link_valid.hh
+++ b/scribo/primitive/internal/is_link_valid.hh
@@ -52,20 +52,22 @@ namespace scribo
///
/// \return True if the link is between the \p i-th component
/// and it neighbor is validated.
+ template <typename L>
mln::util::couple<bool,unsigned>
- is_link_valid(const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ is_link_valid(const object_links<L>& left_link,
+ const object_links<L>& right_link,
unsigned i);
# ifndef MLN_INCLUDE_ONLY
+ template <typename L>
mln::util::couple<bool,unsigned>
- is_link_valid(const mln::util::array<unsigned>& left_link,
- const mln::util::array<unsigned>& right_link,
+ is_link_valid(const object_links<L>& left_link,
+ const object_links<L>& right_link,
unsigned i)
{
- bool b = (right_link[left_link[i]] == i && left_link[i] != i);
- return mln::make::couple(b, left_link[i]);
+ bool b = (right_link(left_link(i)) == i && left_link(i) != i);
+ return mln::make::couple(b, left_link(i));
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/primitive/link/internal/link_functor_base.hh b/scribo/primitive/link/internal/link_functor_base.hh
index 65f897c..5e4af46 100644
--- a/scribo/primitive/link/internal/link_functor_base.hh
+++ b/scribo/primitive/link/internal/link_functor_base.hh
@@ -233,7 +233,7 @@ namespace scribo
unsigned
link_functor_base<L,E>::link(unsigned object) const
{
- return links_[object];
+ return links_(object);
}
template <typename L, typename E>
@@ -256,9 +256,14 @@ namespace scribo
{
(void) start_point;
mln_value(L) v = this->labeled_image_(p);
+ bool is_separator = this->components_.separators()(p);
+
+ if (is_separator)
+ return true;
+
return v != literal::zero // Not the background
&& v != current_object // Not the current component
- && this->links_[v] != current_object // No loops
+ && this->links_(v) != current_object // No loops
&& this->components_(v).tag() != component::Ignored; // Not ignored
}
@@ -288,8 +293,12 @@ namespace scribo
const P& start_point,
const P& p) const
{
- return exact(this)->verify_link_criterion_(current_object,
- start_point, p);
+ return
+ // Do not link with separators...
+ ! this->components_.separators()(p)
+ // ... and perform custom checks.
+ && exact(this)->verify_link_criterion_(current_object,
+ start_point, p);
}
template <typename L, typename E>
@@ -471,7 +480,7 @@ namespace scribo
{
(void) start_point;
(void) anchor;
- this->links_[current_object] = this->labeled_image_(p);
+ this->links_(current_object) = this->labeled_image_(p);
}
diff --git a/scribo/primitive/link/internal/link_single_dmax_base.hh b/scribo/primitive/link/internal/link_single_dmax_base.hh
index b94da8e..6897bd6 100644
--- a/scribo/primitive/link/internal/link_single_dmax_base.hh
+++ b/scribo/primitive/link/internal/link_single_dmax_base.hh
@@ -146,8 +146,8 @@ namespace scribo
unsigned current_object)
{
float
- midcol = (this->components_.bbox(current_object).pmax()[direction_]
- - this->components_.bbox(current_object).pmin()[direction_]) / 2;
+ midcol = (this->components_(current_object).bbox().pmax()[direction_]
+ - this->components_(current_object).bbox().pmin()[direction_]) / 2;
dmax_ = midcol + neighb_max_distance_;
}
diff --git a/scribo/primitive/link/merge_double_link.hh b/scribo/primitive/link/merge_double_link.hh
index 0628cd6..704c103 100644
--- a/scribo/primitive/link/merge_double_link.hh
+++ b/scribo/primitive/link/merge_double_link.hh
@@ -64,7 +64,6 @@ namespace scribo
\brief Validate and merge double link information. A link
must exist in both ways to be validated.
- \param[in] components The Lines of text.
\param[in] left_link The left neighbor of each line of text.
\param[in] right_link The right neighbor of each line of text.
@@ -72,8 +71,7 @@ namespace scribo
*/
template <typename L>
object_links<L>
- merge_double_link(const component_set<L>& components,
- const object_links<L>& left_link,
+ merge_double_link(const object_links<L>& left_link,
const object_links<L>& right_link);
@@ -84,31 +82,30 @@ namespace scribo
template <typename L>
inline
object_links<L>
- merge_double_link(const component_set<L>& components,
- const object_links<L>& left_link,
+ merge_double_link(const object_links<L>& left_link,
const object_links<L>& right_link)
{
trace::entering("scribo::primitive::link::merge_double_link");
- mln_precondition(components.is_valid());
- mln_precondition(left_link.nelements() == right_link.nelements());
- mln_precondition(left_link.components_id_() == components.id_());
- mln_precondition(right_link.components_id_() == components.id_());
+ mln_precondition(left_link.is_valid());
+ mln_precondition(right_link.is_valid());
+ mln_precondition(left_link.components() == right_link.components());
+ const component_set<L>& components = left_link.components();
object_links<L> merge(left_link);
for_all_ncomponents(i, components.nelements())
{
if (components(i).tag() == component::Ignored)
- merge[i] = 0;
+ merge(i) = 0;
else
{
mln::util::couple<bool, unsigned>
nbh = primitive::internal::is_link_valid(left_link,
right_link, i);
if (!nbh.first())
- merge[i] = i;
+ merge(i) = i;
}
}
diff --git a/scribo/primitive/link/with_single_right_link_bottom.hh b/scribo/primitive/link/with_single_right_link_bottom.hh
index 747e15c..85f6b50 100644
--- a/scribo/primitive/link/with_single_right_link_bottom.hh
+++ b/scribo/primitive/link/with_single_right_link_bottom.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -28,7 +29,7 @@
/// \file
///
-/// Link text objects with their right neighbor.
+/// Link text components with their right neighbor.
# include <mln/core/concept/image.hh>
@@ -41,7 +42,6 @@
# include <scribo/core/macros.hh>
# include <scribo/core/tag/anchor.hh>
-# include <scribo/core/object_image.hh>
# include <scribo/core/object_links.hh>
# include <scribo/primitive/link/internal/find_link.hh>
@@ -59,10 +59,10 @@ namespace scribo
namespace link
{
- /// \brief Link objects with their right neighbor if exists.
+ /// \brief Link components with their right neighbor if exists.
/// Lookup startup point is the object bottom center.
///
- /// \param[in] objects An object image.
+ /// \param[in] components A component set.
/// \param[in] The maximum distance allowed to seach a neighbor object.
///
/// \return Object links data.
@@ -70,7 +70,7 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_bottom(const object_image(L)& objects,
+ with_single_right_link_bottom(const component_set<L>& components,
unsigned neighb_max_distance);
@@ -79,7 +79,7 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_bottom(const object_image(L)& objects);
+ with_single_right_link_bottom(const component_set<L>& components);
@@ -103,9 +103,9 @@ namespace scribo
public:
typedef mln_site(L) P;
- single_right_bottom_functor(const object_image(L)& objects,
+ single_right_bottom_functor(const component_set<L>& components,
unsigned dmax)
- : super_(objects, dmax)
+ : super_(components, dmax, anchor::Horizontal)
{
}
@@ -125,15 +125,15 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_bottom(const object_image(L)& objects,
+ with_single_right_link_bottom(const component_set<L>& components,
unsigned neighb_max_distance)
{
trace::entering("scribo::primitive::link::with_single_right_link_bottom");
- mln_precondition(objects.is_valid());
+ mln_precondition(components.is_valid());
internal::single_right_bottom_functor<L>
- functor(objects, neighb_max_distance);
+ functor(components, neighb_max_distance);
object_links<L> output = compute(functor, anchor::Bottom);
@@ -145,9 +145,9 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_bottom(const object_image(L)& objects)
+ with_single_right_link_bottom(const component_set<L>& components)
{
- return with_single_right_link_bottom(objects, mln_max(unsigned));
+ return with_single_right_link_bottom(components, mln_max(unsigned));
}
diff --git a/scribo/primitive/link/with_single_right_link_dmax_ratio.hh b/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
index 858346e..d3637ef 100644
--- a/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
+++ b/scribo/primitive/link/with_single_right_link_dmax_ratio.hh
@@ -61,7 +61,9 @@ namespace scribo
/*! \brief Link objects with their right neighbor if exists.
\param[in] components A component set.
- \param[in] dmax_ratio
+ \param[in] dmax_ratio Size ratio defining the maximum lookup
+ distance.
+ \param[in] anchor Starting point for the neighbor lookup.
\return Object links data.
@@ -77,11 +79,20 @@ namespace scribo
inline
object_links<L>
with_single_right_link_dmax_ratio(const component_set<L>& components,
+ float dmax_ratio, anchor::Type anchor);
+
+ /// \overload
+ /// anchor is set to MassCenter.
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_dmax_ratio(const component_set<L>& components,
float dmax_ratio);
/// \overload
/// dmax_ratio is set to 3.
+ /// anchor is set to MassCenter.
template <typename L>
inline
object_links<L>
@@ -127,11 +138,12 @@ namespace scribo
// Facades
+
template <typename L>
inline
object_links<L>
with_single_right_link_dmax_ratio(const component_set<L>& components,
- float dmax_ratio)
+ float dmax_ratio, anchor::Type anchor)
{
trace::entering("scribo::primitive::link::with_single_right_link_dmax_ratio");
@@ -140,13 +152,25 @@ namespace scribo
internal::single_right_dmax_ratio_functor<L>
functor(components, dmax_ratio);
- object_links<L> output = compute(functor);
+ object_links<L> output = compute(functor, anchor);
trace::exiting("scribo::primitive::link::with_single_right_link_dmax_ratio");
return output;
}
+
+ template <typename L>
+ inline
+ object_links<L>
+ with_single_right_link_dmax_ratio(const component_set<L>& components,
+ float dmax_ratio)
+ {
+ return with_single_right_link_dmax_ratio(components, dmax_ratio,
+ anchor::MassCenter);
+ }
+
+
template <typename L>
inline
object_links<L>
diff --git a/scribo/primitive/link/with_single_right_link_top.hh b/scribo/primitive/link/with_single_right_link_top.hh
index 14a4f37..6d26114 100644
--- a/scribo/primitive/link/with_single_right_link_top.hh
+++ b/scribo/primitive/link/with_single_right_link_top.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -41,7 +42,7 @@
# include <scribo/core/macros.hh>
# include <scribo/core/tag/anchor.hh>
-# include <scribo/core/object_image.hh>
+# include <scribo/core/component_set.hh>
# include <scribo/core/object_links.hh>
# include <scribo/primitive/link/internal/find_link.hh>
@@ -70,7 +71,7 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_top(const object_image(L)& objects,
+ with_single_right_link_top(const component_set<L>& objects,
unsigned neighb_max_distance);
@@ -79,7 +80,7 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_top(const object_image(L)& objects);
+ with_single_right_link_top(const component_set<L>& objects);
@@ -103,9 +104,9 @@ namespace scribo
public:
typedef mln_site(L) P;
- single_right_top_functor(const object_image(L)& objects,
+ single_right_top_functor(const component_set<L>& objects,
unsigned dmax)
- : super_(objects, dmax)
+ : super_(objects, dmax, anchor::Horizontal)
{
}
@@ -125,7 +126,7 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_top(const object_image(L)& objects,
+ with_single_right_link_top(const component_set<L>& objects,
unsigned neighb_max_distance)
{
trace::entering("scribo::primitive::link::with_single_right_link_top");
@@ -145,7 +146,7 @@ namespace scribo
template <typename L>
inline
object_links<L>
- with_single_right_link_top(const object_image(L)& objects)
+ with_single_right_link_top(const component_set<L>& objects)
{
return with_single_right_link_top(objects, mln_max(unsigned));
}
diff --git a/scribo/src/afp/link.hh b/scribo/src/afp/link.hh
index 66115d0..b6ef1f9 100644
--- a/scribo/src/afp/link.hh
+++ b/scribo/src/afp/link.hh
@@ -60,9 +60,9 @@ namespace scribo
{
if (*p != literal::zero // Not the background
&& *p != i // Not the current component
- && right[*p] != i) // No loops
+ && right(*p) != i) // No loops
{
- right[i] = *p;
+ right(i) = *p;
break;
}
}
@@ -79,9 +79,9 @@ namespace scribo
{
if (*p != literal::zero // Not the background
&& *p != i // Not the current component
- && left[*p] != i) // No loops
+ && left(*p) != i) // No loops
{
- left[i] = *p;
+ left(i) = *p;
break;
}
}
@@ -123,9 +123,9 @@ namespace scribo
{
if (*p != literal::zero // Not the background
&& *p != i // Not the current component
- && left[*p] != i) // No loops
+ && left(*p) != i) // No loops
{
- left[i] = *p;
+ left(i) = *p;
break;
}
}
diff --git a/scribo/src/afp/regroup.hh b/scribo/src/afp/regroup.hh
index 2de36b9..3fcfcaa 100644
--- a/scribo/src/afp/regroup.hh
+++ b/scribo/src/afp/regroup.hh
@@ -28,7 +28,7 @@ namespace scribo
new_groups(components, static_cast<unsigned>(components.nlabels()) + 1, 0);
unsigned ngroups = 0;
- for_all_components(i, components.bboxes())
+ for_all_comps(i, components)
{
if (groups[i] == 0)
continue;
diff --git a/scribo/text/recognition.hh b/scribo/text/recognition.hh
index 364e56b..5927d44 100644
--- a/scribo/text/recognition.hh
+++ b/scribo/text/recognition.hh
@@ -143,7 +143,7 @@ namespace scribo
data::fill(text_ima, true);
// Careful : background is set to 'False'
- const component_set<L>& comp_set = lines.component_set_();
+ const component_set<L>& comp_set = lines.components();
const L& lbl = comp_set.labeled_image();
const mln::util::array<component_id_t>& comps = lines(i).components();
--
1.5.6.5
1
0
11 Mar '10
* debug/bboxes_enlarged_image.hh,
* debug/looks_like_a_text_line_image.hh,
* debug/mean_and_base_lines_image.hh: New routines.
* debug/alignment_decision_image.hh,
* debug/decision_image.hh,
* debug/save_bboxes_image.hh: Update code according to last
changes in core classes.
* debug/usage.hh: Make the description optional.
---
scribo/ChangeLog | 15 +++
scribo/debug/alignment_decision_image.hh | 37 +++----
scribo/debug/bboxes_enlarged_image.hh | 136 ++++++++++++++++++++++++
scribo/debug/decision_image.hh | 12 +-
scribo/debug/looks_like_a_text_line_image.hh | 130 +++++++++++++++++++++++
scribo/debug/mean_and_base_lines_image.hh | 147 ++++++++++++++++++++++++++
scribo/debug/save_bboxes_image.hh | 60 ++++++++++-
scribo/debug/usage.hh | 9 +-
8 files changed, 513 insertions(+), 33 deletions(-)
create mode 100644 scribo/debug/bboxes_enlarged_image.hh
create mode 100644 scribo/debug/looks_like_a_text_line_image.hh
create mode 100644 scribo/debug/mean_and_base_lines_image.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index a24406b..54d5f0d 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,20 @@
2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Improve debug routines in Scribo.
+
+ * debug/bboxes_enlarged_image.hh,
+ * debug/looks_like_a_text_line_image.hh,
+ * debug/mean_and_base_lines_image.hh: New routines.
+
+ * debug/alignment_decision_image.hh,
+ * debug/decision_image.hh,
+ * debug/save_bboxes_image.hh: Update code according to last
+ changes in core classes.
+
+ * debug/usage.hh: Make the description optional.
+
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Improve core classes in Scribo.
* core/component_info.hh,
diff --git a/scribo/debug/alignment_decision_image.hh b/scribo/debug/alignment_decision_image.hh
index e3b6163..841bd38 100644
--- a/scribo/debug/alignment_decision_image.hh
+++ b/scribo/debug/alignment_decision_image.hh
@@ -36,7 +36,9 @@
# include <mln/literal/colors.hh>
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
+# include <mln/norm/l1.hh>
+# include <scribo/core/component_set.hh>
# include <scribo/core/object_groups.hh>
# include <scribo/draw/bounding_boxes.hh>
@@ -79,28 +81,28 @@ namespace scribo
template <typename L>
mln::util::couple<mln_site(L),mln_site(L)>
- find_anchors(const object_image(L)& objects,
+ find_anchors(const component_set<L>& components,
unsigned i,
unsigned link_i,
const Alignment& alignment)
{
mln_site(L)
- a1 = objects.bbox(i).center(),
- a2 = objects.bbox(link_i).center();
+ a1 = components(i).bbox().pcenter(),
+ a2 = components(link_i).bbox().pcenter();
switch (alignment)
{
case top:
- a1.row() = objects.bbox(i).pmin().row();
- a2.row() = objects.bbox(link_i).pmin().row();
+ a1.row() = components(i).bbox().pmin().row();
+ a2.row() = components(link_i).bbox().pmin().row();
break;
case center:
break;
case bottom:
- a1.row() = objects.bbox(i).pmax().row();
- a2.row() = objects.bbox(link_i).pmax().row();
+ a1.row() = components(i).bbox().pmax().row();
+ a2.row() = components(link_i).bbox().pmax().row();
break;
}
@@ -120,35 +122,32 @@ namespace scribo
trace::entering("scribo::debug::alignment_decision_image");
const I& input = exact(input_);
- const object_image(L)& objects = links.object_image_();
+ const component_set<L>& components = links.components();
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.object_image_() != filtered_links.object_image_());
- /// Fixme: check that objects has been computed from input.
+ /// Fixme: check that components 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_all_comps(i, components)
+ mln::draw::box(decision_image, components(i).bbox(), literal::blue);
typedef mln_site(L) P;
- for (unsigned i = 1; i < links.size(); ++i)
+ for_all_links(i, links)
{
-
- if (links[i] != i)
+ if (links(i) != i)
{
value::rgb8 value = literal::green;
- if (links[i] != filtered_links[i])
+ if (links(i) != filtered_links(i))
value = literal::red;
mln::util::couple<P,P>
- anchors = internal::find_anchors(objects, i, links[i], alignment);
- if (norm::l1_distance(anchors.first(), anchors.second()) < max_link_length)
+ anchors = internal::find_anchors(components, i, links(i), alignment);
+ if (mln::norm::l1_distance(anchors.first().to_vec(), anchors.second().to_vec()) < max_link_length)
mln::draw::line(decision_image,
anchors.first(),
anchors.second(),
diff --git a/scribo/debug/bboxes_enlarged_image.hh b/scribo/debug/bboxes_enlarged_image.hh
new file mode 100644
index 0000000..edd6d7a
--- /dev/null
+++ b/scribo/debug/bboxes_enlarged_image.hh
@@ -0,0 +1,136 @@
+// Copyright (C) 2010 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_BBOXES_ENLARGED_IMAGE_HH
+# define SCRIBO_DEBUG_BBOXES_ENLARGED_IMAGE_HH
+
+/// \file
+///
+/// \brief Compute an image of enlarged component bounding boxes.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/data/convert.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/literal/colors.hh>
+# include <mln/draw/box.hh>
+
+# include <scribo/core/line_set.hh>
+
+// Declares internal::looks_like_a_text_line.
+# include <scribo/text/merging.hh>
+
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+
+ /// \brief Compute an image of enlarged component bounding boxes.
+ ///
+ /// This check whether each line looks like a text line. If it is
+ /// a text line, its extended bounding box is drawn, otherwise, it
+ /// is normal bounding box.
+ ///
+ /// This rountine uses scribo::internal::looks_like_a_text_line to
+ /// check if a component looks like a text line.
+ ///
+ ///
+ /// \param[in] input An image convertible towards a color image.
+ /// \param[in] lines A line set.
+ /// \param[in] text_value The color used to draw bounding boxes
+ /// of components looking like a text line.
+ /// \param[in] non_text_value The color used to draw bounding
+ /// boxes of components NOT looking like
+ /// a text line.
+ ///
+ /// \return A color image.
+ //
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ bboxes_enlarged_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const value::rgb8& text_value,
+ const value::rgb8& non_text_value);
+
+ /// \overload
+ /// text_value is set to literal::green.
+ /// non_text_value is set to literal::red.
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ bboxes_enlarged_image(const Image<I>& input,
+ const line_set<L>& lines);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ bboxes_enlarged_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const value::rgb8& text_value,
+ const value::rgb8& non_text_value)
+ {
+ trace::entering("scribo::debug::bboxes_enlarged_image");
+ mln_precondition(exact(input).is_valid());
+
+ image2d<value::rgb8> output = data::convert(value::rgb8(), input);
+
+ for_all_lines(l, lines)
+ if (! lines(l).hidden())
+ {
+ if (text::internal::looks_like_a_text_line(lines(l)))
+ mln::draw::box(output, lines(l).ebbox(), text_value);
+ else
+ mln::draw::box(output, lines(l).bbox(), non_text_value);
+ }
+
+ trace::exiting("scribo::debug::bboxes_enlarged_image");
+ return output;
+ }
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ bboxes_enlarged_image(const Image<I>& input,
+ const line_set<L>& lines)
+ {
+ return bboxes_enlarged_image(input, lines,
+ literal::green, literal::red);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEBUG_BBOXES_ENLARGED_IMAGE_HH
diff --git a/scribo/debug/decision_image.hh b/scribo/debug/decision_image.hh
index 011dbfa..cc3f0f0 100644
--- a/scribo/debug/decision_image.hh
+++ b/scribo/debug/decision_image.hh
@@ -130,7 +130,7 @@ namespace scribo
trace::entering("scribo::debug::decision_image");
const I& input = exact(input_);
- const component_set<L>& components = links.component_set_();
+ const component_set<L>& components = links.components();
mln_precondition(input.is_valid());
mln_precondition(links.is_valid());
@@ -142,20 +142,20 @@ namespace scribo
image2d<value::rgb8>
decision_image = data::convert(value::rgb8(), input);
- for_all_components(i, components)
+ for_all_comps(i, components)
mln::draw::box(decision_image, components(i).bbox(), literal::blue);
- for (unsigned i = 1; i < links.size(); ++i)
+ for (unsigned i = 1; i < links.nelements(); ++i)
{
- if (links[i] != i)
+ if (links(i) != i)
{
value::rgb8 value = literal::green;
- if (links[i] != filtered_links[i])
+ if (links(i) != filtered_links(i))
value = literal::red;
mln::draw::line(decision_image,
components(i).bbox().pcenter(),
- components(links[i]).bbox().pcenter(),
+ components(links(i)).bbox().pcenter(),
value);
}
}
diff --git a/scribo/debug/looks_like_a_text_line_image.hh b/scribo/debug/looks_like_a_text_line_image.hh
new file mode 100644
index 0000000..a40c7d6
--- /dev/null
+++ b/scribo/debug/looks_like_a_text_line_image.hh
@@ -0,0 +1,130 @@
+// Copyright (C) 2010 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_LOOKS_LIKE_A_TEXT_LINE_IMAGE_HH
+# define SCRIBO_DEBUG_LOOKS_LIKE_A_TEXT_LINE_IMAGE_HH
+
+/// \file
+///
+/// Compute an image where components are drawn differently whether
+/// they look like a line or not.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/data/convert.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/literal/colors.hh>
+# include <mln/draw/box.hh>
+
+# include <scribo/core/line_set.hh>
+
+// Declares internal::looks_like_a_text_line.
+# include <scribo/text/merging.hh>
+
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+
+ /// \brief Compute an image where components are drawn differently
+ /// whether they look like a line or not.
+ ///
+ /// \param[in] input An image convertible towards a color image.
+ /// \param[in] lines A line set.
+ /// \param[in] text_value The color used to draw bounding boxes
+ /// of components looking like a text line.
+ /// \param[in] non_text_value The color used to draw bounding
+ /// boxes of components NOT looking like
+ /// a text line.
+ ///
+ /// \return A color image.
+ //
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ looks_like_a_text_line_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const value::rgb8& text_value,
+ const value::rgb8& non_text_value);
+
+ /// \overload
+ /// text_value is set to literal::green.
+ /// non_text_value is set to literal::red.
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ looks_like_a_text_line_image(const Image<I>& input,
+ const line_set<L>& lines);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ looks_like_a_text_line_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const value::rgb8& text_value,
+ const value::rgb8& non_text_value)
+ {
+ trace::entering("scribo::debug::looks_like_a_text_line_image");
+ mln_precondition(exact(input).is_valid());
+
+ image2d<value::rgb8> output = data::convert(value::rgb8(), input);
+
+ for_all_lines(l, lines)
+ if (! lines(l).hidden())
+ {
+ if (text::internal::looks_like_a_text_line(lines(l)))
+ mln::draw::box(output, lines(l).bbox(), text_value);
+ else
+ mln::draw::box(output, lines(l).bbox(), non_text_value);
+ }
+
+ trace::exiting("scribo::debug::looks_like_a_text_line_image");
+ return output;
+ }
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ looks_like_a_text_line_image(const Image<I>& input,
+ const line_set<L>& lines)
+ {
+ return looks_like_a_text_line_image(input, lines,
+ literal::green, literal::red);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEBUG_LOOKS_LIKE_A_TEXT_LINE_IMAGE_HH
diff --git a/scribo/debug/mean_and_base_lines_image.hh b/scribo/debug/mean_and_base_lines_image.hh
new file mode 100644
index 0000000..c4517c7
--- /dev/null
+++ b/scribo/debug/mean_and_base_lines_image.hh
@@ -0,0 +1,147 @@
+// Copyright (C) 2010 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_MEAN_AND_BASE_LINES_IMAGE_HH
+# define SCRIBO_DEBUG_MEAN_AND_BASE_LINES_IMAGE_HH
+
+/// \file
+///
+/// \brief Compute a color image showing the mean and the base lines
+/// of the text lines.
+
+# include <mln/core/concept/image.hh>
+# include <mln/data/convert.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/literal/colors.hh>
+
+# include <mln/draw/box.hh>
+# include <mln/draw/dashed_line.hh>
+
+# include <scribo/core/line_set.hh>
+
+
+namespace scribo
+{
+
+ namespace debug
+ {
+
+ using namespace mln;
+
+
+ /// \brief Compute a color image showing the mean and the base lines
+ /// of the text lines.
+ ///
+ /// The mean line is drawn with a dashed line.
+ /// The base line is drawn with a plain line.
+ ///
+ /// \param[in] input An image convertible towards a color image.
+ /// \param[in] lines A line set.
+ /// \param[in] bbox_value Value used to draw lines bounding boxes.
+ /// \param[in] meanline_value Value used to draw mean lines.
+ /// \param[in] baseline_value Value used to draw base lines.
+ ///
+ /// \return A color image.
+ //
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ mean_and_base_lines_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const value::rgb8& bbox_value,
+ const value::rgb8& meanline_value,
+ const value::rgb8& baseline_value);
+
+ /// \overload
+ /// text_value is set to literal::green.
+ /// non_text_value is set to literal::red.
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ mean_and_base_lines_image(const Image<I>& input,
+ const line_set<L>& lines);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ mean_and_base_lines_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const value::rgb8& bbox_value,
+ const value::rgb8& meanline_value,
+ const value::rgb8& baseline_value)
+ {
+ trace::entering("scribo::debug::mean_and_base_lines_image");
+ mln_precondition(exact(input).is_valid());
+
+ image2d<value::rgb8> output = data::convert(value::rgb8(), input);
+
+ for_all_lines(l, lines)
+ {
+ if (! lines(l).hidden())
+ {
+ mln::draw::box(output, lines(l).bbox(), bbox_value);
+
+ if (! (lines(l).type() == line::Text
+ || (lines(l).type() == line::Undefined
+ && lines(l).tag() == line::None
+ && lines(l).card() > 2)))
+ continue;
+
+ point2d
+ b_top(lines(l).meanline(), lines(l).bbox().pmin().col()),
+ e_top(lines(l).meanline(), lines(l).bbox().pmax().col()),
+ b_bot(lines(l).baseline(), lines(l).bbox().pmin().col()),
+ e_bot(lines(l).baseline(), lines(l).bbox().pmax().col());
+
+ mln::draw::line(output, b_bot, e_bot, baseline_value);
+ mln::draw::dashed_line(output, b_top, e_top, meanline_value);
+
+ }
+ }
+
+ trace::exiting("scribo::debug::mean_and_base_lines_image");
+ return output;
+ }
+
+
+ template <typename I, typename L>
+ mln_ch_value(I,value::rgb8)
+ mean_and_base_lines_image(const Image<I>& input,
+ const line_set<L>& lines)
+ {
+ return mean_and_base_lines_image(input, lines,
+ literal::purple, literal::blue,
+ literal::cyan);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::debug
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEBUG_MEAN_AND_BASE_LINES_IMAGE_HH
diff --git a/scribo/debug/save_bboxes_image.hh b/scribo/debug/save_bboxes_image.hh
index 0265ee4..60f2c8d 100644
--- a/scribo/debug/save_bboxes_image.hh
+++ b/scribo/debug/save_bboxes_image.hh
@@ -48,12 +48,30 @@ namespace scribo
using namespace mln;
- /// Draw a list of bounding boxes and their associated mass center.
+ /// Draw a list of bounding boxes
template <typename I>
void
save_bboxes_image(const Image<I>& input,
const mln::util::array< box<mln_site(I)> >& bboxes,
- const value::rgb8& value,
+ const std::string& filename,
+ const value::rgb8& value);
+
+
+ template <typename I, typename L>
+ void
+ save_bboxes_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const std::string& filename,
+ const value::rgb8& value);
+
+ /// \overload
+ /// value is set to literal::red.
+ //
+ template <typename I, typename L>
+ inline
+ void
+ save_bboxes_image(const Image<I>& input,
+ const line_set<L>& lines,
const std::string& filename);
@@ -64,8 +82,8 @@ namespace scribo
void
save_bboxes_image(const Image<I>& input,
const mln::util::array< box<mln_site(I)> >& bboxes,
- const value::rgb8& value,
- const std::string& filename)
+ const std::string& filename,
+ const value::rgb8& value)
{
trace::entering("scribo::debug::save_bboxes_image");
mln_precondition(exact(input).is_valid());
@@ -77,6 +95,40 @@ namespace scribo
trace::exiting("scribo::debug::save_bboxes_image");
}
+
+ template <typename I, typename L>
+ inline
+ void
+ save_bboxes_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const std::string& filename,
+ const value::rgb8& value)
+ {
+ trace::entering("scribo::debug::save_bboxes_image");
+ mln_precondition(exact(input).is_valid());
+
+ image2d<value::rgb8> output = data::convert(value::rgb8(), input);
+
+ for_all_lines(l, lines)
+ if (! lines(l).hidden())
+ mln::draw::box(output, lines(l).bbox(), value);
+
+ io::ppm::save(output, filename);
+ trace::exiting("scribo::debug::save_bboxes_image");
+ }
+
+
+ template <typename I, typename L>
+ inline
+ void
+ save_bboxes_image(const Image<I>& input,
+ const line_set<L>& lines,
+ const std::string& filename)
+ {
+ return save_bboxes_image(input, lines, filename, literal::red);
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::debug
diff --git a/scribo/debug/usage.hh b/scribo/debug/usage.hh
index e3872a9..6b6c9b7 100644
--- a/scribo/debug/usage.hh
+++ b/scribo/debug/usage.hh
@@ -53,21 +53,22 @@ namespace scribo
inline
int
usage(char* argv[], const char *desc, const char* args,
- const char*args_desc[][2], const char *out_desc)
+ const char*args_desc[][2], const char *out_desc = 0)
{
std::cout << "Usage: " << argv[0] << " " << args
<< std::endl
<< std::endl;
std::cout << "-----------" << std::endl;
- std::cout << std::endl
- << desc << std::endl
+ std::cout << desc << std::endl
<< std::endl;
for (unsigned i = 0; args_desc[i][0] != 0; ++i)
std::cout << " " << args_desc[i][0] << ": " << args_desc[i][1]
<< std::endl;
- std::cout << std::endl << "Output: " << out_desc << std::endl;
+ if (out_desc)
+ std::cout << std::endl << "Output: " << out_desc << std::endl;
+
std::cout << "-----------" << std::endl;
std::cout << "EPITA/LRDE - Scribo 2009" << std::endl;
return 1;
--
1.5.6.5
1
0
11 Mar '10
* core/component_info.hh,
* core/component_set.hh: Add new methods and an output operator.
* core/line_info.hh: Add new methods and improve stats computation.
* core/line_set.hh: Add new methods.
* core/macros.hh: Add more specific macros.
* core/tag/component.hh,
* core/tag/line.hh: Add output operators.
---
scribo/ChangeLog | 16 ++
scribo/core/component_info.hh | 43 ++++
scribo/core/component_set.hh | 152 +++++++++++-
scribo/core/line_info.hh | 517 ++++++++++++++++++++++++++++++++++-------
scribo/core/line_set.hh | 213 ++++++++---------
scribo/core/macros.hh | 12 +-
scribo/core/tag/component.hh | 63 +++++-
scribo/core/tag/line.hh | 29 ++-
8 files changed, 823 insertions(+), 222 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 2c2f0c2..a24406b 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,19 @@
+2010-03-11 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Improve core classes in Scribo.
+
+ * core/component_info.hh,
+ * core/component_set.hh: Add new methods and an output operator.
+
+ * core/line_info.hh: Add new methods and improve stats computation.
+
+ * core/line_set.hh: Add new methods.
+
+ * core/macros.hh: Add more specific macros.
+
+ * core/tag/component.hh,
+ * core/tag/line.hh: Add output operators.
+
2010-03-09 Guillaume Lazzara <z(a)lrde.epita.fr>
Share internal data in groups and links structures.
diff --git a/scribo/core/component_info.hh b/scribo/core/component_info.hh
index 1e4aaf5..4ee438c 100644
--- a/scribo/core/component_info.hh
+++ b/scribo/core/component_info.hh
@@ -58,10 +58,17 @@ namespace scribo
component_id_t id() const;
const mln::box2d& bbox() const;
const mln::point2d& mass_center() const;
+
+ // The number of pixels in this component.
unsigned card() const;
+
component::Tag tag() const;
void update_tag(component::Tag tag);
+ component::Type type() const;
+ void update_type(component::Type type);
+
+ // The line it is rattached to. 0 means an invalid line.
line_id_t line_id() const;
bool is_valid() const;
@@ -71,12 +78,19 @@ namespace scribo
mln::box2d bbox_;
mln::point2d mass_center_;
unsigned card_;
+
component::Tag tag_;
+ component::Type type_;
line_id_t line_id_;
};
+
+ std::ostream&
+ operator<<(std::ostream& ostr, const component_info& info);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -138,6 +152,21 @@ namespace scribo
tag_ = tag;
}
+
+ component::Type
+ component_info::type() const
+ {
+ return type_;
+ }
+
+
+ void
+ component_info::update_type(component::Type type)
+ {
+ type_ = type;
+ }
+
+
component_info::line_id_t
component_info::line_id() const
{
@@ -151,6 +180,20 @@ namespace scribo
}
+ std::ostream&
+ operator<<(std::ostream& ostr, const component_info& info)
+ {
+ return ostr << "component_info("
+ << "id=" << info.id()
+ << ", bbox=" << info.bbox()
+ << ", mass_center=" << info.mass_center()
+ << ", card=" << info.card()
+ << ", tag=" << info.tag()
+ << ", line_id=" << info.line_id()
+ << ")" << std::endl;
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/core/component_set.hh b/scribo/core/component_set.hh
index 2f9d10e..14cdc4c 100644
--- a/scribo/core/component_set.hh
+++ b/scribo/core/component_set.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -30,6 +31,11 @@
///
/// \brief Definition of a component set.
+# include <mln/core/concept/site_set.hh>
+# include <mln/core/concept/function.hh>
+
+# include <mln/data/fill.hh>
+
# include <mln/util/array.hh>
# include <mln/accu/pair.hh>
@@ -40,6 +46,10 @@
# include <mln/convert/from_to.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/pw/all.hh>
+
+# include <mln/core/routine/duplicate.hh>
# include <scribo/core/macros.hh>
# include <scribo/core/component_info.hh>
@@ -86,6 +96,7 @@ namespace scribo
mln_value(L) ncomps_;
mln::util::array<scribo::component_info> infos_;
+ mln_ch_value(L, bool) separators_;
};
} // end of namespace scribo::internal
@@ -131,13 +142,6 @@ namespace scribo
/// Return component information for a given component id \p id.
component_info& info(const mln_value(L)& id);
-// /// Return component information for a given component id \p id.
-// component_info& operator()(const mln_value(L)& id);
-
-// /// Return component information for a given component id \p id.
-// const component_info& operator()(const mln_value(L)& id) const;
-
-
/// Return component information for a given component id \p id.
component_info& operator()(const component_id_t& id);
@@ -155,12 +159,38 @@ namespace scribo
/// Return the underlying labeled image
const L& labeled_image() const;
+ /// Is this component set valid?
+ bool is_valid() const;
+
+
+ /// Separators components related routines.
+ /// @{
+
+ /// Return true if an image of separator exists.
+ bool has_separators() const;
+
+ /// Add separators in the underlying labeled image.
+ void add_separators(const mln_ch_value(L, bool)& ima);
+
+ /// Return the Boolean image of separators.
+ const mln_ch_value(L, bool)& separators() const;
+
+ /// Remove any existing separators.
+ void clear_separators();
+
+ /// @}
+
+
+
/// Internal methods
/// @{
/// Return all the component infos.
const mln::util::array<scribo::component_info>& infos_() const;
+ /// Unique set Id.
+ unsigned id_() const;
+
/// @}
private:
@@ -171,6 +201,18 @@ namespace scribo
};
+ template <typename L>
+ bool
+ operator==(const component_set<L>& lhs, const component_set<L>& rhs);
+
+
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const component_set<L>& info);
+
+
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -195,6 +237,9 @@ namespace scribo
const mln_value(L)& ncomps)
: ima_(ima), ncomps_(ncomps)
{
+ initialize(separators_, ima); // FIXME: do we really want that?
+ mln::data::fill(separators_, false);
+
typedef mln::accu::shape::bbox<mln_site(L)> bbox_accu_t;
typedef mln::accu::center<mln_site(L)> center_accu_t;
typedef mln::accu::pair<bbox_accu_t, center_accu_t> pair_accu_t;
@@ -214,6 +259,9 @@ namespace scribo
const mln::util::array<pair_accu_t>& attribs)
: ima_(ima), ncomps_(ncomps)
{
+ initialize(separators_, ima); // FIXME: do we really want that?
+ mln::data::fill(separators_, false);
+
fill_infos(attribs);
}
@@ -224,6 +272,9 @@ namespace scribo
const mln::util::array<pair_data_t>& attribs)
: ima_(ima), ncomps_(ncomps)
{
+ initialize(separators_, ima); // FIXME: do we really want that?
+ mln::data::fill(separators_, false);
+
fill_infos(attribs);
}
@@ -234,6 +285,8 @@ namespace scribo
const mln::util::array<scribo::component_info>& infos)
: ima_(ima), ncomps_(ncomps), infos_(infos)
{
+ initialize(separators_, ima); // FIXME: do we really want that?
+ mln::data::fill(separators_, false);
}
@@ -247,7 +300,7 @@ namespace scribo
infos_.reserve(static_cast<unsigned>(ncomps_) + 1);
infos_.append(component_info()); // Component 0, i.e. the background.
- for_all_components(i, attribs)
+ for_all_comp_data(i, attribs)
{
component_info info(i, attribs[i].first(),
attribs[i].second(), attribs[i].second_accu().nsites());
@@ -265,7 +318,7 @@ namespace scribo
infos_.reserve(static_cast<unsigned>(ncomps_) + 1);
infos_.append(component_info()); // Component 0, i.e. the background.
- for_all_components(i, attribs)
+ for_all_comp_data(i, attribs)
{
component_info info(i, attribs[i].first,
attribs[i].second.first, attribs[i].second.second);
@@ -379,7 +432,7 @@ namespace scribo
{
const F& f = exact(f_);
- for_all_components(i, data_->infos_)
+ for_all_comp_data(i, data_->infos_)
if (!f(i))
data_->infos_[i].update_tag(tag);
}
@@ -405,6 +458,61 @@ namespace scribo
return this->data_->ima_;
}
+
+ template <typename L>
+ inline
+ bool
+ component_set<L>::is_valid() const
+ {
+ return this->data_->ima_.is_valid();
+ }
+
+
+ template <typename L>
+ inline
+ unsigned
+ component_set<L>::id_() const
+ {
+ return (unsigned)data_.ptr_;
+ }
+
+
+ template <typename L>
+ inline
+ bool
+ component_set<L>::has_separators() const
+ {
+ return this->data_->separators_.is_valid();
+ }
+
+
+ template <typename L>
+ inline
+ void
+ component_set<L>::add_separators(const mln_ch_value(L, bool)& ima)
+ {
+ this->data_->separators_ = ima;
+ }
+
+
+ template <typename L>
+ inline
+ const mln_ch_value(L, bool)&
+ component_set<L>::separators() const
+ {
+ return this->data_->separators_;
+ }
+
+
+ template <typename L>
+ inline
+ void
+ component_set<L>::clear_separators()
+ {
+ this->data_->separators_.destroy();
+ }
+
+
template <typename L>
inline
const mln::util::array<scribo::component_info>&
@@ -419,12 +527,32 @@ namespace scribo
component_set<L>::init_(const component_set<L>& set)
{
data_ = new internal::component_set_data<L>();
- data_->ima_ = set.labeled_image();
+ data_->ima_ = mln::duplicate(set.labeled_image());
data_->ncomps_ = set.nelements();
data_->infos_ = set.infos_();
+ data_->separators_ = set.separators();
}
+ template <typename L>
+ bool
+ operator==(const component_set<L>& lhs, const component_set<L>& rhs)
+ {
+ return lhs.id_() == rhs.id_();
+ }
+
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const component_set<L>& info)
+ {
+ ostr << "component_set[" << std::endl;
+ for_all_comps(i, info)
+ ostr << info(i);
+ ostr << "]" << std::endl;
+
+ return ostr;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo
diff --git a/scribo/core/line_info.hh b/scribo/core/line_info.hh
index 42438b0..0445f85 100644
--- a/scribo/core/line_info.hh
+++ b/scribo/core/line_info.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -29,6 +30,9 @@
/// \file
///
/// \brief Line information data structure.
+///
+/// \fixme The meanline should not be stored! The user can deduce it
+/// from the x_height and the baseline.
# include <mln/core/alias/box2d.hh>
@@ -40,13 +44,15 @@
# include <scribo/core/tag/component.hh>
# include <scribo/core/tag/line.hh>
-// # include <scribo/filter/object_links_bottom_aligned.hh>
-// # include <scribo/filter/object_links_top_aligned.hh>
-
+# include <scribo/core/line_set.hh>
+# include <scribo/core/component_set.hh>
namespace scribo
{
+ // Forward declarations.
+ template <typename L> class line_set;
+
typedef mln::util::object_id<scribo::LineId, unsigned> line_id_t;
template <typename L>
@@ -56,18 +62,26 @@ namespace scribo
typedef mln::util::object_id<scribo::LineId, unsigned> line_id_t;
public:
+
+ /// Constructors
+ /// @{
+
line_info();
- line_info(const line_id_t& id,
- const mln::box2d& bbox,
- const mln::util::array<component_id_t>& comps,
- unsigned absolute_median,
- unsigned absolute_baseline,
- unsigned char_space,
- unsigned char_width);
- line_info(const object_links<L>& links,
+
+ line_info(const line_set<L>& holder,
const line_id_t& id,
const mln::util::array<component_id_t>& comps);
+ /// The line id of the target instance is preserved if it is valid.
+ line_info(const line_info<L>& other);
+ /// @}
+
+ /// The line id of the target instance is preserved if it is valid.
+ line_info<L>& operator=(const line_info<L>& other);
+
+ /// If the line info is valid, the line id never changes for a
+ /// given instance.
+ //
line_id_t id() const;
line::Tag tag() const;
@@ -75,12 +89,21 @@ namespace scribo
const mln::box2d& bbox() const;
+ /// Extended bounding box.
+ /// The width is extended with char_width() + char_space() on each side.
+ /// The height is adjusted to max(a_height, - d_height) on each side.
+ //
+ const mln::box2d& ebbox() const;
+
const mln::util::array<component_id_t>& components() const;
unsigned card() const;
- unsigned baseline() const;
- unsigned median() const;
- int x_height() const;
+ int baseline() const;
+ int meanline() const;
+ int ascent() const;
+ int descent() const;
+
+ unsigned x_height() const;
int d_height() const;
int a_height() const;
@@ -90,7 +113,10 @@ namespace scribo
unsigned word_space() const;
line::ReadingDirection reading_direction() const;
+
line::Type type() const;
+ void update_type(line::Type type);
+
bool reverse_video() const;
float orientation() const;
@@ -101,6 +127,15 @@ namespace scribo
bool is_valid() const;
+ /// Hidden status.
+ ///
+ /// When a line is hidden, it should not be used in routines
+ /// computing data over lines.
+ ///
+ /// @{
+ bool hidden() const;
+ void set_hidden(bool b);
+ /// @}
/// Merge related routines.
/// @{
@@ -109,15 +144,18 @@ namespace scribo
///
/// After this merge, the line is tagged with
/// line::Needs_Precise_Stats_Update.
+ ///
+ /// The \p other line is tagged with line::Merged and if \p hide
+ /// is set to 'True', it is set as hidden as well.
//
- void fast_merge(line_info<L>& other);
+ void fast_merge(line_info<L>& other, bool hide = true);
/// This merge updates the component list and recompute from
/// scratch statistics, bounding box and other line attributes.
///
/// After this merge, the line is tagged with line::None.
//
- void precise_merge(line_info<L>& other);
+ void precise_merge(line_info<L>& other, bool hide = true);
/// @}
@@ -126,21 +164,49 @@ namespace scribo
void force_stats_update();
- private:
+ /// Returns the line set holding this element.
+ const line_set<L>& holder() const;
+
+ /// Returns the delta used to compute the extended bbox.
+ int delta_of_line() const;
+
+ private: // Members
+ void copy_data(const line_info<L>& other);
+
+ /// Enlarge the width of a given bbox \p b with a \p delta.
+ mln::box2d enlarge(const mln::box2d& b, int delta) const;
+
+ /// Update bbox and ebbox_ attributes.
+ void update_bbox_and_ebox(line_info<L>& other);
+
+ /// Update the extended bbox.
+ void update_ebbox();
+
+ mln::box2d merged_ebbox(const scribo::line_info<L>& info_l,
+ const scribo::line_info<L>& info);
+
+ void update_components_type(component::Type type);
+
+ private: // Attributes
+ // WARNING: NEVER FORGET TO UPDATE COPY CONSTRUCTOR REDEFINITION!!!!
+
line_id_t id_;
+ bool hidden_;
line::Tag tag_;
mln::box2d bbox_;
+ mln::box2d ebbox_;
mln::util::array<component_id_t> components_;
- // Value relative to the line bbox.
- unsigned baseline_;
- unsigned median_;
+ // Values relative to the line bbox.
+ int baseline_;
+ int meanline_;
// Values relative to the baseline.
- int x_height_;
+ unsigned x_height_;
int d_height_;
int a_height_;
+ // WARNING: NEVER FORGET TO UPDATE COPY CONSTRUCTOR REDEFINITION!!!!
// Character related stats.
unsigned char_space_;
@@ -166,8 +232,10 @@ namespace scribo
bool indented_;
- // Related object links information.
- const object_links<L>* links_;
+ // Line set holding this element.
+ line_set<L> holder_;
+
+ // WARNING: NEVER FORGET TO UPDATE COPY CONSTRUCTOR REDEFINITION!!!!
};
@@ -181,66 +249,111 @@ namespace scribo
template <typename L>
line_info<L>::line_info()
- : id_(0)
+ : id_(0), hidden_(false)
{
}
+ template <typename L>
+ inline
+ void
+ line_info<L>::copy_data(const line_info<L>& other)
+ {
+ // Id MUST NOT change except if this instance have no id.
+ if (! is_valid())
+ {
+ id_ = other.id();
+ hidden_ = other.hidden_;
+ }
+
+ tag_ = other.tag();
+ bbox_ = other.bbox();
+ ebbox_ = other.ebbox();
+ components_ = other.components();
+
+ baseline_ = other.baseline();
+ meanline_ = other.meanline();
+
+ x_height_ = other.x_height();
+ d_height_ = other.d_height();
+ a_height_ = other.a_height();
+
+ char_space_ = other.char_space();
+ char_width_ = other.char_width();
+
+ word_space_ = other.word_space();
+
+ reading_direction_ = other.reading_direction();
+
+ type_ = other.type();
+
+ reverse_video_ = other.reverse_video();
+
+ orientation_ = other.orientation();
+
+ reading_orientation_ = other.reading_orientation();
+
+ indented_ = other.indented();
+
+ holder_ = other.holder();
+ }
+
+ template <typename L>
+ inline
+ line_info<L>::line_info(const line_info<L>& other)
+ : id_(0), hidden_(false)
+ {
+ copy_data(other);
+ }
+
/*!
Exemple:
- ---------------------
- | | | |x| | | | | | | ----> a_height = 4
- ---------------------
- | | | |x| | | | | | |
- ---------------------
- | |x|x|x| | |x|x|x| | ----> Median = 2 ^
- --------------------- |
- | |x| |x| | |x| |x| | | x_height = 3
- --------------------- |
- | |x|x|x| | |x|x|x| | ----> Baseline = 4 v
- ---------------------
- | | | | | | |x| | | |
- ---------------------
- | | | | | | |x| | | | ----> d_height = -2
- ---------------------
-
- All the metrics are computed relatively to the Baseline.
-
- The baseline is defined as an absolute row index.
+ \verbatim
+
+ 0 1 2 3 4 5 6 7 8 9
+ ---------------------
+ 0 | | | |x| | | | | | | ----> a_height = 4
+ ---------------------
+ 1 | | | |x| | | | | | |
+ ---------------------
+ 2 | |x|x|x| | |x|x|x| | ----> Meanline = 2 ^
+ --------------------- |
+ 3 | |x| |x| | |x| |x| | | x_height = 3
+ --------------------- |
+ 4 | |x|x|x| | |x|x|x| | ----> Baseline = 4 v
+ ---------------------
+ 5 | | | | | | |x| | | |
+ ---------------------
+ 6 | | | | | | |x| | | | ----> d_height = -2
+ ---------------------
+
+ \endverbatim
+
+ The baseline, the meanline, the ascent and the descent are defined
+ as an absolute row index.
+
+ All other metrics, such as x_height, are computed relatively to
+ the Baseline.
*/
template <typename L>
- line_info<L>::line_info(const object_links<L>& links,
+ line_info<L>::line_info(const line_set<L>& holder,
const line_id_t& id,
const mln::util::array<component_id_t>& comps)
- : id_(id), tag_(line::None), components_(comps), links_(&links)
+ : id_(id), hidden_(false), tag_(line::None), components_(comps),
+ type_(line::Undefined), holder_(holder)
{
- force_stats_update();
-
-
-// typedef mln_site(L) P;
-// const component_set<L>& comp_set = links_->component_set_();
-// mln::accu::shape::bbox<P> bbox;
-// for_all_elements(i, components_)
-// {
-// unsigned c = components_(i);
-// const box2d& bb = comp_set(c).bbox();
-// // Bounding box.
-// bbox.take(bb);
-// }
-// bbox_ = bbox.to_result();
-
-
+ force_stats_update();
- // FIXME: set valid information for these attributes.
+ // FIXME: set valid information for these attributes in
+ // force_stats_update.
word_space_ = 0;
reading_direction_ = line::LeftToRight;
- type_ = line::Paragraph;
reverse_video_ = false;
orientation_ = 0.;
@@ -251,12 +364,22 @@ namespace scribo
template <typename L>
+ inline
+ line_info<L>&
+ line_info<L>::operator=(const line_info<L>& other)
+ {
+ copy_data(other);
+ return *this;
+ }
+
+ template <typename L>
typename line_info<L>::line_id_t
line_info<L>::id() const
{
return id_;
}
+
template <typename L>
line::Tag
line_info<L>::tag() const
@@ -280,6 +403,13 @@ namespace scribo
return bbox_;
}
+ template <typename L>
+ const mln::box2d&
+ line_info<L>::ebbox() const
+ {
+ return ebbox_;
+ }
+
template <typename L>
const mln::util::array<typename line_info<L>::component_id_t>&
@@ -297,7 +427,7 @@ namespace scribo
template <typename L>
- unsigned
+ int
line_info<L>::baseline() const
{
return baseline_;
@@ -305,14 +435,31 @@ namespace scribo
template <typename L>
- unsigned
- line_info<L>::median() const
+ int
+ line_info<L>::meanline() const
{
- return median_;
+ return meanline_;
}
+
template <typename L>
int
+ line_info<L>::ascent() const
+ {
+ return baseline_ - a_height() + 1;
+ }
+
+
+ template <typename L>
+ int
+ line_info<L>::descent() const
+ {
+ return baseline_ - d_height() + 1;
+ }
+
+
+ template <typename L>
+ unsigned
line_info<L>::x_height() const
{
return x_height_;
@@ -375,6 +522,32 @@ namespace scribo
template <typename L>
+ void
+ line_info<L>::update_components_type(component::Type type)
+ {
+ for_all_elements(i, components_)
+ {
+ unsigned c = components_[i];
+ holder_.components_()(c).update_type(type);
+ }
+ }
+
+
+ template <typename L>
+ void
+ line_info<L>::update_type(line::Type type)
+ {
+ type_ = type;
+
+ // Some line types may involve updating components type as well.
+ if (type == line::Punctuation)
+ update_components_type(component::Punctuation);
+ else if (type == line::Text)
+ update_components_type(component::Character);
+ }
+
+
+ template <typename L>
bool
line_info<L>::reverse_video() const
{
@@ -415,22 +588,170 @@ namespace scribo
template <typename L>
+ bool
+ line_info<L>::hidden() const
+ {
+ return hidden_;
+ }
+
+
+ template <typename L>
void
- line_info<L>::fast_merge(line_info<L>& other)
+ line_info<L>::set_hidden(bool b)
+ {
+ hidden_ = b;
+ }
+
+
+ template <typename L>
+ inline
+ int
+ line_info<L>::delta_of_line() const
+ {
+ return char_width() + 2 * char_space();
+ // FIXME: choose between:
+ // not enough: char_width + char_space
+ // too much: 2 * char_width
+ // looks good: char_width + 2 * char_space
+ }
+
+
+ template <typename L>
+ mln::box2d
+ line_info<L>::enlarge(const mln::box2d& b, int delta) const
+ {
+ mln::box2d b_(mln::point2d(b.pmin().row(), b.pmin().col() - delta),
+ mln::point2d(b.pmax().row(), b.pmax().col() + delta));
+ return b_;
+ }
+
+
+ template <typename L>
+ void
+ line_info<L>::update_ebbox()
+ {
+ int A = a_height_ - x_height_;
+ int D = - d_height_;
+ if (A <= 2 && D > 2)
+ A = D;
+ if (D <= 2 && A > 2)
+ D = A;
+
+ int delta = delta_of_line();
+
+ ebbox_ = mln::make::box2d(meanline_ - A, bbox().pmin().col() - delta,
+ baseline_ + D, bbox().pmax().col() + delta);
+
+ ebbox_.crop_wrt(holder_.components().labeled_image().domain());
+ }
+
+
+ template <typename L>
+ mln::box2d
+ line_info<L>::merged_ebbox(const scribo::line_info<L>& info_l,
+ const scribo::line_info<L>& info)
+ {
+ // line data
+ int
+ baseline_l = info_l.baseline(),
+ d_height = info_l.d_height();
+ unsigned
+ a_height = info_l.a_height(),
+ x_height = info_l.x_height();
+ int A_l = a_height - x_height;
+ int D_l = - d_height;
+ if (A_l <= 2 && D_l > 2)
+ A_l = D_l;
+ if (D_l <= 2 && A_l > 2)
+ D_l = A_l;
+ unsigned delta_l = info_l.delta_of_line();
+ int meanline_l = info_l.meanline();
+
+ // non-line data
+ unsigned delta_ = info.delta_of_line();
+
+ mln::box2d b = mln::make::box2d(// pmin
+ meanline_l - A_l,
+ std::min(info_l.bbox().pmin().col(), info.bbox().pmin().col()) - std::max(delta_l, delta_),
+ // pmax
+ baseline_l + D_l,
+ std::max(info_l.bbox().pmax().col(), info.bbox().pmax().col()) + std::max(delta_l, delta_));
+
+ return b;
+ }
+
+
+ template <typename L>
+ void
+ line_info<L>::update_bbox_and_ebox(line_info<L>& other)
+ {
+ // Merging ebboxes depending on the type of the line.
+
+ if (type() == line::Text) // /this/ IS a text line
+ {
+ if (other.type() == line::Text) // /other/ IS a text line.
+ {
+ // Adjusting ebboxes with the highest delta and merging ebboxes.
+ int d_delta = other.delta_of_line() - this->delta_of_line();
+ if (d_delta < 0) // other.delta_of_line() < this->delta_of_line()
+ ebbox_.merge(enlarge(other.ebbox(), - d_delta));
+ else
+ {
+ mln::box2d b = ebbox_;
+ ebbox_ = other.bbox();
+ ebbox_.merge(enlarge(b, d_delta));
+ }
+
+ ebbox_.crop_wrt(holder_.components().labeled_image().domain());
+ }
+ else // /other/ IS NOT a text line.
+ {
+ ebbox_.merge(other.ebbox());
+ ebbox_.merge(merged_ebbox(*this, other));
+ }
+ }
+ else // /this/ is NOT a text line
+ {
+ if (other.type() != line::Text)
+ {
+ std::cerr << "error in 'line_info::update_bbox_and_ebox':"
+ << "Merging two non text lines." << std::endl;
+ std::abort();
+ }
+
+ update_type(line::Text);
+ ebbox_.merge(other.ebbox());
+ ebbox_.merge(merged_ebbox(other, *this));
+ }
+
+ // Merging bboxes.
+ bbox_.merge(other.bbox());
+
+ // Make sure the ebbox is included in the image domain.
+ ebbox_.crop_wrt(holder_.components().labeled_image().domain());
+ }
+
+
+ template <typename L>
+ void
+ line_info<L>::fast_merge(line_info<L>& other, bool hide)
{
tag_ = line::Needs_Precise_Stats_Update;
other.update_tag(line::Merged);
+ other.set_hidden(hide);
+
+ // Update bbox and ebbox
+ update_bbox_and_ebox(other);
- bbox_.merge(other.bbox());
components_.append(other.components());
}
template <typename L>
void
- line_info<L>::precise_merge(line_info<L>& other)
+ line_info<L>::precise_merge(line_info<L>& other, bool hide)
{
- fast_merge(other);
+ fast_merge(other, hide);
force_stats_update();
}
@@ -439,7 +760,7 @@ namespace scribo
line_info<L>::force_stats_update()
{
typedef mln_site(L) P;
- const component_set<L>& comp_set = links_->component_set_();
+ const component_set<L>& comp_set = holder_.components();
// FIXME: int_u<12> may not be enought but we can't use unsigned
// or any other larger types since there is no median
@@ -449,7 +770,7 @@ namespace scribo
typedef mln::value::int_u<12> median_data_t;
typedef mln::accu::stat::median_h<median_data_t> median_t;
median_t
- absolute_median,
+ absolute_meanline,
absolute_baseline,
char_space,
char_width;
@@ -460,11 +781,22 @@ namespace scribo
{
unsigned c = components_(i);
- const box2d& bb = comp_set(c).bbox();
+ const mln::box2d& bb = comp_set(c).bbox();
+
+ // Bounding box.
+ bbox.take(bb);
+
+ // Ignore punctuation for stats computation but not for bbox
+ // computation.
+ if (holder_.components()(c).type() == component::Punctuation)
+ continue;
+
+
// Space between characters.
int space = bb.pmin().col()
- - comp_set((*links_)[c]).bbox().pmax().col();
+ - comp_set(holder_.links()(c)).bbox().pmax().col();
+
// -- Ignore overlapped characters.
if (space > 0)
char_space.take(space);
@@ -474,16 +806,13 @@ namespace scribo
if (bb.width() <= 1000)
char_width.take(bb.width());
- // Median (compute an absolute value, from the top left
+ // Meanline (compute an absolute value, from the top left
// corner of the image).
- absolute_median.take(bb.pmin().row());
+ absolute_meanline.take(bb.pmin().row());
// Baseline (compute an absolute value, from the top left
// corner of the image).
absolute_baseline.take(bb.pmax().row());
-
- // Bounding box.
- bbox.take(bb);
}
// Finalization
@@ -492,7 +821,7 @@ namespace scribo
bbox_ = bbox.to_result();
// Char space
- if (card() == 1)
+ if (char_space.card() < 2)
char_space_ = 0;
else
char_space_ = char_space.to_result();
@@ -506,21 +835,31 @@ namespace scribo
baseline_ = absolute_baseline.to_result();
- median_ = absolute_baseline - absolute_median;
- x_height_ = absolute_baseline - absolute_median + 1;
- d_height_ = absolute_baseline - bbox.to_result().pmax().row();
+ meanline_ = absolute_meanline.to_result();
+ x_height_ = absolute_baseline - absolute_meanline + 1;
+ d_height_ = absolute_baseline - bbox.to_result().pmax().row() + 1;
a_height_ = absolute_baseline - bbox.to_result().pmin().row() + 1;
//FIXME
//
//word_space_ = ...;
//reading_direction_ = ...;
- //type_ = ...;
//reverse_video_ = ...;
//orientation_ = ...;
//reading_orientation_ = ...;
//indented_ = ...;
+
+ update_ebbox();
}
+
+ }
+
+
+ template <typename L>
+ const line_set<L>&
+ line_info<L>::holder() const
+ {
+ return holder_;
}
@@ -531,10 +870,14 @@ namespace scribo
return ostr << "line_info("
<< "id=" << info.id()
<< ", tag=" << info.tag()
+ << ", type=" << info.type()
<< ", bbox=" << info.bbox()
+ << ", ebbox=" << info.ebbox()
<< ", components=" << info.components()
<< ", baseline=" << info.baseline()
- << ", median=" << info.median()
+ << ", meanline=" << info.meanline()
+ << ", ascent=" << info.ascent()
+ << ", descent=" << info.descent()
<< ", x_height=" << info.x_height()
<< ", d_height=" << info.d_height()
<< ", a_height=" << info.a_height()
diff --git a/scribo/core/line_set.hh b/scribo/core/line_set.hh
index 2d846f0..80a79b3 100644
--- a/scribo/core/line_set.hh
+++ b/scribo/core/line_set.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -46,7 +47,9 @@
# include <scribo/core/macros.hh>
# include <scribo/core/line_info.hh>
-# include <scribo/core/line_stats_extra.hh>
+
+# include <scribo/core/object_links.hh>
+# include <scribo/core/object_groups.hh>
namespace scribo
@@ -63,17 +66,24 @@ namespace scribo
struct line_set_data
{
line_set_data();
+ line_set_data(const object_groups<L>& comp_set);
line_set_data(const mln::util::array<scribo::line_info<L> >& infos,
- const component_set<L>& comp_set);
+ const object_groups<L>& comp_set);
mln::util::array<scribo::line_info<L> > infos_;
- component_set<L> comp_set_;
+ component_set<L> components_;
+ object_links<L> links_;
+ object_groups<L> groups_;
};
} // end of namespace scribo::internal
+ /*! \brief Lines container.
+
+ Line ids start from 1.
+ */
template <typename L>
class line_set
{
@@ -85,12 +95,11 @@ namespace scribo
line_set();
/// Constructor from object groups.
- line_set(const object_links<L>& links, const object_groups<L>& groups);
+ line_set(const object_groups<L>& groups);
/// @}
/// Compute line stats and fill the underlying information.
- void compute_lines(const object_links<L>& links,
- const object_groups<L>& groups);
+ void compute_lines(const object_groups<L>& groups);
/// Return the line count.
mln_value(L) nelements() const;
@@ -115,7 +124,24 @@ namespace scribo
line_set<L> duplicate() const;
/// Return the underlying component set.
- const component_set<L>& component_set_() const;
+ const component_set<L>& components() const;
+
+ /// Return the underlying component set (non-const version).
+ component_set<L>& components_();
+
+ /// Return the underlying component group.
+ const object_groups<L>& groups() const;
+
+ /// Return the underlying links.
+ const object_links<L>& links() const;
+
+
+ /// Massive line computation
+ /// @{
+
+ void force_stats_update();
+
+ /// @}
/// Internal methods
/// @{
@@ -138,8 +164,7 @@ namespace scribo
template <typename L>
scribo::line_set<L>
- line_set(const object_links<L>& links,
- const object_groups<L>& groups);
+ line_set(const object_groups<L>& groups);
} // End of namespace scribo::make
@@ -165,9 +190,19 @@ namespace scribo
template <typename L>
inline
+ line_set_data<L>::line_set_data(const object_groups<L>& groups)
+ : components_(groups.components()), links_(groups.links()),
+ groups_(groups)
+ {
+ }
+
+
+ template <typename L>
+ inline
line_set_data<L>::line_set_data(const mln::util::array<scribo::line_info<L> >& infos,
- const component_set<L>& comp_set)
- : infos_(infos), comp_set_(comp_set)
+ const object_groups<L>& groups)
+ : infos_(infos), components_(groups.components()),
+ links_(groups.links()), groups_(groups)
{
}
@@ -182,28 +217,22 @@ namespace scribo
{
}
+
template <typename L>
inline
- line_set<L>::line_set(const object_links<L>& links,
- const object_groups<L>& groups)
+ line_set<L>::line_set(const object_groups<L>& groups)
{
- compute_lines(links, groups);
+ compute_lines(groups);
}
- // FIXME: groups should have a reference to the links data and we
- // should only required groups as argument.
template <typename L>
-// util::array<line_stats_extra>
void
- line_set<L>::compute_lines(const object_links<L>& links,
- const object_groups<L>& groups)
+ line_set<L>::compute_lines(const object_groups<L>& groups)
{
- data_ = new internal::line_set_data<L>();
+ data_ = new internal::line_set_data<L>(groups);
typedef mln_site(L) P;
- data_->comp_set_ = groups.component_set_();
- const component_set<L>& comp_set = groups.component_set_();
mln_value(L) n_groups = groups.nelements() - 1;
mln::fun::i2v::array<mln_value(L)>
@@ -211,93 +240,32 @@ namespace scribo
n_groups, n_groups);
// FIXME: object_groups should store the relation 'group -> comp'.
- // it would avoid the use of accumulator arrays.
-
- // FIXME: int_u<11> may not be enought but we can't use unsigned
- // or any other larger types since there is no median
- // implementation for high quantification types...
-
- // Init.
-// typedef mln::value::int_u<12> median_data_t;
-// typedef mln::accu::stat::median_h<median_data_t> median_t;
-// util::array<median_t>
-// absolute_median(static_cast<unsigned>(n_groups) + 1),
-// absolute_baseline(static_cast<unsigned>(n_groups) + 1),
-// char_space(static_cast<unsigned>(n_groups) + 1),
-// char_width(static_cast<unsigned>(n_groups) + 1);
-
-// util::array<mln::accu::shape::bbox<P> >
-// bbox(static_cast<unsigned>(n_groups) + 1);
+ mln::util::array< mln::util::array<component_id_t> >
+ group_to_comps(unsigned(n_groups) + 1);
- util::array< util::array<component_id_t> >
- comps(static_cast<unsigned>(n_groups) + 1);
// 1st pass - Compute data.
- for (unsigned i = 1; i < packed_groups.size(); ++i)
- if (comp_set(i).is_valid())
+ for_all_comps(i, data_->components_)
+ if (data_->components_(i).is_valid())
{
unsigned group_id = packed_groups(i);
if (group_id != 0) // Is this component part of a group?
{
-// const box2d& bb = comp_set(i).bbox();
-
-// // Space between characters.
-// int space = bb.pmin().col()
-// - comp_set(links[i]).bbox().pmax().col();
-// // -- Ignore overlapped characters.
-// if (space > 0)
-// char_space(group_id).take(space);
-
-// // Character width
-// // -- Ignore too large components.
-// if (bb.width() <= 1000)
-// char_width(group_id).take(bb.width());
-
-// // Median (compute an absolute value, from the top left
-// // corner of the image).
-// absolute_median(group_id).take(bb.pmin().row());
-
-// // Baseline (compute an absolute value, from the top left
-// // corner of the image).
-// absolute_baseline(group_id).take(bb.pmax().row());
-
-// // Bounding box.
-// bbox(group_id).take(bb);
-
// Component id.
- comps(group_id).append(i);
+ group_to_comps(group_id).append(i);
}
}
// 2nd pass - Store data.
- data_->infos_.reserve(groups.nelements());
+ data_->infos_.reserve(group_to_comps.size());
data_->infos_.append(line_info<L>()); // line with id 0 is invalid.
-// util::array<line_stats_extra> stats_extra;
-// stats_extra.reserve(static_cast<unsigned>(n_groups) + 1);
-// stats_extra.append(line_stats_extra());
-
- for (unsigned i = 1; i <= n_groups; ++i)
+ for_all_groups(i, group_to_comps)
{
-
// Add line info.
- line_info<L> info(links, i, comps(i));
+ line_info<L> info(*this, i, group_to_comps(i));
data_->infos_.append(info);
-
-
- // Prepare extra stats to be returned.
-// line_stats_extra stats(absolute_median(i) * absolute_median(i).card(),
-// absolute_median(i).card(),
-// absolute_baseline(i) * absolute_baseline(i).card(),
-// absolute_baseline(i).card(),
-// char_space(i) * char_space(i).card(),
-// char_space(i).card(),
-// char_width(i) * char_width(i).card(),
-// char_width(i).card());
-// stats_extra.append(stats);
}
-
-// return stats_extra;
}
@@ -351,7 +319,7 @@ namespace scribo
{
const F& f = exact(f_);
- for_all_elements(i, data_->infos_)
+ for_all_lines_info(i, data_->infos_)
if (!f(i))
data_->infos_[i].update_tag(tag);
}
@@ -370,11 +338,44 @@ namespace scribo
template <typename L>
inline
const component_set<L>&
- line_set<L>::component_set_() const
+ line_set<L>::components() const
+ {
+ return data_->components_;
+ }
+
+ template <typename L>
+ inline
+ component_set<L>&
+ line_set<L>::components_()
{
- return data_->comp_set_;
+ return data_->components_;
}
+ template <typename L>
+ inline
+ const object_groups<L>&
+ line_set<L>::groups() const
+ {
+ return data_->groups_;
+ }
+
+ template <typename L>
+ inline
+ const object_links<L>&
+ line_set<L>::links() const
+ {
+ return data_->links_;
+ }
+
+ template <typename L>
+ inline
+ void
+ line_set<L>::force_stats_update()
+ {
+ for_all_lines_info(i, data_->infos_)
+ if (data_->infos_(i).tag() == line::Needs_Precise_Stats_Update)
+ data_->infos_(i).force_stats_update();
+ }
template <typename L>
inline
@@ -389,7 +390,7 @@ namespace scribo
void
line_set<L>::init_(const line_set<L>& set)
{
- data_ = new internal::line_set_data<L>(set.infos_(), set.component_set_());
+ data_ = new internal::line_set_data<L>(set.infos_(), set.groups());
}
@@ -400,27 +401,13 @@ namespace scribo
template <typename L>
scribo::line_set<L>
- line_set(const object_links<L>& links,
- const object_groups<L>& groups)
+ line_set(const object_groups<L>& groups)
{
- mln_precondition(exact(ima).is_valid());
- scribo::line_set<L> tmp(links, groups);
+ mln_precondition(groups.is_valid());
+ scribo::line_set<L> tmp(groups);
return tmp;
}
-
-// template <typename L>
-// scribo::line_set<L>
-// line_set(const object_links<L>& links,
-// const object_groups<L>& groups,
-// util::array<line_stats_extra>& line_stats)
-// {
-// mln_precondition(exact(ima).is_valid());
-// scribo::line_set<L> tmp;
-// line_stats = tmp.compute_lines(links, groups);
-// return tmp;
-// }
-
} // end of namespace scribo::make
diff --git a/scribo/core/macros.hh b/scribo/core/macros.hh
index bf2afde..f644db3 100644
--- a/scribo/core/macros.hh
+++ b/scribo/core/macros.hh
@@ -29,8 +29,8 @@
# define for_all_ncomponents(C, NCOMP) \
for (unsigned C = 1; C <= NCOMP; ++C)
-# define for_all_components(C, S) \
- for (unsigned C = 1; C < S.nelements(); ++C)
+// # define for_all_components(C, S)
+// for (unsigned C = 1; C <= S.nelements(); ++C)
# define for_all_elements(E, S) \
for (unsigned E = 0; E < S.nelements(); ++E)
@@ -43,10 +43,16 @@
# define for_all_comp_data(E, S) \
for (unsigned E = 1; E < S.nelements(); ++E)
+# define for_all_links(E, S) \
+ for_all_comp_data(E, S)
+
+# define for_all_groups(E, S) \
+ for_all_comp_data(E, S)
+
# define for_all_lines(E, S) \
for_all_comps(E, S)
-# define for_all_groups(E, S) \
+# define for_all_lines_info(E, S) \
for_all_comp_data(E, S)
#endif // ! SCRIBO_CORE_MACROS_HH
diff --git a/scribo/core/tag/component.hh b/scribo/core/tag/component.hh
index 7998f08..3c061b3 100644
--- a/scribo/core/tag/component.hh
+++ b/scribo/core/tag/component.hh
@@ -44,11 +44,72 @@ namespace scribo
enum Tag
{
None = 0,
- Separator,
Ignored
};
+ enum Type
+ {
+ Undefined = 0,
+ Character,
+ Separator,
+ Noise,
+ Punctuation
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ std::ostream&
+ operator<<(std::ostream& ostr, const Tag& tag)
+ {
+ std::string str;
+ switch(tag)
+ {
+ default:
+ case None:
+ str = "None";
+ break;
+ case Ignored:
+ str = "Ignored";
+ break;
+ }
+
+ return ostr << str;
+ }
+
+
+ std::ostream&
+ operator<<(std::ostream& ostr, const Type& type)
+ {
+ std::string str;
+ switch(type)
+ {
+ default:
+ case Undefined:
+ str = "Undefined";
+ break;
+ case Character:
+ str = "Character";
+ break;
+ case Separator:
+ str = "Separator";
+ break;
+ case Noise:
+ str = "Noise";
+ break;
+ case Punctuation:
+ str = "Punctuation";
+ break;
+ }
+
+ return ostr << str;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
} // end of namespace scribo::component
} // end of namespace scribo
diff --git a/scribo/core/tag/line.hh b/scribo/core/tag/line.hh
index 383e331..f571188 100644
--- a/scribo/core/tag/line.hh
+++ b/scribo/core/tag/line.hh
@@ -43,7 +43,6 @@ namespace scribo
enum Tag
{
None = 0,
- Separator,
Ignored,
Needs_Precise_Stats_Update,
Merged,
@@ -77,7 +76,12 @@ namespace scribo
Header,
Heading,
PageNumber,
- Paragraph
+ Paragraph,
+
+ // These types are not supported by the XSD.
+ Punctuation,
+ Text,
+ Undefined
};
@@ -104,9 +108,6 @@ namespace scribo
case None:
str = "None";
break;
- case Separator:
- str = "Separator";
- break;
case Ignored:
str = "Ignored";
break;
@@ -160,7 +161,6 @@ namespace scribo
case Caption:
str = "caption";
break;
- default:
case Credit:
str = "credit";
break;
@@ -169,17 +169,34 @@ namespace scribo
break;
case Floating:
str = "floating";
+ break;
case Footer:
str = "footer";
+ break;
case Header:
str = "header";
+ break;
case Heading:
str = "heading";
+ break;
case PageNumber:
str = "page-number";
+ break;
case Paragraph:
str = "paragraph";
break;
+
+ // Values unsupported by the XSD
+ case Punctuation:
+ str = "punctuation";
+ break;
+ case Text:
+ str = "text";
+ break;
+ default:
+ case Undefined:
+ str = "undefined";
+ break;
}
return ostr << str;
--
1.5.6.5
1
0
last-svn-commit-54-g83e3ae6 Share internal data in groups and links structures.
by Guillaume Lazzara 09 Mar '10
by Guillaume Lazzara 09 Mar '10
09 Mar '10
* core/object_groups.hh,
* core/object_links.hh: Share internal data using a tracked
pointer.
---
scribo/ChangeLog | 8 +++
scribo/core/object_groups.hh | 135 ++++++++++++++++++++++++++++++++----------
scribo/core/object_links.hh | 129 +++++++++++++++++++++++++++++++++++-----
3 files changed, 224 insertions(+), 48 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index ee26d66..2c2f0c2 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,11 @@
+2010-03-09 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Share internal data in groups and links structures.
+
+ * core/object_groups.hh,
+ * core/object_links.hh: Share internal data using a tracked
+ pointer.
+
2010-03-02 Guillaume Lazzara <z(a)lrde.epita.fr>
* text/merging.hh (scribo): Update code with lastest Theo's
diff --git a/scribo/core/object_groups.hh b/scribo/core/object_groups.hh
index 6f49bcf..35c5b34 100644
--- a/scribo/core/object_groups.hh
+++ b/scribo/core/object_groups.hh
@@ -30,8 +30,6 @@
/// \file
///
/// \brief Object groups representation.
-///
-/// \fixme Should not inherit from util::array.
# include <mln/util/array.hh>
@@ -44,21 +42,44 @@ namespace scribo
using namespace mln;
+ // Forward declaration.
+ template <typename L> class object_groups;
+
+
+ namespace internal
+ {
+ /// Data structure for \c scribo::object_groups<I>.
+ template <typename L>
+ struct object_groups_data
+ {
+ object_groups_data();
+ object_groups_data(const object_links<L>& links);
+ object_groups_data(const object_links<L>& links, unsigned value);
+
+ mln::util::array<unsigned> comp_to_group_;
+ component_set<L> components_;
+ object_links<L> links_;
+ };
+
+ } // end of namespace scribo::internal
+
+
+
+
/// \brief Object group representation.
//
template <typename L>
class object_groups
- // : public mln::util::array<unsigned>
{
-// typedef mln::util::array<unsigned> super_t;
+ typedef internal::object_groups_data<L> data_t;
public:
object_groups();
- object_groups(const component_set<L>& components);
- object_groups(const component_set<L>& components,
- unsigned value);
+ object_groups(const object_links<L>& links);
+ object_groups(const object_links<L>& links, unsigned value);
- const component_set<L>& component_set_() const;
+ const component_set<L>& components() const;
+ const object_links<L>& links() const;
void init_(const object_links<L>& links);
@@ -69,68 +90,102 @@ namespace scribo
unsigned& operator()(unsigned comp_id);
const unsigned& operator()(unsigned comp_id) const;
- const util::array<unsigned>& comp_to_group() const;
+ const mln::util::array<unsigned>& comp_to_group() const;
private:
- mln::util::array<unsigned> comp_to_group_;
- component_set<L> components_;
+ mln::util::tracked_ptr<data_t> data_;
};
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const object_groups<L>& groups);
+
+
# ifndef MLN_INCLUDE_ONLY
+ namespace internal
+ {
+
+
+ /// Data structure for \c scribo::object_groups<I>.
+ template <typename L>
+ object_groups_data<L>::object_groups_data()
+ {
+ }
+
+
+ template <typename L>
+ object_groups_data<L>::object_groups_data(const object_links<L>& links)
+ : comp_to_group_(unsigned(links.nelements()) + 1),
+ components_(links.components()), links_(links)
+ {
+ };
+
+
+ template <typename L>
+ object_groups_data<L>::object_groups_data(const object_links<L>& links,
+ unsigned value)
+ : comp_to_group_(unsigned(links.nelements() + 1), value),
+ components_(links.components()), links_(links)
+ {
+ };
+
+
+ } // end of namespace scribo::internal
+
+
template <typename L>
object_groups<L>::object_groups()
{
}
template <typename L>
- object_groups<L>::object_groups(const component_set<L>& components)
- // : super_t(static_cast<unsigned>(components.nelements()) + 1),
- : comp_to_group_(static_cast<unsigned>(components.nelements()) + 1),
- components_(components)
+ object_groups<L>::object_groups(const object_links<L>& links)
{
-
+ data_ = new data_t(links);
}
template <typename L>
- object_groups<L>::object_groups(const component_set<L>& components,
- unsigned value)
- // : super_t(static_cast<unsigned>(components.nelements()) + 1, value),
- : comp_to_group_(static_cast<unsigned>(components.nelements()) + 1),
- components_(components)
+ object_groups<L>::object_groups(const object_links<L>& links, unsigned value)
{
-
+ data_ = new data_t(links, value);
}
template <typename L>
const component_set<L>&
- object_groups<L>::component_set_() const
+ object_groups<L>::components() const
{
- return components_;
+ return data_->components_;
}
+ template <typename L>
+ const object_links<L>&
+ object_groups<L>::links() const
+ {
+ return data_->links_;
+ }
template <typename L>
void
object_groups<L>::init_(const object_links<L>& links)
{
- components_ = links.component_set_();
- comp_to_group_.hook_std_vector_() = links.std_vector();
+ data_->comp_to_group_ = links.comp_to_link();
}
template <typename L>
bool
object_groups<L>::is_valid() const
{
- return components_.is_valid() && components_.nelements() == (this->size() - 1);
+ mln_assertion(data_->components_.nelements() == (nelements() - 1));
+ return data_->links_.is_valid();
}
template <typename L>
unsigned
object_groups<L>::nelements() const
{
- return comp_to_group_.nelements();
+ return data_->comp_to_group_.nelements();
}
@@ -138,7 +193,7 @@ namespace scribo
unsigned&
object_groups<L>::operator()(unsigned comp_id)
{
- return comp_to_group_(comp_id);
+ return data_->comp_to_group_(comp_id);
}
@@ -146,16 +201,32 @@ namespace scribo
const unsigned&
object_groups<L>::operator()(unsigned comp_id) const
{
- return comp_to_group_(comp_id);
+ return data_->comp_to_group_(comp_id);
}
template <typename L>
- const util::array<unsigned>&
+ const mln::util::array<unsigned>&
object_groups<L>::comp_to_group() const
{
- return comp_to_group_;
+ return data_->comp_to_group_;
}
+
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const object_groups<L>& groups)
+ {
+ ostr << "object_groups[";
+
+ for_all_groups(g, groups)
+ ostr << g << "->" << groups.comp_to_group()[g] << ", ";
+
+ ostr << "]";
+
+ return ostr;
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/core/object_links.hh b/scribo/core/object_links.hh
index af6a3da..654cb75 100644
--- a/scribo/core/object_links.hh
+++ b/scribo/core/object_links.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -29,10 +30,10 @@
/// \file
///
/// \brief Object links representation.
-///
-/// \fixme Should not inherit from util::array.
+
# include <mln/util/array.hh>
+# include <mln/util/tracked_ptr.hh>
# include <scribo/core/component_set.hh>
@@ -42,58 +43,121 @@ namespace scribo
using namespace mln;
+ // Forward declaration.
+ template <typename L> class object_links;
+
+
+ namespace internal
+ {
+ /// Data structure for \c scribo::object_links<I>.
+ template <typename L>
+ struct object_links_data
+ {
+ object_links_data();
+ object_links_data(const component_set<L>& components, unsigned size);
+ object_links_data(const component_set<L>& components,
+ unsigned size, unsigned value);
+
+ mln::util::array<unsigned> comp_to_link_;
+ component_set<L> components_;
+ };
+
+ } // end of namespace scribo::internal
+
+
+
+
/// \brief Object group representation.
//
template <typename L>
class object_links
- : public mln::util::array<unsigned>
{
- typedef mln::util::array<unsigned> super_t;
+ typedef internal::object_links_data<L> data_t;
public:
object_links();
object_links(const component_set<L>& components);
object_links(const component_set<L>& components, unsigned value);
- const component_set<L>& component_set_() const;
+ const component_set<L>& components() const;
bool is_valid() const;
+ unsigned nelements() const;
+
+ unsigned& operator()(unsigned comp_id);
+ const unsigned& operator()(unsigned comp_id) const;
+
+ const mln::util::array<unsigned>& comp_to_link() const;
+
+
private:
- component_set<L> components_;
+ mln::util::tracked_ptr<data_t> data_;
};
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+
+ /// Data structure for \c scribo::object_links<I>.
+ template <typename L>
+ object_links_data<L>::object_links_data()
+ {
+ }
+
+
+ template <typename L>
+ object_links_data<L>::object_links_data(const component_set<L>& components,
+ unsigned size)
+ : comp_to_link_(size), components_(components)
+ {
+ };
+
+
+ template <typename L>
+ object_links_data<L>::object_links_data(const component_set<L>& components,
+ unsigned size, unsigned value)
+ : comp_to_link_(size, value), components_(components)
+ {
+ };
+
+
+ } // end of namespace scribo::internal
+
+
+
template <typename L>
object_links<L>::object_links()
{
+ data_ = new data_t();
}
+
template <typename L>
object_links<L>::object_links(const component_set<L>& components)
- : super_t(static_cast<unsigned>(components.nelements()) + 1),
- components_(components)
{
-
+ data_ = new data_t(components, unsigned(components.nelements()) + 1);
}
+
template <typename L>
object_links<L>::object_links(const component_set<L>& components,
unsigned value)
- : super_t(static_cast<unsigned>(components.nelements()) + 1, value),
- components_(components)
{
-
+ data_ = new data_t(components, unsigned(components.nelements()) + 1,
+ value);
}
template <typename L>
const component_set<L>&
- object_links<L>::component_set_() const
+ object_links<L>::components() const
{
- return components_;
+ return data_->components_;
}
@@ -101,7 +165,40 @@ namespace scribo
bool
object_links<L>::is_valid() const
{
- return components_.is_valid() && components_.nelements() == (this->size() - 1);
+ return data_->components_.is_valid()
+ && data_->components_.nelements() == (this->nelements() - 1);
+ }
+
+
+ template <typename L>
+ unsigned
+ object_links<L>::nelements() const
+ {
+ return data_->comp_to_link_.nelements() ;
+ }
+
+
+ template <typename L>
+ unsigned&
+ object_links<L>::operator()(unsigned comp_id)
+ {
+ return data_->comp_to_link_(comp_id);
+ }
+
+
+ template <typename L>
+ const unsigned&
+ object_links<L>::operator()(unsigned comp_id) const
+ {
+ return data_->comp_to_link_(comp_id);
+ }
+
+
+ template <typename L>
+ const mln::util::array<unsigned>&
+ object_links<L>::comp_to_link() const
+ {
+ return data_->comp_to_link_;
}
--
1.5.6.5
1
0
08 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch revamp-doc-build has been created
at 13af895daaeda0e5c287eb221453bcf1ac5db581 (commit)
- Log -----------------------------------------------------------------
13af895 Update the documentation's copyright header.
9716b84 Have Doxygen generate its outputs in the build directory.
52239ab Require Doxygen 1.5.6 at bootstrapping time.
42f2b71 bootstrap: Fix a typo in an error message.
bd915de Reorganize doc/Makefile.am.
121d1e6 Have Doxyfile.in generate the user documentation.
443d804 Generate the HTML and LaTeX Doxygen documentation in a single pass.
074db67 Shorten the list of files visited by Doxygen.
6095c47 apps/graph-morpho/morpho.hh: Help Doxygen compile LaTeX formulas.
8f46c4a Clean up Doxygen-related Make rules in milena/doc/.
9391217 configure.ac: Do not configure milena/doc/examples/Makefile.
7bc6643 Stop make from recurring in doc/examples.
cde21c2 Tell Git to ignore files generated in milena/doc/white_paper/figures/.
32e9532 configure.ac: Do not configure milena/doc/white_paper/Makefile.
3fbbba2 Stop make from recurring in doc/white_paper.
203f31e Tell Git to ignore files generated in milena/doc/technical/.
8c6dd29 configure.ac: Do not configure milena/doc/technical/Makefile.
7ef9ac2 Stop make from recurring in doc/technical.
1b2886b configure.ac: Do not configure milena/doc/tutorial/Makefile.
37fc180 Stop make from recurring in doc/tutorial.
d52b4eb configure.ac: Do not configure milena/doc/ref_guide/Makefile.
e4a2af5 Stop make from recurring in doc/ref_guide.
c663f70 Stop pruning Makefiles under milena/doc/.
0964a88 Get rid of Make targets `fake-doc' and `void-doc'.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
last-svn-commit-27-g13af895 Update the documentation's copyright header.
by Roland Levillain 08 Mar '10
by Roland Levillain 08 Mar '10
08 Mar '10
* mln/core/concept/object.hh: Here.
---
milena/ChangeLog | 6 ++++++
milena/mln/core/concept/object.hh | 4 ++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 1c8f44f..676e5b0 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2010-03-08 Roland Levillain <roland(a)lrde.epita.fr>
+ Update the documentation's copyright header.
+
+ * mln/core/concept/object.hh: Here.
+
+2010-03-08 Roland Levillain <roland(a)lrde.epita.fr>
+
Have Doxygen generate its outputs in the build directory.
* doc/Doxyfile.in (OUTPUT_DIRECTORY):
diff --git a/milena/mln/core/concept/object.hh b/milena/mln/core/concept/object.hh
index 74e3c2a..03408db 100644
--- a/milena/mln/core/concept/object.hh
+++ b/milena/mln/core/concept/object.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
+// Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
// Laboratory (LRDE)
//
// This file is part of Olena.
@@ -107,7 +107,7 @@
<LI> \ref mln::win
\section copyright Copyright and License.
- Copyright (C) 2007, 2008, 2009 EPITA Research and Development (LRDE)
+ Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development (LRDE)
This documentation is part of Olena.
--
1.5.6.5
1
0
last-svn-commit-18-g8f46c4a Clean up Doxygen-related Make rules in milena/doc/.
by Roland Levillain 08 Mar '10
by Roland Levillain 08 Mar '10
08 Mar '10
* doc/Makefile.am (DOXYFILE)
(DOXYFILE_USER_PDF, DOXYFILE_USER_HTML)
(DOXYFILE_DEVEL_PDF, DOXYFILE_DEVEL_HTML):
New variables.
(USER_REFMAN_LATEX)
(DEVEL_REFMAN_PDF, DEVEL_REFMAN_LATEX, DEVEL_REFMAN_HTML):
New variables.
(all-local): Depend on $(srcdir)/$(USER_REFMAN_PDF),
$(srcdir)/user-refman-html.stamp.
($(srcdir)/$(USER_REFMAN_PDF)): Split these targets and move the
generation of the LaTeX sources...
($(srcdir)/user-refman-latex.stamp)
($(srcdir)/$(USER_REFMAN_LATEX))
($(srcdir)/devel-refman-latex.stamp)
($(srcdir)/$(DEVEL_REFMAN_LATEX)):
...here (new targets).
($(srcdir)/$(USER_REFMAN_HTML))
($(srcdir)/$(DEVEL_REFMAN_HTML)):
Delegate the actions to...
($(srcdir)/user-refman-html.stamp)
($(srcdir)/devel-refman-html.stamp):
...these (new) targets.
(clean-user-refman-latex, clean-user-refman-html)
(clean-devel-refman-latex, clean-devel-refman-html):
New (phony) targets.
(maintainer-clean-local): Depend on clean-user-refman-latex,
clean-user-refman-html, clean-devel-refman-latex and
clean-devel-refman-html.
(EXTRA_DIST): Disable Doxyfile_devel_html, Doxyfile_devel_pdf,
Doxyfile_user_html and Doxyfile_user_pdf.
Add $(DOXYFILE).in.
($(srcdir)/Doxyfile_user, $(srcdir)/Doxyfile_user_pdf)
($(srcdir)/Doxyfile_devel, $(srcdir)/Doxyfile_devel_pdf):
Rename targets as...
($(DOXYFILE_USER_HTML), $(DOXYFILE_USER_PDF))
($(DOXYFILE_DEVEL_HTML), $(DOXYFILE_DEVEL_PDF)):
...these.
---
milena/ChangeLog | 42 ++++++++
milena/doc/Makefile.am | 269 ++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 267 insertions(+), 44 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 0657f50..aed1cb8 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,45 @@
+2010-03-04 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Clean up Doxygen-related Make rules in milena/doc/.
+
+ * doc/Makefile.am (DOXYFILE)
+ (DOXYFILE_USER_PDF, DOXYFILE_USER_HTML)
+ (DOXYFILE_DEVEL_PDF, DOXYFILE_DEVEL_HTML):
+ New variables.
+ (USER_REFMAN_LATEX)
+ (DEVEL_REFMAN_PDF, DEVEL_REFMAN_LATEX, DEVEL_REFMAN_HTML):
+ New variables.
+ (all-local): Depend on $(srcdir)/$(USER_REFMAN_PDF),
+ $(srcdir)/user-refman-html.stamp.
+ ($(srcdir)/$(USER_REFMAN_PDF)): Split these targets and move the
+ generation of the LaTeX sources...
+ ($(srcdir)/user-refman-latex.stamp)
+ ($(srcdir)/$(USER_REFMAN_LATEX))
+ ($(srcdir)/devel-refman-latex.stamp)
+ ($(srcdir)/$(DEVEL_REFMAN_LATEX)):
+ ...here (new targets).
+ ($(srcdir)/$(USER_REFMAN_HTML))
+ ($(srcdir)/$(DEVEL_REFMAN_HTML)):
+ Delegate the actions to...
+ ($(srcdir)/user-refman-html.stamp)
+ ($(srcdir)/devel-refman-html.stamp):
+ ...these (new) targets.
+ (clean-user-refman-latex, clean-user-refman-html)
+ (clean-devel-refman-latex, clean-devel-refman-html):
+ New (phony) targets.
+ (maintainer-clean-local): Depend on clean-user-refman-latex,
+ clean-user-refman-html, clean-devel-refman-latex and
+ clean-devel-refman-html.
+ (EXTRA_DIST): Disable Doxyfile_devel_html, Doxyfile_devel_pdf,
+ Doxyfile_user_html and Doxyfile_user_pdf.
+ Add $(DOXYFILE).in.
+ ($(srcdir)/Doxyfile_user, $(srcdir)/Doxyfile_user_pdf)
+ ($(srcdir)/Doxyfile_devel, $(srcdir)/Doxyfile_devel_pdf):
+ Rename targets as...
+ ($(DOXYFILE_USER_HTML), $(DOXYFILE_USER_PDF))
+ ($(DOXYFILE_DEVEL_HTML), $(DOXYFILE_DEVEL_PDF)):
+ ...these.
+
2010-03-03 Roland Levillain <roland(a)lrde.epita.fr>
Stop make from recurring in doc/examples.
diff --git a/milena/doc/Makefile.am b/milena/doc/Makefile.am
index 52e1851..3d5f4d9 100644
--- a/milena/doc/Makefile.am
+++ b/milena/doc/Makefile.am
@@ -22,11 +22,15 @@ include $(top_srcdir)/milena/doc/doc.mk
DOXYGEN = doxygen
+DOXYFILE = Doxyfile
+
# Initialiaze variables.
EXTRA_DIST =
dist_doc_DATA =
CLEANFILES =
+# FIXME: Simplify all of this. ``Devel'' targets are really
+# secondary. And we probably don't need so much target aliases!
.PHONY: doc \
doc-user doc-devel \
@@ -66,45 +70,199 @@ EXTRA_DEPS = $(srcdir)/tutorial/tutorial.hh $(srcdir)/ref_guide/ref_guide.hh
## directory of the _source_ tree. See how this is implemented in
## Vaucanson's doc build system. (Do not forget to adjust Doxyfiles.)
-# Doxygen PDF documentation outputs.
+# ----------------------------- #
+# User reference manual (PDF). #
+# ----------------------------- #
+
+# FIXME: Keep it or throw it away?
+all-local: $(srcdir)/$(USER_REFMAN_PDF)
+
+DOXYFILE_USER_PDF = Doxyfile_user_pdf
+
+## FIXME: Rename USER_REFMAN_PDF to something else?
USER_REFMAN_PDF = user-refman.pdf
+## FIXME: Likewise?
+USER_REFMAN_LATEX = user-refman-latex
+
ref-doc-pdf: $(srcdir)/$(USER_REFMAN_PDF)
-# FIXME: Split in two rules: one generating the LaTeX file from the
-# Doxyfile, and another one generating the PDF from the LaTeX source.
-# Moreover, the LaTeX to PDF rule could be factored using a suffix
-# rule (as in LRDE's share/).
-$(srcdir)/$(USER_REFMAN_PDF): $(srcdir)/Doxyfile_user_pdf $(srcdir)/figures.stamp $(EXTRA_DEPS)
- $(DOXYGEN) $< \
- && cd $(srcdir)/user/latex \
- && $(MAKE) pdf \
- && cp -f refman.pdf ../../$(USER_REFMAN_PDF)
-
-# FIXME: Careful, `user-refman-pdf' is a directory, and this make rule
-# depends on its timestamp, which is wrong.
+
+# FIXME: Use texi2dvi instead of Doxygen's generated Makefile?
+# (The LaTeX to PDF rule could be factored using a suffix rule, as in
+# LRDE's share/).
+$(srcdir)/$(USER_REFMAN_PDF): $(srcdir)/$(USER_REFMAN_LATEX)
+ cd $(srcdir)/$(USER_REFMAN_LATEX) && $(MAKE) $(AM_MAKEFLAGS) pdf
+ cp -f $(srcdir)/$(USER_REFMAN_LATEX)/refman.pdf $@
+
+## FIXME: Use a variable instead of `$(srcdir)/user/latex'.
+##
+## FIXME: Are dependencies $(srcdir)/figures.stamp $(EXTRA_DEPS) set
+## on the right rule? Does Doxygen make a copy of figures, or does it
+## generate LaTeX inputs relying on the existence of such figures in
+## the initial location? Investigate.
+$(srcdir)/user-refman-latex.stamp: $(srcdir)/$(DOXYFILE).in $(srcdir)/figures.stamp $(EXTRA_DEPS)
+ @rm -f $@.tmp
+ @touch $@.tmp
+ -rm -rf $(srcdir)/user/latex
+ $(MAKE) $(AM_MAKE_FLAGS) $(DOXYFILE_USER_PDF)
+ $(DOXYGEN) $(DOXYFILE_USER_PDF)
+## Doxygen may generate an incomplete output and exit with success!
+## Check some files before deeming the output as acceptable.
+ test -f $(srcdir)/user/latex/refman.tex
+ -rm -rf $(srcdir)/$(USER_REFMAN_LATEX)
+## FIXME: moving directories between file systems is not portable.
+ mv $(srcdir)/user/latex $(srcdir)/$(USER_REFMAN_LATEX)
+ @mv -f $@.tmp $@
+
+# FIXME: Probably superfluous. Should vanish when HTML and LaTeX
+# genarations are merged.
+$(srcdir)/$(USER_REFMAN_LATEX): $(srcdir)/user-refman-latex.stamp
+## Recover from the removal of $@
+ @if test -d $@; then :; else \
+ rm -f $<; \
+ $(MAKE) $(AM_MAKEFLAGS) $<; \
+ fi
+
+# Clean Doxygen products.
+.PHONY: clean-user-refman-latex
+clean-user-refman-latex:
+ rm -rf $(srcdir)/user/latex $(srcdir)/$(USER_REFMAN_LATEX)
+
+# ------------------------------ #
+# User reference manual (HTML). #
+# ------------------------------ #
+
+# FIXME: Keep it or throw it away?
+all-local: $(srcdir)/user-refman-html.stamp
+
+# FIXME: Rename USER_REFMAN_HTML as DOCDIR_USER_HTML?
USER_REFMAN_HTML = user-refman-html
+
+DOXYFILE_USER_HTML = Doxyfile_user_html
+
ref-doc-html: $(srcdir)/$(USER_REFMAN_HTML)
-$(srcdir)/$(USER_REFMAN_HTML): $(srcdir)/Doxyfile_user $(srcdir)/figures.stamp $(EXTRA_DEPS)
- $(DOXYGEN) $< \
- && rm -fr $(srcdir)/$(USER_REFMAN_HTML) \
- && mv $(srcdir)/user/html $(srcdir)/$(USER_REFMAN_HTML)
-# Doxygen HTML documentation output directories.
-DEVEL_REFMAN_PDF = devel/latex/refman.pdf
+# FIXME: Use `$(USER_REFMAN_HTML).tmp' instead of `$(srcdir)/user/html'.
+$(srcdir)/user-refman-html.stamp: $(srcdir)/$(DOXYFILE).in $(srcdir)/figures.stamp $(EXTRA_DEPS)
+ @rm -f $@.tmp
+ @touch $@.tmp
+ -rm -rf $(srcdir)/user/html
+ $(MAKE) $(AM_MAKE_FLAGS) $(DOXYFILE_USER_HTML)
+ $(DOXYGEN) $(DOXYFILE_USER_HTML)
+ -rm -rf $(srcdir)/$(USER_REFMAN_HTML)
+## FIXME: moving directories between file systems is not portable.
+ mv $(srcdir)/user/html $(srcdir)/$(USER_REFMAN_HTML)
+ @mv -f $@.tmp $@
+
+$(srcdir)/$(USER_REFMAN_HTML): $(srcdir)/user-refman-html.stamp
+## Recover from the removal of $@
+ @if test -d $@; then :; else \
+ rm -f $<; \
+ $(MAKE) $(AM_MAKEFLAGS) $<; \
+ fi
+
+# Clean Doxygen products.
+.PHONY: clean-user-refman-html
+clean-user-refman-html:
+ rm -rf $(srcdir)/user/html $(srcdir)/$(USER_REFMAN_HTML)
+
+# ---------------------------------- #
+# Developer reference manual (PDF). #
+# ---------------------------------- #
+
+DOXYFILE_DEVEL_PDF = Doxyfile_devel_pdf
+
+## FIXME: Rename DEVEL_REFMAN_PDF to something else?
+DEVEL_REFMAN_PDF = devel-refman-pdf
+## FIXME: Likewise?
+DEVEL_REFMAN_LATEX = devel-refman-latex
+
ref-doc-devel-pdf: $(srcdir)/$(DEVEL_REFMAN_PDF)
-# FIXME: Split in two rules: one generating the LaTeX file from the
-# Doxyfile, and another one generating the PDF from the LaTeX source.
-# Moreover, the LaTeX to PDF rule could be factored using a suffix
-# rule (as in LRDE's share/).
-$(srcdir)/$(DEVEL_REFMAN_PDF): $(srcdir)/Doxyfile_devel_pdf $(srcdir)/figures.stamp $(EXTRA_DEPS)
- $(DOXYGEN) $<
- cd $(srcdir)/devel/latex && $(MAKE) $(AM_MAKEFLAGS)
-
-# FIXME: Careful, `devel/html' is a directory, and this make rule
-# depends on its timestamp, which is wrong.
-DEVEL_REFMAN_HTML = devel/html
+
+## FIXME: Use texi2dvi instead of Doxygen's generated Makefile? (The
+## LaTeX to PDF rule could be factored using a suffix rule, as in
+## LRDE's share/).
+$(srcdir)/$(DEVEL_REFMAN_PDF): $(srcdir)/$(DEVEL_REFMAN_LATEX)
+ cd $(srcdir)/$(DEVEL_REFMAN_LATEX) && $(MAKE) $(AM_MAKEFLAGS) pdf
+ cp -f $(srcdir)/$(DEVEL_REFMAN_LATEX)/refman.pdf $@
+
+## FIXME: Use a variable instead of `$(srcdir)/devel/latex'.
+##
+## FIXME: Are dependencies $(srcdir)/figures.stamp $(EXTRA_DEPS) set
+## on the right rule? Does Doxygen make a copy of figures, or does it
+## generate LaTeX inputs relying on the existence of such figures in
+## the initial location? Investigate.
+$(srcdir)/devel-refman-latex.stamp: $(srcdir)/$(DOXYFILE).in $(srcdir)/figures.stamp $(EXTRA_DEPS)
+ @rm -f $@.tmp
+ @touch $@.tmp
+ -rm -rf $(srcdir)/devel/latex
+ $(MAKE) $(AM_MAKE_FLAGS) $(DOXYFILE_DEVEL_PDF)
+ $(DOXYGEN) $(DOXYFILE_DEVEL_PDF)
+## Doxygen may generate an incomplete output and exit with success!
+## Check some files before deeming the output as acceptable.
+ test -f $(srcdir)/devel/latex/refman.tex
+ -rm -rf $(srcdir)/$(DEVEL_REFMAN_LATEX)
+## FIXME: moving directories between file systems is not portable.
+ mv $(srcdir)/devel/latex $(srcdir)/$(DEVEL_REFMAN_LATEX)
+ @mv -f $@.tmp $@
+
+# FIXME: Probably superfluous. Should vanish when HTML and LaTeX
+# genarations are merged.
+$(srcdir)/$(DEVEL_REFMAN_LATEX): $(srcdir)/devel-refman-latex.stamp
+## Recover from the removal of $@
+ @if test -d $@; then :; else \
+ rm -f $<; \
+ $(MAKE) $(AM_MAKEFLAGS) $<; \
+ fi
+
+# Clean Doxygen products.
+.PHONY: clean-devel-refman-latex
+clean-devel-refman-latex:
+ rm -rf $(srcdir)/devel/latex $(srcdir)/$(DEVEL_REFMAN_LATEX)
+
+# ----------------------------------- #
+# Developer reference manual (HTML). #
+# ----------------------------------- #
+
+# FIXME: Rename DEVEL_REFMAN_HTML as DOCDIR_DEVEL_HTML?
+DEVEL_REFMAN_HTML = devel-refman-html
+
+DOXYFILE_DEVEL_HTML = Doxyfile_devel_html
+
ref-doc-devel-html: $(srcdir)/$(DEVEL_REFMAN_HTML)
-$(srcdir)/$(DEVEL_REFMAN_HTML): $(srcdir)/Doxyfile_devel $(srcdir)/figures.stamp $(EXTRA_DEPS)
- $(DOXYGEN) $<
+
+# FIXME: Use `$(DEVEL_REFMAN_HTML).tmp' instead of `$(srcdir)/devel/html'.
+$(srcdir)/devel-refman-html.stamp: $(srcdir)/$(DOXYFILE).in $(srcdir)/figures.stamp $(EXTRA_DEPS)
+ @rm -f $@.tmp
+ @touch $@.tmp
+ -rm -rf $(srcdir)/devel/html
+ $(MAKE) $(AM_MAKE_FLAGS) $(DOXYFILE_DEVEL_HTML)
+ $(DOXYGEN) $(DOXYFILE_DEVEL_HTML)
+ -rm -rf $(srcdir)/$(DEVEL_REFMAN_HTML)
+## FIXME: moving directories between file systems is not portable.
+ mv $(srcdir)/devel/html $(srcdir)/$(DEVEL_REFMAN_HTML)
+ @mv -f $@.tmp $@
+
+$(srcdir)/$(DEVEL_REFMAN_HTML): $(srcdir)/devel-refman-html.stamp
+## Recover from the removal of $@
+ @if test -d $@; then :; else \
+ rm -f $<; \
+ $(MAKE) $(AM_MAKEFLAGS) $<; \
+ fi
+
+# Clean Doxygen products.
+.PHONY: clean-devel-refman-html
+clean-devel-refman-html:
+ rm -rf $(srcdir)/devel/html $(srcdir)/$(DEVEL_REFMAN_HTML)
+
+# ---------- #
+# Cleaning. #
+# ---------- #
+
+maintainer-clean-local: clean-user-refman-latex clean-user-refman-html
+maintainer-clean-local: clean-devel-refman-latex clean-devel-refman-html
+maintainer-clean-local:
+ rm -rf $(srcdir)/user
+ rm -rf $(srcdir)/devel
## ------------------------- ##
## Technical Documentation. ##
@@ -165,12 +323,14 @@ edit = sed -e "s|@ID@|$$Id|" \
-e 's,@srcdir\@,$(srcdir),g' \
-e 's,@builddir\@,$(builddir),g'
+## FIXME: Instead of generating HTML and PDF (LaTeX actualy) output in
+## two passes, do it in a row. It will save us a lot of time.
edit_pdf = sed -e 's,GENERATE_LATEX = NO,GENERATE_LATEX = YES,g' \
-e 's,GENERATE_HTML = YES,GENERATE_HTML = NO,g'
# FIXME: This is not good. We should set these parameters for both
# documentation (devel and user) using @VARIABLES@. Don't generate
-# Doxyfile_user from Doxyfile_devel! Both should be a product
+# Doxyfile_user_html from Doxyfile_devel_html! Both should be a product
# derived from a single source, Doxyfile.in.
edit_user = sed \
-e 's,OUTPUT_DIRECTORY = @srcdir@/devel/,OUTPUT_DIRECTORY = @srcdir@/user/,g' \
@@ -249,13 +409,15 @@ uninstall-local:
chmod -R 700 $(DESTDIR)$(htmldir)/$(USER_REFMAN_HTML)
rm -rf $(DESTDIR)$(htmldir)/$(USER_REFMAN_HTML)
+## FIXME: These are now generated in the build directory.
+# EXTRA_DIST += \
+# Doxyfile_devel_html \
+# Doxyfile_devel_pdf \
+# Doxyfile_user_html \
+# Doxyfile_user_pdf
EXTRA_DIST += \
- Doxyfile.in \
- Doxyfile_devel \
- Doxyfile_devel_pdf \
- Doxyfile_user \
- Doxyfile_user_pdf \
+ $(DOXYFILE).in \
groups/accu.hh \
groups/graph.hh \
groups/images.hh \
@@ -273,6 +435,13 @@ EXTRA_DIST += \
tools/split_sample.sh \
tools/todoxygen.sh
+## FIXME: Unsure about this. If the directory of the generated
+## documentation is to be removed during `maintainer-clean' (see
+## Vaucanson's doc/Makefile.am), then the source Doxyfiles should not
+## be removed earlier (i.e. at `clean') !
+##
+## Note: if configure is used to generate Doxyfiles (see below), these
+## files should be (and will be automatically) remove by `distclean'.
CLEANFILES += \
Doxyfile_user \
Doxyfile_user_pdf \
@@ -283,16 +452,28 @@ CLEANFILES += \
# Sed is used to generate Doxyfile from Doxyfile.in instead of
# configure, because the former is way faster than the latter.
-$(srcdir)/Doxyfile_user: Doxyfile_devel
+#
+## FIXME: This is because, as in TC, we depend on $Id$ from the
+## ChangeLog. Maybe we should depend from something less prone to
+## change.
+##
+## FIXME: Move these rules higher, closer to their use sites.
+##
+## FIXME: There are too many indirect generations here. Simplify.
+
+# FIXME: Directly depend on $(DOXYFILE).in instead.
+$(DOXYFILE_USER_PDF): $(DOXYFILE_USER_HTML)
+ $(edit_pdf) $< >$@
+
+# FIXME: Directly depend on $(DOXYFILE).in instead.
+$(DOXYFILE_USER_HTML): $(DOXYFILE_DEVEL_HTML)
$(edit_user) $< >$@
-$(srcdir)/Doxyfile_user_pdf: Doxyfile_user
+# FIXME: Directly depend on $(DOXYFILE).in instead.
+$(DOXYFILE_DEVEL_PDF): $(DOXYFILE_DEVEL_HTML)
$(edit_pdf) $< >$@
-$(srcdir)/Doxyfile_devel: $(srcdir)/Doxyfile.in
+$(DOXYFILE_DEVEL_HTML): $(srcdir)/$(DOXYFILE).in
Id=`grep '^\$$Id' $(top_srcdir)/milena/ChangeLog \
| sed -e 's/\\\$$//g'`; \
$(edit) $< >$@
-
-$(srcdir)/Doxyfile_devel_pdf: Doxyfile_devel
- $(edit_pdf) $< >$@
--
1.5.6.5
1
0