* scribo/src/Makefile.am: Add a new target.
* scribo/src/text_in_article_preprocess.cc: New.
* scribo/src/text_in_article_pbm.cc: Add optional cropping and
makes the debug optionnal.
* scribo/text/clean.hh: Improve cleanup.
* scribo/text/recognition.hh: Remove last '\n' in Tesseract's
output.
---
scribo/ChangeLog | 16 ++
scribo/src/Makefile.am | 9 +
scribo/src/text_in_article_pbm.cc | 162 +++++++++++++-------
...sauvola_ms.cc => text_in_article_preprocess.cc} | 90 +++++-------
scribo/text/clean.hh | 13 +-
scribo/text/recognition.hh | 14 ++-
6 files changed, 184 insertions(+), 120 deletions(-)
copy scribo/src/{binarization/fg_sauvola_ms.cc => text_in_article_preprocess.cc}
(53%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f2850e0..59f9e67 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,19 @@
+2010-05-04 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Prepare DIA tools for Nuxeo/XWiki.
+
+ * scribo/src/Makefile.am: Add a new target.
+
+ * scribo/src/text_in_article_preprocess.cc: New.
+
+ * scribo/src/text_in_article_pbm.cc: Add optional cropping and
+ makes the debug optionnal.
+
+ * scribo/text/clean.hh: Improve cleanup.
+
+ * scribo/text/recognition.hh: Remove last '\n' in Tesseract's
+ output.
+
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
Improve OCR recognition.
diff --git a/scribo/src/Makefile.am b/scribo/src/Makefile.am
index 80dc782..08b4bd9 100644
--- a/scribo/src/Makefile.am
+++ b/scribo/src/Makefile.am
@@ -82,6 +82,15 @@ if HAVE_TIFF
text_in_article_pbm_SOURCES = text_in_article_pbm.cc
+ 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
+
+
+
bin_PROGRAMS += text_in_photo_fast
text_in_photo_fast_SOURCES = text_in_photo_fast.cc
text_in_photo_fast_CPPFLAGS = $(AM_CPPFLAGS) \
diff --git a/scribo/src/text_in_article_pbm.cc b/scribo/src/text_in_article_pbm.cc
index e71d21b..20a18e9 100644
--- a/scribo/src/text_in_article_pbm.cc
+++ b/scribo/src/text_in_article_pbm.cc
@@ -40,6 +40,8 @@
#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>
@@ -85,6 +87,10 @@ const char *args_desc[][2] =
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}
};
@@ -95,14 +101,20 @@ int main(int argc, char* argv[])
using namespace scribo;
using namespace mln;
- if (argc != 3 && argc != 4 && argc != 5)
+ 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> <debug_dir>",
+ "input.pbm out.txt <denoise: 0|1> [<pmin_row> <pmin_col>
<pmax_row> <pmax_col>] <debug_dir>",
args_desc);
- if (argc == 5)
- scribo::make::internal::debug_filename_prefix = argv[4];
+ 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");
@@ -110,6 +122,27 @@ int main(int argc, char* argv[])
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;
@@ -129,7 +162,9 @@ int main(int argc, char* argv[])
// whitespaces += separators;
- mln::io::pbm::save(separators, "vseparators.pbm");
+ 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");
@@ -214,18 +249,20 @@ int main(int argc, char* argv[])
//===== DEBUG =====
- // Bboxes image.
- scribo::debug::save_bboxes_image(input, lines,
- scribo::make::debug_filename("step1_bboxes.ppm"));
+ if (debug)
+ {
- // Bboxes enlarged
- mln::io::ppm::save(scribo::debug::bboxes_enlarged_image(input, lines),
- scribo::make::debug_filename("step1_bboxes_enlarged.ppm"));
+ // Bboxes image.
+ scribo::debug::save_bboxes_image(input, lines,
+ scribo::make::debug_filename("step1_bboxes.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 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
// {
@@ -261,10 +298,11 @@ int main(int argc, char* argv[])
// }
- // 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"));
+ // 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 =====
@@ -277,56 +315,62 @@ int main(int argc, char* argv[])
//===== 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"));
+ if (debug)
+ {
- // 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"));
+ // 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"));
- // Bboxes image.
- scribo::debug::save_bboxes_image(input, lines,
- scribo::make::debug_filename("step2_bboxes.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 =====
+
+// {
+// 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::io::xml::save_text_lines(argv[1], lines, "out.xml");
diff --git a/scribo/src/binarization/fg_sauvola_ms.cc
b/scribo/src/text_in_article_preprocess.cc
similarity index 53%
copy from scribo/src/binarization/fg_sauvola_ms.cc
copy to scribo/src/text_in_article_preprocess.cc
index 9c606d6..8cfa82f 100644
--- a/scribo/src/binarization/fg_sauvola_ms.cc
+++ b/scribo/src/text_in_article_preprocess.cc
@@ -1,5 +1,4 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,82 +23,69 @@
// 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/value/rgb8.hh>
+
#include <mln/io/magick/load.hh>
#include <mln/io/pbm/save.hh>
-#include <scribo/binarization/sauvola_ms.hh>
-#include <scribo/preprocessing/split_bg_fg.hh>
-#include <scribo/debug/usage.hh>
+#include <mln/value/rgb8.hh>
-bool check_args(int argc, char * argv[])
-{
- if (argc != 7)
- return false;
+#include <mln/logical/not.hh>
- int s = atoi(argv[4]);
+#include <scribo/binarization/sauvola_ms.hh>
- if (s < 2 || s > 3)
- {
- std::cout << "s must be set to 2 or 3."
- << std::endl;
- return false;
- }
+#include <scribo/debug/usage.hh>
+
+#include <scribo/preprocessing/split_bg_fg.hh>
- return true;
-}
const char *args_desc[][2] =
{
{ "input.*", "An image." },
- { "output.pbm", "A binary image." },
- { "lambda", "Lambda used to split bg/fg." },
- { "w", "Window size at scale 1. (Common value: 101)" },
- { "s", "First subsampling ratio (Common value: 3)." },
- { "min_area", "Minimum object area at scale 1 (Common value:
67)" },
+ { "output.pbm", "A text file with all the recognized text" },
+ { "enable fg/bg", "If set to 1 enables foreground extraction. (disabled
by default)" },
+ { "lambda", "Lambda used in remove fg/bg (Automaticaly deduced by
default)." },
{0, 0}
};
-
-
-int main(int argc, char *argv[])
+int main(int argc, char* argv[])
{
- using namespace mln;
using namespace scribo;
+ using namespace mln;
- if (!check_args(argc, argv))
+ if (argc != 3 && argc != 4 && argc != 5)
return scribo::debug::usage(argv,
- "Multi-Scale Binarization based on Sauvola's algorithm. Performs a
binarization on each component of the color image and merges the results.",
- "input.* output.pbm w s area_threshold",
+ "Find text in a color document.",
+ "input.* output.pbm <enable fg/bg> <lambda>",
args_desc);
- trace::entering("main");
-
- unsigned lambda = atoi(argv[2]);
+ image2d<value::rgb8> input_rgb;
+ io::magick::load(input_rgb, argv[1]);
- // Window size
- unsigned w_1 = atoi(argv[3]); // Scale 1
+ unsigned lambda;
+ if (argc == 5)
+ lambda = atoi(argv[4]);
+ else
+ lambda = 1.2 * (input_rgb.nrows() + input_rgb.ncols());
- // First subsampling scale.
- unsigned s = atoi(argv[4]);
-
- // Lambda value
- unsigned lambda_min_1 = atoi(argv[5]);
-
-
- image2d<value::rgb8> input_1;
- io::magick::load(input_1, argv[1]);
+ // Extract foreground
+ if (argc == 4 && atoi(argv[3]) == 1)
+ {
+ std::cout << "Extracting foreground..." << std::endl;
+ input_rgb = preprocessing::split_bg_fg(input_rgb, lambda, 32).second();
+ }
- image2d<value::rgb8>
- fg = scribo::preprocessing::split_bg_fg(input_1, lambda, 32).first();
+ // 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>
- output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1,
SCRIBO_DEFAULT_SAUVOLA_K);
+ logical::not_inplace(input);
- io::pbm::save(output, argv[6]);
+ mln::io::pbm::save(input, argv[2]);
}
-
-
diff --git a/scribo/text/clean.hh b/scribo/text/clean.hh
index fa31ebe..f93bc6f 100644
--- a/scribo/text/clean.hh
+++ b/scribo/text/clean.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -113,14 +114,14 @@ namespace scribo
if (fact < 1)
{
std::cout << "Upsampling..." << " - "
- << std::ceil(fact) << std::endl;
- while (fact < 1)
+ << fact << std::endl;
+ while (fact < 0.90)
{
output = scribo::upsampling::bs2x(output); // 2x upsampling
fact *= 2.0f;
-// std::cout << "fact = " << fact
-// << " - output.domain = " << output.domain()
-// << std::endl;
+// std::cout << "fact = " << fact
+// << " - output.domain = " << output.domain()
+// << std::endl;
}
}
else if (fact > 2.5f)
diff --git a/scribo/text/recognition.hh b/scribo/text/recognition.hh
index 72df1e2..6f9dac7 100644
--- a/scribo/text/recognition.hh
+++ b/scribo/text/recognition.hh
@@ -159,7 +159,7 @@ namespace scribo
/// text_ima_cleaned domain is larger than text_ima's.
I text_ima_cleaned = text::clean(lines(i), text_ima);
- mln::io::pbm::save(text_ima_cleaned, mln::debug::filename("line.pbm",
debug_id++));
+// mln::io::pbm::save(text_ima_cleaned, mln::debug::filename("line.pbm",
debug_id++));
// Setting objects to 'True'
logical::not_inplace(text_ima_cleaned);
@@ -182,7 +182,11 @@ namespace scribo
{
std::cerr << s << std::endl;
if (output_file != 0)
- file << lines(i).bbox() << " " << s << std::endl;
+ {
+ std::string str(s);
+ str = str.substr(0, str.length() - 1);
+ file << lines(i).bbox() << " " << str;
+ }
}
// The string has been allocated by Tesseract. We must free it.
@@ -241,7 +245,11 @@ namespace scribo
{
std::cout << s << std::endl;
if (output_file != 0)
- file << line.domain() << " " << s << std::endl;
+ {
+ std::string str(s);
+ str = str.substr(0, str.length() - 1);
+ file << line.domain() << " " << str;
+ }
}
// The string has been allocated by Tesseract. We must free it.
--
1.5.6.5