* scribo/Makefile: add new targets.
* scribo/core/central_sites.hh,
* scribo/core/component_bboxes.hh: add more assertions.
* scribo/text/recognition.hh,
* scribo/text/grouping/internal/find_root.hh,
* scribo/text/grouping/internal/init_link_array.hh,
* scribo/text/grouping/group_from_double_link.hh,
* scribo/text/grouping/group_from_multiple_links.hh,
* scribo/text/grouping/group_from_single_link.hh,
* scribo/text/grouping/group_with_multiple_links.hh,
* scribo/text/grouping/group_with_single_left_link.hh,
* scribo/text/grouping/group_with_single_right_link.hh,
* scribo/text/extract_bboxes.hh,
* scribo/src/extract_text_double_link.cc,
* scribo/src/extract_text_multiple_links.cc,
* scribo/src/extract_text_single_link.cc,
* scribo/debug/save_linked_textbboxes_image.hh,
* scribo/debug/save_table_image.hh,
* scribo/debug/save_textbboxes_image.hh,
* scribo/draw/bounding_box_links.hh,
* scribo/draw/bounding_boxes.hh: make use of util::text.
* scribo/filter/large_components.hh,
* scribo/filter/small_components.hh,
* scribo/filter/thin_bboxes.hh: new filters.
* scribo/make/debug_filename.hh: improve.
* scribo/make/text.hh: Construct a text class.
* scribo/src/dmap.cc,
* scribo/src/morpho.cc,
* scribo/src/table_extract.cc,
* scribo/src/table_rebuild.cc,
* scribo/src/thin_bboxes.cc: new sample code.
* scribo/src/table.cc: fix include.
* scribo/table/internal/align_lines.hh,
* scribo/table/align_lines_horizontaly.hh,
* scribo/table/align_lines_verticaly.hh,
* scribo/table/connect_horizontal_lines.hh,
* scribo/table/connect_vertical_lines.hh: add more parameters.
* scribo/table/extract.hh: new routine to extract document tables.
* scribo/table/extract_lines_with_opening.hh: new routine to extract
document tables.
* scribo/table/extract_lines_with_rank.hh: fix missing bbox.enlarge.
* scribo/table/internal/connect_lines.hh: make it compile.
* scribo/table/internal/repair_lines.hh: make it work.
* scribo/table/rebuild.hh: new routine to rebuild document tables.
* scribo/core/erase_bboxes.hh,
* scribo/table/repair_horizontal_lines.hh: revamp.
* scribo/tests/filter/small_and_large_bboxes.cc,
* scribo/tests/table/extract_lines_with_rank.cc,
* scribo/tests/table/repair_lines.cc: new tests.
* scribo/text/extract_lines.hh: new routine to extract text
automatically.
* scribo/text/grouping/internal/update_link_array.hh,
* scribo/text/grouping/internal/update_link_graph.hh: fix conditions.
* scribo/util/text.hh: new object to represent text components.
---
milena/sandbox/ChangeLog | 80 ++++++++-
milena/sandbox/scribo/Makefile | 27 ++-
milena/sandbox/scribo/core/central_sites.hh | 2 +-
milena/sandbox/scribo/core/component_bboxes.hh | 19 ++-
milena/sandbox/scribo/core/erase_bboxes.hh | 4 +-
.../scribo/debug/save_linked_textbboxes_image.hh | 49 +++---
milena/sandbox/scribo/debug/save_table_image.hh | 65 +++++--
.../sandbox/scribo/debug/save_textbboxes_image.hh | 7 +-
milena/sandbox/scribo/draw/bounding_box_links.hh | 26 ++--
milena/sandbox/scribo/draw/bounding_boxes.hh | 4 +-
milena/sandbox/scribo/filter/large_components.hh | 196 ++++++++++++++++++
milena/sandbox/scribo/filter/small_components.hh | 207 ++++++++++++++++++++
milena/sandbox/scribo/filter/thin_bboxes.hh | 165 ++++++++++++++++
milena/sandbox/scribo/make/debug_filename.hh | 33 +++-
.../{text/extract_bboxes.hh => make/text.hh} | 81 +++++---
milena/sandbox/scribo/src/dmap.cc | 26 +++
.../sandbox/scribo/src/extract_text_double_link.cc | 69 ++++----
.../scribo/src/extract_text_multiple_links.cc | 34 ++--
.../sandbox/scribo/src/extract_text_single_link.cc | 72 ++++---
milena/sandbox/scribo/src/morpho.cc | 64 ++++++
milena/sandbox/scribo/src/table.cc | 2 +-
...act_text_multiple_links.cc => table_extract.cc} | 37 ++---
...act_text_multiple_links.cc => table_rebuild.cc} | 45 +++--
milena/sandbox/scribo/src/thin_bboxes.cc | 32 +++
.../scribo/table/align_lines_horizontaly.hh | 18 ++-
.../sandbox/scribo/table/align_lines_verticaly.hh | 15 +-
.../scribo/table/connect_horizontal_lines.hh | 14 +-
.../sandbox/scribo/table/connect_vertical_lines.hh | 14 +-
.../{text/extract_bboxes.hh => table/extract.hh} | 73 ++++----
..._with_rank.hh => extract_lines_with_opening.hh} | 67 ++++---
.../scribo/table/extract_lines_with_rank.hh | 27 ++-
.../sandbox/scribo/table/internal/align_lines.hh | 9 +-
.../sandbox/scribo/table/internal/connect_lines.hh | 17 ++-
.../sandbox/scribo/table/internal/repair_lines.hh | 67 +++++--
milena/sandbox/scribo/table/rebuild.hh | 147 ++++++++++++++
.../scribo/table/repair_horizontal_lines.hh | 6 +-
.../filter/small_and_large_bboxes.cc} | 13 ++-
.../scribo/tests/table/extract_lines_with_rank.cc | 36 ++++
milena/sandbox/scribo/tests/table/repair_lines.cc | 45 +++++
milena/sandbox/scribo/text/extract_bboxes.hh | 15 +-
milena/sandbox/scribo/text/extract_lines.hh | 133 +++++++++++++
.../scribo/text/grouping/group_from_double_link.hh | 65 +++++--
.../text/grouping/group_from_multiple_links.hh | 63 ++++---
.../scribo/text/grouping/group_from_single_link.hh | 43 +++--
.../text/grouping/group_with_multiple_links.hh | 37 ++---
.../text/grouping/group_with_single_left_link.hh | 47 ++---
.../text/grouping/group_with_single_right_link.hh | 49 ++---
.../scribo/text/grouping/internal/find_root.hh | 4 +-
.../text/grouping/internal/init_link_array.hh | 7 +-
.../text/grouping/internal/update_link_array.hh | 7 +-
.../text/grouping/internal/update_link_graph.hh | 6 +-
milena/sandbox/scribo/text/recognition.hh | 19 +-
milena/sandbox/scribo/util/text.hh | 189 ++++++++++++++++++
53 files changed, 2087 insertions(+), 511 deletions(-)
create mode 100644 milena/sandbox/scribo/filter/large_components.hh
create mode 100644 milena/sandbox/scribo/filter/small_components.hh
create mode 100644 milena/sandbox/scribo/filter/thin_bboxes.hh
copy milena/sandbox/scribo/{text/extract_bboxes.hh => make/text.hh} (56%)
create mode 100644 milena/sandbox/scribo/src/dmap.cc
create mode 100644 milena/sandbox/scribo/src/morpho.cc
copy milena/sandbox/scribo/src/{extract_text_multiple_links.cc => table_extract.cc}
(61%)
copy milena/sandbox/scribo/src/{extract_text_multiple_links.cc => table_rebuild.cc}
(61%)
create mode 100644 milena/sandbox/scribo/src/thin_bboxes.cc
copy milena/sandbox/scribo/{text/extract_bboxes.hh => table/extract.hh} (55%)
copy milena/sandbox/scribo/table/{extract_lines_with_rank.hh =>
extract_lines_with_opening.hh} (67%)
create mode 100644 milena/sandbox/scribo/table/rebuild.hh
copy milena/sandbox/scribo/{src/extract_text_multiple_links.cc =>
tests/filter/small_and_large_bboxes.cc} (87%)
create mode 100644 milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc
create mode 100644 milena/sandbox/scribo/tests/table/repair_lines.cc
create mode 100644 milena/sandbox/scribo/text/extract_lines.hh
create mode 100644 milena/sandbox/scribo/util/text.hh
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 8c7681f..7137a4d 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,4 +1,82 @@
-2009-03-16 Guillaume Lazzara <z(a)lrde.epita.fr>
+2009-03-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Update Scribo's code.
+
+ * scribo/Makefile: add new targets.
+
+ * scribo/core/central_sites.hh,
+ * scribo/core/component_bboxes.hh: add more assertions.
+
+ * scribo/text/recognition.hh,
+ * scribo/text/grouping/internal/find_root.hh,
+ * scribo/text/grouping/internal/init_link_array.hh,
+ * scribo/text/grouping/group_from_double_link.hh,
+ * scribo/text/grouping/group_from_multiple_links.hh,
+ * scribo/text/grouping/group_from_single_link.hh,
+ * scribo/text/grouping/group_with_multiple_links.hh,
+ * scribo/text/grouping/group_with_single_left_link.hh,
+ * scribo/text/grouping/group_with_single_right_link.hh,
+ * scribo/text/extract_bboxes.hh,
+ * scribo/src/extract_text_double_link.cc,
+ * scribo/src/extract_text_multiple_links.cc,
+ * scribo/src/extract_text_single_link.cc,
+ * scribo/debug/save_linked_textbboxes_image.hh,
+ * scribo/debug/save_table_image.hh,
+ * scribo/debug/save_textbboxes_image.hh,
+ * scribo/draw/bounding_box_links.hh,
+ * scribo/draw/bounding_boxes.hh: make use of util::text.
+
+ * scribo/filter/large_components.hh,
+ * scribo/filter/small_components.hh,
+ * scribo/filter/thin_bboxes.hh: new filters.
+
+ * scribo/make/debug_filename.hh: improve.
+
+ * scribo/make/text.hh: Construct a text class.
+
+ * scribo/src/dmap.cc,
+ * scribo/src/morpho.cc,
+ * scribo/src/table_extract.cc,
+ * scribo/src/table_rebuild.cc,
+ * scribo/src/thin_bboxes.cc: new sample code.
+
+ * scribo/src/table.cc: fix include.
+
+ * scribo/table/internal/align_lines.hh,
+ * scribo/table/align_lines_horizontaly.hh,
+ * scribo/table/align_lines_verticaly.hh,
+ * scribo/table/connect_horizontal_lines.hh,
+ * scribo/table/connect_vertical_lines.hh: add more parameters.
+
+ * scribo/table/extract.hh: new routine to extract document tables.
+
+ * scribo/table/extract_lines_with_opening.hh: new routine to extract
+ document tables.
+
+ * scribo/table/extract_lines_with_rank.hh: fix missing bbox.enlarge.
+
+ * scribo/table/internal/connect_lines.hh: make it compile.
+
+ * scribo/table/internal/repair_lines.hh: make it work.
+
+ * scribo/table/rebuild.hh: new routine to rebuild document tables.
+
+ * scribo/core/erase_bboxes.hh,
+ * scribo/table/repair_horizontal_lines.hh: revamp.
+
+ * scribo/tests/filter/small_and_large_bboxes.cc,
+ * scribo/tests/table/extract_lines_with_rank.cc,
+ * scribo/tests/table/repair_lines.cc: new tests.
+
+ * scribo/text/extract_lines.hh: new routine to extract text
+ automatically.
+
+ * scribo/text/grouping/internal/update_link_array.hh,
+ * scribo/text/grouping/internal/update_link_graph.hh: fix conditions.
+
+ * scribo/util/text.hh: new object to represent text components.
+
+2009-03-19 Guillaume Lazzara <z(a)lrde.epita.fr>
Add a buggy sample case.
diff --git a/milena/sandbox/scribo/Makefile b/milena/sandbox/scribo/Makefile
index cbb462b..09a3a2d 100644
--- a/milena/sandbox/scribo/Makefile
+++ b/milena/sandbox/scribo/Makefile
@@ -1,28 +1,41 @@
+CXX_FLAGS = -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG # -ggdb #-O1
-DNDEBUG
+
all: table photo
tabledbg: demat.hh
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -g src/table.cc
$(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table.out
+ g++ -Wextra -Wall -I../.. -I../ -I. -I$(HOME)/local/include -O1 -g src/table.cc
$(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table.out
table: demat.hh
- g++ -Wextra -Wall -I../.. -I. -I.. -I$(HOME)/local/include -O1 -DNDEBUG src/table.cc
$(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table.out
+ g++ $(CXX_FLAGS) src/table.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o
bin/table.out
oldtable: demat.old.hh
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG src/table_old.cc
$(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/table_old.out
+ g++ $(CXX_FLAGS) src/table_old.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o
bin/table_old.out
photo: demat.hh
- g++ -Wextra -Wall -I../.. -I. -I.. -I$(HOME)/local/include -O1 -DNDEBUG src/photo.cc
$(HOME)/local/lib/libtesseract_full.a -lpthread -o bin/photo.out
+ g++ $(CXX_FLAGS) src/photo.cc $(HOME)/local/lib/libtesseract_full.a -lpthread -o
bin/photo.out
+
+dmap:
+ g++ $(CXX_FLAGS) src/dmap.cc -o bin/dmap.out
extract_text_single_link:
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG
src/extract_text_single_link.cc -o bin/extract_text_single_link.out
+ g++ $(CXX_FLAGS) src/extract_text_single_link.cc -o bin/extract_text_single_link.out
extract_text_double_link:
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG
src/extract_text_double_link.cc -o bin/extract_text_double_link.out
+ g++ $(CXX_FLAGS) src/extract_text_double_link.cc -o bin/extract_text_double_link.out
extract_text_multiple_links:
- g++ -Wextra -Wall -I../.. -I../ -I$(HOME)/local/include -O1 -DNDEBUG
src/extract_text_multiple_links.cc -o bin/extract_text_multiple_links.out
+ g++ $(CXX_FLAGS) src/extract_text_multiple_links.cc -o
bin/extract_text_multiple_links.out
+
+table_rebuild:
+ g++ $(CXX_FLAGS) src/table_rebuild.cc -o bin/table_rebuild.out
+
+table_extract:
+ g++ $(CXX_FLAGS) src/table_extract.cc -o bin/table_extract.out
+thin_bboxes:
+ g++ $(CXX_FLAGS) src/thin_bboxes.cc -o bin/thin_bboxes.out
clean:
rm *.ppm *.pgm *.pbm
diff --git a/milena/sandbox/scribo/core/central_sites.hh
b/milena/sandbox/scribo/core/central_sites.hh
index fe47625..80686f8 100644
--- a/milena/sandbox/scribo/core/central_sites.hh
+++ b/milena/sandbox/scribo/core/central_sites.hh
@@ -86,7 +86,7 @@ namespace scribo
p2[dim] += n / 2;
trace::exiting("scribo::central_sites");
- return make::couple(p1, p2);
+ return mln::make::couple(p1, p2);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/core/component_bboxes.hh
b/milena/sandbox/scribo/core/component_bboxes.hh
index 5af99fc..16b6fa0 100644
--- a/milena/sandbox/scribo/core/component_bboxes.hh
+++ b/milena/sandbox/scribo/core/component_bboxes.hh
@@ -43,23 +43,28 @@
# include <mln/util/array.hh>
+# include <mln/debug/println.hh>
namespace scribo
{
+ using namespace mln;
+
/// Extract the components bboxes.
template <typename I, typename N, typename V>
- util::array< box<mln_site(I)> >
+ util::couple<util::array< box<mln_site(I)> >, mln_ch_value(I,V)>
component_bboxes(const Image<I>& input,
- const Neighborhood<N>& nbh, const V& label_type);
+ const Neighborhood<N>& nbh,
+ V& nbboxes);
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename N, typename V>
inline
- util::array< box<mln_site(I)> >
+ util::couple<util::array< box<mln_site(I)> >, mln_ch_value(I,V)>
component_bboxes(const Image<I>& input,
- const Neighborhood<N>& nbh, const V&)
+ const Neighborhood<N>& nbh,
+ V& nbboxes)
{
trace::entering("scribo::component_bboxes");
@@ -68,13 +73,15 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
- V nbboxes;
mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nbboxes);
+ mln_assertion(exact(lbl).is_valid());
+
typedef util::array< box<mln_site(I)> > bboxes_t;
bboxes_t bboxes = labeling::compute(accu::meta::bbox(), lbl, nbboxes);
+ mln_postcondition(bboxes.nelements() == nbboxes.next());
trace::exiting("scribo::component_bboxes");
- return bboxes;
+ return mln::make::couple(bboxes, lbl);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/core/erase_bboxes.hh
b/milena/sandbox/scribo/core/erase_bboxes.hh
index cea998b..f4b2392 100644
--- a/milena/sandbox/scribo/core/erase_bboxes.hh
+++ b/milena/sandbox/scribo/core/erase_bboxes.hh
@@ -44,6 +44,8 @@
namespace scribo
{
+ using namespace mln;
+
/// Remove the content of bounding boxes from an image.
template <typename I>
void
@@ -68,7 +70,7 @@ namespace scribo
for_all_components(i, bboxes)
data::paste((pw::cst(false) | bboxes[i] |
- (pw::value(input) == true)), input);
+ (pw::value(input) == true)), input);
trace::exiting("scribo::erase_bboxes");
}
diff --git a/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh
b/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh
index a7f8927..4012c05 100644
--- a/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh
+++ b/milena/sandbox/scribo/debug/save_linked_textbboxes_image.hh
@@ -42,6 +42,7 @@
# include <scribo/draw/bounding_boxes.hh>
# include <scribo/draw/bounding_box_links.hh>
+# include <scribo/util/text.hh>
namespace scribo
@@ -54,32 +55,32 @@ namespace scribo
/// Save the bounding box links image.
- template <typename I>
+ template <typename I, typename L>
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& link_array,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& link_array,
const value::rgb8& box_value,
const value::rgb8& link_value,
const std::string& filename);
- template <typename I>
+ template <typename I, typename L>
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_array,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_array,
const value::rgb8& box_value,
const value::rgb8& left_link_value,
const value::rgb8& right_link_value,
const std::string& filename);
- template <typename I, typename G>
+ template <typename I, typename L, typename G>
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const scribo::util::text<L>& text,
const Graph<G>& g,
const value::rgb8& box_value,
const value::rgb8& link_value,
@@ -89,12 +90,12 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
- template <typename I>
+ template <typename I, typename L>
inline
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& link_array,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& link_array,
const value::rgb8& box_value,
const value::rgb8& link_value,
const std::string& filename)
@@ -103,21 +104,21 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
- draw::bounding_boxes(tmp, textbboxes, box_value);
- draw::bounding_box_links(tmp, textbboxes, link_array, link_value);
+ draw::bounding_boxes(tmp, text.bboxes(), box_value);
+ draw::bounding_box_links(tmp, text.bboxes(), link_array, link_value);
io::ppm::save(tmp, filename);
trace::exiting("scribo::debug::save_linked_textbboxes_image");
}
- template <typename I>
+ template <typename I, typename L>
inline
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_link,
+ const scribo::util::text<L>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link,
const value::rgb8& box_value,
const value::rgb8& left_value,
const value::rgb8& right_value,
@@ -127,8 +128,8 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
- draw::bounding_boxes(tmp, textbboxes, box_value);
- draw::bounding_box_links(tmp, textbboxes,
+ draw::bounding_boxes(tmp, text.bboxes(), box_value);
+ draw::bounding_box_links(tmp, text.bboxes(),
left_link, right_link,
left_value, right_value);
io::ppm::save(tmp, filename);
@@ -137,11 +138,11 @@ namespace scribo
}
- template <typename I, typename G>
+ template <typename I, typename L, typename G>
inline
void
save_linked_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const scribo::util::text<L>& text,
const Graph<G>& g,
const value::rgb8& box_value,
const value::rgb8& link_value,
@@ -152,8 +153,8 @@ namespace scribo
mln_precondition(exact(input).is_valid());
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
- draw::bounding_boxes(tmp, textbboxes, box_value);
- draw::bounding_box_links(tmp, textbboxes, g, link_value);
+ draw::bounding_boxes(tmp, text.bboxes(), box_value);
+ draw::bounding_box_links(tmp, text.bboxes(), g, link_value);
io::ppm::save(tmp, filename);
trace::exiting("scribo::debug::save_linked_textbboxes_image");
diff --git a/milena/sandbox/scribo/debug/save_table_image.hh
b/milena/sandbox/scribo/debug/save_table_image.hh
index b170420..4ed0a68 100644
--- a/milena/sandbox/scribo/debug/save_table_image.hh
+++ b/milena/sandbox/scribo/debug/save_table_image.hh
@@ -36,7 +36,9 @@
# include <string>
# include <mln/core/concept/image.hh>
+# include <mln/core/image/image2d.hh>
# include <mln/data/fill.hh>
+# include <mln/level/convert.hh>
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
# include <mln/value/rgb8.hh>
@@ -50,16 +52,29 @@ namespace scribo
namespace debug
{
- /// Save lines bounding boxes in an image filled with \p bg_color.
+ using namespace mln;
+
+ /// Save lines bounding boxes in a copy of \p input_.
/// Bounding boxes are displayed with \p bbox_color.
template <typename I>
void
- save_table(const Image<I>& input_,
- util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const value::rgb8& bg_color,
- const value::rgb8& bbox_color,
- const std::string& filename);
+ save_table_image(const Image<I>& input_,
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > > tableboxes,
+ const value::rgb8& bbox_color,
+ const std::string& filename);
+
+ /// Save lines bounding boxes in an image defined on \p input_domain
+ /// filled with \p bg_color.
+ /// Bounding boxes are displayed with \p bbox_color.
+ template <typename S>
+ void
+ save_table_image(const Site_Set<S>& input_domain,
+ util::couple<util::array<box<mln_site(S)> >,
+ util::array<box<mln_site(S)> > > tableboxes,
+ const value::rgb8& bg_color,
+ const value::rgb8& bbox_color,
+ const std::string& filename);
# ifndef MLN_INCLUDE_ONLY
@@ -67,18 +82,40 @@ namespace scribo
template <typename I>
void
- save_table(const Image<I>& input_,
- util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const value::rgb8& bg_color,
- const value::rgb8& bbox_color,
- const std::string& filename)
+ save_table_image(const Image<I>& input_,
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > > tableboxes,
+ const value::rgb8& bbox_color,
+ const std::string& filename)
{
trace::entering("scribo::debug::save_table_image");
+// mlc_converts_to(mln_value(I), value::rgb8)::check();
const I& input = exact(input_);
mln_precondition(input.is_valid());
- mln_ch_value(I,value::rgb8) out2(exact(input).domain());
+ mln_ch_value(I,value::rgb8) out2 = level::convert(value::rgb8(), input);
+ draw::bounding_boxes(out2, tableboxes.first(), bbox_color);
+ draw::bounding_boxes(out2, tableboxes.second(), bbox_color);
+ io::ppm::save(out2, filename);
+
+ trace::exiting("scribo::internal::save_table");
+ }
+
+
+ template <typename S>
+ void
+ save_table_image(const Site_Set<S>& input_domain_,
+ util::couple<util::array<box<mln_site(S)> >,
+ util::array<box<mln_site(S)> > > tableboxes,
+ const value::rgb8& bg_color,
+ const value::rgb8& bbox_color,
+ const std::string& filename)
+ {
+ trace::entering("scribo::debug::save_table_image");
+ const S& input_domain = exact(input_domain_);
+ mln_precondition(input_domain.is_valid());
+
+ image2d<value::rgb8> out2(input_domain);
data::fill(out2, bg_color);
draw::bounding_boxes(out2, tableboxes.first(), bbox_color);
draw::bounding_boxes(out2, tableboxes.second(), bbox_color);
diff --git a/milena/sandbox/scribo/debug/save_textbboxes_image.hh
b/milena/sandbox/scribo/debug/save_textbboxes_image.hh
index b210b39..86a8b3f 100644
--- a/milena/sandbox/scribo/debug/save_textbboxes_image.hh
+++ b/milena/sandbox/scribo/debug/save_textbboxes_image.hh
@@ -40,6 +40,7 @@
# include <mln/io/ppm/save.hh>
# include <scribo/draw/bounding_boxes.hh>
+# include <scribo/make/debug_filename.hh>
namespace scribo
@@ -55,7 +56,7 @@ namespace scribo
template <typename I>
void
save_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const mln::util::array< box<mln_site(I)> >& textbboxes,
const value::rgb8& value,
const std::string& filename);
@@ -66,7 +67,7 @@ namespace scribo
inline
void
save_textbboxes_image(const Image<I>& input,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const mln::util::array< box<mln_site(I)> >& textbboxes,
const value::rgb8& value,
const std::string& filename)
{
@@ -75,7 +76,7 @@ namespace scribo
mln_ch_value(I,value::rgb8) tmp = level::convert(value::rgb8(), input);
draw::bounding_boxes(tmp, textbboxes, value);
- io::ppm::save(tmp, filename);
+ io::ppm::save(tmp, scribo::make::debug_filename(filename));
trace::exiting("scribo::debug::save_textbboxes_image");
}
diff --git a/milena/sandbox/scribo/draw/bounding_box_links.hh
b/milena/sandbox/scribo/draw/bounding_box_links.hh
index 7cf57ac..e33da38 100644
--- a/milena/sandbox/scribo/draw/bounding_box_links.hh
+++ b/milena/sandbox/scribo/draw/bounding_box_links.hh
@@ -52,17 +52,17 @@ namespace scribo
template <typename I>
void
bounding_box_links(Image<I>& input_,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& link_array,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& link_array,
const mln_value(I)& value);
template <typename I>
void
bounding_box_links(Image<I>& input,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_link,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value);
@@ -78,7 +78,7 @@ namespace scribo
{
draw_graph_edges_functor(I& ima,
- const util::array<box<mln_site(I)> >& textbboxes,
+ const mln::util::array<box<mln_site(I)> >& textbboxes,
const mln_value(I)& value)
: ima_(ima), textbboxes_(textbboxes), value_(value)
{}
@@ -114,7 +114,7 @@ namespace scribo
{ return to_be_treated(id); }
I& ima_;
- const util::array<box<mln_site(I)> >& textbboxes_;
+ const mln::util::array<box<mln_site(I)> >& textbboxes_;
mln_value(I) value_;
unsigned current_vertex;
std::vector<bool> deja_vu;
@@ -127,8 +127,8 @@ namespace scribo
inline
void
bounding_box_links(Image<I>& input_,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& link_array,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& link_array,
const mln_value(I)& value)
{
trace::entering("scribo::draw::bounding_box_links");
@@ -152,9 +152,9 @@ namespace scribo
inline
void
bounding_box_links(Image<I>& input,
- const util::array< box<mln_site(I)> >& bboxes,
- const util::array<unsigned>& left_link,
- const util::array<unsigned>& right_link,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link,
const mln_value(I)& left_link_value,
const mln_value(I)& right_link_value)
{
@@ -172,7 +172,7 @@ namespace scribo
inline
void
bounding_box_links(Image<I>& input,
- const util::array< box<mln_site(I)> >& bboxes,
+ const mln::util::array< box<mln_site(I)> >& bboxes,
const Graph<G>& g,
const mln_value(I)& link_value)
{
diff --git a/milena/sandbox/scribo/draw/bounding_boxes.hh
b/milena/sandbox/scribo/draw/bounding_boxes.hh
index 0db60a4..bfebaf3 100644
--- a/milena/sandbox/scribo/draw/bounding_boxes.hh
+++ b/milena/sandbox/scribo/draw/bounding_boxes.hh
@@ -51,7 +51,7 @@ namespace scribo
template <typename I>
void
bounding_boxes(Image<I>& input_,
- const util::array< box<mln_site(I)> >& boxes,
+ const mln::util::array< box<mln_site(I)> >& boxes,
const mln_value(I)& value);
@@ -63,7 +63,7 @@ namespace scribo
inline
void
bounding_boxes(Image<I>& input_,
- const util::array< box<mln_site(I)> >& boxes,
+ const mln::util::array< box<mln_site(I)> >& boxes,
const mln_value(I)& value)
{
trace::entering("scribo::draw::bounding_boxes");
diff --git a/milena/sandbox/scribo/filter/large_components.hh
b/milena/sandbox/scribo/filter/large_components.hh
new file mode 100644
index 0000000..9ea4e02
--- /dev/null
+++ b/milena/sandbox/scribo/filter/large_components.hh
@@ -0,0 +1,196 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_FILTER_LARGE_COMPONENTS_HH
+# define SCRIBO_FILTER_LARGE_COMPONENTS_HH
+
+/// \file scribo/filter/large_components.hh
+///
+/// Remove large components in a binary image.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/relabel.hh>
+
+# include <mln/util/array.hh>
+# include <mln/value/label_16.hh>
+
+# include <mln/pw/all.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Remove large components in a binary image.
+ /// Set to 'false' all the removed components.
+ ///
+ /// \param[in] input_ A binary image.
+ /// \param[in] nbh_ A neighborhood used for labeling \p input_.
+ /// \param[in] label_type The label type used for labeling.
+ /// \param[in] max_size The minimum cardinality of a component.
+ ///
+ /// \return A binary image without large components.
+ template <typename I, typename N, typename V>
+ mln_concrete(I)
+ large_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_size);
+
+
+ /// Remove large bboxes in a binary image.
+ /// Set to 'false' all the removed bboxes.
+ ///
+ /// \param[in] input_ A binary image.
+ /// \param[in] bboxes Bounding boxes of components extracted from \p
+ /// input_.
+ /// \param[in] max_size The minimum cardinality of a component.
+ ///
+ /// \return A binary image without large bboxes.
+ template <typename P>
+ util::array< box<P> >
+ large_components(const util::array< box<P> >& bboxes,
+ unsigned max_size);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+
+ /// Filter Functor. Return false for all components which are too
+ /// large.
+ template <typename R>
+ struct filter_large_components_functor
+ : Function_l2b< filter_large_and_large_functor<R> >
+ {
+ filter_large_components_functor(const util::array<R>& nsitecomp,
+ unsigned max_size)
+ : nsitecomp_(nsitecomp), max_size_(max_size)
+ {
+ }
+
+
+ /// Return false if the components area is strictly inferior to
+ /// \p max_size_.
+ bool operator()(const value::label_16& l) const
+ {
+ return nsitecomp_[l] <= max_size_;
+ }
+
+
+ const util::array<R>& nsitecomp_;
+ unsigned max_size_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ large_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned max_size)
+ {
+ trace::entering("scribo::filter::large_components");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ V nlabels;
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nlabels);
+
+ typedef accu::count<mln_psite(I)> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef util::array<accu_count_res_t> nsitecomp_t;
+ nsitecomp_t nsitecomp = labeling::compute(accu_count_t(), lbl, nlabels);
+
+ typedef internal::filter_large_and_large_functor<accu_count_res_t> func_t;
+ func_t fl2b(nsitecomp, max_size);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | pw::value(lbl) == literal::zero).rw(), false);
+
+ trace::exiting("scribo::filter::large_components");
+ return output;
+ }
+
+
+ template <typename P>
+ inline
+ util::array< box<P> >
+ large_components(const util::array< box<P> >& bboxes,
+ unsigned max_size)
+ {
+ trace::entering("scribo::filter::large_components");
+
+ mln_precondition(input.is_valid());
+
+ typedef accu::count<P> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef util::array<accu_count_res_t> nsitecomp_t;
+
+ util::array<box<P> > result;
+ result.append(box<P>());
+ for_all_components(i, bboxes)
+ {
+ accu_count_res_t count = set::compute(accu_count_t(), bboxes[i]);
+ if (count <= max_size)
+ result.append(bboxes[i]);
+ }
+
+ trace::exiting("scribo::filter::large_components");
+ return result;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_LARGE_COMPONENTS_HH
diff --git a/milena/sandbox/scribo/filter/small_components.hh
b/milena/sandbox/scribo/filter/small_components.hh
new file mode 100644
index 0000000..8cb6858
--- /dev/null
+++ b/milena/sandbox/scribo/filter/small_components.hh
@@ -0,0 +1,207 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_FILTER_SMALL_COMPONENTS_HH
+# define SCRIBO_FILTER_SMALL_COMPONENTS_HH
+
+/// \file scribo/filter/small_components.hh
+///
+/// Remove small components in a binary image.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/relabel.hh>
+
+# include <mln/util/array.hh>
+# include <mln/value/label_16.hh>
+
+# include <mln/pw/all.hh>
+
+# include <scribo/util/text.hh>
+# include <scribo/make/text.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Remove small components in a binary image.
+ /// Set to 'false' all the removed components.
+ ///
+ /// \param[in] input_ A binary image.
+ /// \param[in] nbh_ A neighborhood used for labeling \p input_.
+ /// \param[in] label_type The label type used for labeling.
+ /// \param[in] min_size The minimum cardinality of a component.
+ ///
+ /// \return A binary image without small components.
+ template <typename I, typename N, typename V>
+ mln_concrete(I)
+ small_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned min_size);
+
+
+ /// Remove too small text components.
+ ///
+ /// \param[in] text Text data.
+ /// \param[in] min_size The minimum cardinality of a component.
+ ///
+ /// \return updated text data.
+ template <typename I>
+ scribo::util::text<I>
+ small_components(const scribo::util::text<I>& text,
+ unsigned min_size);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+
+ /// Filter Functor. Return false for all components which are too
+ /// small.
+ template <typename R>
+ struct filter_small_components_functor
+ : Function_l2b< filter_small_components_functor<R> >
+ {
+ filter_small_components_functor(const mln::util::array<R>& nsitecomp,
+ unsigned min_size)
+ : nsitecomp_(nsitecomp), min_size_(min_size)
+ {
+ }
+
+
+ /// Return false if the components area is strictly inferior to
+ /// \p min_size_.
+ bool operator()(const value::label_16& l) const
+ {
+ return nsitecomp_[l] >= min_size_;
+ }
+
+
+ const mln::util::array<R>& nsitecomp_;
+ unsigned min_size_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ small_components(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned min_size)
+ {
+ trace::entering("scribo::filter::small_components");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ V nlabels;
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nlabels);
+
+ typedef accu::count<mln_psite(I)> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef mln::util::array<accu_count_res_t> nsitecomp_t;
+ nsitecomp_t nsitecomp = labeling::compute(accu_count_t(), lbl, nlabels);
+
+ typedef internal::filter_small_components_functor<accu_count_res_t> func_t;
+ func_t fl2b(nsitecomp, min_size);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | pw::value(lbl) == literal::zero).rw(), false);
+
+ trace::exiting("scribo::filter::small_components");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ scribo::util::text<I>
+ small_components(const scribo::util::text<I>& text,
+ unsigned min_size)
+ {
+ trace::entering("scribo::filter::small_components");
+
+ mln_precondition(text.is_valid());
+
+ typedef mln_site(I) P;
+ typedef accu::count<P> accu_count_t;
+ typedef mln_result(accu_count_t) accu_count_res_t;
+ typedef mln::util::array<accu_count_res_t> nsitecomp_t;
+
+ fun::i2v::array<bool> f(text.nbboxes().next(), false);
+ f(0) = true;
+ mln::util::array<box<P> > bresult;
+ bresult.append(box<P>());
+ for_all_components(i, text.bboxes())
+ {
+ accu_count_res_t count = set::compute(accu_count_t(), text.bbox(i));
+ if (count >= min_size)
+ {
+ bresult.append(text.bbox(i));
+ f(i) = true;
+ }
+ }
+
+ mln_value(I) new_nbboxes;
+ I new_lbl = labeling::relabel(text.label_image(), text.nbboxes(),
+ new_nbboxes, f);
+
+ trace::exiting("scribo::filter::small_components");
+ return scribo::make::text(bresult, new_lbl, new_nbboxes);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_SMALL_COMPONENTS_HH
diff --git a/milena/sandbox/scribo/filter/thin_bboxes.hh
b/milena/sandbox/scribo/filter/thin_bboxes.hh
new file mode 100644
index 0000000..de99242
--- /dev/null
+++ b/milena/sandbox/scribo/filter/thin_bboxes.hh
@@ -0,0 +1,165 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_FILTER_THIN_BBOXES_HH
+# define SCRIBO_FILTER_THIN_BBOXES_HH
+
+/// \file scribo/filter/thin_bboxes.hh
+///
+/// Remove too thin bboxes.
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/compute.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/util/text.hh>
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+
+ /// Filter Functor. Return false for all components which are too
+ /// large.
+ template <typename R>
+ struct filter_too_thin_component_functor
+ : Function_l2b< filter_too_thin_component_functor<R> >
+ {
+ filter_too_thin_component_functor(const mln::util::array<R>& compbboxes,
+ unsigned min_thickness)
+ : compbboxes_(compbboxes), min_thickness_(min_thickness)
+ {
+ }
+
+
+ /// Return false if the components is thinner than
+ /// \p min_thickness_.
+ bool operator()(const value::label_16& l) const
+ {
+ return compbboxes_[l].nrows() > min_thickness_
+ && compbboxes_[l].ncols() > min_thickness_;
+ }
+
+
+ const mln::util::array<R>& compbboxes_;
+ unsigned min_thickness_;
+ };
+
+
+ } // end of namespace scribo::filter::internal
+
+
+ template <typename I, typename N, typename V>
+ inline
+ mln_concrete(I)
+ thin_bboxes(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const V& label_type,
+ unsigned min_thickness)
+ {
+ trace::entering("scribo::filter::thin_bboxes");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ V nlabels;
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nlabels);
+
+ typedef accu::bbox<mln_psite(I)> accu_bbox_t;
+ typedef mln_result(accu_bbox_t) accu_bbox_res_t;
+ typedef mln::util::array<accu_bbox_res_t> compbboxes_t;
+ compbboxes_t compbboxes = labeling::compute(accu_bbox_t(), lbl, nlabels);
+
+ typedef internal::filter_too_thin_component_functor<accu_bbox_res_t> func_t;
+ func_t fl2b(compbboxes, min_thickness);
+ labeling::relabel_inplace(lbl, nlabels, fl2b);
+
+ mln_concrete(I) output = duplicate(input);
+ data::fill((output | pw::value(lbl) == literal::zero).rw(), false);
+
+ trace::exiting("scribo::filter::thin_bboxes");
+ return output;
+ }
+
+
+ template <typename L>
+ inline
+ scribo::util::text<L>
+ thin_bboxes(const scribo::util::text<L>& text,
+ unsigned min_thickness)
+ {
+ trace::entering("scribo::filter::thin_bboxes");
+
+ mln_precondition(text.is_valid());
+
+ typedef mln_site(L) P;
+ typedef accu::bbox<P> accu_bbox_t;
+ typedef mln_result(accu_bbox_t) accu_bbox_res_t;
+ typedef mln::util::array<accu_bbox_res_t> nsitecomp_t;
+
+ typedef internal::filter_too_thin_component_functor<accu_bbox_res_t> func_t;
+ func_t is_not_too_thin(text.bboxes(), min_thickness);
+
+ fun::i2v::array<bool> f(text.nbboxes().next(), false);
+ f(0) = true;
+ mln::util::array<box<P> > bresult;
+ bresult.append(box<P>());
+ for_all_components(i, text.bboxes())
+ if (is_not_too_thin(i))
+ {
+ bresult.append(text.bbox(i));
+ f(i) = true;
+ }
+
+ mln_value(L) new_nbboxes;
+ L new_lbl = labeling::relabel(text.label_image(), text.nbboxes(),
+ mln::make::relabelfun(f, text.nbboxes(), new_nbboxes));
+
+ mln_assertion(new_nbboxes.next() == bresult.nelements());
+
+ trace::exiting("scribo::filter::thin_bboxes");
+ return scribo::make::text(bresult, new_lbl, new_nbboxes);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_FILTER_THIN_BBOXES_HH
diff --git a/milena/sandbox/scribo/make/debug_filename.hh
b/milena/sandbox/scribo/make/debug_filename.hh
index b159328..5a9728c 100644
--- a/milena/sandbox/scribo/make/debug_filename.hh
+++ b/milena/sandbox/scribo/make/debug_filename.hh
@@ -35,6 +35,7 @@
/// Construct and returns a formated output file name.
# include <sstream>
+# include <mln/trace/all.hh>
namespace scribo
@@ -46,25 +47,43 @@ namespace scribo
/// Construct and returns a formated output file name:
///
/// `input_filename`_`id`_`name`
+ /// \sa scribo::make::internal::debug_filename_prefix
std::string
- debug_filename(const char *input_filename,
- const char *name);
+ debug_filename(const std::string& name);
+ namespace internal
+ {
+
+ /// Set the default debug filename prefix.
+ extern char *debug_filename_prefix;
+
+ } // end of namespace scribo::make::internal
+
# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ char *debug_filename_prefix = 0;
+
+ } // end of namespace scribo::make::internal
+
+
inline
std::string
- debug_filename(const char *input_filename,
- const char *name)
+ debug_filename(const std::string& name)
{
static int file_id = 1;
std::ostringstream os;
- os << "./"
- << input_filename
- << "_";
+
+ if (internal::debug_filename_prefix != 0)
+ os << internal::debug_filename_prefix << "_";
+ else
+ mln::trace::warning("You may like to set a default filename prefix.");
if (file_id < 10)
os << "0";
diff --git a/milena/sandbox/scribo/text/extract_bboxes.hh
b/milena/sandbox/scribo/make/text.hh
similarity index 56%
copy from milena/sandbox/scribo/text/extract_bboxes.hh
copy to milena/sandbox/scribo/make/text.hh
index 0c88880..3c32ad0 100644
--- a/milena/sandbox/scribo/text/extract_bboxes.hh
+++ b/milena/sandbox/scribo/make/text.hh
@@ -1,5 +1,4 @@
// Copyright (C) 2009 EPITA Research and Development Laboratory
-// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -26,13 +25,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
+#ifndef SCRIBO_MAKE_TEXT_HH
+# define SCRIBO_MAKE_TEXT_HH
-#ifndef SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-# define SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-
-/// \file scribo/text/grouping/group_with_single_link.hh
+/// \file scribo/make/text.hh
///
-/// Extract text bounding boxes from a binary image.
+/// Construct a util::text.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
@@ -40,56 +38,77 @@
# include <mln/labeling/blobs.hh>
# include <mln/labeling/compute.hh>
# include <mln/util/array.hh>
+# include <scribo/util/text.hh>
-# include <scribo/core/component_bboxes.hh>
namespace scribo
{
- namespace text
+ namespace make
{
- using namespace mln;
- /// Extract text bounding boxes from a binary image.
- ///
- /// \param[in] input_ A binary image.
- ///
- /// \return an array of bounding boxes. The first bounding box is
- /// the background's.
+ template <typename L>
+ scribo::util::text<L>
+ text(const mln::util::array<box<mln_site(L)> >& bboxes,
+ const Image<L>& lbl,
+ mln_value(L)& nbboxes);
+
+
template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes);
+ scribo::util::text<mln_ch_value(I,V)>
+ text(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ V& nbboxes);
+
# ifndef MLN_INCLUDE_ONLY
+ template <typename L>
+ scribo::util::text<L>
+ text(const mln::util::array<box<mln_site(L)> >& bboxes,
+ const Image<L>& lbl,
+ mln_value(L)& nbboxes)
+ {
+ trace::entering("scribo::make::text");
+
+ mln_precondition(exact(lbl).is_valid());
+
+ scribo::util::text<L> result = scribo::util::text<L>(bboxes, lbl,
+ nbboxes);
+
+ trace::exiting("scribo::make::text");
+ return result;
+ }
+
+
template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes)
+ scribo::util::text<mln_ch_value(I,V)>
+ text(const Image<I>& input_, const Neighborhood<N>& nbh_,
+ V& nbboxes)
{
- trace::entering("scribo::text::extract_bboxes");
+ trace::entering("scribo::make::text");
const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
- mlc_equal(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ typedef mln::util::array< box<mln_site(I)> > boxes_t;
+
+ mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nbboxes);
- typedef util::array< box<mln_site(I)> > bboxes_t;
- bboxes_t bboxes = component_bboxes(input, nbh, nbboxes);
+ boxes_t cboxes = labeling::compute(accu::meta::bbox(), lbl, nbboxes);
- trace::exiting("scribo::text::extract_bboxes");
- return bboxes;
+ trace::exiting("scribo::make::text");
+ return make::text(cboxes, lbl, nbboxes);
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::text
+ } // end of namespace scribo::make
} // end of namespace scribo
-#endif // ! SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
+#endif // ! SCRIBO_MAKE_TEXT_HH
diff --git a/milena/sandbox/scribo/src/dmap.cc b/milena/sandbox/scribo/src/dmap.cc
new file mode 100644
index 0000000..dac40ba
--- /dev/null
+++ b/milena/sandbox/scribo/src/dmap.cc
@@ -0,0 +1,26 @@
+#include <mln/essential/2d.hh>
+#include <mln/core/var.hh>
+#include <mln/fun/l2l/wrap.hh>
+#include <mln/transform/distance_and_influence_zone_geodesic.hh>
+
+int main(int, char *argv[])
+{
+ using namespace mln;
+
+ using value::int_u16;
+ using value::label_16;
+ using value::label_8;
+ using value::rgb8;
+
+ image2d<bool> ima;
+ io::pbm::load(ima, argv[1]);
+
+ label_16 nlabels;
+ image2d<label_16> lbl = labeling::blobs(ima, c8(), nlabels);
+
+ mln_VAR(res, transform::distance_and_influence_zone_geodesic(lbl, c8(),
mln_max(unsigned)));
+
+ io::pgm::save(level::transform(res.first(), fun::l2l::wrap<label_8>()),
"dmap.pgm");
+ io::ppm::save(debug::colorize(value::rgb8(), res.second(), nlabels),
"iz.ppm");
+
+}
diff --git a/milena/sandbox/scribo/src/extract_text_double_link.cc
b/milena/sandbox/scribo/src/extract_text_double_link.cc
index 26fccff..ea4b2b8 100644
--- a/milena/sandbox/scribo/src/extract_text_double_link.cc
+++ b/milena/sandbox/scribo/src/extract_text_double_link.cc
@@ -28,6 +28,7 @@
#include <iostream>
#include <mln/essential/2d.hh>
+#include <mln/debug/colorize.hh>
#include <scribo/text/extract_bboxes.hh>
#include <scribo/text/grouping/group_with_single_left_link.hh>
@@ -44,17 +45,6 @@ int usage(const char *name)
}
-namespace scribo { namespace text { namespace grouping
-{
- using namespace mln;
-
- template <typename I>
- util::array< box<mln_site(I)> >
- group_from_double_link(const util::array< box<mln_site(I)> >&
textbboxes,
- util::array<unsigned>& left_link,
- util::array<unsigned>& right_link);
-}}}
-
int main(int argc, char* argv[])
{
using namespace scribo;
@@ -63,47 +53,56 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = "extract_text_double_link";
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ scribo::util::text<image2d<value::label_16> > text
+ = text::extract_bboxes(input, c8(), nbboxes);
- util::array<unsigned> left_link
- = text::grouping::group_with_single_left_link(input,
- c8(), nbboxes,
- textbboxes, 30);
- util::array<unsigned> right_link
- = text::grouping::group_with_single_right_link(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::array<unsigned> left_link
+ = text::grouping::group_with_single_left_link(text, 30);
+ mln::util::array<unsigned> right_link
+ = text::grouping::group_with_single_right_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes <<
std::endl;
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, left_link,
- literal::red, literal::cyan,
- "test_double_link_left_linked.ppm");
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, right_link,
- literal::red, literal::cyan,
- "test_double_link_right_linked.ppm");
+// scribo::debug::save_linked_textbboxes_image(input,
+// text, left_link,
+// literal::red, literal::cyan,
+// scribo::make::debug_filename("left_linked.ppm"));
+// scribo::debug::save_linked_textbboxes_image(input,
+// text, right_link,
+// literal::red, literal::cyan,
+// scribo::make::debug_filename("right_linked.ppm"));
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, left_link, right_link,
+ text, left_link, right_link,
literal::red, literal::cyan,
literal::yellow,
- "test_double_link_double_linked.ppm");
+ scribo::make::debug_filename("links.ppm"));
+
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
// With validation.
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_double_link(textbboxes, left_link, right_link);
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_double_link(text, left_link, right_link);
+
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("label_color.ppm"));
- std::cout << "AFTER double grouping - nbboxes = " <<
grouped_textbboxes.nelements() << std::endl;
+ std::cout << "AFTER double grouping - nbboxes = " <<
grouped_text.bboxes().nelements() << std::endl;
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_double_link_grouped_text.ppm");
+ scribo::make::debug_filename("bboxes.ppm"));
}
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
b/milena/sandbox/scribo/src/extract_text_multiple_links.cc
index 9b181e6..0c8c624 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/src/extract_text_multiple_links.cc
@@ -50,29 +50,39 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix =
"extract_text_multiple_links";
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ scribo::util::text<image2d<value::label_16> > text
+ = text::extract_bboxes(input, c8(), nbboxes);
- util::graph g = text::grouping::group_with_multiple_links(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::graph g = text::grouping::group_with_multiple_links(text, 30);
- std::cout << "BEFORE - nbboxes = " << nbboxes <<
std::endl;
+ std::cout << "BEFORE - nbboxes = " << nbboxes.next() <<
std::endl;
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, g,
+ text, g,
literal::red, literal::cyan,
- "test_multiple_links_left_linked.ppm");
+ scribo::make::debug_filename("left_linked.ppm"));
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_multiple_links(textbboxes, g);
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_multiple_links(text, g);
- std::cout << "AFTER - nbboxes = " <<
grouped_textbboxes.nelements() << std::endl;
+ std::cout << "AFTER - nbboxes = " <<
grouped_text.bboxes().nelements() << std::endl;
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_multiple_links_grouped_text.ppm");
+ scribo::make::debug_filename("grouped_text.ppm"));
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("label_color.ppm"));
+
}
diff --git a/milena/sandbox/scribo/src/extract_text_single_link.cc
b/milena/sandbox/scribo/src/extract_text_single_link.cc
index 5b4e248..1dee956 100644
--- a/milena/sandbox/scribo/src/extract_text_single_link.cc
+++ b/milena/sandbox/scribo/src/extract_text_single_link.cc
@@ -51,56 +51,70 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = "extract_text_single_link";
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ scribo::util::text<image2d<value::label_16> > text
+ = text::extract_bboxes(input, c8(), nbboxes);
{
std::cout << "* Left grouping" << std::endl;
- util::array<unsigned> left_link
- = text::grouping::group_with_single_left_link(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::array<unsigned> left_link
+ = text::grouping::group_with_single_left_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes <<
std::endl;
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, left_link,
+ text, left_link,
literal::red, literal::cyan,
- "test_single_left_link_linked.ppm");
-
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_single_link(textbboxes, left_link);
-
- std::cout << "AFTER - nbboxes = " <<
grouped_textbboxes.nelements() << std::endl;
-
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::make::debug_filename("left_links.ppm"));
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
+
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_single_link(text, left_link);
+
+ std::cout << "AFTER - nbboxes = " <<
grouped_text.bboxes().nelements() << std::endl;
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("left_label_color.ppm"));
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_single_left_link_grouped_text.ppm");
+ scribo::make::debug_filename("left_bboxes.ppm"));
}
{
std::cout << "* Left grouping" << std::endl;
- util::array<unsigned> right_link
- = text::grouping::group_with_single_right_link(input,
- c8(), nbboxes,
- textbboxes, 30);
+ mln::util::array<unsigned> right_link
+ = text::grouping::group_with_single_right_link(text, 30);
std::cout << "BEFORE - nbboxes = " << nbboxes <<
std::endl;
scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, right_link,
+ text, right_link,
literal::red, literal::cyan,
- "test_single_right_link_linked.ppm");
-
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_single_link(textbboxes, right_link);
-
- std::cout << "AFTER - nbboxes = " <<
grouped_textbboxes.nelements() << std::endl;
-
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
+ scribo::make::debug_filename("right_links.ppm"));
+// io::ppm::save(mln::debug::colorize(value::rgb8(),
+// text.label_image(),
+// text.nbboxes()),
+// scribo::make::debug_filename("lbl_before.ppm"));
+
+ scribo::util::text<image2d<value::label_16> > grouped_text
+ = text::grouping::group_from_single_link(text, right_link);
+
+ io::ppm::save(mln::debug::colorize(value::rgb8(),
+ grouped_text.label_image(),
+ grouped_text.nbboxes()),
+ scribo::make::debug_filename("right_label_color.ppm"));
+ std::cout << "AFTER - nbboxes = " <<
grouped_text.bboxes().nelements() << std::endl;
+
+ scribo::debug::save_textbboxes_image(input, grouped_text.bboxes(),
literal::red,
- "test_single_right_link_grouped_text.ppm");
+ scribo::make::debug_filename("right_bboxes.ppm"));
}
diff --git a/milena/sandbox/scribo/src/morpho.cc b/milena/sandbox/scribo/src/morpho.cc
new file mode 100644
index 0000000..a527a3d
--- /dev/null
+++ b/milena/sandbox/scribo/src/morpho.cc
@@ -0,0 +1,64 @@
+#include <mln/essential/2d.hh>
+#include <mln/transform/distance_and_influence_zone_geodesic.hh>
+#include <mln/core/var.hh>
+#include <mln/fun/l2l/wrap.hh>
+#include <mln/win/hline2d.hh>
+#include <mln/morpho/watershed/flooding.hh>
+#include <mln/morpho/watershed/superpose.hh>
+
+#include <scribo/make/debug_filename.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ using value::int_u16;
+ using value::label_16;
+ using value::label_8;
+ using value::rgb8;
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ scribo::make::internal::debug_filename_prefix = "morpho";
+
+ label_16 nlabels;
+ image2d<label_16> lbl = labeling::blobs(input, c8(), nlabels);
+
+ mln_VAR(res, transform::distance_and_influence_zone_geodesic(lbl, c8(),
mln_max(unsigned)));
+
+ io::pgm::save(level::transform(res.first(), fun::l2l::wrap<label_8>()),
"dmap.pgm");
+ io::ppm::save(debug::colorize(rgb8(), res.second(), nlabels), "iz.ppm");
+
+ image2d<unsigned>& dmap = res.first();
+ {
+ image2d<unsigned> clo = morpho::closing::structural(dmap, win::hline2d(51));
+ io::pgm::save(clo, scribo::make::debug_filename("clo_line_51.pgm"));
+ label_16 nlabels;
+ image2d<label_16> wsd = morpho::watershed::flooding(clo, c8(), nlabels);
+
+ io::ppm::save(morpho::watershed::superpose(input, wsd),
+ scribo::make::debug_filename("wsd_line_51.ppm"));
+ }
+
+ {
+ image2d<unsigned> clo = morpho::closing::structural(dmap, win::rectangle2d(11,
101));
+ io::pgm::save(clo,
scribo::make::debug_filename("clo_rectangle_11_101.pgm"));
+ label_16 nlabels;
+ image2d<label_16> wsd = morpho::watershed::flooding(clo, c8(), nlabels);
+
+ io::ppm::save(morpho::watershed::superpose(input, wsd),
+ scribo::make::debug_filename("wsd_rectangle_11_101.ppm"));
+ }
+
+ {
+ image2d<unsigned> clo = morpho::closing::structural(dmap, win::disk2d(51));
+ io::pgm::save(clo, scribo::make::debug_filename("clo_disk_51.pgm"));
+ label_16 nlabels;
+ image2d<label_16> wsd = morpho::watershed::flooding(clo, c8(), nlabels);
+
+ io::ppm::save(morpho::watershed::superpose(input, wsd),
+ scribo::make::debug_filename("wsd_disk_51.ppm"));
+ }
+
+???
diff --git a/milena/sandbox/scribo/src/table.cc b/milena/sandbox/scribo/src/table.cc
index 3472599..3a12c57 100644
--- a/milena/sandbox/scribo/src/table.cc
+++ b/milena/sandbox/scribo/src/table.cc
@@ -26,7 +26,7 @@
// Public License.
-#include "demat.hh"
+#include <demat.hh>
int main(int argc, char*argv[])
{
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
b/milena/sandbox/scribo/src/table_extract.cc
similarity index 61%
copy from milena/sandbox/scribo/src/extract_text_multiple_links.cc
copy to milena/sandbox/scribo/src/table_extract.cc
index 9b181e6..36142a2 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/src/table_extract.cc
@@ -28,13 +28,10 @@
#include <iostream>
#include <mln/essential/2d.hh>
+#include <mln/io/dump/save.hh>
-#include <scribo/text/extract_bboxes.hh>
-#include <scribo/text/grouping/group_with_multiple_links.hh>
-#include <scribo/text/grouping/group_from_multiple_links.hh>
+#include <scribo/table/extract.hh>
-#include <scribo/debug/save_textbboxes_image.hh>
-#include <scribo/debug/save_linked_textbboxes_image.hh>
int usage(const char *name)
{
@@ -42,6 +39,7 @@ int usage(const char *name)
return 1;
}
+
int main(int argc, char* argv[])
{
using namespace scribo;
@@ -50,29 +48,20 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = argv[0];
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
+ logical::not_inplace(input);
- value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
-
- util::graph g = text::grouping::group_with_multiple_links(input,
- c8(), nbboxes,
- textbboxes, 30);
+ trace::quiet = false;
- std::cout << "BEFORE - nbboxes = " << nbboxes <<
std::endl;
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, g,
- literal::red, literal::cyan,
- "test_multiple_links_left_linked.ppm");
+ value::label_16 ncells;
+ image2d<value::label_16> tables = scribo::table::extract(input, ncells);
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_multiple_links(textbboxes, g);
+ std::cout << "ncells (including background) = " << ncells
<< std::endl;
+ io::ppm::save(mln::debug::colorize(value::rgb8(), tables, ncells),
+ scribo::make::debug_filename("table_cells.ppm"));
- std::cout << "AFTER - nbboxes = " <<
grouped_textbboxes.nelements() << std::endl;
-
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
- literal::red,
- "test_multiple_links_grouped_text.ppm");
+ io::dump::save(tables, scribo::make::debug_filename("table_cells.dump"));
}
-
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
b/milena/sandbox/scribo/src/table_rebuild.cc
similarity index 61%
copy from milena/sandbox/scribo/src/extract_text_multiple_links.cc
copy to milena/sandbox/scribo/src/table_rebuild.cc
index 9b181e6..d195b5b 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/src/table_rebuild.cc
@@ -29,12 +29,11 @@
#include <mln/essential/2d.hh>
-#include <scribo/text/extract_bboxes.hh>
-#include <scribo/text/grouping/group_with_multiple_links.hh>
-#include <scribo/text/grouping/group_from_multiple_links.hh>
+#include <scribo/table/rebuild.hh>
+#include <scribo/table/erase.hh>
+#include <scribo/table/extract_lines_with_rank.hh>
+#include <scribo/make/debug_filename.hh>
-#include <scribo/debug/save_textbboxes_image.hh>
-#include <scribo/debug/save_linked_textbboxes_image.hh>
int usage(const char *name)
{
@@ -42,6 +41,7 @@ int usage(const char *name)
return 1;
}
+
int main(int argc, char* argv[])
{
using namespace scribo;
@@ -50,29 +50,30 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = argv[0];
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
+ logical::not_inplace(input);
- value::label_16 nbboxes;
- util::array<box2d> textbboxes = text::extract_bboxes(input, c8(), nbboxes);
+ typedef util::couple<util::array<box2d>,util::array<box2d> >
tblboxes_t;
- util::graph g = text::grouping::group_with_multiple_links(input,
- c8(), nbboxes,
- textbboxes, 30);
+ win::vline2d vline(51);
+ win::hline2d hline(51);
+ tblboxes_t lineboxes
+ = table::extract_lines_with_rank(input, c8(), value::label_16(),
+ vline, hline, 6, 6);
- std::cout << "BEFORE - nbboxes = " << nbboxes <<
std::endl;
- scribo::debug::save_linked_textbboxes_image(input,
- textbboxes, g,
- literal::red, literal::cyan,
- "test_multiple_links_left_linked.ppm");
+ value::label_8 ncells;
+ image2d<value::label_8> tables = scribo::table::rebuild(input, lineboxes, 30,
ncells);
- util::array< box<point2d> > grouped_textbboxes
- = text::grouping::group_from_multiple_links(textbboxes, g);
- std::cout << "AFTER - nbboxes = " <<
grouped_textbboxes.nelements() << std::endl;
+ std::cout << "ncells (including background) = " << ncells
<< std::endl;
+ io::ppm::save(mln::debug::colorize(value::rgb8(), tables, ncells),
+ scribo::make::debug_filename("table_cells.ppm"));
+ io::pgm::save(tables, scribo::make::debug_filename("table_cells.pgm"));
- scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
- literal::red,
- "test_multiple_links_grouped_text.ppm");
+ image2d<bool> in_wo_tables = table::erase(input, lineboxes);
+ io::pbm::save(in_wo_tables,
+ scribo::make::debug_filename("input_wo_tables.pbm"));
}
-
diff --git a/milena/sandbox/scribo/src/thin_bboxes.cc
b/milena/sandbox/scribo/src/thin_bboxes.cc
new file mode 100644
index 0000000..77b158b
--- /dev/null
+++ b/milena/sandbox/scribo/src/thin_bboxes.cc
@@ -0,0 +1,32 @@
+#include <mln/essential/2d.hh>
+#include <scribo/text/extract_lines.hh>
+#include <scribo/filter/thin_bboxes.hh>
+
+int usage(const char *name)
+{
+ std::cout << "Usage: " << name << " <input.pbm>
" << std::endl;
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc < 1)
+ return usage(argv[0]);
+
+ scribo::make::internal::debug_filename_prefix = "thin_bboxes";
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ value::label_16 nlines;
+ typedef scribo::util::text<image2d<value::label_16> > text_t;
+ text_t lines = scribo::text::extract_lines(input, c8(), nlines);
+
+ text_t filtered_lines = scribo::filter::thin_bboxes(lines, 5);
+
+ scribo::debug::save_textbboxes_image(input, filtered_lines.bboxes(),
+ literal::red,
+ scribo::make::debug_filename("thickness_filter"));
+}
diff --git a/milena/sandbox/scribo/table/align_lines_horizontaly.hh
b/milena/sandbox/scribo/table/align_lines_horizontaly.hh
index e75f2f2..4828cfe 100644
--- a/milena/sandbox/scribo/table/align_lines_horizontaly.hh
+++ b/milena/sandbox/scribo/table/align_lines_horizontaly.hh
@@ -38,8 +38,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/site_set/box.hh>
# include <mln/geom/nrows.hh>
-# include <mln/geom/min_nrow.hh>
-# include <mln/geom/max_nrow.hh>
+# include <mln/geom/min_row.hh>
+# include <mln/geom/max_row.hh>
# include <mln/util/array.hh>
@@ -52,18 +52,24 @@ namespace scribo
namespace table
{
+ using namespace mln;
+
/// Align line bounding boxes horizontaly.
///
/// \param[in] input Image from which the line bboxes are
/// extracted from.
/// \param[in, out] lines_bboxes horizontal lines bounding boxes.
+ /// \param[in] max_alignment_diff max space between two lines to
+ /// consider they are potentialy on the
+ /// same line.
///
/// \return A list of the resulting aligned rows. Each integer is actually
/// a row number.
template <typename I>
util::array<int>
align_lines_horizontaly(const Image<I>& input,
- util::array<box<mln_site(I)> >& lines_bboxes);
+ util::array<box<mln_site(I)> >& lines_bboxes,
+ unsigned max_alignment_diff);
# ifndef MLN_INCLUDE_ONLY
@@ -72,7 +78,8 @@ namespace scribo
template <typename I>
util::array<int>
align_lines_horizontaly(const Image<I>& input,
- util::array<box<mln_site(I)> >& lines_bboxes)
+ util::array<box<mln_site(I)> >& lines_bboxes,
+ max_alignment_diff)
{
trace::entering("scribo::table::align_lines_horizontaly");
@@ -80,7 +87,8 @@ namespace scribo
util::array<int> res = internal::align_lines(geom::nrows(input),
geom::min_row(input),
geom::max_row(input),
- lines_bboxes, 0);
+ lines_bboxes, 0,
+ max_alignment_diff);
trace::exiting("scribo::table::align_lines_horizontaly");
return res;
diff --git a/milena/sandbox/scribo/table/align_lines_verticaly.hh
b/milena/sandbox/scribo/table/align_lines_verticaly.hh
index 7e860d0..e4d04ba 100644
--- a/milena/sandbox/scribo/table/align_lines_verticaly.hh
+++ b/milena/sandbox/scribo/table/align_lines_verticaly.hh
@@ -38,8 +38,8 @@
# include <mln/core/concept/image.hh>
# include <mln/core/site_set/box.hh>
# include <mln/geom/ncols.hh>
-# include <mln/geom/min_ncol.hh>
-# include <mln/geom/max_ncol.hh>
+# include <mln/geom/min_col.hh>
+# include <mln/geom/max_col.hh>
# include <mln/util/array.hh>
@@ -53,18 +53,24 @@ namespace scribo
namespace table
{
+ using namespace mln;
+
/// Align line bounding boxes verticaly.
///
/// \param[in] input Image from which the line bboxes are
/// extracted from.
/// \param[in, out] lines_bboxes vertical lines bounding boxes.
+ /// \param[in] max_alignment_diff max space between two lines to
+ /// consider they are potentialy on the
+ /// same line.
///
/// \return A list of the resulting aligned cols. Each integer is actually
/// a col number.
template <typename I>
util::array<int>
align_lines_verticaly(const Image<I>& input,
- util::array<box<mln_site(I)> >& lines_bboxes);
+ util::array<box<mln_site(I)> >& lines_bboxes,
+ unsigned max_alignment_diff);
# ifndef MLN_INCLUDE_ONLY
@@ -81,7 +87,8 @@ namespace scribo
util::array<int> res = internal::align_lines(geom::ncols(input),
geom::min_col(input),
geom::max_col(input),
- lines_bboxes, 1);
+ lines_bboxes, 1,
+ max_alignment_diff);
trace::exiting("scribo::table::align_lines_horizontaly");
return res;
diff --git a/milena/sandbox/scribo/table/connect_horizontal_lines.hh
b/milena/sandbox/scribo/table/connect_horizontal_lines.hh
index 7dcf638..c1d3bd6 100644
--- a/milena/sandbox/scribo/table/connect_horizontal_lines.hh
+++ b/milena/sandbox/scribo/table/connect_horizontal_lines.hh
@@ -55,12 +55,15 @@ namespace scribo
/// bounding boxes.
/// \param[in] input The image from where the lines are
/// extracted.
+ /// \param[in] max_distance max distance allowed between a vertical
+ /// and horizontal lines.
template <typename I>
void
connect_vertical_lines(const util::array<int>& aligned_rows,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance);
# ifndef MLN_INCLUDE_ONLY
@@ -70,14 +73,15 @@ namespace scribo
void
connect_horizontal_lines(const util::array<int>& aligned_cols,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance)
{
trace::entering("scribo::table::connect_horizontal_lines");
mln_precondition(exact(input).is_valid());
internal::connect_lines(aligned_cols, tableboxes.second(),
- 1, exact(input).ncols());
+ 1, exact(input).ncols(), max_distance);
trace::exiting("scribo::table::connect_horizontal_lines");
}
diff --git a/milena/sandbox/scribo/table/connect_vertical_lines.hh
b/milena/sandbox/scribo/table/connect_vertical_lines.hh
index 98c39f7..2ab4990 100644
--- a/milena/sandbox/scribo/table/connect_vertical_lines.hh
+++ b/milena/sandbox/scribo/table/connect_vertical_lines.hh
@@ -55,12 +55,15 @@ namespace scribo
/// bounding boxes.
/// \param[in] input The image from where the lines are
/// extracted.
+ /// \param[in] max_distance max distance allowed between a vertical
+ /// and horizontal lines.
template <typename I>
void
connect_vertical_lines(const util::array<int>& aligned_rows,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance);
# ifndef MLN_INCLUDE_ONLY
@@ -71,14 +74,15 @@ namespace scribo
void
connect_vertical_lines(const util::array<int>& aligned_rows,
util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > > tableboxes,
- const Image<I>& input)
+ util::array<box<mln_site(I)> > >& tableboxes,
+ const Image<I>& input,
+ unsigned max_distance)
{
trace::entering("scribo::table::connect_vertical_lines");
mln_precondition(exact(input).is_valid());
internal::connect_lines(aligned_rows, tableboxes.first(),
- 0, exact(input).nrows());
+ 0, exact(input).nrows(), max_distance);
trace::exiting("scribo::table::connect_vertical_lines");
}
diff --git a/milena/sandbox/scribo/text/extract_bboxes.hh
b/milena/sandbox/scribo/table/extract.hh
similarity index 55%
copy from milena/sandbox/scribo/text/extract_bboxes.hh
copy to milena/sandbox/scribo/table/extract.hh
index 0c88880..06520c9 100644
--- a/milena/sandbox/scribo/text/extract_bboxes.hh
+++ b/milena/sandbox/scribo/table/extract.hh
@@ -26,70 +26,69 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
+#ifndef SCRIBO_TABLE_EXTRACT_HH
+# define SCRIBO_TABLE_EXTRACT_HH
-#ifndef SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-# define SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
-
-/// \file scribo/text/grouping/group_with_single_link.hh
+/// \file scribo/table/extract.hh
///
-/// Extract text bounding boxes from a binary image.
+/// Extract tables from a binary image.
+/// Use arbitrary criterions.
# include <mln/core/concept/image.hh>
-# include <mln/core/concept/neighborhood.hh>
-# include <mln/core/site_set/box.hh>
-# include <mln/labeling/blobs.hh>
-# include <mln/labeling/compute.hh>
+# include <mln/util/couple.hh>
# include <mln/util/array.hh>
-# include <scribo/core/component_bboxes.hh>
+# include <scribo/table/rebuild.hh>
+# include <scribo/table/erase.hh>
+# include <scribo/table/extract_lines_with_rank.hh>
+
+# include <scribo/make/debug_filename.hh>
+
namespace scribo
{
- namespace text
+ namespace table
{
- using namespace mln;
+ template <typename I, typename V>
+ mln_ch_value(I,V)
+ extract(const Image<I>& input_, V& ncells);
- /// Extract text bounding boxes from a binary image.
- ///
- /// \param[in] input_ A binary image.
- ///
- /// \return an array of bounding boxes. The first bounding box is
- /// the background's.
- template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes);
# ifndef MLN_INCLUDE_ONLY
-
- template <typename I, typename N, typename V>
+ template <typename I, typename V>
inline
- util::array< box<mln_site(I)> >
- extract_bboxes(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes)
+ mln_ch_value(I,V)
+ extract(const Image<I>& input_, V& ncells)
{
- trace::entering("scribo::text::extract_bboxes");
+ trace::entering("scribo::table::extract");
const I& input = exact(input_);
-
- mlc_equal(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
+ mlc_equal(mln_value(I), bool)::check();
+
+ typedef util::array< box<mln_site(I)> > boxarray_t;
+ typedef util::couple<boxarray_t, boxarray_t> tblboxes_t;
+
+ win::line<mln_grid(I::site), 0, mln_coord(I::site)> vline(51);
+ win::line<mln_grid(I::site), 1, mln_coord(I::site)> hline(51);
+ tblboxes_t lineboxes
+ = table::extract_lines_with_rank(input, c8(), V(),
+ vline, hline, 6, 6);
- typedef util::array< box<mln_site(I)> > bboxes_t;
- bboxes_t bboxes = component_bboxes(input, nbh, nbboxes);
+ image2d<V> tables
+ = scribo::table::rebuild(input, lineboxes, 30, ncells);
- trace::exiting("scribo::text::extract_bboxes");
- return bboxes;
+ trace::exiting("scribo::table::extract");
+ return tables;
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::text
+ } // end of namespace scribo::table
} // end of namespace scribo
-#endif // ! SCRIBO_TEXT_GROUPING_EXTRACT_BBOXES_HH
+#endif // ! SCRIBO_TABLE_EXTRACT_HH
diff --git a/milena/sandbox/scribo/table/extract_lines_with_rank.hh
b/milena/sandbox/scribo/table/extract_lines_with_opening.hh
similarity index 67%
copy from milena/sandbox/scribo/table/extract_lines_with_rank.hh
copy to milena/sandbox/scribo/table/extract_lines_with_opening.hh
index 242dc30..55fd77f 100644
--- a/milena/sandbox/scribo/table/extract_lines_with_rank.hh
+++ b/milena/sandbox/scribo/table/extract_lines_with_opening.hh
@@ -27,12 +27,12 @@
// Public License.
-#ifndef SCRIBO_TABLE_EXTRACT_LINES_WITH_RANK_HH
-# define SCRIBO_TABLE_EXTRACT_LINES_WITH_RANK_HH
+#ifndef SCRIBO_TABLE_EXTRACT_LINES_WITH_OPENING_HH
+# define SCRIBO_TABLE_EXTRACT_LINES_WITH_OPENING_HH
-/// \file scribo/table/extract_lines_with_rank.hh
+/// \file scribo/table/extract_lines_with_opening.hh
///
-/// Extract table lines using a rank filter.
+/// Extract table lines using a morphological opening filter.
# include <mln/core/concept/image.hh>
@@ -40,14 +40,14 @@
# include <mln/core/concept/neighborhood.hh>
# include <mln/core/site_set/box.hh>
-# include <mln/morpho/rank_filter.hh>
+# include <mln/morpho/erosion.hh>
# include <mln/accu/bbox.hh>
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
-
+# include <scribo/core/macros.hh>
# include <scribo/core/component_bboxes.hh>
namespace scribo
@@ -56,18 +56,18 @@ namespace scribo
namespace table
{
- /// Find table bboxes thanks to a rank filter.
+ using namespace mln;
+
+ /// Find table bboxes thanks to a opening filter.
/*!
*
* \param[in] input_ A binary image.
* \param[in] nbh_ The neighborhood used for labeling image components.
* \param[in] label_type The type used to store the labels.
- * \param[in] vwin Window used to extract the vertical lines in the rank
- * filter.
- * \param[in] hwin Window used to extract the horizontal lines in the rank
- * filter.
- * \param[in] vrank_k Rank used for vertical lines filtering.
- * \param[in] hrank_k Rank used for horizontal lines filtering.
+ * \param[in] vwin Window used to extract the vertical lines in a morphological
+ * opening
+ * \param[in] hwin Window used to extract the horizontal lines in a morphological
+ * opening
*
* \return pair of array of bounding boxes. The first array holds the
* vertical lines bounding boxes and the second one the
@@ -76,45 +76,58 @@ namespace scribo
template <typename I, typename N, typename V, typename HW, typename VW>
util::couple<util::array<box<mln_site(I)> >,
util::array<box<mln_site(I)> > >
- extract_lines_with_rank(const Image<I>& input_,
- const Neighborhood<N>& nbh_, const V& label_type,
- const Window<HW>& vwin, const Window<VW>& hwin,
- unsigned vrank_k, unsigned hrank_k);
+ extract_lines_with_opening(const Image<I>& input_,
+ const Neighborhood<N>& nbh_, const V& label_type,
+ const Window<HW>& vwin, const Window<VW>& hwin);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V, typename HW, typename VW>
+ template <typename I, typename N, typename V, typename VW, typename HW>
inline
util::couple<util::array<box<mln_site(I)> >,
util::array<box<mln_site(I)> > >
- extract_lines_with_rank(const Image<I>& input_,
+ extract_lines_with_opening(const Image<I>& input_,
const Neighborhood<N>& nbh_, const V& label_type,
- const Window<HW>& vwin, const Window<VW>& hwin,
- unsigned vrank_k, unsigned hrank_k)
+ const Window<VW>& vwin_, const Window<HW>& hwin_);
{
- trace::entering("scribo::table::extract_lines_with_rank");
+ trace::entering("scribo::table::extract_lines_with_opening");
mlc_equal(mln_value(I),bool)::check();
mlc_is_a(V, mln::value::Symbolic)::check();
+
const I& input = exact(input_);
const N& nbh = exact(nbh_);
+ const VW& vwin = exact(vwin_);
+ const HW& hwin = exact(hwin_);
+
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
- mln_precondition(exact(vwin).is_valid());
- mln_precondition(exact(hwin).is_valid());
+ mln_precondition(vwin.is_valid());
+ mln_precondition(hwin.is_valid());
typedef accu::bbox<mln_psite(I)> A;
typedef util::array<mln_result(A)> boxes_t;
// Vertical lines
- mln_ch_value(I,bool) vfilter = morpho::rank_filter(input, vwin, vrank_k);
+ mln_ch_value(I,bool) vfilter = morpho::erosion(input, vwin);
boxes_t vboxes = component_bboxes(vfilter, nbh, label_type);
+ for_all_components(i, vboxes)
+ {
+ vboxes[i].enlarge(0, vwin.length() / 2);
+ vboxes[i].crop_wrt(input.domain());
+ }
// Horizontal lines.
- mln_ch_value(I,bool) hfilter = morpho::rank_filter(input, hwin, hrank_k);
+ mln_ch_value(I,bool) hfilter = morpho::erosion(input, hwin);
boxes_t hboxes = component_bboxes(hfilter, nbh, label_type);
+ for_all_components(i, hboxes)
+ {
+ hboxes[i].enlarge(1, hwin.length() / 2);
+ hboxes[i].crop_wrt(input.domain());
+ }
+ trace::exiting("scribo::table::extract_lines_with_opening");
return mln::make::couple(vboxes, hboxes);
}
@@ -124,4 +137,4 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_TABLE_EXTRACT_LINES_WITH_RANK_HH
+#endif // ! SCRIBO_TABLE_EXTRACT_LINES_WITH_OPENING_HH
diff --git a/milena/sandbox/scribo/table/extract_lines_with_rank.hh
b/milena/sandbox/scribo/table/extract_lines_with_rank.hh
index 242dc30..63c90b1 100644
--- a/milena/sandbox/scribo/table/extract_lines_with_rank.hh
+++ b/milena/sandbox/scribo/table/extract_lines_with_rank.hh
@@ -47,7 +47,7 @@
# include <mln/util/array.hh>
# include <mln/util/couple.hh>
-
+# include <scribo/core/macros.hh>
# include <scribo/core/component_bboxes.hh>
namespace scribo
@@ -56,6 +56,8 @@ namespace scribo
namespace table
{
+ using namespace mln;
+
/// Find table bboxes thanks to a rank filter.
/*!
*
@@ -84,25 +86,29 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V, typename HW, typename VW>
+ template <typename I, typename N, typename V, typename VW, typename HW>
inline
util::couple<util::array<box<mln_site(I)> >,
util::array<box<mln_site(I)> > >
extract_lines_with_rank(const Image<I>& input_,
const Neighborhood<N>& nbh_, const V& label_type,
- const Window<HW>& vwin, const Window<VW>& hwin,
+ const Window<VW>& vwin_, const Window<HW>& hwin_,
unsigned vrank_k, unsigned hrank_k)
{
trace::entering("scribo::table::extract_lines_with_rank");
mlc_equal(mln_value(I),bool)::check();
mlc_is_a(V, mln::value::Symbolic)::check();
+
const I& input = exact(input_);
const N& nbh = exact(nbh_);
+ const VW& vwin = exact(vwin_);
+ const HW& hwin = exact(hwin_);
+
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
- mln_precondition(exact(vwin).is_valid());
- mln_precondition(exact(hwin).is_valid());
+ mln_precondition(vwin.is_valid());
+ mln_precondition(hwin.is_valid());
typedef accu::bbox<mln_psite(I)> A;
typedef util::array<mln_result(A)> boxes_t;
@@ -110,11 +116,22 @@ namespace scribo
// Vertical lines
mln_ch_value(I,bool) vfilter = morpho::rank_filter(input, vwin, vrank_k);
boxes_t vboxes = component_bboxes(vfilter, nbh, label_type);
+ for_all_components(i, vboxes)
+ {
+ vboxes[i].enlarge(0, vwin.length() / 2);
+ vboxes[i].crop_wrt(input.domain());
+ }
// Horizontal lines.
mln_ch_value(I,bool) hfilter = morpho::rank_filter(input, hwin, hrank_k);
boxes_t hboxes = component_bboxes(hfilter, nbh, label_type);
+ for_all_components(i, hboxes)
+ {
+ hboxes[i].enlarge(1, hwin.length() / 2);
+ hboxes[i].crop_wrt(input.domain());
+ }
+ trace::exiting("scribo::table::extract_lines_with_rank");
return mln::make::couple(vboxes, hboxes);
}
diff --git a/milena/sandbox/scribo/table/internal/align_lines.hh
b/milena/sandbox/scribo/table/internal/align_lines.hh
index aaad9fa..202b2dd 100644
--- a/milena/sandbox/scribo/table/internal/align_lines.hh
+++ b/milena/sandbox/scribo/table/internal/align_lines.hh
@@ -51,6 +51,8 @@ namespace scribo
namespace internal
{
+ using namespace mln;
+
/// Align table lines bboxes according to a given dimension.
///
/// \return A list of the resulting aligned cols. Each integer is actually
@@ -102,7 +104,8 @@ namespace scribo
int min_coord,
int max_coord,
util::array<box<P> >& line_boxes,
- unsigned dim)
+ unsigned dim,
+ unsigned max_alignment_diff)
{
trace::entering("scribo::internal::align_lines");
@@ -114,9 +117,9 @@ namespace scribo
// Map components with actual lines.
for_all_components(i, line_boxes)
{
- int minline = line_boxes[i].pmin()[dim] - 5;
+ int minline = line_boxes[i].pmin()[dim] - max_alignment_diff;
minline = (minline < min_coord ? min_coord : minline);
- int maxline = line_boxes[i].pmax()[dim] + 5;
+ int maxline = line_boxes[i].pmax()[dim] + max_alignment_diff;
maxline = (maxline > max_coord ? max_coord : maxline);
for (int line = minline;
diff --git a/milena/sandbox/scribo/table/internal/connect_lines.hh
b/milena/sandbox/scribo/table/internal/connect_lines.hh
index d510fe2..08f395f 100644
--- a/milena/sandbox/scribo/table/internal/connect_lines.hh
+++ b/milena/sandbox/scribo/table/internal/connect_lines.hh
@@ -35,6 +35,7 @@
/// Connect vertical lines with aligned rows.
# include <mln/core/image/image1d.hh>
+# include <mln/core/alias/neighb1d.hh>
# include <mln/data/fill.hh>
@@ -45,7 +46,7 @@
# include <mln/opt/at.hh>
# include <scribo/core/macros.hh>
-
+# include <scribo/core/central_sites.hh>
namespace scribo
{
@@ -56,6 +57,8 @@ namespace scribo
namespace internal
{
+ using namespace mln;
+
/// Connect vertical and horizontal lines if they are close to each other.
///
/// ------ ------
@@ -70,7 +73,8 @@ namespace scribo
connect_lines(const util::array<int>& aligned_lines,
util::array< box<P> >& boxes,
unsigned dim,
- unsigned dim_size);
+ unsigned dim_size,
+ unsigned max_distance);
# ifndef MLN_INCLUDE_ONLY
@@ -81,7 +85,8 @@ namespace scribo
connect_lines(const util::array<int>& aligned_lines,
util::array< box<P> >& boxes,
unsigned dim,
- unsigned dim_size)
+ unsigned dim_size,
+ unsigned max_distance)
{
trace::entering("scribo::table::internal::connect_lines");
@@ -91,12 +96,12 @@ namespace scribo
for_all_elements(i, aligned_lines)
opt::at(l, aligned_lines[i]) = i;
- for (unsigned i = 0; i < settings.max_dist_lines; ++i)
+ for (unsigned i = 0; i < max_distance; ++i)
l = morpho::elementary::dilation(l, c2());
for_all_components(i, boxes)
{
- util::couple<point2d, point2d> cp = central_sites(boxes[i], dim);
+ util::couple<P,P> cp = central_sites(boxes[i], dim);
if (opt::at(l, cp.first()[dim]) != -1)
boxes[i].pmin()[dim] = aligned_lines[opt::at(l, cp.first()[dim])];
if (opt::at(l, cp.second()[dim]) != -1)
@@ -110,6 +115,8 @@ namespace scribo
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace scribo::table::internal
+
} // end of namespace scribo::table
} // end of namespace scribo
diff --git a/milena/sandbox/scribo/table/internal/repair_lines.hh
b/milena/sandbox/scribo/table/internal/repair_lines.hh
index 87f0933..cf21564 100644
--- a/milena/sandbox/scribo/table/internal/repair_lines.hh
+++ b/milena/sandbox/scribo/table/internal/repair_lines.hh
@@ -41,10 +41,17 @@
# include <mln/data/fill.hh>
# include <mln/util/couple.hh>
# include <mln/util/array.hh>
+# include <mln/util/ord.hh>
# include <mln/win/line.hh>
# include <mln/pw/all.hh>
+# include <mln/debug/colorize.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/value/label_16.hh>
+# include <scribo/make/debug_filename.hh>
+
# include <scribo/core/central_sites.hh>
+# include <scribo/core/macros.hh>
# include <scribo/table/internal/repair_lines.hh>
@@ -57,15 +64,23 @@ namespace scribo
namespace internal
{
+ /// Repair lines which have small discontinuities.
+ /// FIXME: buggy. Sometimes few lines move or shrink!
+ template <unsigned axis, typename I>
+ void
+ repair_lines(const Image<I>& input_,
+ util::array<box<mln_site(I)> >& tableboxes,
+ unsigned max_discontinuity);
+
# ifndef MLN_INCLUDE_ONLY
- /// Repair lines which have small discontinuities.
- /// FIXME: buggy. Sometimes few lines move or shrink!
+
template <unsigned axis, typename I>
void
repair_lines(const Image<I>& input_,
- util::array<box<mln_site(I)> >& tableboxes)
+ util::array<box<mln_site(I)> >& tableboxes,
+ unsigned max_discontinuity)
{
trace::entering("scribo::table::internal::repair_lines");
@@ -76,7 +91,7 @@ namespace scribo
typedef win::line<mln_grid(P), axis, mln_coord(P)> line_t;
// Initialization
- mln_ch_value(I,unsigned) l(input.domain());
+ mln_ch_value(I,value::label_16) l(input.domain());
data::fill(l, literal::zero);
for_all_components(i, tableboxes)
{
@@ -86,28 +101,52 @@ namespace scribo
}
// Repair
- extension_val<mln_ch_value(I,unsigned)> l_ext(l, literal::zero);
+ extension_val<mln_ch_value(I,value::label_16)> l_ext(l, literal::zero);
util::array<box<P> > result;
std::vector<bool> to_keep(tableboxes.nelements(), true);
- mln_VAR(tbb_ima, extend(l | pw::value(l) != literal::zero, l));
+ mln_VAR(tbb_ima, extend(l | pw::value(l) != pw::cst(literal::zero), l));
//FIXME: use a half window, just the bottom of the vertical line.
- line_t vl(settings.repair_max_dist);
+ line_t vl(max_discontinuity);
mln_piter(tbb_ima_t) p(tbb_ima.domain());
mln_qiter(line_t) q(vl, p);
for_all(p)
+ {
+ util::couple<P,P> cp_p = central_sites(tableboxes[l_ext(p)], axis);
for_all(q)
if (l_ext(q) != literal::zero && l_ext(q) != l_ext(p))
{
- to_keep[l_ext(q)] = false;
-
- tableboxes[l_ext(p)].pmax() = tableboxes[l_ext(q)].pmax();
-
- util::couple<P,P> cp = central_sites(tableboxes[l_ext(q)], axis);
- l_ext(cp.first()) = l_ext(p);
- l_ext(cp.second()) = l_ext(p);
+ if (util::ord_strict(tableboxes[l_ext(p)].pmax(),
+ tableboxes[l_ext(q)].pmax()))
+ {
+ tableboxes[l_ext(p)].pmax() = tableboxes[l_ext(q)].pmax();
+ to_keep[l_ext(q)] = false;
+ }
+
+ if (util::ord_strict(tableboxes[l_ext(q)].pmin(),
+ tableboxes[l_ext(p)].pmin()))
+ {
+ tableboxes[l_ext(p)].pmin() = tableboxes[l_ext(q)].pmin();
+ to_keep[l_ext(q)] = false;
+ }
+
+ if (!to_keep[l_ext(q)])
+ {
+ util::couple<P,P> cp_q = central_sites(tableboxes[l_ext(q)], axis);
+ l_ext(cp_q.first()) = literal::zero;
+ l_ext(cp_q.second()) = literal::zero;
+
+ unsigned p_i = l_ext(p);
+ l_ext(cp_p.first()) = literal::zero;
+ l_ext(cp_p.second()) = literal::zero;
+
+ util::couple<P,P> new_cp_p = central_sites(tableboxes[p_i], axis);
+ l_ext(new_cp_p.first()) = p_i;
+ l_ext(new_cp_p.second()) = p_i;
+ }
}
+ }
// Remove merged boxes.
diff --git a/milena/sandbox/scribo/table/rebuild.hh
b/milena/sandbox/scribo/table/rebuild.hh
new file mode 100644
index 0000000..b78112d
--- /dev/null
+++ b/milena/sandbox/scribo/table/rebuild.hh
@@ -0,0 +1,147 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_TABLE_REBUILD_HH
+# define SCRIBO_TABLE_REBUILD_HH
+
+/// \file scribo/table/rebuild.hh
+///
+/// Rebuild a table from its line bounding boxes.
+
+# include <mln/core/concept/image.hh>
+# include <mln/labeling/background.hh>
+# include <mln/util/array.hh>
+# include <mln/util/couple.hh>
+# include <mln/value/label_8.hh>
+
+# include <scribo/table/align_lines_verticaly.hh>
+# include <scribo/table/align_lines_horizontaly.hh>
+# include <scribo/table/connect_vertical_lines.hh>
+# include <scribo/table/connect_horizontal_lines.hh>
+# include <scribo/table/repair_horizontal_lines.hh>
+# include <scribo/table/repair_vertical_lines.hh>
+
+# include <scribo/debug/save_table_image.hh>
+
+
+
+namespace scribo
+{
+
+ namespace table
+ {
+
+ template <typename I, typename V>
+ mln_ch_value(I,V)
+ rebuild(const Image<I>& in_,
+ const util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > >& lineboxes,
+ unsigned max_dist_lines,
+ V& ncells);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename V>
+ mln_ch_value(I,V)
+ rebuild(const Image<I>& in_,
+ const util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > >& lineboxes,
+ unsigned max_dist_lines,
+ V& ncells)
+ {
+ trace::entering("scribo::table::rebuild");
+ const I& in = exact(in_);
+
+ mlc_equal(mln_value(I), bool)::check();
+ mln_precondition(in.is_valid());
+
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > > tblboxes = lineboxes;
+
+//# ifndef SCRIBO_NDEBUG
+// scribo::debug::save_table_image(in, tblboxes,
+// literal::red, "table.ppm");
+//# endif
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-raw.ppm");
+
+ util::array<int> rows = align_lines_horizontaly(in, tblboxes.second(), 5);
+ util::array<int> cols = align_lines_verticaly(in, tblboxes.first(), 5);
+
+# ifndef SCRIBO_NDEBUG
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-aligned.ppm");
+# endif
+
+ repair_vertical_lines(in, tblboxes, 30);
+ repair_horizontal_lines(in, tblboxes, 30);
+
+# ifndef SCRIBO_NDEBUG
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-repaired.ppm");
+# endif
+
+ // Connect vertical lines with horizontal lines.
+ connect_vertical_lines(rows, tblboxes, in, max_dist_lines);
+ connect_horizontal_lines(cols, tblboxes, in, max_dist_lines);
+
+# ifndef SCRIBO_NDEBUG
+ scribo::debug::save_table_image(in, tblboxes,
+ literal::red, "table-connected.ppm");
+# endif
+
+
+ mln_ch_value(I,bool) res;
+ initialize(res, in);
+ data::fill(res, false);
+ for_all_components(i, tblboxes.first())
+ mln::draw::box(res, tblboxes.first()[i], true);
+ for_all_components(i, tblboxes.second())
+ mln::draw::box(res, tblboxes.second()[i], true);
+
+ mln_ch_value(I,V) lbl = labeling::background(res, c8(), ncells);
+
+//# ifndef SCRIBO_NDEBUG
+// scribo::debug::save_table_image(in, tblboxes,
+// literal::red, "table-connected.ppm");
+//# endif
+
+ trace::exiting("scribo::table::rebuild");
+ return lbl;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::table
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_TABLE_REBUILD_HH
diff --git a/milena/sandbox/scribo/table/repair_horizontal_lines.hh
b/milena/sandbox/scribo/table/repair_horizontal_lines.hh
index 7c1edbd..e871480 100644
--- a/milena/sandbox/scribo/table/repair_horizontal_lines.hh
+++ b/milena/sandbox/scribo/table/repair_horizontal_lines.hh
@@ -59,9 +59,9 @@ namespace scribo
template <typename I>
void
repair_horizontal_lines(const Image<I>& input,
- util::couple<util::array<box<mln_site(I)> >,
- util::array<box<mln_site(I)> > >& tableboxes,
- unsigned max_discontinuity);
+ util::couple<util::array<box<mln_site(I)> >,
+ util::array<box<mln_site(I)> > >& tableboxes,
+ unsigned max_discontinuity);
# ifndef MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
b/milena/sandbox/scribo/tests/filter/small_and_large_bboxes.cc
similarity index 87%
copy from milena/sandbox/scribo/src/extract_text_multiple_links.cc
copy to milena/sandbox/scribo/tests/filter/small_and_large_bboxes.cc
index 9b181e6..2cf7ebc 100644
--- a/milena/sandbox/scribo/src/extract_text_multiple_links.cc
+++ b/milena/sandbox/scribo/tests/filter/small_and_large_bboxes.cc
@@ -32,6 +32,7 @@
#include <scribo/text/extract_bboxes.hh>
#include <scribo/text/grouping/group_with_multiple_links.hh>
#include <scribo/text/grouping/group_from_multiple_links.hh>
+#include <scribo/filter/small_components.hh>
#include <scribo/debug/save_textbboxes_image.hh>
#include <scribo/debug/save_linked_textbboxes_image.hh>
@@ -50,6 +51,8 @@ int main(int argc, char* argv[])
if (argc < 1)
return usage(argv[0]);
+ scribo::make::internal::debug_filename_prefix = argv[0];
+
image2d<bool> input;
io::pbm::load(input, argv[1]);
@@ -66,7 +69,7 @@ int main(int argc, char* argv[])
literal::red, literal::cyan,
"test_multiple_links_left_linked.ppm");
- util::array< box<point2d> > grouped_textbboxes
+ util::array<box2d> grouped_textbboxes
= text::grouping::group_from_multiple_links(textbboxes, g);
std::cout << "AFTER - nbboxes = " <<
grouped_textbboxes.nelements() << std::endl;
@@ -74,5 +77,13 @@ int main(int argc, char* argv[])
scribo::debug::save_textbboxes_image(input, grouped_textbboxes,
literal::red,
"test_multiple_links_grouped_text.ppm");
+
+ util::array<box2d> filtered_textbboxes
+ = scribo::filter::small_components(grouped_textbboxes, 6);
+
+ scribo::debug::save_textbboxes_image(input, filtered_textbboxes,
+ literal::red,
+ "test_multiple_links_filtered_text.ppm");
+
}
diff --git a/milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc
b/milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc
new file mode 100644
index 0000000..ed5ce3c
--- /dev/null
+++ b/milena/sandbox/scribo/tests/table/extract_lines_with_rank.cc
@@ -0,0 +1,36 @@
+#include <mln/essential/2d.hh>
+#include <scribo/table/extract_lines_with_rank.hh>
+#include <scribo/debug/save_table_image.hh>
+#include <mln/util/couple.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc < 2)
+ {
+ std::cout << "Usage: " << argv[0] << "
<image.pbm>" << std::endl;
+ return 1;
+ }
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ typedef util::couple<util::array<box2d>,
+ util::array<box2d> > tblboxes_t;
+
+ tblboxes_t lineboxes;
+ lineboxes.first().append(make::box2d(0,0, 59,59));
+ lineboxes.first().append(make::box2d(0,28, 27, 32));
+ lineboxes.first().append(make::box2d(31,28, 59,32));
+ lineboxes.second().append(make::box2d(0,0, 59,59));
+ lineboxes.second().append(make::box2d(27,0, 31, 26));
+ lineboxes.second().append(make::box2d(27,34, 31,59));
+
+
+ tblboxes_t lineboxes_test = scribo::table::extract_lines_with_rank(input, c8(),
+ value::label_16(), win::vline2d(11),
+ win::hline2d(11), 2, 2);
+
+ mln_assertion(lineboxes == lineboxes_test);
+}
diff --git a/milena/sandbox/scribo/tests/table/repair_lines.cc
b/milena/sandbox/scribo/tests/table/repair_lines.cc
new file mode 100644
index 0000000..ff5551c
--- /dev/null
+++ b/milena/sandbox/scribo/tests/table/repair_lines.cc
@@ -0,0 +1,45 @@
+#include <mln/essential/2d.hh>
+#include <scribo/table/repair_vertical_lines.hh>
+#include <scribo/table/repair_horizontal_lines.hh>
+#include <scribo/table/extract_lines_with_rank.hh>
+#include <scribo/debug/save_table_image.hh>
+#include <mln/util/couple.hh>
+
+int main(int argc, char *argv[])
+{
+ using namespace mln;
+
+ if (argc < 2)
+ {
+ std::cout << "Usage: " << argv[0] << "
<image.pbm>" << std::endl;
+ return 1;
+ }
+
+ image2d<bool> input;
+ io::pbm::load(input, argv[1]);
+
+ typedef util::couple<util::array<box2d>,
+ util::array<box2d> > tblboxes_t;
+
+ tblboxes_t lineboxes;
+ lineboxes.first().append(make::box2d(0,0, 1,1)); // Dummy value for component 0.
+ lineboxes.first().append(make::box2d(0,28, 27, 32));
+ lineboxes.first().append(make::box2d(31,28, 59,32));
+ lineboxes.second().append(make::box2d(0,0, 1,1)); // Dummy value for component 0.
+ lineboxes.second().append(make::box2d(27,0, 31, 26));
+ lineboxes.second().append(make::box2d(27,34, 31,59));
+
+
+// tblboxes_t lineboxes = scribo::table::extract_lines_with_rank(input, c8(),
value::label_16(), win::vline2d(11), win::hline2d(11), 2, 2);
+//
+// std::cout << lineboxes.first() << std::endl;
+// std::cout << lineboxes.second() << std::endl;
+
+ scribo::table::repair_vertical_lines(input, lineboxes, 31);
+ scribo::table::repair_horizontal_lines(input, lineboxes, 31);
+
+ mln_assertion(lineboxes.first().nelements() == 2);
+ mln_assertion(lineboxes.second().nelements() == 2);
+ mln_assertion(lineboxes.first()[1] == make::box2d(0,28, 59,32));
+ mln_assertion(lineboxes.second()[1] == make::box2d(27,0, 31,59));
+}
diff --git a/milena/sandbox/scribo/text/extract_bboxes.hh
b/milena/sandbox/scribo/text/extract_bboxes.hh
index 0c88880..4a936b5 100644
--- a/milena/sandbox/scribo/text/extract_bboxes.hh
+++ b/milena/sandbox/scribo/text/extract_bboxes.hh
@@ -42,6 +42,8 @@
# include <mln/util/array.hh>
# include <scribo/core/component_bboxes.hh>
+# include <scribo/util/text.hh>
+# include <scribo/make/text.hh>
namespace scribo
{
@@ -58,8 +60,7 @@ namespace scribo
/// \return an array of bounding boxes. The first bounding box is
/// the background's.
template <typename I, typename N, typename V>
- inline
- util::array< box<mln_site(I)> >
+ scribo::util::text<mln_ch_value(I,V)>
extract_bboxes(const Image<I>& input_,
const Neighborhood<N>& nbh, V& nbboxes);
@@ -68,7 +69,7 @@ namespace scribo
template <typename I, typename N, typename V>
inline
- util::array< box<mln_site(I)> >
+ scribo::util::text<mln_ch_value(I,V)>
extract_bboxes(const Image<I>& input_,
const Neighborhood<N>& nbh, V& nbboxes)
{
@@ -79,11 +80,13 @@ namespace scribo
mlc_equal(mln_value(I), bool)::check();
mln_precondition(input.is_valid());
- typedef util::array< box<mln_site(I)> > bboxes_t;
- bboxes_t bboxes = component_bboxes(input, nbh, nbboxes);
+ typedef mln::util::array< box<mln_site(I)> > bboxes_t;
+ typedef mln::util::couple<bboxes_t, mln_ch_value(I,V)> bboxes_and_lbl_t;
+ bboxes_and_lbl_t bboxes_and_lbl = component_bboxes(input, nbh, nbboxes);
trace::exiting("scribo::text::extract_bboxes");
- return bboxes;
+ return scribo::make::text(bboxes_and_lbl.first(),
+ bboxes_and_lbl.second(), nbboxes);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/text/extract_lines.hh
b/milena/sandbox/scribo/text/extract_lines.hh
new file mode 100644
index 0000000..6be2e37
--- /dev/null
+++ b/milena/sandbox/scribo/text/extract_lines.hh
@@ -0,0 +1,133 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_TEXT_EXTRACT_LINES_HH
+# define SCRIBO_TEXT_EXTRACT_LINES_HH
+
+/// \file scribo/text/extract_lines.hh
+///
+/// Extract line of text bounding boxes.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/site_set/box.hh>
+
+# include <mln/data/fill.hh>
+
+# include <mln/accu/bbox.hh>
+
+# include <mln/draw/box.hh>
+
+# include <mln/labeling/blobs.hh>
+# include <mln/labeling/compute.hh>
+
+# include <mln/util/array.hh>
+# include <mln/util/graph.hh>
+# include <mln/value/label_16.hh>
+
+# include <scribo/text/grouping/group_with_multiple_links.hh>
+# include <scribo/text/grouping/group_from_multiple_links.hh>
+# include <scribo/filter/small_components.hh>
+# include <scribo/util/text.hh>
+
+# include <scribo/debug/save_textbboxes_image.hh>
+# include <scribo/debug/save_linked_textbboxes_image.hh>
+
+namespace scribo
+{
+
+ namespace text
+ {
+
+ using namespace mln;
+
+
+ template <typename I, typename N, typename V>
+ scribo::util::text<mln_ch_value(I,V)>
+ extract_lines(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ V& nbboxes);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename N, typename V>
+ scribo::util::text<mln_ch_value(I,V)>
+ extract_lines(const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ V& nbboxes)
+ {
+ trace::entering("scribo::text::extract_lines");
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_precondition(input.is_valid());
+ mln_precondition(nbh.is_valid());
+
+ scribo::util::text<mln_ch_value(I,V)> text
+ = scribo::make::text(input, nbh, nbboxes);
+
+# ifndef SCRIBO_NDEBUG
+ debug::save_textbboxes_image(input, text.bboxes(), literal::red,
+ scrib::make::debug_filename("character-bboxes.ppm"));
+# endif // ! SCRIBO_NDEBUG
+
+ //Link character bboxes to their left neighboor if possible.
+ mln::util::graph g
+ = text::grouping::group_with_multiple_links(text, 30);
+# ifndef SCRIBO_NDEBUG
+ debug::save_linked_textbboxes_image(input,
+ text, g,
+ literal::red, literal::cyan,
+ scribo::make::debug_filename("multiple_links_left_linked.ppm"));
+# endif // ! SCRIBO_NDEBUG
+
+ //Merge character bboxes through a graph.
+ scribo::util::text<mln_ch_value(I,V)> grouped_text
+ = text::grouping::group_from_multiple_links(text, g);
+
+# ifndef SCRIBO_NDEBUG
+ debug::save_textbboxes_image(input, grouped_text.bboxes(),
+ literal::red,
+ scribo::make::debug_filename("multiple_links_grouped_text.ppm"));
+# endif // ! SCRIBO_NDEBUG
+
+
+ trace::exiting("scribo::text::extract_lines");
+ return grouped_text;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::text
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_TEXT_EXTRACT_LINES_HH
+
diff --git a/milena/sandbox/scribo/text/grouping/group_from_double_link.hh
b/milena/sandbox/scribo/text/grouping/group_from_double_link.hh
index d178a80..582abcd 100644
--- a/milena/sandbox/scribo/text/grouping/group_from_double_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_from_double_link.hh
@@ -41,10 +41,14 @@
# include <mln/util/array.hh>
+# include <mln/fun/l2l/relabel.hh>
+
# include <scribo/text/grouping/internal/find_root.hh>
# include <scribo/core/macros.hh>
+# include <scribo/util/text.hh>
+
namespace scribo
{
@@ -56,42 +60,67 @@ namespace scribo
{
/// FIXME: Add much more doc!
- template <typename P>
- util::array< box<P> >
- group_from_double_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& left_link,
- util::array<unsigned>& right_link);
+ template <typename I>
+ scribo::util::text<I>
+ group_from_double_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link);
# ifndef MLN_INCLUDE_ONLY
- template <typename P>
+ template <typename I>
inline
- util::array< box<P> >
- group_from_double_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& left_link,
- util::array<unsigned>& right_link)
+ scribo::util::text<I>
+ group_from_double_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& left_link,
+ const mln::util::array<unsigned>& right_link)
{
trace::entering("scribo::text::grouping::group_from_double_link");
mln_precondition(left_link.nelements() == right_link.nelements());
- util::array< accu::bbox<P> > tboxes;
- tboxes.resize(textbboxes.nelements());
- for_all_components(i, textbboxes)
+ mln::util::array< accu::bbox<mln_site(I)> > tboxes;
+ tboxes.resize(text.bboxes().nelements());
+
+ mln::util::array<unsigned> left_parent = left_link;
+ for_all_components(i, left_parent)
+ left_parent[i] = internal::find_root(left_parent, i);
+
+ fun::i2v::array<mln_value(I)> f(text.bboxes().nelements(),
+ literal::zero);
+ for_all_components(i, text.bboxes())
{
unsigned nbh = right_link[left_link[i]];
if (nbh == i)
- tboxes[left_link[i]].take(textbboxes[i]);
+ {
+ tboxes[left_parent[i]].take(text.bbox(i));
+ f(i) = left_parent[left_link[i]];
+ }
else
- tboxes[i].take(textbboxes[i]);
+ {
+ f(i) = i;
+ tboxes[i].take(text.bbox(i));
+ }
}
- util::array< box<P> > result;
+ // Update bounding boxes information.
+ mln::util::array< box<mln_site(I)> > bresult;
// component 0, the background, has an invalid box.
- result.append(box<P>());
+ bresult.append(box<mln_site(I)>());
for_all_components(i, tboxes)
if (tboxes[i].is_valid())
- result.append(tboxes[i]);
+ bresult.append(tboxes[i]);
+
+ // Update label image.
+ mln_value(I) new_nbboxes;
+ I new_lbl = labeling::relabel(text.label_image(),
+ text.nbboxes(),
+ mln::make::relabelfun(f, text.nbboxes(),
+ new_nbboxes));
+
+ mln_assertion(bresult.nelements() == new_nbboxes.next());
+
+ scribo::util::text<I> result(bresult, new_lbl, new_nbboxes);
trace::exiting("scribo::text::grouping::group_from_double_link");
return result;
diff --git a/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh
b/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh
index 612fb87..059fa22 100644
--- a/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh
+++ b/milena/sandbox/scribo/text/grouping/group_from_multiple_links.hh
@@ -47,6 +47,9 @@
# include <mln/util/array.hh>
# include <scribo/core/macros.hh>
+# include <scribo/util/text.hh>
+# include <scribo/make/text.hh>
+
namespace scribo
{
@@ -58,9 +61,9 @@ namespace scribo
{
/// FIXME: Add much more doc!
- template <typename G, typename P>
- util::array<box<P> >
- group_from_multiple_links(util::array<box<P> >& textbboxes,
+ template <typename I, typename G>
+ scribo::util::text<I>
+ group_from_multiple_links(const scribo::util::text<I>& text,
const Graph<G>& g_);
# ifndef MLN_INCLUDE_ONLY
@@ -71,14 +74,15 @@ namespace scribo
/// Functor to be passed to depth_first_search.
/// Map each component vertex with its representative vertex id.
+ template <typename V>
struct map_vertex_to_component_id_functor
{
- template <typename G>
- void init(const Graph<G>& g)
- {
- vertextocomp.resize(exact(g).v_nmax(), mln_max(unsigned));
- ncomp = 0;
- }
+ template <typename G>
+ void init(const Graph<G>& g)
+ {
+ vertextocomp.resize(exact(g).v_nmax(), mln_max(V));
+ ncomp = 0;
+ }
void final()
{}
@@ -96,23 +100,23 @@ namespace scribo
{}
bool to_be_treated(unsigned id)
- { return vertextocomp(id) == mln_max(unsigned); }
+ { return vertextocomp(id) == mln_max(V); }
bool to_be_queued(unsigned id)
{ return to_be_treated(id); }
unsigned ncomp;
- fun::i2v::array<unsigned> vertextocomp;
+ fun::l2l::relabel<V> vertextocomp;
};
} // end of namespace scribo::text::grouping::internal
- template <typename G, typename P>
+ template <typename I, typename G>
inline
- util::array<box<P> >
- group_from_multiple_links(util::array<box<P> >& textbboxes,
+ scribo::util::text<I>
+ group_from_multiple_links(const scribo::util::text<I>& text,
const Graph<G>& g_)
{
trace::entering("scribo::text::grouping::group_from_multiple_links");
@@ -121,25 +125,34 @@ namespace scribo
mln_assertion(g.is_valid());
- internal::map_vertex_to_component_id_functor f;
+ internal::map_vertex_to_component_id_functor<mln_value(I)> f;
canvas::browsing::depth_first_search(g, f);
- util::array< accu::bbox<P> > tboxes;
- tboxes.resize(textbboxes.nelements());
- for_all_components(i, textbboxes)
- tboxes[f.vertextocomp(i)].take(textbboxes[i]);
+ mln::util::array< accu::bbox<mln_site(I)> > tboxes;
+ tboxes.resize(text.nbboxes().next());
+ for_all_components(i, text.bboxes())
+ tboxes[f.vertextocomp(i)].take(text.bbox(i));
- util::array< box<P> > result;
+ // Update bounding boxes.
+ mln::util::array<box<mln_site(I)> > bresult;
// Component 0 - the background has not valid bboxes.
- result.append(box<P>());
- for_all_components(i, textbboxes)
+ bresult.append(box<mln_site(I)>());
+ for_all_components(i, text.bboxes())
if (tboxes[i].is_valid())
- result.append(tboxes[i].to_result());
+ bresult.append(tboxes[i].to_result());
+
+ mln_assertion(bresult.nelements() == f.ncomp);
+
+ // Update label image.
+ mln_value(I) new_nbboxes;
+ I new_lbl = labeling::relabel(text.label_image(),
+ text.nbboxes(),
+ f.vertextocomp);
- mln_assertion(result.nelements() == f.ncomp);
+ mln_assertion(new_nbboxes.next() == bresult.nelements());
trace::exiting("scribo::text::grouping::group_from_multiple_links");
- return result;
+ return scribo::make::text(bresult, new_lbl, new_nbboxes);
}
diff --git a/milena/sandbox/scribo/text/grouping/group_from_single_link.hh
b/milena/sandbox/scribo/text/grouping/group_from_single_link.hh
index eccde96..43bb7b1 100644
--- a/milena/sandbox/scribo/text/grouping/group_from_single_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_from_single_link.hh
@@ -44,6 +44,7 @@
# include <scribo/text/grouping/internal/find_root.hh>
# include <scribo/core/macros.hh>
+# include <scribo/util/text.hh>
namespace scribo
@@ -56,38 +57,46 @@ namespace scribo
{
/// FIXME: Add much more doc!
- template <typename P>
- util::array< box<P> >
- group_from_single_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& link_array);
+ template <typename I>
+ scribo::util::text<I>
+ group_from_single_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& link_array);
# ifndef MLN_INCLUDE_ONLY
- template <typename P>
+ template <typename I>
inline
- util::array< box<P> >
- group_from_single_link(const util::array< box<P> >& textbboxes,
- util::array<unsigned>& link_array)
+ scribo::util::text<I>
+ group_from_single_link(const scribo::util::text<I>& text,
+ const mln::util::array<unsigned>& link_array)
{
trace::entering("scribo::text::grouping::group_from_single_link");
- for (unsigned i = 0; i < link_array.nelements(); ++i)
- link_array[i] = internal::find_root(link_array, i);
+ mln_precondition(text.is_valid());
+ mln_precondition(link_array.nelements() == text.nbboxes().next());
+ mln_precondition(link_array.nelements() == text.bboxes().nelements());
- util::array< accu::bbox<P> > tboxes;
- tboxes.resize(textbboxes.nelements());
- for_all_components(i, textbboxes)
- tboxes[link_array[i]].take(textbboxes[i]);
+ mln::util::array<unsigned> parent_array = link_array;
+ for_all_components(i, parent_array)
+ internal::find_root(parent_array, i);
- util::array< box<P> > result;
+ mln::util::array< accu::bbox<mln_site(I)> > tboxes;
+ tboxes.resize(text.nbboxes().next());
+ for_all_components(i, text.bboxes())
+ tboxes[parent_array[i]].take(text.bbox(i));
+
+ mln::util::array< box<mln_site(I)> > result;
// component 0, the background, has an invalid box.
- result.append(box<P>());
+ result.append(box<mln_site(I)>());
for_all_components(i, tboxes)
if (tboxes[i].is_valid())
result.append(tboxes[i]);
+ I lbl = labeling::relabel(text.label_image(), text.nbboxes(),
+ convert::to<fun::l2l::relabel<mln_value(I)> >(parent_array));
+ mln_value(I) new_nbboxes = result.nelements() - 1;
trace::exiting("scribo::text::grouping::group_from_single_link");
- return result;
+ return scribo::make::text(result, lbl, new_nbboxes);
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh
b/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh
index 2f769fc..236cf16 100644
--- a/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh
+++ b/milena/sandbox/scribo/text/grouping/group_with_multiple_links.hh
@@ -43,6 +43,7 @@
# include <scribo/core/macros.hh>
# include <scribo/text/grouping/internal/init_link_array.hh>
# include <scribo/text/grouping/internal/update_link_graph.hh>
+# include <scribo/util/text.hh>
namespace scribo
{
@@ -55,44 +56,34 @@ namespace scribo
/// Group character bounding boxes with multiple links.
/// Look up for neighbors on the left of each box.
- template <typename I, typename N, typename V>
- util::graph
- group_with_multiple_links(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array<box<mln_site(I)> >& textbboxes,
+ template <typename I>
+ mln::util::graph
+ group_with_multiple_links(const scribo::util::text<I>& text,
unsigned neighb_max_distance);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V>
- util::graph
- group_with_multiple_links(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array<box<mln_site(I)> >& textbboxes,
+ template <typename I>
+ inline
+ mln::util::graph
+ group_with_multiple_links(const scribo::util::text<I>& text,
unsigned neighb_max_distance)
{
trace::entering("scribo::text::grouping::group_with_multiple_links");
- const I& input = exact(input_);
+ mln::util::graph g(text.nbboxes().next());
- mlc_equal(mln_value(I), bool)::check();
- mln_assertion(input.is_valid());
-
- typedef mln_ch_value(I,V) lbl_t;
- lbl_t lbl = labeling::blobs(input, nbh, nbboxes);
-
- util::graph g(nbboxes.next());
-
- for_all_ncomponents(i, nbboxes)
+ for_all_ncomponents(i, text.nbboxes())
{
- unsigned midcol = (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ unsigned midcol = (text.bbox(i).pmax().col()
+ - text.bbox(i).pmin().col()) / 2;
int dmax = midcol + neighb_max_distance;
- mln_site(I) c = textbboxes[i].center();
+ mln_site(I) c = text.bbox(i).center();
/// First site on the right of the central site
mln_site(I) p = c + right;
+ const I& lbl = text.label_image();
while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i)
&& math::abs(p.col() - c.col()) < dmax)
++p.col();
diff --git a/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh
b/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh
index f1a3013..ca1a8da 100644
--- a/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_with_single_left_link.hh
@@ -46,6 +46,8 @@
# include <scribo/core/macros.hh>
# include <scribo/text/grouping/internal/init_link_array.hh>
# include <scribo/text/grouping/internal/update_link_array.hh>
+# include <scribo/text/grouping/internal/find_root.hh>
+# include <scribo/util/text.hh>
//FIXME: not generic.
# include <mln/core/alias/dpoint2d.hh>
@@ -63,46 +65,34 @@ namespace scribo
/// if possible.
/// Iterate to the right but link boxes to the left.
///
- /// \return an util::array. Map a bounding box to its left neighbor.
- template <typename I, typename N, typename V>
+ /// \return an mln::util::array. Map a bounding box to its left neighbor.
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_left_link(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_left_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V>
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_left_link(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_left_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance)
{
trace::entering("scribo::text::grouping::group_with_single_left_link");
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
+ mln_precondition(text.is_valid());
- mlc_equal(mln_value(I), bool)::check();
- mln_assertion(input.is_valid());
- mln_precondition(nbh.is_valid());
-
- typedef mln_ch_value(I,V) lbl_t;
- lbl_t lbl = labeling::blobs(input, nbh, nbboxes);
-
- util::array<unsigned> left_link(nbboxes.next());
+ mln::util::array<unsigned> left_link(text.nbboxes().next());
internal::init_link_array(left_link);
- for_all_ncomponents(i, nbboxes)
+ for_all_ncomponents(i, text.nbboxes())
{
- unsigned midcol = (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ unsigned midcol = (text.bbox(i).pmax().col()
+ - text.bbox(i).pmin().col()) / 2;
int dmax = midcol + neighb_max_distance;
- mln_site(I) c = textbboxes[i].center();
+ mln_site(L) c = text.bbox(i).center();
///
/// Find a neighbor on the right
@@ -110,14 +100,15 @@ namespace scribo
///FIXME: the following code is not generic...
/// First site on the right of the central site
- mln_site(I) p = c + right;
+ mln_site(L) p = c + right;
- while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i)
+ const L& lbl = text.label_image();
+ while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i ||
+ left_link[i] == lbl(p))
&& math::abs(p.col() - c.col()) < dmax)
++p.col();
internal::update_link_array(lbl, left_link, p, c, i, dmax);
-
}
trace::exiting("scribo::text::grouping::group_with_single_left_link");
diff --git a/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh
b/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh
index 7f1eeac..5740b09 100644
--- a/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh
+++ b/milena/sandbox/scribo/text/grouping/group_with_single_right_link.hh
@@ -46,6 +46,8 @@
# include <scribo/core/macros.hh>
# include <scribo/text/grouping/internal/init_link_array.hh>
# include <scribo/text/grouping/internal/update_link_array.hh>
+# include <scribo/text/grouping/internal/find_root.hh>
+# include <scribo/util/text.hh>
//FIXME: not generic.
# include <mln/core/alias/dpoint2d.hh>
@@ -63,46 +65,34 @@ namespace scribo
/// if possible.
/// Iterate to the right but link boxes to the right.
///
- /// \return an util::array. Map a bounding box to its right neighbor.
- template <typename I, typename N, typename V>
+ /// \return an mln::util::array. Map a bounding box to its right neighbor.
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_right_link(const Image<I>& input_,
- const Neighborhood<N>& nbh, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_right_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename V>
+ template <typename L>
inline
- util::array<unsigned>
- group_with_single_right_link(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ mln::util::array<unsigned>
+ group_with_single_right_link(const scribo::util::text<L>& text,
unsigned neighb_max_distance)
{
trace::entering("scribo::text::grouping::group_with_single_right_link");
- const I& input = exact(input_);
- const N& nbh = exact(nbh_);
+ mln_precondition(text.is_valid());
- mlc_equal(mln_value(I), bool)::check();
- mln_assertion(input.is_valid());
- mln_precondition(nbh.is_valid());
-
- typedef mln_ch_value(I,V) lbl_t;
- lbl_t lbl = labeling::blobs(input, nbh, nbboxes);
-
- util::array<unsigned> right_link(nbboxes.next());
+ mln::util::array<unsigned> right_link(text.nbboxes().next());
internal::init_link_array(right_link);
- for_all_ncomponents(i, nbboxes)
+ for_all_ncomponents(i, text.nbboxes())
{
- unsigned midcol = (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ unsigned midcol = (text.bbox(i).pmax().col()
+ - text.bbox(i).pmin().col()) / 2;
int dmax = midcol + neighb_max_distance;
- mln_site(I) c = textbboxes[i].center();
+ mln_site(L) c = text.bbox(i).center();
///
/// Find a neighbor on the left
@@ -110,14 +100,15 @@ namespace scribo
///FIXME: the following code is not generic...
/// First site on the left of the central site
- mln_site(I) p = c + left;
+ mln_site(L) p = c + left;
- while (lbl.domain().has(p) && (lbl(p) == literal::zero || lbl(p) == i)
- && math::abs(p.col() - c.col()) < dmax)
+ const L& lbl = text.label_image();
+ while (lbl.domain().has(p) && (lbl(p) == literal::zero
+ || lbl(p) == i || right_link[i] == lbl(p))
+ && math::abs(p.col() - c.col()) < dmax)
--p.col();
internal::update_link_array(lbl, right_link, p, c, i, dmax);
-
}
trace::exiting("scribo::text::grouping::group_with_single_right_link");
diff --git a/milena/sandbox/scribo/text/grouping/internal/find_root.hh
b/milena/sandbox/scribo/text/grouping/internal/find_root.hh
index 0b1e307..9e3eedf 100644
--- a/milena/sandbox/scribo/text/grouping/internal/find_root.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/find_root.hh
@@ -52,13 +52,13 @@ namespace scribo
/// Find root in a parent array arrays.
unsigned
- find_root(util::array<unsigned>& parent, unsigned x);
+ find_root(mln::util::array<unsigned>& parent, unsigned x);
# ifndef MLN_INCLUDE_ONLY
inline
unsigned
- find_root(util::array<unsigned>& parent, unsigned x)
+ find_root(mln::util::array<unsigned>& parent, unsigned x)
{
if (parent[x] == x)
return x;
diff --git a/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh
b/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh
index ba197f9..7e4f751 100644
--- a/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/init_link_array.hh
@@ -41,6 +41,8 @@
namespace scribo
{
+ using namespace mln;
+
namespace text
{
@@ -51,13 +53,14 @@ namespace scribo
{
/// Initialize a link array.
- void init_link_array(util::array<unsigned>& link_array);
+ void
+ init_link_array(mln::util::array<unsigned>& link_array);
# ifndef MLN_INCLUDE_ONLY
inline
void
- init_link_array(util::array<unsigned>& link_array)
+ init_link_array(mln::util::array<unsigned>& link_array)
{
for (unsigned i = 0; i < link_array.nelements(); ++i)
link_array[i] = i;
diff --git a/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh
b/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh
index 242d18f..501d6f2 100644
--- a/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/update_link_array.hh
@@ -56,7 +56,7 @@ namespace scribo
/// on the right of the current bbox.
template <typename I>
void
- update_link_array(const Image<I>& lbl, util::array<unsigned>&
link_array,
+ update_link_array(const Image<I>& lbl, mln::util::array<unsigned>&
link_array,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax);
@@ -65,7 +65,7 @@ namespace scribo
template <typename I>
inline
void
- update_link_array(const Image<I>& lbl_, util::array<unsigned>&
link_array,
+ update_link_array(const Image<I>& lbl_, mln::util::array<unsigned>&
link_array,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax)
{
@@ -75,7 +75,8 @@ namespace scribo
mln_assertion(lbl.is_valid());
if (lbl.domain().has(p) && lbl(p) != literal::zero && lbl(p) != i
- && (math::abs(p.col() - c.col())) < dmax && link_array[lbl(p)]
== lbl(p))
+ && (math::abs(p.col() - c.col())) < dmax && link_array[lbl(p)]
== lbl(p)
+ && link_array[i] != lbl(p))
link_array[lbl(p)] = i;
}
diff --git a/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh
b/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh
index e31c5e8..f572a47 100644
--- a/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh
+++ b/milena/sandbox/scribo/text/grouping/internal/update_link_graph.hh
@@ -52,7 +52,7 @@ namespace scribo
/// Update graph edges if a valid neighbor is found.
template <typename I>
void
- update_link_graph(Image<I>& lbl_, util::graph& g,
+ update_link_graph(const Image<I>& lbl_, mln::util::graph& g,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax);
@@ -63,7 +63,7 @@ namespace scribo
template <typename I>
inline
void
- update_link_graph(Image<I>& lbl_, util::graph& g,
+ update_link_graph(const Image<I>& lbl_, mln::util::graph& g,
const mln_site(I)& p, const mln_site(I)& c,
unsigned i, int dmax)
{
@@ -72,7 +72,7 @@ namespace scribo
mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
mln_precondition(exact(lbl).is_valid());
- if (lbl.domain().has(p) && lbl(p) != 0u && lbl(p) != i
+ if (lbl.domain().has(p) && lbl(p) != literal::zero && lbl(p) != i
&& (math::abs(p.col() - c.col())) < dmax)
g.add_edge(lbl(p), i);
}
diff --git a/milena/sandbox/scribo/text/recognition.hh
b/milena/sandbox/scribo/text/recognition.hh
index 98c3b67..c11ed54 100644
--- a/milena/sandbox/scribo/text/recognition.hh
+++ b/milena/sandbox/scribo/text/recognition.hh
@@ -54,6 +54,8 @@ namespace scribo
namespace text
{
+ using namespace mln;
+
/// Passes the text bboxes to Tesseract (OCR) and store the result in
/// an image of characters.
///
@@ -71,8 +73,8 @@ namespace scribo
template <typename I, typename N, typename V>
mln_ch_value(I,char)
text_recognition(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const Neighborhood<N>& nbh_, const V& label_type,
+ const scribo::util::text_bboxes<mln_ch_value(I,V)>& textbboxes,
const char *language);
@@ -81,8 +83,8 @@ namespace scribo
template <typename I, typename N, typename V>
mln_ch_value(I,char)
text_recognition(const Image<I>& input_,
- const Neighborhood<N>& nbh_, V& nbboxes,
- const util::array< box<mln_site(I)> >& textbboxes,
+ const Neighborhood<N>& nbh_, const V& label_type,
+ const scribo::util::text_bboxes<mln_ch_value(I,V)>& textbboxes,
const char *language)
{
trace::entering("scribo::text::recognition");
@@ -93,6 +95,7 @@ namespace scribo
mln_precondition(input.is_valid());
mln_precondition(nbh.is_valid());
+ V nbboxes;
mln_ch_value(I,V) lbl = labeling::blobs(input, nbh, nbboxes);
/// Use text bboxes with Tesseract
@@ -104,7 +107,7 @@ namespace scribo
{
if (textbboxes[i].is_valid())
{
- mln_ch_value(I,bool) b(textbboxes[i], 0);
+ mln_ch_value(I,bool) b(textbboxes.bboxes()[i], 0);
data::fill(b, false);
data::fill((b | (pw::value(lbl) == pw::cst(i))).rw(), true);
@@ -119,9 +122,9 @@ namespace scribo
- mln_site(I) p = textbboxes[i].center();
- p.col() -= (textbboxes[i].pmax().col()
- - textbboxes[i].pmin().col()) / 2;
+ mln_site(I) p = textbboxes.bboxes[i].center();
+ p.col() -= (textbboxes.bboxes()[i].pmax().col()
+ - textbboxes.bboxes()[i].pmin().col()) / 2;
if (s != 0)
debug::put_word(txt, p, s);
free(s);
diff --git a/milena/sandbox/scribo/util/text.hh b/milena/sandbox/scribo/util/text.hh
new file mode 100644
index 0000000..2619a79
--- /dev/null
+++ b/milena/sandbox/scribo/util/text.hh
@@ -0,0 +1,189 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef SCRIBO_UTIL_TEXT_HH
+# define SCRIBO_UTIL_TEXT_HH
+
+/// \file scribo/util/text.hh
+///
+/// A class representing text bounding boxes and their associated
+/// labeled image.
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/concept/proxy.hh>
+# include <mln/core/site_set/box.hh>
+# include <mln/value/label_16.hh>
+# include <mln/util/couple.hh>
+# include <mln/util/array.hh>
+
+namespace scribo
+{
+
+ using namespace mln;
+
+ namespace util
+ {
+
+ /// Store text bounding boxes and their associated labeled image.
+ template <typename L>
+ class text
+ {
+ public:
+ typedef mln_site(L) site;
+ typedef mln::util::array<box<site> > boxes_t;
+
+ text();
+ text(const mln::util::array<box<mln_site(L)> >& bboxes,
+ const Image<L>& lbl,
+ const mln_value(L)& nbboxes);
+
+ const L& label_image() const;
+ L& label_image();
+
+ const mln_value(L)& nbboxes() const;
+ mln_value(L)& nbboxes();
+
+ const boxes_t& bboxes() const;
+ boxes_t& bboxes();
+
+ const box<mln_site(L)>& bbox(unsigned i) const;
+ box<mln_site(L)>& bbox(unsigned i);
+
+ bool is_valid() const;
+
+ private:
+ boxes_t bboxes_;
+ L lbl_;
+ mln_value(L) nbboxes_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ inline
+ text<L>::text()
+ {
+ }
+
+ template <typename L>
+ inline
+ text<L>::text(const mln::util::array<box<mln_site(L)> >&
bboxes,
+ const Image<L>& lbl,
+ const mln_value(L)& nbboxes)
+ : bboxes_(bboxes), lbl_(exact(lbl)), nbboxes_(nbboxes)
+ {
+ mln_assertion(bboxes.nelements() == nbboxes.next());
+ }
+
+ template <typename L>
+ inline
+ const L&
+ text<L>::label_image() const
+ {
+ mln_precondition(lbl_.is_valid());
+ return lbl_;
+ }
+
+ template <typename L>
+ inline
+ L&
+ text<L>::label_image()
+ {
+ return lbl_;
+ }
+
+ template <typename L>
+ inline
+ const mln_value(L)&
+ text<L>::nbboxes() const
+ {
+ return nbboxes_;
+ }
+
+ template <typename L>
+ inline
+ mln_value(L)&
+ text<L>::nbboxes()
+ {
+ return nbboxes_;
+ }
+
+ template <typename L>
+ inline
+ const typename text<L>::boxes_t&
+ text<L>::bboxes() const
+ {
+ mln_precondition(bboxes_.nelements() == nbboxes_.next());
+ return bboxes_;
+ }
+
+ template <typename L>
+ inline
+ typename text<L>::boxes_t&
+ text<L>::bboxes()
+ {
+ return bboxes_;
+ }
+
+ template <typename L>
+ inline
+ const box<mln_site(L)>&
+ text<L>::bbox(unsigned i) const
+ {
+ mln_precondition(bboxes_.nelements() == nbboxes_.next());
+ mln_precondition(i < bboxes_.nelements());
+ return bboxes_[i];
+ }
+
+ template <typename L>
+ inline
+ box<mln_site(L)>&
+ text<L>::bbox(unsigned i)
+ {
+ mln_precondition(bboxes_.nelements() == nbboxes_.next());
+ mln_precondition(i < bboxes_.nelements());
+ return bboxes_[i];
+ }
+
+ template <typename L>
+ inline
+ bool
+ text<L>::is_valid() const
+ {
+ return lbl_.is_valid() && bboxes_.nelements() == nbboxes_.next();
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::util
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_UTIL_TEXT_HH
--
1.5.6.5