Commit 31c43fbd authored by Thierry Geraud's avatar Thierry Geraud
Browse files

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.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1480 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent c26f9660
2007-11-14 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.
2007-11-13 Matthieu Garrigues <garrigues@lrde.epita.fr>
A better test for io::pbm.
......
......@@ -67,8 +67,8 @@ namespace mln
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 @@ namespace mln
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();
......
......@@ -184,8 +184,8 @@ namespace mln
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;
}
......
......@@ -128,7 +128,6 @@ namespace mln
return pset;
}
template <typename S>
p_set<mln_psite(S)> to_p_set(const Point_Set<S>& ps_)
{
......
......@@ -62,6 +62,19 @@ namespace mln
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
*
*/
......
......@@ -63,15 +63,15 @@ namespace mln
/*! \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
......
......@@ -66,10 +66,10 @@ namespace mln
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 @@ namespace mln
};
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 @@ namespace mln
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
......
......@@ -208,11 +208,8 @@ namespace mln
T* buffer();
/// Resize image border with new_border.
void resize_(unsigned new_border);
};
......
......@@ -84,17 +84,20 @@ namespace mln
max_row = geom::max_row(ima),
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())
for (p.col() = min_col; p.col() <= max_col; ++p.col())
{
if (i && (i % 8 == 0))
file.read((char*)(&c), 1);
ima(p) = c & 128;
c = c * 2;
++i;
i = 0;
for (p.col() = min_col; p.col() <= max_col; ++p.col())
{
if (i % 8 == 0)
file.read((char*)(&c), 1);
ima(p) = c & 128;
c *= 2;
++i;
}
}
}
......
......@@ -113,7 +113,7 @@ namespace mln
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);
}
......
......@@ -92,7 +92,7 @@ namespace mln
// 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 @@ namespace mln
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);
}
......
......@@ -48,26 +48,24 @@ namespace mln
*
* \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,
unsigned& nlabels);
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,
unsigned& nlabels)
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
......
// 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
......@@ -48,26 +48,24 @@ namespace mln
*
* \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,
unsigned& nlabels);
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,
unsigned& nlabels)
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
......
......@@ -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 @@ namespace mln
* \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 @@ namespace mln
// Routines.
template <typename I, typename N, typename O>
bool 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)
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,
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 @@ namespace mln
};
template <typename I, typename N, typename O>
bool 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)
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,
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
......
// 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