* mln/topo/is_not_end_point.hh: s/nbh/nbh_fg/.
(is_not_end_point<I, N>::is_not_end_point(const Neighborhood<N>&)):
New ctor.
(is_not_end_point<I, N>::set_image): New method.
(is_not_end_point<I, N>::ima_): Turn this reference into a pointer.
Adjust.
* mln/topo/is_simple_point2d.hh
(mln::topo::is_simple_point2d<I, N>::operator())
* mln/topo/detach_point.hh
(mln::topo::detach_point<I>::operator()):
Add preconditions.
* apps/generic-skel/image2d-skel-with-end-points.cc:
Use `mln::topo::is_simple_point2d' and `mln:: topo::detach_point'
from mln/topo/, instead of `is_simple_2d' and `detach' from
image2d-skel.hh
* apps/generic-skel/image2d-skel-unconstrained.cc: Likewise.
Remove the (lack of) constraint, as
mln::topo::skeleton::breadth_first_thinning already takes care of
this.
* apps/generic-skel/image2d-skel.hh: Remove.
* apps/generic-skel/Makefile.am
(image2d_skel_unconstrained_SOURCES)
(image2d_skel_with_end_points_SOURCES):
Remove image2d-skel.hh.
---
milena/ChangeLog | 29 ++++
milena/apps/generic-skel/Makefile.am | 4 +-
.../generic-skel/image2d-skel-unconstrained.cc | 19 +-
.../generic-skel/image2d-skel-with-end-points.cc | 14 +-
milena/apps/generic-skel/image2d-skel.hh | 174 --------------------
milena/mln/topo/detach_point.hh | 1 +
milena/mln/topo/is_not_end_point.hh | 42 ++++-
milena/mln/topo/is_simple_point2d.hh | 1 +
8 files changed, 84 insertions(+), 200 deletions(-)
delete mode 100644 milena/apps/generic-skel/image2d-skel.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 95a51a4..d5db5e7 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,34 @@
2011-07-13 Roland Levillain <roland(a)lrde.epita.fr>
+ Factor code of 2D skeletonizations in apps/generic-skel/.
+
+ * mln/topo/is_not_end_point.hh: s/nbh/nbh_fg/.
+ (is_not_end_point<I, N>::is_not_end_point(const Neighborhood<N>&)):
+ New ctor.
+ (is_not_end_point<I, N>::set_image): New method.
+ (is_not_end_point<I, N>::ima_): Turn this reference into a pointer.
+ Adjust.
+ * mln/topo/is_simple_point2d.hh
+ (mln::topo::is_simple_point2d<I, N>::operator())
+ * mln/topo/detach_point.hh
+ (mln::topo::detach_point<I>::operator()):
+ Add preconditions.
+ * apps/generic-skel/image2d-skel-with-end-points.cc:
+ Use `mln::topo::is_simple_point2d' and `mln:: topo::detach_point'
+ from mln/topo/, instead of `is_simple_2d' and `detach' from
+ image2d-skel.hh
+ * apps/generic-skel/image2d-skel-unconstrained.cc: Likewise.
+ Remove the (lack of) constraint, as
+ mln::topo::skeleton::breadth_first_thinning already takes care of
+ this.
+ * apps/generic-skel/image2d-skel.hh: Remove.
+ * apps/generic-skel/Makefile.am
+ (image2d_skel_unconstrained_SOURCES)
+ (image2d_skel_with_end_points_SOURCES):
+ Remove image2d-skel.hh.
+
+2011-07-13 Roland Levillain <roland(a)lrde.epita.fr>
+
Misc changes in apps/generic-skel/ and tools/.
* apps/generic-skel/image3d-skel-unconstrained.cc:
diff --git a/milena/apps/generic-skel/Makefile.am b/milena/apps/generic-skel/Makefile.am
index 961fef2..fd9febc 100644
--- a/milena/apps/generic-skel/Makefile.am
+++ b/milena/apps/generic-skel/Makefile.am
@@ -33,8 +33,8 @@ bin_PROGRAMS = \
image3d-skel-with-1d-isthmuses
# 2D cases.
-image2d_skel_unconstrained_SOURCES = image2d-skel-unconstrained.cc image2d-skel.hh
-image2d_skel_with_end_points_SOURCES = image2d-skel-with-end-points.cc image2d-skel.hh
+image2d_skel_unconstrained_SOURCES = image2d-skel-unconstrained.cc
+image2d_skel_with_end_points_SOURCES = image2d-skel-with-end-points.cc
# 3D cases, slow versions.
noinst_HEADERS = image3d-skel.hh
diff --git a/milena/apps/generic-skel/image2d-skel-unconstrained.cc
b/milena/apps/generic-skel/image2d-skel-unconstrained.cc
index 4459ba4..7a33334 100644
--- a/milena/apps/generic-skel/image2d-skel-unconstrained.cc
+++ b/milena/apps/generic-skel/image2d-skel-unconstrained.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Milena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -33,9 +33,10 @@
#include <mln/topo/skeleton/breadth_first_thinning.hh>
-#include <mln/io/pbm/all.hh>
+#include <mln/topo/is_simple_point2d.hh>
+#include <mln/topo/detach_point.hh>
-#include "image2d-skel.hh"
+#include <mln/io/pbm/all.hh>
int
@@ -72,14 +73,12 @@ main(int argc, char* argv[])
neighb2d nbh_bg = c8();
// Simplicity criterion functor.
- ::is_simple_2d<I, N> is_simple(nbh_fg, nbh_bg);
- // Detach procedure.
- ::detach<I> detach;
- // (Lack of) constraint.
- fun::p2b::tautology constraint;
+ topo::is_simple_point2d<I, N> is_simple(nbh_fg, nbh_bg);
+ // Simple point detach procedure.
+ topo::detach_point<I> detach;
I output = topo::skeleton::breadth_first_thinning(input, nbh_fg,
- is_simple, detach,
- constraint);
+ is_simple,
+ detach);
io::pbm::save(output, output_filename);
}
diff --git a/milena/apps/generic-skel/image2d-skel-with-end-points.cc
b/milena/apps/generic-skel/image2d-skel-with-end-points.cc
index 604b065..d22f281 100644
--- a/milena/apps/generic-skel/image2d-skel-with-end-points.cc
+++ b/milena/apps/generic-skel/image2d-skel-with-end-points.cc
@@ -34,9 +34,11 @@
#include <mln/topo/skeleton/breadth_first_thinning.hh>
-#include <mln/io/pbm/all.hh>
+#include <mln/topo/is_simple_point2d.hh>
+#include <mln/topo/detach_point.hh>
+#include <mln/topo/is_not_end_point.hh>
-#include "image2d-skel.hh"
+#include <mln/io/pbm/all.hh>
int
@@ -71,11 +73,11 @@ main(int argc, char* argv[])
neighb2d nbh_bg = c8();
// Simplicity criterion functor.
- ::is_simple_2d<I, N> is_simple(nbh_fg, nbh_bg);
- // Detach procedure.
- ::detach<I> detach;
+ topo::is_simple_point2d<I, N> is_simple(nbh_fg, nbh_bg);
+ // Simple point detach procedure.
+ topo::detach_point<I> detach;
// Constraint: do not remove end points.
- is_not_end_point<I, N> constraint(nbh_fg, input);
+ topo::is_not_end_point<I, N> constraint(nbh_fg, input);
I output = topo::skeleton::breadth_first_thinning(input, nbh_fg,
is_simple, detach,
diff --git a/milena/apps/generic-skel/image2d-skel.hh
b/milena/apps/generic-skel/image2d-skel.hh
deleted file mode 100644
index 6cd8c50..0000000
--- a/milena/apps/generic-skel/image2d-skel.hh
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
-//
-// This file is part of the Milena 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 APPS_GENERIC_SKEL_IMAGE2D_SKEL_HH
-# define APPS_GENERIC_SKEL_IMAGE2D_SKEL_HH
-
-/// \file
-/// \brief Definitions for a simplicity criterion and a constraint
-/// to be used in the breadth-first thinning of a 2D regular image.
-
-# include <mln/topo/is_simple_2d.hh>
-
-
-// FIXME: Split this file?
-
-
-/** \brief An equivalent (for mln::image2d) of the
- mln::topo::is_simple_cell functor, based on the mask-based
- criterion mln::topo::is_simple_2d.
-
- This functor acts as an adapter, since mln::topo::is_simple_2d
- does not fit (yet) in the canvas of
- mln::topo::skeleton::breadth_first_thinning. Moreover, this code
- is a bit easier to read since it does not make use of a dual
- neighborhood (having a long and complex type). */
-template <typename I, typename N>
-class is_simple_2d : public mln::Function_v2b< is_simple_2d<I, N> >
-{
-public:
- /// Result type of the functor.
- typedef bool result;
-
- /// Build a functor.
- ///
- /// \param nbh_fg The foreground neighborhood.
- /// \param nbh_bg The background neighborhood.
- is_simple_2d(const mln::Neighborhood<N>& nbh_fg,
- const mln::Neighborhood<N>& nbh_bg)
- : nbh_fg_(mln::exact(nbh_fg)), nbh_bg_(mln::exact(nbh_bg)),
- ima_(0)
- {
- }
-
- /// Build a functor, and assign an image to it.
- ///
- /// \param nbh_fg The foreground neighborhood.
- /// \param nbh_bg The background neighborhood.
- /// \apram ima The image.
- is_simple_2d(const mln::Neighborhood<N>& nbh_fg,
- const mln::Neighborhood<N>& nbh_bg,
- const mln::Image<I>& ima)
- : nbh_fg_(mln::exact(nbh_fg)), nbh_bg_(mln::exact(nbh_bg)),
- ima_(mln::exact(&ima))
- {
- }
-
- /// Set the underlying image.
- void set_image(const mln::Image<I>& ima)
- {
- ima_ = mln::exact(&ima);
- }
-
- /// Based on connectivity numbers.
- bool operator()(const mln_psite(I)& p) const
- {
- return
- mln::connectivity_number_2d(*ima_, nbh_fg_, p, true ) == 1 &&
- mln::connectivity_number_2d(*ima_, nbh_bg_, p, false) == 1;
- }
-
-private:
- /// The foreground neighborhood.
- const N& nbh_fg_;
- /// The background neighborhood.
- const N& nbh_bg_;
- /// The image.
- const I* ima_;
-};
-
-
-template <typename I>
-class detach
-{
-public:
- /// Build a functor.
- detach()
- : ima_(0)
- {
- }
-
- /// Build a functor, and assign an image to it.
- ///
- /// \apram ima The image.
- detach(mln::Image<I>& ima)
- : ima_(mln::exact(&ima))
- {
- }
-
- /// Set the underlying image.
- void set_image(mln::Image<I>& ima)
- {
- ima_ = mln::exact(&ima);
- }
-
- void operator()(const mln_psite(I)& p) const
- {
- (*ima_)(p) = false;
- }
-
-private:
- /// The image.
- I* ima_;
-};
-
-
-template <typename I, typename N>
-struct is_not_end_point : public mln::Function_v2b< is_not_end_point<I, N> >
-{
- /// Build a functor, and assign an image to it.
- ///
- /// \param nbh_fg The foreground neighborhood.
- /// \apram ima The image.
- is_not_end_point(const mln::Neighborhood<N>& nbh,
- const mln::Image<I>& ima)
- : nbh_(mln::exact(nbh)),
- ima_(mln::exact(ima))
- {
- }
-
- // Is \a p not a end point?
- bool operator()(const mln_psite(I)& p) const
- {
- // Number of foreground neighbors pixels.
- unsigned nneighbs = 0;
- mln_niter(N) n(nbh_, p);
- for_all(n)
- if (ima_.has(n) && ima_(n))
- ++nneighbs;
- return nneighbs != 1;
- }
-
-private:
- /// The foreground neighborhood.
- const N& nbh_;
- /// The image.
- const I& ima_;
-};
-
-
-#endif // ! APPS_GENERIC_SKEL_IMAGE2D_SKEL_HH
diff --git a/milena/mln/topo/detach_point.hh b/milena/mln/topo/detach_point.hh
index 6e4d22d..c361e11 100644
--- a/milena/mln/topo/detach_point.hh
+++ b/milena/mln/topo/detach_point.hh
@@ -101,6 +101,7 @@ namespace mln
void
detach_point<I>::operator()(const mln_psite(I)& p) const
{
+ mln_precondition(ima_);
(*ima_)(p) = false;
}
diff --git a/milena/mln/topo/is_not_end_point.hh b/milena/mln/topo/is_not_end_point.hh
index 62561fa..f958a59 100644
--- a/milena/mln/topo/is_not_end_point.hh
+++ b/milena/mln/topo/is_not_end_point.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2010, 2011 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of the Milena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -45,20 +45,28 @@ namespace mln
template <typename I, typename N>
struct is_not_end_point : public Function_v2b< is_not_end_point<I, N> >
{
+ /// Build a functor.
+ ///
+ /// \param nbh The (foreground) neighborhood.
+ is_not_end_point(const Neighborhood<N>& nbh);
+
/// Build a functor, and assign an image to it.
///
- /// \param nbh_fg The foreground neighborhood.
- /// \apram ima The image.
+ /// \param nbh The (foreground) neighborhood.
+ /// \apram ima The image.
is_not_end_point(const Neighborhood<N>& nbh, const Image<I>&
ima);
- // Is \a p not an end point?
+ /// Set the underlying image.
+ void set_image(const Image<I>& ima);
+
+ /// Is \a p not an end point?
bool operator()(const mln_psite(I)& p) const;
private:
- /// The foreground neighborhood.
+ /// The (foreground) neighborhood.
const N& nbh_;
/// The image.
- const I& ima_;
+ const I* ima_;
};
@@ -67,11 +75,27 @@ namespace mln
template <typename I, typename N>
inline
+ is_not_end_point<I, N>::is_not_end_point(const Neighborhood<N>& nbh)
+ : nbh_(exact(nbh)),
+ ima_(0)
+ {
+ }
+
+ template <typename I, typename N>
+ inline
is_not_end_point<I, N>::is_not_end_point(const Neighborhood<N>& nbh,
const Image<I>& ima)
: nbh_(exact(nbh)),
- ima_(exact(ima))
+ ima_(exact(&ima))
+ {
+ }
+
+ template <typename I, typename N>
+ inline
+ void
+ is_not_end_point<I, N>::set_image(const Image<I>& ima)
{
+ ima_ = exact(&ima);
}
template <typename I, typename N>
@@ -79,11 +103,13 @@ namespace mln
bool
is_not_end_point<I, N>::operator()(const mln_psite(I)& p) const
{
+ mln_precondition(ima_);
+ const I& ima = *ima_;
// Number of foreground neighbors pixels.
unsigned nneighbs = 0;
mln_niter(N) n(nbh_, p);
for_all(n)
- if (ima_.has(n) && ima_(n))
+ if (ima.has(n) && ima(n))
++nneighbs;
return nneighbs != 1;
}
diff --git a/milena/mln/topo/is_simple_point2d.hh b/milena/mln/topo/is_simple_point2d.hh
index 8d0d7dd..1f9683c 100644
--- a/milena/mln/topo/is_simple_point2d.hh
+++ b/milena/mln/topo/is_simple_point2d.hh
@@ -126,6 +126,7 @@ namespace mln
bool
is_simple_point2d<I, N>::operator()(const mln_psite(I)& p) const
{
+ mln_precondition(ima_);
return
connectivity_number_2d(*ima_, nbh_fg_, p, true ) == 1 &&
connectivity_number_2d(*ima_, nbh_bg_, p, false) == 1;
--
1.7.2.5