Commit 7ad265ba authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Add labeling routines.

	* tests/sort_points.cc: Rename as...
	* tests/level_sort_points.cc: ...this.
	Augment.
	* tests/labeling.cc: Rename as...
	* tests/labeling_foreground.cc: ...this.
	Update.
	* tests/labeling_regional_maxima.cc: New.
	* mln/convert/to_vec_p.hh: New.
	* mln/pw/image.hh (change_value): Use fixme.
	* mln/core/vec_p.hh (reserve, hook_): New.
	* mln/core/vec_p_piter.hh (vec_p_bkd_piter_): Code.
	* mln/level/sort_points.hh (sort_points): Rename as...
	(sort_points_increasing): ...this.
	(sort_points_decreasing): New.
	* mln/level/fill.hh: Add & to the C function arg; that fixes
	the behavior of icpc when calling fill with the literal 0.
	* mln/level/labeling.hh: Remove; obsolete because of
	labeling::level.
	* mln/linear/sobel.hh: Add FIXME.
	* mln/canvas/labeling.hh: New.
	* mln/labeling/flat_zones.hh: New.
	* mln/labeling/+foreground.hh: Remove.
	* mln/labeling/level.hh: New.
	* mln/labeling/foreground.hh: New.
	* mln/labeling/regional_minima.hh: New.
	* mln/labeling/base.hh: New.
	* mln/labeling/regional_maxima.hh: New.
	* mln/labeling/background.hh: New.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1068 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent bbc64dbf
