
* scribo/estim/font_color.hh: Fix namespace ambiguities. * src/binarization/Makefile.am: Add kim as target. * src/binarization/kim.cc: Cleanup code. * src/binarization/niblack.cc: Fix reverse video. * src/binarization/sauvola_ms.cc: Handle several k values. --- scribo/ChangeLog | 14 +++ scribo/scribo/estim/font_color.hh | 4 +- scribo/src/binarization/Makefile.am | 7 ++ scribo/src/binarization/kim.cc | 143 +++++++++++++++------------------ scribo/src/binarization/niblack.cc | 5 +- scribo/src/binarization/sauvola_ms.cc | 17 +++- 6 files changed, 105 insertions(+), 85 deletions(-) diff --git a/scribo/ChangeLog b/scribo/ChangeLog index 4e61cec..1c1295b 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,19 @@ 2012-08-23 Guillaume Lazzara <z@lrde.epita.fr> + Several small fixes. + + * scribo/estim/font_color.hh: Fix namespace ambiguities. + + * src/binarization/Makefile.am: Add kim as target. + + * src/binarization/kim.cc: Cleanup code. + + * src/binarization/niblack.cc: Fix reverse video. + + * src/binarization/sauvola_ms.cc: Handle several k values. + +2012-08-23 Guillaume Lazzara <z@lrde.epita.fr> + Improve documentation. * scribo/binarization/sauvola_ms.hh, diff --git a/scribo/scribo/estim/font_color.hh b/scribo/scribo/estim/font_color.hh index 9a3c429..78e8c83 100644 --- a/scribo/scribo/estim/font_color.hh +++ b/scribo/scribo/estim/font_color.hh @@ -83,7 +83,7 @@ namespace scribo mln_ch_value(I,value::int_u8) lbl = labeling::blobs(skel, c8(), nlabels); - util::array<algebra::vec<3u, float> > res = + mln::util::array<algebra::vec<3u, float> > res = labeling::compute(accu::meta::stat::mean(), text_ima, lbl, nlabels); accu::stat::median_h<value::int_u12> m_red; @@ -131,7 +131,7 @@ namespace scribo value::int_u8 nlabels = 0; mln_ch_value(J,value::int_u8) lbl = labeling::blobs(skel, c8(), nlabels); - util::array<algebra::vec<3u, float> > res = + mln::util::array<algebra::vec<3u, float> > res = labeling::compute(accu::meta::stat::mean(), text_ima, lbl, nlabels); accu::stat::median_h<value::int_u12> m_val; diff --git a/scribo/src/binarization/Makefile.am b/scribo/src/binarization/Makefile.am index b29ac30..db168fa 100644 --- a/scribo/src/binarization/Makefile.am +++ b/scribo/src/binarization/Makefile.am @@ -30,6 +30,7 @@ if HAVE_MAGICKXX sauvola_ms_debug utilexec_PROGRAMS = \ + kim \ niblack \ otsu \ sauvola \ @@ -66,6 +67,12 @@ if HAVE_MAGICKXX sauvola_ms_fg_LDFLAGS = $(AM_LDFLAGS) \ $(MAGICKXX_LDFLAGS) + kim_SOURCES = kim.cc + kim_CPPFLAGS = $(AM_CPPFLAGS) \ + $(MAGICKXX_CPPFLAGS) + kim_LDFLAGS = $(AM_LDFLAGS) \ + $(MAGICKXX_LDFLAGS) + sauvola_SOURCES = sauvola.cc sauvola_CPPFLAGS = $(AM_CPPFLAGS) \ $(MAGICKXX_CPPFLAGS) diff --git a/scribo/src/binarization/kim.cc b/scribo/src/binarization/kim.cc index 7294a9c..aa81f50 100644 --- a/scribo/src/binarization/kim.cc +++ b/scribo/src/binarization/kim.cc @@ -77,6 +77,47 @@ static const scribo::debug::opt_data opt_desc[] = +double +compute_thres(const mln::image2d<mln::util::couple<double,double> >& integral_sum_sum_2, + int row, int col, unsigned win_size, + const scribo::binarization::internal::sauvola_formula& formula) +{ + point2d + tl(row - win_size - 1, + col - win_size - 1), + br(row + win_size, + col + win_size); + + box2d b(tl, br); + b.crop_wrt(integral_sum_sum_2.domain()); + + point2d tr = b.pmax(); + tr.row() = b.pmin().row(); + point2d bl = b.pmin(); + bl.row() = b.pmax().row(); + + unsigned card_min = b.nsites() - b.height() - b.width() + 1; + + const mln::util::couple<double,double>& + D = integral_sum_sum_2(b.pmax()), + B = integral_sum_sum_2(tr), + C = integral_sum_sum_2(bl), + A = integral_sum_sum_2(b.pmin()); + + double sum = D.first() - B.first() - C.first() + A.first(); + double sum_2 = D.second() - B.second() - C.second() + A.second(); + double mean = sum / card_min; + + double num = (sum_2 - sum * sum / card_min); + double stddev; + if (num > 0) + stddev = std::sqrt(num / (card_min - 1)); + else + stddev = 0; + + return formula(mean, stddev); +} + int main(int argc, char *argv[]) @@ -202,97 +243,43 @@ int main(int argc, char *argv[]) if (!lines(i).is_textline()) continue; - math::round<double> round; double win_min = thickness(lines(i).id()), - win_max = lines(i).bbox().height(), - card_min, - card_max; + win_max = lines(i).bbox().height();; mln_assertion(win_min != 0); mln_assertion(win_max != 0); - binarization::internal::sauvola_formula compute_thres; - point2d tl, br; + scribo::binarization::internal::sauvola_formula formula; - mln_piter(L) p(lines(i).bbox()); - for_all(p) + for (int row = lines(i).bbox().pmin().row(); + row <= lines(i).bbox().pmax().row(); + ++row) { + bool* out_ptr = &output.at_(row, lines(i).bbox().pmin().col()); + value::int_u8* in_ptr = &input_1_gl.at_(row, lines(i).bbox().pmin().col()); + for (int col = lines(i).bbox().pmin().col(); + col <= lines(i).bbox().pmax().col(); + ++col) + { + // Min case + double T_min = compute_thres(integral_sum_sum_2, row, col, win_min, formula); - // Min case - tl.row() = (p.row() - win_min - 1); - tl.col() = (p.col() - win_min - 1); - - br.row() = (p.row() + win_min); - br.col() = (p.col() + win_min); - - box2d b(tl, br); - b.crop_wrt(integral_sum_sum_2.domain()); - - point2d tr = b.pmax(); - tr.row() = b.pmin().row(); - point2d bl = b.pmin(); - bl.row() = b.pmax().row(); - - card_min = b.nsites() - b.height() - b.width() + 1; - - double sum = integral_sum_sum_2(b.pmax()).first() - integral_sum_sum_2(tr).first() - integral_sum_sum_2(bl).first() + integral_sum_sum_2(b.pmin()).first(); - double sum_2 = integral_sum_sum_2(b.pmax()).second() - integral_sum_sum_2(tr).second() - integral_sum_sum_2(bl).second() + integral_sum_sum_2(b.pmin()).second(); - double mean = sum / card_min; - - double num = (sum_2 - sum * sum / card_min); - double stddev = 0; - if (num > 0) - stddev = std::sqrt(num / (card_min - 1)); - else - stddev = 0; - - - double T_min = compute_thres(mean, stddev); - - // Max case - tl.row() = (p.row() - win_max - 1); - tl.col() = (p.col() - win_max - 1); - - br.row() = (p.row() + win_max); - br.col() = (p.col() + win_max); - - b = box2d(tl, br); - b.crop_wrt(integral_sum_sum_2.domain()); - - tr = b.pmax(); - tr.row() = b.pmin().row(); - bl = b.pmin(); - bl.row() = b.pmax().row(); - - card_max = b.nsites() - b.height() - b.width() + 1; - - sum = integral_sum_sum_2(b.pmax()).first() - integral_sum_sum_2(tr).first() - integral_sum_sum_2(bl).first() + integral_sum_sum_2(b.pmin()).first(); - sum_2 = integral_sum_sum_2(b.pmax()).second() - integral_sum_sum_2(tr).second() - integral_sum_sum_2(bl).second() + integral_sum_sum_2(b.pmin()).second(); - mean = sum / card_max; - - num = (sum_2 - sum * sum / card_max); - stddev = 0; - if (num > 0) - stddev = std::sqrt(num / (card_max - 1)); - else - stddev = 0; - - double T_max = compute_thres(mean, stddev); - - - // Final threshold + // Max case + double T_max = compute_thres(integral_sum_sum_2, row, col, win_max, formula); - double teta = 0.3; - double T = teta * T_max + (1 - teta) * T_min; + // Final threshold + double teta = 0.3; // Good results from 0.1 to 0.3 according + // to the paper. + double T = teta * T_max + (1 - teta) * T_min; - mln_assertion(T_min <= 255); - mln_assertion(T_max <= 255); - mln_assertion(T <= 255); + mln_assertion(T_min <= 255); + mln_assertion(T_max <= 255); + mln_assertion(T <= 255); - output(p) = input_1_gl(p) <= T; + *out_ptr++ = *in_ptr++ <= T; + } } - } lt.stop(); diff --git a/scribo/src/binarization/niblack.cc b/scribo/src/binarization/niblack.cc index 4b7ed91..58074fc 100644 --- a/scribo/src/binarization/niblack.cc +++ b/scribo/src/binarization/niblack.cc @@ -29,6 +29,8 @@ #include <mln/io/pbm/save.hh> #include <mln/data/transform.hh> #include <mln/fun/v2v/rgb_to_luma.hh> +#include <mln/arith/revert.hh> +#include <mln/logical/not.hh> #include <scribo/binarization/niblack.hh> #include <scribo/debug/option_parser.hh> @@ -98,8 +100,9 @@ int main(int argc, char *argv[]) image2d<value::int_u8> input_1_gl = data::transform(input, mln::fun::v2v::rgb_to_luma<value::int_u8>()); + arith::revert_inplace(input_1_gl); image2d<bool> out = scribo::binarization::niblack(input_1_gl, w, k); - + logical::not_inplace(out); io::pbm::save(out, options.arg("output.pbm")); trace::exiting("main"); diff --git a/scribo/src/binarization/sauvola_ms.cc b/scribo/src/binarization/sauvola_ms.cc index 483a35b..d07de72 100644 --- a/scribo/src/binarization/sauvola_ms.cc +++ b/scribo/src/binarization/sauvola_ms.cc @@ -109,15 +109,24 @@ int main(int argc, char *argv[]) unsigned s = atoi(options.opt_value("s").c_str()); double k = atof(options.opt_value("k").c_str()); + if (options.is_set("k")) + { + binarization::internal::k2 = k; + binarization::internal::k3 = k; + binarization::internal::k4 = k; + } + else + { + binarization::internal::k2 = atof(options.opt_value("k2").c_str()); + binarization::internal::k3 = atof(options.opt_value("k3").c_str()); + binarization::internal::k4 = atof(options.opt_value("k4").c_str()); + } + if (verbose) std::cout << "Using w_1=" << w_1 << " - s=" << s << " - k=" << k << std::endl; - binarization::internal::k2 = atof(options.opt_value("k2").c_str()); - binarization::internal::k3 = atof(options.opt_value("k3").c_str()); - binarization::internal::k4 = atof(options.opt_value("k4").c_str()); - // Load image2d<value::rgb8> input_1; -- 1.7.2.5
participants (1)
-
Guillaume Lazzara