$extrastylesheet
Olena
User documentation 2.1
An Image Processing Platform
Scribo
Modules
Namespaces
Classes
All
Classes
Namespaces
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Groups
Pages
union.hh
1
// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
2
//
3
// This file is part of Olena.
4
//
5
// Olena is free software: you can redistribute it and/or modify it under
6
// the terms of the GNU General Public License as published by the Free
7
// Software Foundation, version 2 of the License.
8
//
9
// Olena is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
// General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Olena. If not, see <http://www.gnu.org/licenses/>.
16
//
17
// As a special exception, you may use this file as part of a free
18
// software project without restriction. Specifically, if other files
19
// instantiate templates or use macros or inline functions from this
20
// file, or you compile this file and link it with other files to produce
21
// an executable, this file does not by itself cause the resulting
22
// executable to be covered by the GNU General Public License. This
23
// exception does not however invalidate any other reasons why the
24
// executable file might be covered by the GNU General Public License.
25
31
32
#ifndef SCRIBO_PRIMITIVE_EXTRACT_INTERNAL_UNION_HH
33
# define SCRIBO_PRIMITIVE_EXTRACT_INTERNAL_UNION_HH
34
35
# include <mln/core/image/image2d.hh>
36
# include <mln/border/fill.hh>
37
38
39
namespace
scribo
40
{
41
42
namespace
primitive
43
{
44
45
namespace
extract
46
{
47
48
namespace
internal
49
{
50
51
using namespace
mln;
52
53
54
unsigned
find_root
(
image2d<unsigned>
& parent,
unsigned
x);
55
56
57
void
union_find
(
const
image2d<bool>
& input,
bool
lab,
58
image2d<unsigned>
& parent,
image2d<unsigned>
&
area
,
59
unsigned
& max_area);
60
61
62
# ifndef MLN_INCLUDE_ONLY
63
64
inline
65
unsigned
find_root
(
image2d<unsigned>
& parent,
unsigned
x)
66
{
67
if
(parent.
element
(x) == x)
68
return
x;
69
return
parent.
element
(x) =
find_root
(parent, parent.
element
(x));
70
}
71
72
73
inline
74
void
union_find
(
const
image2d<bool>
& input,
75
bool
lab,
76
// output:
77
image2d<unsigned>
& parent,
78
image2d<unsigned>
&
area
,
79
unsigned
& max_area)
80
{
81
const
unsigned
nrows
= input.
nrows
(),
ncols
= input.
ncols
();
82
83
unsigned
op, on,
delta
= input.
delta_offset
(
dpoint2d
(1, 0));
84
85
data::fill
(parent, 0);
86
max_area = 0;
87
88
{
89
90
// row == 0 and col == 0
91
92
op = input.offset_of_point(
point2d
(0,0));
93
if
(input.
element
(op) == lab)
94
{
95
area.
element
(op) = 1;
96
parent.
element
(op) = op;
97
}
98
99
100
// row = 0
101
102
for
(
unsigned
col = 1; col <
ncols
; ++col)
103
{
104
on = op;
105
++op;
106
107
if
(input.
element
(op) != lab)
108
continue
;
109
110
if
(input.
element
(on) == lab)
111
{
112
unsigned
& par_p = parent.
element
(op);
113
par_p =
find_root
(parent, on);
114
++area.
element
(par_p);
115
if
(area.
element
(par_p) > max_area)
116
max_area = area.
element
(par_p);
117
}
118
else
119
{
120
area.
element
(op) = 1;
121
parent.
element
(op) = op;
122
}
123
124
}
125
}
126
127
128
for
(
unsigned
row = 1; row <
nrows
; ++row)
129
{
130
131
{
132
// col == 0
133
134
op = input.offset_of_point(
point2d
(row, 0));
135
on = op -
delta
;
136
137
if
(input.
element
(op) == lab)
138
{
139
if
(input.
element
(on) == lab)
140
{
141
unsigned
& par_p = parent.
element
(op);
142
par_p =
find_root
(parent, on);
143
++area.
element
(par_p);
144
if
(area.
element
(par_p) > max_area)
145
max_area = area.
element
(par_p);
146
}
147
else
148
{
149
area.
element
(op) = 1;
150
parent.
element
(op) = op;
151
}
152
}
153
154
}
155
156
for
(
unsigned
col = 1; col <
ncols
; ++col)
157
{
158
++op;
159
++on;
160
161
if
(input.
element
(op) != lab)
162
continue
;
163
164
bool
merge_ =
false
;
165
166
// up
167
168
if
(input.
element
(on) == lab)
169
{
170
unsigned
& par_p = parent.
element
(op);
171
par_p =
find_root
(parent, on);
172
++area.
element
(par_p);
173
if
(area.
element
(par_p) > max_area)
174
max_area = area.
element
(par_p);
175
merge_ =
true
;
176
}
177
178
179
// left
180
181
unsigned
ol = op - 1;
182
183
if
(input.
element
(ol) == lab)
184
{
185
if
(merge_)
186
{
187
if
(input.
element
(on - 1) != lab)
// not already merged
188
{
189
unsigned
r_op = parent.
element
(op), r_ol =
find_root
(parent, ol);
190
if
(r_op != r_ol)
191
{
192
// do-union
193
if
(r_op < r_ol)
194
{
195
parent.
element
(r_ol) = r_op;
196
area.
element
(r_op) += area.
element
(r_ol);
197
if
(area.
element
(r_op) > max_area)
198
max_area = area.
element
(r_op);
199
}
200
else
201
{
202
parent.
element
(r_op) = r_ol;
203
area.
element
(r_ol) += area.
element
(r_op);
204
if
(area.
element
(r_ol) > max_area)
205
max_area = area.
element
(r_ol);
206
}
207
}
208
}
209
}
// end of "if (merge)
210
else
211
{
212
unsigned
& par_p = parent.
element
(op);
213
par_p =
find_root
(parent, ol);
214
++area.
element
(par_p);
215
if
(area.
element
(par_p) > max_area)
216
max_area = area.
element
(par_p);
217
merge_ =
true
;
218
}
219
}
220
221
222
// finalization
223
224
if
(merge_ ==
false
)
225
{
226
parent.
element
(op) = op;
227
area.
element
(op) = 1;
228
}
229
230
}
231
}
232
233
}
// end of 'union_find'
234
235
# endif // ! MLN_INCLUDE_ONLY
236
237
}
// end of namespace scribo::primivite::extract::internal
238
239
}
// end of namespace scribo::primitive::extract
240
241
}
// end of namespace scribo::primitive
242
243
}
// end of namespace scribo
244
245
246
#endif // ! SCRIBO_PRIMITIVE_EXTRACT_INTERNAL_UNION_HH
scribo
scribo
primitive
extract
internal
union.hh
Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)