MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ threshold_otsu() [2/2]

MAYAFLUX_API void MayaFlux::Kinesis::Vision::threshold_otsu ( std::span< const float >  gray,
std::span< float >  dst 
)

Otsu threshold writing into caller-supplied buffer.

Finds the optimal global threshold by maximising inter-class variance, then applies it.

Parameters
grayInput span, size must be w * h.
dstOutput span, size must be w * h.

Definition at line 279 of file PixelOps.cpp.

280{
281 constexpr int32_t bins = 256;
282 std::array<float, bins> hist {};
283
284 for (float v : gray)
285 hist[static_cast<int32_t>(std::clamp(v, 0.0F, 1.0F) * (bins - 1))]++;
286
287 const auto total = static_cast<float>(gray.size());
288 for (auto& h : hist)
289 h /= total;
290
291 float sum_all = 0.0F;
292 for (int32_t i = 0; i < bins; ++i)
293 sum_all += static_cast<float>(i) * hist[i];
294
295 float sum_bg = 0.0F;
296 float w_bg = 0.0F;
297 float best_var = 0.0F;
298 int32_t best_t = 0;
299
300 for (int32_t t = 0; t < bins; ++t) {
301 w_bg += hist[t];
302 if (w_bg == 0.0F)
303 continue;
304
305 const float w_fg = 1.0F - w_bg;
306 if (w_fg == 0.0F)
307 break;
308
309 sum_bg += static_cast<float>(t) * hist[t];
310
311 const float mean_bg = sum_bg / w_bg;
312 const float mean_fg = (sum_all - sum_bg) / w_fg;
313 const float diff = mean_fg - mean_bg;
314 const float var = w_bg * w_fg * diff * diff;
315
316 if (var > best_var) {
317 best_var = var;
318 best_t = t;
319 }
320 }
321
322 const float t_norm = static_cast<float>(best_t) / static_cast<float>(bins - 1);
323 threshold(gray, dst, t_norm);
324}
uint32_t h
Definition InkPress.cpp:29
uint32_t * dst
uint32_t total
float threshold

References dst, h, threshold, and total.

Referenced by MayaFlux::Kinesis::Vision::VisionExecutor::run(), and threshold_otsu().

+ Here is the caller graph for this function: