27 #ifndef SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
28 # define SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
37 # include <mln/core/image/image2d.hh>
38 # include <mln/core/concept/image.hh>
39 # include <mln/core/alias/neighb2d.hh>
40 # include <mln/core/routine/extend.hh>
41 # include <mln/core/image/dmorph/extended.hh>
43 # include <mln/geom/ncols.hh>
44 # include <mln/geom/nrows.hh>
46 # include <mln/extension/duplicate.hh>
47 # include <mln/extension/adjust_fill.hh>
49 # include <mln/draw/box_plain.hh>
50 # include <mln/util/array.hh>
52 # include <mln/accu/math/count.hh>
54 # include <mln/fun/i2v/array.hh>
57 # include <scribo/core/macros.hh>
58 # include <scribo/core/component_set.hh>
59 # include <scribo/core/object_groups.hh>
61 # include <scribo/primitive/group/apply.hh>
91 # ifndef MLN_INCLUDE_ONLY
103 return parent.
element(x) = my_find_root(parent,
108 template <
typename L>
110 compute_bboxes_image(const component_set<L>&
components)
112 typedef mln_psite(L) P;
113 typedef mln_dpsite(P) D;
118 mln_concrete(L) output;
119 initialize(output, lbl);
122 for_all_comps(i, components)
123 if (components(i).is_valid())
125 mln_box(L) b = components(i).
bbox();
131 row_offset = lbl.delta_offset(D(+1, -
ncols));
133 mln_value(L) *ptr = &output(b.pmin());
134 for (
unsigned row = 0; row <
nrows; ++row, ptr += row_offset)
135 for (
unsigned col = 0; col < ncols; ++col)
157 template <
typename L>
163 mln_trace(
"scribo::filter::impl::generic::object_groups_with_holes");
183 mln::util::array<
unsigned> bg_comps(
184 value::next(components.nelements()), 0);
188 mln::fun::i2v::array<
bool>
189 to_keep(
value::next(components.nelements()), false);
191 const L& lbl = components.labeled_image();
209 bboxes_ima = internal::compute_bboxes_image(components);
221 mln_bkd_pixter(
const L) pxl(lbl);
224 unsigned p = pxl.offset();
225 if (bboxes_ima.element(p) == 0 || lbl.element(p) != literal::zero)
229 for (
unsigned i = 0; i < n_nbhs; ++i)
231 unsigned n = p + dp[i];
232 if (bboxes_ima.element(n) == 0 || lbl.element(n) != literal::zero)
235 unsigned r = internal::my_find_root(parent, n);
252 mln_fwd_pixter(
const L) pxl(bboxes_ima);
255 unsigned p = pxl.offset();
259 unsigned& parent_p = parent.
element(p);
262 parent_p = parent.
element(parent_p);
264 if (
card.element(p) < min_size)
273 && bboxes_ima.element(p) != literal::zero)
275 mln_value(L) group_id = bboxes_ima.element(p);
276 if (!to_keep(group_id))
282 if (bg_comps(group_id) == 0)
284 bg_comps(group_id) = parent_p;
287 else if (bg_comps(group_id) != parent_p)
289 to_keep(group_id) =
true;
300 if (kept == components.nelements())
302 return groups.duplicate();
306 object_groups<L> output = groups.duplicate();
307 for_all_groups(c, groups)
308 if (! to_keep(group_2_comp(c)))
309 output(c).invalidate();
323 template <typename L>
329 mln_trace(
"scribo::filter::object_groups_with_holes");
331 mln_precondition(groups.is_valid());
339 # endif // ! MLN_INCLUDE_ONLY
346 #endif // ! SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH