* scribo/binarization/internal/compute_local_threshold.hh,
* scribo/binarization/internal/first_pass_functor.hh,
* scribo/binarization/internal/sauvola_formula.hh,
* scribo/binarization/local_threshold.hh: Update formula.
---
scribo/ChangeLog | 9 ++++++
.../internal/compute_local_threshold.hh | 15 +++++++++-
.../binarization/internal/first_pass_functor.hh | 2 +-
.../binarization/internal/sauvola_formula.hh | 22 +++++++++++-----
scribo/scribo/binarization/local_threshold.hh | 27 +++++++++++++------
5 files changed, 56 insertions(+), 19 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f8d7491..6c79022 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,12 @@
+2012-08-23 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Compute Sauvola on documents with light text and dark background.
+
+ * scribo/binarization/internal/compute_local_threshold.hh,
+ * scribo/binarization/internal/first_pass_functor.hh,
+ * scribo/binarization/internal/sauvola_formula.hh,
+ * scribo/binarization/local_threshold.hh: Update formula.
+
2012-05-10 Guillaume Lazzara <z(a)lrde.epita.fr>
Improve option parser.
diff --git a/scribo/scribo/binarization/internal/compute_local_threshold.hh
b/scribo/scribo/binarization/internal/compute_local_threshold.hh
index 147ef0f..4c25e17 100644
--- a/scribo/scribo/binarization/internal/compute_local_threshold.hh
+++ b/scribo/scribo/binarization/internal/compute_local_threshold.hh
@@ -42,7 +42,8 @@
-// extern mln::image2d<double> skewness;
+extern mln::image2d<double> skewness;
+extern mln::image2d<bool> skewness_pbm;
namespace scribo
{
@@ -117,6 +118,11 @@ namespace scribo
- simple.at_(row_max, col_min)
- simple.at_(row_min, col_max));
+ // if (!skewness_pbm(p))
+ // {
+ // m_x_y_tmp = 255 * wh - m_x_y_tmp;
+ // }
+
double m_x_y = m_x_y_tmp / wh;
# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
@@ -130,6 +136,11 @@ namespace scribo
- squared.at_(row_max, col_min)
- squared.at_(row_min, col_max));
+ // if (!skewness_pbm(p))
+ // {
+ // s_x_y_tmp = std::pow(255, 2) * wh - s_x_y_tmp;
+ // }
+
double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
@@ -140,7 +151,7 @@ namespace scribo
// Thresholding.
// skewness_ = skewness(p);
// b = (p == point2d(5,5));
- double t_x_y = formula(m_x_y, s_x_y, K, R);
+ double t_x_y = formula(p, m_x_y, s_x_y, K, R);
# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
double alpha = K * (1 - s_x_y / R);
diff --git a/scribo/scribo/binarization/internal/first_pass_functor.hh
b/scribo/scribo/binarization/internal/first_pass_functor.hh
index 8da401b..f0ae5a9 100644
--- a/scribo/scribo/binarization/internal/first_pass_functor.hh
+++ b/scribo/scribo/binarization/internal/first_pass_functor.hh
@@ -132,7 +132,7 @@ namespace scribo
unsigned p = pxl.offset();
value::int_u8 t_p;
- mln::convert::from_to(formula_(mean, stddev, K_, R_),
+ mln::convert::from_to(formula_(input.point_at_index(p), mean, stddev, K_, R_),
t_p);
msk.element(p) = input.element(p) < t_p;
diff --git a/scribo/scribo/binarization/internal/sauvola_formula.hh
b/scribo/scribo/binarization/internal/sauvola_formula.hh
index adbef13..e010e85 100644
--- a/scribo/scribo/binarization/internal/sauvola_formula.hh
+++ b/scribo/scribo/binarization/internal/sauvola_formula.hh
@@ -46,6 +46,10 @@
# define SCRIBO_DEFAULT_SAUVOLA_R 128
+#include <mln/core/alias/point2d.hh>
+
+extern mln::image2d<bool> skewness_pbm;
+
namespace scribo
{
@@ -55,6 +59,8 @@ namespace scribo
namespace internal
{
+ using namespace mln;
+
struct sauvola_formula
{
@@ -70,13 +76,13 @@ namespace scribo
\return A threshold.
*/
- double operator()(const double m_x_y, const double s_x_y,
+ double operator()(const point2d& p, const double m_x_y, const double s_x_y,
const double K, const double R) const;
/*!
\overload K = 0.34 and R = 128.
*/
- double operator()(const double m_x_y, const double s_x_y) const;
+ double operator()(const point2d& p, const double m_x_y, const double s_x_y) const;
};
@@ -88,7 +94,7 @@ namespace scribo
inline
double
- sauvola_formula::operator()(const double m_x_y, const double s_x_y,
+ sauvola_formula::operator()(const point2d& p, const double m_x_y, const double
s_x_y,
const double K, const double R) const
{
// if (b)
@@ -98,15 +104,17 @@ namespace scribo
// if (skewness_ > 0)
// if (new_t != old_t)
// std::cout << skewness_ << " - " << new_t <<
" vs " << old_t << std::endl;
-
- return m_x_y * (1.0 + K * ((s_x_y / R) - 1.0));
+ if (skewness_pbm(p))
+ return m_x_y * (1.0 + K * ((s_x_y / R) - 1.0));
+ else
+ return (255 - m_x_y) * (1.0 + K * ((s_x_y / R) - 1.0));
}
inline
double
- sauvola_formula::operator()(const double m_x_y, const double s_x_y) const
+ sauvola_formula::operator()(const point2d& p, const double m_x_y, const double
s_x_y) const
{
- return (*this)(m_x_y, s_x_y,
+ return (*this)(p, m_x_y, s_x_y,
SCRIBO_DEFAULT_SAUVOLA_K, SCRIBO_DEFAULT_SAUVOLA_R);
}
diff --git a/scribo/scribo/binarization/local_threshold.hh
b/scribo/scribo/binarization/local_threshold.hh
index 9d116ed..ab589e2 100644
--- a/scribo/scribo/binarization/local_threshold.hh
+++ b/scribo/scribo/binarization/local_threshold.hh
@@ -34,12 +34,13 @@
///
/// \brief Binarize an image using a threshold image.
+extern mln::image2d<bool> skewness_pbm;
+
namespace scribo
{
using namespace mln;
-
namespace binarization
{
@@ -110,8 +111,10 @@ namespace scribo
mln_piter(I) p(input.domain());
for_all(p)
- output(p) = (input(p) <= threshold(p));
-
+ if (skewness_pbm(p))
+ output(p) = (input(p) <= threshold(p));
+ else
+ output(p) = ((255 - input(p)) <= threshold(p));
trace::exiting("scribo::binarization::impl::generic::local_threshold");
return output;
@@ -132,6 +135,8 @@ namespace scribo
const I& input = exact(input_);
const T& threshold = exact(threshold_);
+ border::resize(::skewness_pbm, input.border());
+
typedef mln_ch_value(I, bool) O;
O output;
initialize(output, input);
@@ -139,8 +144,12 @@ namespace scribo
mln_pixter(const I) pi(input);
mln_pixter(const T) pt(threshold);
mln_pixter(O) po(output);
+
for_all_3(pi, pt, po)
- po.val() = pi.val() <= pt.val();
+ if (skewness_pbm.element(pi.offset()))
+ po.val() = (pi.val() <= pt.val());
+ else
+ po.val() = ((255 - pi.val()) <= pt.val());
trace::exiting("scribo::binarization::impl::generic::local_threshold_fastest");
return output;
@@ -159,7 +168,7 @@ namespace scribo
template <typename I, typename T>
mln_ch_value(I, bool)
- local_threshold_dispatch(trait::image::value_alignment::any,
+ local_threshold_dispatch(trait::image::speed::any,
trait::image::speed::any,
const Image<I>& input, const Image<T>& threshold)
{
@@ -169,7 +178,7 @@ namespace scribo
template <typename I, typename T>
mln_ch_value(I, bool)
- local_threshold_dispatch(trait::image::value_alignment::with_grid,
+ local_threshold_dispatch(trait::image::speed::fastest,
trait::image::speed::fastest,
const Image<I>& input, const Image<T>& threshold)
{
@@ -181,9 +190,9 @@ namespace scribo
local_threshold_dispatch(const Image<I>& input,
const Image<T>& threshold)
{
- return local_threshold_dispatch(mln_trait_image_value_alignment(I)(),
- mln_trait_image_speed(I)(),
- exact(input), exact(threshold));
+ return local_threshold_dispatch(mln_trait_image_speed(I)(),
+ mln_trait_image_speed(T)(),
+ input, threshold);
}
} // end of namespace scribo::binarization::internal
--
1.7.2.5