* 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(a)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(a)lrde.epita.fr>
+
* doc/mln/convert.dox: Fix from_to_ module name.
2013-04-17 Guillaume Lazzara <z(a)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