33 int bytes_per_pixel,
int bytes_per_line,
34 int left,
int top,
int width,
int height,
35 int** thresholds,
int** hi_values) {
38 int best_hi_value = 1;
39 int best_hi_index = 0;
40 bool any_good_hivalue =
false;
41 double best_hi_dist = 0.0;
42 *thresholds =
new int[bytes_per_pixel];
43 *hi_values =
new int[bytes_per_pixel];
45 for (
int ch = 0; ch < bytes_per_pixel; ++ch) {
46 (*thresholds)[ch] = -1;
47 (*hi_values)[ch] = -1;
50 HistogramRect(imagedata + ch, bytes_per_pixel, bytes_per_line,
51 left, top, width, height, histogram);
54 int best_t =
OtsuStats(histogram, &H, &best_omega_0);
55 if (best_omega_0 == 0 || best_omega_0 == H) {
62 int hi_value = best_omega_0 < H * 0.5;
63 (*thresholds)[ch] = best_t;
64 if (best_omega_0 > H * 0.75) {
65 any_good_hivalue =
true;
67 }
else if (best_omega_0 < H * 0.25) {
68 any_good_hivalue =
true;
72 double hi_dist = hi_value ? (H - best_omega_0) : best_omega_0;
73 if (hi_dist > best_hi_dist) {
74 best_hi_dist = hi_dist;
75 best_hi_value = hi_value;
80 if (!any_good_hivalue) {
82 (*hi_values)[best_hi_index] = best_hi_value;
94 int bytes_per_pixel,
int bytes_per_line,
95 int left,
int top,
int width,
int height,
97 int bottom = top + height;
99 const unsigned char* pixels = imagedata +
100 top * bytes_per_line +
101 left * bytes_per_pixel;
102 for (
int y = top; y < bottom; ++y) {
103 for (
int x = 0; x < width; ++x) {
104 ++histogram[pixels[x * bytes_per_pixel]];
106 pixels += bytes_per_line;
113 int OtsuStats(
const int* histogram,
int* H_out,
int* omega0_out) {
118 mu_T +=
static_cast<double>(i) * histogram[i];
124 int omega_0, omega_1;
125 int best_omega_0 = 0;
126 double best_sig_sq_B = 0.0;
127 double mu_0, mu_1, mu_t;
130 for (
int t = 0; t < kHistogramSize - 1; ++t) {
131 omega_0 += histogram[t];
132 mu_t += t *
static_cast<double>(histogram[t]);
135 omega_1 = H - omega_0;
138 mu_0 = mu_t / omega_0;
139 mu_1 = (mu_T - mu_t) / omega_1;
140 double sig_sq_B = mu_1 - mu_0;
141 sig_sq_B *= sig_sq_B * omega_0 * omega_1;
142 if (best_t < 0 || sig_sq_B > best_sig_sq_B) {
143 best_sig_sq_B = sig_sq_B;
145 best_omega_0 = omega_0;
148 if (H_out !=
NULL) *H_out = H;
149 if (omega0_out !=
NULL) *omega0_out = best_omega_0;