27 const int width,
const int height,
const float pad_factor,
const int pad_min,
31 int *
const restrict label = calloc(npix,
sizeof(
int));
32 int *
const restrict stack = malloc(npix *
sizeof(
int));
41 int capacity = 64, count = 0;
51 for(
size_t pixel_index = 0; pixel_index < npix; pixel_index++)
57 if(label[pixel_index] || !maskb[pixel_index])
continue;
59 stack[stack_top++] = (int)pixel_index;
60 label[pixel_index] = count + 1;
62 int x_min = (int)(pixel_index % (
size_t)
width);
64 int y_min = (int)(pixel_index / (
size_t)
width);
66 float rmax = depth[pixel_index];
69 const int visited_index = stack[--stack_top];
70 const int visited_x = visited_index %
width;
71 const int visited_y = visited_index /
width;
75 if(visited_x < x_min) x_min = visited_x;
76 if(visited_x > x_max) x_max = visited_x;
77 if(visited_y < y_min) y_min = visited_y;
78 if(visited_y > y_max) y_max = visited_y;
79 if(depth[visited_index] > rmax) rmax = depth[visited_index];
83 for(
int delta_y = -1; delta_y <= 1; delta_y++)
84 for(
int delta_x = -1; delta_x <= 1; delta_x++)
86 if(!delta_x && !delta_y)
continue;
88 const int neighbour_x = visited_x + delta_x;
89 const int neighbour_y = visited_y + delta_y;
90 if(neighbour_x < 0 || neighbour_y < 0 || neighbour_x >=
width || neighbour_y >=
height)
continue;
92 const size_t neighbour_index = (size_t)neighbour_y *
width + neighbour_x;
93 if(label[neighbour_index] || !maskb[neighbour_index])
continue;
95 label[neighbour_index] = count + 1;
96 stack[stack_top++] = (int)neighbour_index;
114 const int pad = CLAMP((
int)(pad_factor * rmax + 0.5f), pad_min, pad_max);
115 regions[count].
x0 = x_min;
116 regions[count].
y0 = y_min;
117 regions[count].
x1 = x_max;
118 regions[count].
y1 = y_max;
119 regions[count].
pad = pad;
120 regions[count].
radius = rmax;
121 regions[count].
rx0 =
MAX(x_min - pad, 0);
122 regions[count].
ry0 =
MAX(y_min - pad, 0);
136 int *
const restrict parent = malloc((
size_t)count *
sizeof(
int));
138 int *
const restrict map = malloc((
size_t)count *
sizeof(
int));
139 if(!parent || !merged || !map)
144 *regions_out = regions;
147 for(
int i = 0;
i < count;
i++) parent[
i] =
i;
150 for(
int i = 0;
i < count;
i++)
152 for(
int j =
i + 1; j < count; j++)
155 if(regions[
i].rx0 > regions[j].rx1 || regions[j].rx0 > regions[
i].rx1)
continue;
156 if(regions[
i].ry0 > regions[j].ry1 || regions[j].ry0 > regions[
i].ry1)
continue;
160 while(parent[root_i] != root_i)
162 parent[root_i] = parent[parent[root_i]];
163 root_i = parent[root_i];
168 while(parent[root_j] != root_j)
170 parent[root_j] = parent[parent[root_j]];
171 root_j = parent[root_j];
175 if(root_i != root_j) parent[root_j] = root_i;
179 for(
int i = 0;
i < count;
i++) map[
i] = -1;
183 for(
int i = 0;
i < count;
i++)
187 while(parent[root_i] != root_i)
189 parent[root_i] = parent[parent[root_i]];
190 root_i = parent[root_i];
196 map[root_i] = mcount;
197 merged[mcount] = regions[
i];
204 _hl_region_t *
const merged_region = &merged[map[root_i]];
205 merged_region->
x0 =
MIN(merged_region->
x0, regions[
i].
x0);
206 merged_region->
y0 =
MIN(merged_region->
y0, regions[
i].
y0);
207 merged_region->
x1 =
MAX(merged_region->
x1, regions[
i].
x1);
208 merged_region->
y1 =
MAX(merged_region->
y1, regions[
i].
y1);
209 merged_region->
pad =
MAX(merged_region->
pad, regions[
i].
pad);
215 for(
int merged_region = 0; merged_region < mcount; merged_region++)
217 const int pad = merged[merged_region].pad;
218 merged[merged_region].rx0 =
MAX(merged[merged_region].x0 - pad, 0);
219 merged[merged_region].ry0 =
MAX(merged[merged_region].y0 - pad, 0);
220 merged[merged_region].rx1 =
MIN(merged[merged_region].x1 + pad,
width - 1);
221 merged[merged_region].ry1 =
MIN(merged[merged_region].y1 + pad,
height - 1);
226 *regions_out = merged;
230 *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)