https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add a document-to-words routine based on lines.
* icdar/2009/hsc/input_to_lines.hh (tau): New.
* icdar/2009/hsc/input_to_lines_dat.cc: Update.
* icdar/2009/hsc/input_to_words_dat.cc: New.
* icdar/2009/hsc/line_to_words.hh
(black_on_white, reduce): New.
* icdar/2009/hsc/get_line_images.hh: Fix 1st elt, at index 0.
get_line_images.hh | 13 +++++++--
input_to_lines.hh | 5 ++-
input_to_lines_dat.cc | 2 -
input_to_words_dat.cc | 64 ++++++++++++++++++++++++++++++++++++++++-----
line_to_words.hh | 71 +++++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 134 insertions(+), 21 deletions(-)
Index: icdar/2009/hsc/input_to_lines.hh
--- icdar/2009/hsc/input_to_lines.hh (revision 3644)
+++ icdar/2009/hsc/input_to_lines.hh (working copy)
@@ -16,7 +16,8 @@
template <typename L>
image2d<L>
- input_to_lines(const image2d<bool>& raw_input, L& n_lines)
+ input_to_lines(const image2d<bool>& raw_input, L& n_lines,
+ float tau)
{
// First clean.
image2d<bool> input = clean_input(raw_input);
@@ -35,7 +36,7 @@
wsl = ws_to_wslines(input, small, ws, n_reg);
// Clean lines
- wsl = clean_lines(input, wsl, 0.7f);
+ wsl = clean_lines(input, wsl, tau);
return labeling::relabel(violent_cast_image_<L>(wsl),
n_lines);
Index: icdar/2009/hsc/input_to_words_dat.cc
--- icdar/2009/hsc/input_to_words_dat.cc (revision 3644)
+++ icdar/2009/hsc/input_to_words_dat.cc (working copy)
@@ -4,12 +4,34 @@
#include <mln/io/pbm/load.hh>
#include <mln/io/ppm/save.hh>
#include <mln/debug/colorize.hh>
+#include <mln/estim/min_max.hh>
-#include <sandbox/icdar/2009/hsc/clean_input.hh>
+#include <sandbox/icdar/2009/hsc/input_to_lines.hh>
#include <sandbox/icdar/2009/hsc/line_to_words.hh>
+#include <sandbox/icdar/2009/hsc/get_line_images.hh>
#include <sandbox/icdar/2009/hsc/io/icdar/save.hh>
+namespace mln
+{
+
+ template <typename L>
+ void
+ paste_words(image2d<L>& output,
+ const image2d<L>& words,
+ L l_1st)
+ {
+ mln_piter(box2d) p(words.domain());
+ for_all(p)
+ {
+ if (words(p) == 0)
+ continue;
+ output(p) = l_1st.to_enc() + words(p).to_enc();
+ }
+ }
+
+} // mln
+
void usage(char* argv[])
@@ -27,7 +49,6 @@
int main(int argc, char* argv[])
{
using namespace mln;
- using value::int_u16;
if (argc != 3 && argc != 4)
usage(argv);
@@ -35,15 +56,46 @@
trace::entering("main");
+ typedef image2d<bool> I_bw;
- image2d<bool> input;
+ I_bw input;
io::pbm::load(input, argv[1]);
- input = clean_input(input);
+ typedef value::label<12> Ll;
+ Ll n_lines;
+ image2d<Ll> lines = input_to_lines(input, n_lines, 0.501); // with majoritary
+
+ // std::cout << "n lines = " << n_lines << std::endl;
+
+ typedef value::int_u16 L;
- int_u16 n_words;
- image2d<int_u16> output = line_to_words(input, n_words);
+ image2d<L> output(input.domain());
+ data::fill(output, 0);
+
+ util::array<I_bw> line_ = get_line_images(lines, n_lines, 51);
+
+ L n_words = 0;
+ for (unsigned l = 1; l <= n_lines; ++l)
+ {
+ I_bw line = line_[l]; // A line image.
+
+ L n_line_words = 0;
+ image2d<L> words = line_to_words(line, n_line_words, false);
+ paste_words(output, words, /* 1st label is */ n_words);
+
+ // std::cout << "line = " << l
+ // << " n_words = " << n_line_words << std::endl;
+
+ n_words += n_line_words;
+ }
+
+ {
+ // L l_min, l_max;
+ // estim::min_max(output, l_min, l_max);
+ // if (l_max != n_words)
+ // std::cout << "oops: " << l_max << ' '
<< n_words << std::endl;
+ }
io::icdar::save(output, argv[2]);
Property changes on: icdar/2009/hsc/input_to_words_dat.cc
___________________________________________________________________
Added: svn:mergeinfo
Index: icdar/2009/hsc/line_to_words.hh
--- icdar/2009/hsc/line_to_words.hh (revision 3644)
+++ icdar/2009/hsc/line_to_words.hh (working copy)
@@ -12,20 +12,25 @@
#include <mln/morpho/elementary/dilation.hh>
#include <mln/morpho/watershed/flooding.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/labeling/wrap.hh>
namespace mln
{
-
- image2d<bool> // Fwd decl.
- reduce_negate(const image2d<bool>& input);
+ // Fwd decl.
+ image2d<bool> reduce (const image2d<bool>& input);
+ image2d<bool> reduce_negate(const image2d<bool>& input);
template <typename L>
image2d<L>
- line_to_words(const image2d<bool>& input, L& n_words)
+ line_to_words(const image2d<bool>& input, L& n_words,
+ bool black_on_white = true)
{
// Parameters.
@@ -37,12 +42,20 @@
// end of Parameters.
- image2d<bool>
- sub = reduce_negate(input),
+ image2d<bool> sub, clo;
+
+ if (black_on_white)
+ sub = reduce_negate(input);
+ else
+ sub = reduce(input);
+
clo = morpho::closing::structural(sub,
win::rectangle2d(height,
width));
+ // io::pbm::save(sub, "tmp_sub.pbm");
+ // io::pbm::save(clo, "tmp_clo.pbm");
+
int ww[] = { 00, 11, 0, 11, 0,
11, 7, 5, 7, 11,
00, 5, 0, 5, 0,
@@ -56,11 +69,21 @@
mln_max(int_u12)),
dmap_ = morpho::closing::area(dmap, c4(), l_area);
- image2d<L> ws =
morpho::elementary::dilation(morpho::watershed::flooding(dmap_,
+
+ // io::pgm::save(labeling::wrap(dmap), "tmp_dmap.pgm");
+ // io::pgm::save(labeling::wrap(dmap_), "tmp_dmap_.pgm");
+
+
+ image2d<L> ws_ = morpho::watershed::flooding(dmap_,
c4(),
- n_words),
+ n_words);
+ image2d<L> ws = morpho::elementary::dilation(ws_,
c4());
+ // io::pgm::save(labeling::wrap(ws), "tmp_ws.pgm");
+ // io::pgm::save(labeling::wrap(ws_), "tmp_ws_.pgm");
+
+
image2d<L> output(input.domain());
{
@@ -70,13 +93,43 @@
mln_piter_(box2d) p(input.domain());
for_all(p)
- if (input(p))
+ if (input(p) == black_on_white)
output(p) = 0;
else
output(p) = ws.at_((p.row() - min_row) / 2,
(p.col() - min_col) / 2);
}
+ // io::pgm::save(labeling::wrap(output), "tmp_output.pgm");
+
+ return output;
+ }
+
+
+
+ image2d<bool>
+ reduce(const image2d<bool>& input)
+ {
+ const int
+ min_row = input.domain().pmin().row(),
+ min_col = input.domain().pmin().col(),
+ max_row = input.domain().pmax().row(),
+ max_col = input.domain().pmax().col();
+
+ image2d<bool> output(input.nrows() / 2,
+ input.ncols() / 2);
+
+ for (int row = min_row; row <= max_row; row += 2)
+ for (int col = min_col; col <= max_col; col += 2)
+ {
+ unsigned count = 0;
+ if (input.at_(row, col) == true) ++count;
+ if (input.at_(row, col + 1) == true) ++count;
+ if (input.at_(row + 1, col) == true) ++count;
+ if (input.at_(row + 1, col + 1) == true) ++count;
+ output.at_((row - min_row) / 2,
+ (col - min_col) / 2) = (count >= 2);
+ }
return output;
}
Index: icdar/2009/hsc/input_to_lines_dat.cc
--- icdar/2009/hsc/input_to_lines_dat.cc (revision 3644)
+++ icdar/2009/hsc/input_to_lines_dat.cc (working copy)
@@ -37,7 +37,7 @@
typedef value::label<12> L;
L n_lines;
- image2d<L> output = input_to_lines(input, n_lines);
+ image2d<L> output = input_to_lines(input, n_lines, 0.7); // with 70%
io::icdar::save(output, argv[2]);
Index: icdar/2009/hsc/get_line_images.hh
--- icdar/2009/hsc/get_line_images.hh (revision 3644)
+++ icdar/2009/hsc/get_line_images.hh (working copy)
@@ -39,14 +39,21 @@
util::array<box<mln_site(L)> >
bboxes = labeling::compute(accu::meta::bbox(), lines, nlines);
- util::array<mln_ch_value(L,bool)> result;
+ typedef mln_ch_value(L,bool) line_t;
+ util::array<line_t> result;
- for (unsigned i = 1; i < nlines; ++i)
{
- typedef mln_ch_value(L,bool) line_t;
+ // Skipping index 0:
+ line_t dummy(1,1);
+ result.append(dummy);
+ }
+
+ for (unsigned i = 1; i <= nlines; ++i)
+ {
box<mln_site(L)> b = bboxes[i];
b.enlarge(bbox_line_enlarge);
line_t line(b);
+ data::fill(line, false);
data::fill(((line | bboxes[i]).rw() | (pw::value(lines) == i)).rw(), true);
result.append(line);