30 const int width,
const int height,
const float pad_factor,
const int pad_min,
34 int *
const restrict label = calloc(npix,
sizeof(
int));
35 int *
const restrict stack = malloc(npix *
sizeof(
int));
44 int capacity = 64, count = 0;
54 for(
size_t pixel_index = 0; pixel_index < npix; pixel_index++)
60 if(label[pixel_index] || !maskb[pixel_index])
continue;
62 stack[stack_top++] = (int)pixel_index;
63 label[pixel_index] = count + 1;
65 int x_min = (int)(pixel_index % (
size_t)
width);
67 int y_min = (int)(pixel_index / (
size_t)
width);
69 float rmax = depth[pixel_index];
72 const int visited_index = stack[--stack_top];
73 const int visited_x = visited_index %
width;
74 const int visited_y = visited_index /
width;
78 if(visited_x < x_min) x_min = visited_x;
79 if(visited_x > x_max) x_max = visited_x;
80 if(visited_y < y_min) y_min = visited_y;
81 if(visited_y > y_max) y_max = visited_y;
82 if(depth[visited_index] > rmax) rmax = depth[visited_index];
86 for(
int delta_y = -1; delta_y <= 1; delta_y++)
87 for(
int delta_x = -1; delta_x <= 1; delta_x++)
89 if(!delta_x && !delta_y)
continue;
91 const int neighbour_x = visited_x + delta_x;
92 const int neighbour_y = visited_y + delta_y;
93 if(neighbour_x < 0 || neighbour_y < 0 || neighbour_x >=
width || neighbour_y >=
height)
continue;
95 const size_t neighbour_index = (size_t)neighbour_y *
width + neighbour_x;
96 if(label[neighbour_index] || !maskb[neighbour_index])
continue;
98 label[neighbour_index] = count + 1;
99 stack[stack_top++] = (int)neighbour_index;
102 if(count >= capacity)
117 const int pad = CLAMP((
int)(pad_factor * rmax + 0.5f), pad_min, pad_max);
118 regions[count].
x0 = x_min;
119 regions[count].
y0 = y_min;
120 regions[count].
x1 = x_max;
121 regions[count].
y1 = y_max;
122 regions[count].
pad = pad;
123 regions[count].
radius = rmax;
124 regions[count].
rx0 =
MAX(x_min - pad, 0);
125 regions[count].
ry0 =
MAX(y_min - pad, 0);
139 int *
const restrict parent = malloc((
size_t)count *
sizeof(
int));
141 int *
const restrict map = malloc((
size_t)count *
sizeof(
int));
142 if(!parent || !merged || !map)
147 *regions_out = regions;
150 for(
int i = 0;
i < count;
i++) parent[
i] =
i;
153 for(
int i = 0;
i < count;
i++)
155 for(
int j =
i + 1; j < count; j++)
158 if(regions[
i].rx0 > regions[j].rx1 || regions[j].rx0 > regions[
i].rx1)
continue;
159 if(regions[
i].ry0 > regions[j].ry1 || regions[j].ry0 > regions[
i].ry1)
continue;
163 while(parent[root_i] != root_i)
165 parent[root_i] = parent[parent[root_i]];
166 root_i = parent[root_i];
171 while(parent[root_j] != root_j)
173 parent[root_j] = parent[parent[root_j]];
174 root_j = parent[root_j];
178 if(root_i != root_j) parent[root_j] = root_i;
182 for(
int i = 0;
i < count;
i++) map[
i] = -1;
186 for(
int i = 0;
i < count;
i++)
190 while(parent[root_i] != root_i)
192 parent[root_i] = parent[parent[root_i]];
193 root_i = parent[root_i];
199 map[root_i] = mcount;
200 merged[mcount] = regions[
i];
207 _hl_region_t *
const merged_region = &merged[map[root_i]];
208 merged_region->
x0 =
MIN(merged_region->
x0, regions[
i].
x0);
209 merged_region->
y0 =
MIN(merged_region->
y0, regions[
i].
y0);
210 merged_region->
x1 =
MAX(merged_region->
x1, regions[
i].
x1);
211 merged_region->
y1 =
MAX(merged_region->
y1, regions[
i].
y1);
212 merged_region->
pad =
MAX(merged_region->
pad, regions[
i].
pad);
218 for(
int merged_region = 0; merged_region < mcount; merged_region++)
220 const int pad = merged[merged_region].pad;
221 merged[merged_region].rx0 =
MAX(merged[merged_region].x0 - pad, 0);
222 merged[merged_region].ry0 =
MAX(merged[merged_region].y0 - pad, 0);
223 merged[merged_region].rx1 =
MIN(merged[merged_region].x1 + pad,
width - 1);
224 merged[merged_region].ry1 =
MIN(merged[merged_region].y1 + pad,
height - 1);
229 *regions_out = merged;
233 *regions_out = regions;
int _segment_clipped_regions(const uint8_t *const restrict maskb, const float *const restrict depth, const int width, const int height, const float pad_factor, const int pad_min, const int pad_max, _hl_region_t **regions_out)