olena-2.0-96-ge5f272e Add Wolf's binarization algorithm.

* scribo/binarization/internal/wolf_formula.hh, * scribo/binarization/internal/wolf_functor.hh, * scribo/binarization/wolf.hh, * scribo/util/integral_sum_sum2_global_min_functor.hh, * src/binarization/wolf.cc, * tests/binarization/wolf.cc, * tests/binarization/wolf.ref.pbm, * tests/binarization/wolf_weven_hodd.ref.pbm, * tests/binarization/wolf_wodd_heven.ref.pbm, * tests/binarization/wolf_wodd_hodd.ref.pbm: New. * src/binarization/Makefile.am, * tests/binarization/Makefile.am: Add new target. --- scribo/ChangeLog | 18 ++ .../scribo/binarization/internal/wolf_formula.hh | 95 ++++++++++ .../scribo/binarization/internal/wolf_functor.hh | 176 +++++++++++++++++ scribo/scribo/binarization/wolf.hh | 197 ++++++++++++++++++++ .../util/integral_sum_sum2_global_min_functor.hh | 156 ++++++++++++++++ scribo/src/binarization/Makefile.am | 9 +- scribo/src/binarization/wolf.cc | 107 +++++++++++ scribo/tests/binarization/Makefile.am | 19 ++- scribo/tests/binarization/wolf.cc | 93 +++++++++ scribo/tests/binarization/wolf.ref.pbm | Bin 0 -> 32884 bytes scribo/tests/binarization/wolf_weven_hodd.ref.pbm | Bin 0 -> 32820 bytes scribo/tests/binarization/wolf_wodd_heven.ref.pbm | Bin 0 -> 32884 bytes scribo/tests/binarization/wolf_wodd_hodd.ref.pbm | Bin 0 -> 32820 bytes 13 files changed, 867 insertions(+), 3 deletions(-) create mode 100644 scribo/scribo/binarization/internal/wolf_formula.hh create mode 100644 scribo/scribo/binarization/internal/wolf_functor.hh create mode 100644 scribo/scribo/binarization/wolf.hh create mode 100644 scribo/scribo/util/integral_sum_sum2_global_min_functor.hh create mode 100644 scribo/src/binarization/wolf.cc create mode 100644 scribo/tests/binarization/wolf.cc create mode 100644 scribo/tests/binarization/wolf.ref.pbm create mode 100644 scribo/tests/binarization/wolf_weven_hodd.ref.pbm create mode 100644 scribo/tests/binarization/wolf_wodd_heven.ref.pbm create mode 100644 scribo/tests/binarization/wolf_wodd_hodd.ref.pbm diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 9604def..ff7d1fa 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,23 @@ 2012-08-23 Guillaume Lazzara <z@lrde.epita.fr> + Add Wolf's binarization algorithm. + + * scribo/binarization/internal/wolf_formula.hh, + * scribo/binarization/internal/wolf_functor.hh, + * scribo/binarization/wolf.hh, + * scribo/util/integral_sum_sum2_global_min_functor.hh, + * src/binarization/wolf.cc, + * tests/binarization/wolf.cc, + * tests/binarization/wolf.ref.pbm, + * tests/binarization/wolf_weven_hodd.ref.pbm, + * tests/binarization/wolf_wodd_heven.ref.pbm, + * tests/binarization/wolf_wodd_hodd.ref.pbm: New. + + * src/binarization/Makefile.am, + * tests/binarization/Makefile.am: Add new target. + +2012-08-23 Guillaume Lazzara <z@lrde.epita.fr> + Add more debug. * scribo/binarization/internal/local_threshold_debug.hh, diff --git a/scribo/scribo/binarization/internal/wolf_formula.hh b/scribo/scribo/binarization/internal/wolf_formula.hh new file mode 100644 index 0000000..a3084a7 --- /dev/null +++ b/scribo/scribo/binarization/internal/wolf_formula.hh @@ -0,0 +1,95 @@ +// Copyright (C) 2012 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_BINARIZATION_INTERNAL_WOLF_FORMULA_HH +# define SCRIBO_BINARIZATION_INTERNAL_WOLF_FORMULA_HH + + +/// \file +/// +/// \brief Routines computing a threshold using Wolf's binarization +/// formula. + + +// Setup default Wolf's formula parameters values. +// These macros may be used in other variant of Wolf's algorithms. +// +// Values are set according to the following reference: <FIXME> + +# define SCRIBO_DEFAULT_WOLF_K 0.34 + + +#include <mln/core/alias/point2d.hh> + +namespace scribo +{ + + namespace binarization + { + + namespace internal + { + + using namespace mln; + + template <typename V> + struct wolf_formula + { + + /*! \brief Compute a threshold using Wolf's formula. + + \todo doc! + + \return A threshold. + */ + double operator()(const double m_x_y, const double s_x_y, + const double K, const double global_max_stddev, + const V& global_min) const; + + }; + + +# ifndef MLN_INCLUDE_ONLY + + + template <typename V> + inline + double + wolf_formula<V>::operator()(const double m_x_y, const double s_x_y, + const double K, const double global_max_stddev, + const V& global_min) const + { + return m_x_y - K * (1 - s_x_y / global_max_stddev) * (m_x_y - global_min); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::binarization::internal + + } // end of namespace scribo::binarization + +} // end of namespace scribo + +#endif // ! SCRIBO_BINARIZATION_INTERNAL_WOLF_FORMULA_HH diff --git a/scribo/scribo/binarization/internal/wolf_functor.hh b/scribo/scribo/binarization/internal/wolf_functor.hh new file mode 100644 index 0000000..d394c21 --- /dev/null +++ b/scribo/scribo/binarization/internal/wolf_functor.hh @@ -0,0 +1,176 @@ +// Copyright (C) 2012 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_BINARIZATION_INTERNAL_WOLF_FUNCTOR_HH +# define SCRIBO_BINARIZATION_INTERNAL_WOLF_FUNCTOR_HH + +/// \file +/// +/// + +# include <mln/core/image/image2d.hh> +# include <mln/core/alias/neighb2d.hh> +# include <mln/extension/fill.hh> + +# include <scribo/binarization/internal/wolf_formula.hh> + +# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG +# include <scribo/binarization/internal/local_threshold_debug.hh> +# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG + + +namespace scribo +{ + + namespace binarization + { + + namespace internal + { + + using namespace mln; + + + template <typename I> + struct wolf_functor + { + typedef mln_value(I) V; + + wolf_functor(const Image<I>& input, double K, + const mln_value(I)& global_min, + double global_max_stddev); + + // Run every 4 pixels. + void exec(double mean, double stddev); + + void end_of_row(int); + + void finalize(); + + + const I input; + mln_ch_value(I,bool) output; + + const mln_value(I)* pi; + bool* po; + + double K_; + + V global_min_; + double global_max_stddev_; + + scribo::binarization::internal::wolf_formula<V> formula_; + + int step_; + unsigned next_line3; + unsigned offset1; + unsigned offset2; + }; + +#ifndef MLN_INCLUDE_ONLY + + template <typename I> + wolf_functor<I>::wolf_functor(const Image<I>& input_, + double K, + const mln_value(I)& global_min, + double global_max_stddev) + : input(exact(input_)), + pi(&input(input.domain().pmin())), + K_(K), + global_min_(global_min), + global_max_stddev_(global_max_stddev) + { + step_ = 3; + + // Since we iterate from a smaller image in the largest ones + // and image at scale 1 does not always have a size which can + // be divided by 3, some sites in the border may not be + // processed and we must skip them. + int more_offset = - (3 - input.ncols() % 3); + if (more_offset == - 3) + more_offset = 0; // No offset needed. + + next_line3 = input.delta_index(dpoint2d(+2,0)) + + 2 * input.border() + more_offset; + + offset1 = input.delta_index(dpoint2d(+1,0)); + offset2 = input.delta_index(dpoint2d(+2,0)); + + initialize(output, input); + po = &output(output.domain().pmin()); + } + + template <typename I> + void + wolf_functor<I>::exec(double mean, double stddev) + { + double th = formula_(mean, stddev, K_, + global_max_stddev_, global_min_); + + for (int i = 0; i < step_; ++i, ++po, ++pi) + { + *po = (*pi <= th); + *(po + offset1) = (*(pi + offset1) <= th); + *(po + offset2) = (*(pi + offset2) <= th); + } + +# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG + // Store local mean + unsigned index = pi - input.buffer(); + + debug_mean.element(index) = mean * mean_debug_factor; + debug_stddev.element(index) = stddev * stddev_debug_factor; + debug_threshold.element(index) = th; + + double alpha = K_ * (1 - stddev / R_); + debug_alpham.element(index) = alpha * mean * alpham_debug_factor; + debug_alphacond.element(index) = (stddev < (alpha * mean / 2.)); +# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG + + } + + template <typename I> + void + wolf_functor<I>::end_of_row(int) + { + po += next_line3; + pi += next_line3; + } + + template <typename I> + void + wolf_functor<I>::finalize() + { + } + +#endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::binarization::internal + + } // end of namespace scribo::binarization + +} // end of namespace scribo + +#endif // SCRIBO_BINARIZATION_INTERNAL_WOLF_FUNCTOR_HH diff --git a/scribo/scribo/binarization/wolf.hh b/scribo/scribo/binarization/wolf.hh new file mode 100644 index 0000000..25b4531 --- /dev/null +++ b/scribo/scribo/binarization/wolf.hh @@ -0,0 +1,197 @@ +// Copyright (C) 2012 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_BINARIZATION_WOLF_HH +# define SCRIBO_BINARIZATION_WOLF_HH + +/// \file +/// +/// + +# include <mln/core/concept/image.hh> +# include <scribo/binarization/internal/wolf_functor.hh> +# include <scribo/binarization/internal/local_threshold_core.hh> +# include <scribo/util/integral_sum_sum2_global_min_functor.hh> + +namespace scribo +{ + + namespace binarization + { + + using namespace mln; + + + /*! \brief Convert an image into a binary image. + + \input[in] input An image. + \input[in] window_size The window size. + \input[in] K Wolf's formulae constant. + + \return A binary image. + + This implementation is based on article "Text Localization, + Enhancement and Binarization in Multimedia Documents", Christian + Wolf, Jean-Michel Jolion, Françoise Chassaing, ICPR 2002. + + */ + template <typename I> + mln_ch_value(I, bool) + wolf(const Image<I>& input, unsigned window_size, double K); + + + + /*! \brief Convert an image into a binary image. + + Wolf's formulae constant K is set to 0.34. + + \input[in] input An image. + \input[in] window_size The window size. + + \return A binary image. + + */ + template <typename I> + mln_ch_value(I, bool) + wolf(const Image<I>& input, unsigned window_size); + + + /// \overload + /// The window size is set to 11. + // + template <typename I> + mln_ch_value(I, bool) + wolf(const Image<I>& input); + + +# ifndef MLN_INCLUDE_ONLY + + namespace internal + { + + template <typename I> + struct global_max_stddev + { + global_max_stddev() + : max_stddev(0) + { + } + + // Run every 4 pixels. + void exec(double mean, double stddev) + { + (void) mean; + if (max_stddev < stddev) + max_stddev = stddev; + } + + void end_of_row(int) + { + } + + void finalize() + { + } + + double max_stddev; + }; + + } // end of namespace scribo::binarization::internal + + + // Facades + + template <typename I> + mln_ch_value(I, bool) + wolf(const Image<I>& input, unsigned window_size, double K) + { + trace::entering("scribo::binarization::wolf"); + + mln_precondition(exact(input).is_valid()); + + + // Make sure the image sizes are a multiple of 3 in each + // dimension. (browsing while binarizing relies on that + // property). + mln::util::array<mln::util::couple<box2d, unsigned> > + sub_domains = scribo::util::compute_sub_domains(input, 1, 3); + + border::adjust(input, sub_domains(1).second()); + border::mirror(input); + + scribo::util::integral_sum_sum2_global_min_functor<value::int_u8, double> fi; + image2d<mln::util::couple<double,double> > + integral = scribo::util::init_integral_image(input, 3, fi, + sub_domains[2].first(), + sub_domains[2].second()); + + window_size /= 3; + if (window_size % 2) + window_size += 2; + else + window_size += 1; + + + // Compute max(stddev) of all windows. + internal::global_max_stddev<I> f_max_stddev; + scribo::canvas::integral_browsing(integral, 1, window_size, + window_size, 3, f_max_stddev); + + // Binarize ! + internal::wolf_functor<I> + f(input, K, fi.global_min(), f_max_stddev.max_stddev); + scribo::canvas::integral_browsing(integral, 1, window_size, + window_size, 3, f); + + trace::exiting("scribo::binarization::wolf"); + return f.output; + } + + + template <typename I> + mln_ch_value(I, bool) + wolf(const Image<I>& input, unsigned window_size) + { + return wolf(input, window_size, SCRIBO_DEFAULT_WOLF_K); + } + + + template <typename I> + mln_ch_value(I, bool) + wolf(const Image<I>& input) + { + return wolf(input, 11); + } + + +# endif // ! MLN_INCLUDE_ONLY + + + } // end of namespace scribo::binarization + +} // end of namespace scribo + + +#endif // ! SCRIBO_BINARIZATION_WOLF_HH diff --git a/scribo/scribo/util/integral_sum_sum2_global_min_functor.hh b/scribo/scribo/util/integral_sum_sum2_global_min_functor.hh new file mode 100644 index 0000000..20a61c0 --- /dev/null +++ b/scribo/scribo/util/integral_sum_sum2_global_min_functor.hh @@ -0,0 +1,156 @@ +// Copyright (C) 2012 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_UTIL_INTEGRAL_SUM_SUM2_GLOBAL_MIN_FUNCTOR_HH +# define SCRIBO_UTIL_INTEGRAL_SUM_SUM2_GLOBAL_MIN_FUNCTOR_HH + +/// \file +/// +/// + +# include <mln/util/couple.hh> + +namespace scribo +{ + + namespace util + { + + template <typename V, typename S = mln_sum(V)> + class integral_sum_sum2_global_min_functor + { + public: + typedef mln::util::couple<S, S> result; + + void begin_of_first_row(); + void begin_of_row(); + void end_of_row(); + + void begin_of_col(); + void end_of_col(); + + + void take(const V& v); + + result to_result_first_row() const; + result to_result(const result& up_result) const; + + const V& global_min() const; + + private: + S h_sum_; + S h_sum_2_; + + V global_min_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename V, typename S> + inline + void + integral_sum_sum2_global_min_functor<V,S>::begin_of_first_row() + { + h_sum_ = 0; + h_sum_2_ = 0; + global_min_ = 0; + } + + template <typename V, typename S> + inline + void + integral_sum_sum2_global_min_functor<V,S>::begin_of_row() + { + h_sum_ = 0; + h_sum_2_ = 0; + } + + template <typename V, typename S> + inline + void + integral_sum_sum2_global_min_functor<V,S>::take(const V& v) + { + if (global_min_ > v) + global_min_ = v; + + h_sum_ += v; + h_sum_2_ += v * v; + } + + template <typename V, typename S> + inline + typename integral_sum_sum2_global_min_functor<V,S>::result + integral_sum_sum2_global_min_functor<V,S>::to_result_first_row() const + { + return result(h_sum_, h_sum_2_); + } + + template <typename V, typename S> + inline + typename integral_sum_sum2_global_min_functor<V,S>::result + integral_sum_sum2_global_min_functor<V,S>::to_result(const result& up_result) const + { + return result(h_sum_ + up_result.first(), + h_sum_2_ + up_result.second()); + } + + template <typename V, typename S> + inline + const V& + integral_sum_sum2_global_min_functor<V,S>::global_min() const + { + return global_min_; + } + + template <typename V, typename S> + inline + void + integral_sum_sum2_global_min_functor<V,S>::begin_of_col() + { + } + + template <typename V, typename S> + inline + void + integral_sum_sum2_global_min_functor<V,S>::end_of_col() + { + } + + + template <typename V, typename S> + inline + void + integral_sum_sum2_global_min_functor<V,S>::end_of_row() + { + } + +#endif // ! MLN_INCLUDE_ONLY + + } // end of namespace scribo::util + +} // end of namespace scribo + +#endif // ! SCRIBO_UTIL_INTEGRAL_SUM_SUM2_GLOBAL_MIN_FUNCTOR_HH diff --git a/scribo/src/binarization/Makefile.am b/scribo/src/binarization/Makefile.am index a0a4378..68b83dc 100644 --- a/scribo/src/binarization/Makefile.am +++ b/scribo/src/binarization/Makefile.am @@ -35,7 +35,8 @@ if HAVE_MAGICKXX sauvola \ sauvola_ms \ sauvola_ms_fg \ - sauvola_ms_split + sauvola_ms_split \ + wolf global_threshold_SOURCES = global_threshold.cc @@ -70,6 +71,12 @@ if HAVE_MAGICKXX sauvola_LDFLAGS = $(AM_LDFLAGS) \ $(MAGICKXX_LDFLAGS) + wolf_SOURCES = wolf.cc + wolf_CPPFLAGS = $(AM_CPPFLAGS) \ + $(MAGICKXX_CPPFLAGS) + wolf_LDFLAGS = $(AM_LDFLAGS) \ + $(MAGICKXX_LDFLAGS) + sauvola_debug_SOURCES = sauvola_debug.cc sauvola_debug_CPPFLAGS = $(AM_CPPFLAGS) \ -DSCRIBO_LOCAL_THRESHOLD_DEBUG \ diff --git a/scribo/src/binarization/wolf.cc b/scribo/src/binarization/wolf.cc new file mode 100644 index 0000000..c481e09 --- /dev/null +++ b/scribo/src/binarization/wolf.cc @@ -0,0 +1,107 @@ +// Copyright (C) 2009, 2010, 2011 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/image/image2d.hh> +#include <mln/value/int_u8.hh> +#include <mln/io/magick/load.hh> +#include <mln/io/pbm/save.hh> +#include <mln/data/transform.hh> +#include <mln/fun/v2v/rgb_to_luma.hh> + +#include <scribo/binarization/wolf.hh> +#include <scribo/debug/option_parser.hh> +#include <scribo/debug/logger.hh> + +static const scribo::debug::arg_data arg_desc[] = +{ + { "input.*", "An image." }, + { "output.pbm", "A binary image." }, + {0, 0} +}; + + +// --enable/disable-<name> +static const scribo::debug::toggle_data toggle_desc[] = +{ + // name, description, default value + {0, 0, false} +}; + + +// --<name> <args> +static const scribo::debug::opt_data opt_desc[] = +{ + // name, description, arguments, check args function, number of args, default arg + { "debug-prefix", "Enable debug image outputs. Prefix image name with that " + "given prefix.", "<prefix>", 0, 1, 0 }, + { "k", "Wolf's formulae parameter", "<value>", 0, 1, "0.34" }, + { "verbose", "Enable verbose mode", 0, 0, 0, 0 }, + { "win-size", "Window size", "<size>", 0, 1, "101" }, + {0, 0, 0, 0, 0, 0} +}; + + + +int main(int argc, char *argv[]) +{ + using namespace mln; + + scribo::debug::option_parser options(arg_desc, toggle_desc, opt_desc); + + if (!options.parse(argc, argv)) + return 1; + + // Enable debug output. + if (options.is_set("debug-prefix")) + { + scribo::debug::logger().set_filename_prefix(options.opt_value("debug-prefix").c_str()); + scribo::debug::logger().set_level(scribo::debug::All); + } + + Magick::InitializeMagick(*argv); + + trace::entering("main"); + + bool verbose = options.is_set("verbose"); + unsigned w = atoi(options.opt_value("win-size").c_str()); + double k = atof(options.opt_value("k").c_str()); + + if (verbose) + std::cout << "Using w=" << w << " and k=" << k << std::endl; + + image2d<value::rgb8> input; + io::magick::load(input, options.arg("input.*")); + + // Convert to Gray level image. + image2d<value::int_u8> + input_1_gl = data::transform(input, mln::fun::v2v::rgb_to_luma<value::int_u8>()); + + image2d<bool> out = scribo::binarization::wolf(input_1_gl, w, k); + + io::pbm::save(out, options.arg("output.pbm")); + + trace::exiting("main"); +} diff --git a/scribo/tests/binarization/Makefile.am b/scribo/tests/binarization/Makefile.am index a2962bb..bac5a24 100644 --- a/scribo/tests/binarization/Makefile.am +++ b/scribo/tests/binarization/Makefile.am @@ -22,9 +22,22 @@ include $(top_srcdir)/scribo/tests/tests.mk EXTRA_DIST = \ niblack.res.pbm \ + niblack_wodd_heven.ref.pbm \ + niblack_weven_hodd.ref.pbm \ + niblack_wodd_hodd.ref.pbm \ sauvola_ms.ref.pbm \ + sauvola_ms_wodd_heven.ref.pbm \ + sauvola_ms_weven_hodd.ref.pbm \ + sauvola_ms_wodd_hodd.ref.pbm \ sauvola.ref.pbm \ - otsu.ref.pbm + sauvola_wodd_heven.ref.pbm \ + sauvola_weven_hodd.ref.pbm \ + sauvola_wodd_hodd.ref.pbm \ + otsu.ref.pbm \ + wolf.ref.pbm \ + wolf_wodd_heven.ref.pbm \ + wolf_weven_hodd.ref.pbm \ + wolf_wodd_hodd.ref.pbm check_PROGRAMS = \ global_threshold \ @@ -32,7 +45,8 @@ check_PROGRAMS = \ niblack \ otsu \ sauvola \ - sauvola_ms + sauvola_ms \ + wolf global_threshold_SOURCES = global_threshold.cc @@ -41,6 +55,7 @@ niblack_SOURCES = niblack.cc otsu_SOURCES = otsu.cc sauvola_SOURCES = sauvola.cc sauvola_ms_SOURCES = sauvola_ms.cc +wolf_SOURCES = wolf.cc TESTS = $(check_PROGRAMS) diff --git a/scribo/tests/binarization/wolf.cc b/scribo/tests/binarization/wolf.cc new file mode 100644 index 0000000..27d7cd2 --- /dev/null +++ b/scribo/tests/binarization/wolf.cc @@ -0,0 +1,93 @@ +// Copyright (C) 2012 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. + +/// \file + +#include <mln/core/image/image2d.hh> +#include <mln/data/compare.hh> +#include <mln/value/int_u8.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pbm/load.hh> + +#include <scribo/binarization/wolf.hh> + +#include "tests/data.hh" + +int main() +{ + using namespace mln; + + // even height and width + { + image2d<value::int_u8> input; + io::pgm::load(input, MILENA_IMG_DIR "/lena.pgm"); + + image2d<bool> bin = scribo::binarization::wolf(input, 101); + + image2d<bool> ref; + io::pbm::load(ref, SCRIBO_TESTS_DIR "binarization/wolf.ref.pbm"); + + mln_assertion(bin == ref); + } + + // even height and odd width + { + image2d<value::int_u8> input; + io::pgm::load(input, SCRIBO_IMG_DIR "/lena_wodd_heven.pgm"); + + image2d<bool> bin = scribo::binarization::wolf(input, 101); + + image2d<bool> ref; + io::pbm::load(ref, SCRIBO_TESTS_DIR "binarization/wolf_wodd_heven.ref.pbm"); + + mln_assertion(bin == ref); + } + + // odd height and even width + { + image2d<value::int_u8> input; + io::pgm::load(input, SCRIBO_IMG_DIR "/lena_weven_hodd.pgm"); + + image2d<bool> bin = scribo::binarization::wolf(input, 101); + + image2d<bool> ref; + io::pbm::load(ref, SCRIBO_TESTS_DIR "binarization/wolf_weven_hodd.ref.pbm"); + + mln_assertion(bin == ref); + } + + // odd height and width + { + image2d<value::int_u8> input; + io::pgm::load(input, SCRIBO_IMG_DIR "/lena_wodd_hodd.pgm"); + + image2d<bool> bin = scribo::binarization::wolf(input, 101); + + image2d<bool> ref; + io::pbm::load(ref, SCRIBO_TESTS_DIR "binarization/wolf_wodd_hodd.ref.pbm"); + + mln_assertion(bin == ref); + } +} diff --git a/scribo/tests/binarization/wolf.ref.pbm b/scribo/tests/binarization/wolf.ref.pbm new file mode 100644 index 0000000..9b8a367 Binary files /dev/null and b/scribo/tests/binarization/wolf.ref.pbm differ diff --git a/scribo/tests/binarization/wolf_weven_hodd.ref.pbm b/scribo/tests/binarization/wolf_weven_hodd.ref.pbm new file mode 100644 index 0000000..d2281ed Binary files /dev/null and b/scribo/tests/binarization/wolf_weven_hodd.ref.pbm differ diff --git a/scribo/tests/binarization/wolf_wodd_heven.ref.pbm b/scribo/tests/binarization/wolf_wodd_heven.ref.pbm new file mode 100644 index 0000000..c29fffa Binary files /dev/null and b/scribo/tests/binarization/wolf_wodd_heven.ref.pbm differ diff --git a/scribo/tests/binarization/wolf_wodd_hodd.ref.pbm b/scribo/tests/binarization/wolf_wodd_hodd.ref.pbm new file mode 100644 index 0000000..9dce37a Binary files /dev/null and b/scribo/tests/binarization/wolf_wodd_hodd.ref.pbm differ -- 1.7.2.5
participants (1)
-
Guillaume Lazzara