2007-09-05 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add labeling routines.
* tests/sort_points.cc: Rename as...
* tests/level_sort_points.cc: ...this.
Augment.
* tests/labeling.cc: Rename as...
* tests/labeling_foreground.cc: ...this.
Update.
* tests/labeling_regional_maxima.cc: New.
* mln/convert/to_vec_p.hh: New.
* mln/pw/image.hh (change_value): Use fixme.
* mln/core/vec_p.hh (reserve, hook_): New.
* mln/core/vec_p_piter.hh (vec_p_bkd_piter_): Code.
* mln/level/sort_points.hh (sort_points): Rename as...
(sort_points_increasing): ...this.
(sort_points_decreasing): New.
* mln/level/fill.hh: Add & to the C function arg; that fixes
the behavior of icpc when calling fill with the literal 0.
* mln/level/labeling.hh: Remove; obsolete because of
labeling::level.
* mln/linear/sobel.hh: Add FIXME.
* mln/canvas/labeling.hh: New.
* mln/labeling/flat_zones.hh: New.
* mln/labeling/+foreground.hh: Remove.
* mln/labeling/level.hh: New.
* mln/labeling/foreground.hh: New.
* mln/labeling/regional_minima.hh: New.
* mln/labeling/base.hh: New.
* mln/labeling/regional_maxima.hh: New.
* mln/labeling/background.hh: New.
2007-09-03 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add room in sandbox.
......
// 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_CANVAS_LABELING_HH
# define MLN_CANVAS_LABELING_HH
/*! \file mln/canvas/labeling.hh
*
* \brief Connected component labeling of the object part in a binary
* image.
*/
# include <mln/level/fill.hh>
# include <mln/level/sort_points.hh>
namespace mln
{
namespace canvas
{
template <typename F>
struct labeling
{
F& f;
typedef typename F::I I;
typedef typename F::N N;
typedef typename F::O O;
typedef typename F::S S;
typedef mln_point(I) point;
// aux:
mln_ch_value(O, bool) deja_vu;
mln_ch_value(O, point) parent;
labeling(F& f)
: f(f),
deja_vu(f.output.domain()),
parent(f.output.domain())
{
run();
}
void run()
{
// init
{
f.nlabels = 0;
mln::level::fill(deja_vu, false);
f.init();
}
// first pass
{
mln_fwd_piter(S) p(f.s);
mln_niter(N) n(f.nbh, p);
for_all(p) if (f.handles(p))
{
make_set(p);
for_all(n)
if (f.input.has(n) && deja_vu(n))
if (f.equiv(n, p))
do_union(n, p);
else
f.do_no_union(n, p);
deja_vu(p) = true;
}
}
// second pass
{
mln_bkd_piter(S) p(f.s);
mln_niter(N) n(f.nbh, p);
for_all(p) if (f.handles(p))
{
if (is_root(p))
{
if (f.labels(p))
{
if (f.nlabels == mln_max(mln_value(O)))
{
f.status = false;
return;
}
f.output(p) = ++f.nlabels;
}
}
else
f.output(p) = f.output(parent(p));
}
f.status = true;
}
} // end of run()
void make_set(const point& p)
{
parent(p) = p;
f.init_attr(p);
}
bool is_root(const point& p) const
{
return parent(p) == p;
}
point find_root(const point& x)
{
if (parent(x) == x)
return x;
else
return parent(x) = find_root(parent(x));
}
void do_union(const point& n, const point& p)
{
point r = find_root(n);
if (r != p)
{
parent(r) = p;
f.merge_attr(r, p);
}
}
};
} // end of namespace mln::canvas
} // end of namespace mln
#endif // ! MLN_CANVAS_LABELING_HH
// 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_CONVERT_TO_VEC_P_HH
# define MLN_CONVERT_TO_VEC_P_HH
/*! \file mln/convert/to_vec_p.hh
*
* \brief Conversions to mln::vec_p.
*/
# include <mln/core/vec_p.hh>
namespace mln
{
namespace convert
{
/// Convert a point set \p pset into a vec_p (point set vector).
template <typename S>
vec_p<mln_point(S)> to_vec_p(const Point_Set<S>& pset);
# ifndef MLN_INCLUDE_ONLY
template <typename S>
vec_p<mln_point(S)> to_vec_p(const Point_Set<S>& pset_)
{
const S& pset = exact(pset_);
vec_p<mln_point(S)> v;
v.reserve(pset.npoints());
mln_fwd_piter(S) p(pset);
for_all(p)
v.append(p);
return v;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::convert
} // end of namespace mln
#endif // ! MLN_CONVERT_TO_VEC_P_HH
......@@ -79,6 +79,9 @@ namespace mln
/// Constructor from a vector \p vect.
vec_p(const std::vector<P>& vect);
/// Reserve \p n cells.
void reserve(std::size_t n);
/// Test is \p p belongs to this point set.
bool has(const P& p) const;
......@@ -100,6 +103,9 @@ namespace mln
/// Return the \p i-th point.
const P& operator[](unsigned i) const;
/// Hook to data.
std::vector<P>& hook_();
protected:
std::vector<P> vect_;
......@@ -127,6 +133,20 @@ namespace mln
bb_needs_update_ = true;
}
template <typename P>
void
vec_p<P>::reserve(std::size_t n)
{
vect_.reserve(n);
}
template <typename P>
std::vector<P>&
vec_p<P>::hook_()
{
return vect_;
}
template <typename P>
void
vec_p<P>::update_bb_() const
......
......@@ -92,15 +92,63 @@ namespace mln
// FIXME:
/*! \brief Backward iterator on points of a vec_p<P>.
*
*/
template <typename P>
struct vec_p_bkd_piter_ : internal::fixme
{};
struct vec_p_bkd_piter_ : public Point_Iterator< vec_p_bkd_piter_<P> >
{
enum { dim = P::dim };
/// Point_Site associated type.
typedef P psite;
/// Point associated type.
typedef P point;
/// Dpoint associated type.
typedef mln_dpoint(P) dpoint;
/// Coordinate associated type.
typedef mln_coord(P) coord;
/// Coordinate associated type.
template <typename S>
vec_p_bkd_piter_(const Point_Set<S>& s);
/// Give a hook to the point address.
const P* pointer_() const;
/// Read-only access to the \p i-th coordinate.
coord operator[](unsigned i) const;
/// Test if the iterator is valid.
bool is_valid() const;
/// Invalidate the iterator.
void invalidate();
/// Start an iteration.
void start();
/// Go to the next point.
void next_();
/// Convert the iterator into a point.
operator P() const;
protected:
const std::vector<P>& vect_;
int i_;
P p_;
};
# ifndef MLN_INCLUDE_ONLY
// vec_p_fwd_piter_<P>
template <typename P>
template <typename S>
vec_p_fwd_piter_<P>::vec_p_fwd_piter_(const Point_Set<S>& s)
......@@ -153,7 +201,8 @@ namespace mln
vec_p_fwd_piter_<P>::next_()
{
++i_;
p_ = vect_[i_];
if (is_valid())
p_ = vect_[i_];
}
template <typename P>
......@@ -163,6 +212,72 @@ namespace mln
return p_;
}
// vec_p_bkd_piter_<P>
template <typename P>
template <typename S>
vec_p_bkd_piter_<P>::vec_p_bkd_piter_(const Point_Set<S>& s)
: vect_(exact(s).vect())
{
invalidate();
}
template <typename P>
const P*
vec_p_bkd_piter_<P>::pointer_() const
{
return & p_;
}
template <typename P>
mln_coord(P)
vec_p_bkd_piter_<P>::operator[](unsigned i) const
{
mln_precondition(i < dim);
mln_precondition(is_valid());
return p_[i];
}
template <typename P>
bool
vec_p_bkd_piter_<P>::is_valid() const
{
return i_ >= 0;
}
template <typename P>
void
vec_p_bkd_piter_<P>::invalidate()
{
i_ = -1;
}
template <typename P>
void
vec_p_bkd_piter_<P>::start()
{
i_ = vect_.size() - 1;
if (is_valid())
p_ = vect_[i_];
}
template <typename P>
void
vec_p_bkd_piter_<P>::next_()
{
--i_;
if (is_valid())
p_ = vect_[i_];
}
template <typename P>
vec_p_bkd_piter_<P>::operator P() const
{
mln_precondition(is_valid());
return p_;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
......
// 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_BACKGROUND_HH
# define MLN_LABELING_BACKGROUND_HH
/*! \file mln/labeling/background.hh
*
* \brief Connected component labeling of the background in a binary
* image.
*/
# include <mln/labeling/level.hh>
namespace mln
{
namespace labeling
{
/*! Connected component labeling of the background in a binary
* image.
*
* \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.
*/
template <typename I, typename N, typename O>
bool background(const Image<I>& input, const Neighborhood<N>& nbh,
Image<O>& output,
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)
{
return labeling::level(input, false, nbh, output, nlabels);
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::labeling
} // end of namespace mln
#endif // ! MLN_LABELING_BACKGROUND_HH
// 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_BASE_HH
# define MLN_LABELING_BASE_HH
/*! \file mln/labeling/base.hh
*
* \brief Base class for labeling functors.
*/
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
# include <mln/canvas/labeling.hh>
namespace mln
{
namespace labeling
{
# ifndef MLN_INCLUDE_ONLY
namespace impl
{
/// Base class for labeling functors.
template <typename I_, typename N_, typename O_>
struct base_
{
typedef I_ I;
typedef N_ N;
typedef O_ O;
typedef mln_point(I_) P;
const I& input;
const N& nbh;
O& output;
mln_value(O_) nlabels;
bool status;
base_(const I_& input, const N_& nbh, O_& output)
: input(input),
nbh(nbh),
output(output)
{
}
// Defaults.
bool handles(const P&) const { return true; }
bool labels(const P&) const { return true; }
void init() {}
void do_no_union(const P&, const P&) {}
void init_attr(const P&) {}
void merge_attr(const P&, const P&) {}
};
} // end of namespace mln::labeling::impl
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::labeling
} // end of namespace mln