olena: olena-2.0-562-g77ff87b Add a labeling routine working on grayscale images.

* mln/canvas/labeling/blobs.hh, * mln/labeling/blobs.hh, * mln/labeling/blobs_and_compute.hh: Introduce a new functor method handles(). * tests/labeling/Makefile.am: Add target. * mln/labeling/all_blobs.hh, * tests/labeling/all_blobs.cc: New. --- milena/ChangeLog | 14 ++++ milena/mln/canvas/labeling/blobs.hh | 12 ++-- milena/mln/labeling/{blobs.hh => all_blobs.hh} | 68 ++++++++++---------- milena/mln/labeling/blobs.hh | 52 +++++++++------ milena/mln/labeling/blobs_and_compute.hh | 16 ++++- milena/tests/labeling/Makefile.am | 1 + .../tests/labeling/{foreground.cc => all_blobs.cc} | 48 +++++++------- 7 files changed, 121 insertions(+), 90 deletions(-) copy milena/mln/labeling/{blobs.hh => all_blobs.hh} (62%) copy milena/tests/labeling/{foreground.cc => all_blobs.cc} (68%) diff --git a/milena/ChangeLog b/milena/ChangeLog index edf3a65..d9a8d2b 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,19 @@ 2013-04-17 Guillaume Lazzara <z@lrde.epita.fr> + Add a labeling routine working on grayscale images. + + * mln/canvas/labeling/blobs.hh, + * mln/labeling/blobs.hh, + * mln/labeling/blobs_and_compute.hh: Introduce a new functor + method handles(). + + * tests/labeling/Makefile.am: Add target. + + * mln/labeling/all_blobs.hh, + * tests/labeling/all_blobs.cc: New. + +2013-04-17 Guillaume Lazzara <z@lrde.epita.fr> + * doc/mln/convert.dox: Fix from_to_ module name. 2013-04-17 Guillaume Lazzara <z@lrde.epita.fr> diff --git a/milena/mln/canvas/labeling/blobs.hh b/milena/mln/canvas/labeling/blobs.hh index 7f962db..4a643ce 100644 --- a/milena/mln/canvas/labeling/blobs.hh +++ b/milena/mln/canvas/labeling/blobs.hh @@ -108,14 +108,14 @@ namespace mln initialize(output, input); data::fill(output, zero); - extension::fill(input, false); + //extension::fill(input, false); functor.init(); // <-- functor.init() // Loop. mln_piter(I) p(input.domain()); for_all(p) - if (input(p) && output(p) == zero) // Object point, not labeled yet. + if (functor.handles(input(p)) && output(p) == zero) // Object point, not labeled yet. { // Label this point component. if (nlabels == mln_max(L)) @@ -136,8 +136,8 @@ for this label type: nlabels > max(label_type)."); { cur = qu.front(); qu.pop(); - for_all(n) if (input.has(n)) - if (input(n) && output(n) == zero) + for_all(n) if (input.domain().has(n)) + if (input(p) == input(n) && output(n) == zero) { mln_invariant(! qu.compute_has(n)); qu.push(n); @@ -170,8 +170,8 @@ for this label type: nlabels > max(label_type)."); L& nlabels, F& functor) { mln_trace("labeling::blobs"); - mlc_equal(mln_trait_image_kind(I), - mln::trait::image::kind::binary)::check(); + // mlc_equal(mln_trait_image_kind(I), + // mln::trait::image::kind::binary)::check(); const I& input = exact(input_); const N& nbh = exact(nbh_); mln_precondition(input.is_valid()); diff --git a/milena/mln/labeling/blobs.hh b/milena/mln/labeling/all_blobs.hh similarity index 62% copy from milena/mln/labeling/blobs.hh copy to milena/mln/labeling/all_blobs.hh index 5767d5a..96e5a09 100644 --- a/milena/mln/labeling/blobs.hh +++ b/milena/mln/labeling/all_blobs.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2007, 2008, 2009, 2012 EPITA Research and Development -// Laboratory (LRDE) +// Copyright (C) 2007, 2008, 2009, 2012, 2013 EPITA Research and +// Development Laboratory (LRDE) // // This file is part of Olena. // @@ -24,17 +24,15 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef MLN_LABELING_BLOBS_HH -# define MLN_LABELING_BLOBS_HH +#ifndef MLN_LABELING_ALL_BLOBS_HH +# define MLN_LABELING_ALL_BLOBS_HH /// \file /// -/// Connected component labeling of the binary objects of a binary +/// Connected component labeling of the homogeneous regions of an /// image using a queue-based algorithm. /// /// \todo Handle abort in a nice way... -/// -/// \todo Add a 2nd version precising the 'value' to label. # include <mln/core/concept/image.hh> # include <mln/core/concept/neighborhood.hh> @@ -48,24 +46,25 @@ namespace mln namespace labeling { - /// \brief Connected component labeling of the binary objects of a - /// binary image. - /// - /// \param[in] input The input image. - /// \param[in] nbh The connexity of the objects. - /// \param[out] nlabels The Number of labels. Its value is set in the - /// algorithms. - /// \return The label image. - /// - /// \pre The input image has to be binary (checked at compile-time). - /// - /// A fast queue is used so that the algorithm is not recursive and - /// can handle large binary objects (blobs). - // + /*! \brief Connected component labeling of the homogeneous regions + * of an image. + + \param[in] input The input image. + \param[in] nbh The connexity of the objects. + \param[out] nlabels The Number of labels. Its value is set in the + algorithms. + \return The label image. + + A fast queue is used so that the algorithm is not recursive and + can handle large objects (blobs). + + \ingroup labeling + */ template <typename I, typename N, typename L> mln_ch_value(I, L) - blobs(const Image<I>& input, const Neighborhood<N>& nbh, - L& nlabels); + all_blobs(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels); + # ifndef MLN_INCLUDE_ONLY @@ -74,15 +73,16 @@ namespace mln namespace internal { - /*! - \brief Functor not computing anything. To be passed to the labeling - blobs canvas. + /*! \brief Functor not computing anything. To be passed to the + labeling blobs canvas. */ - template <typename L> - struct dummy_functor + template <typename I, typename L> + struct label_values_functor { void init() {} + bool handles(const mln_value(I)&) { return true; } + void new_label(const mln_value(L)&) {} void process_p(const mln_site(L)&) {} @@ -101,18 +101,16 @@ namespace mln template <typename I, typename N, typename L> inline mln_ch_value(I, L) - blobs(const Image<I>& input_, const Neighborhood<N>& nbh_, - L& nlabels) + all_blobs(const Image<I>& input_, const Neighborhood<N>& nbh_, + L& nlabels) { - mln_trace("labeling::blobs"); - mlc_equal(mln_trait_image_kind(I), - mln::trait::image::kind::binary)::check(); + mln_trace("labeling::all_blobs"); const I& input = exact(input_); const N& nbh = exact(nbh_); mln_precondition(input.is_valid()); typedef mln_ch_value(I,L) out_t; - internal::dummy_functor<out_t> functor; + internal::label_values_functor<I, out_t> functor; out_t output = canvas::labeling::blobs(input, nbh, nlabels, functor); @@ -126,4 +124,4 @@ namespace mln } // end of namespace mln -#endif // ! MLN_LABELING_BLOBS_HH +#endif // ! MLN_LABELING_ALL_BLOBS_HH diff --git a/milena/mln/labeling/blobs.hh b/milena/mln/labeling/blobs.hh index 5767d5a..81073d1 100644 --- a/milena/mln/labeling/blobs.hh +++ b/milena/mln/labeling/blobs.hh @@ -1,5 +1,5 @@ -// Copyright (C) 2007, 2008, 2009, 2012 EPITA Research and Development -// Laboratory (LRDE) +// Copyright (C) 2007, 2008, 2009, 2012, 2013 EPITA Research and +// Development Laboratory (LRDE) // // This file is part of Olena. // @@ -48,41 +48,47 @@ namespace mln namespace labeling { - /// \brief Connected component labeling of the binary objects of a - /// binary image. - /// - /// \param[in] input The input image. - /// \param[in] nbh The connexity of the objects. - /// \param[out] nlabels The Number of labels. Its value is set in the - /// algorithms. - /// \return The label image. - /// - /// \pre The input image has to be binary (checked at compile-time). - /// - /// A fast queue is used so that the algorithm is not recursive and - /// can handle large binary objects (blobs). - // + /*! \brief Connected component labeling of the binary objects of a + binary image. + + \param[in] input The input image. + \param[in] nbh The connexity of the objects. + \param[out] nlabels The Number of labels. Its value is set in the + algorithms. + \return The label image. + + \pre The input image has to be binary (checked at compile-time). + + A fast queue is used so that the algorithm is not recursive and + can handle large binary objects (blobs). + + \ingroup labeling + */ template <typename I, typename N, typename L> mln_ch_value(I, L) blobs(const Image<I>& input, const Neighborhood<N>& nbh, L& nlabels); + # ifndef MLN_INCLUDE_ONLY namespace internal { - /*! - \brief Functor not computing anything. To be passed to the labeling - blobs canvas. + /*! \brief Functor not computing anything. To be passed to the + labeling blobs canvas. */ - template <typename L> - struct dummy_functor + template <typename I, typename L> + struct label_value_functor { + label_value_functor(const mln_value(I)& value) : value_(value) {} + void init() {} + bool handles(const mln_value(I)& v) { return v == value_; } + void new_label(const mln_value(L)&) {} void process_p(const mln_site(L)&) {} @@ -90,6 +96,8 @@ namespace mln void process_n(const mln_site(L)&) {} void finalize() {} + + mln_value(I) value_; }; } // end of namespace mln::labeling::internal @@ -112,7 +120,7 @@ namespace mln mln_precondition(input.is_valid()); typedef mln_ch_value(I,L) out_t; - internal::dummy_functor<out_t> functor; + internal::label_value_functor<I, out_t> functor(true); out_t output = canvas::labeling::blobs(input, nbh, nlabels, functor); diff --git a/milena/mln/labeling/blobs_and_compute.hh b/milena/mln/labeling/blobs_and_compute.hh index 166af6a..f7d2f76 100644 --- a/milena/mln/labeling/blobs_and_compute.hh +++ b/milena/mln/labeling/blobs_and_compute.hh @@ -1,4 +1,4 @@ -// Copyright (C) 2009, 2010, 2012 EPITA Research and Development +// Copyright (C) 2009, 2010, 2012, 2013 EPITA Research and Development // Laboratory (LRDE) // // This file is part of Olena. @@ -46,7 +46,7 @@ namespace mln namespace labeling { - /*! Label an image and compute given accumulators. + /*! \brief Label an image and compute given accumulators. \param[in] input A binary image. \param[in] nbh A neighborhood used for labeling. @@ -56,6 +56,8 @@ namespace mln \return The labeled image, computed attributes for each regions and an array of the accumulators used to compute the attributes. + + \ingroup labeling */ template <typename I, typename N, typename L, typename A> util::couple<mln_ch_value(I,L), @@ -77,7 +79,7 @@ namespace mln \brief Functor not computing anything. To be passed to the labeling blobs canvas. */ - template <typename L, typename A> + template <typename I, typename L, typename A> struct compute_functor { typedef mln_result(A) accu_result; @@ -98,6 +100,12 @@ namespace mln } inline + bool handles(const mln_value(I)& v) + { + return v; + } + + inline void new_label(const mln_value(L)& l) { current_lbl_ = l; @@ -172,7 +180,7 @@ namespace mln mln_precondition(exact(input).is_valid()); typedef mln_ch_value(I,L) out_t; - typedef internal::compute_functor<out_t,A> func_t; + typedef internal::compute_functor<I,out_t,A> func_t; func_t functor(nlabels); out_t output = canvas::labeling::blobs(input, nbh, nlabels, functor); diff --git a/milena/tests/labeling/Makefile.am b/milena/tests/labeling/Makefile.am index 1cabf25..9aa5416 100644 --- a/milena/tests/labeling/Makefile.am +++ b/milena/tests/labeling/Makefile.am @@ -22,6 +22,7 @@ EXTRA_DIST = \ check_PROGRAMS = \ + all_blobs \ background \ blobs \ blobs_and_compute \ diff --git a/milena/tests/labeling/foreground.cc b/milena/tests/labeling/all_blobs.cc similarity index 68% copy from milena/tests/labeling/foreground.cc copy to milena/tests/labeling/all_blobs.cc index 286c166..646227a 100644 --- a/milena/tests/labeling/foreground.cc +++ b/milena/tests/labeling/all_blobs.cc @@ -1,5 +1,5 @@ -// Copyright (C) 2007, 2008, 2009, 2010, 2013 EPITA Research and -// Development Laboratory (LRDE) +// Copyright (C) 2007, 2008, 2009, 2013 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -25,37 +25,39 @@ // executable file might be covered by the GNU General Public License. #include <mln/core/image/image2d.hh> -#include <mln/core/var.hh> #include <mln/io/pbm/load.hh> #include <mln/io/pgm/load.hh> #include <mln/core/alias/neighb2d.hh> -#include <mln/data/compare.hh> -#include <mln/labeling/foreground.hh> +#include <mln/labeling/all_blobs.hh> #include <mln/value/int_u8.hh> +#include <mln/labeling/colorize.hh> +#include <mln/io/ppm/save.hh> +#include <mln/value/rgb8.hh> +#include <mln/debug/println.hh> + #include "tests/data.hh" -#include <mln/io/pgm/save.hh> int main() { using namespace mln; - typedef image2d<bool> I; - neighb2d nbh = c4(); - - // Load ref - image2d<value::int_u8> ref; - io::pgm::load(ref, MLN_TESTS_DIR "/labeling/foreground.ref.pgm"); - - - I input = io::pbm::load(MLN_IMG_DIR "/picasso.pbm"); - image2d<value::int_u8> out; - - value::int_u8 n; - out = labeling::foreground(input, nbh, n); - - - mln_assertion(n == 33); - mln_assertion(ref == out); + // Binary image + { + image2d<bool> pic; + io::pbm::load(pic, MLN_IMG_DIR "/picasso.pbm"); + unsigned n; + labeling::all_blobs(pic, c4(), n); + mln_assertion(n == 142); + } + + // Gray-level image + { + image2d<value::int_u8> pic; + io::pgm::load(pic, MLN_IMG_DIR "/fly.pgm"); + unsigned n; + labeling::all_blobs(pic, c4(), n); + mln_assertion(n == 24); + } } -- 1.7.2.5
participants (1)
-
Guillaume Lazzara