23 int resolve_label(
const std::vector<int> &labels,
int provisional_label) {
24 int final_label = provisional_label;
26 while (final_label != labels[final_label]) {
27 final_label = labels[final_label];
43 std::vector<int> row_above(ncols, 0);
46 int grounded_label = 1;
47 int provisional_label = 2;
53 std::vector<int> labels = {0, grounded_label};
55 std::vector<Run> runs;
57 for (
int r = 0; r < nrows; ++r) {
58 const double *
row = &image[
static_cast<std::ptrdiff_t
>(r) * ncols];
65 int L = provisional_label;
68 runs.push_back({r, c_start, 0,
L});
69 Run ¤t_run = runs.back();
72 while (c < ncols and
row[c] > 0) {
74 if (identify_icebergs and
static_cast<int>(
row[c]) == mask_grounded) {
76 if (
L != provisional_label) {
77 labels[
L] = grounded_label;
88 if (
L != provisional_label) {
98 if (
L == provisional_label) {
103 provisional_label += 1;
107 current_run.
length = c - c_start;
111 for (
int n = 0;
n < current_run.
length; ++
n) {
112 row_above[c_start +
n] =
L;
122 auto N_labels =
static_cast<int>(labels.size());
126 for (
int k = 0;
k < N_labels; ++
k) {
134 for (
int k = 1;
k < N_labels; ++
k) {
135 if (labels[
k] ==
k) {
139 labels[
k] = labels[labels[
k]];
144 if (identify_icebergs) {
147 for (
int k = 1;
k < N_labels; ++
k) {
148 labels[
k] = labels[
k] > 1 ? 1 : 0;
154 for (
int k = 1;
k < N_labels; ++
k) {
160 for (
int k = 0;
k < (int)runs.size(); ++
k) {
162 int run_start = r.row * ncols + r.col;
163 for (
int n = 0;
n < r.length; ++
n) {
164 image[run_start +
n] = labels[r.label];
void label_connected_components(double *image, int nrows, int ncols, bool identify_icebergs, int mask_grounded, int first_label)
int resolve_label(const std::vector< int > &labels, int provisional_label)
static Vector3 row(const double A[3][3], size_t k)