* text/clean.hh: Do not use the distance map anymore.
* text/recognition.hh: Do not return an image of char anymore.
Enlarge the temporary image domain.
---
scribo/ChangeLog | 9 +++++
scribo/text/clean.hh | 73 ++++++++++++++++++++++++-------------------
scribo/text/recognition.hh | 39 ++++++++++++++---------
3 files changed, 74 insertions(+), 47 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 15ea49e..af2f788 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,14 @@
2009-09-15 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Make text cleaning work.
+
+ * text/clean.hh: Do not use the distance map anymore.
+
+ * text/recognition.hh: Do not return an image of char anymore.
+ Enlarge the temporary image domain.
+
+2009-09-15 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Add new filters in Scribo.
* filter/common/objects_photo.hh,
diff --git a/scribo/text/clean.hh b/scribo/text/clean.hh
index 0f87139..e934241 100644
--- a/scribo/text/clean.hh
+++ b/scribo/text/clean.hh
@@ -41,7 +41,7 @@
# include <mln/logical/not.hh>
-# include <mln/world/binary_2d/enlarge.hh>
+//# include <mln/world/binary_2d/enlarge.hh>
# include <mln/debug/filename.hh>
# include <mln/io/pbm/save.hh>
@@ -58,6 +58,15 @@
#include <mln/value/int_u8.hh>
+#include <mln/fun/v2b/threshold.hh>
+#include <mln/binarization/threshold.hh>
+#include <mln/data/convert.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/io/pgm/all.hh>
+
+#include <sandbox/inim/2009/ocr/resize.hh>
+#include <sandbox/fabien/mln/upsampling/hq4x.hh>
+
namespace scribo
{
@@ -70,7 +79,8 @@ namespace scribo
/// Improve quality of an image with text.
///
- /// \param[in] input_ A binary image.
+ /// \param[in] input_ A binary image. Object are set to 'false'
+ /// and backgroud to 'true'.
/// \param[in] dmap_win_ A weighted window.
///
/// \return An image. The text have better quality.
@@ -83,8 +93,6 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
-// static int plop = 0;
-
template <typename I, typename W>
mln_concrete(I)
clean(const Image<I>& input_, const Weighted_Window<W>&
dmap_win_)
@@ -98,43 +106,44 @@ namespace scribo
mln_precondition(input.is_valid());
mln_precondition(dmap_win.is_valid());
-// I input_large = world::binary_2d::enlarge(input, 2);
-// image2d<bool> blur = linear::gaussian(input_large, 2);
-// image2d<value::int_u8> blur =
linear::gaussian(level::convert(value::int_u8(), input_large), 2);
-// image2d<bool> blur =
level::transform(linear::gaussian(level::convert(value::int_u8(), input_large), 2),
fun::v2b::threshold<value::int_u8>(100));
+ // Resize
+ typedef image2d<value::rgb8> J;
+ J tmp = data::convert(value::rgb8(), input);
+ J clarge = mln::upsampling::hq4x(tmp);
+
+ //FIXME: not generic!
+ if (input.domain().pmax()[0] - input.domain().pmin()[0] <= 10)
+ clarge = mln::upsampling::hq4x(clarge);
-// mln_ch_value(I,unsigned)
-// dmap = transform::distance_front(logical::not_(input_large), c8(),
-// dmap_win,
-// mln_max(unsigned));
-// io::pgm::save(labeling::wrap(dmap), mln::debug::filename("dmap.pgm"));
+ I input_large = data::convert(bool(), clarge);
-// I skeleton = topo::skeleton::crest(input_large, dmap, c8());
-// I constraint = topo::skeleton::crest(input_large, dmap, c8());
-// mln_postcondition(constraint.is_valid());
+ // Blur
+ image2d<value::int_u8>
+ blur = linear::gaussian(data::convert(value::int_u8(), input_large), 2);
-// io::pgm::save(labeling::wrap(constraint),
mln::debug::filename("constraint.pgm"));
+ // Skeleton constraint
+ I K = topo::skeleton::crest(input_large, blur, c8());
-// I skeleton =
-// morpho::skeleton_constrained(input_large, c8(),
-//
topo::skeleton::is_simple_point<I,neighb2d>,
-// extend(constraint, false), arith::revert(dmap));
+ // Skeleton
+ I skel_on_gaussian =
+ morpho::skeleton_constrained(input_large, c8(),
+ topo::skeleton::is_simple_point<I,neighb2d>,
+ extend(K, false), arith::revert(blur));
-// win::octagon2d disk(7);
-// I output = morpho::dilation(skeleton, disk);
+ // Dilation
+ win::octagon2d oct(7);
+ I dilate_on_gaussian = morpho::dilation(skel_on_gaussian, oct);
-// if (plop > 20 && plop < 50)
- {
-// io::pbm::save(input, mln::debug::filename("input.pbm"));
-// io::pbm::save(input_large,
mln::debug::filename("input_large_4x.pbm"));
-// io::pbm::save(skeleton, mln::debug::filename("skeleton.pbm"));
-// io::pbm::save(output, mln::debug::filename("dil_skel.pbm"));
- }
+// io::pgm::save(arith::revert(blur), "blur_revert.pgm");
+// io::pgm::save(blur, "gaussian.pgm");
+// io::pbm::save(input_large, mln::debug::filename("input_large_4x.pbm"));
+// io::pbm::save(K, mln::debug::filename("K.pbm"));
+// io::pbm::save(skel_on_gaussian,
mln::debug::filename("skeleton_on_gaussian.pbm"));
+// io::pbm::save(dilate_on_gaussian,
mln::debug::filename("dilation_on_gaussian.pbm"));
-// ++plop;
trace::exiting("scribo::text::clean");
- return input;
+ return dilate_on_gaussian;
}
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/text/recognition.hh b/scribo/text/recognition.hh
index 6293e28..bd9f89b 100644
--- a/scribo/text/recognition.hh
+++ b/scribo/text/recognition.hh
@@ -68,6 +68,8 @@
# include <tesseract/baseapi.h>
+#include <mln/labeling/colorize.hh>
+
namespace scribo
{
@@ -83,11 +85,9 @@ namespace scribo
/// Tesseract. (fra, en, ...)
/// \param[in] output_file If set, store the recognized text in
/// this file.
- ///
- /// \return An image of characters.
//
template <typename L>
- mln_ch_value(L,char)
+ void
recognition(const object_image(L)& objects,
const char *language,
const char *output_file);
@@ -98,7 +98,7 @@ namespace scribo
template <typename L>
- mln_ch_value(L,char)
+ void
recognition(const object_image(L)& objects,
const char *language,
const char *output_file)
@@ -110,9 +110,6 @@ namespace scribo
// Initialize Tesseract.
TessBaseAPI::InitWithLanguage(NULL, NULL, language, NULL, false, 0, NULL);
- mln_ch_value(L,char) txt(objects.domain());
- data::fill(txt, ' ');
-
typedef mln_ch_value(L,bool) I;
int vals[] = { 0, 9, 0, 9, 0,
9, 6, 4, 6, 9,
@@ -128,17 +125,31 @@ namespace scribo
/// Use text bboxes with Tesseract
for_all_ncomponents(i, objects.nlabels())
{
- I text_ima(objects.bbox(i));
- data::fill(text_ima, false);
- data::fill((text_ima | (pw::value(objects) == pw::cst(i))).rw(),
- true);
+ std::cout << "Text recognition... ("
+ << i << "/" << objects.nlabels() << ")"
<< std::endl;
+
+ mln_domain(I) box = objects.bbox(i);
+ // Make sure characters are isolated from the borders.
+ // Help Tesseract.
+ box.enlarge(2);
+ I text_ima(box);
+ data::fill(text_ima, true);
+
+ // Careful : background is set to 'False'
+ data::fill((text_ima | (pw::value(objects) == pw::cst(i))).rw(),
+ false);
/// Improve text quality.
/// text_ima_cleand domain is larger than text_ima's.
I text_ima_cleaned = text::clean(text_ima, dmap_win);
- border::resize(text_ima_cleaned, 0); // Make sure there is no border.
+
+ // Setting objects to 'True'
+ logical::not_inplace(text_ima_cleaned);
+
+ // Make sure there is no border.
+ border::resize(text_ima_cleaned, 0);
// Recognize characters.
char* s = TessBaseAPI::TesseractRect(
@@ -157,10 +168,9 @@ namespace scribo
- objects.bbox(i).pmin().col()) / 2;
if (s != 0)
{
- std::cout << s << std::endl;
+ std::cerr << s << std::endl;
if (output_file != 0)
file << s << std::endl;
- mln::debug::put_word(txt, p, s);
}
// The string has been allocated by Tesseract. We must free it.
@@ -171,7 +181,6 @@ namespace scribo
file.close();
trace::exiting("scribo::text::recognition");
- return txt;
}
--
1.5.6.5