https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Change value index type is now 'unsigned'; several fixes.
Use "out foo(in)" instead of "void foo(in, out)".
* mln/labeling/level.hh: Do it.
* mln/labeling/foreground.hh: Do it.
* mln/labeling/background.hh: Do it.
* tests/labeling_algo.cc: Update.
* tests/labeling_level_fast.cc: Update.
* tests/labeling_foreground.cc: Update.
* tests/labeling_estimate.cc: Update.
* tests/clock_test.cc: Update.
* tests/seed2tiling.cc: Update.
Add another labeling algorithm for comparison purpose.
* mln/labeling/blobs.hh: New.
* tests/labeling_blobs.cc: New.
Change value index type from std::size_t to unsigned.
* mln/core/concept/value_set.hh: Do it.
* mln/core/concept/doc/value_set.hh: Update.
* mln/core/image2d.hh: Layout.
* mln/accu/histo.hh: Update.
* mln/value/other.hh: Update.
* mln/value/lut_vec.hh: Update.
* mln/value/float01_.hh: Update.
* mln/value/internal/iterable_set.hh: Update.
* mln/value/label.hh: Update.
* mln/convert/to_image.hh: Update.
Misc.
* tests/util_ordpair.cc: New.
* tests/core_p_set.cc: Layout.
* tests/convert_to_p_vec.cc: Remove; now obsolete
cause replaced by tests/convert_to_p_array.cc.
* tests/value_bool.cc: New.
* mln/core/cast_image.hh (trait): New specialization.
* mln/value/props.hh (value_at_index, index_of_value):
Update.
Explicitly compute with int/unsigned.
* mln/value/float01.hh: Fix missing includes.
* mln/convert/to_p_set.hh: Layout.
* mln/io/pnm/save.hh: Fix missing std::.
* mln/io/pnm/load.hh: Likewise.
* mln/io/pbm/load.hh: Fix.
* mln/util/tree_fast_to_image.hh (q): Rename as...
(l): ...this.
* mln/util/ordpair.hh: New.
mln/accu/histo.hh | 8 +-
mln/convert/to_image.hh | 4 -
mln/convert/to_p_set.hh | 1
mln/core/cast_image.hh | 13 +++
mln/core/concept/doc/value_set.hh | 6 -
mln/core/concept/value_set.hh | 24 +++++-
mln/core/image2d.hh | 3
mln/io/pbm/load.hh | 11 +-
mln/io/pnm/load.hh | 2
mln/io/pnm/save.hh | 4 -
mln/labeling/background.hh | 20 ++---
mln/labeling/blobs.hh | 134 +++++++++++++++++++++++++++++++++++
mln/labeling/foreground.hh | 20 ++---
mln/labeling/level.hh | 64 ++++++++++-------
mln/util/ordpair.hh | 139 +++++++++++++++++++++++++++++++++++++
mln/util/tree_fast_to_image.hh | 16 ++--
mln/value/float01.hh | 3
mln/value/float01_.hh | 4 -
mln/value/internal/iterable_set.hh | 14 ++-
mln/value/label.hh | 4 -
mln/value/lut_vec.hh | 12 +--
mln/value/other.hh | 2
mln/value/props.hh | 11 +-
tests/clock_test.cc | 8 --
tests/core_p_set.cc | 2
tests/labeling_algo.cc | 11 +-
tests/labeling_blobs.cc | 75 +++++++++++++++++++
tests/labeling_estimate.cc | 7 -
tests/labeling_foreground.cc | 30 ++++++-
tests/labeling_level_fast.cc | 3
tests/seed2tiling.cc | 13 +--
tests/util_ordpair.cc | 44 +++++++++++
tests/value_bool.cc | 45 +++++++++++
33 files changed, 621 insertions(+), 136 deletions(-)
Index: tests/labeling_blobs.cc
--- tests/labeling_blobs.cc (revision 0)
+++ tests/labeling_blobs.cc (revision 0)
@@ -0,0 +1,75 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_blob.cc
+ *
+ * \brief Test on mln::labeling::blob.
+ */
+
+#include <mln/core/image2d.hh>
+#include <mln/core/cast_image.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/pw/all.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/labeling/blobs.hh>
+#include <mln/level/transform.hh>
+
+
+struct fold_t : public mln::Function_v2v< fold_t >
+{
+ typedef mln::value::int_u8 result;
+ result operator()(unsigned i) const { return i = 0 ? 0 : i % 255 + 1; }
+};
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm");
+ unsigned n;
+ io::pgm::save(cast_image<int_u8>( labeling::blobs((pw::value(lena) >
pw::cst(127u)) | lena.domain(),
+ c4(), n) ),
+ "out.pgm");
+ mln_assertion(n = 14);
+
+// image2d<int_u8>
+// lena = io::pgm::load("../img/lena.pgm"),
+// out;
+// unsigned n;
+// image2d<unsigned> labels = labeling::blobs((pw::value(lena) >
pw::cst(127u)) | lena.domain(),
+// c8(), n);
+// mln_assertion(n = 528);
+// io::pgm::save( level::transform(labels, fold_t()),
+// "out.pgm" );
+}
Index: tests/labeling_algo.cc
--- tests/labeling_algo.cc (revision 1479)
+++ tests/labeling_algo.cc (working copy)
@@ -52,20 +52,17 @@
image2d<bool> in = io::pbm::load("../img/toto.pbm");
- image2d<int_u8> lab(in.domain());
- image2d<int_u8> inte(in.domain());
- image2d<int_u8> out(in.domain());
unsigned n;
- labeling::foreground(in, c8(), lab, n);
+ image2d<unsigned> lab = labeling::foreground(in, c8(), n);
std::cout << "number of labels = " << n << std::endl;
std::vector<int_u8> vec;
image2d<int> input(in.domain());
level::fill(input, lab);
- lab(make::point2d (0,0)) = 0;
+ lab.at(0,0) = 0;
- inte = geom::seeds2tiling(lab, c4 ());
+ image2d<unsigned> inte = geom::seeds2tiling(lab, c4 ());
border::fill (inte, 0);
image2d<int_u8> inte2(inte.domain());
@@ -76,6 +73,8 @@
mesh_p<point2d> m = make::voronoi(inte, lab, c4());
std::cout << "OK : generate inte.pgm and out.pgm" << std::endl;
+
+ image2d<int_u8> out(in.domain());
draw::mesh (out, m, 255, 128);
io::pgm::save(out, "out.pgm");
Index: tests/util_ordpair.cc
--- tests/util_ordpair.cc (revision 0)
+++ tests/util_ordpair.cc (revision 0)
@@ -0,0 +1,44 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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 util/ordpair.cc
+ *
+ * \brief Tests on mln::util::ordpair.
+ */
+
+#include <mln/core/point2d.hh>
+#include <mln/util/ordpair.hh>
+
+
+
+int main()
+{
+ using namespace mln;
+
+ point2d p1(5,6), p2(5,7);
+ std::cout << util::ordpair(p1, p2) << std::endl;
+}
Index: tests/labeling_level_fast.cc
--- tests/labeling_level_fast.cc (revision 1479)
+++ tests/labeling_level_fast.cc (working copy)
@@ -55,8 +55,7 @@
debug::println(i1);
unsigned n;
- image2d<value::int_u8> out(i1.domain());
- labeling::level(i1, 2, c4(), out, n);
+ image2d<unsigned> out = labeling::level(i1, 2, c4(), n);
std::cout << "n = " << n << std::endl;
debug::println(out);
Index: tests/core_p_set.cc
--- tests/core_p_set.cc (revision 1479)
+++ tests/core_p_set.cc (working copy)
@@ -54,6 +54,4 @@
std::copy(ps.vect().begin(), ps.vect().end(),
std::ostream_iterator<point2d>(std::cout, " "));
std::cout << std::endl;
-
-
}
Index: tests/clock_test.cc
--- tests/clock_test.cc (revision 1479)
+++ tests/clock_test.cc (working copy)
@@ -149,12 +149,10 @@
a3, 1, a4,
a5, a6, a7};
- image2d<value::int_u8> out(ima.domain());
- image2d<value::int_u8> out2(ima.domain());
level::fill(ima, t);
- labeling::level(ima, false, c8(), out, n);
+ image2d<unsigned> out = labeling::level(ima, false, c8(), n);
tmp = testc4(ima, p);
if (tmp != n)
{
@@ -174,11 +172,11 @@
/// 0 before
level::fill(ima, u);
- labeling::level(ima, false, c4(), out, m);
+ out = labeling::level(ima, false, c4(), m);
/// 1 after
level::fill(ima, t);
- labeling::level(ima, false, c4(), out2, n);
+ image2d<unsigned> out2 = labeling::level(ima, false, c4(), n);
int diff = n - m;
if (diff < 0)
Index: tests/labeling_foreground.cc
--- tests/labeling_foreground.cc (revision 1479)
+++ tests/labeling_foreground.cc (working copy)
@@ -34,10 +34,19 @@
#include <mln/core/neighb2d.hh>
#include <mln/value/int_u8.hh>
#include <mln/pw/all.hh>
+#include <mln/core/cast_image.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
#include <mln/labeling/foreground.hh>
+#include <mln/level/transform.hh>
+
+
+struct fold_t : public mln::Function_v2v< fold_t >
+{
+ typedef mln::value::int_u8 result;
+ result operator()(unsigned i) const { return i = 0 ? 0 : i % 255 + 1; }
+};
int main()
@@ -45,13 +54,20 @@
using namespace mln;
using value::int_u8;
- image2d<int_u8>
- lena = io::pgm::load("../img/tiny.pgm"),
- out(lena.domain());
-
+ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm");
unsigned n;
- labeling::foreground((pw::value(lena) > pw::cst(127u)) | lena.domain(),
- c4(), out, n);
- io::pgm::save(out, "out.pgm");
+ io::pgm::save(cast_image<int_u8>( labeling::foreground((pw::value(lena) >
pw::cst(127u)) | lena.domain(),
+ c4(), n) ),
+ "out.pgm");
mln_assertion(n = 14);
+
+// image2d<int_u8>
+// lena = io::pgm::load("../img/lena.pgm"),
+// out;
+// unsigned n;
+// image2d<unsigned> labels = labeling::foreground((pw::value(lena) >
pw::cst(127u)) | lena.domain(),
+// c8(), n);
+// mln_assertion(n = 528);
+// io::pgm::save( level::transform(labels, fold_t()),
+// "out.pgm" );
}
Index: tests/labeling_estimate.cc
--- tests/labeling_estimate.cc (revision 1479)
+++ tests/labeling_estimate.cc (working copy)
@@ -46,13 +46,12 @@
using namespace mln;
using value::int_u8;
- image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm"),
- out(lena.domain());
+ image2d<int_u8> lena = io::pgm::load("../img/tiny.pgm");
// FIXME: Below, 127u (instead of 127) is mandatory to avoid a warning...
unsigned n;
- labeling::foreground((pw::value(lena) > pw::cst(127u)) | lena.domain(),
- c4(), out, n);
+ image2d<unsigned> out = labeling::foreground((pw::value(lena) > pw::cst(127u))
| lena.domain(),
+ c4(), n);
mln_assertion(n = 14);
unsigned sum = 0;
Index: tests/seed2tiling.cc
--- tests/seed2tiling.cc (revision 1479)
+++ tests/seed2tiling.cc (working copy)
@@ -69,21 +69,17 @@
image2d<bool> input = io::pbm::load(argv[1]);
{
-
- image2d<unsigned> lab(input.domain());
- image2d<unsigned> inte(input.domain());
- image2d<int_u8> inte2(input.domain());
- image2d<int_u8> out(input.domain());
-
const w_window2d_int& w_win = make::mk_chamfer_3x3_int<2,3> ();
unsigned n;
- labeling::foreground(input, c4(), lab, n);
+ image2d<unsigned> lab = labeling::foreground(input, c4(), n);
std::cout << "number of labels = " << n << std::endl;
- inte = geom::seeds2tiling(lab, c4 ());
+ image2d<unsigned> inte = geom::seeds2tiling(lab, c4 ());
border::fill (inte, 0);
+
+ image2d<int_u8> inte2(input.domain());
level::stretch (inte, inte2);
io::pgm::save(inte2, "ima1.pgm");
@@ -91,6 +87,7 @@
<< std::endl;
inte = geom::seeds2tiling_with_chamfer(lab, w_win, max, c4 ());
border::fill (inte, 0);
+
level::stretch (inte, inte2);
io::pgm::save(inte2, "ima2.pgm");
Index: tests/value_bool.cc
--- tests/value_bool.cc (revision 0)
+++ tests/value_bool.cc (revision 0)
@@ -0,0 +1,45 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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/value_bool.cc
+ *
+ * \brief Tests on mln::value::set.
+ */
+
+#include <mln/value/props.hh>
+#include <mln/value/set.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ mln_assertion(mln::trait::value_<bool>::card::value = 2);
+
+ value::set<bool> B;
+ std::cout << B << std::endl;
+}
Index: mln/core/cast_image.hh
--- mln/core/cast_image.hh (revision 1479)
+++ mln/core/cast_image.hh (working copy)
@@ -62,6 +62,19 @@
+ namespace trait
+ {
+
+ template <typename T, typename I>
+ struct image_< cast_image_<T,I> > : default_image_morpher_< I, T,
cast_image_<T,I> >
+ {
+ typedef trait::image::io::read_only io;
+ };
+
+ } // end of namespace mln::trait
+
+
+
/*! \brief FIXME
*
*/
Index: mln/core/concept/value_set.hh
--- mln/core/concept/value_set.hh (revision 1479)
+++ mln/core/concept/value_set.hh (working copy)
@@ -66,10 +66,10 @@
bool has(const value& v) const;
- value operator[](std::size_t i) const;
- std::size_t index_of(const value& v) const;
+ value operator[](unsigned i) const;
+ unsigned index_of(const value& v) const;
- std::size_t nvalues() const;
+ unsigned nvalues() const;
*/
protected:
@@ -77,6 +77,10 @@
};
+ template <typename E>
+ std::ostream& operator<<(std::ostream& ostr, const
Value_Set<E>& vs);
+
+
# ifndef MLN_INCLUDE_ONLY
template <typename E>
@@ -88,12 +92,22 @@
bool (E::*m1)(const value&) const = & E::has;
m1 = 0;
- value (E::*m2)(std::size_t) const = & E::operator[];
+ value (E::*m2)(unsigned) const = & E::operator[];
m2 = 0;
- std::size_t (E::*m3)() const = & E::nvalues;
+ unsigned (E::*m3)() const = & E::nvalues;
m3 = 0;
}
+ template <typename E>
+ std::ostream& operator<<(std::ostream& ostr, const
Value_Set<E>& vs_)
+ {
+ const E& vs = exact(vs_);
+ ostr << "{ ";
+ for (unsigned i = 0; i < vs.nvalues(); ++i)
+ std::cout << vs[i] << ' ';
+ return ostr << '}';
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/core/concept/doc/value_set.hh
--- mln/core/concept/doc/value_set.hh (revision 1479)
+++ mln/core/concept/doc/value_set.hh (working copy)
@@ -63,15 +63,15 @@
/*! \brief Give the number of values in this set.
*/
- std::size_t nvalues() const;
+ unsigned nvalues() const;
/*! \brief Give the \p i-th value of this set.
*/
- value operator[](std::size_t i) const;
+ value operator[](unsigned i) const;
/*! \brief Give the index of value \p v in this set.
*/
- std::size_t index_of(const value& v) const;
+ unsigned index_of(const value& v) const;
};
} // end of namespace mln::doc
Index: mln/core/image2d.hh
--- mln/core/image2d.hh (revision 1479)
+++ mln/core/image2d.hh (working copy)
@@ -208,11 +208,8 @@
T* buffer();
-
-
/// Resize image border with new_border.
void resize_(unsigned new_border);
-
};
Index: mln/accu/histo.hh
--- mln/accu/histo.hh (revision 1479)
+++ mln/accu/histo.hh (working copy)
@@ -67,8 +67,8 @@
void init();
std::size_t operator()(const argument& t) const;
- std::size_t operator[](std::size_t i) const;
- std::size_t nvalues() const;
+ std::size_t operator[](unsigned i) const;
+ unsigned nvalues() const;
std::size_t sum() const;
const std::vector<std::size_t>& vect() const;
@@ -152,14 +152,14 @@
template <typename S>
std::size_t
- histo<S>::operator[](std::size_t i) const
+ histo<S>::operator[](unsigned i) const
{
mln_precondition(i < s_.nvalues());
return h_[i];
}
template <typename S>
- std::size_t
+ unsigned
histo<S>::nvalues() const
{
return s_.nvalues();
Index: mln/value/other.hh
--- mln/value/other.hh (revision 1479)
+++ mln/value/other.hh (working copy)
@@ -92,7 +92,7 @@
{
const V& val = exact(val_);
value::set<V> s;
- std::size_t i = s.index_of(val);
+ unsigned i = s.index_of(val);
mln_assertion(s.nvalues() >= 2);
return i = 0 ? s[1] : s[0];
}
Index: mln/value/lut_vec.hh
--- mln/value/lut_vec.hh (revision 1479)
+++ mln/value/lut_vec.hh (working copy)
@@ -70,10 +70,10 @@
typedef bkd_viter_< lut_vec<S,T> > bkd_viter;
/// Give the \p i-th value.
- T operator[](std::size_t i) const;
+ T operator[](unsigned i) const;
/// Give the number of values.
- std::size_t nvalues() const;
+ unsigned nvalues() const;
// Apply the look-up-table. FIXME: Doc!
T operator()(const mln_value(S)& val) const;
@@ -82,7 +82,7 @@
bool has(const value& v) const;
/// Give the index of value \p v in this set.
- std::size_t index_of(const value& v) const;
+ unsigned index_of(const value& v) const;
/// Ctor. FIXME!
template <typename F>
@@ -108,7 +108,7 @@
}
template <typename S, typename T>
- std::size_t
+ unsigned
lut_vec<S,T>::index_of(const T& v) const
{
mln_invariant(0); // FIXME
@@ -137,14 +137,14 @@
template <typename S, typename T>
T
- lut_vec<S,T>::operator[](std::size_t i) const
+ lut_vec<S,T>::operator[](unsigned i) const
{
mln_precondition(i < nvalues());
return vec_[i];
}
template <typename S, typename T>
- std::size_t
+ unsigned
lut_vec<S,T>::nvalues() const
{
return vec_.size();
Index: mln/value/float01_.hh
--- mln/value/float01_.hh (revision 1479)
+++ mln/value/float01_.hh (working copy)
@@ -92,14 +92,14 @@
template <unsigned n>
struct convert_< float01_<n> >
{
- static float01_<n> value_at_index(std::size_t i)
+ static float01_<n> value_at_index(unsigned i)
{
float01_<n> tmp;
tmp.set_ind(i);
return tmp;
}
- static std::size_t index_of_value(const float01_<n>& v)
+ static unsigned index_of_value(const float01_<n>& v)
{
return v.to_enc();
}
Index: mln/value/internal/iterable_set.hh
--- mln/value/internal/iterable_set.hh (revision 1479)
+++ mln/value/internal/iterable_set.hh (working copy)
@@ -35,6 +35,8 @@
# include <mln/core/concept/value_set.hh>
# include <mln/value/props.hh>
+# include <mln/trait/value_.hh>
+# include <mln/value/builtin/all.hh>
namespace mln
@@ -71,13 +73,13 @@
bool has(const T& v) const;
/// Give the \p i-th value.
- T operator[](std::size_t i) const;
+ T operator[](unsigned i) const;
/// Give the index of value \p v in this iterable_set.
- std::size_t index_of(const T& v) const;
+ unsigned index_of(const T& v) const;
/// Give the number of values.
- std::size_t nvalues() const;
+ unsigned nvalues() const;
};
@@ -93,21 +95,21 @@
template <typename T, typename E>
T
- iterable_set<T,E>::operator[](std::size_t i) const
+ iterable_set<T,E>::operator[](unsigned i) const
{
mln_precondition(i < nvalues());
return mln::value::internal::convert_<T>::value_at_index(i);
}
template <typename T, typename E>
- std::size_t
+ unsigned
iterable_set<T,E>::index_of(const T& v) const
{
return mln::value::internal::convert_<T>::index_of_value(v);
}
template <typename T, typename E>
- std::size_t
+ unsigned
iterable_set<T,E>::nvalues() const
{
typedef mln_trait_value_card(T) card_;
Index: mln/value/props.hh
--- mln/value/props.hh (revision 1479)
+++ mln/value/props.hh (working copy)
@@ -96,14 +96,17 @@
template <typename T>
struct convert_
{
- static T value_at_index(std::size_t i)
+ // FIXME: Check that we have a type T compatible with 'int'.
+
+ static T value_at_index(unsigned i)
{
- return mln_min(T) + i;
+ return T( int(mln_min(T)) + int(i) );
}
- static std::size_t index_of_value(const T& v)
+ static unsigned index_of_value(const T& v)
{
- return v - mln_min(T);
+ return unsigned( int(v) - int(mln_min(T)) );
}
+
};
template <typename T>
Index: mln/value/float01.hh
--- mln/value/float01.hh (revision 1479)
+++ mln/value/float01.hh (working copy)
@@ -38,6 +38,9 @@
# include <mln/core/concept/value.hh>
# include <mln/value/float01_.hh>
+# include <mln/value/props.hh>
+# include <mln/trait/all.hh> // FIXME!
+# include <mln/trait/value_.hh>
Index: mln/value/label.hh
--- mln/value/label.hh (revision 1479)
+++ mln/value/label.hh (working copy)
@@ -96,11 +96,11 @@
template <unsigned n>
struct convert_< label<n> >
{
- static label<n> value_at_index(std::size_t i)
+ static label<n> value_at_index(unsigned i)
{
return i;
}
- static std::size_t index_of_value(const label<n>& v)
+ static unsigned index_of_value(const label<n>& v)
{
return v.to_enc();
}
Index: mln/convert/to_image.hh
--- mln/convert/to_image.hh (revision 1479)
+++ mln/convert/to_image.hh (working copy)
@@ -184,8 +184,8 @@
v_min = h.vset()[0],
v_max = h.vset()[h.vset().nvalues() - 1];
image1d<std::size_t> ima(make::box1d(v_min, v_max));
- for(std::size_t i = 0; i < h.vset().nvalues(); ++i)
- ima(make::point1d(i)) = h[i];
+ for(unsigned i = 0; i < h.vset().nvalues(); ++i)
+ ima(i) = h[i];
return ima;
}
Index: mln/convert/to_p_set.hh
--- mln/convert/to_p_set.hh (revision 1479)
+++ mln/convert/to_p_set.hh (working copy)
@@ -128,7 +128,6 @@
return pset;
}
-
template <typename S>
p_set<mln_psite(S)> to_p_set(const Point_Set<S>& ps_)
{
Index: mln/io/pnm/save.hh
--- mln/io/pnm/save.hh (revision 1479)
+++ mln/io/pnm/save.hh (working copy)
@@ -92,7 +92,7 @@
// write a scalar value into for uncontiguous datas
template <typename V>
void write_value(std::ofstream& file,
- V& v)
+ const V& v)
{
typedef typename V::enc E;
@@ -129,7 +129,7 @@
max_row = geom::max_row(ima);
point2d p;
p.col() = geom::min_col(ima);
- size_t len = geom::ncols(ima) * sizeof(mln_value(I));
+ std::size_t len = geom::ncols(ima) * sizeof(mln_value(I));
for (p.row() = min_row; p.row() <= max_row; ++p.row())
file.write((char*)(& ima(p)), len);
}
Index: mln/io/pnm/load.hh
--- mln/io/pnm/load.hh (revision 1479)
+++ mln/io/pnm/load.hh (working copy)
@@ -113,7 +113,7 @@
min_row = geom::min_row(ima),
max_row = geom::max_row(ima);
- size_t len = geom::ncols(ima) * sizeof(V);
+ std::size_t len = geom::ncols(ima) * sizeof(V);
for (p.row() = min_row; p.row() <= max_row; ++p.row())
file.read((char*)(&ima(p)), len);
}
Index: mln/io/pbm/load.hh
--- mln/io/pbm/load.hh (revision 1479)
+++ mln/io/pbm/load.hh (working copy)
@@ -85,18 +85,21 @@
min_col = geom::min_col(ima),
max_col = geom::max_col(ima);
- unsigned char c;
- int i = 0;
+ char c;
+ int i;
for (p.row() = min_row; p.row() <= max_row; ++p.row())
+ {
+ i = 0;
for (p.col() = min_col; p.col() <= max_col; ++p.col())
{
- if (i && (i % 8 = 0))
+ if (i % 8 = 0)
file.read((char*)(&c), 1);
ima(p) = c & 128;
- c = c * 2;
+ c *= 2;
++i;
}
}
+ }
} // end of namespace mln::io::internal
Index: mln/util/tree_fast_to_image.hh
--- mln/util/tree_fast_to_image.hh (revision 1479)
+++ mln/util/tree_fast_to_image.hh (working copy)
@@ -37,7 +37,7 @@
*/
# include <mln/util/tree_fast.hh>
-# include <mln/core/set_p.hh>
+# include <mln/core/p_set.hh>
# include <list>
namespace mln
@@ -57,22 +57,22 @@
tree_fast_to_image (tree_fast<T>& tree, Image<I>& output_)
{
I& output = exact(output_);
- std::list<unsigned> q;
+ std::list<unsigned> l;
- q.push_back (tree.root_);
- while (!(q.empty ()))
+ l.push_back (tree.root_);
+ while (! l.empty())
{
- unsigned current = q.front ();
+ unsigned current = l.front();
for (unsigned i = 0; i < tree.child_[current].size (); ++i)
- q.push_back (tree.child_[current][i]);
+ l.push_back(tree.child_[current][i]);
- mln_piter(set_p<point2d>) p(tree.data_[current].points);
+ mln_piter(p_set<point2d>) p(tree.data_[current].points);
for_all(p)
{
output(p) = tree.data_[current].value;
}
- q.pop_front ();
+ l.pop_front();
}
}
Index: mln/util/ordpair.hh
--- mln/util/ordpair.hh (revision 0)
+++ mln/util/ordpair.hh (revision 0)
@@ -0,0 +1,139 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_UTIL_ORDPAIR_HH
+# define MLN_UTIL_ORDPAIR_HH
+
+/*! \file mln/util/ordpair.hh
+ *
+ * \brief Definition of an ordered pair.
+ */
+
+# include <mln/core/concept/object.hh>
+
+
+namespace mln
+{
+
+ namespace util
+ {
+
+ /// Ordered pair structure s.a. this->first <= this->second;
+ /// ordered pairs are partially ordered using lexicographical
+ /// ordering.
+ template <typename T>
+ struct ordpair_ : public mln::Object< ordpair_<T> >
+ {
+ ordpair_(const T& t1, const T& t2);
+ T first;
+ T second;
+ };
+
+
+ template <typename T>
+ bool operator=(const ordpair_<T>& lhs, const ordpair_<T>& rhs);
+
+ template <typename T>
+ bool operator< (const ordpair_<T>& lhs, const ordpair_<T>&
rhs);
+
+ template <typename T>
+ bool operator<=(const ordpair_<T>& lhs, const ordpair_<T>&
rhs);
+
+
+ template <typename T>
+ std::ostream& operator<<(std::ostream& ostr, const
ordpair_<T>& op);
+
+
+ /// Routine to construct a ordpair on the fly.
+ template <typename T>
+ ordpair_<T> ordpair(const T& t1, const T& t2);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ ordpair_<T>::ordpair_(const T& t1, const T& t2)
+ {
+ if (t1 > t2)
+ {
+ first = t2;
+ second = t1;
+ }
+ else
+ {
+ first = t1;
+ second = t2;
+ }
+ mln_postcondition(first <= second);
+ }
+
+ template <typename T>
+ bool operator=(const ordpair_<T>& lhs, const ordpair_<T>& rhs)
+ {
+ return lhs.first = rhs.first && lhs.second = rhs.second;
+ }
+
+ template <typename T>
+ bool operator< (const ordpair_<T>& lhs, const ordpair_<T>&
rhs)
+ {
+ return
+ lhs.first < rhs.first ||
+ (lhs.first = rhs.first && lhs.second < rhs.second);
+ }
+
+ template <typename T>
+ bool operator<=(const ordpair_<T>& lhs, const ordpair_<T>&
rhs)
+ {
+ return
+ lhs.first < rhs.first ||
+ (lhs.first = rhs.first && lhs.second <= rhs.second);
+ }
+
+
+ template <typename T>
+ std::ostream& operator<<(std::ostream& ostr, const
ordpair_<T>& op)
+ {
+ return ostr << '(' << op.first << ',' <<
op.second << ')';
+ }
+
+
+ template <typename T>
+ ordpair_<T>
+ ordpair(const T& t1, const T& t2)
+ {
+ ordpair_<T> tmp(t1, t2);
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::util
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_EXACT_HH
Index: mln/labeling/blobs.hh
--- mln/labeling/blobs.hh (revision 0)
+++ mln/labeling/blobs.hh (revision 0)
@@ -0,0 +1,134 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// 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_BLOBS_HH
+# define MLN_LABELING_BLOBS_HH
+
+/*! \file mln/labeling/blobs.hh
+ *
+ * \brief Connected component labeling of the image objects at a given
+ * blobs.
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/level/fill.hh>
+# include <mln/core/p_queue_fast.hh>
+
+
+
+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 neighborhood.
+ * \param[out] nlabels The number of labels.
+ * \return The label image.
+ *
+ * A fast queue is used so that the algorithm is not recursive and
+ * can handle large binary objects (blobs).
+ */
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ blobs(const Image<I>& input, const Neighborhood<N>& nbh,
unsigned& nlabels);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // ...
+
+ } // end of namespace mln::labeling::impl
+
+
+ // Facade.
+
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ blobs(const Image<I>& input_, const Neighborhood<N>& nbh_,
unsigned& nlabels)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ mln_precondition(input.has_data());
+
+ typedef mln_psite(I) P;
+
+ P cur;
+ mln_niter(N) n(nbh, cur);
+ p_queue_fast<P> qu;
+
+ // Initialization.
+ nlabels = 0;
+ mln_ch_value(I, unsigned) output;
+ initialize(output, input);
+ level::fill(output, 0);
+
+ // Loop.
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (input(p) && ! output(p)) // Object point, not labeled yet.
+ {
+ // Label this point component.
+ ++nlabels;
+ mln_invariant(qu.is_empty());
+ qu.push(p);
+ output(p) = nlabels;
+ do
+ {
+ cur = qu.front();
+ qu.pop();
+ for_all(n) if (input.has(n))
+ if (input(n) && ! output(n))
+ {
+ mln_invariant(! qu.has(n));
+ qu.push(n);
+ output(n) = nlabels;
+ }
+ }
+ while (! qu.is_empty());
+ }
+
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LABELING_BLOBS_HH
Index: mln/labeling/level.hh
--- mln/labeling/level.hh (revision 1479)
+++ mln/labeling/level.hh (working copy)
@@ -37,8 +37,7 @@
# include <mln/core/concept/image.hh>
# include <mln/labeling/base.hh>
# include <mln/level/fill.hh>
-# include <mln/border/resize.hh>
-# include <mln/border/fill.hh>
+# include <mln/border/adjust.hh>
# include <mln/value/other.hh>
@@ -55,14 +54,14 @@
* \param[in] input The input image.
* \param[in] val The level to consider for the labeling.
* \param[in] nbh The neighborhood.
- * \param[out] output The label image.
* \param[out] nlabels The number of labels.
- *
- * \return Succeed or not.
+ * \return The label image.
*/
- template <typename I, typename N, typename O>
- bool level(const Image<I>& input, const mln_value(I)& val, const
Neighborhood<N>& nbh,
- Image<O>& output, unsigned& nlabels);
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ level(const Image<I>& input, const mln_value(I)& val, const
Neighborhood<N>& nbh,
+ unsigned& nlabels);
+
# ifndef MLN_INCLUDE_ONLY
@@ -98,16 +97,23 @@
// Routines.
- template <typename I, typename N, typename O>
- bool level_(trait::image::speed::any, const I& input,
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ level_(trait::image::speed::any, const I& input,
const mln_value(I)& val, const Neighborhood<N>& nbh,
- trait::image::speed::any, O& output, unsigned& nlabels)
+ unsigned& nlabels)
{
+ typedef mln_ch_value(I, unsigned) O;
+ O output;
+ initialize(output, input);
+
typedef impl::level_t<I,N,O> F;
F f(input, val, exact(nbh), output);
canvas::labeling<F> run(f);
+
nlabels = f.nlabels;
- return f.status;
+ // FIXME: Handle f.status
+ return output;
}
// FIXME: Add fast versions.
@@ -134,36 +140,42 @@
};
- template <typename I, typename N, typename O>
- bool level_(trait::image::speed::fastest, const I& input,
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ level_(trait::image::speed::fastest, const I& input,
const mln_value(I)& val, const Neighborhood<N>& nbh,
- trait::image::speed::fastest, O& output, unsigned& nlabels)
+ unsigned& nlabels)
{
+ typedef mln_ch_value(I, unsigned) O;
typedef level_fast_t<I,N,O> F;
- border::resize(input, exact(nbh).delta());
- border::resize(output, exact(nbh).delta());
+ border::adjust(input, exact(nbh).delta());
+ O output;
+ initialize(output, input);
+ mln_assertion(output.border() = input.border());
F f(input, val, exact(nbh), output);
-
canvas::labeling_fast<F> run(f);
+
+ // FIXME: Handle f.status
+
nlabels = f.nlabels;
- return f.status;
+ return output;
}
} // end of namespace mln::labeling::impl
+
// Facade.
- template <typename I, typename N, typename O>
- bool level(const Image<I>& input, const mln_value(I)& val, const
Neighborhood<N>& nbh,
- Image<O>& output, unsigned& nlabels)
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ level(const Image<I>& input, const mln_value(I)& val, const
Neighborhood<N>& nbh,
+ unsigned& nlabels)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
+ mln_precondition(exact(input).has_data());
return impl::level_(mln_trait_image_speed(I)(), exact(input),
- val, nbh,
- mln_trait_image_speed(O)(), exact(output),
- nlabels);
+ val, nbh, nlabels);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/labeling/foreground.hh
--- mln/labeling/foreground.hh (revision 1479)
+++ mln/labeling/foreground.hh (working copy)
@@ -48,26 +48,24 @@
*
* \param[in] input The input image.
* \param[in] nbh The neighborhood to consider.
- * \param[out] output The label image.
* \param[out] nlabels The number of labels.
- *
- * \return The number of labels.
+ * \return The label image.
*/
- template <typename I, typename N, typename O>
- bool foreground(const Image<I>& input, const Neighborhood<N>&
nbh,
- Image<O>& output,
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ foreground(const Image<I>& input, const Neighborhood<N>& nbh,
unsigned& nlabels);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename O>
- bool foreground(const Image<I>& input, const Neighborhood<N>&
nbh,
- Image<O>& output,
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ foreground(const Image<I>& input, const Neighborhood<N>& nbh,
unsigned& nlabels)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- return labeling::level(input, true, nbh, output, nlabels);
+ mln_precondition(exact(input).has_data());
+ return labeling::level(input, true, nbh, nlabels);
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/labeling/background.hh
--- mln/labeling/background.hh (revision 1479)
+++ mln/labeling/background.hh (working copy)
@@ -48,26 +48,24 @@
*
* \param[in] input The input image.
* \param[in] nbh The neighborhood to consider.
- * \param[out] output The label image.
* \param[out] nlabels The number of labels.
- *
- * \return The number of labels.
+ * \return The label image.
*/
- template <typename I, typename N, typename O>
- bool background(const Image<I>& input, const Neighborhood<N>&
nbh,
- Image<O>& output,
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ background(const Image<I>& input, const Neighborhood<N>& nbh,
unsigned& nlabels);
# ifndef MLN_INCLUDE_ONLY
- template <typename I, typename N, typename O>
- bool background(const Image<I>& input, const Neighborhood<N>&
nbh,
- Image<O>& output,
+ template <typename I, typename N>
+ mln_ch_value(I, unsigned)
+ background(const Image<I>& input, const Neighborhood<N>& nbh,
unsigned& nlabels)
{
- mln_precondition(exact(output).domain() = exact(input).domain());
- return labeling::level(input, false, nbh, output, nlabels);
+ mln_precondition(exact(input).has_data());
+ return labeling::level(input, false, nbh, nlabels);
}
# endif // ! MLN_INCLUDE_ONLY