27 #ifndef SCRIBO_BINARIZATION_KIM_HH
28 # define SCRIBO_BINARIZATION_KIM_HH
36 #include <scribo/binarization/sauvola.hh>
37 #include <scribo/util/integral_sum_sum2_functor.hh>
38 #include <scribo/text/extract_lines.hh>
61 kim(const
Image<I>& input,
unsigned window_size,
double k);
70 kim(const
Image<I>& input,
unsigned window_size);
73 # ifndef MLN_INCLUDE_ONLY
80 int row,
int col,
unsigned win_size,
84 tl(row - win_size - 1,
90 b.crop_wrt(integral_sum_sum_2.domain());
93 tr.
row() = b.pmin().row();
95 bl.
row() = b.pmax().row();
97 unsigned card_min = b.nsites() - b.height() - b.width() + 1;
100 D = integral_sum_sum_2(b.pmax()),
101 B = integral_sum_sum_2(tr),
102 C = integral_sum_sum_2(bl),
103 A = integral_sum_sum_2(b.pmin());
105 double sum = D.
first() - B.first() - C.first() + A.first();
106 double sum_2 = D.
second() - B.second() - C.second() + A.second();
107 double mean = sum / card_min;
109 double num = (sum_2 - sum * sum / card_min);
112 stddev =
std::sqrt(num / (card_min - 1));
116 return formula(mean, stddev);
122 template <
typename I>
124 kim(const
Image<I>& input_,
unsigned window_size,
double k)
126 mln_trace(
"scribo::binarization::kim");
128 const I& input =
exact(input_);
130 mln_precondition(input.is_valid());
139 integral_sum_sum_2 = scribo::util::init_integral_image(input, 1, f_sum_sum2);
142 line_set<image2d<scribo::def::lbl_type> >
148 const component_set<L>& comp_set = lines.components();
149 const L& lbl = comp_set.labeled_image();
153 for_all_lines(i, lines)
155 if (!lines(i).is_textline())
158 std::map<unsigned, unsigned>
histo;
160 for (
int l = lines(i).
bbox().pmin().row(); l <= lines(i).bbox().pmax().row(); ++l)
162 const V* end_ptr = &lbl.at_(l, lines(i).
bbox().pmax().col() + 1);
163 for (
const V* run_ptr = &lbl.at_(l, lines(i).
bbox().pmin().col()); run_ptr != end_ptr; ++run_ptr)
169 if (histo.find(count) != histo.end())
172 histo.insert(std::make_pair(count, 1));
179 for (std::map<unsigned, unsigned>::const_iterator it = histo.begin(); it != histo.end(); ++it)
180 if (it->second > max)
190 for_all_lines(i, lines)
192 if (!lines(i).is_textline())
197 win_max = lines(i).bbox().height();;
199 mln_assertion(win_min != 0);
200 mln_assertion(win_max != 0);
206 for (
int row = lines(i).
bbox().pmin().row();
207 row <= lines(i).bbox().pmax().row();
210 bool* out_ptr = &output.at_(row, lines(i).
bbox().pmin().col());
211 const mln_value(I)* in_ptr = &input.at_(row, lines(i).
bbox().pmin().col());
212 for (
int col = lines(i).
bbox().pmin().col();
213 col <= lines(i).bbox().pmax().col();
217 double T_min = compute_thres(integral_sum_sum_2, row, col, win_min, formula);
220 double T_max = compute_thres(integral_sum_sum_2, row, col, win_max, formula);
223 double T = teta * T_max + (1 - teta) * T_min;
225 mln_assertion(T_min <= 255);
226 mln_assertion(T_max <= 255);
227 mln_assertion(T <= 255);
229 *out_ptr++ = *in_ptr++ <= T;
238 template <
typename I>
240 kim(const
Image<I>& input,
unsigned window_size)
242 return kim(input, window_size, SCRIBO_DEFAULT_SAUVOLA_K);
245 # endif // ! MLN_INCLUDE_ONLY
251 #endif // ! SCRIBO_BINARIZATION_KIM_HH