27 #ifndef SCRIBO_FILTER_OBJECTS_WITH_HOLES_HH
28 # define SCRIBO_FILTER_OBJECTS_WITH_HOLES_HH
36 # include <mln/core/image/image2d.hh>
37 # include <mln/core/alias/neighb2d.hh>
38 # include <mln/core/routine/extend.hh>
39 # include <mln/core/image/dmorph/extended.hh>
41 # include <mln/extension/duplicate.hh>
43 # include <mln/draw/box_plain.hh>
44 # include <mln/util/array.hh>
46 # include <mln/labeling/blobs_and_compute.hh>
48 # include <mln/accu/math/count.hh>
50 # include <mln/fun/i2v/array.hh>
52 # include <mln/io/pbm/save.hh>
53 # include <mln/io/pgm/save.hh>
55 # include <mln/data/convert.hh>
57 # include <mln/labeling/background.hh>
59 # include <scribo/core/macros.hh>
60 # include <scribo/core/component_set.hh>
61 # include <scribo/filter/internal/compute.hh>
63 # include <mln/data/fill.hh>
64 # include <mln/data/paste.hh>
66 # include <mln/util/timer.hh>
68 # include <mln/value/label_16.hh>
71 #include <mln/debug/filename.hh>
98 unsigned min_holes_count,
115 template <
typename L>
122 # ifndef MLN_INCLUDE_ONLY
131 return parent.
element(x) = my_find_root(parent,
136 template <
typename L>
138 compute_bboxes_image(const component_set<L>&
components)
140 typedef mln_psite(L) P;
141 typedef mln_dpsite(P) D;
146 mln_concrete(L) output;
147 initialize(output, lbl);
150 for_all_comps(i, components)
151 if (components(i).is_valid())
153 mln_box(L) b = components(i).
bbox();
157 nrows = b.pmax().row() - b.pmin().row() + 1,
158 ncols = b.pmax().col() - b.pmin().col() + 1,
159 row_offset = lbl.delta_offset(D(+1, -
ncols));
161 mln_value(L) *ptr = &output(b.pmin());
162 for (
unsigned row = 0; row <
nrows; ++row, ptr += row_offset)
163 for (
unsigned col = 0; col < ncols; ++col)
181 template <typename L>
185 unsigned min_holes_count,
188 mln_trace(
"scribo::filter::objects_with_holes");
190 typedef component_set<L> O;
196 util::array<util::set<unsigned> > bg_comps(
197 value::next(components.nelements()));
200 to_keep(value::next(components.nelements()),
203 const L& lbl = components.labeled_image();
216 bboxes_ima = internal::compute_bboxes_image(components);
223 util::array<int>
dp = positive_offsets_wrt(lbl, nbh);
224 const unsigned n_nbhs = dp.nelements();
226 mln_bkd_pixter(
const L) pxl(lbl);
229 unsigned p = pxl.offset();
230 if (bboxes_ima.element(p) == 0 || lbl.element(p) != literal::zero)
234 for (
unsigned i = 0; i < n_nbhs; ++i)
236 unsigned n = p + dp[i];
237 if (bboxes_ima.element(n) == 0 || lbl.element(n) != literal::zero)
240 unsigned r = internal::my_find_root(parent, n);
258 mln_fwd_pixter(
const L) pxl(bboxes_ima);
261 unsigned p = pxl.offset();
264 if (parent.
element(p) == 0 || bboxes_ima.element(p) == literal::zero)
267 unsigned& parent_p = parent.
element(p);
270 parent_p = parent.
element(parent_p);
272 if (card.
element(p) < min_size)
280 mln_value(L) object_id = bboxes_ima.element(p);
284 && bg_comps(object_id).nelements() < min_holes_count)
286 if (! bg_comps(object_id).
has(parent_p))
288 bg_comps(object_id).insert(parent_p);
290 if (bg_comps(object_id).
nelements() == min_holes_count)
292 to_keep(object_id) =
true;
300 if (kept == components.nelements())
305 component_set<L> output = components.duplicate();
315 template <
typename L>
321 mln_trace(
"scribo::filter::objects_with_holes");
323 typedef component_set<L> O;
329 util::array<unsigned> bg_comps(
330 value::next(components.nelements()), 0);
331 util::array<bool> bg_comps_done(
332 value::next(components.nelements()),
false);
335 to_keep(value::next(components.nelements()),
false);
337 const L& lbl = components.labeled_image();
350 bboxes_ima = internal::compute_bboxes_image(components);
357 util::array<int> dp = positive_offsets_wrt(lbl, nbh);
358 const unsigned n_nbhs = dp.nelements();
360 mln_bkd_pixter(
const L) pxl(lbl);
363 unsigned p = pxl.offset();
364 if (bboxes_ima.element(p) == 0 || lbl.element(p) != literal::zero)
368 for (
unsigned i = 0; i < n_nbhs; ++i)
370 unsigned n = p + dp[i];
371 if (bboxes_ima.element(n) == 0 || lbl.element(n) != literal::zero)
374 unsigned r = internal::my_find_root(parent, n);
389 mln_fwd_pixter(
const L) pxl(bboxes_ima);
392 unsigned p = pxl.offset();
396 unsigned& parent_p = parent.
element(p);
399 parent_p = parent.
element(parent_p);
401 if (card.
element(p) < min_size)
410 && bboxes_ima.element(p) != literal::zero)
412 mln_value(L) object_id = bboxes_ima.element(p);
413 if (!bg_comps_done(object_id) && components(object_id).is_valid())
415 if (bg_comps(object_id) == 0)
417 bg_comps(object_id) = parent_p;
419 else if (bg_comps(object_id) != parent_p)
421 bg_comps_done(object_id) =
true;
422 to_keep(object_id) =
true;
429 component_set<L> output;
430 if (kept == components.nelements())
435 output = components.duplicate();
444 # endif // ! MLN_INCLUDE_ONLY
451 #endif // ! SCRIBO_FILTER_OBJECTS_WITH_HOLES_HH