50 std::span<const float> mask, uint32_t w, uint32_t
h)
52 const size_t n =
static_cast<size_t>(w) *
h;
54 std::vector<uint32_t> labels(n, 0);
56 uint32_t next_label = 1;
58 for (uint32_t py = 0; py <
h; ++py) {
59 for (uint32_t px = 0; px < w; ++px) {
60 const size_t idx =
static_cast<size_t>(py) * w + px;
62 if (!is_fg(mask[idx]))
68 if (px > 0 && is_fg(mask[idx - 1]))
69 left = labels[idx - 1];
70 if (py > 0 && is_fg(mask[idx - w]))
71 above = labels[idx - w];
73 if (left == 0 && above == 0) {
74 labels[idx] = next_label++;
75 }
else if (left != 0 && above == 0) {
77 }
else if (left == 0 && above != 0) {
81 uf.unite(left, above);
86 std::vector<uint32_t> remap(next_label, 0);
88 for (uint32_t i = 1; i < next_label; ++i) {
89 const uint32_t root = uf.find(i);
91 remap[root] = ++compact;
92 remap[i] = remap[root];
96 uint32_t x_min, y_min, x_max, y_max;
100 std::vector<Extent> extents(compact + 1,
101 Extent { .x_min = w, .y_min =
h, .x_max = 0, .y_max = 0, .pixel_count = 0 });
103 for (uint32_t py = 0; py <
h; ++py) {
104 for (uint32_t px = 0; px < w; ++px) {
105 const size_t idx =
static_cast<size_t>(py) * w + px;
106 if (labels[idx] == 0)
109 const uint32_t lbl = remap[labels[idx]];
112 auto& e = extents[lbl];
113 e.x_min = std::min(e.x_min, px);
114 e.y_min = std::min(e.y_min, py);
115 e.x_max = std::max(e.x_max, px);
116 e.y_max = std::max(e.y_max, py);
121 const float inv_w = 1.0F /
static_cast<float>(w);
122 const float inv_h = 1.0F /
static_cast<float>(
h);
124 std::vector<BoundingBox> boxes;
125 boxes.reserve(compact);
127 for (uint32_t i = 1; i <= compact; ++i) {
128 const auto& e = extents[i];
129 const float x =
static_cast<float>(e.x_min) * inv_w;
130 const float y =
static_cast<float>(e.y_min) * inv_h;
131 const float bw =
static_cast<float>(e.x_max - e.x_min + 1) * inv_w;
132 const float bh =
static_cast<float>(e.y_max - e.y_min + 1) * inv_h;
133 boxes.push_back({ .x = x, .y = y, .w = bw, .h = bh, .confidence = 1.0F, .label_id = i });
136 return { .label_map = std::move(labels), .boxes = std::move(boxes), .count = compact };