23 #include "allheaders.h"
39 int OtsuThreshold(Pix* src_pix,
int left,
int top,
int width,
int height,
40 int** thresholds,
int** hi_values) {
41 int num_channels = pixGetDepth(src_pix) / 8;
45 int best_hi_value = 1;
46 int best_hi_index = 0;
47 bool any_good_hivalue =
false;
48 double best_hi_dist = 0.0;
49 *thresholds =
new int[num_channels];
50 *hi_values =
new int[num_channels];
52 int *histogramAllChannels =
new int[
kHistogramSize * num_channels];
58 if (od.selectedDeviceIsOpenCL() &&
59 (num_channels == 1 || num_channels == 4) && top == 0 && left == 0 ) {
61 (
const unsigned char*)pixGetData(src_pix),
63 pixGetWpl(src_pix) * 4,
69 histogramAllChannels);
72 for (
int ch = 0; ch < num_channels; ++ch) {
73 (*thresholds)[ch] = -1;
74 (*hi_values)[ch] = -1;
78 int best_t =
OtsuStats(histogram, &H, &best_omega_0);
79 if (best_omega_0 == 0 || best_omega_0 == H) {
86 int hi_value = best_omega_0 < H * 0.5;
87 (*thresholds)[ch] = best_t;
88 if (best_omega_0 > H * 0.75) {
89 any_good_hivalue =
true;
91 }
else if (best_omega_0 < H * 0.25) {
92 any_good_hivalue =
true;
96 double hi_dist = hi_value ? (H - best_omega_0) : best_omega_0;
97 if (hi_dist > best_hi_dist) {
98 best_hi_dist = hi_dist;
99 best_hi_value = hi_value;
106 for (
int ch = 0; ch < num_channels; ++ch) {
107 (*thresholds)[ch] = -1;
108 (*hi_values)[ch] = -1;
111 HistogramRect(src_pix, ch, left, top, width, height, histogram);
114 int best_t =
OtsuStats(histogram, &H, &best_omega_0);
115 if (best_omega_0 == 0 || best_omega_0 == H) {
122 int hi_value = best_omega_0 < H * 0.5;
123 (*thresholds)[ch] = best_t;
124 if (best_omega_0 > H * 0.75) {
125 any_good_hivalue =
true;
126 (*hi_values)[ch] = 0;
127 }
else if (best_omega_0 < H * 0.25) {
128 any_good_hivalue =
true;
129 (*hi_values)[ch] = 1;
132 double hi_dist = hi_value ? (H - best_omega_0) : best_omega_0;
133 if (hi_dist > best_hi_dist) {
134 best_hi_dist = hi_dist;
135 best_hi_value = hi_value;
143 delete[] histogramAllChannels;
145 if (!any_good_hivalue) {
147 (*hi_values)[best_hi_index] = best_hi_value;
158 int left,
int top,
int width,
int height,
161 int num_channels = pixGetDepth(src_pix) / 8;
162 channel =
ClipToRange(channel, 0, num_channels - 1);
163 int bottom = top + height;
165 int src_wpl = pixGetWpl(src_pix);
166 l_uint32* srcdata = pixGetData(src_pix);
167 for (
int y = top; y < bottom; ++y) {
168 const l_uint32* linedata = srcdata + y * src_wpl;
169 for (
int x = 0; x < width; ++x) {
170 int pixel = GET_DATA_BYTE(const_cast<void*>(
171 reinterpret_cast<const void *>(linedata)),
172 (x + left) * num_channels + channel);
182 int OtsuStats(
const int* histogram,
int* H_out,
int* omega0_out) {
187 mu_T +=
static_cast<double>(i) * histogram[i];
193 int omega_0, omega_1;
194 int best_omega_0 = 0;
195 double best_sig_sq_B = 0.0;
196 double mu_0, mu_1, mu_t;
199 for (
int t = 0; t < kHistogramSize - 1; ++t) {
200 omega_0 += histogram[t];
201 mu_t += t *
static_cast<double>(histogram[t]);
204 omega_1 = H - omega_0;
207 mu_0 = mu_t / omega_0;
208 mu_1 = (mu_T - mu_t) / omega_1;
209 double sig_sq_B = mu_1 - mu_0;
210 sig_sq_B *= sig_sq_B * omega_0 * omega_1;
211 if (best_t < 0 || sig_sq_B > best_sig_sq_B) {
212 best_sig_sq_B = sig_sq_B;
214 best_omega_0 = omega_0;
217 if (H_out !=
NULL) *H_out = H;
218 if (omega0_out !=
NULL) *omega0_out = best_omega_0;
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
#define PERF_COUNT_START(FUNCT_NAME)
int OtsuStats(const int *histogram, int *H_out, int *omega0_out)
int OtsuThreshold(Pix *src_pix, int left, int top, int width, int height, int **thresholds, int **hi_values)
void HistogramRect(Pix *src_pix, int channel, int left, int top, int width, int height, int *histogram)