9 # include <vcl_msvc_warnings.h> 20 typedef unsigned LABEL;
27 std::vector<node> store_;
29 disjoint_sets(): store_(1u)
31 store_.front().parent=0;
32 store_.front().rank=0;
43 n.parent=root(n.parent);
49 void merge_labels(LABEL left_label, LABEL right_label)
51 LABEL left_root = root(left_label);
52 LABEL right_root = root(right_label);
53 if (left_root == right_root)
return;
54 node& left_root_node = store_[left_root];
55 node& right_root_node = store_[right_root];
56 if (left_root_node.rank > right_root_node.rank)
58 right_root_node.parent = left_root_node.parent;
62 left_root_node.parent = right_root_node.parent;
63 if (left_root_node.rank == right_root_node.rank)
64 right_root_node.rank++;
71 node n = {(LABEL)store_.size(), 0};
88 unsigned ni=src_binary.
ni();
89 unsigned nj=src_binary.
nj();
93 disjoint_sets merge_list;
94 std::vector<unsigned> neighbouring_labels;
96 unsigned n_prev_neighbours;
106 n_prev_neighbours=0; assert(!
"unknown connectivity");
111 int neighbourhood_ii[] = { -1, 0, -1, +1};
112 int neighbourhood_jj[] = { 0, -1, -1, -1};
115 for (
unsigned j=0; j<nj; ++j)
116 for (
unsigned i=0; i<ni; ++i)
118 if (!src_binary(i,j))
continue;
119 neighbouring_labels.clear();
120 for (
unsigned l=0; l<n_prev_neighbours; ++l)
122 unsigned ii = i + neighbourhood_ii[l];
123 if (ii >= ni)
continue;
124 unsigned jj = j + neighbourhood_jj[l];
125 if (jj >= nj)
continue;
126 unsigned d = dest_label(ii,jj);
127 if (d!=0) neighbouring_labels.push_back(d);
129 if (neighbouring_labels.empty())
131 unsigned new_label = merge_list.new_label();
132 dest_label(i,j) = new_label;
137 std::sort(neighbouring_labels.begin(), neighbouring_labels.end());
138 auto end = std::unique(neighbouring_labels.begin(), neighbouring_labels.end());
141 auto it=neighbouring_labels.
begin();
142 unsigned label = *it++;
143 dest_label(i,j) = label;
149 for (; it!=end; ++it)
150 merge_list.merge_labels(*it, label);
153 unsigned n_merge=merge_list.size();
154 std::vector<unsigned> renumbering(n_merge, 0u);
158 for (
unsigned l=1; l<n_merge; ++l)
160 if (renumbering[l]!=0)
continue;
161 unsigned root_label = merge_list.root(l);
162 unsigned root_label_renumber = renumbering[root_label];
163 if (root_label_renumber==0)
165 renumbering[root_label]=l;
169 renumbering[l]=renumbering[root_label];
174 std::vector<unsigned> labels(renumbering.begin(), renumbering.end());
175 std::sort(labels.begin(), labels.end());
176 labels.erase(std::unique(labels.begin(), labels.end()), labels.end());
177 const auto dodgy = static_cast<unsigned>(-1);
178 std::vector<unsigned> renum_renum(renumbering.size(), dodgy);
180 for (
unsigned l=0, n=labels.size(); l<n; ++l)
181 renum_renum[labels[l]] = l;
183 for (
unsigned int & it : renumbering)
187 assert(std::find(renumbering.begin(), renumbering.end(), dodgy)
188 == renumbering.end() );
192 for (
unsigned j=0; j<nj; ++j)
193 for (
unsigned i=0; i<ni; ++i)
194 dest_label(i,j) = renumbering[dest_label(i,j)];
203 unsigned ni=src_label.
ni();
204 unsigned nj=src_label.
nj();
208 unsigned n_edge_neighbours;
218 n_edge_neighbours=0; assert(!
"unknown connectivity");
223 int neighbourhood_ii[] = { 0, -1, 1, 0, -1, 1, -1, 1};
224 int neighbourhood_jj[] = { -1, 0, 0, 1, -1, -1, 1, 1};
226 for (
unsigned j=0; j<nj; ++j)
227 for (
unsigned i=0; i<ni; ++i)
229 unsigned v = src_label(i,j);
231 for (
unsigned l=0; l<n_edge_neighbours; ++l)
233 unsigned ii = i + neighbourhood_ii[l];
234 if (ii >= ni)
continue;
235 unsigned jj = j + neighbourhood_jj[l];
236 if (jj >= nj)
continue;
237 if (
v!=src_label(ii,jj))
250 std::vector<vil_blob_region>& dest_regions)
252 dest_regions.clear();
253 unsigned ni=src_label.
ni();
254 unsigned nj=src_label.
nj();
256 for (
unsigned j=0; j<nj; ++j)
257 for (
unsigned i=0; i<ni;)
259 unsigned label = src_label(i,j);
266 if (label > dest_regions.size()) dest_regions.resize(label);
269 while (++i < ni && src_label(i,j)==label);
270 dest_regions[label-1].push_back(
vil_chord(i_start, i-1, j));
278 std::vector<vil_blob_pixel_list>& dest_pixel_lists)
280 dest_pixel_lists.clear();
281 unsigned ni=src_label.
ni();
282 unsigned nj=src_label.
nj();
284 for (
unsigned j=0; j<nj; ++j)
285 for (
unsigned i=0; i<ni; ++i)
287 unsigned label = src_label(i,j);
288 if (!label)
continue;
290 if (label > dest_pixel_lists.size()) dest_pixel_lists.resize(label);
291 dest_pixel_lists[label-1].push_back(std::make_pair(i,j));
void vil_blob_labels_to_edge_labels(const vil_image_view< unsigned > &src_label, vil_blob_connectivity conn, vil_image_view< unsigned > &dest_label)
Set all non-blob-edge pixels in a blob label image to zero.
void fill(T value)
Fill view with given value.
vil_blob_connectivity
Specify 4- or 8- neighbour connectivity.
void set_size(unsigned ni, unsigned nj) override
resize current planes to ni x nj.
void vil_blob_labels_to_regions(const vil_image_view< unsigned > &src_label, std::vector< vil_blob_region > &dest_regions)
Convert a label image into a list of chorded regions.
unsigned ni() const
Width.
unsigned nj() const
Height.
Store information about position of a row of pixels in an image.
void vil_blob_labels(const vil_image_view< bool > &src_binary, vil_blob_connectivity conn, vil_image_view< unsigned > &dest_label)
Produce a label image that enumerates all disjoint blobs in a binary image.
void vil_blob_labels_to_pixel_lists(const vil_image_view< unsigned > &src_label, std::vector< vil_blob_pixel_list > &dest_pixel_lists)
Convert a label image (or an edge label image) into a set of pixel lists.
Finds connected regions in a boolean image.