Img2Num C++ (Internal Developer Docs) dev
API Documentation
Loading...
Searching...
No Matches
anonymous_namespace{graph.cpp} Namespace Reference

Functions

void dt_1d (const std::vector< float > &f, std::vector< float > &d, int n)
 
float max_inscribed_radius (const Node_ptr &n)
 

Function Documentation

◆ dt_1d()

void anonymous_namespace{graph.cpp}::dt_1d ( const std::vector< float > &  f,
std::vector< float > &  d,
int  n 
)

Definition at line 313 of file graph.cpp.

313 {
314 constexpr float INF = 1e20f;
315 std::vector<int> v(n);
316 std::vector<float> z(n + 1);
317 int k = 0;
318 v[0] = 0;
319 z[0] = -INF;
320 z[1] = INF;
321 for (int q = 1; q < n; ++q) {
322 float s;
323 while (true) {
324 s = ((f[q] + static_cast<float>(q) * q) - (f[v[k]] + static_cast<float>(v[k]) * v[k])) /
325 (2.0f * static_cast<float>(q - v[k]));
326 if (s <= z[k] && k > 0) {
327 --k;
328 } else {
329 break;
330 }
331 }
332 ++k;
333 v[k] = q;
334 z[k] = s;
335 z[k + 1] = INF;
336 }
337 k = 0;
338 for (int q = 0; q < n; ++q) {
339 while (z[k + 1] < static_cast<float>(q))
340 ++k;
341 const float dq = static_cast<float>(q - v[k]);
342 d[q] = dq * dq + f[v[k]];
343 }
344}

◆ max_inscribed_radius()

float anonymous_namespace{graph.cpp}::max_inscribed_radius ( const Node_ptr &  n)

Definition at line 351 of file graph.cpp.

351 {
352 std::vector<uint8_t> mask;
353 const std::array<int, 4> xywh = n->create_binary_image(mask); // tight bbox
354 const int w = xywh[2];
355 const int h = xywh[3];
356 if (w <= 0 || h <= 0)
357 return 0.0f;
358
359 // Pad by one pixel so the region's boundary against the exterior is treated
360 // as background by the distance transform.
361 const int pw = w + 2;
362 const int ph = h + 2;
363 constexpr float INF = 1e20f;
364
365 std::vector<float> grid(static_cast<size_t>(pw) * ph);
366 for (int y = 0; y < ph; ++y) {
367 for (int x = 0; x < pw; ++x) {
368 const bool inside = x >= 1 && x <= w && y >= 1 && y <= h &&
369 mask[static_cast<size_t>(y - 1) * w + (x - 1)];
370 grid[static_cast<size_t>(y) * pw + x] = inside ? INF : 0.0f;
371 }
372 }
373
374 // Separable two-pass transform: columns first, then rows.
375 std::vector<float> in, out(std::max(pw, ph));
376 in.resize(ph);
377 for (int x = 0; x < pw; ++x) {
378 for (int y = 0; y < ph; ++y)
379 in[y] = grid[static_cast<size_t>(y) * pw + x];
380 dt_1d(in, out, ph);
381 for (int y = 0; y < ph; ++y)
382 grid[static_cast<size_t>(y) * pw + x] = out[y];
383 }
384 in.resize(pw);
385 float max_d2 = 0.0f;
386 for (int y = 0; y < ph; ++y) {
387 for (int x = 0; x < pw; ++x)
388 in[x] = grid[static_cast<size_t>(y) * pw + x];
389 dt_1d(in, out, pw);
390 for (int x = 0; x < pw; ++x)
391 if (out[x] > max_d2)
392 max_d2 = out[x];
393 }
394 return std::sqrt(max_d2);
395}