olena-2.0-488-gf8e6233 Add support for graylevel images in labeling::blobs.

* mln/canvas/labeling/blobs.hh: Add a fastest version and make it support graylevel images. * mln/labeling/blobs.hh, * mln/labeling/blobs_and_compute.hh: Add support for graylevel images. * tests/labeling/blobs.cc, * tests/labeling/blobs_and_compute.cc: Add a test for graylevel images. * tests/labeling/Makefile.am: Remove all_blobs target. * mln/labeling/all_blobs.hh, * tests/labeling/all_blobs.cc: Remove. --- milena/ChangeLog | 18 ++++ milena/mln/canvas/labeling/blobs.hh | 136 ++++++++++++++++++++++++++-- milena/mln/labeling/all_blobs.hh | 127 -------------------------- milena/mln/labeling/blobs.hh | 65 ++++++++++---- milena/mln/labeling/blobs_and_compute.hh | 83 +++++++++++++++-- milena/tests/labeling/Makefile.am | 1 - milena/tests/labeling/all_blobs.cc | 63 ------------- milena/tests/labeling/blobs.cc | 26 +++++- milena/tests/labeling/blobs_and_compute.cc | 55 ++++++++--- 9 files changed, 329 insertions(+), 245 deletions(-) delete mode 100644 milena/mln/labeling/all_blobs.hh delete mode 100644 milena/tests/labeling/all_blobs.cc diff --git a/milena/ChangeLog b/milena/ChangeLog index 4949cad..1f9c705 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,23 @@ 2013-04-18 Guillaume Lazzara <z@lrde.epita.fr> + Add support for graylevel images in labeling::blobs. + + * mln/canvas/labeling/blobs.hh: Add a fastest version and make it + support graylevel images. + + * mln/labeling/blobs.hh, + * mln/labeling/blobs_and_compute.hh: Add support for graylevel images. + + * tests/labeling/blobs.cc, + * tests/labeling/blobs_and_compute.cc: Add a test for graylevel images. + + * tests/labeling/Makefile.am: Remove all_blobs target. + + * mln/labeling/all_blobs.hh, + * tests/labeling/all_blobs.cc: Remove. + +2013-04-18 Guillaume Lazzara <z@lrde.epita.fr> + * mln/core/internal/pixel_impl.hh: Add change_offset(). 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 4a643ce..f913901 100644 --- a/milena/mln/canvas/labeling/blobs.hh +++ b/milena/mln/canvas/labeling/blobs.hh @@ -90,9 +90,15 @@ namespace mln template <typename I, typename N, typename L, typename F> mln_ch_value(I, L) - blobs(const Image<I>& input_, const N& nbh, L& nlabels, F& functor) + blobs(const Image<I>& input_, const Neighborhood<N>& nbh_, L& nlabels, F& functor) { + mln_trace("mln::canvas::labeling::impl::generic::blobs"); + const I& input = exact(input_); + const N& nbh = exact(nbh_); + + mln_precondition(input.is_valid()); + mln_precondition(nbh.is_valid()); typedef mln_psite(I) P; @@ -108,20 +114,24 @@ namespace mln initialize(output, input); data::fill(output, zero); - //extension::fill(input, false); + // No initialization needed in border since we look into + // the image domain for the neighborhood. + // + // extension::fill(input, functor.neutral_value()); // <-- functor.neutral_value() functor.init(); // <-- functor.init() // Loop. mln_piter(I) p(input.domain()); for_all(p) - if (functor.handles(input(p)) && output(p) == zero) // Object point, not labeled yet. + if (functor.handles(input(p)) // <-- functor.handles() + && output(p) == zero) // Object point, not labeled yet. { // Label this point component. if (nlabels == mln_max(L)) { - mln_trace_warning("labeling aborted! Too many labels \ -for this label type: nlabels > max(label_type)."); + mln_trace_warning("labeling aborted! Too many labels " + "for this label type: nlabels > max(label_type)."); return output; } @@ -157,10 +167,119 @@ for this label type: nlabels > max(label_type)."); } // end of namespace mln::labeling::impl::generic + template <typename I, typename N, typename L, typename F> + mln_ch_value(I, L) + blobs_fastest(const Image<I>& input_, const Neighborhood<N>& nbh_, + L& nlabels, F& functor) + { + mln_trace("mln::canvas::labeling::impl::blobs_fastest"); + + const I& input = exact(input_); + const N& nbh = exact(nbh_); + + mln_precondition(input.is_valid()); + mln_precondition(nbh.is_valid()); + + typedef mln_psite(I) P; + + mln_pixter(const I) cur(input); + mln_nixter(const I,N) n(cur, nbh); + p_queue_fast<unsigned> qu; + const L zero = literal::zero; + + // Initialization. + nlabels = literal::zero; + typedef mln_ch_value(I, L) out_t; + out_t output; + initialize(output, input); + data::fill(output, zero); + + extension::fill(input, functor.neutral_value()); // <-- functor.neutral_value() + + functor.init(); // <-- functor.init() + + // Loop. + mln_pixter(const I) p(input); + for_all(p) + if (functor.handles(p.val()) // <-- functor.handles() + && output.element(p.offset()) == zero) // Object point, not labeled yet. + { + // Label this point component. + if (nlabels == mln_max(L)) + { + mln_trace_warning("labeling aborted! Too many labels " + "for this label type: nlabels > max(label_type)."); + + return output; + } + ++nlabels; + functor.new_label(nlabels); // <-- functor.new_label() + mln_invariant(qu.is_empty()); + qu.push(p.offset()); + output.element(p.offset()) = nlabels; + functor.process_p_(p.offset()); // <-- functor.process_p_() + do + { + cur.change_offset(qu.front()); + qu.pop(); + for_all(n) + if (p.val() == n.val() && output.element(n.offset()) == zero) + { + mln_invariant(! qu.compute_has(n.offset())); + qu.push(n.offset()); + output.element(n) = nlabels; + functor.process_n_(n.offset()); // <-- functor.process_n_() + } + } + while (! qu.is_empty()); + } + + functor.finalize(); // <-- functor.finalize() + + return output; + } + } // end of namespace mln::canvas::labeling::impl + // Dispatch + + namespace internal + { + + template <typename I, typename N, typename L, typename F> + inline + mln_ch_value(I, L) + blobs_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels, F& functor, mln::trait::image::speed::any) + { + return impl::generic::blobs(input, nbh, nlabels, functor); + } + + template <typename I, typename N, typename L, typename F> + inline + mln_ch_value(I, L) + blobs_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels, F& functor, mln::trait::image::speed::fastest) + { + return impl::blobs_fastest(input, nbh, nlabels, functor); + } + + template <typename I, typename N, typename L, typename F> + inline + mln_ch_value(I, L) + blobs_dispatch(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels, F& functor) + { + typedef mln_trait_image_speed(I) speed; + return blobs_dispatch(input, nbh, nlabels, functor, speed()); + } + + } // end of namespace mln::canvas::labeling::internal + + + // Facade. template <typename I, typename N, typename L, typename F> @@ -169,16 +288,15 @@ for this label type: nlabels > max(label_type)."); blobs(const Image<I>& input_, const Neighborhood<N>& nbh_, L& nlabels, F& functor) { - mln_trace("labeling::blobs"); - // mlc_equal(mln_trait_image_kind(I), - // mln::trait::image::kind::binary)::check(); + mln_trace("mln::canvas::labeling::blobs"); + const I& input = exact(input_); const N& nbh = exact(nbh_); mln_precondition(input.is_valid()); // The only implementation is the generic one. mln_ch_value(I, L) - output = impl::generic::blobs(input, nbh, nlabels, functor); + output = internal::blobs_dispatch(input, nbh, nlabels, functor); return output; } diff --git a/milena/mln/labeling/all_blobs.hh b/milena/mln/labeling/all_blobs.hh deleted file mode 100644 index 96e5a09..0000000 --- a/milena/mln/labeling/all_blobs.hh +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (C) 2007, 2008, 2009, 2012, 2013 EPITA Research and -// Development Laboratory (LRDE) -// -// This file is part of Olena. -// -// Olena is free software: you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation, version 2 of the License. -// -// Olena is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to produce -// an executable, this file does not by itself cause the resulting -// executable to be covered by the GNU General Public License. This -// exception does not however invalidate any other reasons why the -// executable file might be covered by the GNU General Public License. - -#ifndef MLN_LABELING_ALL_BLOBS_HH -# define MLN_LABELING_ALL_BLOBS_HH - -/// \file -/// -/// Connected component labeling of the homogeneous regions of an -/// image using a queue-based algorithm. -/// -/// \todo Handle abort in a nice way... - -# include <mln/core/concept/image.hh> -# include <mln/core/concept/neighborhood.hh> - -# include <mln/canvas/labeling/blobs.hh> - - -namespace mln -{ - - namespace labeling - { - - /*! \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) - all_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. - */ - 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)&) {} - - void process_n(const mln_site(L)&) {} - - void finalize() {} - }; - - } // end of namespace mln::labeling::internal - - - - // Facade. - - template <typename I, typename N, typename L> - inline - mln_ch_value(I, L) - all_blobs(const Image<I>& input_, const Neighborhood<N>& nbh_, - L& nlabels) - { - 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::label_values_functor<I, out_t> functor; - out_t - output = canvas::labeling::blobs(input, nbh, nlabels, functor); - - return output; - } - -# endif // ! MLN_INCLUDE_ONLY - - } // end of namespace mln::labeling - -} // end of namespace mln - - -#endif // ! MLN_LABELING_ALL_BLOBS_HH diff --git a/milena/mln/labeling/blobs.hh b/milena/mln/labeling/blobs.hh index 81073d1..d3c672d 100644 --- a/milena/mln/labeling/blobs.hh +++ b/milena/mln/labeling/blobs.hh @@ -33,8 +33,6 @@ /// 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,27 +46,41 @@ namespace mln namespace labeling { - /*! \brief Connected component labeling of the binary objects of a - binary image. + /*! \brief Connected component labeling of the objects 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. - - \pre The input image has to be binary (checked at compile-time). + \param[in] background_value The value to be considered as + background and not to be labeled. + \return A labeled image. A fast queue is used so that the algorithm is not recursive and - can handle large binary objects (blobs). + 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); + L& nlabels, const mln_value(I)& background_value); + + /*! \overload + \brief Connected component labeling of the objects of an + image. + + background_value is set to literal::zero. + + \ingroup labeling + */ + template <typename I, typename N, typename L> + inline + mln_ch_value(I, L) + blobs(const Image<I>& input_, const Neighborhood<N>& nbh_, + L& nlabels); # ifndef MLN_INCLUDE_ONLY @@ -83,11 +95,14 @@ namespace mln template <typename I, typename L> struct label_value_functor { - label_value_functor(const mln_value(I)& value) : value_(value) {} + label_value_functor(const mln_value(I)& background_value) + : background_value_(background_value) {} void init() {} - bool handles(const mln_value(I)& v) { return v == value_; } + mln_value(I) neutral_value() const { return this->background_value_; } + + bool handles(const mln_value(I)& v) const { return v != this->background_value_; } void new_label(const mln_value(L)&) {} @@ -97,7 +112,15 @@ namespace mln void finalize() {} - mln_value(I) value_; + + // Fastest interface + + void process_p_(unsigned) {} + + void process_n_(unsigned) {} + + + mln_value(I) background_value_; }; } // end of namespace mln::labeling::internal @@ -110,23 +133,33 @@ namespace mln inline mln_ch_value(I, L) blobs(const Image<I>& input_, const Neighborhood<N>& nbh_, - L& nlabels) + L& nlabels, const mln_value(I)& background_value) { mln_trace("labeling::blobs"); - 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()); typedef mln_ch_value(I,L) out_t; - internal::label_value_functor<I, out_t> functor(true); + internal::label_value_functor<I, out_t> functor(background_value); out_t output = canvas::labeling::blobs(input, nbh, nlabels, functor); return output; } + template <typename I, typename N, typename L> + inline + mln_ch_value(I, L) + blobs(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels) + { + return blobs(input, nbh, nlabels, + static_cast<mln_value(I)>(literal::zero)); + } + + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::labeling diff --git a/milena/mln/labeling/blobs_and_compute.hh b/milena/mln/labeling/blobs_and_compute.hh index f7d2f76..2b7b445 100644 --- a/milena/mln/labeling/blobs_and_compute.hh +++ b/milena/mln/labeling/blobs_and_compute.hh @@ -35,7 +35,7 @@ # include <mln/core/concept/image.hh> # include <mln/core/concept/neighborhood.hh> -# include <mln/labeling/blobs.hh> +# include <mln/canvas/labeling/blobs.hh> # include <mln/labeling/compute.hh> # include <mln/util/couple.hh> @@ -52,6 +52,8 @@ namespace mln \param[in] nbh A neighborhood used for labeling. \param[in,out] nlabels The number of labels found. \param[in] accu An accumulator to be computed while labeling. + \param[in] background_value The value to be considered as + background and not to be labeled. \return The labeled image, computed attributes for each regions and an array of the accumulators used to compute the @@ -64,8 +66,21 @@ namespace mln util::couple<util::array<mln_result(A)>, util::array<A> > > blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh, - L& nlabels, const Accumulator<A>& accu); + L& nlabels, const Accumulator<A>& accu, + const mln_value(I)& background_value); + /*! \brief Label an image and compute given accumulators. + + background_value is set to literal::zero. + + \ingroup labeling + */ + template <typename I, typename N, typename L, typename A> + util::couple<mln_ch_value(I,L), + util::couple<util::array<mln_result(A)>, + util::array<A> > > + blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels, const Accumulator<A>& accu); # ifndef MLN_INCLUDE_ONLY @@ -87,8 +102,10 @@ namespace mln typedef util::couple<util::array<accu_result>, util::array<A> > result; - compute_functor(const mln_value(L)& nlabels) - : nlabels_(nlabels) + compute_functor(const mln_value(L)& nlabels, const I& input, + const mln_value(I)& background_value) + : nlabels_(nlabels), input_(input), + background_value_(background_value) { } @@ -100,9 +117,15 @@ namespace mln } inline + mln_value(I) neutral_value() const + { + return background_value_; + } + + inline bool handles(const mln_value(I)& v) { - return v; + return v != background_value_; } inline @@ -131,6 +154,21 @@ namespace mln } + // Fastest interface + + inline + void process_p_(const unsigned p) + { + process__(accu_argument(), p); + } + + inline + void process_n_(const unsigned n) + { + process__(accu_argument(), n); + } + + private: inline void process__(const mln_psite(L)&, const mln_site(L)& p) @@ -144,6 +182,19 @@ namespace mln accus_[current_lbl_].take(current_lbl_); } + inline + void process__(const mln_psite(L)&, const unsigned p) + { + accus_[current_lbl_].take(input_.point_at_offset(p)); + } + + inline + void process__(const mln_value(L)&, const unsigned) + { + accus_[current_lbl_].take(current_lbl_); + } + + template <typename V> inline void process__(const V&, const mln_site(L)&) @@ -156,6 +207,8 @@ namespace mln util::array<A> accus_; mln_value(L) current_lbl_; mln_value(L) nlabels_; + const I input_; + mln_value(I) background_value_; }; } // end of namespace mln::labeling::internal @@ -170,18 +223,18 @@ namespace mln util::couple<util::array<mln_result(A)>, util::array<A> > > blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh, - L& nlabels, const Accumulator<A>& accu) + L& nlabels, const Accumulator<A>& accu, + const mln_value(I)& background_value) { mln_trace("labeling::blobs_and_compute"); (void) accu; - mlc_equal(mln_trait_image_kind(I), - mln::trait::image::kind::binary)::check(); mln_precondition(exact(input).is_valid()); + mln_precondition(exact(nbh).is_valid()); typedef mln_ch_value(I,L) out_t; typedef internal::compute_functor<I,out_t,A> func_t; - func_t functor(nlabels); + func_t functor(nlabels, exact(input), background_value); out_t output = canvas::labeling::blobs(input, nbh, nlabels, functor); @@ -193,6 +246,18 @@ namespace mln } + template <typename I, typename N, typename L, typename A> + util::couple<mln_ch_value(I,L), + util::couple<util::array<mln_result(A)>, + util::array<A> > > + blobs_and_compute(const Image<I>& input, const Neighborhood<N>& nbh, + L& nlabels, const Accumulator<A>& accu) + { + return blobs_and_compute(input, nbh, nlabels, accu, + static_cast<mln_value(I)>(literal::zero)); + } + + # endif // ! MLN_INCLUDE_ONLY diff --git a/milena/tests/labeling/Makefile.am b/milena/tests/labeling/Makefile.am index 9aa5416..1cabf25 100644 --- a/milena/tests/labeling/Makefile.am +++ b/milena/tests/labeling/Makefile.am @@ -22,7 +22,6 @@ EXTRA_DIST = \ check_PROGRAMS = \ - all_blobs \ background \ blobs \ blobs_and_compute \ diff --git a/milena/tests/labeling/all_blobs.cc b/milena/tests/labeling/all_blobs.cc deleted file mode 100644 index 646227a..0000000 --- a/milena/tests/labeling/all_blobs.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007, 2008, 2009, 2013 EPITA Research and Development -// Laboratory (LRDE) -// -// This file is part of Olena. -// -// Olena is free software: you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation, version 2 of the License. -// -// Olena is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to produce -// an executable, this file does not by itself cause the resulting -// executable to be covered by the GNU General Public License. This -// exception does not however invalidate any other reasons why the -// executable file might be covered by the GNU General Public License. - -#include <mln/core/image/image2d.hh> -#include <mln/io/pbm/load.hh> -#include <mln/io/pgm/load.hh> -#include <mln/core/alias/neighb2d.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" - - -int main() -{ - using namespace mln; - - // 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); - } -} diff --git a/milena/tests/labeling/blobs.cc b/milena/tests/labeling/blobs.cc index c3f00bb..9e436b2 100644 --- a/milena/tests/labeling/blobs.cc +++ b/milena/tests/labeling/blobs.cc @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008, 2009 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,8 +26,10 @@ #include <mln/core/image/image2d.hh> #include <mln/io/pbm/load.hh> +#include <mln/io/pgm/load.hh> #include <mln/core/alias/neighb2d.hh> #include <mln/labeling/blobs.hh> +#include <mln/value/int_u8.hh> #include "tests/data.hh" @@ -35,8 +38,21 @@ int main() { using namespace mln; - image2d<bool> pic = io::pbm::load(MLN_IMG_DIR "/picasso.pbm"); - unsigned n; - labeling::blobs(pic, c4(), n); - mln_assertion(n == 33); + // Binary image + { + image2d<bool> pic = io::pbm::load(MLN_IMG_DIR "/picasso.pbm"); + unsigned n; + labeling::blobs(pic, c4(), n); + mln_assertion(n == 33); + } + + // Gray-level image + { + image2d<value::int_u8> pic; + io::pgm::load(pic, MLN_IMG_DIR "/fly.pgm"); + unsigned n; + labeling::blobs(pic, c4(), n); + + mln_assertion(n == 24); + } } diff --git a/milena/tests/labeling/blobs_and_compute.cc b/milena/tests/labeling/blobs_and_compute.cc index 47abd66..66e15c1 100644 --- a/milena/tests/labeling/blobs_and_compute.cc +++ b/milena/tests/labeling/blobs_and_compute.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2009, 2010, 2011 EPITA Research and Development +// Copyright (C) 2009, 2010, 2011, 2013 EPITA Research and Development // Laboratory (LRDE) // // This file is part of Olena. @@ -26,6 +26,7 @@ #include <mln/core/image/image2d.hh> #include <mln/io/pbm/load.hh> +#include <mln/io/pgm/load.hh> #include <mln/core/alias/neighb2d.hh> #include <mln/accu/center.hh> #include <mln/labeling/blobs_and_compute.hh> @@ -40,22 +41,46 @@ int main() { using namespace mln; - image2d<bool> pic = io::pbm::load(MLN_IMG_DIR "/picasso.pbm"); - value::label_8 n; + { + image2d<bool> pic = io::pbm::load(MLN_IMG_DIR "/picasso.pbm"); + value::label_8 n; - typedef image2d<value::label_8> L; - typedef util::array<point2d> arr_t; - typedef accu::center<point2d,point2d> accu_t; - typedef util::array<accu_t> accu_arr_t; - typedef util::couple<L,util::couple<arr_t, accu_arr_t> > res_t; - res_t result = labeling::blobs_and_compute(pic, c4(), n, - accu_t()); + typedef image2d<value::label_8> L; + typedef util::array<point2d> arr_t; + typedef accu::center<point2d,point2d> accu_t; + typedef util::array<accu_t> accu_arr_t; + typedef util::couple<L,util::couple<arr_t, accu_arr_t> > res_t; + res_t result = labeling::blobs_and_compute(pic, c4(), n, + accu_t()); - mln_assertion(result.second().first().size() == 34); - mln_assertion(result.second().second().size() == 34); - mln_assertion(result.second().first()[1] == point2d(10,30)); - mln_assertion(result.second().second()[33] == point2d(311,67)); - mln_assertion(n == 33); + mln_assertion(result.second().first().size() == 34); + mln_assertion(result.second().second().size() == 34); + mln_assertion(result.second().first()[1] == point2d(10,30)); + mln_assertion(result.second().second()[33] == point2d(311,67)); + mln_assertion(n == 33); + } + + { + image2d<value::label_8> pic; + io::pgm::load(pic, MLN_IMG_DIR "/fly.pgm"); + value::label_8 n; + + + typedef image2d<value::label_8> L; + typedef util::array<point2d> arr_t; + typedef accu::center<point2d,point2d> accu_t; + typedef util::array<accu_t> accu_arr_t; + typedef util::couple<L,util::couple<arr_t, accu_arr_t> > res_t; + res_t result = labeling::blobs_and_compute(pic, c4(), n, + accu_t()); + + mln_assertion(result.second().first().size() == 25); + mln_assertion(result.second().second().size() == 25); + mln_assertion(result.second().first()[1] == point2d(0,0)); + mln_assertion(result.second().second()[24] == point2d(4,4)); + mln_assertion(n == 24); + } + } -- 1.7.2.5
participants (1)
-
Guillaume Lazzara