* 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(a)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(a)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