last-svn-commit-125-g21af64a Improve debug outputs in Sauvola and make binarization tools compile again.

* binarization/internal/first_pass_functor.hh, * binarization/sauvola_ms.hh, * binarization/sauvola_threshold_image.hh: Add debug outputs if SCRIBO_SAUVOLA_DEBUG flag is set. * binarization/sauvola_ms_split.hh: Remove lambda argument. * binarization/sauvola_threshold_image_debug.hh: Add the threshold image as debug output. * src/binarization/Makefile.am: Add sauvola_ms_debug. * src/binarization/sauvola_ms_debug.cc: New. * src/binarization/fg_sauvola_ms.cc, * src/binarization/pgm_sauvola_ms.cc, * src/binarization/ppm_fg_sauvola_ms.cc, * src/binarization/ppm_sauvola_ms.cc, * src/binarization/ppm_sauvola_ms_split.cc, * src/binarization/sauvola_debug.cc, * src/binarization/sauvola_ms.cc, * src/binarization/sauvola_ms_split.cc: Make compile again. --- scribo/ChangeLog | 27 +++++ scribo/binarization/internal/first_pass_functor.hh | 31 +++++- scribo/binarization/sauvola_ms.hh | 98 ++++++----------- scribo/binarization/sauvola_ms_split.hh | 23 ++-- scribo/binarization/sauvola_threshold_image.hh | 115 +++++++++++++++++++- .../binarization/sauvola_threshold_image_debug.hh | 29 ++++-- scribo/src/binarization/Makefile.am | 11 ++- scribo/src/binarization/fg_sauvola_ms.cc | 17 ++-- scribo/src/binarization/pgm_sauvola_ms.cc | 7 +- scribo/src/binarization/ppm_fg_sauvola_ms.cc | 16 ++- scribo/src/binarization/ppm_sauvola_ms.cc | 13 ++- scribo/src/binarization/ppm_sauvola_ms_split.cc | 8 +- scribo/src/binarization/sauvola_debug.cc | 19 +++- scribo/src/binarization/sauvola_ms.cc | 15 ++- .../{sauvola_ms.cc => sauvola_ms_debug.cc} | 38 ++++++- scribo/src/binarization/sauvola_ms_split.cc | 6 +- 16 files changed, 329 insertions(+), 144 deletions(-) copy scribo/src/binarization/{sauvola_ms.cc => sauvola_ms_debug.cc} (74%) diff --git a/scribo/ChangeLog b/scribo/ChangeLog index e44137e..76decb5 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,3 +1,30 @@ +2010-05-25 Guillaume Lazzara <z@lrde.epita.fr> + + Improve debug outputs in Sauvola and make binarization tools + compile again. + + * binarization/internal/first_pass_functor.hh, + * binarization/sauvola_ms.hh, + * binarization/sauvola_threshold_image.hh: Add debug outputs if + SCRIBO_SAUVOLA_DEBUG flag is set. + + * binarization/sauvola_ms_split.hh: Remove lambda argument. + + * binarization/sauvola_threshold_image_debug.hh: Add the threshold + image as debug output. + + * src/binarization/Makefile.am: Add sauvola_ms_debug. + * src/binarization/sauvola_ms_debug.cc: New. + + * src/binarization/fg_sauvola_ms.cc, + * src/binarization/pgm_sauvola_ms.cc, + * src/binarization/ppm_fg_sauvola_ms.cc, + * src/binarization/ppm_sauvola_ms.cc, + * src/binarization/ppm_sauvola_ms_split.cc, + * src/binarization/sauvola_debug.cc, + * src/binarization/sauvola_ms.cc, + * src/binarization/sauvola_ms_split.cc: Make compile again. + 2010-05-04 Guillaume Lazzara <z@lrde.epita.fr> Small fixes for Nuxeo/XWiki. diff --git a/scribo/binarization/internal/first_pass_functor.hh b/scribo/binarization/internal/first_pass_functor.hh index 3455060..4d47d94 100644 --- a/scribo/binarization/internal/first_pass_functor.hh +++ b/scribo/binarization/internal/first_pass_functor.hh @@ -42,6 +42,13 @@ namespace scribo namespace internal { +# ifdef SCRIBO_SAUVOLA_DEBUG + // Global debug images. + extern image2d<value::int_u8> debug_k; + extern image2d<float> debug_s_n; + extern image2d<float> debug_k_l; +# endif // ! SCRIBO_SAUVOLA_DEBUG + using namespace mln; @@ -81,6 +88,13 @@ namespace scribo initialize(t_sub, input); initialize(parent, input); initialize(msk, input); + +# ifdef SCRIBO_SAUVOLA_DEBUG + initialize(debug_k, input); + initialize(debug_s_n, input); + initialize(debug_k_l, input); +# endif // ! SCRIBO_SAUVOLA_DEBUG + extension::fill(msk, false); initialize(card, input); @@ -96,9 +110,20 @@ namespace scribo unsigned p = pxl.offset(); - value::int_u8 t_p = sauvola_threshold_formula(mean, stddev, - K_, - SCRIBO_DEFAULT_SAUVOLA_R); +# ifdef SCRIBO_SAUVOLA_DEBUG + value::int_u8 + t_p = sauvola_threshold_formula(mean, stddev, + K_, + SCRIBO_DEFAULT_SAUVOLA_R, + debug_k.element(p), + debug_s_n.element(p), + debug_k_l.element(p)); +# else + value::int_u8 + t_p = sauvola_threshold_formula(mean, stddev, + K_, + SCRIBO_DEFAULT_SAUVOLA_R); +# endif // SCRIBO_SAUVOLA_DEBUG msk.element(p) = input.element(p) < t_p; diff --git a/scribo/binarization/sauvola_ms.hh b/scribo/binarization/sauvola_ms.hh index 621c638..0390180 100644 --- a/scribo/binarization/sauvola_ms.hh +++ b/scribo/binarization/sauvola_ms.hh @@ -54,9 +54,6 @@ # include <mln/extension/adjust.hh> -// FIXME: to be removed later... -# include <mln/io/pgm/save.hh> - # include <scribo/subsampling/integral_single_image.hh> # include <scribo/core/macros.hh> @@ -66,6 +63,14 @@ # include <scribo/canvas/integral_browsing.hh> +# ifdef SCRIBO_SAUVOLA_DEBUG +# include <mln/io/pgm/save.hh> +# include <mln/data/saturate.hh> +# include <mln/data/convert.hh> +# include <mln/arith/times.hh> +# endif // ! SCRIBO_SAUVOLA_DEBUG + + namespace scribo { @@ -116,9 +121,12 @@ namespace scribo using namespace mln; - // FIXME: to be removed later... +# ifdef SCRIBO_SAUVOLA_DEBUG char* scale_image_output = 0; - + char* k_image_output = 0; + char* s_n_image_output = 0; + char* k_l_image_output = 0; +# endif // ! SCRIBO_SAUVOLA_DEBUG template <typename V> V my_find_root(image2d<V>& parent, const V& x) @@ -906,9 +914,10 @@ namespace scribo // Propagate scale values. e_2 = transform::influence_zone_geodesic(e_2, c8()); - // FIXME: Remove or make it better... +# ifdef SCRIBO_SAUVOLA_DEBUG if (internal::scale_image_output) io::pgm::save(e_2, internal::scale_image_output); +# endif // ! SCRIBO_SAUVOLA_DEBUG // Binarize image2d<bool> @@ -921,67 +930,9 @@ namespace scribo } // end of namespace scribo::binarization::impl::generic - template <typename I> - mln_ch_value(I,bool) - sauvola_ms_rgb8(const Image<I>& input_1_, unsigned w_1, - unsigned s, double K) - { - const I& input_1 = exact(input_1_); - - mln_ch_value(I, value::int_u8) gima; - gima = data::transform(input_1, mln::fun::v2v::rgb_to_int_u<8>()); - - mln_ch_value(I, bool) - output = generic::sauvola_ms(gima, w_1, s, K); - - return output; - } - - } // end of namespace scribo::binarization::impl - - // Dispatch - - namespace internal - { - - template <typename I> - mln_ch_value(I,bool) - sauvola_ms_dispatch(const mln_value(I)&, - const Image<I>& input_1, unsigned w_1, - unsigned s, double K) - { - return impl::generic::sauvola_ms(input_1, w_1, s, K); - } - - - - template <typename I> - mln_ch_value(I,bool) - sauvola_ms_dispatch(const value::rgb8&, - const Image<I>& input_1, unsigned w_1, - unsigned s, double K) - { - return impl::sauvola_ms_rgb8(input_1, w_1, s, K); - } - - - template <typename I> - mln_ch_value(I,bool) - sauvola_ms_dispatch(const Image<I>& input_1, unsigned w_1, - unsigned s, double K) - { - typedef mln_value(I) V; - return sauvola_ms_dispatch(V(), input_1, w_1, s, K); - } - - - } // end of namespace scribo::binarization::internal - - - // Facade template <typename I> @@ -992,9 +943,26 @@ namespace scribo trace::entering("scribo::binarization::sauvola_ms"); mln_precondition(exact(input_1_).is_valid()); + // Gray level images ONLY. + mlc_is_not_a(mln_value(I), value::Vectorial)::check(); + mlc_is_not(mln_value(I), bool)::check(); mln_ch_value(I,bool) - output = internal::sauvola_ms_dispatch(input_1_, w_1, s, K); + output = impl::generic::sauvola_ms(exact(input_1_), w_1, s, K); + + +# ifdef SCRIBO_SAUVOLA_DEBUG + if (internal::k_image_output) + io::pgm::save(internal::debug_k, internal::k_image_output); + + if (internal::s_n_image_output) + io::pgm::save(data::saturate(value::int_u8(), internal::debug_s_n * 100), + internal::s_n_image_output); + if (internal::k_l_image_output) + io::pgm::save(data::saturate(value::int_u8(), internal::debug_k_l * 10), + internal::k_l_image_output); +# endif // ! SCRIBO_SAUVOLA_DEBUG + trace::exiting("scribo::binarization::sauvola_ms"); return output; diff --git a/scribo/binarization/sauvola_ms_split.hh b/scribo/binarization/sauvola_ms_split.hh index de8517c..ac06a39 100644 --- a/scribo/binarization/sauvola_ms_split.hh +++ b/scribo/binarization/sauvola_ms_split.hh @@ -54,24 +54,23 @@ namespace scribo /*! \brief Binarize a color image merging the binarization of each component using Sauvola's algorithm. - \param[in] input_1 A grayscale or a color image. + \param[in] input_1 A color image. \param[in] w_1 The window size used to compute stats. \param[in] s The scale factor used for the first subscaling. - \param[in] lambda_min_1 Size of the objects kept at scale 1. \param[in] min_ntrue A site is set to 'True' in the output if it is set to 'True' at least \p min_ntrue components. Possible values: 1, 2, 3. \param[in] K Sauvola's formula parameter. - \p w_1 and \p lambda_min_1 are expressed according to the image - at scale 0, i.e. the original size. + \p w_1 is expressed according to the image at scale 0, i.e. the + original size. \return A Boolean image. */ template <typename I> mln_ch_value(I, bool) sauvola_ms_split(const Image<I>& input_1_, unsigned w_1, - unsigned s, unsigned lambda_min_1, unsigned min_ntrue, + unsigned s, unsigned min_ntrue, double K); @@ -80,7 +79,7 @@ namespace scribo template <typename I> mln_ch_value(I, bool) sauvola_ms_split(const Image<I>& input_1_, unsigned w_1, - unsigned s, unsigned lambda_min_1, unsigned min_ntrue); + unsigned s, unsigned min_ntrue); @@ -90,7 +89,7 @@ namespace scribo template <typename I> mln_ch_value(I, bool) sauvola_ms_split(const Image<I>& input_1_, unsigned w_1, - unsigned s, unsigned lambda_min_1, unsigned min_ntrue, + unsigned s, unsigned min_ntrue, double K) { trace::entering("scribo::binarization::sauvola_ms_split"); @@ -109,9 +108,9 @@ namespace scribo bin_t r_b, g_b, b_b; - r_b = impl::generic::sauvola_ms(r_i, w_1, s, lambda_min_1, K); - g_b = impl::generic::sauvola_ms(g_i, w_1, s, lambda_min_1, K); - b_b = impl::generic::sauvola_ms(b_i, w_1, s, lambda_min_1, K); + r_b = impl::generic::sauvola_ms(r_i, w_1, s, K); + g_b = impl::generic::sauvola_ms(g_i, w_1, s, K); + b_b = impl::generic::sauvola_ms(b_i, w_1, s, K); border::resize(r_b, input_1.border()); border::resize(g_b, input_1.border()); @@ -153,9 +152,9 @@ namespace scribo template <typename I> mln_ch_value(I, bool) sauvola_ms_split(const Image<I>& input_1, unsigned w_1, - unsigned s, unsigned lambda_min_1, unsigned min_ntrue) + unsigned s, unsigned min_ntrue) { - return sauvola_ms_split(input_1, w_1, s, lambda_min_1, min_ntrue, + return sauvola_ms_split(input_1, w_1, s, min_ntrue, SCRIBO_DEFAULT_SAUVOLA_K); } diff --git a/scribo/binarization/sauvola_threshold_image.hh b/scribo/binarization/sauvola_threshold_image.hh index 88b3842..c45fc98 100644 --- a/scribo/binarization/sauvola_threshold_image.hh +++ b/scribo/binarization/sauvola_threshold_image.hh @@ -119,6 +119,15 @@ namespace scribo namespace internal { +# ifdef SCRIBO_SAUVOLA_DEBUG + // Declare debug images. + image2d<value::int_u8> debug_k; + image2d<float> debug_s_n; + image2d<float> debug_k_l; +# endif // ! SCRIBO_SAUVOLA_DEBUG + + + /*! \brief compute Sauvola's threshold applying directly the formula. \param[in] m_x_y Mean value. @@ -131,12 +140,96 @@ namespace scribo \return A threshold. */ +# ifdef SCRIBO_SAUVOLA_DEBUG + inline + double + sauvola_threshold_formula(const double m_x_y, const double s_x_y, + const double K, const double R, + value::int_u8& dbg_k, float& dbg_s_n, + float& dbg_k_l) +# else inline double sauvola_threshold_formula(const double m_x_y, const double s_x_y, const double K, const double R) +# endif // ! SCRIBO_SAUVOLA_DEBUG { - return m_x_y * (1.0 + K * ((s_x_y / R) - 1.0)); +// double s_N = s_x_y / 256; + double K_2 = K; +// double K_2 = exp(K * log(s_x_y / 256)); +// if (s_x_y < 30) +// K_2 = 0.01; +// else if (s_x_y < 80) +// K_2 = 0.1; +// else if (s_x_y > 80) +// K_2 = K; + + +// Results_0.1_0.34 +// +// if (s_N < 0.1f) +// { +// K_2 = 0.1f; +// dbg_k = 0; +// dbg_s_n = s_N; +// } +// else if (s_N > 0.34) +// { +// K_2 = 0.34; +// dbg_k = 255; +// dbg_s_n = s_N; +// } +// else +// { +// K_2 = s_N; +// dbg_k = 150; +// dbg_s_n = s_N; +// } + + +// const double k_min = 0.1f; +// const double k_max = 1.0f; +// const double s_1 = 0.05f; +// const double s_2 = 0.50f; + +// double k_b = (k_max - k_min) / (double)(s_2 - s_1); +// double k_a = 0.1f - s_1 * k_b; +// K_2 = k_a + k_b * s_N; + +// dbg_s_n = s_N; +// if (K_2 < k_min) +// dbg_k = 0; +// else if (K_2 > k_max) +// dbg_k = 255; +// else +// dbg_k = 150; + + + +// if (s_N < 0.1f) +// { +// K_2 = 0.1f; +// dbg_k = 0; +// dbg_s_n = s_N; +// dbg_k_l = 0.1; +// } +// else +// { +// // double K_L = ((long int)((s_N * 11) + 0.49999)) * s_N; +// double K_L = s_N * K / 3.0f; +// // K_2 = std::min(K_L, (double) 1.0); +// K_2 = K_L; +// if (K_L > 1.0f) +// dbg_k = 255; +// else +// dbg_k = 150; + +// dbg_s_n = s_N; +// dbg_k_l = K_L; +// } + + + return m_x_y * (1.0 + K_2 * ((s_x_y / R) - 1.0)); } @@ -146,9 +239,15 @@ namespace scribo double sauvola_threshold_formula(double m_x_y, double s_x_y) { - return sauvola_threshold_formula(m_x_y, s_x_y, - SCRIBO_DEFAULT_SAUVOLA_K, - SCRIBO_DEFAULT_SAUVOLA_R); +# ifdef SCRIBO_SAUVOLA_DEBUG +# warning "This overload of sauvola_threshold_formula is disabled in debug mode!" + std::cout << "This overload of sauvola_threshold_formula is disabled in debug mode!" << std::endl; + return 0; +# else + return sauvola_threshold_formula(m_x_y, s_x_y, + SCRIBO_DEFAULT_SAUVOLA_K, + SCRIBO_DEFAULT_SAUVOLA_R); +# endif // !SCRIBO_SAUVOLA_DEBUG } @@ -208,7 +307,11 @@ namespace scribo double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f)); // Thresholding. +# ifdef SCRIBO_SAUVOLA_DEBUG + double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R, debug_k(p), debug_s_n(p), debug_k_l(p)); +# else double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R); +# endif // ! SCRIBO_SAUVOLA_DEBUG return t_x_y; } @@ -252,7 +355,11 @@ namespace scribo double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f)); // Thresholding. +# ifdef SCRIBO_SAUVOLA_DEBUG + double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R, debug_k(p), debug_s_n(p), debug_k_l(p)); +# else double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R); +# endif // !SCRIBO_SAUVOLA_DEBUG return t_x_y; } diff --git a/scribo/binarization/sauvola_threshold_image_debug.hh b/scribo/binarization/sauvola_threshold_image_debug.hh index 359bb57..a507920 100644 --- a/scribo/binarization/sauvola_threshold_image_debug.hh +++ b/scribo/binarization/sauvola_threshold_image_debug.hh @@ -126,7 +126,7 @@ namespace scribo template <typename P, typename M, typename J> double compute_sauvola_threshold(const P& p, - M& mean, M& stddev, + M& mean, M& stddev, M& thres, const J& simple, const J& squared, int win_width, double K, double R) @@ -171,6 +171,8 @@ namespace scribo // Thresholding. double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R); + thres(p) = t_x_y; + return t_x_y; } @@ -205,6 +207,7 @@ namespace scribo unsigned window_size, double K, Image<M>& mean_, Image<M>& stddev_, + Image<M>& thres_, Image<J>& simple_, Image<J>& squared_) { @@ -213,6 +216,7 @@ namespace scribo const I& input = exact(input_); M& mean = exact(mean_); M& stddev = exact(stddev_); + M& thres = exact(thres_); J& simple = exact(simple_); J& squared = exact(squared_); @@ -235,7 +239,7 @@ namespace scribo for(def::coord col = 0; col < ncols; ++col) output.at_(row, col) = internal::compute_sauvola_threshold(P(row, col), - mean, stddev, + mean, stddev, thres, simple, squared, window_size, K, SCRIBO_DEFAULT_SAUVOLA_R); @@ -255,12 +259,13 @@ namespace scribo unsigned window_size, double K, Image<M>& mean, Image<M>& stddev, + Image<M>& thres, Image<J>& simple, Image<J>& squared) { return impl::generic::sauvola_threshold_image_debug(input, window_size, K, - mean, stddev, + mean, stddev, thres, simple, squared); } @@ -272,6 +277,7 @@ namespace scribo unsigned window_size, double K, Image<M>& mean, Image<M>& stddev, + Image<M>& thres, Image<J>& simple, Image<J>& squared) { @@ -284,7 +290,7 @@ namespace scribo mln_ch_value(I, value::int_u8) output = impl::generic::sauvola_threshold_image_debug(gima, window_size, K, - mean, stddev, + mean, stddev, thres, simple, squared); trace::exiting("scribo::binarization::impl::sauvola_threshold_image_debug_rgb8"); @@ -309,12 +315,12 @@ namespace scribo const I& input, unsigned window_size, double K, - M& mean, M& stddev, + M& mean, M& stddev, M& thres, J& simple, J& squared) { return impl::sauvola_threshold_image_debug_gl(input, window_size, K, - mean, stddev, + mean, stddev, thres, simple, squared); } @@ -324,7 +330,7 @@ namespace scribo sauvola_threshold_image_debug_dispatch(const value::rgb8&, const I& input, unsigned window_size, double K, - M& mean, M& stddev, + M& mean, M& stddev, M& thres, J& simple, J& squared) { @@ -337,7 +343,7 @@ namespace scribo inline mln_ch_value(I, value::int_u8) sauvola_threshold_image_debug_dispatch(const mln_value(I)&, const I& input, - M& mean, M& stddev, + M& mean, M& stddev, M& thres, unsigned window_size, double K, J& simple, @@ -360,6 +366,7 @@ namespace scribo sauvola_threshold_image_debug(const Image<I>& input, unsigned window_size, double K, Image<M>& mean, Image<M>& stddev, + Image<M>& thres, Image<J>& simple, Image<J>& squared) { @@ -376,6 +383,7 @@ namespace scribo K, exact(mean), exact(stddev), + exact(thres), exact(simple), exact(squared)); @@ -389,14 +397,15 @@ namespace scribo mln_ch_value(I, value::int_u8) sauvola_threshold_image_debug(const Image<I>& input, unsigned window_size, double K, - Image<M>& mean, Image<M>& stddev) + Image<M>& mean, Image<M>& stddev, + Image<M>& thres) { mln_ch_value(I, double) simple = init_integral_image(input, scribo::internal::identity_), squared = init_integral_image(input, scribo::internal::square_); return sauvola_threshold_image_debug(input, window_size, K, - mean, stddev, + mean, stddev, thres, simple, squared); } diff --git a/scribo/src/binarization/Makefile.am b/scribo/src/binarization/Makefile.am index ccedd77..efc35dc 100644 --- a/scribo/src/binarization/Makefile.am +++ b/scribo/src/binarization/Makefile.am @@ -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. # @@ -43,7 +44,7 @@ if HAVE_MAGICKXX sauvola \ sauvola_debug \ sauvola_ms \ - sauvola_ms_static \ + sauvola_ms_debug \ sauvola_ms_split fg_sauvola_ms_SOURCES = fg_sauvola_ms.cc @@ -71,6 +72,12 @@ if HAVE_MAGICKXX sauvola_ms_LDFLAGS = $(AM_LDFLAGS) \ $(MAGICKXX_LDFLAGS) + sauvola_ms_debug_SOURCES = sauvola_ms_debug.cc + sauvola_ms_debug_CPPFLAGS = $(AM_CPPFLAGS) -DSCRIBO_SAUVOLA_DEBUG \ + $(MAGICKXX_CPPFLAGS) + sauvola_ms_debug_LDFLAGS = $(AM_LDFLAGS) \ + $(MAGICKXX_LDFLAGS) + sauvola_ms_split_SOURCES = sauvola_ms_split.cc sauvola_ms_split_CPPFLAGS = $(AM_CPPFLAGS) \ diff --git a/scribo/src/binarization/fg_sauvola_ms.cc b/scribo/src/binarization/fg_sauvola_ms.cc index 9c606d6..cad605f 100644 --- a/scribo/src/binarization/fg_sauvola_ms.cc +++ b/scribo/src/binarization/fg_sauvola_ms.cc @@ -35,7 +35,7 @@ bool check_args(int argc, char * argv[]) { - if (argc != 7) + if (argc != 6) return false; int s = atoi(argv[4]); @@ -58,7 +58,6 @@ const char *args_desc[][2] = { "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)" }, {0, 0} }; @@ -73,7 +72,7 @@ int main(int argc, char *argv[]) if (!check_args(argc, argv)) 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", + "input.* output.pbm w s", args_desc); trace::entering("main"); @@ -86,18 +85,22 @@ int main(int argc, char *argv[]) // First subsampling scale. unsigned s = atoi(argv[4]); - // Lambda value - unsigned lambda_min_1 = atoi(argv[5]); - + // Load image2d<value::rgb8> input_1; io::magick::load(input_1, argv[1]); + // Split foreground/background image2d<value::rgb8> fg = scribo::preprocessing::split_bg_fg(input_1, lambda, 32).first(); + // Convert to Gray level image. + image2d<value::int_u8> + fg_gl = data::transform(fg, mln::fun::v2v::rgb_to_int_u<8>()); + + // Binarize image2d<bool> - output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1, SCRIBO_DEFAULT_SAUVOLA_K); + output = scribo::binarization::sauvola_ms(fg_gl, w_1, s, SCRIBO_DEFAULT_SAUVOLA_K); io::pbm::save(output, argv[6]); } diff --git a/scribo/src/binarization/pgm_sauvola_ms.cc b/scribo/src/binarization/pgm_sauvola_ms.cc index fefdd6a..38ff2e6 100644 --- a/scribo/src/binarization/pgm_sauvola_ms.cc +++ b/scribo/src/binarization/pgm_sauvola_ms.cc @@ -93,10 +93,6 @@ int main(int argc, char *argv[]) else s = 3u; - // Lambda value - unsigned lambda_min_1 = 67; // FIXME: should be adapted to the - // window size. - double k; if (argc >= 6) k = atof(argv[5]); @@ -107,8 +103,7 @@ int main(int argc, char *argv[]) io::pgm::load(input_1, argv[1]); image2d<bool> - output = scribo::binarization::sauvola_ms(input_1, w_1, s, - lambda_min_1, k); + output = scribo::binarization::sauvola_ms(input_1, w_1, s, k); io::pbm::save(output, argv[2]); } diff --git a/scribo/src/binarization/ppm_fg_sauvola_ms.cc b/scribo/src/binarization/ppm_fg_sauvola_ms.cc index 65e8621..33a11ac 100644 --- a/scribo/src/binarization/ppm_fg_sauvola_ms.cc +++ b/scribo/src/binarization/ppm_fg_sauvola_ms.cc @@ -97,10 +97,6 @@ int main(int argc, char *argv[]) else s = 3u; - // Lambda value - unsigned lambda_min_1 = 67; // FIXME: should be adapted to the - // window size. - double k; if (argc >= 7) k = atof(argv[6]); @@ -108,15 +104,23 @@ int main(int argc, char *argv[]) k = 0.34f; - + // Load image2d<value::rgb8> input_1; io::ppm::load(input_1, argv[1]); + + // Split foreground/background image2d<value::rgb8> fg = scribo::preprocessing::split_bg_fg(input_1, lambda, 32).second(); + + // Convert to Gray level image. + image2d<value::int_u8> + fg_gl = data::transform(fg, mln::fun::v2v::rgb_to_int_u<8>()); + + // Binarize image2d<bool> - output = scribo::binarization::sauvola_ms(fg, w_1, s, lambda_min_1, k); + output = scribo::binarization::sauvola_ms(fg_gl, w_1, s, k); io::pbm::save(output, argv[2]); } diff --git a/scribo/src/binarization/ppm_sauvola_ms.cc b/scribo/src/binarization/ppm_sauvola_ms.cc index f2cbb6f..9e68b0e 100644 --- a/scribo/src/binarization/ppm_sauvola_ms.cc +++ b/scribo/src/binarization/ppm_sauvola_ms.cc @@ -93,22 +93,23 @@ int main(int argc, char *argv[]) else s = 3u; - // Lambda value - unsigned lambda_min_1 = 67; // FIXME: should be adapted to the - // window size. - double k; if (argc >= 6) k = atof(argv[5]); else k = 0.34f; + // Load image2d<value::rgb8> input_1; io::ppm::load(input_1, argv[1]); + // Convert to Gray level image. + image2d<value::int_u8> + input_1_gl = data::transform(input_1, mln::fun::v2v::rgb_to_int_u<8>()); + + // Binarize image2d<bool> - output = scribo::binarization::sauvola_ms(input_1, w_1, s, - lambda_min_1, k); + output = scribo::binarization::sauvola_ms(input_1_gl, w_1, s, k); io::pbm::save(output, argv[2]); } diff --git a/scribo/src/binarization/ppm_sauvola_ms_split.cc b/scribo/src/binarization/ppm_sauvola_ms_split.cc index b1f10ea..84e4abf 100644 --- a/scribo/src/binarization/ppm_sauvola_ms_split.cc +++ b/scribo/src/binarization/ppm_sauvola_ms_split.cc @@ -101,9 +101,6 @@ int main(int argc, char *argv[]) else min_ntrue = 2; - // Lambda value - unsigned lambda_min_1 = 67; // FIXME: should be adapted to the - // window size. double k; if (argc >= 7) @@ -112,14 +109,15 @@ int main(int argc, char *argv[]) k = 0.34f; - + // Load image2d<value::rgb8> input_1; io::ppm::load(input_1, argv[1]); std::cout << "Using w=" << w_1 << " - s=" << s << " - min_ntrue=" << min_ntrue << " - k=" << k << std::endl; + // Binarize image2d<bool> - output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, lambda_min_1, min_ntrue, k); + output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, min_ntrue, k); io::pbm::save(output, argv[2]); } diff --git a/scribo/src/binarization/sauvola_debug.cc b/scribo/src/binarization/sauvola_debug.cc index 8bbc19c..b17dd13 100644 --- a/scribo/src/binarization/sauvola_debug.cc +++ b/scribo/src/binarization/sauvola_debug.cc @@ -28,6 +28,10 @@ #include <mln/io/pbm/save.hh> #include <mln/io/pgm/save.hh> +#include <mln/data/stretch.hh> +#include <mln/data/convert.hh> +#include <mln/data/saturate.hh> + #include <scribo/binarization/local_threshold.hh> #include <scribo/binarization/sauvola_threshold_image_debug.hh> #include <scribo/debug/usage.hh> @@ -82,9 +86,10 @@ int main(int argc, char *argv[]) io::magick::load(input, argv[1]); - image2d<value::int_u8> mean, stddev; + image2d<float> mean, stddev, thres; initialize(mean, input); initialize(stddev, input); + initialize(thres, input); image2d<value::int_u8> gima = data::transform(input, @@ -94,12 +99,18 @@ int main(int argc, char *argv[]) image2d<bool> out = local_threshold(gima, sauvola_threshold_image_debug(gima, w, k, - mean, stddev)); + mean, stddev, thres)); io::pbm::save(out, argv[2]); - io::pgm::save(mean, argv[3]); - io::pgm::save(stddev, argv[4]); + + io::pgm::save(data::stretch(value::int_u8(), mean), argv[3]); + io::pgm::save(data::stretch(value::int_u8(), stddev), argv[4]); + + io::pgm::save(data::saturate(value::int_u8(), mean), "mean_saturated.pgm"); + io::pgm::save(data::saturate(value::int_u8(), stddev), "stddev_saturated.pgm"); + + io::pgm::save(data::saturate(value::int_u8(), thres), "thres_saturated.pgm"); trace::exiting("main"); } diff --git a/scribo/src/binarization/sauvola_ms.cc b/scribo/src/binarization/sauvola_ms.cc index 3983793..984ddee 100644 --- a/scribo/src/binarization/sauvola_ms.cc +++ b/scribo/src/binarization/sauvola_ms.cc @@ -34,7 +34,7 @@ bool check_args(int argc, char * argv[]) { - if (argc < 3 || argc > 7) + if (argc < 3 || argc > 6) return false; if (argc >= 5) @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) if (!check_args(argc, argv)) return scribo::debug::usage(argv, "Multi-Scale Binarization based on Sauvola's algorithm.", - "input.* output.pbm <w> <s> <k> <scale.pgm>", + "input.* output.pbm <w> <s> <k>", args_desc); trace::entering("main"); @@ -100,14 +100,17 @@ int main(int argc, char *argv[]) else k = 0.34f; - if (argc >= 7) - scribo::binarization::internal::scale_image_output = argv[6]; - + // Load image2d<value::rgb8> input_1; io::magick::load(input_1, argv[1]); + // Convert to Gray level image. + image2d<value::int_u8> + input_1_gl = data::transform(input_1, mln::fun::v2v::rgb_to_int_u<8>()); + + // Binarize image2d<bool> - output = scribo::binarization::sauvola_ms(input_1, w_1, s, k); + output = scribo::binarization::sauvola_ms(input_1_gl, w_1, s, k); io::pbm::save(output, argv[2]); } diff --git a/scribo/src/binarization/sauvola_ms.cc b/scribo/src/binarization/sauvola_ms_debug.cc similarity index 74% copy from scribo/src/binarization/sauvola_ms.cc copy to scribo/src/binarization/sauvola_ms_debug.cc index 3983793..80594dd 100644 --- a/scribo/src/binarization/sauvola_ms.cc +++ b/scribo/src/binarization/sauvola_ms_debug.cc @@ -34,7 +34,7 @@ bool check_args(int argc, char * argv[]) { - if (argc < 3 || argc > 7) + if (argc < 3 || argc > 10) return false; if (argc >= 5) @@ -61,9 +61,23 @@ const char *args_desc[][2] = { "s", "First subsampling ratio (default: 3)." }, { "k", "Sauvola's formuale parameter (default: 0.34)" }, { "scale.pgm", "Image of scales used for binarization." }, + { "k_image.pgm", "Image of the parameter K used in the image." }, + { "sn_image.pgm", "Image of the parameter normalized standard deviation." }, + { "k_l_image.pgm", "Precise image of the parameter K used for each site." }, {0, 0} }; +namespace scribo +{ + namespace binarization + { + namespace internal + { + extern image2d<value::int_u8> debug_k; + } + } +} + @@ -75,7 +89,7 @@ int main(int argc, char *argv[]) if (!check_args(argc, argv)) return scribo::debug::usage(argv, "Multi-Scale Binarization based on Sauvola's algorithm.", - "input.* output.pbm <w> <s> <k> <scale.pgm>", + "input.* output.pbm <w> <s> <k> <scale.pgm> <k_image.pgm> <sn_image.pgm> <k_l_image.pgm", args_desc); trace::entering("main"); @@ -103,11 +117,29 @@ int main(int argc, char *argv[]) if (argc >= 7) scribo::binarization::internal::scale_image_output = argv[6]; + if (argc >= 8) + scribo::binarization::internal::k_image_output = argv[7]; + + if (argc >= 9) + scribo::binarization::internal::s_n_image_output = argv[8]; + + if (argc >= 10) + scribo::binarization::internal::k_l_image_output = argv[9]; + + + // Load image2d<value::rgb8> input_1; io::magick::load(input_1, argv[1]); + + // Convert to Gray level image. + image2d<value::int_u8> + input_1_gl = data::transform(input_1, mln::fun::v2v::rgb_to_int_u<8>()); + + + // Binarize. image2d<bool> - output = scribo::binarization::sauvola_ms(input_1, w_1, s, k); + output = scribo::binarization::sauvola_ms(input_1_gl, w_1, s, k); io::pbm::save(output, argv[2]); } diff --git a/scribo/src/binarization/sauvola_ms_split.cc b/scribo/src/binarization/sauvola_ms_split.cc index af8b604..fc9e15c 100644 --- a/scribo/src/binarization/sauvola_ms_split.cc +++ b/scribo/src/binarization/sauvola_ms_split.cc @@ -101,10 +101,6 @@ int main(int argc, char *argv[]) else min_ntrue = 2; - // Lambda value - unsigned lambda_min_1 = 67; // FIXME: should be adapted to the - // window size. - double k; if (argc >= 7) k = atof(argv[6]); @@ -119,7 +115,7 @@ int main(int argc, char *argv[]) std::cout << "Using w=" << w_1 << " - s=" << s << " - min_ntrue=" << min_ntrue << " - k=" << k << std::endl; image2d<bool> - output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, lambda_min_1, min_ntrue, k); + output = scribo::binarization::sauvola_ms_split(input_1, w_1, s, min_ntrue, k); io::pbm::save(output, argv[2]); } -- 1.5.6.5
participants (1)
-
Guillaume Lazzara