Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
May 2010
- 6 participants
- 142 discussions
last-svn-commit-157-g9ced049 Add `swilena' to the branches to be uploaded.
by Roland Levillain 28 May '10
by Roland Levillain 28 May '10
28 May '10
* lrde-upload.sh: Here.
Add a copyright header.
---
ChangeLog | 7 +++++++
lrde-upload.sh | 33 ++++++++++++++++++++++++++-------
2 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 953c68b..bd092e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-05-28 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Add `swilena' to the branches to be uploaded.
+
+ * lrde-upload.sh: Here.
+ Add a copyright header.
+
2010-05-10 Roland Levillain <roland(a)lrde.epita.fr>
Upload only branches master and next, in their own directories.
diff --git a/lrde-upload.sh b/lrde-upload.sh
index 8a30466..436beb7 100755
--- a/lrde-upload.sh
+++ b/lrde-upload.sh
@@ -1,5 +1,22 @@
#! /bin/sh
+# Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+
+
# This file is run by the LRDE autobuilder after a successful compilation.
# It is not meant to be distributed with Olena.
@@ -14,19 +31,21 @@ set -ex
# | | `-- ...
# | |-- olena-$VERSION-snapshot-master-$date.tar.bz2
# | `-- olena-$VERSION-snapshot-master-$date.tar.gz
-# `-- next
-# |-- doc
-# | `-- milena
-# | `-- ...
-# |-- olena-$VERSION-snapshot-next-$date.tar.bz2
-# `-- olena-$VERSION-snapshot-next-$date.tar.gz
+# |-- next
+# | |-- doc
+# | | `-- milena
+# | | `-- ...
+# | |-- olena-$VERSION-snapshot-next-$date.tar.bz2
+# | `-- olena-$VERSION-snapshot-next-$date.tar.gz
+# ...
+#
# Buildbot will tell us the name of the branch being compiled using $1.
branch=$1
case "$branch" in
# Consider these branches only.
- master|next) ;;
+ master|next|swilena) ;;
# Don't upload other branches.
*) exit ;;
esac
--
1.5.6.5
1
0
branch fix-g++-4.2-strict-aliasing deleted: last-svn-commit-144-g72a1d9c
by git@lrde.epita.fr 28 May '10
by git@lrde.epita.fr 28 May '10
28 May '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch fix-g++-4.2-strict-aliasing has been deleted
was 72a1d9cca4425b195b9132e2bd645274f52c765a
-----------------------------------------------------------------------
72a1d9cca4425b195b9132e2bd645274f52c765a Prevent g++ 4.2 from issuing bad code for graph-morpho/samples_image2d.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
28 May '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch g++-3.3-compatibility has been deleted
was 81ebf3143f310e04f99738afb8b5ad9cbc39eaa7
-----------------------------------------------------------------------
81ebf3143f310e04f99738afb8b5ad9cbc39eaa7 Help g++ 3.3 compile Scribo code.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
28 May '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch fix-lrde-upload has been deleted
was 68d80d9e1c6f2b66a45e6bb107c7697871386426
-----------------------------------------------------------------------
68d80d9e1c6f2b66a45e6bb107c7697871386426 Upload only the HTML version of the user reference manual.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
* src/preprocessing/Makefile.am,
* src/text/Makefile.am,
* src/Makefile.am: Update.
* src/multi_scale/Makefile.am,
* src/multi_scale/find_lines.cc
* src/text/pbm_recognition.cc
* src/text/recognition.cc
* src/text_in_article_preprocess.cc
* src/text_in_doc.cc
* src/text_in_doc_ppm.cc
* src/text_in_photo.cc
* src/text_in_photo_invert.cc
* src/text_in_photo_pbm_fast.cc
* src/text_in_photo_ppm.cc
* test.cc: Remove. Deprecated.
* src/text_in_article_pbm.cc: Rename as...
* src/pbm_text_in_doc.cc: ... this. Make use of the new toolchain
routines.
* src/text/pbm_lines_recognition.cc,
* src/text_in_doc_preprocess.cc: New.
* src/text_in_photo_fast.cc: Rename as...
* src/text_in_picture.cc: ... this.
* src/preprocessing/subsample.cc: Make use of io::magick.
---
scribo/ChangeLog | 33 ++
scribo/src/Makefile.am | 78 +--
scribo/src/multi_scale/Makefile.am | 26 -
scribo/src/multi_scale/find_lines.cc | 180 -------
scribo/src/pbm_text_in_doc.cc | 132 +++++
scribo/src/preprocessing/Makefile.am | 26 +-
scribo/src/preprocessing/subsample.cc | 16 +-
scribo/src/text/Makefile.am | 18 +-
.../{recognition.cc => pbm_lines_recognition.cc} | 92 ++--
scribo/src/text/pbm_recognition.cc | 20 +-
scribo/src/text_in_article_pbm.cc | 381 --------------
scribo/src/text_in_doc.cc | 304 -----------
scribo/src/text_in_doc_ppm.cc | 322 ------------
...cle_preprocess.cc => text_in_doc_preprocess.cc} | 18 +-
scribo/src/text_in_photo.cc | 250 ---------
scribo/src/text_in_photo_invert.cc | 245 ---------
scribo/src/text_in_photo_pbm_fast.cc | 441 ----------------
scribo/src/text_in_photo_ppm.cc | 532 --------------------
.../{text_in_photo_fast.cc => text_in_picture.cc} | 2 +
scribo/test.cc | 44 --
20 files changed, 312 insertions(+), 2848 deletions(-)
delete mode 100644 scribo/src/multi_scale/Makefile.am
delete mode 100644 scribo/src/multi_scale/find_lines.cc
create mode 100644 scribo/src/pbm_text_in_doc.cc
rename scribo/src/text/{recognition.cc => pbm_lines_recognition.cc} (52%)
delete mode 100644 scribo/src/text_in_article_pbm.cc
delete mode 100644 scribo/src/text_in_doc.cc
delete mode 100644 scribo/src/text_in_doc_ppm.cc
rename scribo/src/{text_in_article_preprocess.cc => text_in_doc_preprocess.cc} (84%)
delete mode 100644 scribo/src/text_in_photo.cc
delete mode 100644 scribo/src/text_in_photo_invert.cc
delete mode 100644 scribo/src/text_in_photo_pbm_fast.cc
delete mode 100644 scribo/src/text_in_photo_ppm.cc
rename scribo/src/{text_in_photo_fast.cc => text_in_picture.cc} (99%)
delete mode 100644 scribo/test.cc
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f091afa..de7acfa 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,38 @@
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Cleanup sample tools.
+
+ * src/preprocessing/Makefile.am,
+ * src/text/Makefile.am,
+ * src/Makefile.am: Update.
+
+ * src/multi_scale/Makefile.am,
+ * src/multi_scale/find_lines.cc
+ * src/text/pbm_recognition.cc
+ * src/text/recognition.cc
+ * src/text_in_article_preprocess.cc
+ * src/text_in_doc.cc
+ * src/text_in_doc_ppm.cc
+ * src/text_in_photo.cc
+ * src/text_in_photo_invert.cc
+ * src/text_in_photo_pbm_fast.cc
+ * src/text_in_photo_ppm.cc
+ * test.cc: Remove. Deprecated.
+
+ * src/text_in_article_pbm.cc: Rename as...
+ * src/pbm_text_in_doc.cc: ... this. Make use of the new toolchain
+ routines.
+
+ * src/text/pbm_lines_recognition.cc,
+ * src/text_in_doc_preprocess.cc: New.
+
+ * src/text_in_photo_fast.cc: Rename as...
+ * src/text_in_picture.cc: ... this.
+
+ * src/preprocessing/subsample.cc: Make use of io::magick.
+
+2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* toolchain/text_in_doc.hh: Introduce a new routine for extracting
text in a document.
diff --git a/scribo/src/Makefile.am b/scribo/src/Makefile.am
index 08b4bd9..e910f53 100644
--- a/scribo/src/Makefile.am
+++ b/scribo/src/Makefile.am
@@ -25,81 +25,51 @@ SUBDIRS = \
primitive \
filter \
misc \
- multi_scale \
+ nuxeo_xwiki \
preprocessing \
table \
text
bin_PROGRAMS = \
- pbm_lines_in_doc \
- text_in_photo \
- text_in_photo_ppm \
- text_in_photo_pbm_fast \
- text_in_photo_invert
+ pbm_lines_in_doc
pbm_lines_in_doc_SOURCES = pbm_lines_in_doc.cc
-text_in_photo_SOURCES = text_in_photo.cc
-text_in_photo_ppm_SOURCES = text_in_photo_ppm.cc
-text_in_photo_pbm_fast_SOURCES = text_in_photo_pbm_fast.cc
-text_in_photo_invert_SOURCES = text_in_photo_invert.cc
-
if HAVE_TESSERACT
-if HAVE_TIFF
-
- bin_PROGRAMS += text_in_doc
- text_in_doc_SOURCES = text_in_doc.cc
- text_in_doc_CPPFLAGS = $(AM_CPPFLAGS) \
- $(TESSERACT_CPPFLAGS) \
- $(TIFF_CPPFLAGS)
- text_in_doc_LDFLAGS = $(AM_LDFLAGS) \
- $(TESSERACT_LDFLAGS) \
- $(TIFF_LDFLAGS) \
- -lpthread -lhpdf
-
- bin_PROGRAMS += text_in_doc_ppm
- text_in_doc_ppm_SOURCES = text_in_doc_ppm.cc
- text_in_doc_ppm_CPPFLAGS = $(AM_CPPFLAGS) \
- $(TESSERACT_CPPFLAGS) \
- $(TIFF_CPPFLAGS)
- text_in_doc_ppm_LDFLAGS = $(AM_LDFLAGS) \
- $(TESSERACT_LDFLAGS) \
- $(TIFF_LDFLAGS) \
- -lpthread -lhpdf
-
-
- bin_PROGRAMS += text_in_article_pbm
- text_in_article_pbm_CPPFLAGS = $(AM_CPPFLAGS) \
+
+ bin_PROGRAMS += pbm_text_in_doc
+ pbm_text_in_doc_CPPFLAGS = $(AM_CPPFLAGS) -g -ggdb \
$(TESSERACT_CPPFLAGS) \
$(TIFF_CPPFLAGS)
- text_in_article_pbm_LDFLAGS = $(AM_LDFLAGS) \
+ pbm_text_in_doc_LDFLAGS = $(AM_LDFLAGS) -g -ggdb\
$(TESSERACT_LDFLAGS) \
$(TIFF_LDFLAGS) \
-lpthread
# -lhpdf
- text_in_article_pbm_SOURCES = text_in_article_pbm.cc
+ pbm_text_in_doc_SOURCES = pbm_text_in_doc.cc
+
+endif HAVE_TESSERACT
- bin_PROGRAMS += text_in_article_preprocess
- text_in_article_preprocess_CPPFLAGS = $(AM_CPPFLAGS) \
- `Magick++-config --cppflags`
- text_in_article_preprocess_LDFLAGS = $(AM_LDFLAGS) \
- -lpthread `Magick++-config --libs`
- text_in_article_preprocess_SOURCES = text_in_article_preprocess.cc
+if HAVE_MAGICKXX
+ bin_PROGRAMS += text_in_doc_preprocess
+ text_in_doc_preprocess_CPPFLAGS = $(AM_CPPFLAGS) \
+ `Magick++-config --cppflags`
+ text_in_doc_preprocess_LDFLAGS = $(AM_LDFLAGS) \
+ -lpthread `Magick++-config --libs`
+ text_in_doc_preprocess_SOURCES = text_in_doc_preprocess.cc
- bin_PROGRAMS += text_in_photo_fast
- text_in_photo_fast_SOURCES = text_in_photo_fast.cc
- text_in_photo_fast_CPPFLAGS = $(AM_CPPFLAGS) \
- $(TESSERACT_CPPFLAGS) \
- `Magick++-config --cppflags`
- text_in_photo_fast_LDFLAGS = $(AM_LDFLAGS) \
- $(TESSERACT_LDFLAGS) \
- -lpthread `Magick++-config --libs`
+ bin_PROGRAMS += text_in_picture
+ text_in_picture_SOURCES = text_in_picture.cc
+ text_in_picture_CPPFLAGS = $(AM_CPPFLAGS) \
+ `Magick++-config --cppflags`
-endif HAVE_TIFF
-endif HAVE_TESSERACT
+ text_in_picture_LDFLAGS = $(AM_LDFLAGS) \
+ -lpthread `Magick++-config --libs`
+
+endif HAVE_MAGICKXX
diff --git a/scribo/src/multi_scale/Makefile.am b/scribo/src/multi_scale/Makefile.am
deleted file mode 100644
index f3dfb42..0000000
--- a/scribo/src/multi_scale/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE).
-#
-# This file is part of Olena.
-#
-# Olena is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, version 2 of the License.
-#
-# Olena is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Olena. If not, see <http://www.gnu.org/licenses/>.
-#
-
-## Process this file through Automake to create Makefile.in.
-
-include $(top_srcdir)/scribo/scribo.mk
-
-bin_PROGRAMS = \
- find_lines
-
-find_lines_SOURCES = find_lines.cc
-
diff --git a/scribo/src/multi_scale/find_lines.cc b/scribo/src/multi_scale/find_lines.cc
deleted file mode 100644
index c5a2f97..0000000
--- a/scribo/src/multi_scale/find_lines.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/core/image/image2d.hh>
-#include <mln/data/convert.hh>
-#include <mln/debug/superpose.hh>
-#include <mln/io/pbm/all.hh>
-#include <mln/io/ppm/save.hh>
-#include <mln/pw/all.hh>
-#include <mln/subsampling/subsampling.hh>
-#include <mln/value/label_16.hh>
-#include <mln/value/rgb8.hh>
-
-#include <mln/world/binary_2d/enlarge.hh>
-
-#include <scribo/debug/usage.hh>
-
-#include <scribo/core/object_image.hh>
-#include <scribo/primitive/extract/lines_h_pattern.hh>
-#include <scribo/primitive/extract/lines_v_pattern.hh>
-
-#include <scribo/filter/objects_h_thin.hh>
-#include <scribo/filter/objects_v_thin.hh>
-
-#include <sandbox/theo/Rd/sequential.hh>
-
-#include <mln/morpho/erosion.hh>
-
-const char *args_desc[][2] =
-{
- { "input.pbm", "A binary image." },
- { "length", " Minimum line length." },
- {0, 0}
-};
-
-
-namespace mln
-{
-
- template <typename I>
- mln_concrete(I)
- process(const I& input, const std::string& filename,
- unsigned length, unsigned delta, unsigned ratio)
- {
- (void) filename;
-
- I hlines = scribo::primitive::extract::lines_h_pattern(input,
- length,
- delta);
-
- value::label_16 nhlines;
- hlines = scribo::filter::objects_v_thin(hlines, c8(),
- nhlines, delta * ratio);
-// I vlines = scribo::primitive::extract::lines_v_pattern(input,
-// length,
-// delta);
-
-
-// value::label_16 nvlines;
-// vlines = scribo::filter::objects_h_thin(vlines, c8(),
-// nvlines, delta * ratio);
-
-// image2d<value::rgb8> out = debug::superpose(input, hlines, literal::red);
-// out = debug::superpose(out, vlines, literal::green);
-// io::ppm::save(out, filename);
-
- return hlines;
- }
-
-
- template <typename I>
- mln_concrete(I)
- merge_results(const I& input,
- const I& out, const I& out_sub2x, const I& out_sub4x)
- {
- mln_concrete(I) output;
- initialize(output, input);
-
-
-
- return output;
- }
-
-
-} // end of namespace mln
-
-
-
-int main(int argc, char *argv[])
-{
- using namespace mln;
-
- if (argc != 4)
- return scribo::debug::usage(argv,
- "Extract discontinued horizontal and vertical lines (multi-scale version)",
- "input.pbm length output.ppm",
- args_desc,
- "A color image. Horizontal lines are in red and vertical lines in green.");
-
- trace::entering("main");
-
- typedef image2d<bool> I;
- dpoint2d none(0, 0);
-
- I input;
- io::pbm::load(input, argv[1]);
-
-
- // 1/1
- std::cout << "1/1" << std::endl;
- I hlines = scribo::primitive::extract::lines_h_pattern(input,
- atoi(argv[2]),
- 3);
-
-
-
-// I vlines = scribo::primitive::extract::lines_v_pattern(input,
-// atoi(argv[2]),
-// 3);
-
- image2d<value::rgb8> out = debug::superpose(input, hlines, literal::red);
-// out = debug::superpose(out, vlines, literal::green);
- io::ppm::save(out, "out_1_1.ppm");
-
-// I out = process(input, "out_1_1.ppm", atoi(argv[2]), 3);
-
-
-
- // 1/2
- std::cout << "1/2" << std::endl;
- I input_sub2x = mln::subsampling::subsampling(input, none, 2);
- I out_sub2 = process(input_sub2x, "out_1_2.ppm", atoi(argv[2]), 3, 2);
-
-
-
-// // 1/4
-// std::cout << "1/4" << std::endl;
-// I input_sub4x = mln::subsampling::subsampling(input, none, 4);
-// I out_sub4 = process(input_sub4x, "out_1_4.ppm", atoi(argv[2]), 3, 4);
-
-
-// out_sub4 = world::binary_2d::enlarge(out_sub4, 2);
- out_sub2 = world::binary_2d::enlarge(out_sub2, 1);
-
-// io::ppm::save(merge_results(input, out, out_sub2, out_sub4), argv[2]);
-
- I tmp = morpho::Rd::sequential(hlines, input, c8());
- io::pbm::save(tmp, "rd.pbm");
- I tmp_sub2 = morpho::Rd::sequential(out_sub2, input, c8());
- io::pbm::save(tmp_sub2, "rd_sub2.pbm");
-
- out = debug::superpose(input, tmp_sub2, literal::red);
- out = debug::superpose(out, tmp, literal::red);
- io::ppm::save(out, "out.ppm");
-
- trace::exiting("main");
-}
diff --git a/scribo/src/pbm_text_in_doc.cc b/scribo/src/pbm_text_in_doc.cc
new file mode 100644
index 0000000..993bbcb
--- /dev/null
+++ b/scribo/src/pbm_text_in_doc.cc
@@ -0,0 +1,132 @@
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+
+#include <libgen.h>
+#include <fstream>
+#include <iostream>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pbm/all.hh>
+
+
+#include <scribo/toolchain/text_in_doc.hh>
+
+#include <scribo/core/line_set.hh>
+
+#include <scribo/debug/usage.hh>
+
+#include <scribo/make/debug_filename.hh>
+
+#include <scribo/preprocessing/crop_without_localization.hh>
+
+#include <scribo/io/xml/save_text_lines.hh>
+#include <scribo/io/text_boxes/save.hh>
+
+
+
+
+const char *args_desc[][2] =
+{
+ { "input.pbm", "A binary image. 'False' for object, 'True'\
+for the background." },
+ { "out.txt", "Text output" },
+ { "denoise_enabled", "1 enables denoising, 0 disables it. (enabled by default)" },
+ { "pmin_row", "Row index of the top left corner of the Region of interest." },
+ { "pmin_col", "Col index of the top left corner of the Region of interest." },
+ { "pmax_row", "Row index of the bottom right corner of the Region of interest." },
+ { "pmax_col", "Col index of the bottom right corner of the Region of interest." },
+ { "debug_dir", "Output directory for debug image" },
+ {0, 0}
+};
+
+
+int main(int argc, char* argv[])
+{
+ using namespace scribo;
+ using namespace mln;
+
+ if (argc != 3 && argc != 4 && argc != 5 && argc != 8 && argc != 9)
+ return scribo::debug::usage(argv,
+ "Find text lines using left/right validation and display x-height in a binarized article.",
+ "input.pbm out.txt <denoise_enabled> [<pmin_row> <pmin_col> <pmax_row> <pmax_col>] <debug_dir>",
+ args_desc);
+
+ bool debug = false;
+
+ // Enable debug output.
+ if (argc == 5 || argc == 9)
+ {
+ scribo::make::internal::debug_filename_prefix = argv[argc - 1];
+ debug = true;
+ }
+
+ trace::entering("main");
+
+
+ image2d<bool> input;
+ mln::io::pbm::load(input, argv[1]);
+
+
+ // Optional Cropping
+ point2d crop_shift = literal::origin;
+ if (argc >= 8)
+ {
+ mln::def::coord
+ minr = atoi(argv[4]),
+ minc = atoi(argv[5]),
+ maxr = atoi(argv[6]),
+ maxc = atoi(argv[7]);
+
+ box2d roi = mln::make::box2d(minr, minc, maxr, maxc);
+ input = preprocessing::crop_without_localization(input, roi);
+ crop_shift = point2d(minr, minc);
+
+ if (debug)
+ mln::io::pbm::save(input,
+ scribo::make::debug_filename("input_cropped.pbm"));
+ }
+
+ bool denoise = (argc > 3 && atoi(argv[3]) != 0);
+
+
+ // Run document toolchain.
+ typedef image2d<scribo::def::lbl_type> L;
+ line_set<L>
+ lines = scribo::toolchain::text_in_doc(input, denoise, debug);
+
+
+ // Saving results
+ scribo::io::xml::save_text_lines(argv[1], lines, "out.xml");
+
+ // Specify shift due to previous crop.
+ scribo::io::text_boxes::save(lines, argv[2], crop_shift);
+
+
+ trace::exiting("main");
+}
diff --git a/scribo/src/preprocessing/Makefile.am b/scribo/src/preprocessing/Makefile.am
index 501233a..1f683e4 100644
--- a/scribo/src/preprocessing/Makefile.am
+++ b/scribo/src/preprocessing/Makefile.am
@@ -25,12 +25,34 @@ bin_PROGRAMS = \
homogeneous_contrast \
preprocess \
split_bg_fg \
- subsample \
unskew
denoise_SOURCES = denoise.cc
homogeneous_contrast_SOURCES = homogeneous_contrast.cc
preprocess_SOURCES = preprocess.cc
split_bg_fg_SOURCES = split_bg_fg.cc
-subsample_SOURCES = subsample.cc
unskew_SOURCES = unskew.cc
+
+if HAVE_MAGICKXX
+
+ bin_PROGRAMS += to_pgm
+ to_pgm_SOURCES = to_pgm.cc
+ to_pgm_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(TESSERACT_CPPFLAGS) \
+ `Magick++-config --cppflags`
+
+ to_pgm_LDFLAGS = $(AM_LDFLAGS) \
+ $(TESSERACT_LDFLAGS) \
+ -lpthread `Magick++-config --libs`
+
+ bin_PROGRAMS += subsample
+ subsample_SOURCES = subsample.cc
+ subsample_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(TESSERACT_CPPFLAGS) \
+ `Magick++-config --cppflags`
+
+ subsample_LDFLAGS = $(AM_LDFLAGS) \
+ $(TESSERACT_LDFLAGS) \
+ -lpthread `Magick++-config --libs`
+
+endif HAVE_MAGICKXX
\ No newline at end of file
diff --git a/scribo/src/preprocessing/subsample.cc b/scribo/src/preprocessing/subsample.cc
index 388d4d9..fde31e0 100644
--- a/scribo/src/preprocessing/subsample.cc
+++ b/scribo/src/preprocessing/subsample.cc
@@ -25,19 +25,21 @@
#include <mln/core/image/image2d.hh>
#include <mln/core/alias/neighb2d.hh>
-#include <mln/io/pgm/all.hh>
+#include <mln/io/magick/load.hh>
+#include <mln/io/ppm/save.hh>
#include <mln/subsampling/antialiased.hh>
-#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
#include <scribo/debug/usage.hh>
const char *args_desc[][2] =
{
- { "input.pgm", "A gray-scale image." },
+ { "input.*", "An image." },
{ "ratio", "Scale ratio." },
+ { "output.ppm", "A color image." },
{0, 0}
};
@@ -49,17 +51,17 @@ int main(int argc, char *argv[])
if (argc != 4)
return scribo::debug::usage(argv,
"Subsample.",
- "input.pgm ratio output.pgm",
+ "input.* ratio output.ppm",
args_desc);
trace::entering("main");
- typedef image2d<value::int_u8> I;
+ typedef image2d<value::rgb8> I;
I input;
- io::pgm::load(input, argv[1]);
+ io::magick::load(input, argv[1]);
unsigned ratio = atoi(argv[2]);
- io::pgm::save(mln::subsampling::antialiased(input, ratio), argv[3]);
+ io::ppm::save(mln::subsampling::antialiased(input, ratio), argv[3]);
trace::exiting("main");
}
diff --git a/scribo/src/text/Makefile.am b/scribo/src/text/Makefile.am
index aab9b19..3b3b4ae 100644
--- a/scribo/src/text/Makefile.am
+++ b/scribo/src/text/Makefile.am
@@ -29,15 +29,15 @@ cleantxt_SOURCES = cleantxt.cc
if HAVE_TESSERACT
if HAVE_TIFF
- bin_PROGRAMS += recognition
- recognition_SOURCES = recognition.cc
- recognition_CPPFLAGS = $(AM_CPPFLAGS) \
- $(TESSERACT_CPPFLAGS) \
- $(TIFF_CPPFLAGS)
- recognition_LDFLAGS = $(AM_LDFLAGS) \
- $(TESSERACT_LDFLAGS) \
- $(TIFF_LDFLAGS) \
- -lpthread
+ bin_PROGRAMS += pbm_lines_recognition
+ pbm_lines_recognition_SOURCES = pbm_lines_recognition.cc
+ pbm_lines_recognition_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(TESSERACT_CPPFLAGS) \
+ $(TIFF_CPPFLAGS)
+ pbm_lines_recognition_LDFLAGS = $(AM_LDFLAGS) \
+ $(TESSERACT_LDFLAGS) \
+ $(TIFF_LDFLAGS) \
+ -lpthread
bin_PROGRAMS += pbm_recognition
pbm_recognition_SOURCES = pbm_recognition.cc
diff --git a/scribo/src/text/recognition.cc b/scribo/src/text/pbm_lines_recognition.cc
similarity index 52%
rename from scribo/src/text/recognition.cc
rename to scribo/src/text/pbm_lines_recognition.cc
index de5cafa..5aaa15b 100644
--- a/scribo/src/text/recognition.cc
+++ b/scribo/src/text/pbm_lines_recognition.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -26,33 +26,30 @@
#include <iostream>
#include <mln/core/image/image2d.hh>
-
-#include <mln/util/array.hh>
-
-#include <mln/io/txt/save.hh>
#include <mln/io/pbm/load.hh>
+#include <mln/value/int_u16.hh>
-#include <mln/value/label_16.hh>
+#include <scribo/text/recognition.hh>
-#include <mln/core/alias/neighb2d.hh>
+#include <scribo/debug/usage.hh>
-#include <scribo/primitive/extract/objects.hh>
+#include <scribo/core/component_set.hh>
+#include <scribo/core/object_links.hh>
+#include <scribo/core/object_groups.hh>
-#include <scribo/primitive/group/apply.hh>
-#include <scribo/primitive/link/with_several_left_links.hh>
-#include <scribo/primitive/link/with_several_right_links.hh>
-#include <scribo/primitive/group/from_double_link.hh>
-#include <scribo/filter/objects_small.hh>
-#include <scribo/filter/objects_thin.hh>
-#include <scribo/text/recognition.hh>
+#include <scribo/text/merging.hh>
+#include <scribo/primitive/extract/components.hh>
+#include <scribo/primitive/link/with_single_left_link_dmax_ratio.hh>
+#include <scribo/primitive/group/from_single_link.hh>
+
+#include <scribo/io/text_boxes/save.hh>
-#include <scribo/debug/usage.hh>
const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. 'True' for objects, 'False'\
for the background." },
- { "out.txt", "OCR's output." },
+ { "lang", "Must be set to \"eng\", \"fra\", \"deu\", \"spa\", \"ita\" (Default \"fra\")" },
{0, 0}
};
@@ -63,39 +60,48 @@ int main(int argc, char* argv[])
using namespace scribo;
using namespace mln;
- if (argc != 3)
+ if (argc != 2 && argc != 3 && argc != 4)
return scribo::debug::usage(argv,
- "Text extraction and recognition",
- "input.pbm out.txt",
- args_desc,
- "The text is printed on the standard output and stored in 'out.txt'");
+ "Text recognition",
+ "input.pbm [lang] [file]",
+ args_desc);
trace::entering("main");
image2d<bool> input;
- io::pbm::load(input, argv[1]);
-
- /// Extract text.
- typedef mln_ch_value_(image2d<bool>,value::label_16) L;
- value::label_16 nbboxes;
- object_image(L)
- objects = scribo::primitive::extract::objects(input, c8(), nbboxes);
-
- /// Filter non interesting objects
- objects = filter::objects_small(objects, 4);
- objects = filter::objects_thin<L>(objects, 2);
-
- /// Group objects.
- object_links<L> left_link
- = primitive::link::with_several_left_links(objects, 30);
- object_links<L> right_link
- = primitive::link::with_several_right_links(objects, 30);
+ mln::io::pbm::load(input, argv[1]);
+
+ typedef image2d<value::int_u16> L;
+ value::int_u16 ncomps;
+ component_set<L>
+ comps = scribo::primitive::extract::components(input, c8(), ncomps);
+ std::cout << "ncomps = " << ncomps << std::endl;
+
+ object_links<L>
+ links = scribo::primitive::link::with_single_left_link_dmax_ratio(comps, 2);
+
object_groups<L>
- groups = primitive::group::from_double_link(objects, left_link, right_link);
+ groups = scribo::primitive::group::from_single_link(links);
+
+ line_set<L> lines(groups);
+ lines = text::merging(lines);
+
+ std::string str = argv[2];
+ const char *lang;
+ if (argc < 3 || (str != "eng" && str != "fra"
+ && str != "deu" && str != "spa"
+ && str != "ita"))
+ lang = "fra";
+ else
+ lang = argv[2];
+
+ char *output = 0;
+ if (argc >= 4)
+ output = argv[3];
+
+ scribo::text::recognition(lines, lang);
- objects = primitive::group::apply(objects, groups);
- /// Try to recognize text in grouped objects.
- scribo::text::recognition(objects, "fra", argv[2]);
+ scribo::io::text_boxes::save(lines, output);
trace::exiting("main");
}
diff --git a/scribo/src/text/pbm_recognition.cc b/scribo/src/text/pbm_recognition.cc
index 70ceca1..082faef 100644
--- a/scribo/src/text/pbm_recognition.cc
+++ b/scribo/src/text/pbm_recognition.cc
@@ -37,6 +37,7 @@ const char *args_desc[][2] =
{
{ "input.pbm", "A binary image. 'True' for objects, 'False'\
for the background." },
+ { "lang", "Must be set to \"eng\", \"fra\", \"deu\", \"spa\", \"ita\" (Default \"fra\")" },
{0, 0}
};
@@ -47,19 +48,28 @@ int main(int argc, char* argv[])
using namespace scribo;
using namespace mln;
- if (argc != 2)
+ if (argc != 2 && argc != 3)
return scribo::debug::usage(argv,
"Text recognition",
- "input.pbm",
- args_desc,
- "The text is printed on the standard output");
+ "input.pbm [lang]",
+ args_desc);
trace::entering("main");
image2d<bool> input;
io::pbm::load(input, argv[1]);
- scribo::text::recognition(input, "fra");
+
+ std::string str = argv[2];
+ const char *lang;
+ if (argc < 3 || (str != "eng" && str != "fra"
+ && str != "deu" && str != "spa"
+ && str != "ita"))
+ lang = "fra";
+ else
+ lang = argv[2];
+
+ scribo::text::recognition(input, lang);
trace::exiting("main");
}
diff --git a/scribo/src/text_in_article_pbm.cc b/scribo/src/text_in_article_pbm.cc
deleted file mode 100644
index 20a18e9..0000000
--- a/scribo/src/text_in_article_pbm.cc
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-
-#include <libgen.h>
-#include <fstream>
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/io/pbm/all.hh>
-#include <mln/io/ppm/save.hh>
-#include <mln/io/dump/save.hh>
-
-#include <mln/literal/colors.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/label_16.hh>
-
-#include <mln/data/paste_without_localization.hh>
-
-#include <scribo/core/line_set.hh>
-
-#include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/extract/vertical_separators.hh>
-
-#include <scribo/primitive/remove/separators.hh>
-
-#include <scribo/primitive/link/merge_double_link.hh>
-#include <scribo/primitive/link/internal/dmax_width_and_height.hh>
-#include <scribo/primitive/link/with_single_left_link_dmax_ratio.hh>
-#include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
-
-#include <scribo/primitive/group/from_single_link.hh>
-
-#include <scribo/filter/object_links_bbox_h_ratio.hh>
-#include <scribo/filter/objects_small.hh>
-
-
-#include <scribo/debug/usage.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/bboxes_enlarged_image.hh>
-#include <scribo/debug/mean_and_base_lines_image.hh>
-#include <scribo/debug/looks_like_a_text_line_image.hh>
-
-#include <scribo/make/debug_filename.hh>
-
-#include <scribo/text/recognition.hh>
-
-#include <scribo/text/merging.hh>
-
-
-#include <scribo/preprocessing/denoise_fg.hh>
-
-#include <scribo/io/xml/save_text_lines.hh>
-
-// #include <mln/morpho/closing/structural.hh>
-// #include <mln/win/rectangle2d.hh>
-
-
-const char *args_desc[][2] =
-{
- { "input.pbm", "A binary image. 'False' for object, 'True'\
-for the background." },
- { "out.txt", "Text output" },
- { "denoise", "1 enables denoising, 0 disables it. (enabled by default)" },
- { "pmin_row", "Row index of the top left corner of the Region of interest." },
- { "pmin_col", "Col index of the top left corner of the Region of interest." },
- { "pmax_row", "Row index of the bottom right corner of the Region of interest." },
- { "pmax_col", "Col index of the bottom right corner of the Region of interest." },
- { "debug_dir", "Output directory for debug image" },
- {0, 0}
-};
-
-
-int main(int argc, char* argv[])
-{
- using namespace scribo;
- using namespace mln;
-
- if (argc != 3 && argc != 4 && argc != 5 && argc != 8 && argc != 9)
- return scribo::debug::usage(argv,
- "Find text lines using left/right validation and display x-height in a binarized article.",
- "input.pbm out.txt <denoise: 0|1> [<pmin_row> <pmin_col> <pmax_row> <pmax_col>] <debug_dir>",
- args_desc);
-
- bool debug = false;
-
- // Enable debug output.
- if (argc == 5 || argc == 9)
- {
- scribo::make::internal::debug_filename_prefix = argv[argc - 1];
- debug = true;
- }
-
- trace::entering("main");
-
-
- image2d<bool> input;
- mln::io::pbm::load(input, argv[1]);
-
-
- // Optional Cropping
- if (argc >= 8)
- {
- def::coord
- minr = atoi(argv[4]),
- minc = atoi(argv[5]),
- maxr = atoi(argv[6]),
- maxc = atoi(argv[7]);
-
- box2d roi = mln::make::box2d(minr, minc, maxr, maxc);
- image2d<bool> tmp(maxr - minr + 1, maxc - minc + 1);
- data::paste_without_localization(input | roi, tmp);
- input = tmp;
-
- if (debug)
- mln::io::pbm::save(input,
- scribo::make::debug_filename("input_cropped.pbm"));
- }
-
-
- typedef value::label_16 V;
- typedef image2d<V> L;
-
-
- // Add whitespace separators.
-// win::rectangle2d win = win::rectangle2d(151, 41);
-// image2d<bool> whitespaces = morpho::closing::structural(input, win);
-// logical::not_inplace(whitespaces);
-
- // Remove separators
- std::cout << "Find vertical separators..." << std::endl;
- image2d<bool> separators = primitive::extract::vertical_separators(input, 81);
-
- std::cout << "Remove separators..." << std::endl;
- image2d<bool> input_cleaned = primitive::remove::separators(input,
- separators);
-
-// whitespaces += separators;
-
- if (debug)
- mln::io::pbm::save(separators,
- scribo::make::debug_filename("vseparators.pbm"));
-// mln::io::pbm::save(whitespaces, "separators.pbm");
-
-// mln::io::pbm::save(input_cleaned, "input_no_separators.pbm");
-
- // Denoise
- if (argc > 3 && atoi(argv[3]) != 0)
- {
- std::cout << "Denoise..." << std::endl;
- input_cleaned = preprocessing::denoise_fg(input_cleaned, c8(), 3);
- }
-
-// mln::io::pbm::save(input_cleaned, "input_denoised.pbm");
-
- /// Finding components.
- std::cout << "Finding components..." << std::endl;
- V ncomponents;
- component_set<L>
- components = scribo::primitive::extract::components(input_cleaned, c8(),
- ncomponents);
-
- /// Set separator components.
- components.add_separators(separators);
-// components.add_separators(whitespaces);
-
- components = scribo::filter::components_small(components, 3);
-
-
- /// Linking potential objects
- std::cout << "Linking objects..." << std::endl;
- object_links<L> left_link
- = primitive::link::with_single_left_link_dmax_ratio(components,
- primitive::link::internal::dmax_width_and_height(1),
- anchor::MassCenter);
- object_links<L> right_link
- = primitive::link::with_single_right_link_dmax_ratio(components,
- primitive::link::internal::dmax_width_and_height(1),
- anchor::MassCenter);
-
- // Validating left and right links.
- object_links<L>
- merged_links = primitive::link::merge_double_link(left_link, right_link);
-
-
- // Remove links if bboxes have too different sizes.
- object_links<L> hratio_filtered_links
- = filter::object_links_bbox_h_ratio(merged_links, 2.5f);
-
-
-// #ifndef NOUT
-// if (argc == 4)
-// {
-// image2d<value::rgb8>
-// hratio_decision_image = scribo::debug::decision_image(input,
-// merged_links,
-// hratio_filtered_links);
-// io::ppm::save(hratio_decision_image,
-// scribo::make::debug_filename("hratio_links_decision_image.ppm"));
-// }
-// #endif
-
-
-
-// // FIXME: from_single_link should return a packed object_groups?
-// //
-// //######
- object_groups<L>
- groups = primitive::group::from_single_link(hratio_filtered_links);
-// value::label_16 n_groups;
-// mln::fun::i2v::array<value::label_16>
-// groups_packed = mln::make::relabelfun(groups,
-// filtered_objects.nlabels(),
-// n_groups);
-// //######
-
-
-
- // Construct a line set.
- line_set<L>
- lines = scribo::make::line_set(groups);
-
-
-
- //===== DEBUG =====
-
- if (debug)
- {
-
- // Bboxes image.
- scribo::debug::save_bboxes_image(input, lines,
- scribo::make::debug_filename("step1_bboxes.ppm"));
-
- // Bboxes enlarged
- mln::io::ppm::save(scribo::debug::bboxes_enlarged_image(input, lines),
- scribo::make::debug_filename("step1_bboxes_enlarged.ppm"));
-
- // Looks like a text line
- mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
- scribo::make::debug_filename("step1_looks_like_a_text_line.ppm"));
-
-// // Bboxes + line infos
-// {
-// std::ofstream file(scribo::make::debug_filename("step1_bboxes_100p.txt").c_str());
-// // std::ofstream file_50p(scribo::make::debug_filename("step1_bboxes_50p.txt").c_str());
-
-// for_all_lines(l, lines)
-// if (lines(l).tag() != line::Merged
-// && lines(l).tag() != line::Ignored
-// && lines(l).tag() != line::Pathological)
-// {
-// file << lines(l).bbox().pmin().row() << " "
-// << lines(l).bbox().pmin().col() << " "
-// << lines(l).bbox().pmax().row() << " "
-// << lines(l).bbox().pmax().col() << " "
-// << lines(l).card() << " "
-// << lines(l).baseline() << " "
-// << lines(l).x_height() << " "
-// << lines(l).meanline() << " "
-// << lines(l).d_height() << " "
-// << lines(l).a_height() << " "
-// << lines(l).char_space() << " "
-// << lines(l).char_width() << std::endl;
-
-// // file_50p << lines(l).bbox().pmin().row() / 2 << " "
-// // << lines(l).bbox().pmin().col() / 2 << " "
-// // << lines(l).bbox().pmax().row() / 2 << " "
-// // << lines(l).bbox().pmax().col() / 2 << std::endl;
-// }
-
-// file.close();
-// // file_50p.close();
-// }
-
-
- // mean and base lines.
- mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
- scribo::make::debug_filename("step1_x_height.ppm"));
-
- }
- //===== END OF DEBUG =====
-
-
-
-
- std::cout << "Merging lines..." << std::endl;
- lines = scribo::text::merging(lines);
-
-
-
- //===== DEBUG =====
-
- if (debug)
- {
-
- // mean and base lines.
- mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
- scribo::make::debug_filename("step2_x_height.ppm"));
-
- // Looks like a text line
- mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
- scribo::make::debug_filename("step2_looks_like_a_text_line.ppm"));
-
- // Bboxes image.
- scribo::debug::save_bboxes_image(input, lines,
- scribo::make::debug_filename("step2_bboxes.ppm"));
-
-
- }
-
-
-// {
-// std::ofstream file(scribo::make::debug_filename("step2_bboxes_100p.txt").c_str());
-// // std::ofstream file_50p(scribo::make::debug_filename("step2_bboxes_50p.txt").c_str());
-
-// for_all_lines(l, lines)
-// if (lines(l).tag() != line::Merged
-// && lines(l).tag() != line::Ignored
-// && lines(l).tag() != line::Pathological)
-// {
-// file << lines(l).bbox().pmin().row() << " "
-// << lines(l).bbox().pmin().col() << " "
-// << lines(l).bbox().pmax().row() << " "
-// << lines(l).bbox().pmax().col() << " "
-// << lines(l).card() << " "
-// << lines(l).baseline() << " "
-// << lines(l).x_height() << " "
-// << lines(l).meanline() << " "
-// << lines(l).d_height() << " "
-// << lines(l).a_height() << " "
-// << lines(l).char_space() << " "
-// << lines(l).char_width() << std::endl;
-
-// // file_50p << lines(l).bbox().pmin().row() / 2 << " "
-// // << lines(l).bbox().pmin().col() / 2 << " "
-// // << lines(l).bbox().pmax().row() / 2 << " "
-// // << lines(l).bbox().pmax().col() / 2 << std::endl;
-// }
-
-// file.close();
-// // file_50p.close();
-// }
-
-
- //===== END OF DEBUG =====
-
-
- scribo::io::xml::save_text_lines(argv[1], lines, "out.xml");
-
-
-
- scribo::text::recognition(lines, "fra", argv[2]);
-
-
- trace::exiting("main");
-}
diff --git a/scribo/src/text_in_doc.cc b/scribo/src/text_in_doc.cc
deleted file mode 100644
index cfca7d1..0000000
--- a/scribo/src/text_in_doc.cc
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-
-#include <libgen.h>
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/logical/not.hh>
-
-#include <mln/labeling/colorize.hh>
-
-#include <mln/io/pbm/all.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/math/min.hh>
-
-#include <mln/literal/colors.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/label_16.hh>
-
-#include <mln/draw/box.hh>
-
-#include <mln/extension/adjust.hh>
-
-#include <scribo/table/erase.hh>
-
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/extract/lines_h_discontinued.hh>
-#include <scribo/primitive/extract/lines_v_discontinued.hh>
-
-#include <scribo/primitive/link/merge_double_link.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
-
-#include <scribo/primitive/group/apply.hh>
-#include <scribo/primitive/group/from_double_link.hh>
-#include <scribo/primitive/group/from_single_link.hh>
-
-#include <scribo/filter/object_links_bottom_aligned.hh>
-#include <scribo/filter/object_links_bbox_h_ratio.hh>
-#include <scribo/filter/object_links_bbox_overlap.hh>
-
-#include <scribo/filter/objects_small.hh>
-#include <scribo/filter/objects_thin.hh>
-#include <scribo/filter/objects_thick.hh>
-
-#include <scribo/filter/object_groups_small.hh>
-
-#include <scribo/text/recognition.hh>
-
-#include <scribo/debug/decision_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-
-#include <scribo/debug/usage.hh>
-
-#include <scribo/make/debug_filename.hh>
-
-
-const char *args_desc[][2] =
-{
- { "input.pbm", "A binary image. 'False' for objects, 'True'\
-for the background." },
- { "out.txt", "A text file with all the recognized text" },
- { "output_dir", "Output directory for debug image" },
- {0, 0}
-};
-
-
-int main(int argc, char* argv[])
-{
- using namespace scribo;
- using namespace mln;
-
- if (argc != 3 && argc != 4)
- return scribo::debug::usage(argv,
- "Find text in a binarized photo.",
- "input.pbm out.txt <output_dir>",
- args_desc,
- "Debug outputs. The recognized text is printed in the standard output.");
-
- if (argc == 4)
- scribo::make::internal::debug_filename_prefix = argv[3];
-
- trace::entering("main");
-
-
- image2d<bool> input;
- io::pbm::load(input, argv[1]);
-
- logical::not_inplace(input);
-
-
- typedef image2d<value::label_16> L;
-
- /// Extracting vertical and horizontal lines.
- std::cout << "Extracting lines..." << std::endl;
- value::label_16 nhlines, nvlines;
- object_image(L)
- lbl_v = primitive::extract::lines_v_discontinued(input, c8(),
- nvlines, 51, 8);
- object_image(L)
- lbl_h = primitive::extract::lines_h_discontinued(input, c8(),
- nhlines, 51, 6);
-
- /// Reconstruct and erase tables.
- std::cout << "Reconstructing and removing tables..." << std::endl;
- image2d<bool> input_notables
- = scribo::table::erase(input, lbl_h, lbl_v);
-
-
- io::pbm::save(input_notables, "table_erased.ppm");
-
- /// Finding objects.
- std::cout << "Finding objects..." << std::endl;
- value::label_16 nobjects;
- object_image(L)
- objects = scribo::primitive::extract::objects(input_notables,
- c8(),
- nobjects);
-
-
- /// First filtering.
- std::cout << "Filtering objects..." << std::endl;
- object_image(L) filtered_objects
- = scribo::filter::objects_small(objects, 6);
-
- filtered_objects
- = scribo::filter::objects_thin(filtered_objects, 1);
-
-// filtered_objects
-// = scribo::filter::objects_thick(filtered_objects,
-// math::min(input.ncols(), input.nrows()) / 5);
-
-
-
- /// Linking potential objects
- std::cout << "Linking objects..." << std::endl;
- object_links<L> left_link
- = primitive::link::with_single_left_link(filtered_objects, 30);
- object_links<L> right_link
- = primitive::link::with_single_right_link(filtered_objects, 30);
-
-
-#ifndef NOUT
- if (argc == 4)
- {
- std::cerr << "BEFORE - nobjects = " << nobjects << std::endl;
- scribo::debug::save_linked_bboxes_image(input,
- filtered_objects,
- left_link, right_link,
- literal::red, literal::cyan,
- literal::yellow,
- literal::green,
- scribo::make::debug_filename("links.ppm"));
- }
-#endif
-
-
- // Validating left and right links.
- object_links<L>
- merged_links = primitive::link::merge_double_link(filtered_objects,
- left_link,
- right_link);
-
-
-
-
- // Remove links if bboxes are not aligned.
- std::cout << "Filtering object links..." << std::endl;
- object_links<L> bottom_filtered_links
- = filter::object_links_bottom_aligned(filtered_objects,
- merged_links,
- 5);
-
-
-
-#ifndef NOUT
- if (argc == 4)
- {
- image2d<value::rgb8>
- bottom_decision_image = scribo::debug::decision_image(input,
- merged_links,
- bottom_filtered_links);
-
- io::ppm::save(bottom_decision_image,
- scribo::make::debug_filename("bottom_links_decision_image.ppm"));
- }
-#endif
-
-
-
-
-
- // Remove links if bboxes have too different sizes.
- object_links<L> hratio_filtered_links
- = filter::object_links_bbox_h_ratio(filtered_objects,
- bottom_filtered_links,
- 0.6f);
-
-
-
-
-#ifndef NOUT
- if (argc == 4)
- {
- image2d<value::rgb8>
- hratio_decision_image = scribo::debug::decision_image(input,
- bottom_filtered_links,
- hratio_filtered_links);
- io::ppm::save(hratio_decision_image,
- scribo::make::debug_filename("hratio_links_decision_image.ppm"));
- }
-#endif
-
-
-
-
- //Remove links if bboxes overlap too much.
- object_links<L> overlap_filtered_links
- = filter::object_links_bbox_overlap(filtered_objects,
- hratio_filtered_links,
- 0.80f);
-
-
-
-
-#ifndef NOUT
- if (argc == 4)
- {
- image2d<value::rgb8> overlap_decision_image
- = scribo::debug::decision_image(input,
- hratio_filtered_links,
- overlap_filtered_links);
- io::ppm::save(overlap_decision_image,
- scribo::make::debug_filename("overlap_links_decision_image.ppm"));
- }
-#endif
-
-
-
-
- object_groups<L>
- groups = primitive::group::from_single_link(filtered_objects,
- overlap_filtered_links);
-
-
-// // Remove objects part of groups with strictly less than 3 objects.
-// object_groups<L> filtered_groups = filter::object_groups_small(groups, 3);
-
-
-// #ifndef NOUT
-// image2d<value::rgb8>
-// decision_image = scribo::debug::decision_image(input,
-// groups, filtered_groups);
-// #endif
-
- std::cout << "Grouping objects..." << std::endl;
- object_image(L)
- grouped_objects = primitive::group::apply(filtered_objects, groups);
-
-
-#ifndef NOUT
- if (argc == 4)
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- grouped_objects,
- grouped_objects.nlabels()),
- scribo::make::debug_filename("out.ppm"));
-#endif
-
-
- std::cout << "Text recognition..." << std::endl;
- text::recognition(grouped_objects, "fra", argv[2]);
-
- trace::exiting("main");
-}
diff --git a/scribo/src/text_in_doc_ppm.cc b/scribo/src/text_in_doc_ppm.cc
deleted file mode 100644
index 0dafc09..0000000
--- a/scribo/src/text_in_doc_ppm.cc
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-
-#include <libgen.h>
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/logical/not.hh>
-
-#include <mln/labeling/colorize.hh>
-
-#include <mln/io/pbm/all.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/math/min.hh>
-
-#include <mln/literal/colors.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/label_16.hh>
-
-#include <mln/draw/box.hh>
-
-#include <mln/extension/adjust.hh>
-
-#include <scribo/binarization/sauvola.hh>
-
-#include <scribo/table/erase.hh>
-
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/primitive/extract/objects.hh>
-#include <scribo/primitive/extract/lines_h_discontinued.hh>
-#include <scribo/primitive/extract/lines_v_discontinued.hh>
-
-#include <scribo/primitive/link/merge_double_link.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
-
-#include <scribo/primitive/group/apply.hh>
-#include <scribo/primitive/group/from_double_link.hh>
-#include <scribo/primitive/group/from_single_link.hh>
-
-#include <scribo/filter/object_links_bottom_aligned.hh>
-#include <scribo/filter/object_links_bbox_h_ratio.hh>
-#include <scribo/filter/object_links_bbox_overlap.hh>
-
-#include <scribo/filter/objects_small.hh>
-#include <scribo/filter/objects_thin.hh>
-#include <scribo/filter/objects_thick.hh>
-
-#include <scribo/filter/object_groups_small.hh>
-
-#include <scribo/text/recognition.hh>
-
-#include <scribo/debug/decision_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-
-#include <scribo/debug/usage.hh>
-
-#include <scribo/preprocessing/split_bg_fg.hh>
-
-#include <scribo/make/debug_filename.hh>
-
-
-const char *args_desc[][2] =
-{
- { "input.ppm", "A color image." },
- { "out.txt", "A text file with all the recognized text" },
- { "output_dir", "Output directory for debug image" },
- {0, 0}
-};
-
-
-int main(int argc, char* argv[])
-{
- using namespace scribo;
- using namespace mln;
-
- if (argc != 3 && argc != 4)
- return scribo::debug::usage(argv,
- "Find text in a color document.",
- "input.ppm out.txt <output_dir>",
- args_desc,
- "Debug outputs. The recognized text is printed in the standard output.");
-
- if (argc == 4)
- scribo::make::internal::debug_filename_prefix = argv[3];
-
- trace::entering("main");
-
-
- image2d<value::rgb8> input_rgb;
- io::ppm::load(input_rgb, argv[1]);
-
-
- unsigned lambda;
- if (argc == 5)
- lambda = atoi(argv[4]);
- else
- lambda = 1.2 * (input_rgb.nrows() + input_rgb.ncols());
-
- // Extract foreground
- std::cout << "Extracting foreground..." << std::endl;
- image2d<value::rgb8>
- fg = preprocessing::split_bg_fg(input_rgb,
- lambda,
- 32).second();
-
- // Binarize foreground to use it in the processing chain.
- std::cout << "Binarizing foreground..." << std::endl;
- image2d<bool> input = scribo::binarization::sauvola(fg);
-
-
- typedef image2d<value::label_16> L;
-
- /// Extracting vertical and horizontal lines.
- std::cout << "Extracting lines..." << std::endl;
- value::label_16 nhlines, nvlines;
- object_image(L)
- lbl_v = primitive::extract::lines_v_discontinued(input, c8(),
- nvlines, 51, 8);
- object_image(L)
- lbl_h = primitive::extract::lines_h_discontinued(input, c8(),
- nhlines, 51, 6);
-
- /// Reconstruct and erase tables.
- std::cout << "Reconstructing and removing tables..." << std::endl;
- image2d<bool> input_notables
- = scribo::table::erase(input, lbl_h, lbl_v);
-
-
- io::pbm::save(input_notables, "table_erased.ppm");
-
- /// Finding objects.
- std::cout << "Finding objects..." << std::endl;
- value::label_16 nobjects;
- object_image(L)
- objects = scribo::primitive::extract::objects(input_notables,
- c8(),
- nobjects);
-
-
- /// First filtering.
- std::cout << "Filtering objects..." << std::endl;
- object_image(L) filtered_objects
- = scribo::filter::objects_small(objects, 6);
-
- filtered_objects
- = scribo::filter::objects_thin(filtered_objects, 1);
-
-// filtered_objects
-// = scribo::filter::objects_thick(filtered_objects,
-// math::min(input.ncols(), input.nrows()) / 5);
-
-
-
- /// Linking potential objects
- std::cout << "Linking objects..." << std::endl;
- object_links<L> left_link
- = primitive::link::with_single_left_link(filtered_objects, 30);
- object_links<L> right_link
- = primitive::link::with_single_right_link(filtered_objects, 30);
-
-
-#ifndef NOUT
- if (argc == 4)
- {
- std::cerr << "BEFORE - nobjects = " << nobjects << std::endl;
- scribo::debug::save_linked_bboxes_image(input,
- filtered_objects,
- left_link, right_link,
- literal::red, literal::cyan,
- literal::yellow,
- literal::green,
- scribo::make::debug_filename("links.ppm"));
- }
-#endif
-
-
- // Validating left and right links.
- object_links<L>
- merged_links = primitive::link::merge_double_link(filtered_objects,
- left_link,
- right_link);
-
-
-
-
- // Remove links if bboxes are not aligned.
- std::cout << "Filtering object links..." << std::endl;
- object_links<L> bottom_filtered_links
- = filter::object_links_bottom_aligned(filtered_objects,
- merged_links,
- 5);
-
-
-
-#ifndef NOUT
- if (argc == 4)
- {
- image2d<value::rgb8>
- bottom_decision_image = scribo::debug::decision_image(input,
- merged_links,
- bottom_filtered_links);
-
- io::ppm::save(bottom_decision_image,
- scribo::make::debug_filename("bottom_links_decision_image.ppm"));
- }
-#endif
-
-
-
-
-
-// // Remove links if bboxes have too different sizes.
-// object_links<L> hratio_filtered_links
-// = filter::object_links_bbox_h_ratio(filtered_objects,
-// bottom_filtered_links,
-// 0.6f);
-
-
-
-
-// #ifndef NOUT
-// if (argc == 4)
-// {
-// image2d<value::rgb8>
-// hratio_decision_image = scribo::debug::decision_image(input,
-// bottom_filtered_links,
-// hratio_filtered_links);
-// io::ppm::save(hratio_decision_image,
-// scribo::make::debug_filename("hratio_links_decision_image.ppm"));
-// }
-// #endif
-
-
-
-
- //Remove links if bboxes overlap too much.
- object_links<L> overlap_filtered_links
- = filter::object_links_bbox_overlap(filtered_objects,
- bottom_filtered_links,
- 0.80f);
-
-
-
-
-#ifndef NOUT
- if (argc == 4)
- {
- image2d<value::rgb8> overlap_decision_image
- = scribo::debug::decision_image(input,
- bottom_filtered_links,
- overlap_filtered_links);
- io::ppm::save(overlap_decision_image,
- scribo::make::debug_filename("overlap_links_decision_image.ppm"));
- }
-#endif
-
-
-
-
- object_groups<L>
- groups = primitive::group::from_single_link(filtered_objects,
- overlap_filtered_links);
-
-
-// // Remove objects part of groups with strictly less than 3 objects.
-// object_groups<L> filtered_groups = filter::object_groups_small(groups, 3);
-
-
-// #ifndef NOUT
-// image2d<value::rgb8>
-// decision_image = scribo::debug::decision_image(input,
-// groups, filtered_groups);
-// #endif
-
- std::cout << "Grouping objects..." << std::endl;
- object_image(L)
- grouped_objects = primitive::group::apply(filtered_objects, groups);
-
-
-#ifndef NOUT
- if (argc == 4)
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- grouped_objects,
- grouped_objects.nlabels()),
- scribo::make::debug_filename("out.ppm"));
-#endif
-
- std::cout << "Text recognition..." << std::endl;
- text::recognition(grouped_objects, "fra", argv[2]);
-
- trace::exiting("main");
-}
diff --git a/scribo/src/text_in_article_preprocess.cc b/scribo/src/text_in_doc_preprocess.cc
similarity index 84%
rename from scribo/src/text_in_article_preprocess.cc
rename to scribo/src/text_in_doc_preprocess.cc
index bf70c7f..27ed9ed 100644
--- a/scribo/src/text_in_article_preprocess.cc
+++ b/scribo/src/text_in_doc_preprocess.cc
@@ -41,8 +41,11 @@
#include <scribo/debug/usage.hh>
#include <scribo/preprocessing/split_bg_fg.hh>
+#include <scribo/preprocessing/deskew.hh>
+#include <mln/io/pgm/all.hh>
+
const char *args_desc[][2] =
{
@@ -81,11 +84,20 @@ int main(int argc, char* argv[])
input_rgb = preprocessing::split_bg_fg(input_rgb, lambda, 32).second();
}
+ // Convert to Gray level image.
+ image2d<value::int_u8>
+ input_gl = data::transform(input_rgb, mln::fun::v2v::rgb_to_int_u<8>());
+
+
+ // Deskewing
+ std::cout << "Deskew if needed..." << std::endl;
+ input_gl = preprocessing::deskew(input_gl);
+
// Binarize foreground to use it in the processing chain.
std::cout << "Binarizing foreground..." << std::endl;
- image2d<bool> input = scribo::binarization::sauvola_ms(input_rgb, 101, 3);
+ image2d<bool> input_bin = scribo::binarization::sauvola_ms(input_gl, 101, 3);
- logical::not_inplace(input);
+ logical::not_inplace(input_bin);
- mln::io::pbm::save(input, argv[2]);
+ mln::io::pbm::save(input_bin, argv[2]);
}
diff --git a/scribo/src/text_in_photo.cc b/scribo/src/text_in_photo.cc
deleted file mode 100644
index 5426dce..0000000
--- a/scribo/src/text_in_photo.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#include <libgen.h>
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/colorize.hh>
-
-#include <mln/io/pbm/all.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/math/min.hh>
-
-#include <mln/literal/colors.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/label_16.hh>
-
-#include <mln/draw/box.hh>
-
-
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/primitive/extract/objects.hh>
-
-#include <scribo/primitive/link/merge_double_link.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
-
-#include <scribo/primitive/group/apply.hh>
-#include <scribo/primitive/group/from_double_link.hh>
-#include <scribo/primitive/group/from_single_link.hh>
-
-#include <scribo/filter/object_links_bbox_h_ratio.hh>
-#include <scribo/filter/object_links_bbox_overlap.hh>
-
-#include <scribo/filter/objects_small.hh>
-#include <scribo/filter/objects_thin.hh>
-#include <scribo/filter/objects_thick.hh>
-
-#include <scribo/filter/object_groups_small.hh>
-
-#include <scribo/debug/decision_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-
-#include <scribo/debug/usage.hh>
-
-#include <scribo/make/debug_filename.hh>
-
-const char *args_desc[][2] =
-{
- { "input.pbm", "A binary image. 'True' for objects, 'False'\
-for the background." },
- {0, 0}
-};
-
-
-int main(int argc, char* argv[])
-{
- using namespace scribo;
- using namespace mln;
-
- if (argc != 3)
- return scribo::debug::usage(argv,
- "Find text in a binarized photo.",
- "input.pbm output_dir",
- args_desc,
- "A color image where the text is \
-highlighted.");
-
- scribo::make::internal::debug_filename_prefix = argv[2];
-
- trace::entering("main");
-
- image2d<bool> input;
- io::pbm::load(input, argv[1]);
-
- typedef image2d<value::label_16> L;
-
- /// Finding objects.
- value::label_16 nobjects;
- object_image(L)
- objects = scribo::primitive::extract::objects(input, c8(), nobjects);
-
- /// First filtering.
- object_image(L) filtered_objects
- = scribo::filter::objects_small(objects, 6);
-
- filtered_objects
- = scribo::filter::objects_thin(filtered_objects, 1);
-
-// filtered_objects
-// = scribo::filter::objects_thick(filtered_objects,
-// math::min(input.ncols(), input.nrows()) / 5);
-
-
- /// Grouping potential objects
- object_links<L> left_link
- = primitive::link::with_single_left_link(filtered_objects, 30);
- object_links<L> right_link
- = primitive::link::with_single_right_link(filtered_objects, 30);
-
-
-
-
-
-#ifndef NOUT
- std::cout << "BEFORE - nobjects = " << nobjects << std::endl;
- scribo::debug::save_linked_bboxes_image(input,
- filtered_objects,
- left_link, right_link,
- literal::red, literal::cyan,
- literal::yellow,
- literal::green,
- scribo::make::debug_filename("links.ppm"));
-#endif
-
-
-
- // Validating left and right links.
- object_links<L>
- merged_links = primitive::link::merge_double_link(filtered_objects,
- left_link,
- right_link);
- // Remove links if bboxes have too different sizes.
- object_links<L>
- hratio_filtered_links = filter::object_links_bbox_h_ratio(filtered_objects,
- merged_links,
- 0.7f);
-
-
-
-
-#ifndef NOUT
- image2d<value::rgb8>
- hratio_decision_image = scribo::debug::decision_image(input,
- merged_links,
- hratio_filtered_links);
- io::ppm::save(hratio_decision_image,
- scribo::make::debug_filename("hratio_links_decision_image.ppm"));
-#endif
-
-
-
-
- //Remove links if bboxes overlap too much.
- object_links<L> overlap_filtered_links
- = filter::object_links_bbox_overlap(filtered_objects,
- hratio_filtered_links,
- 0.80f);
-
-
-
-
-#ifndef NOUT
- image2d<value::rgb8> overlap_decision_image
- = scribo::debug::decision_image(input,
- hratio_filtered_links,
- overlap_filtered_links);
- io::ppm::save(overlap_decision_image,
- scribo::make::debug_filename("overlap_links_decision_image.ppm"));
-#endif
-
-
-
-
- object_groups<L>
- groups = primitive::group::from_single_link(filtered_objects,
- overlap_filtered_links);
-
-
- // Remove objects part of groups with strictly less than 3 objects.
- object_groups<L> filtered_groups = filter::object_groups_small(groups, 3);
-
-
-
-
-#ifndef NOUT
- image2d<value::rgb8> decision_image;
- if (argc == 4)
- decision_image = scribo::debug::decision_image(input,
- groups, filtered_groups);
-#endif
-
-
-
- /// Apply grouping in the object image.
- object_image(L)
- grouped_objects = primitive::group::apply(filtered_objects,
- filtered_groups);
-
-
- /// Objects have been grouped. We try to link groups together.
- /// This time a single link is enough since non-wanted objects have
- /// been removed.
- left_link
- = primitive::link::with_single_left_link(grouped_objects, 30);
-
- /// Grouping groups.
- groups = primitive::group::from_single_link(grouped_objects, left_link);
-
- grouped_objects = primitive::group::apply(grouped_objects, groups);
-
-
-
-
-#ifndef NOUT
- scribo::draw::bounding_boxes(decision_image, grouped_objects, literal::blue);
- io::ppm::save(decision_image, scribo::make::debug_filename("decision_image.ppm"));
-
- std::cout << "AFTER - nobjects = " << grouped_objects.nlabels() << std::endl;
-#endif
-
-
-
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- grouped_objects,
- grouped_objects.nlabels()),
-// "/dev/null");
- scribo::make::debug_filename("out.ppm"));
-
-
- trace::exiting("main");
-}
diff --git a/scribo/src/text_in_photo_invert.cc b/scribo/src/text_in_photo_invert.cc
deleted file mode 100644
index 71baee6..0000000
--- a/scribo/src/text_in_photo_invert.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#include <libgen.h>
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/colorize.hh>
-
-#include <mln/io/pbm/all.hh>
-#include <mln/io/pgm/all.hh>
-#include <mln/io/ppm/all.hh>
-
-#include <mln/math/min.hh>
-
-#include <mln/literal/colors.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/label_16.hh>
-
-#include <mln/draw/box.hh>
-
-#include <mln/logical/not.hh>
-
-#include <mln/labeling/superpose.hh>
-
-#include <scribo/primitive/extract/objects.hh>
-
-#include <scribo/primitive/link/with_single_left_link.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
-
-#include <scribo/primitive/group/apply.hh>
-#include <scribo/primitive/group/from_double_link.hh>
-#include <scribo/primitive/group/from_single_link.hh>
-
-#include <scribo/filter/objects_small.hh>
-#include <scribo/filter/objects_thin.hh>
-#include <scribo/filter/objects_thick.hh>
-#include <scribo/filter/object_groups_small.hh>
-
-#include <scribo/make/debug_filename.hh>
-
-#include <scribo/debug/decision_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-
-#include <scribo/debug/usage.hh>
-
-const char *args_desc[][2] =
-{
- { "input.pbm", "A binary image. 'True' for objects, 'False'\
-for the background." },
- { "input_i.pbm", "A binary image. 'True' for objects, 'False'\
-for the background." },
- {0, 0}
-};
-
-
-
-namespace mln
-{
-
- template <typename V>
- object_image(image2d<value::label_16>)
- run(const image2d<V>& input)
- {
- using namespace scribo;
-
- typedef image2d<value::label_16> L;
-
- /// Finding objects.
- value::label_16 nobjects;
- object_image(L)
- objects = scribo::primitive::extract::objects(input, c8(), nobjects);
-
-
- /// First filtering.
- object_image(L) filtered_objects
- = scribo::filter::objects_small(objects, 6);
-
- filtered_objects
- = scribo::filter::objects_thin(filtered_objects, 1);
-
- filtered_objects
- = scribo::filter::objects_thick(filtered_objects,
- math::min(input.ncols(), input.nrows()) / 6);
-
-
- /// Finding links between potential objects
- object_links<L> left_link
- = primitive::link::with_single_left_link(filtered_objects, 30);
- object_links<L> right_link
- = primitive::link::with_single_right_link(filtered_objects, 30);
-
-
-
- std::cout << "BEFORE - nobjects = " << nobjects << std::endl;
- scribo::debug::save_linked_bboxes_image(input,
- filtered_objects,
- left_link, right_link,
- literal::red, literal::cyan,
- literal::yellow,
- literal::green,
- scribo::make::debug_filename("links.ppm"));
-
-
-
-
- // Trying to group objects
- object_groups<L>
- groups = primitive::group::from_double_link(filtered_objects,
- left_link, right_link);
-
- // Remove objects part of groups with strictly less than 3 objects.
- object_groups<L> filtered_groups = filter::object_groups_small(groups, 3);
-
-#ifndef NOUT
- image2d<value::rgb8>
- decision_image = scribo::debug::decision_image(input,
- groups, filtered_groups);
-#endif
-
-
- /// Apply grouping in the object image.
- object_image(L)
- grouped_objects = primitive::group::apply(filtered_objects,
- filtered_groups);
-
-
- // Objects have been removed we need to update object links again.
- // This time a single link is enough since non-wanted objects have
- // been removed.
- left_link
- = primitive::link::with_single_left_link(filtered_objects, 30);
-
-
-
- // Grouping objects again.
- groups = primitive::group::from_single_link(filtered_objects, left_link);
-
- grouped_objects = primitive::group::apply(filtered_objects, groups);
-
-#ifndef NOUT
- for (unsigned i = 1; i <= grouped_objects.nlabels(); ++i)
- mln::draw::box(decision_image, grouped_objects.bbox(i), literal::blue);
-
- io::ppm::save(decision_image, scribo::make::debug_filename("decision_image.ppm"));
-#endif // ! NOUT
-
-
- std::cout << "AFTER - nobjects = " << grouped_objects.nlabels() << std::endl;
-//
-
- return grouped_objects;
- }
-
-
-}
-
-
-
-int main(int argc, char* argv[])
-{
- using namespace scribo;
- using namespace mln;
-
- if (argc != 4)
- return scribo::debug::usage(argv,
- "Find text in a binarized photo.",
- "input.pbm input_i.pbm output_dir",
- args_desc,
- "Several color images");
-
-
- scribo::make::internal::debug_filename_prefix = argv[3];
-
-
- trace::entering("main");
-
- image2d<bool> input;
- io::pbm::load(input, argv[1]);
-
- typedef image2d<value::label_16> L;
-
- value::label_16 new_nlabels;
-
- object_image(L) out_1 = run(input);
-
-#ifndef NOUT
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- out_1,
- new_nlabels),
- scribo::make::debug_filename("out_normal.ppm"));
-#endif // ! NOUT
-
-
- image2d<bool> input_i;
- io::pbm::load(input_i, argv[2]);
-
- object_image(L) out_2 = run(input_i);
-
-#ifndef NOUT
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- out_2,
- new_nlabels),
- scribo::make::debug_filename("out_inverted.ppm"));
-#endif // ! NOUT
-
-
- L out = labeling::superpose(out_1, out_1.nlabels(),
- out_2, out_2.nlabels(),
- new_nlabels);
-
-
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- out,
- new_nlabels),
- scribo::make::debug_filename("out_combined.ppm"));
-
-
- trace::exiting("main");
-}
diff --git a/scribo/src/text_in_photo_pbm_fast.cc b/scribo/src/text_in_photo_pbm_fast.cc
deleted file mode 100644
index 6b27bbc..0000000
--- a/scribo/src/text_in_photo_pbm_fast.cc
+++ /dev/null
@@ -1,441 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#include <libgen.h>
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/imorph/tr_image.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/colorize.hh>
-
-#include <mln/data/stretch.hh>
-
-#include <mln/io/pbm/all.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/math/min.hh>
-
-#include <mln/logical/not.hh>
-
-#include <mln/literal/colors.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/label_16.hh>
-
-#include <mln/fun/v2v/rgb_to_int_u.hh>
-
-#include <mln/data/wrap.hh>
-
-#include <mln/draw/box.hh>
-
-#include <mln/geom/translate.hh>
-
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/binarization/sauvola_ms.hh>
-#include <scribo/binarization/sauvola.hh>
-
-#include <scribo/primitive/extract/components.hh>
-
-#include <scribo/primitive/link/merge_double_link.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
-
-#include <scribo/primitive/group/apply.hh>
-#include <scribo/primitive/group/from_double_link.hh>
-#include <scribo/primitive/group/from_single_link.hh>
-
-#include <scribo/filter/objects_with_holes.hh>
-#include <scribo/filter/object_links_bbox_h_ratio.hh>
-#include <scribo/filter/object_links_bbox_overlap.hh>
-
-#include <scribo/filter/common/objects_photo.hh>
-
-#include <scribo/filter/object_groups_small.hh>
-#include <scribo/filter/object_groups_v_thickness.hh>
-
-#include <scribo/debug/decision_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-
-#include <scribo/debug/usage.hh>
-
-#include <scribo/preprocessing/split_bg_fg.hh>
-
-#include <scribo/make/debug_filename.hh>
-
-#include <mln/util/timer.hh>
-#include <mln/core/var.hh>
-
-
-#include <scribo/src/afp/components.hh>
-#include <scribo/src/afp/link.hh>
-#include <scribo/src/afp/regroup.hh>
-
-#include <scribo/core/line_set.hh>
-
-const char *args_desc[][2] =
-{
- { "input.ppm", "A color image." },
- { "debug_output_dir", "Directory were debug images will be saved" },
- { "lambda", "Lambda value used for foreground extraction" },
- {0, 0}
-};
-
-
-namespace mln
-{
-
- struct mask_non_text : Function_v2v<mask_non_text>
- {
- typedef value::rgb8 result;
- typedef image2d<bool> I;
-
- mask_non_text(const image2d<bool>& mask)
- : mask_(mask), p_(mask_)
- {
- p_.start();
- }
-
- result operator()(const result& v) const
- {
- bool b = p_.val();
- p_.next();
- if (!b)
- return v / 2;
- else
- return v;
-
- }
-
- I mask_;
- mutable mln_pixter_(I) p_;
- };
-
-
- template <typename I, typename L>
- mln_concrete(I)
- compute_highlight_image(const I& input_rgb,
- const scribo::component_set<L>& components)
- {
- mln_ch_value(I, bool) mask;
- initialize(mask, input_rgb);
- data::fill(mask, false);
-
- for_all_comps(i, components)
- if (components(i).is_valid())
- data::fill((mask | components(i).bbox()).rw(), true);
-
- mask_non_text f(mask);
- mln_concrete(I) output = data::transform(input_rgb, f);
-
- for_all_comps(i, components)
- if (components(i).is_valid())
- mln::draw::box(output, components(i).bbox(), literal::red);
-
- return output;
- }
-
- template <typename I, typename L>
- mln_concrete(I)
- compute_text_image(const I& input_rgb,
- const scribo::component_set<L>& grouped_objects)
- {
- unsigned shift = 5;
- float height = 1, width = 0;
- for_all_comps(i, grouped_objects)
- if (grouped_objects(i).is_valid())
- {
- height += grouped_objects(i).bbox().nrows() + shift;
- width = math::max(static_cast<float>(grouped_objects(i).bbox().ncols()),
- width);
- }
- if (width == 0)
- width = 1;
-
- I output(height, width);
- data::fill(output, literal::black);
-
- algebra::vec<2, float> dv;
- dv[0] = 0;
- dv[1] = 0;
- for_all_comps(i, grouped_objects)
- if (grouped_objects(i).is_valid())
- {
- mln_VAR(tmp, duplicate(input_rgb | grouped_objects(i).bbox()));
-
- typedef fun::x2x::translation<mln_site_(I)::dim, float> trans_t;
- trans_t trans(dv - grouped_objects(i).bbox().pmin().to_vec());
-
- mln_domain(I)
- tr_box(grouped_objects(i).bbox().pmin().to_vec() + trans.t(),
- grouped_objects(i).bbox().pmax().to_vec() + trans.t());
-
- tr_image<mln_domain(I), tmp_t, trans_t> tr_ima(tr_box, tmp, trans);
-
- data::paste(tr_ima, output);
- dv[0] += grouped_objects(i).bbox().nrows() + shift;
- }
-
- return output;
- }
-
-} // end of namespace mln
-
-
-int main(int argc, char* argv[])
-{
- using namespace scribo;
- using namespace mln;
-
- if (argc < 3 || argc > 8)
- return scribo::debug::usage(argv,
- "Find text in a photo.\n\n\
-Common usage: ./pbm_text_in_photo input.pbm output.ppm 1 1 1",
- "input.pbm output.ppm <Bg comp filter enabled> <small group filter enabled> <thin group filter enabled> [debug_output_dir] [lambda]",
- args_desc,
- "A color image where the text is highlighted.");
-
- std::string out_base_dir;
- bool debug = false;
- if (argc > 6)
- {
- scribo::make::internal::debug_filename_prefix = argv[6];
- debug = true;
- out_base_dir = argv[6];
- }
-
- trace::entering("main");
-
- image2d<bool> input;
- io::pbm::load(input, argv[1]);
-
-
- mln::util::timer timer_, global_t_;
- float t_;
-
-
-
- typedef image2d<value::label_16> L;
-
- /// Finding components.
- timer_.restart();
-
- typedef component_set<L> Obj;
- Obj filtered_components;
-
- {
- mln::util::array<std::pair<box2d, std::pair<point2d, unsigned> > > attribs;
-
- value::label_16 ncomponents;
- L components = extract_components(input, ncomponents, attribs);
-
- filtered_components = Obj(components, ncomponents, attribs);
- }
-
- t_ = timer_;
- std::cout << "Object extracted " << t_ << " - " << filtered_components.nelements() << " components" << std::endl;
-
- /// linking potential components
- timer_.restart();
- mln::util::couple<object_links<L>, object_links<L> >
- links = primitive::link::left_right(filtered_components);
-
- object_links<L>& left_link = links.first();
- object_links<L>& right_link = links.second();
-
- t_ = timer_;
- std::cout << "Link done " << t_ << std::endl;
-
-
-
- // Validating left and right links.
- timer_.restart();
- object_links<L>
- merged_links = primitive::link::merge_double_link(left_link, right_link);
- t_ = timer_;
- std::cout << "Right/Left Validation. " << t_ << std::endl;
-
-
- // Remove links if bboxes have too different sizes.
- timer_.restart();
- object_links<L>
- hratio_filtered_links = filter::object_links_bbox_h_ratio(merged_links,
- 1.50f);
-
- //Remove links if bboxes overlap too much.
- object_links<L> overlap_filtered_links
- = filter::object_links_bbox_overlap(hratio_filtered_links, 0.80f);
-
- t_ = timer_;
- std::cout << "Components links filtered. " << t_ << std::endl;
-
- timer_.restart();
- object_groups<L>
- groups = primitive::group::from_single_link(overlap_filtered_links);
-
-
-
-// Apply grouping in a temporary image (for debug purpose).
-
- t_ = timer_;
- std::cout << "Components grouped. " << t_ << std::endl;
-
- std::cout << "Filtering groups..." << std::endl;
-
- mln::util::timer g_timer;
-
- timer_.restart();
- // Remove components part of groups with strictly less than 3 components.
-
- g_timer.start();
- object_groups<L> filtered_small_groups;
- if (argc > 4 && atoi(argv[4]) != 0)
- {
- std::cout << "** Using group too small" << std::endl;
- filtered_small_groups = filter::object_groups_small(groups, 3);
- }
- else
- filtered_small_groups = groups;
- t_ = g_timer;
- std::cout << "Small groups removed " << t_ << std::endl;
-
-
-
- // Remove components part of groups having a mean thickness lower than 8.
- g_timer.restart();
- object_groups<L> filtered_thin_groups;
- if (argc > 5 && atoi(argv[5]) != 0)
- {
- std::cout << "** Using group too thin" << std::endl;
- filtered_thin_groups
- = filter::object_groups_v_thickness(filtered_small_groups, 8);
- }
- else
- filtered_thin_groups = filtered_small_groups;
- t_ = g_timer;
- std::cout << "Groups too thin " << t_ << std::endl;
-
-
-
- /// Apply grouping in the object image.
- g_timer.restart();
-
-// groups = primitive::group::regroup_left(filtered_components,
-// filtered_thin_groups,
-// 30);
-
- component_set<L>
- grouped_components = primitive::group::apply(filtered_thin_groups);
-
- t_ = g_timer;
- std::cout << "Group applied to object image " << t_ << std::endl;
-
- /// Components have been grouped. We try to link groups together.
- /// This time a single link is enough since non-wanted components have
- /// been removed.
- g_timer.restart();
-
- left_link = primitive::link::left(grouped_components, 30);
-
-
- /// Grouping groups.
- groups = primitive::group::from_single_link(left_link);
-
-
- grouped_components = primitive::group::apply(groups);
-
- t_ = g_timer;
- std::cout << "Link and group again " << t_ << std::endl;
-
- timer_.stop();
-
- timer_.resume();
-
- g_timer.restart();
-
-
- /// Filter grouped objects not having enough background components.
- if (argc > 3 && atoi(argv[3]) != 0)
- {
- std::cout << "** Using objects_with_two_holes" << std::endl;
- grouped_components = scribo::filter::components_with_two_holes(grouped_components, 5);
- t_ = g_timer;
- std::cout << "Objects_with_holes " << t_ << std::endl;
- }
-
-
- t_ = timer_;
- std::cout << "Objects groups filtered. " << t_ << std::endl;
-
-
- t_ = global_t_;
- std::cout << "*** Result computed " << t_ << std::endl;
-
- timer_.restart();
- std::cout << "Saving result..." << std::endl;
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- grouped_components.labeled_image(),
- grouped_components.nelements()),
- argv[2]);
-
-
- scribo::line_set<L>
- lines = scribo::line_set<L>(filtered_thin_groups);
-
-
- // Bboxes + line infos
- {
- std::ofstream file(scribo::make::debug_filename("text_bboxes.txt").c_str());
-
- for_all_lines(l, lines)
- if (lines(l).tag() != line::Merged
- && lines(l).tag() != line::Ignored
- && lines(l).tag() != line::Pathological)
- {
- file << lines(l).bbox().pmin().row() << " "
- << lines(l).bbox().pmin().col() << " "
- << lines(l).bbox().pmax().row() << " "
- << lines(l).bbox().pmax().col()
-// << " "
-// << lines(l).card() << " "
-// << lines(l).baseline() << " "
-// << lines(l).x_height() << " "
-// << lines(l).median() << " "
-// << lines(l).d_height() << " "
-// << lines(l).a_height() << " "
-// << lines(l).char_space() << " "
-// << lines(l).char_width()
- << std::endl;
- }
-
- file.close();
- }
-
-
- trace::exiting("main");
- return grouped_components.nelements() != 0;
-}
diff --git a/scribo/src/text_in_photo_ppm.cc b/scribo/src/text_in_photo_ppm.cc
deleted file mode 100644
index 9027ab0..0000000
--- a/scribo/src/text_in_photo_ppm.cc
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#include <libgen.h>
-#include <iostream>
-
-#include <mln/core/image/image2d.hh>
-#include <mln/core/image/imorph/tr_image.hh>
-#include <mln/core/alias/neighb2d.hh>
-
-#include <mln/labeling/colorize.hh>
-
-#include <mln/io/pbm/all.hh>
-#include <mln/io/ppm/save.hh>
-
-#include <mln/math/min.hh>
-
-#include <mln/logical/not.hh>
-
-#include <mln/fun/v2v/rgb_to_int_u.hh>
-
-#include <mln/literal/colors.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/value/label_16.hh>
-
-#include <mln/draw/box.hh>
-
-#include <mln/geom/translate.hh>
-
-#include <scribo/binarization/sauvola.hh>
-
-#include <scribo/draw/bounding_boxes.hh>
-
-#include <scribo/primitive/extract/objects.hh>
-
-#include <scribo/primitive/link/merge_double_link.hh>
-#include <scribo/primitive/link/with_single_left_link.hh>
-#include <scribo/primitive/link/with_single_right_link.hh>
-
-#include <scribo/primitive/group/apply.hh>
-#include <scribo/primitive/group/from_double_link.hh>
-#include <scribo/primitive/group/from_single_link.hh>
-
-#include <scribo/filter/objects_with_holes.hh>
-#include <scribo/filter/object_links_bbox_h_ratio.hh>
-#include <scribo/filter/object_links_bbox_overlap.hh>
-
-#include <scribo/filter/common/objects_photo.hh>
-
-#include <scribo/filter/object_groups_small.hh>
-#include <scribo/filter/object_groups_v_thickness.hh>
-
-#include <scribo/debug/decision_image.hh>
-#include <scribo/debug/save_bboxes_image.hh>
-#include <scribo/debug/save_linked_bboxes_image.hh>
-
-#include <scribo/debug/usage.hh>
-
-#include <scribo/preprocessing/split_bg_fg.hh>
-
-#include <scribo/make/debug_filename.hh>
-
-#include <mln/util/timer.hh>
-#include <mln/core/var.hh>
-
-const char *args_desc[][2] =
-{
- { "input.ppm", "A color image." },
- { "debug_output_dir", "Directory were debug images will be saved" },
- { "lambda", "Lambda value used for foreground extraction" },
- {0, 0}
-};
-
-
-namespace mln
-{
-
- struct mask_non_text : Function_v2v<mask_non_text>
- {
- typedef value::rgb8 result;
- typedef image2d<bool> I;
-
- mask_non_text(const image2d<bool>& mask)
- : mask_(mask), p_(mask_)
- {
- p_.start();
- }
-
- result operator()(const result& v) const
- {
- bool b = p_.val();
- p_.next();
- if (!b)
- return v / 2;
- else
- return v;
-
- }
-
- I mask_;
- mutable mln_pixter_(I) p_;
- };
-
-
- template <typename I, typename L>
- mln_concrete(I)
- compute_highlight_image(const I& input_rgb,
- const object_image<L>& objects)
- {
- mln_ch_value(I, bool) mask;
- initialize(mask, input_rgb);
- data::fill(mask, false);
-
- for_all_components(i, objects.bboxes())
- data::fill((mask | objects.bbox(i)).rw(), true);
-
- mask_non_text f(mask);
- mln_concrete(I) output = data::transform(input_rgb, f);
-
- for_all_components(i, objects.bboxes())
- mln::draw::box(output, objects.bbox(i), literal::red);
-
- return output;
- }
-
-
- template <typename I, typename L>
- mln_concrete(I)
- compute_text_image(const I& input_rgb,
- const object_image<L>& grouped_objects)
- {
- const util::array<mln_domain(L)>& bboxes = grouped_objects.bboxes();
-
- unsigned shift = 5;
- float height = 1, width = 0;
- for_all_components(i, bboxes)
- {
- height += bboxes(i).nrows() + shift;
- width = math::max(static_cast<float>(bboxes(i).ncols()), width);
- }
- if (width == 0)
- width = 1;
-
- I output(height, width);
- data::fill(output, literal::black);
-
- algebra::vec<2, float> dv;
- dv[0] = 0;
- dv[1] = 0;
- for_all_ncomponents(i, grouped_objects.nlabels())
- {
- mln_VAR(tmp, duplicate(input_rgb | grouped_objects.bbox(i)));
-
- typedef fun::x2x::translation<mln_site_(I)::dim, float> trans_t;
- trans_t trans(dv - grouped_objects.bbox(i).pmin().to_vec());
-
- mln_domain(I) tr_box(grouped_objects.bbox(i).pmin().to_vec() + trans.t(),
- grouped_objects.bbox(i).pmax().to_vec() + trans.t());
-
- tr_image<mln_domain(I), tmp_t, trans_t> tr_ima(tr_box, tmp, trans);
-
- data::paste(tr_ima, output);
- dv[0] += grouped_objects.bbox(i).nrows() + shift;
- }
-
- return output;
- }
-
-} // end of namespace mln
-
-
-int main(int argc, char* argv[])
-{
- using namespace scribo;
- using namespace mln;
-
- if (argc != 3 && argc != 4 && argc != 5 && argc != 6)
- return scribo::debug::usage(argv,
- "Find text in a photo.",
- "input.ppm output.ppm [bg/fg] [debug_output_dir] [lambda]",
- args_desc,
- "A color image where the text is highlighted.");
-
- if (argc > 4)
- scribo::make::internal::debug_filename_prefix = argv[4];
-
- trace::entering("main");
-
- image2d<value::rgb8> input_rgb;
- io::ppm::load(input_rgb, argv[1]);
-
-
- unsigned lambda;
- if (argc == 6)
- lambda = atoi(argv[5]);
- else
- lambda = 1.2 * (input_rgb.nrows() + input_rgb.ncols());
-
-
- util::timer timer_;
-
- // Extract foreground
- image2d<value::int_u8> intensity_ima;
- std::cout << "Extracting foreground..." << std::endl;
- timer_.start();
-
- if (argc > 3 && atoi(argv[3]) != 0)
- {
- // Extract foreground
- timer_.start();
- image2d<value::rgb8>
- fg = preprocessing::split_bg_fg(input_rgb,
- lambda,
- 32).second();
- intensity_ima = data::transform(fg, mln::fun::v2v::rgb_to_int_u<8>());
- float t_ = timer_;
- std::cout << "Foreground extracted. " << t_ << std::endl;
- }
- else
- {
- timer_.start();
- intensity_ima = data::transform(input_rgb,
- mln::fun::v2v::rgb_to_int_u<8>());
- float t_ = timer_;
- std::cout << "Intensity image " << t_ << std::endl;
- }
- float t_ = timer_;
- std::cout << "Foreground extracted. " << t_ << std::endl;
-
- // Binarize foreground to use it in the processing chain.
- // FIXME: TOO SLOW!
- std::cout << "Binarizing foreground..." << std::endl;
- timer_.restart();
- image2d<bool> input = binarization::sauvola(intensity_ima, 11);
- io::pbm::save(input, "input.pbm");
- t_ = timer_;
- std::cout << "Foreground binarized. " << t_ << std::endl;
-
-
-
- typedef image2d<value::label_16> L;
-
- /// Finding objects.
- std::cout << "Extracting objects..." << std::endl;
- timer_.restart();
- value::label_16 nobjects;
- object_image(L)
- objects = scribo::primitive::extract::objects(input, c8(), nobjects);
- t_ = timer_;
- std::cout << "Object extracted" << t_ << std::endl;
-
- /// First filtering.
- std::cout << "Filtering objects..." << std::endl;
- timer_.restart();
- object_image(L) filtered_objects = filter::common::objects_photo(objects);
- t_ = timer_;
- std::cout << "Object filtered" << t_ << std::endl;
-
-
-
- /// linking potential objects
- std::cout << "Linking objects..." << std::endl;
- timer_.restart();
- object_links<L> left_link
- = primitive::link::with_single_left_link(filtered_objects, 30);
- t_ = timer_;
- std::cout << "Left Link done" << t_ << std::endl;
-
- timer_.restart();
- object_links<L> right_link
- = primitive::link::with_single_right_link(filtered_objects, 30);
- t_ = timer_;
- std::cout << "Right Link done" << t_ << std::endl;
-
-
-
-#ifndef NOUT
- if (argc > 3)
- {
- std::cerr << "BEFORE - nobjects = " << nobjects << std::endl;
- scribo::debug::save_linked_bboxes_image(input,
- filtered_objects,
- left_link, right_link,
- literal::red, literal::cyan,
- literal::yellow,
- literal::green,
- scribo::make::debug_filename("links.ppm"));
- }
-#endif
-
-
-
- // Validating left and right links.
- timer_.restart();
- object_links<L>
- merged_links = primitive::link::merge_double_link(filtered_objects,
- left_link,
- right_link);
- t_ = timer_;
- std::cout << "Right/Left Validation. " << t_ << std::endl;
-
-
- // Remove links if bboxes have too different sizes.
- std::cout << "Filtering object links..." << std::endl;
- timer_.restart();
- object_links<L>
- hratio_filtered_links = filter::object_links_bbox_h_ratio(filtered_objects,
- merged_links,
- 1.50f);
-
-
-
-
-#ifndef NOUT
- if (argc > 3)
- {
- image2d<value::rgb8>
- hratio_decision_image = scribo::debug::decision_image(input,
- merged_links,
- hratio_filtered_links);
- io::ppm::save(hratio_decision_image,
- scribo::make::debug_filename("hratio_links_decision_image.ppm"));
- }
-#endif
-
-
-
-
- //Remove links if bboxes overlap too much.
- object_links<L> overlap_filtered_links
- = filter::object_links_bbox_overlap(filtered_objects,
- hratio_filtered_links,
- 0.80f);
-
-
-
-
-#ifndef NOUT
- if (argc > 3)
- {
- image2d<value::rgb8> overlap_decision_image
- = scribo::debug::decision_image(input,
- hratio_filtered_links,
- overlap_filtered_links);
- io::ppm::save(overlap_decision_image,
- scribo::make::debug_filename("overlap_links_decision_image.ppm"));
- }
-#endif
-
-
- t_ = timer_;
- std::cout << "Objects links filtered. " << t_ << std::endl;
-
- std::cout << "Grouping objects..." << std::endl;
- timer_.restart();
- object_groups<L>
- groups = primitive::group::from_single_link(filtered_objects,
- overlap_filtered_links);
-
-
-
- /// Apply grouping in a temporary image (for debug purpose).
- object_image(L)
- raw_group_image = primitive::group::apply(filtered_objects,
- filter::object_groups_small(groups, 2));
-
- t_ = timer_;
- std::cout << "Objects grouped. " << t_ << std::endl;
-
-#ifndef NOUT
-
- if (argc > 3)
- scribo::debug::save_bboxes_image(input,
- raw_group_image.bboxes(),
- literal::red,
- scribo::make::debug_filename("group_image.ppm"));
-#endif // !NOUT
-
- std::cout << "Filtering groups..." << std::endl;
-
- util::timer g_timer;
-
- timer_.restart();
- // Remove objects part of groups with strictly less than 3 objects.
-
- g_timer.start();
- object_groups<L>
- filtered_small_groups = filter::object_groups_small(groups, 3);
- t_ = g_timer;
- std::cout << "Small groups removed " << t_ << std::endl;
-
-
-
-#ifndef NOUT
- image2d<value::rgb8> decision_image;
- if (argc > 3)
- {
- decision_image = scribo::debug::decision_image(input,
- groups,
- filtered_small_groups);
- io::ppm::save(decision_image,
- scribo::make::debug_filename("small_groups_filter.ppm"));
- }
-#endif
-
-
-
- // Remove objects part of groups having a mean thickness lower than 8.
- g_timer.restart();
- object_groups<L> filtered_thin_groups
- = filter::object_groups_v_thickness(filtered_small_groups, 8);
- t_ = g_timer;
- std::cout << "Groups too thin " << t_ << std::endl;
-
-
-#ifndef NOUT
- if (argc > 3)
- {
- decision_image = scribo::debug::decision_image(input,
- groups,
- filtered_thin_groups);
-
- io::ppm::save(decision_image,
- scribo::make::debug_filename("thin_groups_filter.ppm"));
- }
-#endif
-
-
-
- /// Apply grouping in the object image.
- g_timer.restart();
-
- object_image(L)
- grouped_objects = primitive::group::apply(filtered_objects,
- filtered_thin_groups);
-
- t_ = g_timer;
- std::cout << "Group applied to object image " << t_ << std::endl;
-
- /// Objects have been grouped. We try to link groups together.
- /// This time a single link is enough since non-wanted objects have
- /// been removed.
- g_timer.restart();
- left_link
- = primitive::link::with_single_left_link(grouped_objects, 30);
-
- /// Grouping groups.
- groups = primitive::group::from_single_link(grouped_objects, left_link);
-
-
- grouped_objects = primitive::group::apply(grouped_objects, groups);
-
- t_ = g_timer;
- std::cout << "Link and group again " << t_ << std::endl;
-
- timer_.stop();
-
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- grouped_objects,
- grouped_objects.nlabels()),
- scribo::make::debug_filename("out_before_hole_filter.ppm"));
-
-
- timer_.resume();
-
- g_timer.restart();
- /// Filter grouped objects not having enough background components.
- grouped_objects = scribo::filter::objects_with_holes_slow(grouped_objects, 2);
-// grouped_objects = scribo::filter::objects_with_holes(grouped_objects, 2, 2);
- t_ = g_timer;
- std::cout << "Objects_with_holes " << t_ << std::endl;
-
- t_ = timer_;
- std::cout << "Objects groups filtered. " << t_ << std::endl;
-
-#ifndef NOUT
- if (argc > 3)
- {
- scribo::draw::bounding_boxes(decision_image, raw_group_image, literal::yellow);
- scribo::draw::bounding_boxes(decision_image, grouped_objects, literal::blue);
- io::ppm::save(decision_image, scribo::make::debug_filename("decision_image.ppm"));
-
- std::cerr << "AFTER - nobjects = " << grouped_objects.nlabels() << std::endl;
- }
-#endif
-
-
- std::cout << "Saving result..." << std::endl;
- io::ppm::save(mln::labeling::colorize(value::rgb8(),
- grouped_objects,
- grouped_objects.nlabels()),
- argv[2]);
-
-#ifndef NOUT
- io::ppm::save(compute_highlight_image(input_rgb, grouped_objects),
- scribo::make::debug_filename("orig_with_bboxes.ppm"));
-// scribo::debug::save_bboxes_image(input_rgb, grouped_objects.bboxes(),
-// literal::red,
-// scribo::make::debug_filename("orig_with_bboxes.ppm"));
-#endif
-
- io::ppm::save(compute_text_image(input_rgb, grouped_objects),
- scribo::make::debug_filename("out_text.ppm"));
-
-
- std::cout << "# objects = " << grouped_objects.nlabels() << std::endl;
-
- trace::exiting("main");
- return grouped_objects.nlabels() != 0;
-}
diff --git a/scribo/src/text_in_photo_fast.cc b/scribo/src/text_in_picture.cc
similarity index 99%
rename from scribo/src/text_in_photo_fast.cc
rename to scribo/src/text_in_picture.cc
index d61cc6f..8ad4697 100644
--- a/scribo/src/text_in_photo_fast.cc
+++ b/scribo/src/text_in_picture.cc
@@ -106,6 +106,7 @@
// #include <scribo/core/line_set.hh>
// #include <scribo/text/recognition.hh>
+// #include <scribo/text/merging.hh>
const char *args_desc[][2] =
{
@@ -697,6 +698,7 @@ Common usage: ./text_in_photo_fast input.ppm output.ppm 1 1 1 1 1",
// scribo::line_set<L>
// lines = scribo::make::line_set(groups);
+// lines = scribo::text::merging(lines);
// text::recognition(lines, "fra", "out.txt");
trace::exiting("main");
diff --git a/scribo/test.cc b/scribo/test.cc
deleted file mode 100644
index 462d9b5..0000000
--- a/scribo/test.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2009
- EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#include <mln/essential/2d.hh>
-#include <mln/util/ord.hh>
-
-int main()
-{
- using namespace mln;
-
-
- point2d p1(0, 2);
- point2d p2(0, 2);
-
- std::cout << util::ord_strict(p1, p2) << std::endl;
- std::cout << util::ord_weak(p1, p2) << std::endl;
-
- std::cout << util::ord_strict(p2, p1) << std::endl;
- std::cout << util::ord_weak(p2, p1) << std::endl;
-
-}
--
1.5.6.5
1
0
last-svn-commit-133-gff15d07 toolchain/text_in_doc.hh: Introduce a new routine for extracting text in a document.
by Guillaume Lazzara 25 May '10
by Guillaume Lazzara 25 May '10
25 May '10
---
scribo/ChangeLog | 5 +
scribo/toolchain/text_in_doc.hh | 294 +++++++++++++++++++++++++++++++++++++++
2 files changed, 299 insertions(+), 0 deletions(-)
create mode 100644 scribo/toolchain/text_in_doc.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index b682f14..f091afa 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,10 @@
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * toolchain/text_in_doc.hh: Introduce a new routine for extracting
+ text in a document.
+
+2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* core/def/lbl_type.hh: Introduce a global label type.
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/toolchain/text_in_doc.hh b/scribo/toolchain/text_in_doc.hh
new file mode 100644
index 0000000..50db26a
--- /dev/null
+++ b/scribo/toolchain/text_in_doc.hh
@@ -0,0 +1,294 @@
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_TOOLCHAIN_TEXT_IN_DOC_HH
+# define SCRIBO_TOOLCHAIN_TEXT_IN_DOC_HH
+
+/// \file
+///
+/// Extract text from a document.
+
+# include <mln/io/ppm/save.hh>
+
+# include <scribo/core/def/lbl_type.hh>
+
+# include <scribo/primitive/extract/components.hh>
+# include <scribo/primitive/extract/vertical_separators.hh>
+
+# include <scribo/primitive/remove/separators.hh>
+
+# include <scribo/filter/object_links_bbox_h_ratio.hh>
+# include <scribo/filter/objects_small.hh>
+
+# include <scribo/primitive/group/from_single_link.hh>
+
+# include <scribo/primitive/link/merge_double_link.hh>
+# include <scribo/primitive/link/internal/dmax_width_and_height.hh>
+# include <scribo/primitive/link/with_single_left_link_dmax_ratio.hh>
+# include <scribo/primitive/link/with_single_right_link_dmax_ratio.hh>
+
+# include <scribo/preprocessing/denoise_fg.hh>
+
+# include <scribo/text/recognition.hh>
+# include <scribo/text/merging.hh>
+
+# include <scribo/make/debug_filename.hh>
+
+# include <scribo/debug/save_bboxes_image.hh>
+# include <scribo/debug/bboxes_enlarged_image.hh>
+# include <scribo/debug/mean_and_base_lines_image.hh>
+# include <scribo/debug/looks_like_a_text_line_image.hh>
+
+
+
+namespace scribo
+{
+
+ namespace toolchain
+ {
+
+ template <typename I>
+ line_set<mln_ch_value(I, def::lbl_type)>
+ text_in_doc(const Image<I>& input, bool denoise, bool debug = false);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ line_set<mln_ch_value(I, def::lbl_type)>
+ text_in_doc(const Image<I>& input, bool denoise, bool debug = false)
+ {
+ typedef value::label<30> V;
+ typedef image2d<V> L;
+
+ // Add whitespace separators.
+ // win::rectangle2d win = win::rectangle2d(151, 41);
+ // image2d<bool> whitespaces = morpho::closing::structural(input, win);
+ // logical::not_inplace(whitespaces);
+
+ // Remove separators
+ if (debug)
+ std::cout << "Find vertical separators..." << std::endl;
+
+ image2d<bool>
+ separators = primitive::extract::vertical_separators(input, 81);
+
+ if (debug)
+ std::cout << "Remove separators..." << std::endl;
+
+ image2d<bool> input_cleaned = primitive::remove::separators(input,
+ separators);
+
+// whitespaces += separators;
+
+ if (debug)
+ {
+ mln::io::pbm::save(separators,
+ scribo::make::debug_filename("vseparators.pbm"));
+// mln::io::pbm::save(whitespaces, "separators.pbm");
+
+ mln::io::pbm::save(input_cleaned, scribo::make::debug_filename("input_wo_vseparators.pbm"));
+ }
+
+ // Denoise
+ if (denoise)
+ {
+ if (debug)
+ std::cout << "Denoise..." << std::endl;
+
+ input_cleaned = preprocessing::denoise_fg(input_cleaned, c8(), 3);
+
+ if (debug)
+ mln::io::pbm::save(input_cleaned,
+ scribo::make::debug_filename("denoised.pbm"));
+ }
+
+ /// Finding components.
+ if (debug)
+ std::cout << "Finding components..." << std::endl;
+
+ V ncomponents;
+ component_set<L>
+ components = scribo::primitive::extract::components(input_cleaned, c8(),
+ ncomponents);
+
+ /// Set separator components.
+ components.add_separators(separators);
+// components.add_separators(whitespaces);
+
+ components = scribo::filter::components_small(components, 3);
+
+
+ /// Linking potential objects
+ if (debug)
+ std::cout << "Linking objects..." << std::endl;
+
+ object_links<L> left_link
+ = primitive::link::with_single_left_link_dmax_ratio(components,
+ primitive::link::internal::dmax_width_and_height(1),
+ anchor::MassCenter);
+ object_links<L> right_link
+ = primitive::link::with_single_right_link_dmax_ratio(components,
+ primitive::link::internal::dmax_width_and_height(1),
+ anchor::MassCenter);
+
+ // Validating left and right links.
+ object_links<L>
+ merged_links = primitive::link::merge_double_link(left_link,
+ right_link);
+
+
+ // Remove links if bboxes have too different sizes.
+ object_links<L> hratio_filtered_links
+ = filter::object_links_bbox_h_ratio(merged_links, 2.5f);
+
+
+// #ifndef NOUT
+// if (argc == 4)
+// {
+// image2d<value::rgb8>
+// hratio_decision_image = scribo::debug::decision_image(input,
+// merged_links,
+// hratio_filtered_links);
+// io::ppm::save(hratio_decision_image,
+// scribo::make::debug_filename("hratio_links_decision_image.ppm"));
+// }
+// #endif
+
+
+ object_groups<L>
+ groups = primitive::group::from_single_link(hratio_filtered_links);
+
+
+ // Construct a line set.
+ line_set<L>
+ lines = scribo::make::line_set(groups);
+
+
+
+ //===== DEBUG =====
+
+ if (debug)
+ {
+
+ // Bboxes image.
+ scribo::debug::save_bboxes_image(input, lines,
+ scribo::make::debug_filename("step1_bboxes.ppm"));
+
+ // Bboxes enlarged
+ mln::io::ppm::save(scribo::debug::bboxes_enlarged_image(input, lines),
+ scribo::make::debug_filename("step1_bboxes_enlarged.ppm"));
+
+ // Looks like a text line
+ mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
+ scribo::make::debug_filename("step1_looks_like_a_text_line.ppm"));
+
+
+ // mean and base lines.
+ mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
+ scribo::make::debug_filename("step1_x_height.ppm"));
+
+ }
+ //===== END OF DEBUG =====
+
+
+
+ if (debug)
+ std::cout << "Merging lines..." << std::endl;
+ lines = scribo::text::merging(lines);
+
+
+
+ //===== DEBUG =====
+
+ if (debug)
+ {
+
+ // mean and base lines.
+ mln::io::ppm::save(scribo::debug::mean_and_base_lines_image(input, lines),
+ scribo::make::debug_filename("step2_x_height.ppm"));
+
+ // Looks like a text line
+ mln::io::ppm::save(scribo::debug::looks_like_a_text_line_image(input, lines),
+ scribo::make::debug_filename("step2_looks_like_a_text_line.ppm"));
+
+ // Bboxes image.
+ scribo::debug::save_bboxes_image(input, lines,
+ scribo::make::debug_filename("step2_bboxes.ppm"));
+
+
+ }
+
+
+
+ if (debug)
+ {
+ std::ofstream file(scribo::make::debug_filename("step2_bboxes_100p.txt").c_str());
+
+ for_all_lines(l, lines)
+ if (lines(l).tag() != line::Merged
+ && lines(l).tag() != line::Ignored
+ && lines(l).tag() != line::Pathological)
+ {
+ file << lines(l).bbox().pmin().row() << " "
+ << lines(l).bbox().pmin().col() << " "
+ << lines(l).bbox().pmax().row() << " "
+ << lines(l).bbox().pmax().col() << " "
+ << lines(l).card() << " "
+ << lines(l).baseline() << " "
+ << lines(l).x_height() << " "
+ << lines(l).meanline() << " "
+ << lines(l).d_height() << " "
+ << lines(l).a_height() << " "
+ << lines(l).char_space() << " "
+ << lines(l).char_width() << std::endl;
+
+ }
+
+ file.close();
+ }
+
+
+ //===== END OF DEBUG =====
+
+
+
+ scribo::text::recognition(lines, "fra");
+
+ return lines;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::toolchain
+
+} // end of namespace scribo
+
+
+#endif // SCRIBO_TOOLCHAIN_TEXT_IN_DOC_HH
+
--
1.5.6.5
1
0
last-svn-commit-132-g12ddb97 core/def/lbl_type.hh: Introduce a global label type.
by Guillaume Lazzara 25 May '10
by Guillaume Lazzara 25 May '10
25 May '10
---
scribo/ChangeLog | 4 +++
.../src/process_args.hh => core/def/lbl_type.hh} | 23 ++++++++++---------
2 files changed, 16 insertions(+), 11 deletions(-)
copy scribo/{demo/demat/src/process_args.hh => core/def/lbl_type.hh} (82%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index a4e2373..b682f14 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * core/def/lbl_type.hh: Introduce a global label type.
+
+2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Improve line detection.
* primitive/extract/lines_h_pattern.hh,
diff --git a/scribo/demo/demat/src/process_args.hh b/scribo/core/def/lbl_type.hh
similarity index 82%
copy from scribo/demo/demat/src/process_args.hh
copy to scribo/core/def/lbl_type.hh
index 5ca72cf..6434bbe 100644
--- a/scribo/demo/demat/src/process_args.hh
+++ b/scribo/core/def/lbl_type.hh
@@ -23,25 +23,26 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH
-# define SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH
+#ifndef SCRIBO_CORE_LBL_TYPE_HH
+# define SCRIBO_CORE_LBL_TYPE_HH
+
+/// \file
+///
+/// Global type definition for labels.
+
+# include <mln/value/label.hh>
namespace scribo
{
- namespace demo
+ namespace def
{
- struct process_args
- {
- unsigned scale;
- };
+ typedef mln::value::label<30u> lbl_type;
-
- } // end of namespace scribo::demo
+ } // end of namespace scribo::def
} // end of namespace scribo
-
-#endif // !SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH
+#endif // ! SCRIBO_CORE_DEF_HH
--
1.5.6.5
1
0
* primitive/extract/lines_h_pattern.hh,
* primitive/extract/lines_v_pattern.hh: Use reconstruction
algorithm.
* primitive/extract/lines_pattern.hh: Add a fast implementation.
---
scribo/ChangeLog | 10 ++
scribo/primitive/extract/lines_h_pattern.hh | 40 ++++--
scribo/primitive/extract/lines_pattern.hh | 227 ++++++++++++++++++++++-----
scribo/primitive/extract/lines_v_pattern.hh | 39 +++--
4 files changed, 250 insertions(+), 66 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index fe1e390..a4e2373 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,15 @@
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Improve line detection.
+
+ * primitive/extract/lines_h_pattern.hh,
+ * primitive/extract/lines_v_pattern.hh: Use reconstruction
+ algorithm.
+
+ * primitive/extract/lines_pattern.hh: Add a fast implementation.
+
+2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
* io/text_boxes/save.hh: New. Save text boxes information.
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/primitive/extract/lines_h_pattern.hh b/scribo/primitive/extract/lines_h_pattern.hh
index 08025a1..0da7900 100644
--- a/scribo/primitive/extract/lines_h_pattern.hh
+++ b/scribo/primitive/extract/lines_h_pattern.hh
@@ -53,15 +53,30 @@ namespace scribo
using namespace mln;
- /// Extract horizontal lines matching a specific pattern.
- ///
- /// \param[in] input A binary image.
- /// \param[in] length The minimum line length.
- /// \param[in] delta Distance between the object pixel and the
- /// background pixel.
- ///
- /// \result An image of horizontal lines.
- //
+ /*! \brief Extract horizontal lines matching a specific pattern.
+
+ \param[in] input A binary image.
+ \param[in] length The minimum line length.
+ \param[in] delta Distance between the object pixel and the
+ background pixel.
+
+ \result An image of horizontal lines.
+
+
+ o
+ | ^
+ | | Delta
+ | v
+ X
+ | ^
+ | | Delta
+ | v
+ o
+
+ Using a delta of 0 is equivalent to the use of a c2_row
+ neighborhood.
+
+ */
template <typename I>
mln_concrete(I)
lines_h_pattern(const Image<I>& input, unsigned length, unsigned delta);
@@ -73,15 +88,16 @@ namespace scribo
mln_concrete(I)
lines_h_pattern(const Image<I>& input, unsigned length, unsigned delta)
{
+ trace::entering("scribo::primitive::extract::lines_h_pattern");
+
mlc_is(mln_value(I), bool)::check();
mln_precondition(exact(input).is_valid());
- mln_precondition(length % 2 == 1);
// FIXME: not generic.
window2d win;
mln_deduce(I, site, dpsite)
- dp1(-delta, 0),
- dp2( delta, 0);
+ dp1(-delta - 1, 0),
+ dp2( delta + 1, 0);
win.insert(dp1);
win.insert(dp2);
diff --git a/scribo/primitive/extract/lines_pattern.hh b/scribo/primitive/extract/lines_pattern.hh
index 18cb784..5f9950a 100644
--- a/scribo/primitive/extract/lines_pattern.hh
+++ b/scribo/primitive/extract/lines_pattern.hh
@@ -75,61 +75,216 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename W>
- mln_concrete(I)
- lines_pattern(const Image<I>& input_, unsigned length,
- unsigned dir, const Window<W>& win_)
+
+ // Implementations
+
+ namespace impl
{
- trace::entering("scribo::primitive::extract::lines_pattern");
- const I& input = exact(input_);
- const W& win = exact(win_);
- mlc_is(mln_value(I), bool)::check();
- mln_precondition(input.is_valid());
+ namespace generic
+ {
+
+ template <typename I, typename W>
+ mln_concrete(I)
+ lines_pattern(const Image<I>& input_, unsigned length,
+ unsigned dir, const Window<W>& win_)
+ {
+ trace::entering("scribo::primitive::extract::impl::generic::lines_pattern");
+
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ mlc_is(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+
+ // Adjusting extension.
+ extension::adjust_fill(input, length / 2, 0);
+
+ accu::count_value<bool> accu(true);
+ mln_ch_value(I,unsigned)
+ tmp = accu::transform_line(accu, input, length, dir);
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ mln_piter(I) p(input.domain());
+ mln_qiter(window2d) q(win, p);
+ bool is_foreground;
+ for_all(p)
+ {
- // Adjusting extension.
- extension::adjust_fill(input, length / 2, 0);
+ // If the foreground part of the pattern has more than 20%
+ // of background pixels, the current pixel is considered as
+ // background pixel.
+ if (length - tmp(p) > unsigned(0.2f * length) + 1)
+ {
+ output(p) = false;
+ continue;
+ }
- accu::count_value<bool> accu(true);
- mln_ch_value(I,unsigned)
- tmp = accu::transform_line(accu, input, length, dir);
+ // If the background parts of the pattern have exactly or
+ // less than 95% of background pixels, the current pixel is
+ // considered as part of the background.
+ is_foreground = true;
+ for_all(q)
+ if ((length - tmp(q)) < unsigned(length * 0.95f) + 1)
+ {
+ is_foreground = false;
+ break;
+ }
- mln_concrete(I) output;
- initialize(output, input);
+ output(p) = is_foreground;
+ }
+
+ trace::exiting("scribo::primitive::extract::impl::generic::lines_pattern");
+ return output;
+ }
+
+ } // end of namespace scribo::primitive::extract::impl::generic
- mln_piter(I) p(input.domain());
- mln_qiter(window2d) q(win, p);
- bool is_foreground;
- for_all(p)
+
+
+ template <typename I, typename W>
+ mln_concrete(I)
+ lines_pattern_fast(const Image<I>& input_, unsigned length,
+ unsigned dir, const Window<W>& win_)
{
+ trace::entering("scribo::primitive::extract::impl::lines_pattern_fast");
+
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ mlc_is(mln_value(I), bool)::check();
+ mln_precondition(input.is_valid());
+
+ // Adjusting extension.
+ extension::adjust_fill(input, length / 2, 0);
- // If the foreground part of the pattern has more than 20%
- // of background pixels, the current pixel is considered as
- // background pixel.
- if (length - tmp(p) > unsigned(0.2f * length) + 1)
+ accu::count_value<bool> accu(true);
+ mln_ch_value(I,unsigned)
+ tmp = accu::transform_line(accu, input, length, dir);
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ util::array<int>
+ q_arr = offsets_wrt(output, win);
+
+ bool is_foreground;
+ unsigned ncols = geom::ncols(output);
+ unsigned hit_ratio = 0.2f * length + 1;
+ unsigned miss_ratio = 0.95f * length + 1;
+
+ mln_box_runstart_piter(I) p(output.domain());
+ for_all(p)
{
- output(p) = false;
- continue;
- }
+ unsigned pi = output.index_of_point(p);
+ unsigned *tmp_ptr = &tmp.element(pi);
+ unsigned *end_ptr = tmp_ptr + ncols;
+
+ mln_value(I) *out_ptr = &output.element(pi);
- // If the background parts of the pattern have exactly or
- // less than 95% of background pixels, the current pixel is
- // considered as part of the background.
- is_foreground = true;
- for_all(q)
- if ((length - tmp(q)) < unsigned(length * 0.95f) + 1)
+ for (; tmp_ptr < end_ptr; ++out_ptr, ++tmp_ptr)
{
- is_foreground = false;
- break;
+
+ // If the foreground part of the pattern has more than 20%
+ // of background pixels, the current pixel is considered as
+ // background pixel.
+ if (length - *tmp_ptr > hit_ratio)
+ {
+ *out_ptr = false;
+ continue;
+ }
+
+ // If the background parts of the pattern have exactly or
+ // less than 95% of background pixels, the current pixel is
+ // considered as part of the background.
+ is_foreground = true;
+ for (unsigned i = 0; i < q_arr.size(); ++i)
+ if ((length - *(tmp_ptr + q_arr[i])) < miss_ratio)
+ {
+ is_foreground = false;
+ break;
+ }
+
+ *out_ptr = is_foreground;
}
+ }
+
+ trace::exiting("scribo::primitive::extract::impl::lines_pattern_fast");
+ return output;
+ }
+
+ } // end of namespace scribo::primitive::extract::impl
+
+
+
+ // Dispatch
- output(p) = is_foreground;
+ namespace internal
+ {
+
+ template <typename I, typename W>
+ mln_concrete(I)
+ lines_pattern_dispatch(mln::trait::image::value_storage::any,
+ mln::trait::image::value_access::any,
+ mln::trait::image::ext_domain::any,
+ const Image<I>& input, unsigned length,
+ unsigned dir, const Window<W>& win)
+ {
+ return impl::generic::lines_pattern(input, length, dir, win);
+ }
+
+
+ template <typename I, typename W>
+ mln_concrete(I)
+ lines_pattern_dispatch(mln::trait::image::value_storage::one_block,
+ mln::trait::image::value_access::direct,
+ mln::trait::image::ext_domain::some,
+ const Image<I>& input, unsigned length,
+ unsigned dir, const Window<W>& win)
+ {
+ return impl::lines_pattern_fast(input, length, dir, win);
}
+
+ template <typename I, typename W>
+ mln_concrete(I)
+ lines_pattern_dispatch(const Image<I>& input, unsigned length,
+ unsigned dir, const Window<W>& win)
+ {
+ return lines_pattern_dispatch(mln_trait_image_value_storage(I)(),
+ mln_trait_image_value_access(I)(),
+ mln_trait_image_ext_domain(I)(),
+ input,
+ length,
+ dir, win);
+ }
+
+ } // end of namespace scribo::primitive::extract::internal
+
+
+ // Facade
+
+ template <typename I, typename W>
+ mln_concrete(I)
+ lines_pattern(const Image<I>& input, unsigned length,
+ unsigned dir, const Window<W>& win)
+ {
+ trace::entering("scribo::primitive::extract::lines_pattern");
+
+ mlc_is(mln_value(I), bool)::check();
+ mln_precondition(exact(input).is_valid());
+ mln_precondition(exact(win).is_valid());
+ mln_precondition(length != 0);
+ mln_precondition(dir == 0 || dir == 1);
+
+ mln_concrete(I)
+ output = internal::lines_pattern_dispatch(input, length, dir, win);
+
trace::exiting("scribo::primitive::extract::lines_pattern");
return output;
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::primitive::extract
diff --git a/scribo/primitive/extract/lines_v_pattern.hh b/scribo/primitive/extract/lines_v_pattern.hh
index ccd21c5..cbdf080 100644
--- a/scribo/primitive/extract/lines_v_pattern.hh
+++ b/scribo/primitive/extract/lines_v_pattern.hh
@@ -30,15 +30,17 @@
///
/// Extract vertical lines matching a specific pattern.
-#include <mln/core/concept/image.hh>
-#include <mln/core/alias/window2d.hh>
-
-# include <mln/win/hline2d.hh>
-
+# include <mln/core/concept/image.hh>
+# include <mln/core/alias/window2d.hh>
+# include <mln/win/rectangle2d.hh>
# include <mln/morpho/dilation.hh>
+# include <mln/arith/times.hh>
+
# include <scribo/primitive/extract/lines_pattern.hh>
+# include <scribo/primitive/internal/rd.hh>
+
namespace scribo
{
@@ -70,26 +72,27 @@ namespace scribo
mln_concrete(I)
lines_v_pattern(const Image<I>& input, unsigned length, unsigned delta)
{
- mln_precondition(length % 2 == 1);
+ trace::entering("scribo::primitive::extract::lines_v_pattern");
-// bool win_def[1][7] = { { 1, 0, 0, 0, 0, 0, 1 } };
-
-// window2d win;
-// convert::from_to(win_def, win);
+ mln_precondition(length % 2 == 1);
- // FIXME: not generic.
window2d win;
mln_deduce(I, site, dpsite)
- dp1(0, -delta),
- dp2(0, delta);
+ dp1(0, -delta - 1),
+ dp2(0, delta + 1);
win.insert(dp1);
win.insert(dp2);
- //FIXME: Add reconstruction instead of this arbitrary dilation.
- win::vline2d vwin(length/2 + 2);
-// win::vline2d vwin(length);
- return morpho::dilation(lines_pattern(input, length, 0, win), vwin);
-// return lines_pattern(input, length, 0, win);
+ mln_concrete(I) output = lines_pattern(input, length, 0, win);
+
+ mln_concrete(I)
+ output_dil = morpho::dilation(output,
+ win::rectangle2d(length / 2 + delta, 3));
+
+ output = scribo::primitive::internal::rd(output, input * output_dil);
+
+ trace::exiting("scribo::primitive::extract::lines_v_pattern");
+ return output;
}
--
1.5.6.5
1
0
last-svn-commit-130-gcbbbffd io/text_boxes/save.hh: New. Save text boxes information.
by Guillaume Lazzara 25 May '10
by Guillaume Lazzara 25 May '10
25 May '10
---
scribo/ChangeLog | 4 ++
scribo/io/text_boxes/save.hh | 102 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 106 insertions(+), 0 deletions(-)
create mode 100644 scribo/io/text_boxes/save.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 623147b..fe1e390 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * io/text_boxes/save.hh: New. Save text boxes information.
+
+2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add a new deskew algorithm.
* preprocessing/deskew.hh,
diff --git a/scribo/io/text_boxes/save.hh b/scribo/io/text_boxes/save.hh
new file mode 100644
index 0000000..5bbf97b
--- /dev/null
+++ b/scribo/io/text_boxes/save.hh
@@ -0,0 +1,102 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_IO_TEXT_BOXES_SAVE_HH
+# define SCRIBO_IO_TEXT_BOXES_SAVE_HH
+
+/// \file
+///
+/// \brief Save text line information as XML.
+
+
+# include <fstream>
+# include <sstream>
+
+# include <scribo/core/line_set.hh>
+
+namespace scribo
+{
+
+ namespace io
+ {
+
+ namespace text_boxes
+ {
+
+ template <typename L>
+ void
+ save(const line_set<L>& lines,
+ const std::string& output_name,
+ const mln_site(L)& crop_shift = literal::origin);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L>
+ void
+ save(const line_set<L>& lines,
+ const std::string& output_name,
+ const mln_site(L)& crop_shift = literal::origin)
+ {
+ trace::entering("scribo::io::text_boxes:save");
+ mln_precondition(lines.is_valid());
+
+ std::ofstream file(output_name.c_str());
+ if (! file)
+ {
+ std::cerr << "error: cannot open file '" << output_name << "'!";
+ abort();
+ }
+
+ for_all_lines(l, lines)
+ {
+ if (! lines(l).is_valid() || lines(l).tag() != line::None || lines(l).type() != line::Text || lines(l).text().empty())
+ continue;
+
+ file << lines(l).bbox().pmin().row() + crop_shift.row()<< " "
+ << lines(l).bbox().pmin().col() + crop_shift.col()<< " "
+ << lines(l).bbox().pmax().row() + crop_shift.row() << " "
+ << lines(l).bbox().pmax().col() + crop_shift.col()<< " "
+ << lines(l).text() << std::endl;
+ }
+
+ file.close();
+
+
+ trace::exiting("scribo::io::text_boxes::save");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::io::text_boxes
+
+ } // end of namespace scribo::io
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_IO_TEXT_BOXES_SAVE_HH
--
1.5.6.5
1
0
* preprocessing/deskew.hh,
* preprocessing/deskew_crop.hh: New.
* preprocessing/unskew.hh: Remove. Deprecated.
* tests/preprocessing/unskew.cc: Rename as...
* tests/preprocessing/deskew.cc: ... this.
* tests/preprocessing/Makefile.am: Update.
* tests/img/text_to_group.pgm: New test image.
---
scribo/ChangeLog | 16 +
scribo/preprocessing/deskew.hh | 437 ++++++++++++++++++++
scribo/preprocessing/deskew_crop.hh | 187 +++++++++
scribo/preprocessing/unskew.hh | 115 -----
scribo/tests/img/text_to_group.pgm | Bin 0 -> 3053 bytes
scribo/tests/preprocessing/Makefile.am | 4 +-
.../tests/preprocessing/{unskew.cc => deskew.cc} | 22 +-
7 files changed, 657 insertions(+), 124 deletions(-)
create mode 100644 scribo/preprocessing/deskew.hh
create mode 100644 scribo/preprocessing/deskew_crop.hh
delete mode 100644 scribo/preprocessing/unskew.hh
create mode 100644 scribo/tests/img/text_to_group.pgm
rename scribo/tests/preprocessing/{unskew.cc => deskew.cc} (74%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index c5476be..623147b 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,21 @@
2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a new deskew algorithm.
+
+ * preprocessing/deskew.hh,
+ * preprocessing/deskew_crop.hh: New.
+
+ * preprocessing/unskew.hh: Remove. Deprecated.
+
+ * tests/preprocessing/unskew.cc: Rename as...
+ * tests/preprocessing/deskew.cc: ... this.
+
+ * tests/preprocessing/Makefile.am: Update.
+
+ * tests/img/text_to_group.pgm: New test image.
+
+2010-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add crop tools.
* preprocessing/crop.hh,
diff --git a/scribo/preprocessing/deskew.hh b/scribo/preprocessing/deskew.hh
new file mode 100644
index 0000000..27d38a1
--- /dev/null
+++ b/scribo/preprocessing/deskew.hh
@@ -0,0 +1,437 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PREPROCESSING_DESKEW_HH
+# define SCRIBO_PREPROCESSING_DESKEW_HH
+
+/// \file
+///
+/// Deskew an image.
+
+/// \FIXME: provide a version for binary images.
+
+
+# include <queue>
+# include <mln/core/image/image2d.hh>
+# include <mln/math/pi.hh>
+# include <mln/geom/rotate.hh>
+
+# define PI 3.1415926535897932384
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ using namespace mln;
+
+ namespace internal
+ {
+
+ class Hough
+ {
+ public:
+ Hough(int width, int height);
+
+ ~Hough();
+
+ void look_up_table();
+
+ int width() const;
+
+ int height() const;
+
+ double mtheta() const;
+ double mrho() const;
+
+ int mrhoi() const;
+ int mthetai() const;
+
+ double get_cos(int index) const;
+ double get_sin(int index) const;
+
+ image2d<unsigned>& acc();
+
+ private:
+ int width_;
+ int height_;
+
+ double max_rho_;
+ double max_theta_;
+
+ int max_rho_index_;
+ int max_theta_index_;
+
+ double* cos_;
+ double* sin_;
+
+ image2d<unsigned> acc_;
+ };
+
+
+ struct s_angle
+ {
+ int pos;
+ unsigned max;
+ };
+
+
+ struct QCompare
+ {
+ bool operator()(const s_angle& s1, const s_angle& s2);
+ };
+
+ } // end of namespace scribo::preprocessing::internal
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ bool
+ QCompare::operator()(const s_angle& s1, const s_angle& s2)
+ {
+ return (s1.max > s2.max);
+ }
+
+
+ Hough::Hough(int width, int height)
+ : width_(width / 2),
+ height_(height / 2),
+ max_rho_(sqrt((width * width) + (height * height))),
+ max_theta_(math::pi),
+ max_rho_index_(this->max_rho_ + 1),
+ max_theta_index_(500),
+ acc_(this->max_rho_index_, this->max_theta_index_)
+ {
+ look_up_table();
+ }
+
+
+ Hough::~Hough()
+ {
+ delete[] this->cos_;
+ delete[] this->sin_;
+ }
+
+ inline
+ void Hough::look_up_table()
+ {
+ this->cos_ = new double[this->max_theta_index_];
+ this->sin_ = new double[this->max_theta_index_];
+
+ for (int i = 0; i < this->max_theta_index_; ++i)
+ {
+ double i_val = (i + 650) * this->max_theta_ / 1800.0f;
+
+ this->cos_[i] = cos(i_val);
+ this->sin_[i] = sin(i_val);
+ }
+ }
+
+ inline
+ int Hough::width() const
+ {
+ return this->width_;
+ }
+
+ inline
+ int Hough::height() const
+ {
+ return this->height_;
+ }
+
+ inline
+ double Hough::mtheta() const
+ {
+ return this->max_theta_;
+ }
+
+ inline
+ double Hough::mrho() const
+ {
+ return this->max_rho_;
+ }
+
+ inline
+ int Hough::mrhoi() const
+ {
+ return this->max_rho_index_;
+ }
+
+ inline
+ int Hough::mthetai() const
+ {
+ return this->max_theta_index_;
+ }
+
+ inline
+ double Hough::get_cos(int index) const
+ {
+ return this->cos_[index];
+ }
+
+ inline
+ double Hough::get_sin(int index) const
+ {
+ return this->sin_[index];
+ }
+
+ inline
+ image2d<unsigned>& Hough::acc()
+ {
+ return this->acc_;
+ }
+
+ inline
+ static
+ void
+ vote(int x, int y, Hough& hough, int theta)
+ {
+ int theta_min = std::max(theta - 25, 0);
+ int theta_max = std::min(theta + 25, hough.mthetai());
+
+ x -= hough.width();
+ y -= hough.height();
+
+ for (int i = theta_min; i < theta_max; ++i)
+ {
+ double rho = x * hough.get_cos(i) + y * hough.get_sin(i);
+ double rho_index = (0.5 + (rho / hough.mrho() + 0.5)
+ * hough.mrhoi());
+
+ ++(opt::at(hough.acc(), rho_index, i));
+ }
+ }
+
+
+ inline
+ static
+ void
+ init_hist(Hough& hough, int hist[500],
+ std::priority_queue<s_angle, std::vector<s_angle>, QCompare>& q,
+ int nb_elm)
+ {
+ int max_rho = hough.mrhoi();
+ int max_theta = hough.mthetai();
+ unsigned max_elm = (nb_elm > max_rho) ? (nb_elm / max_rho) << 5 : 1;
+
+ for (int j = 0; j < max_theta; ++j)
+ {
+ hist[j] = 0;
+
+ if (q.size() < max_elm)
+ {
+ if (opt::at(hough.acc(), 0, j) > 0)
+ {
+ s_angle s;
+
+ s.max = opt::at(hough.acc(), 0, j);
+ s.pos = j;
+
+ q.push(s);
+ }
+ }
+ else if (opt::at(hough.acc(), 0, j) > q.top().max)
+ {
+ s_angle s;
+
+ s.max = opt::at(hough.acc(), 0, j);
+ s.pos = j;
+
+ q.pop();
+ q.push(s);
+ }
+ }
+ }
+
+
+ inline
+ static
+ double
+ get_max(Hough& hough, int hist[500],
+ std::priority_queue<s_angle, std::vector<s_angle>, QCompare>& q,
+ int nb_elm)
+ {
+ int max = 0;
+ int h_value = 0;
+ int max_rho = hough.mrhoi();
+ int max_theta = hough.mthetai();
+ double pos = 0.f;
+ unsigned max_elm = (nb_elm > max_rho) ? (nb_elm / max_rho) << 5 : 1;
+
+
+ for (int i = 1; i < max_rho; ++i)
+ {
+ for (int j = 0; j < max_theta; ++j)
+ {
+ if (q.size() < max_elm)
+ {
+ if (opt::at(hough.acc(), i, j) > 0)
+ {
+ s_angle s;
+
+ s.max = opt::at(hough.acc(), i, j);
+ s.pos = j;
+
+ q.push(s);
+ }
+ }
+ else if (opt::at(hough.acc(), i, j) > q.top().max)
+ {
+ s_angle s;
+
+ s.max = opt::at(hough.acc(), i, j);
+ s.pos = j;
+
+ q.pop();
+ q.push(s);
+ }
+ }
+ }
+
+ while (!q.empty())
+ {
+ hist[q.top().pos] += q.top().max;
+ h_value = hist[q.top().pos];
+
+ if (h_value > max)
+ {
+ max = h_value;
+ pos = q.top().pos;
+ }
+
+ q.pop();
+ }
+
+ return pos;
+ }
+
+
+ double
+ perform_deskew(const image2d<value::int_u8>& gray)
+ {
+ Hough hough(gray.ncols(), gray.nrows());
+ std::priority_queue<s_angle, std::vector<s_angle>, QCompare> q;
+ int hist[500];
+ int nb_elm = 0;
+
+ for (unsigned i = 0; i < gray.nrows() - 1; ++i)
+ {
+ for (unsigned j = 1; j < gray.ncols() - 1; ++j)
+ {
+ unsigned up = 1;
+ unsigned down = 1;
+ unsigned mean = ((opt::at(gray, i, j) * opt::at(gray, i + 1, j))) >> 8;
+
+ for (unsigned k = j - 1; k <= j + 1; ++k)
+ {
+ up *= opt::at(gray, i, k);
+ down *= opt::at(gray, i + 1, k);
+ }
+
+ up = 255 - (up >> 16);
+ down = down >> 16;
+
+ if (up > down && down > mean && down > 130)
+ {
+
+ ++nb_elm;
+ double gy = opt::at(gray, i - 1, j - 1) + 2 * opt::at(gray, i - 1, j) +
+ opt::at(gray, i - 1, j + 1);
+ gy += -opt::at(gray, i + 1, j - 1) - 2 * opt::at(gray, i + 1, j) -
+ opt::at(gray, i + 1, j + 1);
+
+ double gx = opt::at(gray, i - 1, j - 1) + 2 * opt::at(gray, i, j - 1) +
+ opt::at(gray, i + 1, j - 1);
+ gx += -opt::at(gray, i - 1, j + 1) - 2 * opt::at(gray, i, j + 1) -
+ opt::at(gray, i + 1, j + 1);
+
+ double tanv = (PI / 2.0 - atan(gy / gx)) * 180.0 / PI;
+
+ if (tanv <= 25.0 || tanv >= 155.0)
+ {
+ ++nb_elm;
+ vote(j, i, hough, (tanv <= 25.0 ? 250.0 - tanv * 10.0 :
+ (180.0 - tanv) * 10.0 + 250.0));
+ }
+ }
+ }
+ }
+
+ init_hist(hough, hist, q, nb_elm);
+
+ return 90 - (get_max(hough, hist, q, nb_elm) + 650) / 10;
+ }
+
+
+
+ } // end of namespace scribo::preprocessing::internal
+
+
+
+ template <typename I>
+ mln_concrete(I)
+ deskew(const Image<I>& input_gl_)
+ {
+ const I& input_gl = exact(input_gl_);
+
+ trace::entering("scribo::preprocessing::deskew");
+ mln_assertion(input_gl.is_valid());
+ mlc_is(mln_domain(I), box2d)::check();
+ mlc_is_not(mln_value(I), bool)::check();
+ mlc_is_not_a(mln_value(I), value::Vectorial)::check();
+
+ double angle = internal::perform_deskew(input_gl);
+// std::cout << angle << std::endl;
+
+ mln_concrete(I) output = input_gl;
+
+ // FIXME: trick to make this routine faster for really small
+ // angles (no impact on the results)
+ if (angle > 0.5 || angle < -0.5)
+ output = geom::rotate(input_gl, - angle,
+ //mln_max(mln_value(I)),
+ extend(input_gl, mln_max(mln_value(I))),
+ make::box2d(input_gl.nrows(),
+ input_gl.ncols()));
+
+ trace::exiting("scribo::preprocessing::deskew");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace scribo
+
+
+# endif // SCRIBO_PREPROCESSING_DESKEW_HH
diff --git a/scribo/preprocessing/deskew_crop.hh b/scribo/preprocessing/deskew_crop.hh
new file mode 100644
index 0000000..3b15cb1
--- /dev/null
+++ b/scribo/preprocessing/deskew_crop.hh
@@ -0,0 +1,187 @@
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_PREPROCESSING_DESKEW_CROP_HH
+# define SCRIBO_PREPROCESSING_DESKEW_CROP_HH
+
+/// \file
+///
+/// \brief Deskew a region of interest.
+
+# include <scribo/preprocessing/deskew.hh>
+
+namespace scribo
+{
+
+ namespace preprocessing
+ {
+
+ /*! \brief Deskew a region of interest.
+
+ \param[in] input_bin A binary image.
+ \param[in] input_gray A gray-level image.
+
+ \return A deskewed binary image.
+
+
+
+ Handles skew angles from -25 to +25 degrees.
+
+ \p input_bin and \p input_gray must be 2D images and must be
+ identical (e.g. only the value differs).
+
+ This algorithm is designed for images created from a region of
+ interest (e.g. Not a full document).
+
+ */
+ template <typename I, typename J>
+ mln_concrete(I)
+ deskew(const Image<I>& crop_gl_, const Image<I>& input_gl_);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+
+ /*! \brief Compute the skew angle using a Hough transform.
+
+ \param[in] input_bin A binary image.
+ \param[in] input_gray A gray-level image.
+ \param[in] threshold
+ \param[in] length
+
+ \return A deskewed binary image.
+
+ This algorithm tries to use only the sites located on the
+ baselines (the most relevant sites for deskewing).
+ A site is considered as relevant for this algorithm if :
+ - \p threshold sites in the window of length \p length are set to True.
+ - The bottom left, bottom and bottom right sites are set to False.
+
+ Note: Increasing \p length value while keeping threshold value
+ low increases the number of relevant sites.
+
+ Handles skew angles from -25 to +25 degrees.
+
+ \p input_bin and \p input_gray must be 2D images and must be
+ identical (e.g. only the value differs).
+
+ This algorithm is designed for images created from a region of
+ interest (e.g. Not a full document).
+
+ */
+// double
+// perform_deskew_crop(const image2d<bool>& input_bin,
+// const image2d<value::int_u8>& input_gray,
+// int threshold,
+// int length)
+// {
+// Hough hough(input_bin.ncols(), input_bin.nrows());
+// int
+// mid = length >> 1,
+// max = 0;
+// double pos = 0;
+
+// for (int i = 1; i < input_bin.nrows() - 1; ++i)
+// {
+// int
+// acc = 0,
+// begin = 0,
+// end = length;
+
+// for (int j = 0; j < length; ++j)
+// acc += opt::at(input_bin, i, j);
+
+// for (int j = mid + 1; end < input_bin.ncols(); ++j, ++end, ++begin)
+// {
+// acc += opt::at(input_bin, i, end) - opt::at(input_bin, i, begin);
+
+// if (acc > threshold && !opt::at(input_bin, i + 1, j) &&
+// !opt::at(input_bin, i + 1, j - 1) && !opt::at(input_bin, i + 1, j + 1))
+// {
+// double gy = opt::at(input_gray, i - 1, j - 1) + 2 * opt::at(input_gray, i - 1, j) + opt::at(input_gray, i - 1, j + 1);
+// gy += - opt::at(input_gray, i + 1, j - 1) - 2 * opt::at(input_gray, i + 1, j) - opt::at(input_gray, i + 1, j + 1);
+
+// double gx = opt::at(input_gray, i - 1, j - 1) + 2 * opt::at(input_gray, i, j - 1) + opt::at(input_gray, i + 1, j - 1);
+// gx += - opt::at(input_gray, i - 1, j + 1) - 2 * opt::at(input_gray, i, j + 1) - opt::at(input_gray, i + 1, j + 1);
+
+// if (abs(gx) + abs(gy) >= 255)
+// vote(j, i, deskew, &max, &pos);
+// }
+// }
+// }
+
+// return 90 - (pos + 650) / 10.0f;
+// }
+
+
+// } // end of namespace scribo::preprocessing::internal
+
+
+ // Facade
+
+
+ template <typename I>
+ mln_concrete(I)
+ deskew(const Image<I>& crop_gl_, const Image<I>& input_gl_)
+ {
+ const I& crop_gl = exact(crop_gl_);
+ const I& input_gl = exact(input_gl_);
+
+ trace::entering("scribo::preprocessing::deskew_crop");
+ mln_assertion(crop_gl.is_valid());
+ mln_assertion(input_gl.is_valid());
+ mlc_is(mln_domain(I), box2d)::check();
+ mlc_is_not(mln_value(I), bool)::check();
+ mlc_is_not_a(mln_value(I), value::Vectorial)::check();
+
+ double angle = internal::perform_deskew(crop_gl);
+ std::cout << angle << std::endl;
+
+ mln_concrete(I) output = crop_gl;
+
+ // FIXME: trick to make this routine faster for really small
+ // angles (no impact on the results)
+ if (angle > 0.5 || angle < -0.5)
+ output = geom::rotate(crop_gl, - angle,
+ //mln_max(mln_value(I)),
+ extend(input_gl, mln_max(mln_value(I))),
+ make::box2d(crop_gl.nrows(),
+ crop_gl.ncols()));
+
+ trace::exiting("scribo::preprocessing::deskew_crop");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::preprocessing
+
+} // end of namespace scribo
+
+
+# endif // SCRIBO_PREPROCESSING_DESKEW_CROP_HH
diff --git a/scribo/preprocessing/unskew.hh b/scribo/preprocessing/unskew.hh
deleted file mode 100644
index a01cae3..0000000
--- a/scribo/preprocessing/unskew.hh
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#ifndef SCRIBO_PREPROCESSING_UNSKEW_HH
-# define SCRIBO_PREPROCESSING_UNSKEW_HH
-
-/// \file
-///
-/// Unskew an image.
-
-# include <mln/core/image/image2d.hh>
-
-# include <mln/accu/compute.hh>
-# include <mln/accu/max_site.hh>
-
-# include <mln/transform/hough.hh>
-# include <mln/geom/rotate.hh>
-
-# include <mln/io/pgm/save.hh>
-# include <mln/core/image/vmorph/cast_image.hh>
-# include <mln/value/int_u8.hh>
-
-# include <mln/util/couple.hh>
-
-namespace scribo
-{
-
- namespace preprocessing
- {
-
- using namespace mln;
-
- /// Unskew a document.
- /// Based on the Hough transform.
- ///
- /// \param[in] input_ A binary image. Objects to be unskewed must be set
- /// to "true".
- ///
- /// \return A binary image.
- //
- template <typename I>
- mln::util::couple<mln_concrete(I), double>
- unskew(const Image<I>& input_);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-
- template <typename I>
- mln::util::couple<mln_concrete(I), double>
- unskew(const Image<I>& input_)
- {
- trace::entering("scribo::preprocessing::unskew");
-
- const I& input = exact(input_);
- mlc_equal(mln_value(I), bool)::check();
- mln_precondition(input.is_valid());
-
- image2d<float> hough_ima = transform::hough(input);
-
- point2d max_p = accu::compute(accu::max_site<image2d<float> >(), hough_ima);
-
- double angle = 0;
- int max_angle = max_p.row();
-
-// std::cout << "max_angle = " << max_angle << std::endl;
- if (max_angle > 180)
- max_angle = - max_angle % 180;
-
- if (max_angle < 90 && max_angle > 0)
- angle = - max_angle;
- else if (max_angle < 0 && max_angle > -90)
- angle = max_angle;
- else if (max_angle < 180 && max_angle > 90)
- angle = 180 - max_angle;
- else if (max_angle < -90 && max_angle > -180)
- angle = 180 + max_angle;
-
-// std::cout << "effective angle = " << angle << std::endl;
- mln_concrete(I) output = geom::rotate(input, angle);
-
- trace::exiting("scribo::preprocessing::unskew");
- return mln::make::couple(output, angle);
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace scribo::preprocessing
-
-} // end of namespace mln
-
-# endif // SCRIBO_PREPROCESSING_UNSKEW_HH
diff --git a/scribo/tests/img/text_to_group.pgm b/scribo/tests/img/text_to_group.pgm
new file mode 100644
index 0000000000000000000000000000000000000000..220ffbaa2e49e0b1e8fe644de06e4d627748d19e
GIT binary patch
literal 3053
zcmWGA<x*B~4svx2@ei_6aQE~LPzdnzRdCD9DM>9-2um$0&dkqKFw`^T;xaQ(Fg4&Z
zGBxF57zLvtFd70wHw6B}0Rx=%pD+{b;r}pi12vGq9MuaAEFyw!V8aTYA_yl4xKemZ
zfTf60nwBAeJ=}>Cg+~>f0dgsv17~0pg-gO2*i?bUFinJOfitkF0&B%^4O|PHF{&35
YQdq(no(y0rz+pv#D6+m$_Am+o0N4yHPXGV_
literal 0
HcmV?d00001
diff --git a/scribo/tests/preprocessing/Makefile.am b/scribo/tests/preprocessing/Makefile.am
index d180604..f94a852 100644
--- a/scribo/tests/preprocessing/Makefile.am
+++ b/scribo/tests/preprocessing/Makefile.am
@@ -23,11 +23,11 @@ check_PROGRAMS = \
crop \
crop_without_localization \
rotate_90 \
- unskew
+ deskew
crop_SOURCES = crop.cc
crop_without_localization_SOURCES = crop_without_localization.cc
rotate_90_SOURCES = rotate_90.cc
-unskew_SOURCES = unskew.cc
+deskew_SOURCES = deskew.cc
TESTS = $(check_PROGRAMS)
diff --git a/scribo/tests/preprocessing/unskew.cc b/scribo/tests/preprocessing/deskew.cc
similarity index 74%
rename from scribo/tests/preprocessing/unskew.cc
rename to scribo/tests/preprocessing/deskew.cc
index 9c84951..5b55889 100644
--- a/scribo/tests/preprocessing/unskew.cc
+++ b/scribo/tests/preprocessing/deskew.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -23,11 +24,16 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
+/// \file
+///
+/// \fixme Add a better test.....
+
#include <mln/core/image/image2d.hh>
-#include <mln/io/pbm/load.hh>
-#include <mln/io/pbm/save.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/data/compare.hh>
-#include <scribo/preprocessing/unskew.hh>
+#include <scribo/preprocessing/deskew.hh>
#include <scribo/tests/data.hh>
@@ -37,8 +43,10 @@ int main(int argc, char *argv[])
(void) argv;
using namespace mln;
- image2d<bool> ima;
- io::pbm::load(ima, SCRIBO_IMG_DIR "/text_to_group.pbm");
+ image2d<value::int_u8> ima;
+ io::pgm::load(ima, SCRIBO_IMG_DIR "/text_to_group.pgm");
+
+ image2d<value::int_u8> tmp = scribo::preprocessing::deskew(ima);
- io::pbm::save(scribo::preprocessing::unskew(ima).first(), "unskew.pbm");
+ mln_assertion(ima == tmp);
}
--
1.5.6.5
1
0