1480: Change value index type is now 'unsigned'; several fixes.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@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
participants (1)
-
Thierry Geraud