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];
    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;
   152                    int left, 
int top, 
int width, 
int height,
   155   int num_channels = pixGetDepth(src_pix) / 8;
   156   channel = 
ClipToRange(channel, 0, num_channels - 1);
   157   int bottom = top + height;
   159   int src_wpl = pixGetWpl(src_pix);
   160   l_uint32* srcdata = pixGetData(src_pix);
   161   for (
int y = top; y < bottom; ++y) {
   162     const l_uint32* linedata = srcdata + y * src_wpl;
   163     for (
int x = 0; x < width; ++x) {
   164       int pixel = GET_DATA_BYTE(linedata, (x + left) * num_channels + channel);
   174 int OtsuStats(
const int* histogram, 
int* H_out, 
int* omega0_out) {
   179     mu_T += 
static_cast<double>(i) * histogram[i];
   185   int omega_0, omega_1;
   186   int best_omega_0 = 0;
   187   double best_sig_sq_B = 0.0;
   188   double mu_0, mu_1, mu_t;
   192     omega_0 += histogram[t];
   193     mu_t += t * 
static_cast<double>(histogram[t]);
   196     omega_1 = H - omega_0;
   199     mu_0 = mu_t / omega_0;
   200     mu_1 = (mu_T - mu_t) / omega_1;
   201     double sig_sq_B = mu_1 - mu_0;
   202     sig_sq_B *= sig_sq_B * omega_0 * omega_1;
   203     if (best_t < 0 || sig_sq_B > best_sig_sq_B) {
   204       best_sig_sq_B = sig_sq_B;
   206       best_omega_0 = omega_0;
   209   if (H_out != 
nullptr) *H_out = H;
   210   if (omega0_out != 
nullptr) *omega0_out = best_omega_0;
 
int OtsuStats(const int *histogram, int *H_out, int *omega0_out)
#define PERF_COUNT_START(FUNCT_NAME)
void HistogramRect(Pix *src_pix, int channel, int left, int top, int width, int height, int *histogram)
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
int OtsuThreshold(Pix *src_pix, int left, int top, int width, int height, int **thresholds, int **hi_values)