MCPcopy Create free account
hub / github.com/creatale/node-dv / OtsuThreshold

Function OtsuThreshold

deps/tesseract/ccstruct/otsuthr.cpp:39–216  ·  view source on GitHub ↗

Computes the Otsu threshold(s) for the given image rectangle, making one for each channel. Each channel is always one byte per pixel. Returns an array of threshold values and an array of hi_values, such that a pixel value >threshold[channel] is considered foreground if hi_values[channel] is 0 or background if 1. A hi_value of -1 indicates that there is no apparent foreground. At least one hi_value

Source from the content-addressed store, hash-verified

37// The return value is the number of channels in the input image, being
38// the size of the output thresholds and hi_values arrays.
39int 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;
42 // Of all channels with no good hi_value, keep the best so we can always
43 // produce at least one answer.
44 PERF_COUNT_START("OtsuThreshold")
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];
51
52 // only use opencl if compiled w/ OpenCL and selected device is opencl
53#ifdef USE_OPENCL
54 // all of channel 0 then all of channel 1...
55 int* histogramAllChannels = new int[kHistogramSize * num_channels];
56
57 // Calculate Histogram on GPU
58 OpenclDevice od;
59 if (od.selectedDeviceIsOpenCL() && (num_channels == 1 || num_channels == 4) &&
60 top == 0 && left == 0) {
61 od.HistogramRectOCL((unsigned char*)pixGetData(src_pix), num_channels,
62 pixGetWpl(src_pix) * 4, left, top, width, height,
63 kHistogramSize, histogramAllChannels);
64
65 // Calculate Threshold from Histogram on cpu
66 for (int ch = 0; ch < num_channels; ++ch) {
67 (*thresholds)[ch] = -1;
68 (*hi_values)[ch] = -1;
69 int *histogram = &histogramAllChannels[kHistogramSize * ch];
70 int H;
71 int best_omega_0;
72 int best_t = OtsuStats(histogram, &H, &best_omega_0);
73 if (best_omega_0 == 0 || best_omega_0 == H) {
74 // This channel is empty.
75 continue;
76 }
77 // To be a convincing foreground we must have a small fraction of H
78 // or to be a convincing background we must have a large fraction of H.
79 // In between we assume this channel contains no thresholding information.
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;
84 (*hi_values)[ch] = 0;
85 } else if (best_omega_0 < H * 0.25) {
86 any_good_hivalue = true;
87 (*hi_values)[ch] = 1;
88 } else {
89 // In case all channels are like this, keep the best of the bad lot.
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;
94 best_hi_index = ch;
95 }
96 }

Callers 2

GetPixRectThresholdsMethod · 0.85
thresholder.cppFile · 0.85

Calls 7

pixGetDepthFunction · 0.85
pixGetDataFunction · 0.85
pixGetWplFunction · 0.85
OtsuStatsFunction · 0.85
HistogramRectFunction · 0.85
HistogramRectOCLMethod · 0.80

Tested by

no test coverage detected