https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Have area closing and opening work on line graph images.
* mln/core/concept/point_set.hh (mln::Point_Set<E>::Point_Set):
No longer require the presence of a bounding box.
* mln/core/concept/point_site.hh: Add a FIXME.
* mln/level/sort_points.hh: Wrap long lines.
(sort_points_increasing_(trait::image::quant::low, const I&))
(sort_points_decreasing_(trait::image::quant::low, const I&)):
Fix the initialization of the return value.
* mln/level/sort_psites.hh: New.
Use it...
* mln/morpho/closing_attribute.hh,
* mln/morpho/opening_attribute.hh: ...here.
s/point/psite/
* mln/canvas/morpho/algebraic_union_find.hh,
* mln/labeling/regional_minima.hh,
* mln/convert/to_p_array.hh:
Likewise.
* mln/core/p_array.hh
(mln::p_array<P>::psite, mln::p_array<P>::point): New typedefs.
(mln::p_array<P>::has): Tale a psite as argument, not a point.
s/box_<P>/box_<point>/.
* mln/core/p_array_piter.hh
(mln::p_array_fwd_piter_<P>::psite)
(mln::p_array_fwd_piter_<P>::point):
(mln::p_array_bkd_piter_<P>::psite)
(mln::p_array_bkd_piter_<P>::point):
New typedefs.
(mln::p_array_fwd_piter_<P>::to_psite)
(mln::p_array_fwd_piter_<P>::operator psite):
(mln::p_array_bkd_piter_<P>::to_psite)
(mln::p_array_bkd_piter_<P>::operator psite):
New.
(mln::p_array_fwd_piter_<P>::operator P):
(mln::p_array_bkd_piter_<P>::operator P):
Remove.
(mln::p_array_fwd_piter_<P>::p_)
(mln::p_array_bkd_piter_<P>::p_):
Change the type of this member from P to psite.
(mln::p_array_fwd_piter_<P>::to_point)
(mln::p_array_fwd_piter_<P>::operator[](unsigned)):
(mln::p_array_bkd_piter_<P>::to_point)
(mln::p_array_bkd_piter_<P>::operator[](unsigned)):
Fix return types.
* tests/morpho/lena_line_graph_image_wst2.cc: Simplify the line
graph image using an area closing, instead of simplifying the
initial (image2d) image.
mln/canvas/morpho/algebraic_union_find.hh | 19 +-
mln/convert/to_p_array.hh | 16 -
mln/core/concept/point_set.hh | 9 -
mln/core/concept/point_site.hh | 2
mln/core/p_array.hh | 13 +
mln/core/p_array_piter.hh | 105 ++++++++----
mln/labeling/regional_minima.hh | 4
mln/level/sort_points.hh | 14 -
mln/level/sort_psites.hh | 244 +++++++++++++++++++++++++++++
mln/morpho/closing_attribute.hh | 6
mln/morpho/opening_attribute.hh | 6
tests/morpho/lena_line_graph_image_wst2.cc | 39 ++--
12 files changed, 383 insertions(+), 94 deletions(-)
Index: mln/core/concept/point_set.hh
--- mln/core/concept/point_set.hh (revision 1774)
+++ mln/core/concept/point_set.hh (working copy)
@@ -77,8 +77,10 @@
typedef bkd_piter;
bool has(const psite& p) const;
- const box_<point>& bbox() const;
std::size_t npoints() const;
+
+ // FIXME: No longer required (at least, not this way).
+ const box_<point>& bbox() const;
*/
protected:
@@ -157,8 +159,9 @@
bool (E::*m1)(const psite& p) const = & E::has;
m1 = 0;
- const box_<point>& (E::*m2)() const = & E::bbox;
- m2 = 0;
+ // FIXME: No longer required (at least, not this way).
+// const box_<point>& (E::*m2)() const = & E::bbox;
+// m2 = 0;
std::size_t (E::*m3)() const = & E::npoints;
m3 = 0;
}
Index: mln/core/concept/point_site.hh
--- mln/core/concept/point_site.hh (revision 1774)
+++ mln/core/concept/point_site.hh (working copy)
@@ -338,6 +338,8 @@
return tmp;
}
+ // FIXME: We shall not rely on a point object associted to the point
+ // site! (Such an object does not always exist.)
template <typename P>
inline
std::ostream& operator<<(std::ostream& ostr, const
Point_Site<P>& p_)
Index: mln/level/sort_points.hh
--- mln/level/sort_points.hh (revision 1774)
+++ mln/level/sort_points.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -156,8 +156,7 @@
for_all(p)
vec[loc[vset.index_of(input(p))]++] = p;
- p_array<mln_point(I)> v;
- v.hook_() = vec;
+ p_array<mln_point(I)> v(vec);
return v;
}
@@ -201,8 +200,7 @@
for_all(p)
vec[loc[vset.index_of(input(p))]++] = p;
- p_array<mln_point(I)> v;
- v.hook_() = vec;
+ p_array<mln_point(I)> v(vec);
return v;
}
@@ -218,7 +216,8 @@
sort_points_increasing(const Image<I>& input)
{
mln_precondition(exact(input).has_data());
- return impl::sort_points_increasing_(mln_trait_image_quant(I)(), exact(input));
+ return impl::sort_points_increasing_(mln_trait_image_quant(I)(),
+ exact(input));
}
template <typename I>
@@ -227,7 +226,8 @@
sort_points_decreasing(const Image<I>& input)
{
mln_precondition(exact(input).has_data());
- return impl::sort_points_decreasing_(mln_trait_image_quant(I)(), exact(input));
+ return impl::sort_points_decreasing_(mln_trait_image_quant(I)(),
+ exact(input));
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/level/sort_psites.hh
--- mln/level/sort_psites.hh (revision 0)
+++ mln/level/sort_psites.hh (revision 0)
@@ -0,0 +1,244 @@
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// 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_LEVEL_SORT_PSITES_HH
+# define MLN_LEVEL_SORT_PSITES_HH
+
+/*! \file mln/level/sort_psites.hh
+ *
+ * \brief Sort_Psites the contents of an image into another one.
+ *
+ * \todo Factor code + optimize.
+ */
+
+/* FIXME: Factor with mln/level/sort_points.hh, if needed (maybe wait
+ for the upcoming big changes regarding types associated to images
+ (point -> site, etc.). */
+
+# include <algorithm>
+
+# include <mln/core/concept/image.hh>
+# include <mln/convert/to_p_array.hh>
+# include <mln/histo/compute.hh>
+
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ /*! Sort psites the image \p input through a function \p f to set
+ * the \p output image in increasing way.
+ *
+ * \param[in] input The input image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I>
+ p_array<mln_psite(I)> sort_psites_increasing(const Image<I>& input);
+
+ /*! Sort psites the image \p input through a function \p f to set
+ * the \p output image in decreasing way.
+ *
+ * \param[in] input The input image.
+ *
+ * \pre \p input.has_data
+ */
+ template <typename I>
+ p_array<mln_psite(I)> sort_psites_decreasing(const Image<I>& input);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ // utility
+
+ template <typename I>
+ struct value_psite_less_
+ {
+ const I& ima_;
+
+ inline
+ value_psite_less_(const I& ima)
+ : ima_(ima)
+ {
+ }
+
+ inline
+ bool operator()(const mln_psite(I)& lhs,
+ const mln_psite(I)& rhs) const
+ {
+ return ima_(lhs) < ima_(rhs) || (ima_(lhs) == ima_(rhs)
+ && lhs < rhs);
+ }
+ };
+
+ template <typename I>
+ struct value_psite_greater_
+ {
+ const I& ima_;
+
+ inline
+ value_psite_greater_(const I& ima)
+ : ima_(ima)
+ {
+ }
+
+ inline
+ bool operator()(const mln_psite(I)& lhs,
+ const mln_psite(I)& rhs) const
+ {
+ return ima_(lhs) > ima_(rhs) || (ima_(lhs) == ima_(rhs)
+ && lhs > rhs);
+ }
+ };
+
+
+ // increasing
+
+ template <typename I>
+ inline
+ p_array<mln_psite(I)>
+ sort_psites_increasing_(trait::image::quant::any, // general case
+ const I& input)
+ {
+ p_array<mln_psite(I)> v = convert::to_p_array(input.domain());
+ std::sort(v.hook_().begin(), v.hook_().end(),
+ value_psite_less_<I>(input));
+ return v;
+ }
+
+ template <typename I>
+ inline
+ p_array<mln_psite(I)>
+ sort_psites_increasing_(trait::image::quant::low, // low quantization
+ const I& input)
+ {
+ typedef mln_vset(I) S;
+ const S& vset = input.values();
+ const unsigned n = vset.nvalues();
+
+ // h
+ histo::data<S> h = histo::compute(input);
+
+ // preparing output data
+ std::vector<unsigned> loc(vset.nvalues());
+ loc[0] = 0;
+ for (unsigned i = 1; i != n; ++i)
+ loc[i] = loc[i-1] + h[i-1];
+
+ // computing output data
+ std::vector<mln_psite(I)> vec(input.npoints());
+ mln_fwd_piter(I) p(input.domain());
+ for_all(p)
+ vec[loc[vset.index_of(input(p))]++] = p;
+
+ p_array<mln_psite(I)> v(vec);
+ return v;
+ }
+
+
+ // decreasing
+
+ template <typename I>
+ inline
+ p_array<mln_psite(I)>
+ sort_psites_decreasing_(trait::image::quant::any, // general case
+ const I& input)
+ {
+ p_array<mln_psite(I)> v = convert::to_p_array(input.domain());
+ std::sort(v.hook_().begin(), v.hook_().end(),
+ value_psite_greater_<I>(input));
+ return v;
+ }
+
+ template <typename I>
+ inline
+ p_array<mln_psite(I)>
+ sort_psites_decreasing_(trait::image::quant::low, // low quantization
+ const I& input)
+ {
+ typedef mln_vset(I) S;
+ const S& vset = input.values();
+ const unsigned n = vset.nvalues();
+
+ // h
+ histo::data<S> h = histo::compute(input);
+
+ // preparing output data
+ std::vector<unsigned> loc(vset.nvalues());
+ loc[n-1] = 0;
+ for (int i = n - 2; i >= 0; --i)
+ loc[i] = loc[i+1] + h[i+1];
+
+ // computing output data
+ std::vector<mln_psite(I)> vec(input.npoints());
+ mln_fwd_piter(I) p(input.domain());
+ for_all(p)
+ vec[loc[vset.index_of(input(p))]++] = p;
+
+ p_array<mln_psite(I)> v(vec);
+ return v;
+ }
+
+
+ } // end of namespace mln::level::impl
+
+
+ // Facades.
+
+ template <typename I>
+ inline
+ p_array<mln_psite(I)>
+ sort_psites_increasing(const Image<I>& input)
+ {
+ mln_precondition(exact(input).has_data());
+ return impl::sort_psites_increasing_(mln_trait_image_quant(I)(),
+ exact(input));
+ }
+
+ template <typename I>
+ inline
+ p_array<mln_psite(I)>
+ sort_psites_decreasing(const Image<I>& input)
+ {
+ mln_precondition(exact(input).has_data());
+ return impl::sort_psites_decreasing_(mln_trait_image_quant(I)(),
+ exact(input));
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_SORT_PSITES_HH
Index: mln/morpho/closing_attribute.hh
--- mln/morpho/closing_attribute.hh (revision 1774)
+++ mln/morpho/closing_attribute.hh (working copy)
@@ -35,7 +35,7 @@
# include <mln/morpho/includes.hh>
# include <mln/canvas/morpho/algebraic_union_find.hh>
-# include <mln/level/sort_points.hh>
+# include <mln/level/sort_psites.hh>
# include <mln/util/pix.hh>
@@ -66,7 +66,7 @@
typename I_, typename N_, typename O_>
struct closing_attribute_t
{
- typedef mln_point(I_) P;
+ typedef mln_psite(I_) P;
// requirements from mln::canvas::morpho::algebraic_union_find
@@ -108,7 +108,7 @@
closing_attribute_t(const I_& input, const N_& nbh,
mln_result(A) lambda, O_& output)
: input(input), nbh(nbh), lambda(lambda), output(output),
- s(level::sort_points_increasing(input))
+ s(level::sort_psites_increasing(input))
{
}
Index: mln/morpho/opening_attribute.hh
--- mln/morpho/opening_attribute.hh (revision 1774)
+++ mln/morpho/opening_attribute.hh (working copy)
@@ -35,7 +35,7 @@
# include <mln/morpho/includes.hh>
# include <mln/canvas/morpho/algebraic_union_find.hh>
-# include <mln/level/sort_points.hh>
+# include <mln/level/sort_psites.hh>
# include <mln/util/pix.hh>
@@ -66,7 +66,7 @@
typename I_, typename N_, typename O_>
struct opening_attribute_t
{
- typedef mln_point(I_) P;
+ typedef mln_psite(I_) P;
// requirements from mln::canvas::morpho::algebraic_union_find
@@ -108,7 +108,7 @@
opening_attribute_t(const I_& input, const N_& nbh,
mln_result(A) lambda, O_& output)
: input(input), nbh(nbh), lambda(lambda), output(output),
- s(level::sort_points_decreasing(input))
+ s(level::sort_psites_decreasing(input))
{
}
Index: mln/canvas/morpho/algebraic_union_find.hh
--- mln/canvas/morpho/algebraic_union_find.hh (revision 1774)
+++ mln/canvas/morpho/algebraic_union_find.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -60,11 +60,11 @@
typedef typename F::O O;
typedef typename F::S S;
typedef typename F::A A;
- typedef mln_point(I) point;
+ typedef mln_psite(I) psite;
// aux:
mln_ch_value(O, bool) deja_vu;
- mln_ch_value(O, point) parent;
+ mln_ch_value(O, psite) parent;
mln_ch_value(O, A) data;
algebraic_union_find(F& f)
@@ -83,6 +83,7 @@
initialize(data, f.input);
f.init();
}
+
// first pass
{
mln_fwd_piter(S) p(f.s);
@@ -116,18 +117,18 @@
} // end of run()
- void make_set(const point& p)
+ void make_set(const psite& p)
{
parent(p) = p;
data(p).take_as_init(make::pix(f.input, p)); // FIXME: algebraic so p!
}
- bool is_root(const point& p) const
+ bool is_root(const psite& p) const
{
return parent(p) == p;
}
- point find_root(const point& x)
+ psite find_root(const psite& x)
{
if (parent(x) == x)
return x;
@@ -135,15 +136,15 @@
return parent(x) = find_root(parent(x));
}
- bool equiv(const point2d& r, const point2d& p)
+ bool equiv(const psite& r, const psite& p)
{
// Either a flat zone or the component of r is still growing.
return f.input(r) == f.input(p) || f.is_active(data(r));
}
- void do_union(const point& n, const point& p)
+ void do_union(const psite& n, const psite& p)
{
- point r = find_root(n);
+ psite r = find_root(n);
if (r != p)
{
if (equiv(r, p))
Index: mln/labeling/regional_minima.hh
--- mln/labeling/regional_minima.hh (revision 1774)
+++ mln/labeling/regional_minima.hh (working copy)
@@ -38,7 +38,7 @@
# include <mln/core/concept/neighborhood.hh>
# include <mln/canvas/labeling.hh>
# include <mln/level/fill.hh>
-# include <mln/level/sort_points.hh>
+# include <mln/level/sort_psites.hh>
namespace mln
@@ -107,7 +107,7 @@
regional_minima_functor(const I_& input, const N_& nbh)
: input(input),
nbh(nbh),
- s(level::sort_points_increasing(input)), // FIXME:
+ s(level::sort_psites_increasing(input)), // FIXME:
// sort_psites_increasing
attr(input.domain())
{
Index: mln/convert/to_p_array.hh
--- mln/convert/to_p_array.hh (revision 1774)
+++ mln/convert/to_p_array.hh (working copy)
@@ -45,14 +45,14 @@
/// Convert a point set \p pset into a p_array (point set vector).
template <typename S>
- p_array<mln_point(S)> to_p_array(const Point_Set<S>& pset);
+ p_array<mln_psite(S)> to_p_array(const Point_Set<S>& pset);
/// Convert a window \p win centered at point \p p into a p_array
/// (point set vector).
template <typename W>
- p_array<mln_point(W)> to_p_array(const Window<W>& win,
- const mln_point(W)& p);
+ p_array<mln_psite(W)> to_p_array(const Window<W>& win,
+ const mln_psite(W)& p);
@@ -60,10 +60,10 @@
template <typename S>
inline
- p_array<mln_point(S)> to_p_array(const Point_Set<S>& pset_)
+ p_array<mln_psite(S)> to_p_array(const Point_Set<S>& pset_)
{
const S& pset = exact(pset_);
- p_array<mln_point(S)> v;
+ p_array<mln_psite(S)> v;
v.reserve(pset.npoints());
mln_fwd_piter(S) p(pset);
for_all(p)
@@ -73,10 +73,10 @@
template <typename W>
inline
- p_array<mln_point(W)> to_p_array(const Window<W>& win,
- const mln_point(W)& p)
+ p_array<mln_psite(W)> to_p_array(const Window<W>& win,
+ const mln_psite(W)& p)
{
- p_array<mln_point(W)> v;
+ p_array<mln_psite(W)> v;
v.reserve(exact(win).ndpoints());
mln_qiter(W) q(win, p);
for_all(q)
Index: mln/core/p_array.hh
--- mln/core/p_array.hh (revision 1774)
+++ mln/core/p_array.hh (working copy)
@@ -60,6 +60,11 @@
class p_array : public internal::point_set_base_< P, p_array<P> >
{
public:
+ /// The associated psite type.
+ typedef P psite;
+
+ /// The associated point type.
+ typedef mln_point(P) point;
/// Forward Point_Iterator associated type.
typedef p_array_fwd_piter_<P> fwd_piter;
@@ -77,13 +82,13 @@
void reserve(std::size_t n);
/// Test is \p p belongs to this point set.
- bool has(const P& p) const;
+ bool has(const psite& p) const;
/// Give the number of points.
std::size_t npoints() const;
/// Give the exact bounding box.
- const box_<P>& bbox() const;
+ const box_<point>& bbox() const;
/// Append a point \p p.
p_array<P>& append(const P& p);
@@ -103,7 +108,7 @@
protected:
std::vector<P> vect_;
- mutable accu::bbox<P> bb_;
+ mutable accu::bbox<point> bb_;
mutable bool bb_needs_update_;
void update_bb_() const;
@@ -177,7 +182,7 @@
template <typename P>
inline
- const box_<P>&
+ const box_<mln_point(P)>&
p_array<P>::bbox() const
{
mln_precondition(npoints() != 0);
Index: mln/core/p_array_piter.hh
--- mln/core/p_array_piter.hh (revision 1774)
+++ mln/core/p_array_piter.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -28,10 +28,8 @@
#ifndef MLN_CORE_P_ARRAY_PITER_HH
# define MLN_CORE_P_ARRAY_PITER_HH
-/*! \file mln/core/p_array_piter.hh
- *
- * \brief Definition of point iterators on mln::p_array.
- */
+/// \file mln/core/p_array_piter.hh
+/// \brief Definition of point iterators on mln::p_array.
# include <mln/core/p_array.hh>
@@ -39,28 +37,34 @@
namespace mln
{
- /*! \brief Forward iterator on points of a p_array<P>.
- *
- */
+ /// \brief Forward iterator on points of a p_array<P>.
template <typename P>
- struct p_array_fwd_piter_ : public internal::point_iterator_base_< P,
p_array_fwd_piter_<P> >
+ struct p_array_fwd_piter_
+ : public internal::point_iterator_base_< P, p_array_fwd_piter_<P> >
{
typedef p_array_fwd_piter_<P> self_;
typedef internal::point_iterator_base_< P, self_ > super_;
public:
+ /// The associated psite type.
+ typedef P psite;
+
+ /// The associated point type.
+ typedef mln_point(P) point;
- // Make definitions from super class available.
enum { dim = super_::dim };
/// Coordinate associated type.
template <typename S>
p_array_fwd_piter_(const Point_Set<S>& s);
+ /// Reference of the corresponding psite.
+ const psite& to_psite() const;
+
/// Reference of the corresponding point.
- const P& to_point() const;
+ const point& to_point() const;
/// Read-only access to the \p i-th coordinate.
- mln_coord(P) operator[](unsigned i) const;
+ mln_coord(point) operator[](unsigned i) const;
/// Test if the iterator is valid.
bool is_valid() const;
@@ -74,39 +78,46 @@
/// Go to the next point.
void next_();
- /// Convert the iterator into a point.
- operator P() const;
+ /// Convert the iterator into a psite.
+ operator psite() const;
protected:
const std::vector<P>& vect_;
- unsigned i_; // FIXME: Why it's unsigned in fwd iterator and signed in the bkd
one ?
- P p_;
+ // FIXME: Why it's unsigned in fwd iterator and signed in the bkd one ?
+ unsigned i_;
+ psite p_;
};
- /*! \brief Backward iterator on points of a p_array<P>.
- *
- */
+ /// \brief Backward iterator on points of a p_array<P>.
template <typename P>
- struct p_array_bkd_piter_ : public internal::point_iterator_base_< P,
p_array_bkd_piter_<P> >
+ struct p_array_bkd_piter_
+ : public internal::point_iterator_base_< P, p_array_bkd_piter_<P> >
{
typedef p_array_bkd_piter_<P> self_;
typedef internal::point_iterator_base_< P, self_ > super_;
public:
+ /// The associated psite type.
+ typedef P psite;
+
+ /// The associated point type.
+ typedef mln_point(P) point;
- // Make definitions from super class available.
enum { dim = super_::dim };
/// Coordinate associated type.
template <typename S>
p_array_bkd_piter_(const Point_Set<S>& s);
+ /// Reference of the corresponding psite.
+ const psite& to_psite() const;
+
/// Reference of the corresponding point.
- const P& to_point() const;
+ const point& to_point() const;
/// Read-only access to the \p i-th coordinate.
- mln_coord(P) operator[](unsigned i) const;
+ mln_coord(point) operator[](unsigned i) const;
/// Test if the iterator is valid.
bool is_valid() const;
@@ -120,20 +131,28 @@
/// Go to the next point.
void next_();
- /// Convert the iterator into a point.
- operator P() const;
+ /// Convert the iterator into a psite.
+ operator psite() const;
protected:
const std::vector<P>& vect_;
+ /* FIXME: See the comment on p_array_fwd_piter_<P>::i_ above. We
+ could turn this `int' into an `unsigned'. Then,
+ - setting the value of i_ to -1 (== UINT_MAX) in invalidate(),
+ - and having valid() test whether i_ is strictly smaller than
+ vect_.size()
+ should work in both iterators (fwd and bkd). */
int i_;
- P p_;
+ psite p_;
};
# ifndef MLN_INCLUDE_ONLY
- // p_array_fwd_piter_<P>
+ /*------------------------.
+ | p_array_fwd_piter_<P>. |
+ `------------------------*/
template <typename P>
template <typename S>
@@ -147,19 +166,27 @@
template <typename P>
inline
const P&
- p_array_fwd_piter_<P>::to_point() const
+ p_array_fwd_piter_<P>::to_psite() const
{
return p_;
}
template <typename P>
inline
- mln_coord(P)
+ const mln_point(P)&
+ p_array_fwd_piter_<P>::to_point() const
+ {
+ return p_.to_point();
+ }
+
+ template <typename P>
+ inline
+ mln_coord(mln_point_(P))
p_array_fwd_piter_<P>::operator[](unsigned i) const
{
mln_precondition(i < dim);
mln_precondition(is_valid());
- return p_[i];
+ return p_.to_point()[i];
}
template <typename P>
@@ -207,7 +234,9 @@
}
- // p_array_bkd_piter_<P>
+ /*------------------------.
+ | p_array_bkd_piter_<P>. |
+ `------------------------*/
template <typename P>
template <typename S>
@@ -221,19 +250,27 @@
template <typename P>
inline
const P&
- p_array_bkd_piter_<P>::to_point() const
+ p_array_bkd_piter_<P>::to_psite() const
{
return p_;
}
template <typename P>
inline
- mln_coord(P)
+ const mln_point(P)&
+ p_array_bkd_piter_<P>::to_point() const
+ {
+ return p_.to_point();
+ }
+
+ template <typename P>
+ inline
+ mln_coord(mln_point_(P))
p_array_bkd_piter_<P>::operator[](unsigned i) const
{
mln_precondition(i < dim);
mln_precondition(is_valid());
- return p_[i];
+ return p_.to_point()[i];
}
template <typename P>
Index: tests/morpho/lena_line_graph_image_wst2.cc
--- tests/morpho/lena_line_graph_image_wst2.cc (revision 1774)
+++ tests/morpho/lena_line_graph_image_wst2.cc (working copy)
@@ -34,7 +34,6 @@
\brief More tests on the Watershed Transform (WST) on a
mln::line_graph_image.
-
The scenario is as follows:
\li load a 2-D, gray-level image from a PGM file;
\li simplify the image to reduce the number of local minima;
@@ -99,14 +98,6 @@
image2d<input_val_t> input;
io::pgm::load(input, MLN_IMG_DIR "/small.pgm");
- /* FIXME: In fact, we'd probably want to compute the gradient
- /before/ simplfying the image, but as the area closing doesn't
- work (yet) on graph images, hence we cannot do this yet. */
-
- // Simplify the input image.
- image2d<input_val_t> work(input.domain());
- morpho::closing_area(input, c8(), 500, work);
-
/*-------------.
| Line graph. |
`-------------*/
@@ -118,18 +109,18 @@
// Points.
/* FIXME: The need for such a structure during the conversion
exhibits the lack of a service from util::graph (or a another,
- missing tool) regarding the retrieval of node ids from
+ missing tool) regarding the retrieval of nodes' ids from
points. */
std::map<point2d, util::node_id> points;
util::node_id id = 0;
// Nodes.
std::vector<input_val_t> node_values;
- mln_fwd_piter_(image2d<input_val_t>) p(work.domain());
+ mln_fwd_piter_(image2d<input_val_t>) p(input.domain());
for_all (p)
{
g.add_node (p);
- node_values.push_back (work(p));
+ node_values.push_back (input(p));
/* FIXME: ``Guessing'' the id of the point just being inserted
is bad. utill:graph<N,E>::add_node should return this
id. */
@@ -144,12 +135,12 @@
mln_fwd_qiter_(window2d) q(next_c4_win, p);
for_all (p)
for_all (q)
- if (work.has(q))
+ if (input.has(q))
{
g.add_edge(points[p], points[q]);
// The computed value is a kind of norm of the gradient
// bewteen P and Q.
- edge_values.push_back(math::abs(work(p) - work(q)));
+ edge_values.push_back(math::abs(input(p) - input(q)));
}
// Line graph point set.
@@ -163,21 +154,27 @@
| Simplification. |
`-----------------*/
- // FIXME: Adjust the area closing filter, so that we can apply it on
- // graph images.
+ typedef line_graph_elt_neighborhood<point2d> nbh_t;
+ nbh_t nbh;
+
+ ima_t closed_lg_ima (lg_ima.domain());
+ /* FIXME: We should change the attribute closing performed here;
+ instead of computing the area using the data on the lines
+ (edges), whe should use the data on the pixels (vertices).
+
+ The best way is probably to create another attribute-functor and
+ use the algebraic_union_find canvas. */
+ morpho::closing_area(lg_ima, nbh, 20, closed_lg_ima);
/*------.
| WST. |
`------*/
- typedef line_graph_elt_neighborhood<point2d> nbh_t;
- nbh_t nbh;
-
// Perform a Watershed Transform.
typedef int_u16 wst_full_val_t;
wst_full_val_t nbasins;
typedef line_graph_image<point2d, wst_full_val_t> wst_full_ima_t;
- wst_full_ima_t wshed_full = morpho::meyer_wst(lg_ima, nbh, nbasins);
+ wst_full_ima_t wshed_full = morpho::meyer_wst(closed_lg_ima, nbh, nbasins);
std::cout << "nbasins = " << nbasins << std::endl;
// Reduce the value set to 8-bit.
@@ -243,7 +240,7 @@
{
if (wshed(pw) == 0)
{
- mln_point_(wst_ima_t) pp(pw);
+ mln_psite_(wst_ima_t) pp(pw);
// Equivalent of the line (edge) PP in OUTPUT.
int row1 = pp.first()[0] * 2;
int col1 = pp.first()[1] * 2;