23 std::fill(labels.begin(), labels.end(), Similarity());
26 template<
class Tin,
class Tlabel,
class Comparator,
class Boolean>
27 int connected(
const Tin *img, Tlabel *out,
28 int width,
int height, Comparator,
29 Boolean K8_connectivity);
33 Similarity() : id(0), sameas(0) {}
34 Similarity(
int _id,
int _sameas) : id(_id), sameas(_sameas) {}
35 Similarity(
int _id) : id(_id), sameas(_id) {}
39 bool is_root_label(
int id) {
40 return (labels[
id].sameas ==
id);
43 while (!is_root_label(
id)) {
46 labels[id].sameas = labels[labels[id].sameas].sameas;
48 id = labels[id].sameas;
52 bool is_equivalent(
int id,
int as) {
53 return (root_of(
id) == root_of(as));
55 bool merge(
int id1,
int id2) {
56 if(!is_equivalent(id1, id2)) {
57 labels[root_of(id1)].sameas = root_of(id2);
63 if(highest_label+1 > labels.size())
64 labels.reserve(highest_label*2);
65 labels.resize(highest_label+1);
66 labels[highest_label] = Similarity(highest_label);
67 return highest_label++;
71 template<
class Tin,
class Tlabel,
class Comparator,
class Boolean>
72 void label_image(
const Tin *img, Tlabel *out,
73 int width,
int height, Comparator,
74 Boolean K8_connectivity);
75 template<
class Tlabel>
76 int relabel_image(Tlabel *out,
int width,
int height);
79 std::vector<Similarity> labels;
83 template<
class Tin,
class Tlabel,
class Comparator,
class Boolean>
86 int width,
int height, Comparator SAME,
87 Boolean K8_connectivity)
89 label_image(img,labelimg, width,height, SAME, K8_connectivity);
90 return relabel_image(labelimg, width,height);
93 template<
class Tin,
class Tlabel,
class Comparator,
class Boolean>
95 ConnectedComponents::label_image(
const Tin *img, Tlabel *labelimg,
96 int width,
int height, Comparator SAME,
97 const Boolean K8_CONNECTIVITY)
100 const Tin *last_row = 0;
101 struct Label_handler {
102 Label_handler(
const Tin *img, Tlabel *limg) :
103 piximg(img), labelimg(limg) {}
104 Tlabel &operator()(
const Tin *pixp) {
return labelimg[pixp-piximg]; }
107 } label(img, labelimg);
111 label(&row[0]) = new_label();
114 for(
int c=1; c<width; ++c) {
115 if(SAME(row[c], row[c-1]))
116 label(&row[c]) = label(&row[c-1]);
118 label(&row[c]) = new_label();
122 for(
int r=1; r<height; ++r) {
127 if(SAME(row[0], last_row[0]))
128 label(&row[0]) = label(&last_row[0]);
130 label(&row[0]) = new_label();
133 for(
int c=1; c<width; ++c) {
137 if(SAME(row[c],row[c-1]))
138 mylab = label(&row[c-1]);
139 for(
int d=(K8_CONNECTIVITY?-1:0); d<1; ++d) {
142 if(SAME(row[c], last_row[c+d])) {
143 if(mylab>=0) merge(mylab, label(&last_row[c+d]));
144 else mylab = label(&last_row[c+d]);
147 if(mylab>=0) label(&row[c]) =
static_cast<Tlabel
>(mylab);
148 else label(&row[c]) = new_label();
150 if(K8_CONNECTIVITY && SAME(row[c-1], last_row[c]))
151 merge(label(&row[c-1]), label(&last_row[c]));
156 template<
class Tlabel>
158 ConnectedComponents::relabel_image(Tlabel *labelimg,
int width,
int height)
161 for(
int id=0;
id<labels.size(); ++id)
162 if(is_root_label(
id))
163 labels[
id].tag = newtag++;
165 for(
int i = 0; i<width*height; ++i)
166 labelimg[i] = labels[root_of(labelimg[i])].tag;
172 #endif // _CONNECTED_H ConnectedComponents(int soft_maxlabels)
Definition: connected_components.h:19
int connected(const Tin *img, Tlabel *out, int width, int height, Comparator, Boolean K8_connectivity)
Definition: connected_components.h:85
void clear()
Definition: connected_components.h:22
Efficient (multi-label) connected components algorithm.
Definition: connected_components.h:16