Commit 4bf89fb7 authored by Guillaume Lazzara's avatar Guillaume Lazzara
Browse files

Add a new routine to highlight text areas in an image.

	* scribo/debug/highlight_text_area.hh: New.

	* scribo/src/debug/Makefile.am,
	* scribo/src/debug/highlight_text_area.cc: New tool.

	* scribo/src/text_in_picture.cc: Make use of this new routine.
parent a6a8d2a4
2010-06-15 Guillaume Lazzara <z@lrde.epita.fr>
Add a new routine to highlight text areas in an image.
* debug/highlight_text_area.hh: New.
* src/debug/Makefile.am,
* src/debug/highlight_text_area.cc: New tool.
* src/text_in_picture.cc: Make use of this new routine.
2010-06-03 Guillaume Lazzara <z@lrde.epita.fr> 2010-06-03 Guillaume Lazzara <z@lrde.epita.fr>
* src/README: New. * src/README: New.
......
// 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_DEBUG_HIGHLIGHT_TEXT_AREA_HH
# define SCRIBO_DEBUG_HIGHLIGHT_TEXT_AREA_HH
/// \file
///
/// Darken an image and highlight the text areas.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/function.hh>
# include <mln/draw/box.hh>
# include <mln/data/fill.hh>
# include <mln/data/transform.hh>
# include <mln/literal/colors.hh>
# include <mln/value/rgb8.hh>
# include <scribo/core/component_set.hh>
# include <scribo/core/line_set.hh>
namespace scribo
{
namespace debug
{
using namespace mln;
/*! \brief Darken an image and highlight valid lines.
\param[in] input An image.
\param[in] bbox An array of text area bounding boxes.
\return a color image with highlighted text areas.
*/
template <typename I>
mln_ch_value(I, value::rgb8)
highlight_text_area(const Image<I>& input_,
const mln::util::array<box<mln_site(I)> >& bbox);
/*! \brief Darken an image and highlight valid lines.
\param[in] input An image.
\param[in] lines A line set.
\return a color image with highlighted text areas.
*/
template <typename I, typename L>
mln_ch_value(I, value::rgb8)
highlight_text_area(const Image<I>& input_,
const line_set<L>& lines);
/*! \brief Darken an image and highlight valid lines.
This overload is useful if you do know that all the components
are text.
\param[in] input An image.
\param[in] components A component set.
\return a color image with highlighted text areas.
*/
template <typename I, typename L>
mln_ch_value(I, value::rgb8)
highlight_text_area(const Image<I>& input_,
const scribo::component_set<L>& components);
# ifndef MLN_INCLUDE_ONLY
namespace internal
{
template <typename M, typename R>
struct mask_non_text
: Function_v2v<mask_non_text<M, R> >,
private mlc_is(mln_value(M), bool)::check_t
{
typedef R result;
mask_non_text(const Image<M>& mask)
: mask_(exact(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;
}
M mask_;
mutable mln_pixter(M) p_;
};
} // end of namespace scribo::debug::internal
template <typename I>
mln_ch_value(I, value::rgb8)
highlight_text_area(const Image<I>& input_,
const mln::util::array<box<mln_site(I)> >& bbox)
{
trace::entering("scribo::debug::highlight_text_area");
const I& input = exact(input_);
mln_precondition(input.is_valid());
mlc_is(mln_value(I), value::rgb8)::check();
typedef mln_ch_value(I, bool) mask_t;
mask_t mask;
initialize(mask, input);
data::fill(mask, false);
for_all_elements(i, bbox)
data::fill((mask | bbox(i)).rw(), true);
internal::mask_non_text<mask_t, mln_value(I)> f(mask);
mln_concrete(I) output = data::transform(input, f);
for_all_elements(i, bbox)
mln::draw::box(output, bbox(i), literal::red);
trace::exiting("scribo::debug::highlight_text_area");
return output;
}
template <typename I, typename L>
mln_ch_value(I, value::rgb8)
highlight_text_area(const Image<I>& input_,
const line_set<L>& lines)
{
trace::entering("scribo::debug::highlight_text_area");
const I& input = exact(input_);
mln_precondition(input.is_valid());
mlc_is(mln_value(I), value::rgb8)::check();
typedef mln_ch_value(I, bool) mask_t;
mask_t mask;
initialize(mask, input);
data::fill(mask, false);
for_all_lines(i, lines)
{
if (! lines(i).is_valid()
|| lines(i).tag() != line::None
|| lines(i).type() != line::Text)
continue;
data::fill((mask | lines(i).bbox()).rw(), true);
}
internal::mask_non_text<mask_t, mln_value(I)> f(mask);
mln_concrete(I) output = data::transform(input, f);
for_all_lines(i, lines)
{
if (! lines(i).is_valid()
|| lines(i).tag() != line::None
|| lines(i).type() != line::Text)
continue;
mln::draw::box(output, lines(i).bbox(), literal::red);
}
trace::exiting("scribo::debug::highlight_text_area");
return output;
}
template <typename I, typename L>
mln_ch_value(I, value::rgb8)
highlight_text_area(const Image<I>& input_,
const scribo::component_set<L>& components)
{
trace::entering("scribo::debug::highlight_text_area");
const I& input = exact(input_);
mln_precondition(input.is_valid());
mlc_is(mln_value(I), value::rgb8)::check();
typedef mln_ch_value(I, bool) mask_t;
mask_t mask;
initialize(mask, input);
data::fill(mask, false);
for_all_comps(i, components)
if (components(i).is_valid())
data::fill((mask | components(i).bbox()).rw(), true);
internal::mask_non_text<mask_t, mln_value(I)> f(mask);
mln_ch_value(I, value::rgb8) output = data::transform(input, f);
for_all_comps(i, components)
if (components(i).is_valid())
mln::draw::box(output, components(i).bbox(), literal::red);
trace::exiting("scribo::debug::highlight_text_area");
return output;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo::debug
} // end of namespace scribo
#endif // ! SCRIBO_DEBUG_HIGHLIGHT_TEXT_AREA_HH
# 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. # This file is part of Olena.
# #
...@@ -74,3 +75,15 @@ show_objects_large_small_SOURCES = show_objects_large_small.cc ...@@ -74,3 +75,15 @@ show_objects_large_small_SOURCES = show_objects_large_small.cc
show_objects_small_SOURCES = show_objects_small.cc show_objects_small_SOURCES = show_objects_small.cc
show_objects_thick_SOURCES = show_objects_thick.cc show_objects_thick_SOURCES = show_objects_thick.cc
show_objects_thin_SOURCES = show_objects_thin.cc show_objects_thin_SOURCES = show_objects_thin.cc
if HAVE_MAGICKXX
bin_PROGRAMS += highlight_text_area
highlight_text_area_SOURCES = highlight_text_area.cc
highlight_text_area_CPPFLAGS = $(AM_CPPFLAGS) \
`Magick++-config --cppflags`
highlight_text_area_LDFLAGS = $(AM_LDFLAGS) \
-lpthread `Magick++-config --libs`
endif HAVE_MAGICKXX
\ No newline at end of file
// 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.
# include <iostream>
# include <fstream>
# include <mln/core/image/image2d.hh>
# include <mln/util/array.hh>
# include <mln/core/alias/box2d.hh>
# include <mln/make/box2d.hh>
# include <mln/io/ppm/save.hh>
# include <mln/io/magick/load.hh>
# include <mln/value/rgb8.hh>
# include <scribo/debug/highlight_text_area.hh>
# include <scribo/debug/usage.hh>
const char *args_desc[][2] =
{
{ "input.*", "An image." },
{ "ocr_text.txt", "OCR result which must contain text boxes coordinates." },
{ "output.ppm", "A color image with highlighted text areas." },
{0, 0}
};
int main(int argc, char *argv[])
{
using namespace mln;
if (argc != 4)
return scribo::debug::usage(argv,
"Highlight text areas in an image.",
"input.* ocr_text.txt output.ppm",
args_desc);
trace::entering("main");
image2d<value::rgb8> input;
io::magick::load(input, argv[1]);
mln::util::array<box2d> bbox;
std::ifstream file(argv[2]);
if (! file)
{
std::cerr << "error: file '" << argv[2]
<< "' not found!";
abort();
}
while (! file.eof())
{
int
pmin_row, pmin_col,
pmax_row, pmax_col;
file >> pmin_row;
file >> pmin_col;
file >> pmax_row;
file >> pmax_col;
std::string txt;
getline (file, txt);
bbox.append(mln::make::box2d(pmin_row, pmin_col, pmax_row, pmax_col));
}
io::ppm::save(scribo::debug::highlight_text_area(input, bbox), argv[3]);
trace::exiting("main");
}
...@@ -86,6 +86,8 @@ ...@@ -86,6 +86,8 @@
#include <scribo/filter/object_groups_small.hh> #include <scribo/filter/object_groups_small.hh>
#include <scribo/filter/object_groups_v_thickness.hh> #include <scribo/filter/object_groups_v_thickness.hh>
#include <scribo/debug/highlight_text_area.hh>
#include <scribo/debug/decision_image.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/save_linked_bboxes_image.hh>
...@@ -153,55 +155,6 @@ namespace mln ...@@ -153,55 +155,6 @@ 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> template <typename I, typename L>
mln_concrete(I) mln_concrete(I)
...@@ -684,7 +637,7 @@ Common usage: ./text_in_photo_fast input.ppm output.ppm 1 1 1 1 1", ...@@ -684,7 +637,7 @@ Common usage: ./text_in_photo_fast input.ppm output.ppm 1 1 1 1 1",
comps.nelements()), comps.nelements()),
argv[2]); argv[2]);
io::ppm::save(compute_highlight_image(input_rgb, comps), io::ppm::save(scribo::debug::highlight_text_area(input_rgb, comps),
out_base_dir + "_input_with_bboxes.ppm"); out_base_dir + "_input_with_bboxes.ppm");
io::ppm::save(compute_text_image(input_rgb, comps), io::ppm::save(compute_text_image(input_rgb, comps),
out_base_dir + "_out_text.ppm"); out_base_dir + "_out_text.ppm");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment