23 #include "allheaders.h"
25 #if defined(USE_OPENCL)
40 int OtsuThreshold(Pix* src_pix,
int left,
int top,
int width,
int height,
41 int** thresholds,
int** hi_values) {
42 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];
55 int* histogramAllChannels =
new int[
kHistogramSize * num_channels];
59 if (od.selectedDeviceIsOpenCL() && (num_channels == 1 || num_channels == 4) &&
60 top == 0 && left == 0) {
61 od.HistogramRectOCL(pixGetData(src_pix), num_channels,
62 pixGetWpl(src_pix) * 4, left, top, width, height,
66 for (
int ch = 0; ch < num_channels; ++ch) {
67 (*thresholds)[ch] = -1;
68 (*hi_values)[ch] = -1;
72 int best_t =
OtsuStats(histogram, &H, &best_omega_0);
73 if (best_omega_0 == 0 || best_omega_0 == H) {
80 int hi_value = best_omega_0 < H * 0.5;
81 (*thresholds)[ch] = best_t;
82 if (best_omega_0 > H * 0.75) {
83 any_good_hivalue =
true;
85 }
else if (best_omega_0 < H * 0.25) {
86 any_good_hivalue =
true;
90 double hi_dist = hi_value ? (H - best_omega_0) : best_omega_0;
91 if (hi_dist > best_hi_dist) {
92 best_hi_dist = hi_dist;
93 best_hi_value = hi_value;
100 for (
int ch = 0; ch < num_channels; ++ch) {
101 (*thresholds)[ch] = -1;
102 (*hi_values)[ch] = -1;
105 HistogramRect(src_pix, ch, left, top, width, height, histogram);
108 int best_t =
OtsuStats(histogram, &H, &best_omega_0);
109 if (best_omega_0 == 0 || best_omega_0 == H) {
116 int hi_value = best_omega_0 < H * 0.5;
117 (*thresholds)[ch] = best_t;
118 if (best_omega_0 > H * 0.75) {
119 any_good_hivalue =
true;
120 (*hi_values)[ch] = 0;
121 }
else if (best_omega_0 < H * 0.25) {
122 any_good_hivalue =
true;
123 (*hi_values)[ch] = 1;
126 double hi_dist = hi_value ? (H - best_omega_0) : best_omega_0;
127 if (hi_dist > best_hi_dist) {
128 best_hi_dist = hi_dist;
129 best_hi_value = hi_value;
136 delete[] histogramAllChannels;
139 if (!any_good_hivalue) {
141 (*hi_values)[best_hi_index] = best_hi_value;
151 int left,
int top,
int width,
int height,
153 int num_channels = pixGetDepth(src_pix) / 8;
154 channel =
ClipToRange(channel, 0, num_channels - 1);
155 int bottom = top + height;
157 int src_wpl = pixGetWpl(src_pix);
158 l_uint32* srcdata = pixGetData(src_pix);
159 for (
int y = top; y < bottom; ++y) {
160 const l_uint32* linedata = srcdata + y * src_wpl;
161 for (
int x = 0; x < width; ++x) {
162 int pixel = GET_DATA_BYTE(linedata, (x + left) * num_channels + channel);
171 int OtsuStats(
const int* histogram,
int* H_out,
int* omega0_out) {
176 mu_T += static_cast<double>(i) * histogram[i];
182 int omega_0, omega_1;
183 int best_omega_0 = 0;
184 double best_sig_sq_B = 0.0;
185 double mu_0, mu_1, mu_t;
189 omega_0 += histogram[t];
190 mu_t += t * static_cast<double>(histogram[t]);
193 omega_1 = H - omega_0;
196 mu_0 = mu_t / omega_0;
197 mu_1 = (mu_T - mu_t) / omega_1;
198 double sig_sq_B = mu_1 - mu_0;
199 sig_sq_B *= sig_sq_B * omega_0 * omega_1;
200 if (best_t < 0 || sig_sq_B > best_sig_sq_B) {
201 best_sig_sq_B = sig_sq_B;
203 best_omega_0 = omega_0;
206 if (H_out !=
nullptr) *H_out = H;
207 if (omega0_out !=
nullptr) *omega0_out = best_omega_0;