* mln/core/concept/function.hh: add Function_l2b and Function_l2l.
* mln/fun/i2v/array.hh: inherits from array_base.
* mln/fun/internal/array_base.hh: base implementation for functions
based on an array.
* mln/fun/l2l/relabel.hh: l2l function used in labeling::relabel.
* mln/labeling/blobs.hh: use literal::zero and compare output(p) to
literal::zero instead of using operator!.
* mln/labeling/relabel.hh: new routine.
* mln/make/relabelfun.hh: new. Create a l2l function from a l2b
function.
* mln/value/label.hh: update. Make it work.
* mln/value/label_16.hh,
* mln/value/label_8.hh: New aliases.
* tests/labeling/Makefile.am,
* tests/labeling/relabel.cc: add a new test for labeling::relabel.
---
milena/ChangeLog | 29 +++
milena/mln/core/concept/function.hh | 200 +++++++++++++-------
milena/mln/fun/i2v/array.hh | 63 ++-----
.../fun/{i2v/array.hh => internal/array_base.hh} | 146 +++++----------
milena/mln/fun/{i2v/array.hh => l2l/relabel.hh} | 161 +++++++---------
milena/mln/labeling/blobs.hh | 47 +++---
milena/mln/labeling/relabel.hh | 130 +++++++++++++
milena/mln/make/relabelfun.hh | 93 +++++++++
milena/mln/value/label.hh | 142 +++++++-------
milena/mln/value/label_16.hh | 54 ++++++
milena/mln/value/label_8.hh | 54 ++++++
milena/tests/labeling/Makefile.am | 4 +-
milena/tests/labeling/relabel.cc | 96 ++++++++++
13 files changed, 808 insertions(+), 411 deletions(-)
copy milena/mln/fun/{i2v/array.hh => internal/array_base.hh} (58%)
copy milena/mln/fun/{i2v/array.hh => l2l/relabel.hh} (53%)
create mode 100644 milena/mln/labeling/relabel.hh
create mode 100644 milena/mln/make/relabelfun.hh
create mode 100644 milena/mln/value/label_16.hh
create mode 100644 milena/mln/value/label_8.hh
create mode 100644 milena/tests/labeling/relabel.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index c8f90ed..07bdbdc 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,32 @@
+2008-11-20 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add labeling::relabel.
+
+ * mln/core/concept/function.hh: add Function_l2b and Function_l2l.
+
+ * mln/fun/i2v/array.hh: inherits from array_base.
+
+ * mln/fun/internal/array_base.hh: base implementation for functions
+ based on an array.
+
+ * mln/fun/l2l/relabel.hh: l2l function used in labeling::relabel.
+
+ * mln/labeling/blobs.hh: use literal::zero and compare output(p) to
+ literal::zero instead of using operator!.
+
+ * mln/labeling/relabel.hh: new routine.
+
+ * mln/make/relabelfun.hh: new. Create a l2l function from a l2b
+ function.
+
+ * mln/value/label.hh: update. Make it work.
+
+ * mln/value/label_16.hh,
+ * mln/value/label_8.hh: New aliases.
+
+ * tests/labeling/Makefile.am,
+ * tests/labeling/relabel.cc: add a new test for labeling::relabel.
+
2008-11-20 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Bench the diff between canvas as class v. as procedure.
diff --git a/milena/mln/core/concept/function.hh b/milena/mln/core/concept/function.hh
index 68cb2d8..37112a4 100644
--- a/milena/mln/core/concept/function.hh
+++ b/milena/mln/core/concept/function.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +29,9 @@
#ifndef MLN_CORE_CONCEPT_FUNCTION_HH
# define MLN_CORE_CONCEPT_FUNCTION_HH
-/*! \file mln/core/concept/function.hh
- *
- * \brief Definition of several concepts of functions.
- */
+/// \file mln/core/concept/function.hh
+///
+/// Definition of several concepts of functions.
# include <mln/core/concept/object.hh>
@@ -48,10 +48,11 @@ namespace mln
template <typename E> struct Function_p2b;
template <typename E> struct Function_p2p;
template <typename E> struct Function_x2x;
+ template <typename E> struct Function_l2b;
+ template <typename E> struct Function_l2l;
template <typename E> struct Function_vv2v;
-
/// Function category flag type.
template <>
struct Function<void>
@@ -60,19 +61,20 @@ namespace mln
};
- /*! \brief Base class for implementation of function-objects.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function : public Object<E>
{
typedef Function<void> category;
- /*
- An operator() has to be provided. Its signature depends
- on the particular function-object one considers.
- */
+ /*
+ ** An operator() has to be provided. Its signature depends
+ ** on the particular function-object one considers.
+ */
+
protected:
Function();
Function(const Function&);
@@ -86,12 +88,11 @@ namespace mln
template <>
struct Function_v2v<void> { typedef Function<void> super; };
- /*!
- * \brief Base class for implementation of function-objects from
- * value to value.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from
+ /// value to value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_v2v : public Function<E>
{
@@ -109,12 +110,11 @@ namespace mln
template <>
struct Function_i2v<void> { typedef Function_v2v<void> super; };
- /*!
- * \brief Base class for implementation of function-objects from
- * index to value.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from
+ /// index to value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_i2v : public Function_v2v<E>
{
@@ -132,12 +132,11 @@ namespace mln
template <>
struct Function_p2v<void> { typedef Function_v2v<void> super; };
- /*!
- * \brief Base class for implementation of function-objects from point to
- * value.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from point to
+ /// value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_p2v : public virtual Function_v2v<E>
{
@@ -155,12 +154,11 @@ namespace mln
template <>
struct Function_v2b<void> { typedef Function_v2v<void> super; };
- /*!
- * \brief Base class for implementation of function-objects from value to
- * bool.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from value to
+ /// bool.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_v2b : public virtual Function_v2v<E>
{
@@ -179,12 +177,11 @@ namespace mln
template <>
struct Function_p2b<void> { typedef Function_p2v<void> super; }; // FIXME
- /*!
- * \brief Base class for implementation of function-objects from point to
- * bool.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from point to
+ /// bool.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_p2b : public Function_p2v<E>,
public Function_v2b<E>
@@ -204,12 +201,11 @@ namespace mln
template <>
struct Function_p2p<void> { typedef Function_p2v<void> super; }; // FIXME
- /*!
- * \brief Base class for implementation of function-objects from point to
- * point.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from point to
+ /// point.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_p2p : public Function_p2v<E>
{
@@ -227,12 +223,11 @@ namespace mln
template <>
struct Function_x2x<void> { typedef Function_v2v<void> super; }; // FIXME
- /*!
- * \brief Base class for implementation of function-objects from vector to
- * vector.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from vector to
+ /// Vector.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_x2x : public Function_v2v<E>
{
@@ -247,12 +242,11 @@ namespace mln
| Vector <-> Vector. |
`--------------------*/
- /*!
- * \brief Base class for implementation of bijective function-objects from
- * vector to vector.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of bijective function-objects from
+ /// vector to vector.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Bijection_x2x : public Function_x2x< E >
{
@@ -265,6 +259,50 @@ namespace mln
};
+ /*-----------------.
+ | Label -> Value. |
+ `-----------------*/
+
+ template <>
+ struct Function_l2b<void> { typedef Function_v2b<void> super; };
+
+ /// Base class for implementation of function-objects from
+ /// label to value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
+ template <typename E>
+ struct Function_l2b : public Function_v2b<E>
+ {
+ typedef Function_l2b<void> category;
+ protected:
+ Function_l2b();
+ Function_l2b(const Function_l2b&);
+ };
+
+
+ /*-----------------.
+ | Label -> Label. |
+ `-----------------*/
+
+ template <>
+ struct Function_l2l<void> { typedef Function_v2v<void> super; };
+
+ /// Base class for implementation of function-objects from
+ /// label to value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
+ template <typename E>
+ struct Function_l2l : public Function_v2v<E>
+ {
+ typedef Function_l2l<void> category;
+ protected:
+ Function_l2l();
+ Function_l2l(const Function_l2l&);
+ };
+
+
/*------------------------.
| Value, Value -> Value. |
`------------------------*/
@@ -272,12 +310,11 @@ namespace mln
template <>
struct Function_vv2v<void> { typedef Function<void> super; };
- /*!
- * \brief Base class for implementation of function-objects from
- * a couple of values to a value.
- *
- * The parameter \a E is the exact type.
- */
+ /// Base class for implementation of function-objects from
+ /// a couple of values to a value.
+ ///
+ /// The parameter \a E is the exact type.
+ ///
template <typename E>
struct Function_vv2v : public Function<E>
{
@@ -408,6 +445,33 @@ namespace mln
template <typename E>
inline
+ Function_l2b<E>::Function_l2b()
+ {
+ }
+
+ template <typename E>
+ inline
+ Function_l2b<E>::Function_l2b(const Function_l2b<E>& rhs)
+ : Function_v2v<E>(rhs),
+ Function_v2b<E>(rhs)
+ {
+ }
+
+ template <typename E>
+ inline
+ Function_l2l<E>::Function_l2l()
+ {
+ }
+
+ template <typename E>
+ inline
+ Function_l2l<E>::Function_l2l(const Function_l2l<E>& rhs)
+ : Function_v2v<E>(rhs)
+ {
+ }
+
+ template <typename E>
+ inline
Function_vv2v<E>::Function_vv2v()
{
}
diff --git a/milena/mln/fun/i2v/array.hh b/milena/mln/fun/i2v/array.hh
index a97bf33..ee9b1bb 100644
--- a/milena/mln/fun/i2v/array.hh
+++ b/milena/mln/fun/i2v/array.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -34,6 +34,7 @@
# include <vector>
# include <algorithm>
+# include <mln/fun/internal/array_base.hh>
# include <mln/core/concept/function.hh>
# include <mln/util/array.hh>
@@ -41,7 +42,6 @@
namespace mln
{
-
/// Forward declaration.
namespace fun
{
@@ -74,7 +74,6 @@ namespace mln
} // end of namespace mln::convert
-
namespace fun
{
@@ -82,11 +81,12 @@ namespace mln
{
template <typename T>
- class array : public Function_i2v< array<T> >
+ class array : public Function_i2v< array<T> >,
+ public internal::array_base<T>
{
- public:
+ typedef internal::array_base<T> super_base_;
- typedef T result;
+ public:
/// Constructors
/// \{
@@ -95,6 +95,8 @@ namespace mln
array();
/// Constructs a function with \p nvalues.
array(unsigned n);
+ /// Constructs a function with \p nvalues and \p val as default value.
+ array(unsigned n, const T& val);
/// Used in from_to(). Constructs that function from an util::array.
/// Always prefer using from_to instead of this constructor.
@@ -105,14 +107,6 @@ namespace mln
/// \}
- void resize(unsigned n);
- unsigned size() const;
-
- const T& operator()(unsigned i) const;
- T& operator()(unsigned i);
-
- private:
- std::vector<T> v_;
};
} // end of namespace mln::fun::i2v
@@ -120,6 +114,7 @@ namespace mln
} // end of namespace mln::fun
+
# ifndef MLN_INCLUDE_ONLY
@@ -165,14 +160,14 @@ namespace mln
template <typename T>
inline
array<T>::array(unsigned n)
+ : super_base_(n)
{
- resize(n);
}
template <typename T>
inline
array<T>::array(const util::array<T>& from)
- : v_(from.std_vector())
+ : super_base_(from)
{
}
@@ -180,45 +175,11 @@ namespace mln
template <typename T>
inline
array<T>::array(const std::vector<T>& from)
- : v_(from)
+ : super_base_(from)
{
}
- template <typename T>
- inline
- void
- array<T>::resize(unsigned n)
- {
- v_.resize(n);
- }
-
- template <typename T>
- inline
- unsigned
- array<T>::size() const
- {
- return v_.size();
- }
-
- template <typename T>
- inline
- const T&
- array<T>::operator()(unsigned i) const
- {
- mln_precondition(i < v_.size());
- return v_[i];
- }
-
- template <typename T>
- inline
- T&
- array<T>::operator()(unsigned i)
- {
- mln_precondition(i < v_.size());
- return v_[i];
- }
-
} // end of namespace mln::fun::i2v
} // end of namespace mln::fun
diff --git a/milena/mln/fun/i2v/array.hh b/milena/mln/fun/internal/array_base.hh
similarity index 58%
copy from milena/mln/fun/i2v/array.hh
copy to milena/mln/fun/internal/array_base.hh
index a97bf33..32abb8a 100644
--- a/milena/mln/fun/i2v/array.hh
+++ b/milena/mln/fun/internal/array_base.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,10 +25,10 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_FUN_I2V_ARRAY_HH
-# define MLN_FUN_I2V_ARRAY_HH
+#ifndef MLN_FUN_INTERNAL_ARRAY_BASE_HH
+# define MLN_FUN_INTERNAL_ARRAY_BASE_HH
-/// \file mln/fun/i2v/array.hh
+/// \file mln/fun/internal/array_base.hh
///
/// Function mapping an Id i to a value v.
@@ -41,137 +41,92 @@
namespace mln
{
-
- /// Forward declaration.
namespace fun
{
- namespace i2v
+ namespace internal
{
template <typename T>
- class array;
-
- } // end of namespace mln::fun::i2v
-
- } // end of namespace mln::fun
-
-
-
- namespace convert
- {
-
- template <typename T>
- inline
- void
- from_to(const util::array<T>& from, fun::i2v::array<T>& to);
-
- template <typename T>
- inline
- void
- from_to(const std::vector<T>& from, fun::i2v::array<T>& to);
-
- } // end of namespace mln::convert
+ class array_base
+ {
+ public:
+ typedef T result;
+ void resize(unsigned n);
+ unsigned size() const;
- namespace fun
- {
+ const T& operator()(unsigned i) const;
+ T& operator()(unsigned i);
- namespace i2v
- {
- template <typename T>
- class array : public Function_i2v< array<T> >
- {
- public:
+ protected:
- typedef T result;
+ std::vector<T> v_;
/// Constructors
/// \{
/// Default.
- array();
- /// Constructs a function with \p nvalues.
- array(unsigned n);
+ array_base();
+ /// Constructs an array with \p nvalues.
+ array_base(unsigned n);
- /// Used in from_to(). Constructs that function from an util::array.
+ /// Constructs an array with \p nvalues and \p val as value.
+ array_base(unsigned n, const T& val);
+
+ /// Used in from_to(). Constructs that object from an util::array.
/// Always prefer using from_to instead of this constructor.
- array(const util::array<T>& from);
- /// Used in from_to(). Constructs that function from an std::vector.
+ array_base(const util::array<T>& from);
+ /// Used in from_to(). Constructs that object from an std::vector.
/// Always prefer using from_to instead of this constructor.
- array(const std::vector<T>& from);
+ array_base(const std::vector<T>& from);
/// \}
- void resize(unsigned n);
- unsigned size() const;
-
- const T& operator()(unsigned i) const;
- T& operator()(unsigned i);
-
- private:
- std::vector<T> v_;
};
- } // end of namespace mln::fun::i2v
+ } // end of namespace mln::fun::internal
} // end of namespace mln::fun
-# ifndef MLN_INCLUDE_ONLY
-
-
- // convert::from_to
-
- namespace convert
- {
-
- template <typename T>
- inline
- void
- from_to(const util::array<T>& from, fun::i2v::array<T>& to)
- {
- to = fun::i2v::array<T>(from);
- }
-
- template <typename T>
- inline
- void
- from_to(const std::vector<T>& from, fun::i2v::array<T>& to)
- {
- to = fun::i2v::array<T>(from);
- }
-
- } // end of namespace mln::convert
+# ifndef MLN_INCLUDE_ONLY
- /// fun::i2v::array
+ /// fun::internal::array_base
namespace fun
{
- namespace i2v
+ namespace internal
{
template <typename T>
inline
- array<T>::array()
+ array_base<T>::array_base()
{
}
template <typename T>
inline
- array<T>::array(unsigned n)
+ array_base<T>::array_base(unsigned n)
+ : v_(n)
{
- resize(n);
}
template <typename T>
inline
- array<T>::array(const util::array<T>& from)
+ array_base<T>::array_base(unsigned n, const T& val)
+ : v_(n, val)
+ {
+ }
+
+ template <typename T>
+ inline
+ array_base<T>::array_base(const util::array<T>& from)
: v_(from.std_vector())
{
@@ -179,7 +134,7 @@ namespace mln
template <typename T>
inline
- array<T>::array(const std::vector<T>& from)
+ array_base<T>::array_base(const std::vector<T>& from)
: v_(from)
{
@@ -188,7 +143,7 @@ namespace mln
template <typename T>
inline
void
- array<T>::resize(unsigned n)
+ array_base<T>::resize(unsigned n)
{
v_.resize(n);
}
@@ -196,7 +151,7 @@ namespace mln
template <typename T>
inline
unsigned
- array<T>::size() const
+ array_base<T>::size() const
{
return v_.size();
}
@@ -204,7 +159,7 @@ namespace mln
template <typename T>
inline
const T&
- array<T>::operator()(unsigned i) const
+ array_base<T>::operator()(unsigned i) const
{
mln_precondition(i < v_.size());
return v_[i];
@@ -213,27 +168,20 @@ namespace mln
template <typename T>
inline
T&
- array<T>::operator()(unsigned i)
+ array_base<T>::operator()(unsigned i)
{
mln_precondition(i < v_.size());
return v_[i];
}
- } // end of namespace mln::fun::i2v
+ } // end of namespace mln::fun::internal
} // end of namespace mln::fun
- template <typename T>
- inline
- fun::i2v::array<T> array(T t)
- {
- fun::i2v::array<T> tmp(t);
- return tmp;
- }
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
-#endif // ! MLN_FUN_I2V_ARRAY_HH
+#endif // ! MLN_FUN_INTERNAL_ARRAY_BASE_HH
diff --git a/milena/mln/fun/i2v/array.hh b/milena/mln/fun/l2l/relabel.hh
similarity index 53%
copy from milena/mln/fun/i2v/array.hh
copy to milena/mln/fun/l2l/relabel.hh
index a97bf33..f4cd50a 100644
--- a/milena/mln/fun/i2v/array.hh
+++ b/milena/mln/fun/l2l/relabel.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,34 +25,36 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_FUN_I2V_ARRAY_HH
-# define MLN_FUN_I2V_ARRAY_HH
+#ifndef MLN_FUN_L2L_ARRAY_HH
+# define MLN_FUN_L2L_ARRAY_HH
-/// \file mln/fun/i2v/array.hh
+/// \file mln/fun/l2l/array.hh
///
-/// Function mapping an Id i to a value v.
+/// Function mapping a label to a new one.
+/// \sa mln::labeling::relabel
# include <vector>
# include <algorithm>
+# include <mln/fun/internal/array_base.hh>
# include <mln/core/concept/function.hh>
# include <mln/util/array.hh>
+# include <mln/metal/converts_to.hh>
namespace mln
{
-
/// Forward declaration.
namespace fun
{
- namespace i2v
+ namespace l2l
{
- template <typename T>
- class array;
+ template <typename L>
+ class relabel;
- } // end of namespace mln::fun::i2v
+ } // end of namespace mln::fun::l2l
} // end of namespace mln::fun
@@ -61,58 +63,51 @@ namespace mln
namespace convert
{
- template <typename T>
+ template <typename L>
inline
void
- from_to(const util::array<T>& from, fun::i2v::array<T>& to);
+ from_to(const util::array<L>& from,
+ fun::l2l::relabel<L>& to);
- template <typename T>
+ template <typename L>
inline
void
- from_to(const std::vector<T>& from, fun::i2v::array<T>& to);
+ from_to(const std::vector<L>& from,
+ fun::l2l::relabel<L>& to);
} // end of namespace mln::convert
-
namespace fun
{
- namespace i2v
+ namespace l2l
{
- template <typename T>
- class array : public Function_i2v< array<T> >
+ template <typename L>
+ class relabel : public Function_l2l< relabel<L> >,
+ public internal::array_base<L>
{
- public:
+ typedef internal::array_base<L> super_base_;
- typedef T result;
-
- /// Constructors
- /// \{
+ public:
/// Default.
- array();
+ relabel();
/// Constructs a function with \p nvalues.
- array(unsigned n);
+ relabel(unsigned n);
+ /// Constructs a function with \p nvalues and \p label as default label.
+ relabel(unsigned n, const L& label);
/// Used in from_to(). Constructs that function from an util::array.
/// Always prefer using from_to instead of this constructor.
- array(const util::array<T>& from);
+ relabel(const util::array<L>& from);
/// Used in from_to(). Constructs that function from an std::vector.
/// Always prefer using from_to instead of this constructor.
- array(const std::vector<T>& from);
+ relabel(const std::vector<L>& from);
/// \}
- void resize(unsigned n);
- unsigned size() const;
-
- const T& operator()(unsigned i) const;
- T& operator()(unsigned i);
-
- private:
- std::vector<T> v_;
};
} // end of namespace mln::fun::i2v
@@ -120,6 +115,7 @@ namespace mln
} // end of namespace mln::fun
+
# ifndef MLN_INCLUDE_ONLY
@@ -128,112 +124,87 @@ namespace mln
namespace convert
{
- template <typename T>
+ template <typename L>
inline
void
- from_to(const util::array<T>& from, fun::i2v::array<T>& to)
+ from_to(const util::array<L>& from, fun::l2l::relabel<L>& to)
{
- to = fun::i2v::array<T>(from);
+ to = fun::l2l::relabel<L>(from);
}
- template <typename T>
+ template <typename L>
inline
void
- from_to(const std::vector<T>& from, fun::i2v::array<T>& to)
+ from_to(const std::vector<L>& from, fun::l2l::relabel<L>& to)
{
- to = fun::i2v::array<T>(from);
+ to = fun::l2l::relabel<L>(from);
}
} // end of namespace mln::convert
- /// fun::i2v::array
+ /// fun::l2l::relabel
namespace fun
{
- namespace i2v
+ namespace l2l
{
- template <typename T>
+ template <typename L>
inline
- array<T>::array()
+ relabel<L>::relabel()
{
+ // FIXME: Too restrictive?
+ mlc_converts_to(L, unsigned)::check();
}
- template <typename T>
+ template <typename L>
inline
- array<T>::array(unsigned n)
+ relabel<L>::relabel(unsigned n)
+ : super_base_(n)
{
- resize(n);
+ // FIXME: Too restrictive?
+ mlc_converts_to(L, unsigned)::check();
}
- template <typename T>
+ template <typename L>
inline
- array<T>::array(const util::array<T>& from)
- : v_(from.std_vector())
+ relabel<L>::relabel(unsigned n, const L& label)
+ : super_base_(n, label)
{
-
+ // FIXME: Too restrictive?
+ mlc_converts_to(L, unsigned)::check();
}
- template <typename T>
+ template <typename L>
inline
- array<T>::array(const std::vector<T>& from)
- : v_(from)
+ relabel<L>::relabel(const util::array<L>& from)
+ : super_base_(from)
{
-
+ // FIXME: Too restrictive?
+ mlc_converts_to(L, unsigned)::check();
}
- template <typename T>
+ template <typename L>
inline
- void
- array<T>::resize(unsigned n)
+ relabel<L>::relabel(const std::vector<L>& from)
+ : super_base_(from)
{
- v_.resize(n);
+ // FIXME: Too restrictive?
+ mlc_converts_to(L, unsigned)::check();
}
- template <typename T>
- inline
- unsigned
- array<T>::size() const
- {
- return v_.size();
- }
- template <typename T>
- inline
- const T&
- array<T>::operator()(unsigned i) const
- {
- mln_precondition(i < v_.size());
- return v_[i];
- }
+# endif // ! MLN_INCLUDE_ONLY
- template <typename T>
- inline
- T&
- array<T>::operator()(unsigned i)
- {
- mln_precondition(i < v_.size());
- return v_[i];
- }
- } // end of namespace mln::fun::i2v
+ } // end of namespace mln::fun::l2l
} // end of namespace mln::fun
- template <typename T>
- inline
- fun::i2v::array<T> array(T t)
- {
- fun::i2v::array<T> tmp(t);
- return tmp;
- }
-
-# endif // ! MLN_INCLUDE_ONLY
-
} // end of namespace mln
-#endif // ! MLN_FUN_I2V_ARRAY_HH
+#endif // ! MLN_FUN_L2L_ARRAY_HH
diff --git a/milena/mln/labeling/blobs.hh b/milena/mln/labeling/blobs.hh
index 9f521a9..f5d6689 100644
--- a/milena/mln/labeling/blobs.hh
+++ b/milena/mln/labeling/blobs.hh
@@ -29,13 +29,12 @@
#ifndef MLN_LABELING_BLOBS_HH
# define MLN_LABELING_BLOBS_HH
-/*! \file mln/labeling/blobs.hh
- *
- * \brief Connected component labeling of the binary objects of a binary
- * image using a queue-based algorithm.
- *
- * \todo Handle abort in a nice way...
- */
+/// \file mln/labeling/blobs.hh
+///
+/// Connected component labeling of the binary objects of a binary
+/// 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>
@@ -50,19 +49,19 @@ namespace mln
namespace labeling
{
- /*! 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.
- * \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).
- */
+ /// 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.
+ /// \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).
+ ///
template <typename I, typename N, typename L>
mln_ch_value(I, L)
blobs(const Image<I>& input, const Neighborhood<N>& nbh,
@@ -88,15 +87,15 @@ namespace mln
p_queue_fast<P> qu;
// Initialization.
- nlabels = 0;
+ nlabels = literal::zero;
mln_ch_value(I, L) output;
initialize(output, input);
- level::fill(output, 0);
+ level::fill(output, literal::zero);
// Loop.
mln_piter(I) p(input.domain());
for_all(p)
- if (input(p) && ! output(p)) // Object point, not labeled yet.
+ if (input(p) && output(p) == literal::zero) // Object point, not labeled
yet.
{
// Label this point component.
if (nlabels == mln_max(L))
@@ -113,7 +112,7 @@ namespace mln
cur = qu.front();
qu.pop();
for_all(n) if (input.has(n))
- if (input(n) && ! output(n))
+ if (input(n) && output(n) == literal::zero)
{
mln_invariant(! qu.compute_has(n));
qu.push(n);
diff --git a/milena/mln/labeling/relabel.hh b/milena/mln/labeling/relabel.hh
new file mode 100644
index 0000000..841cd1c
--- /dev/null
+++ b/milena/mln/labeling/relabel.hh
@@ -0,0 +1,130 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_RELABEL_HH
+# define MLN_LABELING_RELABEL_HH
+
+/// \file mln/labeling/relabel.hh
+///
+/// Remove components and relabel a labeled image.
+
+# include <mln/core/concept/image.hh>
+# include <mln/make/relabelfun.hh>
+# include <mln/level/transform.hh>
+# include <mln/level/transform_inplace.hh>
+# include <mln/value/label.hh>
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ /// Remove components and relabel a labeled image.
+ /// \input[in] label the labeled image.
+ /// \input[in] nlabels the number of labels in \p label.
+ /// \input[out] new_nlabels the number of labels after relabeling.
+ /// \input[in] f function returning the new component id for each pixel
+ /// value.
+ ///
+ /// \return the relabeled image.
+ template <typename I, typename F>
+ mln_concrete(I)
+ relabel(const Image<I>& label,
+ const mln_value(I)& nlabels,
+ mln_value(I)& new_nlabels,
+ const Function_l2b<F>& fl2b);
+
+ /// Remove components and relabel a labeled image inplace.
+ /// \input[in, out] label the labeled image.
+ /// \input[in, out] nlabels the number of labels in \p label.
+ /// \input[in] f function returning the new component id for each
+ /// pixel value.
+ ///
+ template <typename I, typename F>
+ void
+ relabel_inplace(Image<I>& label,
+ mln_value(I)& nlabels,
+ const Function_l2b<F>& fl2b);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename I, typename F>
+ inline
+ mln_concrete(I)
+ relabel(const Image<I>& label,
+ const mln_value(I)& nlabels,
+ mln_value(I)& new_nlabels,
+ const Function_l2b<F>& fl2b)
+ {
+ trace::entering("labeling::relabel");
+
+ // FIXME: we may want to check that it is exactly a label.
+ mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
+ mln_precondition(exact(label).has_data());
+
+ typedef fun::l2l::relabel<mln_value(I)> fl2l_t;
+ fl2l_t fl2l = make::relabelfun(fl2b, nlabels, new_nlabels);
+ mln_concrete(I) output = level::transform(label, fl2l);
+
+ trace::exiting("labeling::relabel");
+ return output;
+ }
+
+
+ template <typename I, typename F>
+ inline
+ void
+ relabel_inplace(Image<I>& label,
+ mln_value(I)& nlabels,
+ const Function_l2b<F>& fl2b)
+ {
+ trace::entering("labeling::relabel");
+
+ // FIXME: we may want to check that it is exactly a label.
+ mlc_is_a(mln_value(I), mln::value::Symbolic)::check();
+ mln_precondition(exact(label).has_data());
+
+ typedef fun::l2l::relabel<mln_value(I)> fl2l_t;
+ fl2l_t fl2l = make::relabelfun(fl2b, nlabels, nlabels);
+ level::transform_inplace(label, fl2l);
+
+ trace::exiting("labeling::relabel");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_RELABEL_HH
diff --git a/milena/mln/make/relabelfun.hh b/milena/mln/make/relabelfun.hh
new file mode 100644
index 0000000..d02dd88
--- /dev/null
+++ b/milena/mln/make/relabelfun.hh
@@ -0,0 +1,93 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_MAKE_RELABELFUN_HH
+# define MLN_MAKE_RELABELFUN_HH
+
+/// \file mln/make/relabelfun.hh
+///
+/// Routines to construct a function in order to relabel a labeled image.
+
+# include <mln/core/concept/function.hh>
+# include <mln/fun/l2l/relabel.hh>
+# include <mln/value/label.hh>
+
+namespace mln
+{
+
+ namespace make
+ {
+
+ /// Create a l2l function from a l2b function.
+ /// This function can be used to relabel a labeled image.
+ ///
+ /// \param[in] f a l2b function.
+ ///
+ /// \return a l2l function.
+ ///
+ /// \sa mln::labeling::relabel
+ template <unsigned n, typename F>
+ mln::fun::l2l::relabel< value::label<n> >
+ relabelfun(const mln::Function_l2b<F>& fl2b,
+ const value::label<n>& nlabels);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n, typename F>
+ inline
+ mln::fun::l2l::relabel< value::label<n> >
+ relabelfun(const mln::Function_l2b<F>& fl2b_,
+ const value::label<n>& nlabels,
+ value::label<n>& new_nlabels)
+ {
+ trace::entering("mln::make::relabelfun");
+
+ const F& fl2b = exact(fl2b_);
+
+ value::label<n> tmp_nlabels = literal::zero;
+ typedef value::label<n> label_t;
+ fun::l2l::relabel<label_t> fl2l(nlabels.next(), literal::zero);
+ for (label_t i = 1; i <= nlabels; ++i)
+ if (fl2b(i))
+ {
+ fl2l(i) = i;
+ ++tmp_nlabels;
+ }
+ new_nlabels = tmp_nlabels;
+ trace::exiting("mln::make::relabelfun");
+ return fl2l;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::make
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MAKE_RELABELFUN_HH
diff --git a/milena/mln/value/label.hh b/milena/mln/value/label.hh
index 7eb1be0..02eec94 100644
--- a/milena/mln/value/label.hh
+++ b/milena/mln/value/label.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +28,9 @@
#ifndef MLN_VALUE_LABEL_HH
# define MLN_VALUE_LABEL_HH
-/*! \file mln/value/label.hh
- *
- * \brief Define a generic class for labels.
- */
+/// \file mln/value/label.hh
+///
+/// Define a generic class for labels.
# include <mln/metal/math/pow.hh>
# include <mln/value/concept/symbolic.hh>
@@ -44,11 +43,14 @@
namespace mln
{
- // Fwd decl.
+ // Forward declaration.
namespace value {
template <unsigned n> struct label;
}
+ namespace literal {
+ struct zero_t;
+ }
namespace trait
@@ -59,6 +61,7 @@ namespace mln
{
private:
typedef mln::value::label<n> self_;
+
public:
enum {
@@ -71,7 +74,7 @@ namespace mln
typedef mln_value_quant_from_(card) quant;
static const self_ min() { return 0; }
- static const self_ max() { return card - 1; }
+ static const self_ max() { return mlc_pow_int(2, n) - 1; }
};
} // end of namespace trait
@@ -82,90 +85,70 @@ namespace mln
{
- /*! \brief Label value class.
- *
- * The parameter \c n is the number of encoding bits.
- */
+ /// Label value class.
+ ///
+ /// The parameter \c n is the number of encoding bits.
+ ///
template <unsigned n>
- struct label : public Symbolic< label<n> >
+ struct label
+ : public Symbolic< label<n> >,
+ public internal::value_like_< unsigned, // Equivalent.
+ typename internal::encoding_unsigned_<n>::ret, // Enc.
+ int, // Interoperation.
+ label<n> > // Exact.
+
{
public:
-
/// Encoding associated type.
typedef typename internal::encoding_unsigned_<n>::ret enc;
- /// Equivalent associated type.
- typedef typename internal::encoding_unsigned_<n>::ret equiv;
-
/// Constructor without argument.
label();
/// Constructor from an (unsigned) integer.
label(unsigned i);
+ /// Constructor from literal::zero.
+ label(const literal::zero_t& v);
+
+ /// Conversion to an unsigned integer.
+ operator unsigned() const;
+
/// Assignment from an (unsigned) integer.
label<n>& operator=(unsigned i);
+ /// Assignment from literal::zero.
+ label<n>& operator=(const literal::zero_t& v);
+
/// Self increment.
label<n>& operator++();
/// Self decrement.
label<n>& operator--();
+ /// Return the next value.
+ label<n> next() const;
+
/// Conversion to unsigned.
const enc& to_enc() const;
- /// Unit value.
- static const label<n> one;
-
protected:
enc v_;
};
- namespace internal
- {
-
- template <unsigned n>
- struct convert_< label<n> >
- {
- static label<n> value_at_index(unsigned i)
- {
- return i;
- }
- static unsigned index_of_value(const label<n>& v)
- {
- return v.to_enc();
- }
- };
-
- } // end of mln::value::internal
-
-
-
// Safety.
template <> struct label<0>;
template <> struct label<1>;
-
- /// Equality comparison.
- template <unsigned n>
- bool operator==(const label<n>& lhs, const label<n>& rhs);
-
- /// Ordering comparison.
- template <unsigned n>
- bool operator<(const label<n>& lhs, const label<n>& rhs);
-
-
-
- /*! \brief Print a label \p l into the output stream \p ostr.
- *
- * \param[in,out] ostr An output stream.
- * \param[in] l A label.
- *
- * \return The modified output stream \p ostr.
- */
+ /// Print a label \p l into the output stream \p ostr.
+ ///
+ /// \param[in,out] ostr An output stream.
+ /// \param[in] l A label.
+ ///
+ /// \return The modified output stream \p ostr.
+ ///
template <unsigned n>
std::ostream& operator<<(std::ostream& ostr, const label<n>&
l);
@@ -182,12 +165,25 @@ namespace mln
inline
label<n>::label(unsigned i)
{
- mln_precondition(i <= mln_max(enc));
v_ = enc(i);
}
template <unsigned n>
inline
+ label<n>::label(const literal::zero_t&)
+ {
+ v_ = 0;
+ }
+
+ template <unsigned n>
+ inline
+ label<n>::operator unsigned() const
+ {
+ return to_enc();
+ }
+
+ template <unsigned n>
+ inline
label<n>&
label<n>::operator=(unsigned i)
{
@@ -199,6 +195,15 @@ namespace mln
template <unsigned n>
inline
label<n>&
+ label<n>::operator=(const literal::zero_t&)
+ {
+ v_ = 0;
+ return *this;
+ }
+
+ template <unsigned n>
+ inline
+ label<n>&
label<n>::operator++()
{
mln_precondition(v_ < mln_max(enc));
@@ -217,28 +222,19 @@ namespace mln
}
template <unsigned n>
- const label<n> label<n>::one = 1;
-
- template <unsigned n>
inline
- const mln_enc(label<n>)&
- label<n>::to_enc() const
+ label<n>
+ label<n>::next() const
{
- return v_;
+ return label<n>(v_ + 1);
}
template <unsigned n>
inline
- bool operator==(const label<n>& lhs, const label<n>& rhs)
- {
- return lhs.to_enc() == rhs.to_enc();
- }
-
- template <unsigned n>
- inline
- bool operator<(const label<n>& lhs, const label<n>& rhs)
+ const mln_enc(label<n>)&
+ label<n>::to_enc() const
{
- return lhs.to_enc() < rhs.to_enc();
+ return v_;
}
template <unsigned n>
diff --git a/milena/mln/value/label_16.hh b/milena/mln/value/label_16.hh
new file mode 100644
index 0000000..c7d4e13
--- /dev/null
+++ b/milena/mln/value/label_16.hh
@@ -0,0 +1,54 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_VALUE_LABEL_16_HH
+# define MLN_VALUE_LABEL_16_HH
+
+/// \file mln/value/label16.hh
+///
+/// Define the alias value::label16.
+
+# include <mln/value/label.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ /// Alias for 16-bit integers.
+ typedef label<16> label16;
+
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_LABEL_16_HH
diff --git a/milena/mln/value/label_8.hh b/milena/mln/value/label_8.hh
new file mode 100644
index 0000000..2a27179
--- /dev/null
+++ b/milena/mln/value/label_8.hh
@@ -0,0 +1,54 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_VALUE_LABEL_8_HH
+# define MLN_VALUE_LABEL_8_HH
+
+/// \file mln/value/label8.hh
+///
+/// Define the alias value::label8.
+
+# include <mln/value/label.hh>
+
+
+namespace mln
+{
+
+ namespace value
+ {
+
+
+ /// Alias for 8-bit labels.
+ typedef mln::value::label<8> label8;
+
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+
+#endif // ! MLN_VALUE_LABEL_8_HH
diff --git a/milena/tests/labeling/Makefile.am b/milena/tests/labeling/Makefile.am
index 399a1eb..044f83d 100644
--- a/milena/tests/labeling/Makefile.am
+++ b/milena/tests/labeling/Makefile.am
@@ -10,7 +10,8 @@ check_PROGRAMS = \
foreground \
level \
regional_maxima \
- regional_minima
+ regional_minima \
+ relabel
background_SOURCES = background.cc
blobs_SOURCES = blobs.cc
@@ -20,5 +21,6 @@ foreground_SOURCES = foreground.cc
level_SOURCES = level.cc
regional_maxima_SOURCES = regional_maxima.cc
regional_minima_SOURCES = regional_minima.cc
+relabel_SOURCES = relabel.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/labeling/relabel.cc b/milena/tests/labeling/relabel.cc
new file mode 100644
index 0000000..409ded7
--- /dev/null
+++ b/milena/tests/labeling/relabel.cc
@@ -0,0 +1,96 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+// (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/// \file tests/labeling/relabel.cc
+///
+/// Tests on mln::labeling::relabel.
+
+
+#include <mln/core/image/image2d.hh>
+#include <mln/labeling/relabel.hh>
+#include <mln/value/label_16.hh>
+#include <mln/debug/println.hh>
+
+
+struct not_to_removed : public mln::Function_l2b< not_to_removed >
+{
+ bool operator()(const mln::value::label16& l) const
+ {
+ return l < mln::value::label16(3);
+ }
+};
+
+
+bool is_valid(const mln::value::label16& l)
+{
+ return l == 0u|| l == 1u || l == 2u;
+}
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::label16;
+
+ label16 vals[6][5] = {
+ {0, 1, 1, 0, 0},
+ {0, 1, 1, 4, 0},
+ {0, 0, 0, 0, 0},
+ {2, 2, 0, 3, 0},
+ {2, 5, 3, 3, 3},
+ {2, 5, 5, 0, 0}
+ };
+
+ image2d<label16> lbl = make::image(vals);
+ label16 nlabels = 5;
+
+
+ {
+ label16 new_nlabels;
+ image2d<label16> lbl2 = labeling::relabel(lbl,
+ nlabels,
+ new_nlabels,
+ not_to_removed());
+ mln_assertion(new_nlabels == 2u);
+ mln_piter_(image2d<label16>) p(lbl2.domain());
+ for_all(p)
+ mln_assertion(is_valid(lbl2(p)));
+ }
+
+ {
+ label16 new_nlabels;
+ labeling::relabel_inplace(lbl,
+ nlabels,
+ not_to_removed());
+ mln_assertion(nlabels == 2u);
+ mln_piter_(image2d<label16>) p(lbl.domain());
+ for_all(p)
+ mln_assertion(is_valid(lbl(p)));
+ }
+}
--
1.5.6.5