---
scribo/ChangeLog | 12 ++-
.../fill_object_holes.hh} | 134 ++++++++++++++++----
2 files changed, 118 insertions(+), 28 deletions(-)
copy scribo/{filter/object_groups_with_holes.hh =>
postprocessing/fill_object_holes.hh} (65%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 4aa545d..97f15b8 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,11 +1,15 @@
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * postprocessing/fill_object_holes.hh: New routine.
+
+2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new routines to detect separators.
- * scribo/primitive/extract/horizontal_separators.hh,
- * scribo/primitive/extract/separators.hh,
- * scribo/primitive/extract/vertical_separators.hh,
- * scribo/primitive/remove/separators.hh: New.
+ * primitive/extract/horizontal_separators.hh,
+ * primitive/extract/separators.hh,
+ * primitive/extract/vertical_separators.hh,
+ * primitive/remove/separators.hh: New.
2010-04-30 Guillaume Lazzara <z(a)lrde.epita.fr>
diff --git a/scribo/filter/object_groups_with_holes.hh
b/scribo/postprocessing/fill_object_holes.hh
similarity index 65%
copy from scribo/filter/object_groups_with_holes.hh
copy to scribo/postprocessing/fill_object_holes.hh
index 570ae6a..4771844 100644
--- a/scribo/filter/object_groups_with_holes.hh
+++ b/scribo/postprocessing/fill_object_holes.hh
@@ -23,12 +23,16 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
-# define SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
+#ifndef SCRIBO_POSTPROCESSING_FILL_OBJECT_HOLES_HH
+# define SCRIBO_POSTPROCESSING_FILL_OBJECT_HOLES_HH
/// \file
///
-/// \brief Remove groups not having a minimum number of holes.
+/// \brief Fill-in object small holes.
+
+/// \FIXME share code with filter/object_groups_with_holes.hh
+/// \FIXME Merge the two following routines.
+/// \FIXME Use a size ratio in both overloads.
# include <sstream>
@@ -47,28 +51,32 @@
# include <mln/fun/i2v/array.hh>
# include <scribo/core/macros.hh>
-# include <scribo/core/component_set.hh>
+# include <scribo/core/object_groups.hh>
+# include <scribo/primitive/group/apply.hh>
namespace scribo
{
- namespace filter
+ namespace postprocessing
{
using namespace mln;
- /*! \brief Remove groups not having a minimum number of holes.
+ /*! \brief Fill-in object small holes.
+ */
+ template <typename I>
+ inline
+ mln_concrete(I)
+ fill_object_holes(const Image<I>& input, float ratio);
- */
template <typename L>
inline
object_groups<L>
- object_groups_with_holes(const object_groups<L>& components,
- unsigned min_size);
-
+ fill_object_holes(const object_groups<L>& groups,
+ unsigned min_size);
# ifndef MLN_INCLUDE_ONLY
@@ -124,7 +132,7 @@ namespace scribo
}
- } // end of namespace scribo::filter::internal
+ } // end of namespace scribo::postprocessing::internal
@@ -139,10 +147,10 @@ namespace scribo
template <typename L>
inline
object_groups<L>
- object_groups_with_holes(const object_groups<L>& groups,
+ fill_object_holes(const object_groups<L>& groups,
unsigned min_size)
{
- trace::entering("scribo::filter::impl::generic::object_groups_with_holes");
+
trace::entering("scribo::postprocessing::impl::generic::fill_object_holes");
// Grouping groups and relabel the underlying labeled image.
// Groups are now considered as components.
@@ -259,7 +267,7 @@ namespace scribo
if (kept == components.nelements())
{
-
trace::exiting("scribo::filter::impl::generic::object_groups_with_holes");
+
trace::exiting("scribo::postprocessing::impl::generic::fill_object_holes");
return groups.duplicate();
}
@@ -269,15 +277,15 @@ namespace scribo
output(c) = 0;
-
trace::exiting("scribo::filter::impl::generic::object_groups_with_holes");
+
trace::exiting("scribo::postprocessing::impl::generic::fill_object_holes");
return output;
}
}
- } // end of namespace scribo::filter::impl::generic
+ } // end of namespace scribo::postprocessing::impl::generic
- } // end of namespace scribo::filter::impl
+ } // end of namespace scribo::postprocessing::impl
@@ -286,25 +294,103 @@ namespace scribo
template <typename L>
inline
object_groups<L>
- object_groups_with_holes(const object_groups<L>& groups,
- unsigned min_size)
+ fill_object_holes(const object_groups<L>& groups,
+ unsigned min_size)
{
- trace::entering("scribo::filter::object_groups_with_holes");
+ trace::entering("scribo::postprocessing::fill_object_holes");
mln_precondition(groups.is_valid());
object_groups<L>
- output = impl::generic::object_groups_with_holes(groups, min_size);
+ output = impl::generic::fill_object_holes(groups, min_size);
+
+ trace::exiting("scribo::postprocessing::fill_object_holes");
+ return output;
+ }
+
+
+ template <typename I>
+ inline
+ mln_concrete(I)
+ fill_object_holes(const Image<I>& input_, float ratio)
+ {
+ trace::entering("scribo::postprocessing::fill_object_holes");
+
+ mln_precondition(input.is_valid());
+ mlc_is(mln_value(I), bool)::check();
+
+ const I& input = exact(input_);
+ mln_concrete(I) output = duplicate(input);
+
+ typedef value::int_u16 L;
+ typedef mln_ch_value(I, L) Li;
+ typedef accu::math::count<mln_site(Li)> A;
+
+ typedef util::couple<Li, util::couple<util::array<unsigned>,
+ util::array<A> > > res_t;
+
+ // Holes card Image
+
+ std::cout << "> Holes card image" << std::endl;
+
+ L nlabels;
+
+ res_t res = labeling::blobs_and_compute(input, c8(), nlabels, A());
- trace::exiting("scribo::filter::object_groups_with_holes");
+ util::array<unsigned>& holes_card = res.second().first();
+ mln_ch_value(I, unsigned)
+ holes = data::transform(res.first(), holes_card);
+
+
+
+ // Threshold Image
+
+ std::cout << "> Threshold image" << std::endl;
+
+
+ I input_i = logical::not_(input);
+ res = labeling::blobs_and_compute(input_i, c8(), nlabels, A());
+
+ util::array<unsigned>& card = res.second().first();
+ for (unsigned i = 1; i < card.size(); ++i)
+ card(i) = card(i) * ratio;
+
+ mln_ch_value(I, unsigned)
+ thres = data::transform(res.first(), card);
+ thres = transform::influence_zone_geodesic(thres, c8());
+
+
+
+ // Thresholding
+
+ std::cout << "> Thresholding" << std::endl;
+
+ I hole_mask;
+ initialize(hole_mask, holes);
+ data::fill(hole_mask, false);
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (holes(p))
+ hole_mask(p) = holes(p) < thres(p);
+
+
+ // Cleanup
+
+ std::cout << "> Cleanup" << std::endl;
+
+ data::fill((output | pw::value(hole_mask)).rw(), false);
+
+
+ trace::exiting("scribo::postprocessing::fill_object_holes");
return output;
}
+
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace scribo::filter
+ } // end of namespace scribo::postprocessing
} // end of namespace scribo
-#endif // ! SCRIBO_FILTER_OBJECT_GROUPS_WITH_HOLES_HH
+#endif // ! SCRIBO_POSTPROCESSING_FILL_OBJECT_HOLES_HH
--
1.5.6.5