* mln/make/graph.hh: use an adjacency matrix and a neighborhood.
* mln/make/region_adjacency_graph.hh: make a graph from a watershed
image.
* tests/make/Makefile.am,
* tests/make/graph.cc,
* tests/make/region_adjacency_graph.cc: add new tests.
---
milena/ChangeLog | 13 ++
milena/mln/make/graph.hh | 84 ++++++++----
milena/mln/make/region_adjacency_graph.hh | 202 +++++++++++++++++++++++++++
milena/mln/util/graph.hh | 10 ++
milena/tests/make/Makefile.am | 6 +-
milena/tests/make/graph.cc | 58 ++++++++
milena/tests/make/region_adjacency_graph.cc | 59 ++++++++
7 files changed, 403 insertions(+), 29 deletions(-)
create mode 100644 milena/mln/make/region_adjacency_graph.hh
create mode 100644 milena/tests/make/graph.cc
create mode 100644 milena/tests/make/region_adjacency_graph.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 7797b25..2282bcd 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,16 @@
+2009-02-16 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix make::graph and add make::region_adjacency_graph.
+
+ * mln/make/graph.hh: use an adjacency matrix and a neighborhood.
+
+ * mln/make/region_adjacency_graph.hh: make a graph from a watershed
+ image.
+
+ * tests/make/Makefile.am,
+ * tests/make/graph.cc,
+ * tests/make/region_adjacency_graph.cc: add new tests.
+
2009-02-13 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add unit test for n_max.hh.
diff --git a/milena/mln/make/graph.hh b/milena/mln/make/graph.hh
index df76416..c9dddb1 100644
--- a/milena/mln/make/graph.hh
+++ b/milena/mln/make/graph.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 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
@@ -34,6 +35,11 @@
///
/// \sa transform::influence_zone_geodesic.
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/box2d.hh>
+# include <mln/extension/adjust_fill.hh>
# include <mln/util/graph.hh>
namespace mln
@@ -48,8 +54,10 @@ namespace mln
/// \param[in] nlabels number of influence zone in \p iz.
///
/// \return util::graph Graph based on the adjacency of the influence zones.
- template <typename I>
- util::graph graph(const Image<I>& iz, mln_value(I) nlabels);
+ template <typename I, typename N>
+ util::graph
+ graph(const Image<I>& iz_, const Neighborhood<N>& nbh,
+ mln_value(I) nlabels);
@@ -59,53 +67,71 @@ namespace mln
namespace internal
{
- template <typename I>
+ template <typename I, typename N>
void
- graph_tests(const Image<I>& iz, mln_value(I))
+ graph_tests(const Image<I>& iz, const Neighborhood<N>& nbh,
+ mln_value(I))
{
mln_precondition(exact(iz).is_valid());
-
+ mln_precondition(exact(nbh).is_valid());
(void) iz;
+ (void) nbh;
}
} // end of namespace mln::make::internal
-
namespace impl
{
namespace generic
{
- template <typename I>
+ template <typename I, typename N>
util::graph
- graph(const Image<I>& iz_, mln_value(I) nlabels)
+ graph(const Image<I>& iz_, const Neighborhood<N>& nbh_,
+ mln_value(I) nlabels)
{
trace::entering("make::impl::generic::graph");
- internal::graph_tests(iz_, nlabels);
+ internal::graph_tests(iz_, nbh_, nlabels);
const I& iz = exact(iz_);
+ const N& nbh = exact(nbh_);
- util::graph g;
- g.add_vertices(nlabels.next());
+ mln::image2d<bool> adj(mln::box2d(nlabels.next(), nlabels.next()));
+ data::fill(adj, false);
+ typedef mln_value(I) L;
mln_piter(I) p(iz.domain());
+ mln_niter(N) n(nbh, p);
for_all(p)
{
- // Checking 'forward' neighboors and create an edge if necessary.
- for (unsigned dim = 0; dim < mln_site_(I)::dim; ++dim)
+ L l1 = iz(p);
+ for_all(n)
{
- mln_site(I) n = p;
- ++n[dim];
-
- // FIXME: check that calling iz.domain().has() is correct
- // and that we don't prefer iz.has().
- if (iz.domain().has(n) && iz(p) != iz(n))
- g.add_edge(iz(p), iz(n));
+ if (iz.domain().has(n))
+ {
+ L l2 = iz(n);
+ if (iz(n) != iz((p)))
+ {
+ // l2 is adjacent to l1
+ if (l2 < l1)
+ adj(point2d(l1,l2)) = true;
+ else
+ adj(point2d(l2,l1)) = true;
+ }
+ }
}
}
+ // Construct graph.
+ util::graph g;
+ g.add_vertices(nlabels.next());
+ for (unsigned i = 0; i < geom::nrows(adj); ++i)
+ for (unsigned j = 0; j < i; ++j)
+ if (adj(point2d(i,j)))
+ g.add_edge(i, j);
+
trace::exiting("make::impl::generic::graph");
return g;
}
@@ -119,11 +145,12 @@ namespace mln
namespace internal
{
- template <typename I>
+ template <typename I, typename N>
util::graph
- graph_dispatch(const Image<I>& iz, mln_value(I) nlabels)
+ graph_dispatch(const Image<I>& iz, const Neighborhood<N>& nbh,
+ mln_value(I) nlabels)
{
- return make::impl::generic::graph(iz, nlabels);
+ return make::impl::generic::graph(iz, nbh, nlabels);
}
} // end of namespace mln::make::internal
@@ -132,16 +159,17 @@ namespace mln
// Facade
- template <typename I>
+ template <typename I, typename N>
inline
util::graph
- graph(const Image<I>& iz, mln_value(I) nlabels)
+ graph(const Image<I>& iz, const Neighborhood<N>& nbh,
+ mln_value(I) nlabels)
{
trace::entering("make::graph");
- internal::graph_tests(iz, nlabels);
+ internal::graph_tests(iz, nbh, nlabels);
- util::graph g = internal::graph_dispatch(iz, nlabels);
+ util::graph g = internal::graph_dispatch(iz, nbh, nlabels);
trace::exiting("make::graph");
return g;
diff --git a/milena/mln/make/region_adjacency_graph.hh b/milena/mln/make/region_adjacency_graph.hh
new file mode 100644
index 0000000..695174d
--- /dev/null
+++ b/milena/mln/make/region_adjacency_graph.hh
@@ -0,0 +1,202 @@
+// Copyright (C) 2009 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.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MAKE_REGION_ADJACENCY_GRAPH_HH
+# define MLN_MAKE_REGION_ADJACENCY_GRAPH_HH
+
+/// \file mln/make/region_adjacency_graph.hh
+///
+/// Create a region_adjacency_graph from a watershed image.
+///
+/// \sa morpho::meyer_wst.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/image/image2d.hh>
+# include <mln/core/alias/box2d.hh>
+# include <mln/extension/adjust_fill.hh>
+# include <mln/util/graph.hh>
+
+namespace mln
+{
+
+ namespace make
+ {
+
+ /// Create a region adjacency graph from a watershed image.
+ ///
+ /// \param[in] wshd watershed image.
+ /// \param[in] nbasins number of influence zone in \p wshd.
+ ///
+ /// \return util::graph Graph based on the adjacency of the influence zones.
+ template <typename I, typename N>
+ util::graph
+ region_adjacency_graph(const Image<I>& wshd_,
+ const Neighborhood<N>& nbh,
+ mln_value(I) nbasins);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace internal
+ {
+
+ template <typename I, typename N>
+ void
+ region_adjacency_graph_tests(const Image<I>& wshd,
+ const Neighborhood<N>& nbh,
+ mln_value(I))
+ {
+ mln_precondition(exact(wshd).is_valid());
+ mln_precondition(exact(nbh).is_valid());
+ (void) wshd;
+ (void) nbh;
+ }
+
+ } // end of namespace mln::make::internal
+
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I, typename N>
+ util::graph
+ region_adjacency_graph(const Image<I>& wshd_,
+ const Neighborhood<N>& nbh_,
+ mln_value(I) nbasins)
+ {
+ trace::entering("make::impl::generic::region_adjacency_graph");
+
+ internal::region_adjacency_graph_tests(wshd_, nbh_, nbasins);
+ const I& wshd = exact(wshd_);
+ const N& nbh = exact(nbh_);
+
+ mln::image2d<bool> adj(mln::box2d(nbasins.next(), nbasins.next()));
+ data::fill(adj, false);
+ extension::adjust_fill(wshd, nbh, 0u);
+
+ typedef mln_value(I) L;
+ L l1, l2;
+ mln_piter(I) p(wshd.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ {
+ if (wshd(p) != 0u)
+ continue;
+ // p is in the watershed line.
+ l1 = l2 = 0;
+ for_all(n)
+ if (wshd.has(n) && wshd(n) != 0u)
+ {
+ if (l1 == 0u) // First label to be stored.
+ l1 = wshd(n);
+ else
+ if (wshd(n) != l1) // Useless: && l2 == 0)
+ { // Second label to be stored.
+ mln_invariant(l2 == 0u);
+ l2 = wshd(n);
+ break;
+ }
+ }
+ if (l2 == 0u || l1 == 0u)
+ continue;
+ if (l2 < l1)
+ std::swap(l1, l2);
+
+ // adjacency l1 l2
+ adj(point2d(l2,l1)) = true;
+ }
+
+ // Construct graph.
+ util::graph g;
+ g.add_vertices(nbasins.next());
+ for (unsigned i = 1; i < geom::nrows(adj); ++i)
+ for (unsigned j = 1; j < i; ++j)
+ if (adj(point2d(i,j)))
+ g.add_edge(i, j);
+
+
+ trace::exiting("make::impl::generic::region_adjacency_graph");
+ return g;
+ }
+
+ } // end of namespace mln::make::impl::generic
+
+ } // end of namespace mln::make::impl
+
+
+
+ namespace internal
+ {
+
+ template <typename I, typename N>
+ util::graph
+ region_adjacency_graph_dispatch(const Image<I>& wshd,
+ const Neighborhood<N>& nbh,
+ mln_value(I) nbasins)
+ {
+ return make::impl::generic::region_adjacency_graph(wshd, nbh, nbasins);
+ }
+
+ } // end of namespace mln::make::internal
+
+
+
+ // Facade
+
+ template <typename I, typename N>
+ inline
+ util::graph
+ region_adjacency_graph(const Image<I>& wshd,
+ const Neighborhood<N>& nbh,
+ mln_value(I) nbasins)
+ {
+ trace::entering("make::region_adjacency_graph");
+
+ internal::region_adjacency_graph_tests(wshd, nbh, nbasins);
+
+ util::graph g = internal::region_adjacency_graph_dispatch(wshd, nbh, nbasins);
+
+ trace::exiting("make::region_adjacency_graph");
+ return g;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ } // end of namespace mln::make
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MAKE_REGION_ADJACENCY_GRAPH_HH
diff --git a/milena/mln/util/graph.hh b/milena/mln/util/graph.hh
index 897deb4..f95e1e8 100644
--- a/milena/mln/util/graph.hh
+++ b/milena/mln/util/graph.hh
@@ -71,8 +71,11 @@ namespace mln
vertices_t vertices_;
/// The edges.
edges_t edges_;
+
+# ifndef NDEBUG
/// An index of the set of edges, for fast-access purpose.
edges_set_t edges_set_;
+# endif // ! NDEBUG
};
} // end of namespace mln::internal
@@ -383,8 +386,10 @@ namespace mln
unsigned
graph::add_edge(unsigned id_v1, unsigned id_v2)
{
+ //FIXME: to be removed! We should not check that, except in without NDEBUG.
// Does this edge already exist in the graph?
edge_data_t edge(id_v1, id_v2);
+# ifndef NDEBUG
if (data_->edges_set_.find(edge) != data_->edges_set_.end ())
{
// Return the erroneous value.
@@ -392,6 +397,7 @@ namespace mln
}
else
{
+# endif // ! NDEBUG
// Otherwise insert it into the graph.
/* FIXME: This is not thread-proof (these two lines should
form an atomic section). */
@@ -404,7 +410,11 @@ namespace mln
data_->vertices_[edge.second()].push_back(id);
return id;
+
+# ifndef NDEBUG
}
+# endif // ! NDEBUG
+
}
inline
diff --git a/milena/tests/make/Makefile.am b/milena/tests/make/Makefile.am
index 913867c..95eb5ea 100644
--- a/milena/tests/make/Makefile.am
+++ b/milena/tests/make/Makefile.am
@@ -4,18 +4,22 @@ include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
dual_neighb \
+ graph \
h_mat \
image2d \
image3d \
mat \
+ region_adjacency_graph \
w_window \
w_window_directional
-dual_neighb_SOURCES = dual_neighb.cc
+dual_neighb_SOURCES = dual_neighb.c
+graph_SOURCES = graph.cc
h_mat_SOURCES = h_mat.cc
image2d_SOURCES = image2d.cc
image3d_SOURCES = image3d.cc
mat_SOURCES = mat.cc
+region_adjacency_graph_SOURCES = region_adjacency_graph.cc
w_window_SOURCES = w_window.cc
w_window_directional_SOURCES = w_window_directional.cc
diff --git a/milena/tests/make/graph.cc b/milena/tests/make/graph.cc
new file mode 100644
index 0000000..bb88706
--- /dev/null
+++ b/milena/tests/make/graph.cc
@@ -0,0 +1,58 @@
+// Copyright (C) 2009 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.
+
+/// \file tests/make/graph.cc
+///
+/// Tests on mln::make::graph.
+
+#include <mln/make/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/util/graph.hh>
+#include <mln/make/graph.hh>
+#include <mln/value/label_8.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ value::label_8 vals[9] = { 1, 1, 3,
+ 1, 2, 3,
+ 1, 0, 4 };
+
+ image2d<value::label_8> ima = make::image2d(vals);
+
+ util::graph g = make::graph(ima, c4(), 4u);
+
+ mln_assertion(g.e_nmax() == 7u);
+ mln_assertion(g.v_nmax() == 5u);
+ mln_assertion(g.v_nmax_nbh_edges(0) == 3);
+ mln_assertion(g.v_nmax_nbh_edges(1) == 3);
+ mln_assertion(g.v_nmax_nbh_edges(2) == 3);
+ mln_assertion(g.v_nmax_nbh_edges(3) == 3);
+ mln_assertion(g.v_nmax_nbh_edges(4) == 2);
+}
diff --git a/milena/tests/make/region_adjacency_graph.cc b/milena/tests/make/region_adjacency_graph.cc
new file mode 100644
index 0000000..7f8cb12
--- /dev/null
+++ b/milena/tests/make/region_adjacency_graph.cc
@@ -0,0 +1,59 @@
+// Copyright (C) 2009 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.
+
+/// \file tests/make/graph.cc
+///
+/// Tests on mln::make::region_adjacency_graph.
+
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/util/graph.hh>
+
+#include <mln/value/label_8.hh>
+
+#include <mln/make/image2d.hh>
+#include <mln/make/region_adjacency_graph.hh>
+
+int main()
+{
+ using namespace mln;
+
+ value::label_8 vals[16] = { 1, 0, 3, 3,
+ 1, 0, 0, 0,
+ 0, 0, 4, 4,
+ 2, 2, 0, 4 };
+
+ image2d<value::label_8> ima = make::image2d(vals);
+
+ util::graph g = make::region_adjacency_graph(ima, c4(), 4u);
+
+ mln_assertion(g.e_nmax() == 4u);
+ mln_assertion(g.v_nmax() == 5u);
+ mln_assertion(g.v_nmax_nbh_edges(0) == 0);
+ for (unsigned i = 1; i < 4; ++i)
+ mln_assertion(g.v_nmax_nbh_edges(i) == 2);
+}
--
1.5.6.5
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-02-13 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add unit test for n_max.hh.
* mln/labeling/all.hh: Update for n_max.hh
* tests/labeling/Makefile.am: Update for n_max.cc
* tests/labeling/n_max.cc: Unit test for n_max().
---
mln/labeling/all.hh | 1
tests/labeling/Makefile.am | 2 +
tests/labeling/n_max.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
Index: trunk/milena/tests/labeling/n_max.cc
===================================================================
--- trunk/milena/tests/labeling/n_max.cc (revision 0)
+++ trunk/milena/tests/labeling/n_max.cc (revision 3374)
@@ -0,0 +1,70 @@
+// Copyright (C) 2009 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.
+
+/// \file tests/labeling/n_max.cc
+///
+/// Test on mln::labeling::n_max.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+
+#include <mln/labeling/flat_zones.hh>
+#include <mln/labeling/compute.hh>
+#include <mln/labeling/n_max.hh>
+
+#include <mln/fun/v2b/threshold.hh>
+#include <mln/level/transform.hh>
+
+#include <mln/accu/count.hh>
+
+#include <mln/io/pgm/all.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::label_16;
+
+ image2d<int_u8> lena = io::pgm::load<int_u8>(MLN_IMG_DIR "/lena.pgm");
+
+ image2d<bool> threshold = level::transform(lena, fun::v2b::threshold<int_u8>(100));
+ label_16 nlabels;
+ image2d<label_16> labels = labeling::flat_zones(threshold, c4(), nlabels);
+ accu::count<int_u8> a_;
+
+ util::array<unsigned> a = labeling::compute(a_, threshold, labels, nlabels);
+ util::array<label_16> arr_big = labeling::n_max<label_16>(a, 3);
+
+ mln_assertion(arr_big[1] == 4);
+ mln_assertion(arr_big[2] == 6);
+ mln_assertion(arr_big[3] == 323);
+}
Index: trunk/milena/tests/labeling/Makefile.am
===================================================================
--- trunk/milena/tests/labeling/Makefile.am (revision 3373)
+++ trunk/milena/tests/labeling/Makefile.am (revision 3374)
@@ -10,6 +10,7 @@
flat_zones \
foreground \
level \
+ n_max \
regional_maxima \
regional_minima \
relabel
@@ -21,6 +22,7 @@
flat_zones_SOURCES = flat_zones.cc
foreground_SOURCES = foreground.cc
level_SOURCES = level.cc
+n_max_SOURCES = n_max.cc
regional_maxima_SOURCES = regional_maxima.cc
regional_minima_SOURCES = regional_minima.cc
relabel_SOURCES = relabel.cc
Index: trunk/milena/mln/labeling/all.hh
===================================================================
--- trunk/milena/mln/labeling/all.hh (revision 3373)
+++ trunk/milena/mln/labeling/all.hh (revision 3374)
@@ -60,6 +60,7 @@
# include <mln/labeling/flat_zones.hh>
# include <mln/labeling/foreground.hh>
# include <mln/labeling/level.hh>
+# include <mln/labeling/n_max.hh>
# include <mln/labeling/regional_maxima.hh>
# include <mln/labeling/regional_minima.hh>
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Fix labeling fill holes and add a 3D ball window.
* mln/labeling/fill_holes.hh: Fix.
* mln/labeling/all.hh: Update.
* tests/labeling/fill_holes.cc: New.
* tests/labeling/Makefile.am: Update.
* mln/win/ball3d.hh: New.
* mln/win/all.hh: Update.
mln/labeling/all.hh | 4 ++-
mln/labeling/fill_holes.hh | 14 +++++-----
mln/win/all.hh | 11 ++++----
mln/win/ball3d.hh | 41 ++++++++++++++++----------------
tests/labeling/Makefile.am | 2 +
tests/labeling/fill_holes.cc | 55 +++++++++++++++++++++++++++++++++++++++++++
6 files changed, 94 insertions(+), 33 deletions(-)
Index: mln/win/ball3d.hh
--- mln/win/ball3d.hh (revision 3368)
+++ mln/win/ball3d.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -26,39 +26,39 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_WIN_DISK2D_HH
-# define MLN_WIN_DISK2D_HH
+#ifndef MLN_WIN_BALL3D_HH
+# define MLN_WIN_BALL3D_HH
-/// \file mln/win/disk2d.hh
+/// \file mln/win/ball3d.hh
///
-/// Definition of the mln::win::disk2d window.
+/// Definition of the mln::win::ball3d window.
# include <mln/core/internal/classical_window_base.hh>
-# include <mln/core/alias/dpoint2d.hh>
+# include <mln/core/alias/dpoint3d.hh>
namespace mln
{
- mln_internal_add_classical_window_trait(disk2d);
+ mln_internal_add_classical_window_trait(ball3d);
namespace win
{
- /*! \brief Disk window defined on the 2D square grid.
+ /*! \brief Ball (sphere) window defined on the 3D square grid.
*
- * A disk2d is centered and symmetric.
+ * A ball3d is centered and symmetric.
*
*/
- struct disk2d : public internal::classical_window_base< dpoint2d, disk2d >
+ struct ball3d : public internal::classical_window_base< dpoint3d, ball3d >
{
/*! \brief Constructor.
*
* \param[in] length Length, thus diameter.
*
*/
- disk2d(unsigned length);
+ ball3d(unsigned length);
/*! \brief Give the disk diameter.
*/
@@ -80,7 +80,7 @@
# ifndef MLN_INCLUDE_ONLY
inline
- disk2d::disk2d(unsigned length)
+ ball3d::ball3d(unsigned length)
: length_(length)
{
mln_precondition(length % 2 == 1);
@@ -90,26 +90,27 @@
r2 = static_cast<def::coord>(r * r);
for (def::coord a = minus_r; a <= r; ++a)
for (def::coord b = minus_r; b <= r; ++b)
- if (a * a + b * b <= r2)
- insert(dpoint2d(a, b));
+ for (def::coord c = minus_r; c <= r; ++c)
+ if (a * a + b * b + c * c <= r2)
+ insert(dpoint3d(a, b, c));
}
inline
- unsigned disk2d::length() const
+ unsigned ball3d::length() const
{
return length_;
}
inline
- unsigned disk2d::delta_() const
+ unsigned ball3d::delta_() const
{
return length_ / 2;
}
inline
- void disk2d::print_(std::ostream& ostr) const
+ void ball3d::print_(std::ostream& ostr) const
{
- ostr << "[disk2d: length=" << length_ << ']';
+ ostr << "[ball3d: length=" << length_ << ']';
}
# endif // ! MLN_INCLUDE_ONLY
@@ -120,4 +121,4 @@
-#endif // ! MLN_WIN_DISK2D_HH
+#endif // ! MLN_WIN_BALL3D_HH
Property changes on: mln/win/ball3d.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/win/all.hh
--- mln/win/all.hh (revision 3372)
+++ mln/win/all.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 EPITA, 2009 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 +29,9 @@
#ifndef MLN_WIN_ALL_HH
# define MLN_WIN_ALL_HH
-/*! \file mln/win/all.hh
- *
- * \brief File that includes all win-related routines.
- */
+/// \file mln/win/all.hh
+///
+/// File that includes all win-related routines.
namespace mln
@@ -46,6 +46,7 @@
// Types.
# include <mln/win/backdiag2d.hh>
+# include <mln/win/ball3d.hh>
# include <mln/win/cube3d.hh>
# include <mln/win/cuboid3d.hh>
# include <mln/win/diag2d.hh>
Index: mln/labeling/all.hh
--- mln/labeling/all.hh (revision 3372)
+++ mln/labeling/all.hh (working copy)
@@ -1,4 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008, 2009 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
@@ -55,6 +56,7 @@
# include <mln/labeling/background.hh>
# include <mln/labeling/blobs.hh>
# include <mln/labeling/compute.hh>
+# include <mln/labeling/fill_holes.hh>
# include <mln/labeling/flat_zones.hh>
# include <mln/labeling/foreground.hh>
# include <mln/labeling/level.hh>
Index: mln/labeling/fill_holes.hh
--- mln/labeling/fill_holes.hh (revision 3372)
+++ mln/labeling/fill_holes.hh (working copy)
@@ -36,10 +36,9 @@
# include <mln/labeling/background.hh>
# include <mln/labeling/compute.hh>
+# include <mln/core/image/image_if.hh>
# include <mln/accu/count.hh>
-# include <mln/value/int_u8.hh>
-
namespace mln
{
@@ -81,19 +80,20 @@
mln_precondition(exact(input).is_valid());
mln_precondition(exact(nbh).is_valid());
- using value::int_u8;
-
mln_ch_value(I, bool) output;
initialize(output, input);
data::fill(output, false);
- accu::count<int_u8> a_;
mln_ch_value(I, L) lbls = labeling::background(input, nbh, nlabels);
+
+ accu::count<mln_value(I)> a_;
util::array<unsigned> arr = labeling::compute(a_, input, lbls, nlabels);
+
int bg_count = 0;
int bg_lbl = 0;
- for (int i = 0; i < arr.nelements(); ++i)
+ // We start at 1 to ignore the object.
+ for (int i = 1; i < arr.nelements(); ++i)
{
if (arr[i] > bg_count)
{
@@ -102,7 +102,7 @@
}
}
- data::fill((output | pw::value(lbls) != bg_lbl).rw(), true);
+ data::fill((output | (pw::value(lbls) != bg_lbl)).rw(), true);
trace::exiting("labeling::fill_holes");
return output;
Index: tests/labeling/fill_holes.cc
--- tests/labeling/fill_holes.cc (revision 0)
+++ tests/labeling/fill_holes.cc (revision 0)
@@ -0,0 +1,55 @@
+// Copyright (C) 2009 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.
+
+/// \file tests/labeling/fill_holes.cc
+///
+/// Test on mln::labeling::fill_holes.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/labeling/fill_holes.hh>
+#include <mln/value/label_8.hh>
+
+#include <mln/debug/println.hh>
+#include <mln/io/pbm/save.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+
+ image2d<bool> pic = io::pbm::load(MLN_IMG_DIR "/picasso.pbm");
+ debug::println(pic);
+ value::label_8 n;
+ image2d<bool> out = labeling::fill_holes(pic, c4(), n);
+ debug::println(out);
+ io::pbm::save(out, "out.pbm");
+// mln_assertion(n == 33);
+}
Index: tests/labeling/Makefile.am
--- tests/labeling/Makefile.am (revision 3372)
+++ tests/labeling/Makefile.am (working copy)
@@ -6,6 +6,7 @@
background \
blobs \
compute \
+ fill_holes \
flat_zones \
foreground \
level \
@@ -16,6 +17,7 @@
background_SOURCES = background.cc
blobs_SOURCES = blobs.cc
compute_SOURCES = compute.cc
+fill_holes_SOURCES = fill_holes.cc
flat_zones_SOURCES = flat_zones.cc
foreground_SOURCES = foreground.cc
level_SOURCES = level.cc
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-02-13 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add n_max() function to compute n maxima in an array.
* mln/labeling/n_max.hh: Implement the n_max() function.
---
n_max.hh | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
Index: trunk/milena/mln/labeling/n_max.hh
===================================================================
--- trunk/milena/mln/labeling/n_max.hh (revision 0)
+++ trunk/milena/mln/labeling/n_max.hh (revision 3371)
@@ -0,0 +1,90 @@
+// Copyright (C) 2009 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_LABELING_N_MAX_HH
+# define MLN_LABELING_N_MAX_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/util/array.hh>
+
+/// \file mln/labeling/mean_values.hh
+///
+/// Construct from a count accumulator of a labeled image an array with
+/// the ordered n biggest labels
+///
+/// \return an array starting at index 1
+
+
+namespace mln
+{
+
+ namespace labeling
+ {
+
+ template <typename L, typename V>
+ util::array<L>
+ n_max(const util::array<V>& in_arr, unsigned n);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L, typename V>
+ util::array<L>
+ n_max(const util::array<V>& in_arr, unsigned n)
+ {
+ trace::entering("mln::labeling::n_max");
+
+ util::array<L> output(n + 1, 0);
+
+ int swap = 0;
+ for (unsigned i = 0; i < in_arr.nelements(); ++i)
+ {
+ if (in_arr[i] > in_arr[output[n]])
+ {
+ output[n] = i;
+ }
+ int j = n - 1;
+ while (j > 0 && in_arr[output[j]] < in_arr[output[j + 1]])
+ {
+ swap = output[j];
+ output[j] = output[j + 1];
+ output[j + 1] = swap;
+ --j;
+ }
+ }
+
+ trace::exiting("mln::labeling::n_max");
+ return output;
+ }
+
+# endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::labeling
+
+} // end of namespace mln
+
+#endif // ! MLN_LABELING_N_MAX_HH