* scribo/binarization/all.hh: Update includes.
* scribo/binarization/internal/compute_local_threshold.hh,
* scribo/binarization/internal/compute_sauvola_threshold.hh,
* scribo/binarization/internal/first_pass_functor.hh,
* scribo/binarization/internal/local_threshold_debug.hh,
* scribo/binarization/internal/sauvola_debug.hh,
* scribo/binarization/internal/sauvola_formula.hh,
* scribo/binarization/sauvola.hh,
* scribo/binarization/sauvola_ms.hh,
* scribo/binarization/sauvola_threshold.hh,
* scribo/binarization/sauvola_threshold_image.hh: Revamp code in
order to share some parts with Niblack's algorithm.
* scribo/binarization/internal/niblack_formula.hh,
* scribo/binarization/niblack.hh,
* scribo/binarization/niblack_threshold.hh: New.
* src/binarization/Makefile.am
* tests/binarization/Makefile.am: Add new targets.
* src/binarization/niblack.cc: New tool.
* tests/binarization/niblack.cc: New test.
* tests/binarization/niblack.ref.pbm: New test data.
---
scribo/ChangeLog | 31 ++
scribo/scribo/binarization/all.hh | 5 +-
.../internal/compute_local_threshold.hh | 224 +++++++++++++++
.../internal/compute_sauvola_threshold.hh | 285 ------------------
.../binarization/internal/first_pass_functor.hh | 24 +-
.../binarization/internal/local_threshold_debug.hh | 88 ++++++
.../binarization/internal/niblack_formula.hh | 105 +++++++
.../scribo/binarization/internal/sauvola_debug.hh | 87 ------
.../binarization/internal/sauvola_formula.hh | 121 ++++++++
scribo/scribo/binarization/niblack.hh | 218 ++++++++++++++
scribo/scribo/binarization/niblack_threshold.hh | 299 +++++++++++++++++++
scribo/scribo/binarization/sauvola.hh | 24 +-
scribo/scribo/binarization/sauvola_ms.hh | 21 +-
scribo/scribo/binarization/sauvola_threshold.hh | 296 +++++++++++++++++++
.../scribo/binarization/sauvola_threshold_image.hh | 301 --------------------
scribo/src/binarization/Makefile.am | 12 +-
scribo/src/binarization/niblack.cc | 106 +++++++
.../binarization/pgm_sauvola_threshold_image.cc | 7 +-
scribo/tests/binarization/Makefile.am | 3 +
scribo/tests/binarization/niblack.cc | 52 ++++
scribo/tests/binarization/niblack.ref.pbm | Bin 0 -> 16498 bytes
21 files changed, 1597 insertions(+), 712 deletions(-)
create mode 100644 scribo/scribo/binarization/internal/compute_local_threshold.hh
delete mode 100644 scribo/scribo/binarization/internal/compute_sauvola_threshold.hh
create mode 100644 scribo/scribo/binarization/internal/local_threshold_debug.hh
create mode 100644 scribo/scribo/binarization/internal/niblack_formula.hh
delete mode 100644 scribo/scribo/binarization/internal/sauvola_debug.hh
create mode 100644 scribo/scribo/binarization/internal/sauvola_formula.hh
create mode 100644 scribo/scribo/binarization/niblack.hh
create mode 100644 scribo/scribo/binarization/niblack_threshold.hh
create mode 100644 scribo/scribo/binarization/sauvola_threshold.hh
delete mode 100644 scribo/scribo/binarization/sauvola_threshold_image.hh
create mode 100644 scribo/src/binarization/niblack.cc
create mode 100644 scribo/tests/binarization/niblack.cc
create mode 100644 scribo/tests/binarization/niblack.ref.pbm
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 5aa2a06..0923b28 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,34 @@
+2011-10-17 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add Niblack's binarization algorithm.
+
+ * scribo/binarization/all.hh: Update includes.
+
+ * scribo/binarization/internal/compute_local_threshold.hh,
+ * scribo/binarization/internal/compute_sauvola_threshold.hh,
+ * scribo/binarization/internal/first_pass_functor.hh,
+ * scribo/binarization/internal/local_threshold_debug.hh,
+ * scribo/binarization/internal/sauvola_debug.hh,
+ * scribo/binarization/internal/sauvola_formula.hh,
+ * scribo/binarization/sauvola.hh,
+ * scribo/binarization/sauvola_ms.hh,
+ * scribo/binarization/sauvola_threshold.hh,
+ * scribo/binarization/sauvola_threshold_image.hh: Revamp code in
+ order to share some parts with Niblack's algorithm.
+
+ * scribo/binarization/internal/niblack_formula.hh,
+ * scribo/binarization/niblack.hh,
+ * scribo/binarization/niblack_threshold.hh: New.
+
+ * src/binarization/Makefile.am
+ * tests/binarization/Makefile.am: Add new targets.
+
+ * src/binarization/niblack.cc: New tool.
+
+ * tests/binarization/niblack.cc: New test.
+
+ * tests/binarization/niblack.ref.pbm: New test data.
+
2011-10-14 Guillaume Lazzara <z(a)lrde.epita.fr>
Add a new tool for global thresholding.
diff --git a/scribo/scribo/binarization/all.hh b/scribo/scribo/binarization/all.hh
index 6f40505..5530861 100644
--- a/scribo/scribo/binarization/all.hh
+++ b/scribo/scribo/binarization/all.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -50,6 +51,6 @@ namespace scribo
# include <scribo/binarization/sauvola.hh>
# include <scribo/binarization/sauvola_ms.hh>
# include <scribo/binarization/sauvola_ms_split.hh>
-# include <scribo/binarization/sauvola_threshold_image.hh>
+# include <scribo/binarization/sauvola_threshold.hh>
#endif // ! SCRIBO_BINARIZATION_ALL_HH
diff --git a/scribo/scribo/binarization/internal/compute_local_threshold.hh b/scribo/scribo/binarization/internal/compute_local_threshold.hh
new file mode 100644
index 0000000..147ef0f
--- /dev/null
+++ b/scribo/scribo/binarization/internal/compute_local_threshold.hh
@@ -0,0 +1,224 @@
+// Copyright (C) 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.
+
+#ifndef SCRIBO_BINARIZATION_INTERNAL_COMPUTE_LOCAL_THRESHOLD_HH
+# define SCRIBO_BINARIZATION_INTERNAL_COMPUTE_LOCAL_THRESHOLD_HH
+
+
+/// \file
+///
+/// \brief Compute a threshold with Local's binarization formula.
+
+# include <algorithm>
+# include <cmath>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/int_u8.hh>
+
+# include <scribo/binarization/internal/local_threshold_debug.hh>
+
+
+
+// extern mln::image2d<double> skewness;
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ namespace internal
+ {
+
+ using namespace mln;
+
+
+ /*! \brief Compute a point wise threshold according to a local
+ binarization formula.
+
+ \param[in] p A site.
+ \param[in] simple An integral image of mean values.
+ \param[in] squared An integral image of squared mean values.
+ \param[in] win_width Window width.
+ \param[in] k Control the threshold value in the local
+ window. The higher, the lower the threshold
+ form the local mean m(x, y).
+ \param[in] R Maximum value of the standard deviation (128
+ for grayscale documents).
+ \param[in] formula The function to use to compute the local
+ threshold.
+
+ \return A threshold.
+ */
+ template <typename P, typename J, typename F>
+ double
+ compute_local_threshold(const P& p,
+ const J& simple,
+ const J& squared,
+ int win_width, double K, double R,
+ const F& formula);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename P, typename J, typename F>
+ double
+ compute_local_threshold(const P& p,
+ const J& simple,
+ const J& squared,
+ int win_width, double K, double R,
+ const F& formula)
+ {
+ mln_precondition(simple.nrows() == squared.nrows());
+ mln_precondition(simple.ncols() == squared.ncols());
+
+ // Window half width.
+ int w_2 = win_width >> 1;
+
+ int row_min = std::max(0, p.row() - w_2 - 1);
+ int col_min = std::max(0, p.col() - w_2 - 1);
+
+ int row_max = std::min(static_cast<int>(simple.nrows()) - 1,
+ p.row() + w_2);
+ int col_max = std::min(static_cast<int>(simple.ncols()) - 1,
+ p.col() + w_2);
+
+
+ double wh = (row_max - row_min) * (col_max - col_min);
+
+ // Mean.
+ double m_x_y_tmp = (simple.at_(row_max, col_max)
+ + simple.at_(row_min, col_min)
+ - simple.at_(row_max, col_min)
+ - simple.at_(row_min, col_max));
+
+ double m_x_y = m_x_y_tmp / wh;
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ // Store local mean
+ debug_mean(p) = m_x_y * mean_debug_factor;
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ // Standard deviation.
+ double s_x_y_tmp = (squared.at_(row_max, col_max)
+ + squared.at_(row_min, col_min)
+ - squared.at_(row_max, col_min)
+ - squared.at_(row_min, col_max));
+
+ 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
+ // Store local standard deviation
+ debug_stddev(p) = s_x_y * stddev_debug_factor;
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ // Thresholding.
+ // skewness_ = skewness(p);
+ // b = (p == point2d(5,5));
+ double t_x_y = formula(m_x_y, s_x_y, K, R);
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ double alpha = K * (1 - s_x_y / R);
+ debug_alpham(p) = alpha * m_x_y * alpham_debug_factor;
+ debug_alphacond(p) = (s_x_y < (alpha * m_x_y / 2.));
+# endif // !SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ return t_x_y;
+ }
+
+
+ template <typename P, typename J, typename F>
+ double
+ compute_local_threshold_single_image(const P& p,
+ const J& integral,
+ int win_width,
+ double K, double R,
+ const F& formula)
+ {
+ // Window half width.
+ int w_2 = win_width >> 1;
+
+ int row_min = std::max(0, p.row() - w_2);
+ int col_min = std::max(0, p.col() - w_2);
+
+ int row_max = std::min(static_cast<int>(integral.nrows()) - 1,
+ p.row() + w_2);
+ int col_max = std::min(static_cast<int>(integral.ncols()) - 1,
+ p.col() + w_2);
+
+
+ double wh = (row_max - row_min + 1) * (col_max - col_min + 1);
+
+ // Mean.
+ double m_x_y_tmp = (integral.at_(row_max, col_max).first()
+ + integral.at_(row_min, col_min).first()
+ - integral.at_(row_max, col_min).first()
+ - integral.at_(row_min, col_max).first());
+
+ double m_x_y = m_x_y_tmp / wh;
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ // Store local mean
+ debug_mean(p) = m_x_y * mean_debug_factor;
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ // Standard deviation.
+ double s_x_y_tmp = (integral.at_(row_max, col_max).second()
+ + integral.at_(row_min, col_min).second()
+ - integral.at_(row_max, col_min).second()
+ - integral.at_(row_min, col_max).second());
+
+ 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
+ // Store local standard deviation
+ debug_stddev(p) = s_x_y * stddev_debug_factor;
+# endif // !SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ // Thresholding.
+ double t_x_y = formula(m_x_y, s_x_y, K, R);
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ double alpha = K * (1 - s_x_y / R);
+ debug_alpham(p) = alpha * m_x_y * alpham_debug_factor;
+ debug_alphacond(p) = (s_x_y < (alpha * m_x_y / 2.));
+# endif // !SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ return t_x_y;
+ }
+
+
+#endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::binarization::internal
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_BINARIZATION_INTERNAL_COMPUTE_LOCAL_THRESHOLD_HH
diff --git a/scribo/scribo/binarization/internal/compute_sauvola_threshold.hh b/scribo/scribo/binarization/internal/compute_sauvola_threshold.hh
deleted file mode 100644
index d3ca07f..0000000
--- a/scribo/scribo/binarization/internal/compute_sauvola_threshold.hh
+++ /dev/null
@@ -1,285 +0,0 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#ifndef SCRIBO_BINARIZATION_INTERNAL_COMPUTE_SAUVOLA_THRESHOLD_HH
-# define SCRIBO_BINARIZATION_INTERNAL_COMPUTE_SAUVOLA_THRESHOLD_HH
-
-
-/// \file
-///
-/// \brief Compute a threshold with Sauvola's binarization formula.
-
-# include <algorithm>
-# include <cmath>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/value/int_u8.hh>
-
-# include <scribo/binarization/internal/sauvola_debug.hh>
-
-
-// Setup default Sauvola's formulae parameters values.
-// These macros may be used in other variant of Sauvola's algorithm.
-//
-// Values are set according to the following reference: "Automatic
-// Evaluation of Document Binarization Results", Badekas and al, 2005
-//
-// Badekas et al. said 0.34 was best.
-# define SCRIBO_DEFAULT_SAUVOLA_K 0.34
-//
-// 128 is best for grayscale documents.
-# define SCRIBO_DEFAULT_SAUVOLA_R 128
-
-
-namespace scribo
-{
-
- namespace binarization
- {
-
- namespace internal
- {
-
- using namespace mln;
-
-
- /*! \brief Compute a point wise threshold according Sauvola's
- binarization.
-
- \param[in] p A site.
- \param[in] simple An integral image of mean values.
- \param[in] squared An integral image of squared mean values.
- \param[in] win_width Window width.
- \param[in] k Control the threshold value in the local
- window. The higher, the lower the threshold
- form the local mean m(x, y).
- \param[in] R Maximum value of the standard deviation (128
- for grayscale documents).
-
- \return A threshold.
- */
- template <typename P, typename J>
- double
- compute_sauvola_threshold(const P& p,
- const J& simple,
- const J& squared,
- int win_width, double K, double R);
-
- /// \overload
- /// K is set to 0.34 and R to 128.
- //
- template <typename P, typename J>
- double
- compute_sauvola_threshold(const P& p,
- const J& simple,
- const J& squared,
- int win_width);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-
-
- /*! \brief compute Sauvola's threshold applying directly the formula.
-
- \param[in] m_x_y Mean value.
- \param[in] s_x_y Standard deviation.
- \param[in] k Control the threshold value in the local
- window. The higher, the lower the threshold
- form the local mean m(x, y).
- \param[in] R Maximum value of the standard deviation (128
- for grayscale documents).
-
- \return A threshold.
- */
- inline
- double
- sauvola_threshold_formula(const double m_x_y, const double s_x_y,
- const double K, const double R)
- {
- return m_x_y * (1.0 + K * ((s_x_y / R) - 1.0));
- }
-
- /// \overload
- /// K is set to 0.34 and R to 128.
- //
- inline
- 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);
- }
-
-
-
- template <typename P, typename J>
- double
- compute_sauvola_threshold(const P& p,
- const J& simple,
- const J& squared,
- int win_width, double K, double R)
- {
- mln_precondition(simple.nrows() == squared.nrows());
- mln_precondition(simple.ncols() == squared.ncols());
-
- // Window half width.
- int w_2 = win_width >> 1;
-
- int row_min = std::max(0, p.row() - w_2 - 1);
- int col_min = std::max(0, p.col() - w_2 - 1);
-
- int row_max = std::min(static_cast<int>(simple.nrows()) - 1,
- p.row() + w_2);
- int col_max = std::min(static_cast<int>(simple.ncols()) - 1,
- p.col() + w_2);
-
-
- double wh = (row_max - row_min) * (col_max - col_min);
-
- // Mean.
- double m_x_y_tmp = (simple.at_(row_max, col_max)
- + simple.at_(row_min, col_min)
- - simple.at_(row_max, col_min)
- - simple.at_(row_min, col_max));
-
- double m_x_y = m_x_y_tmp / wh;
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
- // Store local mean
- debug_mean(p) = m_x_y * mean_debug_factor;
-# endif // ! SCRIBO_SAUVOLA_DEBUG
-
- // Standard deviation.
- double s_x_y_tmp = (squared.at_(row_max, col_max)
- + squared.at_(row_min, col_min)
- - squared.at_(row_max, col_min)
- - squared.at_(row_min, col_max));
-
- double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
- // Store local standard deviation
- debug_stddev(p) = s_x_y * stddev_debug_factor;
-# endif // ! SCRIBO_SAUVOLA_DEBUG
-
- // Thresholding.
- double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R);
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
- double alpha = K * (1 - s_x_y / R);
- debug_alpham(p) = alpha * m_x_y * alpham_debug_factor;
- debug_alphacond(p) = (s_x_y < (alpha * m_x_y / 2.));
-# endif // !SCRIBO_SAUVOLA_DEBUG
-
- return t_x_y;
- }
-
-
- template <typename P, typename J>
- double
- compute_sauvola_threshold_single_image(const P& p,
- const J& integral,
- int win_width,
- double K, double R)
- {
- // Window half width.
- int w_2 = win_width >> 1;
-
- int row_min = std::max(0, p.row() - w_2);
- int col_min = std::max(0, p.col() - w_2);
-
- int row_max = std::min(static_cast<int>(integral.nrows()) - 1,
- p.row() + w_2);
- int col_max = std::min(static_cast<int>(integral.ncols()) - 1,
- p.col() + w_2);
-
-
- double wh = (row_max - row_min + 1) * (col_max - col_min + 1);
-
- // Mean.
- double m_x_y_tmp = (integral.at_(row_max, col_max).first()
- + integral.at_(row_min, col_min).first()
- - integral.at_(row_max, col_min).first()
- - integral.at_(row_min, col_max).first());
-
- double m_x_y = m_x_y_tmp / wh;
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
- // Store local mean
- debug_mean(p) = m_x_y * mean_debug_factor;
-# endif // ! SCRIBO_SAUVOLA_DEBUG
-
- // Standard deviation.
- double s_x_y_tmp = (integral.at_(row_max, col_max).second()
- + integral.at_(row_min, col_min).second()
- - integral.at_(row_max, col_min).second()
- - integral.at_(row_min, col_max).second());
-
- double s_x_y = std::sqrt((s_x_y_tmp - (m_x_y_tmp * m_x_y_tmp) / wh) / (wh - 1.f));
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
- // Store local standard deviation
- debug_stddev(p) = s_x_y * stddev_debug_factor;
-# endif // !SCRIBO_SAUVOLA_DEBUG
-
- // Thresholding.
- double t_x_y = sauvola_threshold_formula(m_x_y, s_x_y, K, R);
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
- double alpha = K * (1 - s_x_y / R);
- debug_alpham(p) = alpha * m_x_y * alpham_debug_factor;
- debug_alphacond(p) = (s_x_y < (alpha * m_x_y / 2.));
-# endif // !SCRIBO_SAUVOLA_DEBUG
-
- return t_x_y;
- }
-
-
-
- template <typename P, typename J>
- double
- compute_sauvola_threshold(const P& p,
- const J& simple,
- const J& squared,
- int win_width)
- {
- return compute_sauvola_threshold(p, simple, squared, win_width,
- SCRIBO_DEFAULT_SAUVOLA_K,
- SCRIBO_DEFAULT_SAUVOLA_R);
- }
-
-
-#endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace scribo::binarization::internal
-
- } // end of namespace scribo::binarization
-
-} // end of namespace scribo
-
-#endif // ! SCRIBO_BINARIZATION_INTERNAL_COMPUTE_SAUVOLA_THRESHOLD_HH
diff --git a/scribo/scribo/binarization/internal/first_pass_functor.hh b/scribo/scribo/binarization/internal/first_pass_functor.hh
index 0b1a7ac..8da401b 100644
--- a/scribo/scribo/binarization/internal/first_pass_functor.hh
+++ b/scribo/scribo/binarization/internal/first_pass_functor.hh
@@ -37,7 +37,11 @@
# include <mln/value/int_u8.hh>
# include <mln/data/fill.hh>
-# include <scribo/binarization/sauvola_threshold_image.hh>
+# include <scribo/binarization/internal/sauvola_formula.hh>
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+# include <scribo/binarization/internal/local_threshold_debug.hh>
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
namespace scribo
@@ -67,8 +71,11 @@ namespace scribo
mln::util::array<int> dp;
double K_;
+ double R_;
+
+ sauvola_formula formula_;
- first_pass_functor(const I& input, double K);
+ first_pass_functor(const I& input, double K, double R);
void exec(double mean, double stddev);
void finalize();
@@ -88,10 +95,11 @@ namespace scribo
template <typename I>
- first_pass_functor<I>::first_pass_functor(const I& input, double K)
+ first_pass_functor<I>::first_pass_functor(const I& input, double K, double R)
: input(input),
pxl(input),
- K_(K)
+ K_(K),
+ R_(R)
{
res = 0;
pxl.start();
@@ -100,10 +108,10 @@ namespace scribo
initialize(parent, input);
initialize(msk, input);
-# ifdef SCRIBO_SAUVOLA_DEBUG
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
initialize(debug_mean, input);
initialize(debug_stddev, input);
-# endif // ! SCRIBO_SAUVOLA_DEBUG
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
mln::extension::fill(msk, false);
@@ -124,9 +132,7 @@ namespace scribo
unsigned p = pxl.offset();
value::int_u8 t_p;
- mln::convert::from_to(sauvola_threshold_formula(mean, stddev,
- K_,
- SCRIBO_DEFAULT_SAUVOLA_R),
+ mln::convert::from_to(formula_(mean, stddev, K_, R_),
t_p);
msk.element(p) = input.element(p) < t_p;
diff --git a/scribo/scribo/binarization/internal/local_threshold_debug.hh b/scribo/scribo/binarization/internal/local_threshold_debug.hh
new file mode 100644
index 0000000..a9da06c
--- /dev/null
+++ b/scribo/scribo/binarization/internal/local_threshold_debug.hh
@@ -0,0 +1,88 @@
+// Copyright (C) 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.
+
+#ifndef SCRIBO_BINARIZATION_INTERNAL_LOCAL_THRESHOLD_DEBUG_HH
+# define SCRIBO_BINARIZATION_INTERNAL_LOCAL_THRESHOLD_DEBUG_HH
+
+/// \file
+///
+/// \brief Declare all debug related variables for local based
+/// algorithms.
+
+
+/// FIXME: A struct may be a bit better...
+
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ using namespace mln;
+
+ namespace internal
+ {
+
+ char* stddev_image_output = 0;
+ char* mean_image_output = 0;
+ char* threshold_image_output = 0;
+
+ char* scale_image_output = 0;
+
+ char* alpham_image_output = 0;
+ char* alphacond_image_output = 0;
+
+ // Declare debug images.
+ image2d<double> debug_stddev;
+ image2d<double> debug_mean;
+ image2d<double> debug_threshold;
+
+ image2d<double> debug_alpham;
+ image2d<bool> debug_alphacond;
+
+ double mean_debug_factor = 1.0;
+ double stddev_debug_factor = 1.0;
+ double alpham_debug_factor = 2.0;
+
+ } // end of namespace scribo::binarization::internal
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+
+#endif // ! SCRIBO_BINARIZATION_INTERNAL_LOCAL_THRESHOLD_DEBUG_HH
diff --git a/scribo/scribo/binarization/internal/niblack_formula.hh b/scribo/scribo/binarization/internal/niblack_formula.hh
new file mode 100644
index 0000000..54dbc9b
--- /dev/null
+++ b/scribo/scribo/binarization/internal/niblack_formula.hh
@@ -0,0 +1,105 @@
+// Copyright (C) 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.
+
+#ifndef SCRIBO_BINARIZATION_INTERNAL_NIBLACK_FORMULA_HH
+# define SCRIBO_BINARIZATION_INTERNAL_NIBLACK_FORMULA_HH
+
+
+/// \file
+///
+/// \brief Routines computing a threshold using Niblack's binarization
+/// formula.
+
+// \fixme Having an unused parameter to fulfill the required interface
+// may not be the best solution...
+
+// Setup default Niblack's formula parameters values.
+# define SCRIBO_DEFAULT_NIBLACK_K -0.2
+
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ namespace internal
+ {
+
+ struct niblack_formula
+ {
+
+ /*! \brief compute a threshold using Niblack's formula.
+
+ \param[in] m_x_y Mean value.
+ \param[in] s_x_y Standard deviation.
+ \param[in] k Control the threshold value in the local
+ window. The higher, the lower the threshold
+ form the local mean m(x, y).
+ \param[in] R Maximum value of the standard deviation (128
+ for grayscale documents). Unused in this formula.
+
+ \return A threshold.
+ */
+ double operator()(const double m_x_y, const double s_x_y,
+ const double K, const double R) const;
+
+ /*!
+ \overload K = 0.34.
+ */
+ double operator()(const double m_x_y, const double s_x_y) const;
+
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ double
+ niblack_formula::operator()(const double m_x_y, const double s_x_y,
+ const double K, const double /*R*/) const
+ {
+ return m_x_y + K * s_x_y;
+ }
+
+ inline
+ double
+ niblack_formula::operator()(const double m_x_y, const double s_x_y) const
+ {
+ return (*this)(m_x_y, s_x_y,
+ SCRIBO_DEFAULT_NIBLACK_K, 128);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::binarization::internal
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_BINARIZATION_INTERNAL_NIBLACK_FORMULA_HH
diff --git a/scribo/scribo/binarization/internal/sauvola_debug.hh b/scribo/scribo/binarization/internal/sauvola_debug.hh
deleted file mode 100644
index 0f8ccf0..0000000
--- a/scribo/scribo/binarization/internal/sauvola_debug.hh
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#ifndef SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_DEBUG_HH
-# define SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_DEBUG_HH
-
-/// \file
-///
-/// \brief Declare all debug related variables for Sauvola*
-/// algorithms.
-
-
-/// FIXME: A struct may be a bit better...
-
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
-
-# ifndef MLN_INCLUDE_ONLY
-
-
-namespace scribo
-{
-
- namespace binarization
- {
-
- using namespace mln;
-
- namespace internal
- {
-
- char* stddev_image_output = 0;
- char* mean_image_output = 0;
- char* threshold_image_output = 0;
-
- char* scale_image_output = 0;
-
- char* alpham_image_output = 0;
- char* alphacond_image_output = 0;
-
- // Declare debug images.
- image2d<double> debug_stddev;
- image2d<double> debug_mean;
- image2d<double> debug_threshold;
-
- image2d<double> debug_alpham;
- image2d<bool> debug_alphacond;
-
- double mean_debug_factor = 1.0;
- double stddev_debug_factor = 1.0;
- double alpham_debug_factor = 2.0;
-
- } // end of namespace scribo::binarization::internal
-
- } // end of namespace scribo::binarization
-
-} // end of namespace scribo
-
-
-# endif // ! MLN_INCLUDE_ONLY
-
-# endif // ! SCRIBO_SAUVOLA_DEBUG
-
-
-#endif // ! SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_DEBUG_HH
diff --git a/scribo/scribo/binarization/internal/sauvola_formula.hh b/scribo/scribo/binarization/internal/sauvola_formula.hh
new file mode 100644
index 0000000..adbef13
--- /dev/null
+++ b/scribo/scribo/binarization/internal/sauvola_formula.hh
@@ -0,0 +1,121 @@
+// Copyright (C) 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.
+
+#ifndef SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_FORMULA_HH
+# define SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_FORMULA_HH
+
+
+/// \file
+///
+/// \brief Routines computing a threshold using Sauvola's binarization
+/// formula.
+
+
+// Setup default Sauvola's formula parameters values.
+// These macros may be used in other variant of Sauvola's algorithms.
+//
+// Values are set according to the following reference: "Automatic
+// Evaluation of Document Binarization Results", Badekas and al, 2005
+//
+// Badekas et al. said 0.34 was best for Sauvola.
+# define SCRIBO_DEFAULT_SAUVOLA_K 0.34
+//
+// 128 is best for grayscale documents.
+# define SCRIBO_DEFAULT_SAUVOLA_R 128
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ namespace internal
+ {
+
+ struct sauvola_formula
+ {
+
+ /*! \brief Compute a threshold using Sauvola's formula.
+
+ \param[in] m_x_y Mean value.
+ \param[in] s_x_y Standard deviation.
+ \param[in] k Control the threshold value in the local
+ window. The higher, the lower the threshold
+ form the local mean m(x, y).
+ \param[in] R Maximum value of the standard deviation (128
+ for grayscale documents).
+
+ \return A threshold.
+ */
+ double operator()(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;
+
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // bool b;
+ // double skewness_;
+
+ inline
+ double
+ sauvola_formula::operator()(const double m_x_y, const double s_x_y,
+ const double K, const double R) const
+ {
+ // if (b)
+ // std::cout << skewness_ << " - " << (K * -1 * skewness_) << std::endl;
+ // volatile double new_t = ((skewness_ < 0) ? -skewness_ : 1 * m_x_y * (1.0 + K * ((s_x_y / R) - 1.0)));
+ // volatile double old_t = (m_x_y * (1.0 + K * ((s_x_y / R) - 1.0)));
+ // 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));
+ }
+
+ inline
+ double
+ sauvola_formula::operator()(const double m_x_y, const double s_x_y) const
+ {
+ return (*this)(m_x_y, s_x_y,
+ SCRIBO_DEFAULT_SAUVOLA_K, SCRIBO_DEFAULT_SAUVOLA_R);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::binarization::internal
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_BINARIZATION_INTERNAL_SAUVOLA_FORMULA_HH
diff --git a/scribo/scribo/binarization/niblack.hh b/scribo/scribo/binarization/niblack.hh
new file mode 100644
index 0000000..e66e7b4
--- /dev/null
+++ b/scribo/scribo/binarization/niblack.hh
@@ -0,0 +1,218 @@
+// Copyright (C) 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.
+
+#ifndef SCRIBO_BINARIZATION_NIBLACK_HH
+# define SCRIBO_BINARIZATION_NIBLACK_HH
+
+/// \file
+///
+///
+
+# include <mln/core/concept/image.hh>
+# include <mln/data/transform.hh>
+# include <mln/value/int_u8.hh>
+
+# include <scribo/binarization/niblack_threshold.hh>
+# include <scribo/binarization/local_threshold.hh>
+# include <scribo/binarization/internal/local_threshold_debug.hh>
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+# include <mln/io/pgm/save.hh>
+# include <mln/io/pbm/save.hh>
+# include <mln/data/saturate.hh>
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+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 Niblack's formulae constant.
+
+ \return A binary image.
+
+ */
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack(const Image<I>& input, unsigned window_size, double K);
+
+
+
+ /*! \brief Convert an image into a binary image.
+
+ Niblack'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)
+ niblack(const Image<I>& input, unsigned window_size);
+
+
+ /// \overload
+ /// The window size is set to 11.
+ //
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack(const Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementations.
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack(const Image<I>& input, unsigned window_size, double K)
+ {
+ trace::entering("scribo::binarization::impl::generic::niblack");
+ mln_precondition(exact(input).is_valid());
+
+ mln_ch_value(I,value::int_u8)
+ threshold_image = binarization::niblack_threshold(input, window_size, K);
+
+ mln_ch_value(I, bool)
+ output = local_threshold(input, threshold_image);
+
+ trace::exiting("scribo::binarization::impl::generic::niblack");
+ return output;
+ }
+
+ } // end of namespace scribo::binarization::impl::generic
+
+
+ } // end of namespace scribo::binarization::impl
+
+
+
+ // Dispatch
+
+ namespace internal
+ {
+
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack_dispatch(const mln_value(I)&,
+ const Image<I>& input, unsigned window_size,
+ double K)
+ {
+ return impl::generic::niblack(input, window_size, K);
+ }
+
+
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack_dispatch(const Image<I>& input, unsigned window_size,
+ double K)
+ {
+ typedef mln_value(I) V;
+ return niblack_dispatch(V(), input, window_size, K);
+ }
+
+ } // end of namespace scribo::binarization::internal
+
+
+
+ // Facades
+
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack(const Image<I>& input, unsigned window_size, double K)
+ {
+ trace::entering("scribo::binarization::niblack");
+
+ mln_precondition(exact(input).is_valid());
+
+ mln_ch_value(I, bool)
+ output = internal::niblack_dispatch(input, window_size, K);
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ if (internal::stddev_image_output)
+ io::pgm::save(data::saturate(value::int_u8(), internal::debug_stddev),
+ internal::stddev_image_output);
+ if (internal::mean_image_output)
+ io::pgm::save(data::saturate(value::int_u8(), internal::debug_mean),
+ internal::mean_image_output);
+ if (internal::threshold_image_output)
+ io::pgm::save(data::saturate(value::int_u8(), internal::debug_threshold),
+ internal::threshold_image_output);
+
+ if (internal::alpham_image_output)
+ io::pgm::save(data::saturate(value::int_u8(), internal::debug_alpham),
+ internal::alpham_image_output);
+ if (internal::alphacond_image_output)
+ io::pbm::save(internal::debug_alphacond, internal::alphacond_image_output);
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+
+ trace::exiting("scribo::binarization::niblack");
+ return output;
+ }
+
+
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack(const Image<I>& input, unsigned window_size)
+ {
+ return niblack(input, window_size, SCRIBO_DEFAULT_NIBLACK_K);
+ }
+
+
+ template <typename I>
+ mln_ch_value(I, bool)
+ niblack(const Image<I>& input)
+ {
+ return niblack(input, 11);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_BINARIZATION_NIBLACK_HH
diff --git a/scribo/scribo/binarization/niblack_threshold.hh b/scribo/scribo/binarization/niblack_threshold.hh
new file mode 100644
index 0000000..db4a74e
--- /dev/null
+++ b/scribo/scribo/binarization/niblack_threshold.hh
@@ -0,0 +1,299 @@
+// Copyright (C) 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.
+
+#ifndef SCRIBO_BINARIZATION_NIBLACK_THRESHOLD_HH
+# define SCRIBO_BINARIZATION_NIBLACK_THRESHOLD_HH
+
+/// \file
+///
+/// Compute an image of local threshold using Niblack algorithm.
+
+/// \fixme return type too restrictive!
+/// \fixme Revamp code and merge with sauvola_threshold.hh.
+
+# include <algorithm>
+# include <cmath>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/int_u.hh>
+# include <mln/value/int_u8.hh>
+
+# include <scribo/core/init_integral_image.hh>
+# include <scribo/binarization/internal/compute_local_threshold.hh>
+# include <scribo/binarization/internal/niblack_formula.hh>
+
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ using namespace mln;
+
+ /*! \brief Compute an image of local threshold using Niblack algorithm.
+
+ \input[in] input A gray level image.
+ \input[in] window_size The window size.
+ \input[out] simple The sum of all intensities of \p input.
+ \input[out] squared The sum of all squared intensities of \p
+ input.
+
+ \return An image of local thresholds.
+
+ */
+ template <typename I, typename J>
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input, unsigned window_size,
+ double K,
+ Image<J>& simple,
+ Image<J>& squared);
+
+ /// \overload
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input, unsigned window_size,
+ double K);
+
+ /// \overload
+ /// K is set to 0.34
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input, unsigned window_size);
+
+
+ /// \overload
+ /// The window size is set to 11.
+ //
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementation
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename J>
+ inline
+ mln_concrete(I)
+ niblack_threshold(const Image<I>& input_, unsigned window_size,
+ double K,
+ Image<J>& simple_,
+ Image<J>& squared_)
+ {
+ trace::entering("scribo::binarization::impl::generic::niblack_threshold");
+
+ const I& input = exact(input_);
+ J& simple = exact(simple_);
+ J& squared = exact(squared_);
+
+ mln_assertion(input.is_valid());
+ mln_assertion(simple.is_valid());
+ mln_assertion(squared.is_valid());
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ initialize(internal::debug_mean, input);
+ initialize(internal::debug_stddev, input);
+ initialize(internal::debug_threshold, input);
+ initialize(internal::debug_alpham, input);
+ initialize(internal::debug_alphacond, input);
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ const mln::def::coord
+ nrows = static_cast<mln::def::coord>(input.nrows()),
+ ncols = static_cast<mln::def::coord>(input.ncols());
+
+
+ internal::niblack_formula formula;
+ for(mln::def::coord row = 0; row < nrows; ++row)
+ for(mln::def::coord col = 0; col < ncols; ++col)
+ {
+ // FIXME: Setting R parameter to 128 should not be
+ // hard-coded. Even though it is not used in Niblack's
+ // formula, this parameter is used for debug images and
+ // should be adapted to the data range values.
+ double t = internal::compute_local_threshold(P(row, col), simple,
+ squared, window_size,
+ K,
+ 128,
+ formula);
+ mln::convert::from_to(t, output.at_(row, col));
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ internal::debug_threshold.at_(row, col) = t;
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+ }
+
+ trace::exiting("scribo::binarization::impl::generic::niblack_threshold");
+ return output;
+ }
+
+ } // end of namespace scribo::binarization::impl::generic
+
+
+
+ template <typename I, typename J>
+ inline
+ mln_concrete(I)
+ niblack_threshold_gl(const I& input, unsigned window_size,
+ double K,
+ Image<J>& simple,
+ Image<J>& squared)
+ {
+ return impl::generic::niblack_threshold(input, window_size, K,
+ simple, squared);
+ }
+
+
+ } // end of namespace scribo::binarization::impl
+
+
+
+
+ // Dispatch
+
+ namespace internal
+ {
+
+ template <unsigned n, typename I, typename J>
+ inline
+ mln_ch_value(I, value::int_u<n>)
+ niblack_threshold_dispatch(const value::int_u<n>&, const I& input,
+ unsigned window_size,
+ double K,
+ J& simple,
+ J& squared)
+ {
+ return impl::niblack_threshold_gl(input, window_size, K,
+ simple, squared);
+ }
+
+
+ template <typename I, typename J>
+ inline
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold_dispatch(const mln_value(I)&, const I& input,
+ unsigned window_size,
+ double K,
+ J& simple,
+ J& squared)
+ {
+ // No dispatch for this kind of value type.
+ mlc_abort(I)::check();
+
+ typedef mln_ch_value(I,bool) output_t;
+ return output_t();
+ }
+
+
+ } // end of namespace scribo::binarization::internal
+
+
+
+ template <typename I, typename J>
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input, unsigned window_size,
+ double K,
+ Image<J>& simple,
+ Image<J>& squared)
+ {
+ trace::entering("scribo::binarization::niblack_threshold");
+
+ mln_precondition(mln_site_(I)::dim == 2);
+ mln_precondition(exact(input).is_valid());
+
+ typedef mln_value(I) value_t;
+ mln_ch_value(I, value::int_u8)
+ output = internal::niblack_threshold_dispatch(value_t(),
+ exact(input),
+ window_size,
+ K,
+ exact(simple),
+ exact(squared));
+
+ trace::exiting("scribo::text::ppm2pbm");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input, unsigned window_size,
+ double K)
+ {
+ mln_ch_value(I, double)
+ simple = init_integral_image(input, scribo::internal::identity_),
+ squared = init_integral_image(input, scribo::internal::square_);
+
+ return niblack_threshold(input, window_size,
+ K, simple, squared);
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input, unsigned window_size)
+ {
+ return niblack_threshold(input, window_size,
+ SCRIBO_DEFAULT_NIBLACK_K);
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ niblack_threshold(const Image<I>& input)
+ {
+ return niblack_threshold(input, 11);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_BINARIZATION_NIBLACK_THRESHOLD_HH
diff --git a/scribo/scribo/binarization/sauvola.hh b/scribo/scribo/binarization/sauvola.hh
index 45891c3..fc3e104 100644
--- a/scribo/scribo/binarization/sauvola.hh
+++ b/scribo/scribo/binarization/sauvola.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -35,15 +35,15 @@
# include <mln/data/transform.hh>
# include <mln/value/int_u8.hh>
-# include <scribo/binarization/sauvola_threshold_image.hh>
+# include <scribo/binarization/sauvola_threshold.hh>
# include <scribo/binarization/local_threshold.hh>
-# include <scribo/binarization/internal/sauvola_debug.hh>
+# include <scribo/binarization/internal/local_threshold_debug.hh>
-# ifdef SCRIBO_SAUVOLA_DEBUG
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
# include <mln/io/pgm/save.hh>
# include <mln/io/pbm/save.hh>
# include <mln/data/saturate.hh>
-# endif // ! SCRIBO_SAUVOLA_DEBUG
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
namespace scribo
{
@@ -110,11 +110,11 @@ namespace scribo
trace::entering("scribo::binarization::impl::generic::sauvola");
mln_precondition(exact(input).is_valid());
+ mln_ch_value(I,value::int_u8)
+ threshold_image = binarization::sauvola_threshold(input, window_size, K);
+
mln_ch_value(I, bool)
- output = local_threshold(input,
- binarization::sauvola_threshold_image(input,
- window_size,
- K));
+ output = local_threshold(input, threshold_image);
trace::exiting("scribo::binarization::impl::generic::sauvola");
return output;
@@ -168,7 +168,7 @@ namespace scribo
mln_ch_value(I, bool)
output = internal::sauvola_dispatch(input, window_size, K);
-# ifdef SCRIBO_SAUVOLA_DEBUG
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
if (internal::stddev_image_output)
io::pgm::save(data::saturate(value::int_u8(), internal::debug_stddev),
internal::stddev_image_output);
@@ -184,7 +184,7 @@ namespace scribo
internal::alpham_image_output);
if (internal::alphacond_image_output)
io::pbm::save(internal::debug_alphacond, internal::alphacond_image_output);
-# endif // ! SCRIBO_SAUVOLA_DEBUG
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
trace::exiting("scribo::binarization::sauvola");
diff --git a/scribo/scribo/binarization/sauvola_ms.hh b/scribo/scribo/binarization/sauvola_ms.hh
index c1a3414..36629f9 100644
--- a/scribo/scribo/binarization/sauvola_ms.hh
+++ b/scribo/scribo/binarization/sauvola_ms.hh
@@ -60,16 +60,15 @@
# include <scribo/core/macros.hh>
-# include <scribo/binarization/sauvola_threshold_image.hh>
# include <scribo/binarization/internal/first_pass_functor.hh>
# include <scribo/canvas/integral_browsing.hh>
-# ifdef SCRIBO_SAUVOLA_DEBUG
-# include <scribo/binarization/internal/sauvola_debug.hh>
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+# include <scribo/binarization/internal/local_threshold_debug.hh>
# include <mln/io/pgm/save.hh>
# include <scribo/make/debug_filename.hh>
-# endif // ! SCRIBO_SAUVOLA_DEBUG
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
@@ -179,7 +178,7 @@ namespace scribo
// 1st pass
scribo::binarization::internal::first_pass_functor< image2d<int_u8> >
- f(sub, K);
+ f(sub, K, SCRIBO_DEFAULT_SAUVOLA_R);
scribo::canvas::integral_browsing(integral_sum_sum_2,
ratio,
w_local_w, w_local_h,
@@ -259,10 +258,10 @@ namespace scribo
} // end of 2nd pass
-# ifdef SCRIBO_SAUVOLA_DEBUG
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
io::pbm::save(f.msk,
scribo::make::debug_filename(internal::threshold_image_output).c_str());
-# endif // ! SCRIBO_SAUVOLA_DEBUG
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
return f.t_sub;
}
@@ -923,18 +922,18 @@ namespace scribo
}
-# ifdef SCRIBO_SAUVOLA_DEBUG
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
if (internal::scale_image_output)
io::pgm::save(e_2, internal::scale_image_output);
-# endif // ! SCRIBO_SAUVOLA_DEBUG
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
// Propagate scale values.
e_2 = transform::influence_zone_geodesic(e_2, c8());
-// # ifdef SCRIBO_SAUVOLA_DEBUG
+// # ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
// if (internal::scale_image_output)
// io::pgm::save(e_2, internal::scale_image_output);
-// # endif // ! SCRIBO_SAUVOLA_DEBUG
+// # endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
// Binarize
image2d<bool>
diff --git a/scribo/scribo/binarization/sauvola_threshold.hh b/scribo/scribo/binarization/sauvola_threshold.hh
new file mode 100644
index 0000000..df46e95
--- /dev/null
+++ b/scribo/scribo/binarization/sauvola_threshold.hh
@@ -0,0 +1,296 @@
+// 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.
+
+#ifndef SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_HH
+# define SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_HH
+
+/// \file
+///
+/// Compute an image of local threshold using Sauvola algorithm.
+
+/// \fixme return type too restrictive!
+
+# include <algorithm>
+# include <cmath>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/int_u.hh>
+# include <mln/value/int_u8.hh>
+
+# include <scribo/core/init_integral_image.hh>
+# include <scribo/binarization/internal/compute_local_threshold.hh>
+# include <scribo/binarization/internal/sauvola_formula.hh>
+
+
+
+namespace scribo
+{
+
+ namespace binarization
+ {
+
+ using namespace mln;
+
+ /*! \brief Compute an image of local threshold using Sauvola algorithm.
+
+ \input[in] input A gray level image.
+ \input[in] window_size The window size.
+ \input[out] simple The sum of all intensities of \p input.
+ \input[out] squared The sum of all squared intensities of \p
+ input.
+
+ \return An image of local thresholds.
+
+ */
+ template <typename I, typename J>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size,
+ double K,
+ Image<J>& simple,
+ Image<J>& squared);
+
+ /// \overload
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size,
+ double K);
+
+ /// \overload
+ /// K is set to 0.34
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size);
+
+
+ /// \overload
+ /// The window size is set to 11.
+ //
+ template <typename I>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Implementation
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename J>
+ inline
+ mln_concrete(I)
+ sauvola_threshold(const Image<I>& input_, unsigned window_size,
+ double K,
+ Image<J>& simple_,
+ Image<J>& squared_)
+ {
+ trace::entering("scribo::binarization::impl::generic::sauvola_threshold");
+
+ const I& input = exact(input_);
+ J& simple = exact(simple_);
+ J& squared = exact(squared_);
+
+ mln_assertion(input.is_valid());
+ mln_assertion(simple.is_valid());
+ mln_assertion(squared.is_valid());
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ initialize(internal::debug_mean, input);
+ initialize(internal::debug_stddev, input);
+ initialize(internal::debug_threshold, input);
+ initialize(internal::debug_alpham, input);
+ initialize(internal::debug_alphacond, input);
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+
+ // Sauvola Algorithm with I.I.
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ const mln::def::coord
+ nrows = static_cast<mln::def::coord>(input.nrows()),
+ ncols = static_cast<mln::def::coord>(input.ncols());
+
+ internal::sauvola_formula formula;
+ for(mln::def::coord row = 0; row < nrows; ++row)
+ for(mln::def::coord col = 0; col < ncols; ++col)
+ {
+ double t = internal::compute_local_threshold(P(row, col), simple,
+ squared, window_size,
+ K,
+ SCRIBO_DEFAULT_SAUVOLA_R,
+ formula);
+ mln::convert::from_to(t, output.at_(row, col));
+
+# ifdef SCRIBO_LOCAL_THRESHOLD_DEBUG
+ internal::debug_threshold.at_(row, col) = t;
+# endif // ! SCRIBO_LOCAL_THRESHOLD_DEBUG
+ }
+
+ trace::exiting("scribo::binarization::impl::generic::sauvola_threshold");
+ return output;
+ }
+
+ } // end of namespace scribo::binarization::impl::generic
+
+
+
+ template <typename I, typename J>
+ inline
+ mln_concrete(I)
+ sauvola_threshold_gl(const I& input, unsigned window_size,
+ double K,
+ Image<J>& simple,
+ Image<J>& squared)
+ {
+ return impl::generic::sauvola_threshold(input, window_size, K,
+ simple, squared);
+ }
+
+
+ } // end of namespace scribo::binarization::impl
+
+
+
+
+ // Dispatch
+
+ namespace internal
+ {
+
+ template <unsigned n, typename I, typename J>
+ inline
+ mln_ch_value(I, value::int_u<n>)
+ sauvola_threshold_dispatch(const value::int_u<n>&, const I& input,
+ unsigned window_size,
+ double K,
+ J& simple,
+ J& squared)
+ {
+ return impl::sauvola_threshold_gl(input, window_size, K,
+ simple, squared);
+ }
+
+
+ template <typename I, typename J>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold_dispatch(const mln_value(I)&, const I& input,
+ unsigned window_size,
+ double K,
+ J& simple,
+ J& squared)
+ {
+ // No dispatch for this kind of value type.
+ mlc_abort(I)::check();
+
+ typedef mln_ch_value(I,bool) output_t;
+ return output_t();
+ }
+
+
+ } // end of namespace scribo::binarization::internal
+
+
+
+ template <typename I, typename J>
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size,
+ double K,
+ Image<J>& simple,
+ Image<J>& squared)
+ {
+ trace::entering("scribo::binarization::sauvola_threshold");
+
+ mln_precondition(mln_site_(I)::dim == 2);
+ mln_precondition(exact(input).is_valid());
+
+ typedef mln_value(I) value_t;
+ mln_ch_value(I, value::int_u8)
+ output = internal::sauvola_threshold_dispatch(value_t(),
+ exact(input),
+ window_size,
+ K,
+ exact(simple),
+ exact(squared));
+
+ trace::exiting("scribo::text::ppm2pbm");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size,
+ double K)
+ {
+ mln_ch_value(I, double)
+ simple = init_integral_image(input, scribo::internal::identity_),
+ squared = init_integral_image(input, scribo::internal::square_);
+
+ return sauvola_threshold(input, window_size,
+ K, simple, squared);
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input, unsigned window_size)
+ {
+ return sauvola_threshold(input, window_size,
+ SCRIBO_DEFAULT_SAUVOLA_K);
+ }
+
+
+ template <typename I>
+ inline
+ mln_ch_value(I, value::int_u8)
+ sauvola_threshold(const Image<I>& input)
+ {
+ return sauvola_threshold(input, 11);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::binarization
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_HH
diff --git a/scribo/scribo/binarization/sauvola_threshold_image.hh b/scribo/scribo/binarization/sauvola_threshold_image.hh
deleted file mode 100644
index 94cd688..0000000
--- a/scribo/scribo/binarization/sauvola_threshold_image.hh
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
-//
-// This file is part of Olena.
-//
-// Olena is free software: you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation, version 2 of the License.
-//
-// Olena is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Olena. If not, see <http://www.gnu.org/licenses/>.
-//
-// As a special exception, you may use this file as part of a free
-// software project without restriction. Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to produce
-// an executable, this file does not by itself cause the resulting
-// executable to be covered by the GNU General Public License. This
-// exception does not however invalidate any other reasons why the
-// executable file might be covered by the GNU General Public License.
-
-#ifndef SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_HH
-# define SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_HH
-
-/// \file
-///
-/// Compute an image of local threshold using Sauvola algorithm.
-
-/// \fixme return type too restrictive!
-
-# include <algorithm>
-# include <cmath>
-
-# include <mln/core/image/image2d.hh>
-# include <mln/value/int_u.hh>
-# include <mln/value/int_u8.hh>
-
-# include <scribo/core/init_integral_image.hh>
-# include <scribo/binarization/internal/compute_sauvola_threshold.hh>
-
-
-
-namespace scribo
-{
-
- namespace binarization
- {
-
- using namespace mln;
-
- /*! \brief Compute an image of local threshold using Sauvola algorithm.
-
- \input[in] input An image.
- \input[in] window_size The window size.
- \input[out] simple The sum of all intensities of \p input.
- \input[out] squared The sum of all squared intensities of \p
- input.
-
- \return An image of local thresholds.
-
- */
- template <typename I, typename J>
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size,
- double K,
- Image<J>& simple,
- Image<J>& squared);
-
- /// \overload
- template <typename I>
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size,
- double K);
-
- /// \overload
- /// K is set to 0.34
- template <typename I>
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size);
-
-
- /// \overload
- /// The window size is set to 11.
- //
- template <typename I>
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input);
-
-
-
-# ifndef MLN_INCLUDE_ONLY
-
-
- // Implementation
-
-
- namespace impl
- {
-
- namespace generic
- {
-
- template <typename I, typename J>
- inline
- mln_concrete(I)
- sauvola_threshold_image(const Image<I>& input_, unsigned window_size,
- double K,
- Image<J>& simple_,
- Image<J>& squared_)
- {
- trace::entering("scribo::binarization::impl::generic::sauvola_threshold_image");
-
- const I& input = exact(input_);
- J& simple = exact(simple_);
- J& squared = exact(squared_);
-
- mln_assertion(input.is_valid());
- mln_assertion(simple.is_valid());
- mln_assertion(squared.is_valid());
-
- typedef mln_value(I) V;
- typedef mln_site(I) P;
-
-# ifdef SCRIBO_SAUVOLA_DEBUG
- initialize(internal::debug_mean, input);
- initialize(internal::debug_stddev, input);
- initialize(internal::debug_threshold, input);
- initialize(internal::debug_alpham, input);
- initialize(internal::debug_alphacond, input);
-# endif // ! SCRIBO_SAUVOLA_DEBUG
-
- // Sauvola Algorithm with I.I.
-
- mln_concrete(I) output;
- initialize(output, input);
-
- const mln::def::coord
- nrows = static_cast<mln::def::coord>(input.nrows()),
- ncols = static_cast<mln::def::coord>(input.ncols());
-
-
- for(mln::def::coord row = 0; row < nrows; ++row)
- for(mln::def::coord col = 0; col < ncols; ++col)
- {
-# ifdef SCRIBO_SAUVOLA_DEBUG
-
- double t = internal::compute_sauvola_threshold(P(row, col), simple,
- squared, window_size,
- K,
- SCRIBO_DEFAULT_SAUVOLA_R);
- mln::convert::from_to(t, output.at_(row, col));
- internal::debug_threshold.at_(row, col) = t;
-# else
- mln::convert::from_to(
- internal::compute_sauvola_threshold(P(row, col), simple,
- squared, window_size,
- K,
- SCRIBO_DEFAULT_SAUVOLA_R),
- output.at_(row, col));
-# endif // ! SCRIBO_SAUVOLA_DEBUG
- }
-
- trace::exiting("scribo::binarization::impl::generic::sauvola_threshold");
- return output;
- }
-
- } // end of namespace scribo::binarization::impl::generic
-
-
-
- template <typename I, typename J>
- inline
- mln_concrete(I)
- sauvola_threshold_image_gl(const I& input, unsigned window_size,
- double K,
- Image<J>& simple,
- Image<J>& squared)
- {
- return impl::generic::sauvola_threshold_image(input, window_size, K,
- simple, squared);
- }
-
-
- } // end of namespace scribo::binarization::impl
-
-
-
-
- // Dispatch
-
- namespace internal
- {
-
- template <unsigned n, typename I, typename J>
- inline
- mln_ch_value(I, value::int_u<n>)
- sauvola_threshold_image_dispatch(const value::int_u<n>&, const I& input,
- unsigned window_size,
- double K,
- J& simple,
- J& squared)
- {
- return impl::sauvola_threshold_image_gl(input, window_size, K,
- simple, squared);
- }
-
-
- template <typename I, typename J>
- inline
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image_dispatch(const mln_value(I)&, const I& input,
- unsigned window_size,
- double K,
- J& simple,
- J& squared)
- {
- // No dispatch for this kind of value type.
- mlc_abort(I)::check();
-
- typedef mln_ch_value(I,bool) output_t;
- return output_t();
- }
-
-
- } // end of namespace scribo::binarization::internal
-
-
-
- template <typename I, typename J>
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size,
- double K,
- Image<J>& simple,
- Image<J>& squared)
- {
- trace::entering("scribo::binarization::sauvola_threshold_image");
-
- mln_precondition(mln_site_(I)::dim == 2);
- mln_precondition(exact(input).is_valid());
-
- typedef mln_value(I) value_t;
- mln_ch_value(I, value::int_u8)
- output = internal::sauvola_threshold_image_dispatch(value_t(),
- exact(input),
- window_size,
- K,
- exact(simple),
- exact(squared));
-
- trace::exiting("scribo::text::ppm2pbm");
- return output;
- }
-
-
- template <typename I>
- inline
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size,
- double K)
- {
- 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(input, window_size,
- K, simple, squared);
- }
-
-
- template <typename I>
- inline
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input, unsigned window_size)
- {
- return sauvola_threshold_image(input, window_size,
- SCRIBO_DEFAULT_SAUVOLA_K);
- }
-
-
- template <typename I>
- inline
- mln_ch_value(I, value::int_u8)
- sauvola_threshold_image(const Image<I>& input)
- {
- return sauvola_threshold_image(input, 11);
- }
-
-
-# endif // ! MLN_INCLUDE_ONLY
-
- } // end of namespace scribo::binarization
-
-} // end of namespace scribo
-
-
-#endif // ! SCRIBO_BINARIZATION_SAUVOLA_THRESHOLD_IMAGE_HH
diff --git a/scribo/src/binarization/Makefile.am b/scribo/src/binarization/Makefile.am
index 315e621..567972a 100644
--- a/scribo/src/binarization/Makefile.am
+++ b/scribo/src/binarization/Makefile.am
@@ -46,6 +46,7 @@ if HAVE_MAGICKXX
sauvola_ms_debug
utilexec_PROGRAMS = \
+ niblack \
otsu \
sauvola \
sauvola_ms \
@@ -60,6 +61,13 @@ if HAVE_MAGICKXX
$(MAGICKXX_LDFLAGS)
+ niblack_SOURCES = niblack.cc
+ niblack_CPPFLAGS = $(AM_CPPFLAGS) \
+ $(MAGICKXX_CPPFLAGS)
+ niblack_LDFLAGS = $(AM_LDFLAGS) \
+ $(MAGICKXX_LDFLAGS)
+
+
otsu_SOURCES = otsu.cc
otsu_CPPFLAGS = $(AM_CPPFLAGS) \
$(MAGICKXX_CPPFLAGS)
@@ -80,7 +88,7 @@ if HAVE_MAGICKXX
sauvola_debug_SOURCES = sauvola_debug.cc
sauvola_debug_CPPFLAGS = $(AM_CPPFLAGS) \
- -DSCRIBO_SAUVOLA_DEBUG \
+ -DSCRIBO_LOCAL_THRESHOLD_DEBUG \
$(MAGICKXX_CPPFLAGS)
sauvola_debug_LDFLAGS = $(AM_LDFLAGS) \
$(MAGICKXX_LDFLAGS)
@@ -94,7 +102,7 @@ if HAVE_MAGICKXX
sauvola_ms_debug_SOURCES = sauvola_ms_debug.cc
sauvola_ms_debug_CPPFLAGS = $(AM_CPPFLAGS) \
- -DSCRIBO_SAUVOLA_DEBUG \
+ -DSCRIBO_LOCAL_THRESHOLD_DEBUG \
$(MAGICKXX_CPPFLAGS)
sauvola_ms_debug_LDFLAGS = $(AM_LDFLAGS) \
$(MAGICKXX_LDFLAGS)
diff --git a/scribo/src/binarization/niblack.cc b/scribo/src/binarization/niblack.cc
new file mode 100644
index 0000000..4b7ed91
--- /dev/null
+++ b/scribo/src/binarization/niblack.cc
@@ -0,0 +1,106 @@
+// Copyright (C) 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/niblack.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", "Niblack's formulae parameter", "<value>", 0, 1, "-0.2" },
+ { "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::niblack(input_1_gl, w, k);
+
+ io::pbm::save(out, options.arg("output.pbm"));
+
+ trace::exiting("main");
+}
diff --git a/scribo/src/binarization/pgm_sauvola_threshold_image.cc b/scribo/src/binarization/pgm_sauvola_threshold_image.cc
index a38784a..69e2e15 100644
--- a/scribo/src/binarization/pgm_sauvola_threshold_image.cc
+++ b/scribo/src/binarization/pgm_sauvola_threshold_image.cc
@@ -1,4 +1,5 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -25,7 +26,7 @@
#include <mln/io/pgm/all.hh>
-#include <scribo/binarization/sauvola.hh>
+#include <scribo/binarization/sauvola_threshold.hh>
#include <scribo/debug/usage.hh>
const char *args_desc[][2] =
@@ -67,7 +68,7 @@ int main(int argc, char *argv[])
image2d<value::int_u8> input;
io::pgm::load(input, argv[1]);
- image2d<value::int_u8> out = scribo::binarization::sauvola_threshold_image(input, w, k);
+ image2d<value::int_u8> out = scribo::binarization::sauvola_threshold(input, w, k);
io::pgm::save(out, argv[2]);
diff --git a/scribo/tests/binarization/Makefile.am b/scribo/tests/binarization/Makefile.am
index b8ab2d9..a2962bb 100644
--- a/scribo/tests/binarization/Makefile.am
+++ b/scribo/tests/binarization/Makefile.am
@@ -21,6 +21,7 @@
include $(top_srcdir)/scribo/tests/tests.mk
EXTRA_DIST = \
+ niblack.res.pbm \
sauvola_ms.ref.pbm \
sauvola.ref.pbm \
otsu.ref.pbm
@@ -28,6 +29,7 @@ EXTRA_DIST = \
check_PROGRAMS = \
global_threshold \
local_threshold \
+ niblack \
otsu \
sauvola \
sauvola_ms
@@ -35,6 +37,7 @@ check_PROGRAMS = \
global_threshold_SOURCES = global_threshold.cc
local_threshold_SOURCES = local_threshold.cc
+niblack_SOURCES = niblack.cc
otsu_SOURCES = otsu.cc
sauvola_SOURCES = sauvola.cc
sauvola_ms_SOURCES = sauvola_ms.cc
diff --git a/scribo/tests/binarization/niblack.cc b/scribo/tests/binarization/niblack.cc
new file mode 100644
index 0000000..99a58e2
--- /dev/null
+++ b/scribo/tests/binarization/niblack.cc
@@ -0,0 +1,52 @@
+// Copyright (C) 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.
+
+/// \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 <mln/io/pbm/save.hh>
+
+#include <scribo/binarization/niblack.hh>
+
+#include "tests/data.hh"
+
+int main()
+{
+ using namespace mln;
+
+ image2d<value::int_u8> input;
+ io::pgm::load(input, MILENA_IMG_DIR "/lena.pgm");
+
+ image2d<bool> bin = scribo::binarization::niblack(input, 101);
+
+ image2d<bool> ref;
+ io::pbm::load(ref, SCRIBO_TESTS_DIR "binarization/niblack.ref.pbm");
+
+ mln_assertion(bin == ref);
+}
diff --git a/scribo/tests/binarization/niblack.ref.pbm b/scribo/tests/binarization/niblack.ref.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..7a3435193f1961f8161b71f8f60f3102d5ebbf87
GIT binary patch
literal 16498
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
literal 0
HcmV?d00001
--
1.7.2.5
* README (Bibliography): Here.
Fix copyright header.
* src/README: Fix copyright header.
---
scribo/ChangeLog | 8 ++++++++
scribo/README | 34 ++++++++++++++++++++++++++++++----
scribo/src/README | 9 +++++----
3 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 04c55b8..420997a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,11 @@
+2011-10-06 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Mention the ICDAR 2011 paper in SCRIBO's README.
+
+ * README (Bibliography): Here.
+ Fix copyright header.
+ * src/README: Fix copyright header.
+
2011-09-19 Guillaume Lazzara <z(a)lrde.epita.fr>
Fix paths in the SCRIBO viewer.
diff --git a/scribo/README b/scribo/README
index 84fe60a..4ba7f07 100644
--- a/scribo/README
+++ b/scribo/README
@@ -1,13 +1,13 @@
Copyright (C) 2009, 2010, 2011 EPITA Research and Development
Laboratory (LRDE)
-This file is part of Scribo.
+This file is part of Olena.
-Scribo is free software: you can redistribute it and/or modify it under
+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.
-Scribo is distributed in the hope that it will be useful,
+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.
@@ -80,4 +80,30 @@ KNOWN ISSUES
-fno-strict-aliasing flag.
- On Mac OS X Lion (10.7.0) prefer using GraphicsMagick++ instead of
- ImageMagick++. The latter may cause crashes.
\ No newline at end of file
+ ImageMagick++. The latter may cause crashes.
+
+
+============
+Bibliography
+============
+
+Further information about SCRIBO can be found into the following paper.
+
+ * `The SCRIBO Module of the Olena Platform: a Free Software
+ Framework for Document Image Analysis.` Guillaume Lazzara,
+ Roland Levillain, Thierry Géraud, Yann Jacquelet, Julien
+ Marquegnies, Arthur Crépin-Leblond. In the proceedings of the
+ 11th International Conference on Document Analysis and
+ Recognition (ICDAR)
+ http://www.icdar2011.org/
+ Beijing, China September 18 - 21, 2011.
+
+
+ You can download this paper and related material from
+<http://publications.lrde.epita.fr>.
+
+
+
+.. Local Variables:
+.. mode: rst
+.. End:
diff --git a/scribo/src/README b/scribo/src/README
index 582168d..9101525 100644
--- a/scribo/src/README
+++ b/scribo/src/README
@@ -1,12 +1,13 @@
-Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE)
+Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+Laboratory (LRDE)
-This file is part of Scribo.
+This file is part of Olena.
-Scribo is free software: you can redistribute it and/or modify it under
+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.
-Scribo is distributed in the hope that it will be useful,
+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.
--
1.7.2.5
---
ChangeLog | 4 ++++
README | 11 +++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b385e9c..2515596 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2011-10-06 Roland Levillain <roland(a)lrde.epita.fr>
+
+ * README (Bibliography): Mention the GRETSI 2011 paper.
+
2011-09-16 Roland Levillain <roland(a)lrde.epita.fr>
* configure.ac, NEWS: Version 2.0a.
diff --git a/README b/README
index 5c4bd9f..2ea740c 100644
--- a/README
+++ b/README
@@ -544,6 +544,13 @@ papers.
About Image Processing Programming:
+ * `Une approche générique du logiciel pour le traitement d'images
+ préservant les performances`. Roland Levillain, Thierry Géraud,
+ Laurent Najman. In the proceedings of the 23rd Symposium on
+ Signal and Image Processing (GRETSI)
+ http://www.gretsi2011.org/
+ Bordeaux, France, September 5 - 8, 2011.
+
* `Why and How to Design a Generic and Efficient Image Processing
Framework: The Case of the Milena Library`. Roland Levillain,
Thierry Géraud, Laurent Najman. In the proceedings of the 2010
@@ -618,8 +625,8 @@ About Generic Programming Paradigm:
2000.
- You can download these papers and related materials from
-<http://www.lrde.epita.fr/cgi-bin/twiki/view/Publications>
+ You can download these papers and related material from
+<http://publications.lrde.epita.fr>.
--
1.7.2.5
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch next has been updated
via 8f46b1c939d1f110f4ad55ba3c2fdb51c5c1d709 (commit)
via 0c903e4c6d40d4f86ebda65250c26274854f34cc (commit)
from 00537669dbd854328126aa97cb7e7658129de3da (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
8f46b1c Mention the ICDAR 2011 paper in SCRIBO's README.
0c903e4 README (Bibliography): Mention the GRETSI 2011 paper.
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 4 ++++
README | 11 +++++++++--
scribo/ChangeLog | 8 ++++++++
scribo/README | 34 ++++++++++++++++++++++++++++++----
scribo/src/README | 9 +++++----
5 files changed, 56 insertions(+), 10 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
* apps/morphers/mask+channel.cc,
* apps/morphers/recorder.cc,
* apps/morphers/mask+recorder.cc:
New.
* apps/morphers/Makefile.am: New.
* apps/Makefile.am (SUBDIRS): Add morphers.
---
milena/ChangeLog | 11 ++
milena/apps/Makefile.am | 5 +-
.../Makefile.am | 24 +++-
.../morphers/mask+channel.cc} | 76 +++++------
milena/apps/morphers/mask+recorder.cc | 140 ++++++++++++++++++++
milena/apps/morphers/recorder.cc | 135 +++++++++++++++++++
6 files changed, 338 insertions(+), 53 deletions(-)
copy milena/apps/{constrained-connectivity => morphers}/Makefile.am (62%)
copy milena/{doc/examples/tuto3_rw_image.cc => apps/morphers/mask+channel.cc} (58%)
create mode 100644 milena/apps/morphers/mask+recorder.cc
create mode 100644 milena/apps/morphers/recorder.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 544cc30..c10deb8 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,14 @@
+2011-11-14 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Add examples of morphers.
+
+ * apps/morphers/mask+channel.cc,
+ * apps/morphers/recorder.cc,
+ * apps/morphers/mask+recorder.cc:
+ New.
+ * apps/morphers/Makefile.am: New.
+ * apps/Makefile.am (SUBDIRS): Add morphers.
+
2011-10-04 Roland Levillain <roland(a)lrde.epita.fr>
Handle the case of filling an empty border.
diff --git a/milena/apps/Makefile.am b/milena/apps/Makefile.am
index c42ffd7..465f1db 100644
--- a/milena/apps/Makefile.am
+++ b/milena/apps/Makefile.am
@@ -1,4 +1,5 @@
-# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2008, 2009, 2011 EPITA Research and Development
+# Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -16,7 +17,7 @@
#
# Applied examples of Milena.
-SUBDIRS = mesh-segm-skel graph-morpho constrained-connectivity
+SUBDIRS = mesh-segm-skel graph-morpho constrained-connectivity morphers
# Examples from papers.
SUBDIRS += papers
diff --git a/milena/apps/constrained-connectivity/Makefile.am b/milena/apps/morphers/Makefile.am
similarity index 62%
copy from milena/apps/constrained-connectivity/Makefile.am
copy to milena/apps/morphers/Makefile.am
index c0dfb0d..d7af433 100644
--- a/milena/apps/constrained-connectivity/Makefile.am
+++ b/milena/apps/morphers/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -14,17 +14,27 @@
# You should have received a copy of the GNU General Public License
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
+# Illustrations of morphers.
+
# Find Milena headers.
AM_CPPFLAGS = -I$(top_srcdir)/milena -I$(top_builddir)/milena
# Produce fast code.
APPS_CXXFLAGS = @APPS_CXXFLAGS@
AM_CXXFLAGS = $(APPS_CXXFLAGS)
-noinst_PROGRAMS = constrained-connectivity
-constrained_connectivity_SOURCES = constrained-connectivity.cc
-constrained_connectivity_CXXFLAGS = $(AM_CXXFLAGS) $(STRICT_ALIASING_CXXFLAGS)
+noinst_PROGRAMS = \
+ mask+channel \
+ recorder \
+ mask+recorder
+
+mask_channel_SOURCES = mask+channel.cc
+recorder_SOURCES = recorder.cc
+mask_recorder_SOURCES = mask+recorder.cc
-TESTS = test-constrained-connectivity
+MOSTLYCLEANFILES = \
+ lena-mask-channel.ppm \
+ lena-fill??????.ppm \
+ lena-roi-fill??????.ppm
-# The sample image form Pierre Soille's PAMI 2008 article.
-EXTRA_DIST = soille.pgm
+# FIXME: Also produce movies (see comments in recorder.cc and
+# mask+recorder.cc.)
diff --git a/milena/doc/examples/tuto3_rw_image.cc b/milena/apps/morphers/mask+channel.cc
similarity index 58%
copy from milena/doc/examples/tuto3_rw_image.cc
copy to milena/apps/morphers/mask+channel.cc
index 14ba056..ffbe023 100644
--- a/milena/doc/examples/tuto3_rw_image.cc
+++ b/milena/apps/morphers/mask+channel.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,58 +24,46 @@
// executable file might be covered by the GNU General Public License.
/// \file
+/// \brief Example projecting a RGB image to the green channel and
+/// then applying a domain restricting with a mask.
-#include <mln/core/image/image2d.hh>
-#include <mln/value/rgb8.hh>
-#include <mln/data/fill.hh>
-#include <mln/data/paste.hh>
-#include <mln/core/routine/duplicate.hh>
-#include <mln/literal/colors.hh>
-#include <mln/opt/at.hh>
+#include <sstream>
+#include <iomanip>
-#include <tests/data.hh>
-#include <doc/tools/sample_utils.hh>
+#include <string>
-int main()
-{
- using namespace mln;
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/fun/component/green.hh>
- // \{
- image2d<value::rgb8> ima(40, 40);
- // \}
+#include <mln/value/rgb8.hh>
+
+/* FIXME: We wanted to use `fun_image' and `operator<<' from
+ <mln/core/image/vmorph/fun_image.hh, but they only create read-only
+ images. Use `thru_image' instead. */
+#include <mln/core/image/vmorph/thru_image.hh>
- // \{
- data::fill(ima, literal::red);
- // \}
+#include <mln/core/routine/duplicate.hh>
- // \{
- for (def::coord row = 20; row < 30; ++row)
- for (def::coord col = 20; col < 30; ++col)
- ima(point2d(row, col)) = literal::blue;
- // \}
+#include <mln/literal/colors.hh>
+#include <mln/data/fill.hh>
- // \{
- for (def::coord row = 20; row < 30; ++row)
- for (def::coord col = 20; col < 30; ++col)
- opt::at(ima, row, col) = literal::blue;
- // \}
- doc::ppmsave(ima, "tuto3_rw_image");
+#include <mln/io/ppm/all.hh>
- image2d<value::rgb8> ima2 = duplicate(ima);
+#include "apps/data.hh"
- // \{
- image2d<value::rgb8> lena;
- io::ppm::load(lena, MLN_IMG_DIR "/small.ppm");
- // \}
- // \{
- data::fill(ima, lena);
- // \}
- doc::ppmsave(ima, "tuto3_rw_image");
+int main()
+{
+ using namespace mln;
+ using mln::value::rgb8;
- ima = ima2;
- // \{
- data::paste(ima, lena);
- // \}
- doc::ppmsave(lena, "tuto3_rw_image");
+ image2d<rgb8> lena = io::ppm::load<rgb8>(MLN_IMG_DIR "/tiny.ppm");
+ fun::green green;
+ /* FIXME: Cheat: use generic fill as mln::decorated_image does not
+ define properly its properties. */
+ data::impl::generic::fill_with_value((thru(green, lena).rw() |
+ box2d(point2d(5,5), point2d(10,10))).rw(),
+ 255);
+ io::ppm::save(lena, "lena-mask-channel.ppm");
}
diff --git a/milena/apps/morphers/mask+recorder.cc b/milena/apps/morphers/mask+recorder.cc
new file mode 100644
index 0000000..d697451
--- /dev/null
+++ b/milena/apps/morphers/mask+recorder.cc
@@ -0,0 +1,140 @@
+// Copyright (C) 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.
+
+/// \file
+/// \brief Morpher recording every change in the morphed image
+/// followed by the application of a domain restriction with a mask.
+///
+/// To produce an AVI movie from the `lena-roi-fill*.ppm' files, use:
+///
+/// for f in lena-roi-fill*ppm; convert $f -scale 2500% $(basename $f .ppm).png
+/// mencoder "mf://lena-roi-fill*.png" -o lena-roi-fill.avi -ovc lavc -lavcopts vcodec=mjpeg
+///
+/// The output `lena-roi-fill.avi' can be embedded in a PDF file. */
+
+// FIXME: Factor with recorder.cc.
+
+#include <sstream>
+#include <iomanip>
+
+#include <string>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+#include <mln/core/image/imorph/decorated_image.hh>
+
+#include <mln/value/rgb8.hh>
+
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/literal/colors.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/io/ppm/all.hh>
+
+#include "apps/data.hh"
+
+
+// FIXME: mln::decorated_image lacks a proper definition of
+// properties! (see mln/core/image/imorph/decorated_image.hh
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename I, typename D>
+ struct image_< decorated_image<I,D> >
+ : default_image_morpher< I,
+ mln_value(I),
+ decorated_image<I,D> >
+ {
+ typedef trait::image::category::identity_morpher category;
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+// Recorder.
+template <typename I>
+struct recorder
+{
+ void reading(const I&, const mln_psite(I)&) const
+ {
+ // N/A.
+ }
+
+ void writing(I& ima, const mln_psite(I)&, const mln_value(I)&)
+ {
+ sequence.push_back(mln::duplicate(ima));
+ }
+
+ std::vector<I> sequence;
+};
+
+template <typename I>
+mln::decorated_image< I, recorder<I> >
+record(mln::Image<I>& ima)
+{
+ return mln::decorate(ima, recorder<I>());
+}
+
+
+// I/O.
+namespace ppm
+{
+ template <typename I>
+ void
+ save(const mln::decorated_image< I, recorder<I> >& rec,
+ const std::string& prefix)
+ {
+ for (size_t i = 0; i < rec.decoration().sequence.size(); ++i)
+ {
+ std::stringstream s;
+ s << std::setfill ('0') << std::setw (6) << i;
+ mln::io::ppm::save(rec.decoration().sequence[i],
+ prefix + s.str() + ".ppm");
+ }
+ }
+}
+
+
+int main()
+{
+ using namespace mln;
+ using mln::value::rgb8;
+
+ typedef image2d<rgb8> I;
+ I lena = io::ppm::load<rgb8>(MLN_IMG_DIR "/tiny.ppm");
+ decorated_image< I, recorder<I> > lena_rec = record(lena);
+ /* FIXME: Cheat: use generic fill as mln::decorated_image does not
+ define properly its properties. */
+ data::impl::generic::fill_with_value((lena_rec | box2d(point2d(5,5),
+ point2d(10,10))).rw(),
+ literal::green);
+ ppm::save(lena_rec, "lena-roi-fill");
+}
diff --git a/milena/apps/morphers/recorder.cc b/milena/apps/morphers/recorder.cc
new file mode 100644
index 0000000..195f24c
--- /dev/null
+++ b/milena/apps/morphers/recorder.cc
@@ -0,0 +1,135 @@
+// Copyright (C) 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.
+
+/// \file
+/// \brief Morpher recording every change in the morphed image.
+///
+/// To produce an AVI movie from the `lena-fill*.ppm' files, use:
+///
+/// for f in lena-fill*ppm; convert $f -scale 2500% $(basename $f .ppm).png
+/// mencoder "mf://lena-fill*.png" -o lena-fill.avi -ovc lavc -lavcopts vcodec=mjpeg
+///
+/// The output `lena-fill.avi' can be embedded in a PDF file. */
+
+#include <sstream>
+#include <iomanip>
+
+#include <string>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/imorph/decorated_image.hh>
+
+#include <mln/value/rgb8.hh>
+
+#include <mln/core/routine/duplicate.hh>
+
+#include <mln/literal/colors.hh>
+#include <mln/data/fill.hh>
+
+#include <mln/io/ppm/all.hh>
+
+#include "apps/data.hh"
+
+
+// FIXME: mln::decorated_image lacks a proper definition of
+// properties! (see mln/core/image/imorph/decorated_image.hh
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename I, typename D>
+ struct image_< decorated_image<I,D> >
+ : default_image_morpher< I,
+ mln_value(I),
+ decorated_image<I,D> >
+ {
+ typedef trait::image::category::identity_morpher category;
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+
+// Recorder.
+template <typename I>
+struct recorder
+{
+ void reading(const I&, const mln_psite(I)&) const
+ {
+ // N/A.
+ }
+
+ void writing(I& ima, const mln_psite(I)&, const mln_value(I)&)
+ {
+ sequence.push_back(mln::duplicate(ima));
+ }
+
+ std::vector<I> sequence;
+};
+
+template <typename I>
+mln::decorated_image< I, recorder<I> >
+record(mln::Image<I>& ima)
+{
+ return mln::decorate(ima, recorder<I>());
+}
+
+
+// I/O.
+namespace ppm
+{
+ template <typename I>
+ void
+ save(const mln::decorated_image< I, recorder<I> >& rec,
+ const std::string& prefix)
+ {
+ for (size_t i = 0; i < rec.decoration().sequence.size(); ++i)
+ {
+ std::stringstream s;
+ s << std::setfill ('0') << std::setw (6) << i;
+ mln::io::ppm::save(rec.decoration().sequence[i],
+ prefix + s.str() + ".ppm");
+ }
+ }
+}
+
+
+int main()
+{
+ using namespace mln;
+ using mln::value::rgb8;
+
+ typedef image2d<rgb8> I;
+ I lena = io::ppm::load<rgb8>(MLN_IMG_DIR "/tiny.ppm");
+ decorated_image< I, recorder<I> > lena_rec = record(lena);
+ /* FIXME: Cheat: use generic fill as mln::decorated_image does not
+ define properly its properties. */
+ data::impl::generic::fill_with_value(lena_rec,
+ literal::green);
+ ppm::save(lena_rec, "lena-fill");
+}
--
1.7.2.5