$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
show_paragraph_blocks.cc
1 // Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #include <iostream>
27 
28 #include <mln/core/image/image2d.hh>
29 #include <mln/io/pbm/save.hh>
30 #include <mln/io/pgm/save.hh>
31 #include <mln/draw/box_plain.hh>
32 
33 #include <mln/debug/filename.hh>
34 
35 #include <mln/util/timer.hh>
36 
37 #include <scribo/core/def/lbl_type.hh>
38 #include <scribo/debug/usage.hh>
39 
40 #include <scribo/core/component_set.hh>
41 #include <scribo/core/paragraph_set.hh>
42 #include <scribo/core/line_info.hh>
43 
44 #include <scribo/text/link_lines.hh>
45 #include <scribo/filter/line_links_x_height.hh>
46 
47 #include <scribo/io/xml/load.hh>
48 
49 // int i = 0;
50 
51 const char *args_desc[][2] =
52 {
53  {0, 0}
54 };
55 
56 
57 
58 int main(int argc, char* argv[])
59 {
60  using namespace scribo;
61  using namespace mln;
62 
63  if (argc != 3)
64  return scribo::debug::usage(argv,
65  "Show paragraph blocks",
66  "lines.xml out_blocks.pbm",
67  args_desc);
68 
69  mln_trace("main");
70 
72  document<L> doc;
73  scribo::io::xml::load(doc, argv[1]);
74 
75  if (! doc.has_text())
76  {
77  std::cout << "ERROR: this XML file does not contain any text information!"
78  << std::endl;
79  return 1;
80  }
81 
82 
83  // Link text lines
84  line_links<L> llinks = scribo::text::link_lines(doc.lines());
85  llinks = scribo::filter::line_links_x_height(llinks);
86 
88  doc.set_paragraphs(parset);
89 
91  t.start();
92 
93  image2d<bool> blocks;
94  initialize(blocks, doc.lines().components().labeled_image());
95  data::fill(blocks, false);
96 
97  // image2d<value::int_u8> log;
98  // initialize(log, blocks);
99  // data::fill(log, 0);
100 
101  for_all_paragraphs(p, parset)
102  if (parset(p).nlines() >= 3)
103  {
104  box2d last_tbox, last_box;
105 
106  // For each line in this paragraph.
107  for_all_elements(l, parset(p).line_ids())
108  {
109  const line_info<L>& line = parset.lines()(parset(p).line_ids()(l));
110 
111  if (last_box.is_valid())
112  {
113  if (last_box.pmax().row() < line.bbox().pmin().row())
114  {
115  last_tbox = last_box;
116 
117  point2d
118  pmin(std::min(last_tbox.pmax().row(), line.bbox().pmin().row()),
119  std::max(last_tbox.pmin().col(), line.bbox().pmin().col())),
120  pmax(std::max(last_tbox.pmax().row(), line.bbox().pmin().row()),
121  std::min(last_tbox.pmax().col(), line.bbox().pmax().col()));
122 
123  // invalid case:
124  //
125  // =======
126  // ======
127 
128  if (pmax.col() > pmin.col())
129  {
130  box2d new_box(pmin, pmax);
131  mln::draw::box_plain(blocks, new_box, true);
132  // mln::draw::box_plain(log, new_box, 1);
133 
134  // mln::io::pgm::save(log, mln::debug::filename("log.pgm", i++));
135  }
136  }
137  else // Handle the case when there are several text boxes on the same line.
138  {
139  if (last_tbox.is_valid() && last_tbox.pmax().row() < line.bbox().pmin().row())
140  {
141  // Top box
142  point2d
143  pmin(std::min(last_tbox.pmax().row(), line.bbox().pmin().row()),
144  std::max(last_tbox.pmin().col(), line.bbox().pmin().col())),
145  pmax(std::max(last_tbox.pmax().row(), line.bbox().pmin().row()),
146  std::min(last_tbox.pmax().col(), line.bbox().pmax().col()));
147 
148  box2d new_box(pmin, pmax);
149 
150  mln::draw::box_plain(blocks, new_box, true);
151  // mln::draw::box_plain(log, new_box, 2);
152  // mln::io::pgm::save(log, mln::debug::filename("log.pgm", i++));
153  }
154 
155  if (last_box.pmax().col() < line.bbox().pmax().col()
156  && last_box.pmin().col() < line.bbox().pmin().col())
157  {
158  // Left box
159  point2d
160  pmin(std::min(last_tbox.pmax().row(), line.bbox().pmin().row()),
161  std::min(last_box.pmax().col(), line.bbox().pmin().col())),
162  pmax(std::min(last_box.pmax().row(), line.bbox().pmax().row()),
163  std::max(last_box.pmax().col(), line.bbox().pmin().col()));
164 
165  box2d new_box(pmin, pmax);
166  mln::draw::box_plain(blocks, new_box, true);
167  // mln::draw::box_plain(log, new_box, 3);
168  // mln::io::pgm::save(log, mln::debug::filename("log.pgm", i++));
169  }
170  }
171  }
172 
173  mln::draw::box_plain(blocks, line.bbox(), true);
174  // mln::draw::box_plain(log, line.bbox(), 255);
175  // mln::io::pgm::save(log, mln::debug::filename("log.pgm", i++));
176  last_box = line.bbox();
177  }
178  }
179 
180  t.stop();
181  std::cout << t << std::endl;
182 
183  mln::io::pbm::save(blocks, argv[2]);
184  // mln::io::pgm::save(log, "log.pgm");
185 
186 }