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 315 of file graph.cpp.

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

◆ max_inscribed_radius()

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

Definition at line 353 of file graph.cpp.

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