MayaFlux 0.5.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 299 of file PixelOps.cpp.

300{
301 constexpr int32_t bins = 256;
302 std::array<float, bins> hist {};
303
304 for (float v : gray)
305 hist[static_cast<int32_t>(std::clamp(v, 0.0F, 1.0F) * (bins - 1))]++;
306
307 const auto total = static_cast<float>(gray.size());
308 for (auto& h : hist)
309 h /= total;
310
311 float sum_all = 0.0F;
312 for (int32_t i = 0; i < bins; ++i)
313 sum_all += static_cast<float>(i) * hist[i];
314
315 float sum_bg = 0.0F;
316 float w_bg = 0.0F;
317 float best_var = 0.0F;
318 int32_t best_t = 0;
319
320 for (int32_t t = 0; t < bins; ++t) {
321 w_bg += hist[t];
322 if (w_bg == 0.0F)
323 continue;
324
325 const float w_fg = 1.0F - w_bg;
326 if (w_fg == 0.0F)
327 break;
328
329 sum_bg += static_cast<float>(t) * hist[t];
330
331 const float mean_bg = sum_bg / w_bg;
332 const float mean_fg = (sum_all - sum_bg) / w_fg;
333 const float diff = mean_fg - mean_bg;
334 const float var = w_bg * w_fg * diff * diff;
335
336 if (var > best_var) {
337 best_var = var;
338 best_t = t;
339 }
340 }
341
342 const float t_norm = static_cast<float>(best_t) / static_cast<float>(bins - 1);
343 threshold(gray, dst, t_norm);
344}
uint32_t h
Definition InkPress.cpp:28
float threshold

References h, and threshold.

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

+ Here is the caller graph for this function: