https://svn.lrde.epita.fr/svn/oln/trunk/milena
I've just remembered mln/labeling/level.hh existed, and probably does the
same job as the file I'm checking in. I needed it to implement Meyer's
Watershed Transfom algorithm, so I'll remove it as soon as I merge both
files.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a computation of the level components.
* mln/morpho/level_components.hh: New.
Imported from Olena proto-1.0.
* tests/morpho/level_components.cc: New test.
* tests/morpho/Makefile.am (check_PROGRAMS): Add level_components.
(level_components_SOURCES): New.
mln/morpho/level_components.hh | 138 ++++++++++++++++++++++++++++-----------
tests/morpho/Makefile.am | 2
tests/morpho/level_components.cc | 62 +++++++++++++++++
3 files changed, 166 insertions(+), 36 deletions(-)
Index: mln/morpho/level_components.hh
--- mln/morpho/level_components.hh (revision 1680)
+++ mln/morpho/level_components.hh (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2005 EPITA Research and Development Laboratory
+// Copyright (C) 2005, 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
@@ -25,62 +25,128 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef OLENA_MORPHO_LEVEL_COMPONENTS_HH
-# define OLENA_MORPHO_LEVEL_COMPONENTS_HH
+#ifndef MLN_MORPHO_MORPHO_COMPONENTS_HH
+# define MLN_MORPHO_MORPHO_COMPONENTS_HH
+
+// FIXME: This file seems to contain the same algorithm as
+// mln/labeling/level.hh. Merge or remove to avoid duplication.
+
+// FIXME: Provide neighborhood-aware versions of these algorithms.
# include <queue>
-# include "oln/level/fill.hh"
+# include <mln/trait/value_.hh>
+# include <mln/trait/ch_value.hh>
+
+# include <mln/level/fill.hh>
+
+# include <mln/morpho/includes.hh>
+
+
+namespace mln {
+
+ namespace morpho {
+
+ /** Compute the level components of \a input.
+
+ \p DestValue is the value type of the output.
+
+ The result is an image where each level component is given a
+ value between \c mln_value(DestValue) and \c ncomps (the
+ number of level components).
+
+ \param[in] input The image whose minima are computed.
+ \param[in] win The window describing the connexity of \a input.
+ \param[out] ncomps The number of minima found by the algorithm.
+ \return The image of components
-namespace oln {
+ \pre \p DestValue is large enough to hold a number of values
+ equal to \c nminima + 1, so as to tag all the minima points
+ plus the non-minima points. */
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input, const Window<W>& win,
+ unsigned& ncomps);
- namespace level {
+ /// \brief Like the 3-argument version of mln::moprho::level_components,
+ /// without the out argument \c ncomps.
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input, const Window<W>& win);
- /// Compute the level components of \a input.
- template <typename DestValue, typename I>
- typename ch_value_type<I, DestValue>::ret
- level_components(const abstract::image_with_nbh<I>& input)
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input_, const Window<W>& win_,
+ unsigned& ncomps)
{
- mlc_is_a(I, abstract::scalar_valued_image)::ensure();
+ /* FIXME: Ensure the input image has scalar values. */
+
+ /* FIXME: Errors due to a too small DestValue type should be
+ reported more explicitely. Currently, we abort with messages
+ akin to this one:
+
+ Assertion failed:
+ (unsigned(i) <= mln::trait::value_< enc_ >::max()),
+ function operator=, file ../../../../milena/mln/value/int_u.hh,
+ line 243.
+
+ This is not user-friendly at all! */
- typename ch_value_type<I, DestValue>::ret labels(input.size(),
- input.nbh_get());
- typename ch_value_type<I, bool>::ret processed(input.size(),
- input.nbh_get());
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+
+ mln_ch_value(I, DestValue) labels(input.domain());
+ mln_ch_value(I, bool) processed(input.domain());
level::fill (processed, false);
- DestValue cur_label = ntg_min_val(DestValue);
+ DestValue cur_label = mln_min(DestValue);
- typedef oln_type_of(I, point) point_type;
- std::queue<point_type> q;
+ typedef mln_point(I) point_type;
+ std::queue<point_type> queue;
- oln_type_of(I, piter) p(input.size());
- for_all_p (p)
- if (!processed[p])
+ mln_piter(I) p(input.domain());
+ for_all(p)
+ if (!processed(p))
{
- labels[p] = cur_label;
- processed[p] = true;
- q.push(p);
- while (!q.empty())
+ labels(p) = cur_label;
+ processed(p) = true;
+ queue.push(p);
+ while (!queue.empty())
{
- point_type s = q.front();
- q.pop();
- oln_type_of(I, niter) n(input);
- for_all_n_of_p (n, s)
- if (input.hold(n) and !processed[n] and input[n] == input[s])
+ point_type s = queue.front();
+ queue.pop();
+ mln_qiter(W) q(win, s);
+ for_all(q)
+ if (input.has(q) and !processed(q) and input(q) == input(s))
{
- labels[n] = cur_label;
- processed[n] = true;
- q.push(n);
+ labels(q) = cur_label;
+ processed(q) = true;
+ queue.push(q);
}
}
++cur_label;
}
+ // Update ncomps.
+ ncomps = cur_label;
return labels;
}
- } // end of namespace oln::level
+ template <typename DestValue, typename I, typename W>
+ mln_ch_value(I, DestValue)
+ level_components(const Image<I>& input, const Window<W>& win)
+ {
+ // Dummy value.
+ unsigned ncomps;
+ return level_components<DestValue>(input, win, ncomps);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho
-} // end of namespace oln
+} // end of namespace mln
-#endif // ! OLENA_MORPHO_LEVEL_COMPONENTS_HH
+#endif // ! MLN_MORPHO_MORPHO_COMPONENTS_HH
Index: tests/morpho/level_components.cc
--- tests/morpho/level_components.cc (revision 0)
+++ tests/morpho/level_components.cc (revision 0)
@@ -0,0 +1,62 @@
+// Copyright (C) 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.
+
+/// \file tests/morpho/level_components.cc
+// /\brief Test on mln::morpho::level_components
+
+#include <iostream>
+
+#include <mln/core/image2d.hh>
+#include <mln/core/window2d.hh>
+#include <mln/core/neighb2d.hh>
+
+#include <mln/convert/to_window.hh>
+
+#include <mln/value/int_u8.hh>
+
+#include <mln/morpho/level_components.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include "tests/data.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> input;
+ io::pgm::load(input, MLN_IMG_DIR "/squares.pgm");
+ unsigned ncomps;
+ // FIXME: Do we really need to use a neighborood to express a 4-c window?
+ image2d<int_u8> output =
+ morpho::level_components<int_u8>(input, convert::to_window(c4()), ncomps);
+ std::cout << "ncomps = " << ncomps << std::endl;
+ io::pgm::save(output, "out.pgm");
+}
Index: tests/morpho/Makefile.am
--- tests/morpho/Makefile.am (revision 1692)
+++ tests/morpho/Makefile.am (working copy)
@@ -11,6 +11,7 @@
gradient \
hit_or_miss \
laplacian \
+ level_components \
opening_area \
thinning
@@ -22,6 +23,7 @@
gradient_SOURCES = gradient.cc
hit_or_miss_SOURCES = hit_or_miss.cc
laplacian_SOURCES = laplacian.cc
+level_components_SOURCES = level_components.cc
opening_area_SOURCES = opening_area.cc
thinning_SOURCES = thinning.cc
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-01-25 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
* tests/level/replace.cc: Fix licence in replace.cc.
---
replace.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: trunk/milena/tests/level/replace.cc
===================================================================
--- trunk/milena/tests/level/replace.cc (revision 1683)
+++ trunk/milena/tests/level/replace.cc (revision 1684)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2008 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
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Miscellaneous corrections in documentation and aesthetics changes.
* mln/core/macros.hh: Use Doxygen delimiters to document pairs of
macros.
* mln/value/stack.hh: Wrap long lines.
Fix Doxygen comments.
* mln/border/get.hh: Fix header inclusions.
Fix Doxygen comments.
* tests/stack.cc: Don't include unnecessary files.
mln/border/get.hh | 9 +--
mln/core/concept/README | 2
mln/core/macros.hh | 142 ++++++++++++++++++++++++++++++++++--------------
mln/core/neighb2d.hh | 2
mln/value/stack.hh | 13 +++-
tests/stack.cc | 4 -
6 files changed, 119 insertions(+), 53 deletions(-)
Index: mln/core/macros.hh
--- mln/core/macros.hh (revision 1689)
+++ mln/core/macros.hh (working copy)
@@ -36,186 +36,246 @@
// a
-/// Shortcut to access the argument type associated to T.
+/// Shortcuts to access the argument type associated to T.
+/// \{
# define mln_argument(T) typename T::argument
# define mln_argument_(T) T::argument
+/// \}
// b
-/// Shortcut to access the bkd_niter type associated to T.
+/// Shortcuts to access the bkd_niter type associated to T.
+/// \{
# define mln_bkd_niter(T) typename T::bkd_niter
# define mln_bkd_niter_(T) T::bkd_niter
+/// \}
-/// Shortcut to access the bkd_piter type associated to T.
+/// Shortcuts to access the bkd_piter type associated to T.
+/// \{
# define mln_bkd_piter(T) typename T::bkd_piter
# define mln_bkd_piter_(T) T::bkd_piter
+/// \}
-/// Shortcut to access the bkd_qiter type associated to T.
+/// Shortcuts to access the bkd_qiter type associated to T.
+/// \{
# define mln_bkd_qiter(T) typename T::bkd_qiter
# define mln_bkd_qiter_(T) T::bkd_qiter
+/// \}
-/// Shortcut to access the bkd_viter type associated to T.
+/// Shortcuts to access the bkd_viter type associated to T.
+/// \{
# define mln_bkd_viter(T) typename T::bkd_viter
# define mln_bkd_viter_(T) T::bkd_viter
+/// \}
-/// Shortcut to access the box type associated to T.
+/// Shortcuts to access the box type associated to T.
+/// \{
# define mln_box(T) typename T::box
# define mln_box_(T) T::box
+/// \}
// c
-/// Shortcut to access the coord type associated to T.
+/// Shortcuts to access the coord type associated to T.
+/// \{
# define mln_coord(T) typename T::coord
# define mln_coord_(T) T::coord
+/// \}
// d
-/// Shortcut to access the dpoint type associated to T.
+/// Shortcuts to access the dpoint type associated to T.
+/// \{
# define mln_dpoint(T) typename T::dpoint
# define mln_dpoint_(T) T::dpoint
+/// \}
// e
-/// Shortcut to access the encoding type associated to T.
+/// Shortcuts to access the encoding type associated to T.
+/// \{
# define mln_enc(T) typename T::enc
# define mln_enc_(T) T::enc
+/// \}
-/// Shortcut to access the equivalent type associated to T.
+/// Shortcuts to access the equivalent type associated to T.
+/// \{
# define mln_equiv(T) typename T::equiv
# define mln_equiv_(T) T::equiv
+/// \}
// f
-/// Shortcut to access the fwd_niter type associated to T.
+/// Shortcuts to access the fwd_niter type associated to T.
+/// \{
# define mln_fwd_niter(T) typename T::fwd_niter
# define mln_fwd_niter_(T) T::fwd_niter
+/// \}
-/// Shortcut to access the fwd_piter type associated to T.
+/// Shortcuts to access the fwd_piter type associated to T.
+/// \{
# define mln_fwd_piter(T) typename T::fwd_piter
# define mln_fwd_piter_(T) T::fwd_piter
+/// \}
-/// Shortcut to access the fwd_qiter type associated to T.
+/// Shortcuts to access the fwd_qiter type associated to T.
+/// \{
# define mln_fwd_qiter(T) typename T::fwd_qiter
# define mln_fwd_qiter_(T) T::fwd_qiter
+/// \}
-/// Shortcut to access the fwd_viter type associated to T.
+/// Shortcuts to access the fwd_viter type associated to T.
+/// \{
# define mln_fwd_viter(T) typename T::fwd_viter
# define mln_fwd_viter_(T) T::fwd_viter
+/// \}
// i
-/// Shortcut to access the image type associated to T.
+/// Shortcuts to access the image type associated to T.
+/// \{
# define mln_image(T) typename T::image
# define mln_image_(T) T::image
+/// \}
-/// Shortcut to access the invert type associated to T.
+/// Shortcuts to access the invert type associated to T.
+/// \{
# define mln_invert(T) typename T::invert
# define mln_invert_(T) T::invert
+/// \}
// l
-
-/// Shortcut to access the lvalue type associated to T.
+/// Shortcuts to access the lvalue type associated to T.
+/// \{
# define mln_lvalue(T) typename T::lvalue
# define mln_lvalue_(T) T::lvalue
+/// \}
// m
-/// Shortcut to access the mesh type associated to T.
+/// Shortcuts to access the mesh type associated to T.
+/// \{
# define mln_mesh(T) typename T::mesh
# define mln_mesh_(T) T::mesh
-
-
-// n
-
-/// Shortcut to access the neighborhood type associated to T.
-# define mln_neighb(T) typename T::neighb
-# define mln_neighb_(T) T::neighb
+/// \}
// p
-/// Shortcut to access the type of point iterator (piter) associated to T.
+/// Shortcuts to access the type of point iterator (piter) associated to T.
+/// \{
# define mln_piter(T) typename T::fwd_piter
# define mln_piter_(T) T::fwd_piter
+/// \}
-/// Shortcut to access the type of point by line iterator (line_piter) associated to T.
+/// Shortcuts to access the type of point by line iterator
+/// (line_piter) associated to T.
+/// \{
# define mln_line_piter(T) typename T::line_piter
# define mln_line_piter_(T) T::line_piter
+/// \}
-/// Shortcut to access the type of point set (pset) associated to T.
+/// Shortcuts to access the type of point set (pset) associated to T.
+/// \{
# define mln_pset(T) typename T::pset
# define mln_pset_(T) T::pset
+/// \}
-/// Shortcut to access the type of point site (psite) associated to T.
+/// Shortcuts to access the type of point site (psite) associated to T.
+/// \{
# define mln_psite(T) typename T::psite
# define mln_psite_(T) T::psite
+/// \}
-/// Shortcut to access the point type associated to T.
+/// Shortcuts to access the point type associated to T.
+/// \{
# define mln_point(T) typename T::point
# define mln_point_(T) T::point
+/// \}
// q
-/// Shortcut to access the qualified (const or mutable) value type associated to T.
+/// Shortcuts to access the qualified (const or mutable) value type
+/// associated to T.
+/// \{
# define mln_qlf_value(T) typename mln::trait::qlf_value< T >::ret
# define mln_qlf_value_(T) mln::trait::qlf_value< T >::ret
+/// \}
-/// Shortcut to access the qiter type associated to T.
+/// Shortcuts to access the qiter type associated to T.
+/// \{
# define mln_qiter(T) typename T::fwd_qiter
# define mln_qiter_(T) T::fwd_qiter
+/// \}
// n
-/// Shortcut to access the niter type associated to T.
+/// Shortcuts to access the niter type associated to T.
+/// \{
# define mln_niter(T) typename T::fwd_niter
# define mln_niter_(T) T::fwd_niter
+/// \}
// r
-/// Shortcut to access the result type associated to T.
+/// Shortcuts to access the result type associated to T.
+/// \{
# define mln_result(T) typename T::result
# define mln_result_(T) T::result
+/// \}
-/// Shortcut to access the rvalue type associated to T.
+/// Shortcuts to access the rvalue type associated to T.
+/// \{
# define mln_rvalue(T) typename T::rvalue
# define mln_rvalue_(T) T::rvalue
+/// \}
// v
-/// Shortcut to access the value type associated to T.
+/// Shortcuts to access the value type associated to T.
+/// \{
# define mln_value(T) typename T::value
# define mln_value_(T) T::value
+/// \}
-/// Shortcut to access the type of value set (vset) associated to T.
+/// Shortcuts to access the type of value set (vset) associated to T.
+/// \{
# define mln_vset(T) typename T::vset
# define mln_vset_(T) T::vset
+/// \}
-/// Shortcut to access the viter type associated to T.
+/// Shortcuts to access the viter type associated to T.
+/// \{
# define mln_viter(T) typename T::fwd_viter
# define mln_viter_(T) T::fwd_viter
+/// \}
// w
-/// Shortcut to access the weight type associated to T.
+/// Shortcuts to access the weight type associated to T.
+/// \{
# define mln_weight(T) typename T::weight
# define mln_weight_(T) T::weight
+/// \}
-/// Shortcut to access the window type associated to T.
+/// Shortcuts to access the window type associated to T.
+/// \{
# define mln_window(T) typename T::window
# define mln_window_(T) T::window
+/// \}
Index: mln/value/stack.hh
--- mln/value/stack.hh (revision 1689)
+++ mln/value/stack.hh (working copy)
@@ -131,8 +131,10 @@
namespace value
{
- /*! \brief stack image class. stack_image stores a
- * vector of n images of the same domain.
+ /*! \brief Stack image class.
+ *
+ * mln::value::stack_image stores a vector of n images of the same
+ * domain.
*
* The parameter \c n is the number of images, \c I is the type of
* a stack element. Acces a value will compute a vector which
@@ -143,7 +145,8 @@
* stack[n](p)]
*/
template <unsigned n, typename I>
- struct stack_image : public mln::internal::image_value_morpher_< I, stack_image<n,I> >
+ struct stack_image
+ : public mln::internal::image_value_morpher_< I, stack_image<n,I> >
{
/// Point_Site associated type.
typedef mln_psite(I) psite;
@@ -168,9 +171,11 @@
typedef stack_image< n, tag::image_<I> > skeleton;
- /// Constructor.
+ /// Constructors.
+ /// \{
stack_image(const metal::vec<n,I>& imas);
stack_image();
+ /// \}
/// Test if this image has been initialized.
Index: mln/border/get.hh
--- mln/border/get.hh (revision 1689)
+++ mln/border/get.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
@@ -33,7 +33,7 @@
* \brief Define function that returns the real border thickness of image.
*/
-# include <mln/border/find.hh>
+# include <mln/trait/images.hh>
namespace mln
@@ -42,13 +42,12 @@
namespace border
{
- /*! Get the virtual (outer) border thickness of image \p ima.
+ /*! Get the virtual (outer) border thickness of image \a ima.
*
* \param[in] ima The image.
* \result The border thickness (0 if there is no border).
*
- * \pre \p ima has to be initialized.
- *
+ * \pre \a ima has to be initialized.
*/
template <typename I>
unsigned get(const Image<I>& ima);
Index: tests/stack.cc
--- tests/stack.cc (revision 1689)
+++ tests/stack.cc (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
@@ -32,8 +32,6 @@
#include <mln/core/image2d.hh>
#include <mln/value/stack.hh>
-#include <mln/debug/iota.hh>
-#include <mln/debug/println.hh>
int main()
Index: mln/core/neighb2d.hh
--- mln/core/neighb2d.hh (revision 1689)
+++ mln/core/neighb2d.hh (working copy)
@@ -98,6 +98,8 @@
inline
const neighb2d& c4()
{
+ // FIXME: `flower' is probably not a canonical name to state
+ // whether the neighborhood is initialized or not. :)
static bool flower = true;
static neighb2d it;
if (flower)
Index: mln/core/concept/README
--- mln/core/concept/README (revision 1689)
+++ mln/core/concept/README (working copy)
@@ -5,6 +5,8 @@
concept files themselves, but we'd like a kind of centralized summary
too. An index would be nice.
+See what Doxygen's \page provides.
+
* Image
Images are functions mapping point sites from a given domain (point
site set) to a value.
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Adjust the morphological dilation w.r.t. a neighborhood.
* mln/morpho/includes.hh: Include mln/metal/has_neighborhood.hh.
* mln/morpho/dilation.hh: Remove dead code.
(dilation(const Image<I>&, Image<O>&)): Update preconditions.
Fix delegation to mln::morpho::impl::dilation_wrt_nbh.
* tests/morpho/dilation.cc: Peform tests using neighborhoods.
Use smaller structural elemements to speed up tests.
mln/morpho/dilation.hh | 84 +++++++++++++++--------------------------------
mln/morpho/includes.hh | 2 +
tests/morpho/dilation.cc | 26 ++++++++++----
3 files changed, 48 insertions(+), 64 deletions(-)
Index: mln/morpho/includes.hh
--- mln/morpho/includes.hh (revision 1687)
+++ mln/morpho/includes.hh (working copy)
@@ -38,6 +38,8 @@
# include <mln/core/concept/window.hh>
# include <mln/core/concept/neighborhood.hh>
+# include <mln/metal/has_neighborhood.hh>
+
# include <mln/value/ops.hh>
# include <mln/accu/min.hh>
Index: mln/morpho/dilation.hh
--- mln/morpho/dilation.hh (revision 1687)
+++ mln/morpho/dilation.hh (working copy)
@@ -92,32 +92,6 @@
namespace impl
{
- /*---------------------.
- | Neighborhood-based. |
- `---------------------*/
-
- /* FIXME: We might want to move this function into the body of
- the facade (see at the bottom of the file. */
- // Sole case. Convert the neighborhood into a window, and
- // delegate to the window-based implementation.
- template <typename I, typename N, typename O>
- inline
- void dilation_wrt_nbh(const Image<I>& input,
- const Neighborhood<N>& nbh,
- Image<O>& output)
- {
- /* FIXME: The following comment applies to every algorithm
- having a neighborhood and a window flavor: move it
- elsewhere.
-
- We solely depend on the neighborhood-to-window conversion
- here. This means the conversion should be smart enough to
- produce a working window, even in the case of a non
- dpoint-set-based neighborhood. */
- dilation_wrt_win(input, to_window(nbh), output);
- }
-
-
/*---------------.
| Window-based. |
`---------------*/
@@ -171,24 +145,6 @@
}
}
- // FIXME: Seems to be duplicate code!
-
-// /// Stage 1: dispatch w.r.t. the window type.
-// /// \{
-
-// /// Default case.
-// template <typename I, typename W, typename O>
-// inline
-// void dilation_wrt_win(const Image<I>& input, const Window<W>& win,
-// Image<O>& output)
-// {
-// // Perform stage 2: dispatch w.r.t. the value kind.
-// dilation_wrt_value(mln_trait_image_kind(I)(), exact(input),
-// exact(win), output);
-// }
-
- // ...
-
// ------------- //
// Dispatchers. //
@@ -284,6 +240,31 @@
/// \}
+
+ /*---------------------.
+ | Neighborhood-based. |
+ `---------------------*/
+
+ /* FIXME: We might want to move this function into the body of
+ the facade (see at the bottom of the file. */
+ // Sole case. Convert the neighborhood into a window, and
+ // delegate to the window-based implementation.
+ template <typename I, typename N, typename O>
+ inline
+ void dilation_wrt_nbh(const Image<I>& input, const Neighborhood<N>& nbh,
+ Image<O>& output)
+ {
+ /* FIXME: The following comment applies to every algorithm
+ having a neighborhood and a window flavor: move it
+ elsewhere.
+
+ We solely depend on the neighborhood-to-window conversion
+ here. This means the conversion should be smart enough to
+ produce a working window, even in the case of a non
+ dpoint-set-based neighborhood. */
+ dilation_wrt_win(input, convert::to_window(nbh), output);
+ }
+
} // end of namespace mln::morpho::impl
@@ -301,22 +282,13 @@
{
trace::entering("morpho::dilation");
+ metal::has_neighborhood<I>::check();
+
mln_precondition(exact(output).domain() == exact(input).domain());
- // Ensure the image has a `neighb' typedef.
typedef mln_neighb(I) neighb;
- // FIXME: Encapsulate this in a class + a macro.
- // FIXME: Do we have better concept checking tools?
- {
- // Ensure the image has a `neighb' method.
- neighb (I::*m)() const = &I::neighb;
- m = 0;
-
- // FIXME: Do we need to check for more?
- }
-
- impl::dilation_wrt_nbh(input, output);
+ impl::dilation_wrt_nbh(input, exact(input).neighborhood(), output);
trace::exiting("morpho::dilation");
}
Index: tests/morpho/dilation.cc
--- tests/morpho/dilation.cc (revision 1687)
+++ tests/morpho/dilation.cc (working copy)
@@ -51,6 +51,9 @@
#include <mln/convert/to_p_array.hh>
#include <mln/convert/to_window.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/neighb/image.hh>
+
#include "tests/data.hh"
@@ -70,23 +73,30 @@
io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
{
- // FIXME: This struct. elt. is far too big for a routinely run
- // test; either use a smaller one or qualify this test as
- // ``long''.
- win::rectangle2d rec(21, 21);
+ win::rectangle2d rec(5, 3);
image2d<int_u8> out(lena.domain());
morpho::dilation(lena, rec, out);
io::pgm::save(out, "out1.pgm");
}
{
- win::octagon2d oct(6);
+ win::octagon2d oct(7);
image2d<int_u8> out(lena.domain());
morpho::dilation(lena, oct, out);
io::pgm::save(out, "out2.pgm");
}
- // FIXME: Add tests using neighborhoods, too.
+ {
+ image2d<int_u8> out(lena.domain());
+ morpho::dilation(lena + c4(), out);
+ io::pgm::save(out, "out3.pgm");
+ }
+
+ {
+ image2d<int_u8> out(lena.domain());
+ morpho::dilation(lena + c8(), out);
+ io::pgm::save(out, "out4.pgm");
+ }
// {
// p_array<point2d> vec = convert::to_p_array(rec, point2d::zero);
@@ -95,7 +105,7 @@
// image2d<int_u8> out(lena.domain());
// level::ero(lena, win, out);
// morpho::dilation(lena, win, out);
-// io::pgm::save(out, "out.pgm");
+// io::pgm::save(out, "out5.pgm");
// }
// {
@@ -107,7 +117,7 @@
// image2d<int_u8>::fwd_piter p(lena.domain());
// for_all(p)
// test(p) = out(p) ? 255 : 0;
-// io::pgm::save(test, "test.pgm");
+// io::pgm::save(test, "out6.pgm");
// }
}
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a morpher adding a neighborhood to an image.
* mln/neighb/image.hh: New.
Provide a morpher adding a neighborhood to an image.
* mln/neighb/get.hh: New.
Get the neighborhood from an image with neighborhood.
* mln/metal/has_neighborhood.hh: New.
Provide a static assertion `has_neighborhood' for images.
* mln/tag/skeleton.hh (mln::tag::neighb_): New tag.
* mln/trait/ch_value.hh
(trait::impl::ch_value_< M< tag::image_<I>, tag::neighb_<N> >, V >):
New specialization for mln::neighb::image<I, N>.
* tests/Makefile.am (SUBDIRS): Add neighb.
* tests/neighb/Makefile.am: New.
* tests/neighb/image.cc: New.
Exercize mln/neighb/images.cc and mln/neighb/get.cc.
mln/metal/has_neighborhood.hh | 53 +++++++++++
mln/neighb/get.hh | 194 ++++++++++++++++++++++++++++++++++++++++++
mln/neighb/image.hh | 191 +++++++++++++++++++++++++++++++++++++++++
mln/tag/skeleton.hh | 3
mln/trait/ch_value.hh | 10 +-
tests/Makefile.am | 1
tests/neighb/Makefile.am | 10 ++
tests/neighb/image.cc | 59 ++++++++++++
8 files changed, 519 insertions(+), 2 deletions(-)
Index: mln/neighb/image.hh
--- mln/neighb/image.hh (revision 0)
+++ mln/neighb/image.hh (revision 0)
@@ -0,0 +1,191 @@
+// Copyright (C) 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_NEIGHB_IMAGE_HH
+# define MLN_NEIGHB_IMAGE_HH
+
+/// \file mln/neighb/image.hh
+/// \brief An image morpher adding a neighborhood to an image.
+
+# include <mln/core/internal/image_identity.hh>
+# include <mln/core/concept/neighborhood.hh>
+
+
+namespace mln
+{
+
+ // Fwd decl.
+ namespace neighb { template <typename I, typename N> struct image; }
+
+ /// Create an image with a neighborhood from an image and a
+ /// neighborhood.
+ template <typename I, typename N>
+ neighb::image<I, N>
+ operator+ (Image<I>& ima, const Neighborhood<N>& nbh);
+
+
+ namespace internal
+ {
+
+ /// \internal Data structure for mln::neighb::image
+ template <typename I, typename N>
+ struct data_< mln::neighb::image<I, N> >
+ {
+ data_(I& ima, const N& nbh);
+
+ I ima_;
+ N nbh_;
+ };
+
+ } // end of namespace mln::internal
+
+
+
+ namespace trait
+ {
+
+ template <typename I, typename N>
+ struct image_< neighb::image<I, N> >
+ : public default_image_morpher_< I, mln_value(I), neighb::image<I, N> >
+
+ {
+ typedef trait::image::category::morpher category;
+
+ typedef trait::image::neighb::some neighb;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace neighb
+ {
+ /// \brief A class that embodies an image with an attached
+ /// neighborhood.
+ ///
+ /// Parameter \c I is the actual type of the image, and \c N is
+ /// the one of the neighborhood.
+ ///
+ /// \pre The domains of \c I and \c N must be compatible.
+ template <typename I, typename N>
+ struct image
+ : public internal::image_identity_ < I, mln_pset(I), image <I, N> >
+ {
+ /// Point_Site associated type.
+ typedef mln_psite(I) psite;
+
+ /// Point_Set associated type.
+ typedef mln_pset(I) pset;
+
+ /// Neighborhood associated type.
+ typedef N neighb;
+
+ /// Skeleton.
+ typedef image< tag::image_<I>, tag::neighb_<N> > skeleton;
+
+ /// Constructor.
+ image(Image<I>& ima, const Neighborhood<N>& nbh);
+
+ /// Test if this image has been initialized.
+ bool has_data() const;
+
+ /// Return the neighborhood associated to this image.
+ const neighb& neighborhood() const;
+ };
+
+ } // end of namespace mln::neighb
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*------------.
+ | operator+. |
+ `------------*/
+
+ template <typename I, typename N>
+ neighb::image<I, N>
+ operator+ (Image<I>& ima, const Neighborhood<N>& nbh)
+ {
+ neighb::image<I, N> tmp(ima, nbh);
+ return tmp;
+ }
+
+ /*--------------------------------------.
+ | internal::data_< cast_image_<T,I> >. |
+ `--------------------------------------*/
+
+ namespace internal
+ {
+ template <typename I, typename N>
+ inline
+ data_< neighb::image<I, N> >::data_(I& ima, const N& nbh)
+ : ima_(ima),
+ nbh_(nbh)
+ {
+ }
+ }
+
+ /*----------------------.
+ | neighb::image<I, N>. |
+ `----------------------*/
+
+ namespace neighb
+ {
+
+ template <typename I, typename N>
+ inline
+ image<I, N>::image(Image<I>& ima, const Neighborhood<N>& nbh)
+ {
+ this->data_ =
+ new mln::internal::data_< mln::neighb::image<I, N> >(exact(ima),
+ exact(nbh));
+ }
+
+ template <typename I, typename N>
+ inline
+ bool
+ image<I, N>::has_data() const
+ {
+ return this->delegatee_()->has_data();
+ }
+
+ template <typename I, typename N>
+ inline
+ const N&
+ image<I, N>::neighborhood() const
+ {
+ return this->data_->nbh_;
+ }
+
+ } // end of namespace mln::neighb
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#include <mln/neighb/get.hh>
+
+#endif // ! MLN_NEIGHB_IMAGE_HH
Index: mln/neighb/get.hh
--- mln/neighb/get.hh (revision 0)
+++ mln/neighb/get.hh (revision 0)
@@ -0,0 +1,194 @@
+// Copyright (C) 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_NEIGHB_GET_HH
+# define MLN_NEIGHB_GET_HH
+
+/// \file mln/neighb/get.hh
+/// \brief Define function that returns the neighborhood assocoatied
+/// to an image.
+
+# include <mln/trait/images.hh>
+# include <mln/neighb/image.hh>
+
+
+/// Shortcuts to access the neighborhood type associated to I.
+/// \{
+# define mln_neighb(T) typename mln::neighb::get_helper<I>::type
+# define mln_neighb_(T) mln::neighb::get_helper<I>::type
+/// \}
+
+
+namespace mln
+{
+
+ namespace neighb
+ {
+
+ // Fwd decl.
+ template <typename I>
+ struct get_helper;
+
+ template <typename I>
+ typename get_helper<I>::type
+ get(const Image<I>& ima);
+
+
+ /// FIXME: Move this to mln/trait/neighb.hh? And split
+ /// neighborhood type deduction from neighborhood access (fun)?
+
+ /// Get the (possible) neighborhood type associated to an image
+ /// type \c I.
+ template <typename I>
+ struct get_helper
+ {
+ /// Select the neighborhood from the presence of the
+ /// neighborhood and the category of the image.
+ /// {
+
+ // FIXME: Rename select_from_traits.
+
+ template <typename image_neighb, typename image_category, typename I_>
+ struct select_from_traits;
+
+ /// Case where the image has a neighborhood and is a primary
+ /// image.
+ template <typename I_>
+ struct select_from_traits<trait::image::neighb::some,
+ trait::image::category::primary,
+ I_>
+ {
+ typedef typename I_::neighb type;
+
+ static const type&
+ run(const I_& ima) { return ima.neighborhood(); }
+ };
+
+ /// Special case: neighb::image<I_, N_>.
+ template <typename I_, typename N_>
+ struct select_from_traits<trait::image::neighb::some,
+ trait::image::category::morpher,
+ mln::neighb::image<I_, N_> >
+ {
+ typedef typename neighb::image<I_, N_>::neighb type;
+
+ static const type&
+ run(const neighb::image<I_, N_>& ima) { return ima.neighborhood(); }
+ };
+
+ /// Case where the image has a neighborhood and is a morpher.
+ template <typename I_>
+ struct select_from_traits<trait::image::neighb::some,
+ trait::image::category::morpher,
+ I_>
+ {
+ typedef typename get_helper<typename I_::delegatee>::type type;
+
+ static const type&
+ run(const I_& ima) { return neighb::get( *ima.delegatee_() ); }
+ };
+
+ /// Case where the image has a neighborhood and is a identity morpher.
+ template <typename I_>
+ struct select_from_traits<trait::image::neighb::some,
+ trait::image::category::identity_morpher,
+ I_>
+ {
+ typedef typename get_helper<typename I_::delegatee>::type type;
+
+ static const type&
+ run(const I_& ima) { return neighb::get( *ima.delegatee_() ); }
+ };
+
+ /// Case where the image has a neighborhood and is a value morpher.
+ template <typename I_>
+ struct select_from_traits<trait::image::neighb::some,
+ trait::image::category::value_morpher,
+ I_>
+ {
+ typedef typename get_helper<typename I_::delegatee>::type type;
+
+ static const type&
+ run(const I_& ima) { return neighb::get( *ima.delegatee_() ); }
+ };
+
+ /// \brief Default case: error.
+ ///
+ /// Causes:
+ /// \li the image has no neighborhood;
+ /// \li the image category is of an invalid morpher type (e.g.,
+ /// a domain morpher);
+ /// \li the trait for the neighborhood of the image is not
+ /// defined or ill-defined;
+ /// \li the trait for the image category is not defined or
+ /// ill-defined.
+ template <typename image_neighb, typename image_category, typename I_>
+ struct select_from_traits
+ {
+ /// Nothing.
+ };
+
+ /// \}
+
+ typedef select_from_traits< mln_trait_image_neighb(I),
+ mln_trait_image_category(I),
+ I > selection_;
+
+ typedef typename selection_::type type;
+
+ static const type& run(const I& ima) { return selection_::run(ima); }
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Facade.
+
+ template <typename I>
+ inline
+ typename get_helper<I>::type
+ get(const Image<I>& ima)
+ {
+ trace::entering("neighb::get");
+
+ mln_precondition(exact(ima).has_data());
+ typename neighb::get_helper<I>::type res =
+ neighb::get_helper<I>::run(exact(ima));
+
+ trace::exiting("neighb::get");
+ return res;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::neighb
+
+} // end of namespace mln
+
+
+#endif // ! MLN_NEIGHB_GET_HH
Index: mln/metal/has_neighborhood.hh
--- mln/metal/has_neighborhood.hh (revision 0)
+++ mln/metal/has_neighborhood.hh (revision 0)
@@ -0,0 +1,53 @@
+// Copyright (C) 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_METAL_HAS_NEIGHBORHOOD_HH
+# define MLN_METAL_HAS_NEIGHBORHOOD_HH
+
+# include <mln/neighb/get.hh>
+
+namespace mln
+{
+
+ namespace metal
+ {
+
+ template <typename I>
+ struct has_neighborhood
+ {
+ static void check()
+ {
+ // Ensure the image has a `neighb' property.
+ typedef mln_neighb(I) neighb;
+ }
+ };
+
+ } // end of namespace mln::metal
+
+} // end of namespace mln
+
+#endif // ! MLN_METAL_HAS_NEIGHBORHOOD_HH
Index: mln/tag/skeleton.hh
--- mln/tag/skeleton.hh (revision 1685)
+++ mln/tag/skeleton.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
@@ -48,6 +48,7 @@
template <typename S> struct pset_ { typedef S param; };
template <typename D> struct data_ { typedef D param; };
template <typename F> struct function_ { typedef F param; };
+ template <typename N> struct neighb_ { typedef N param; };
// With value.
template <unsigned u> struct unsigned_ { enum { value = u }; };
Index: mln/trait/ch_value.hh
--- mln/trait/ch_value.hh (revision 1685)
+++ mln/trait/ch_value.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
@@ -109,6 +109,14 @@
typedef mln_ch_value(I, V) ret;
};
+ // For mln::neighb::image<I, N>.
+ template < template <class, class> class M, typename I, typename N,
+ typename V >
+ struct ch_value_< M< tag::image_<I>, tag::neighb_<N> >, V >
+ {
+ typedef M < mln_ch_value(I, V), N > ret;
+ };
+
template < template <class, class> class M, typename I, typename S,
typename V >
struct ch_value_< M< tag::image_<I>, tag::pset_<S> >, V >
Index: tests/Makefile.am
--- tests/Makefile.am (revision 1685)
+++ tests/Makefile.am (working copy)
@@ -18,6 +18,7 @@
level \
logical \
morpho \
+ neighb \
norm \
set \
util \
Index: tests/neighb/image.cc
--- tests/neighb/image.cc (revision 0)
+++ tests/neighb/image.cc (revision 0)
@@ -0,0 +1,59 @@
+// Copyright (C) 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.
+
+/*! \file tests/neighb/image.cc
+ *
+ * \brief Tests on mln::neighb::image.
+ */
+
+#include <mln/neighb/image.hh>
+#include <mln/core/image2d.hh>
+#include <mln/core/neighb2d.hh>
+#include <mln/metal/has_neighborhood.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<int> ima_t;
+ typedef neighb2d nbh_t;
+
+ typedef neighb::image<ima_t, nbh_t> ima_with_nbh_t;
+
+ metal::has_neighborhood<ima_with_nbh_t>::check();
+
+ ima_t ima (make::box2d(5, 5));
+
+ // Explicit construction.
+ ima_with_nbh_t ima1 (ima, c4());
+ neighb::get(ima1);
+
+ // Construction using operator+.
+ ima_with_nbh_t ima2 = ima + c4();
+ neighb::get(ima2);
+}
Index: tests/neighb/Makefile.am
--- tests/neighb/Makefile.am (revision 0)
+++ tests/neighb/Makefile.am (revision 0)
@@ -0,0 +1,10 @@
+## Process this file through Automake to create Makefile.in -*- Makefile -*-
+
+include $(top_srcdir)/milena/tests/tests.mk
+
+check_PROGRAMS = \
+ image
+
+image_SOURCES = image.cc
+
+TESTS = $(check_PROGRAMS)
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2008-01-25 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
Add a replace routine.
* mln/level/replace.hh: New, the routine replace a value by another
one in an image.
* tests/level/replace.cc: New, a little test.
---
mln/level/replace.hh | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
tests/level/replace.cc | 63 +++++++++++++++++++++++++++++
2 files changed, 168 insertions(+)
Index: trunk/milena/tests/level/replace.cc
===================================================================
--- trunk/milena/tests/level/replace.cc (revision 0)
+++ trunk/milena/tests/level/replace.cc (revision 1683)
@@ -0,0 +1,63 @@
+// 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.
+
+/*! \file tests/level/replace.cc
+ *
+ * \brief Tests on mln::level::replace.
+ */
+
+#include <mln/core/image2d.hh>
+#include <mln/level/replace.hh>
+#include <mln/level/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+
+ int vs[3][3] = {
+
+ { 10, 3, 4 },
+ { 5, 10, 7 },
+ { 8, 9, 10 },
+
+ };
+
+ image2d<int> rhs = make::image2d(vs);
+
+ level::replace(rhs, 10, 11);
+
+ int vs_ref[3][3] = {
+
+ { 11, 3, 4 },
+ { 5, 11, 7 },
+ { 8, 9, 11 },
+ };
+
+ mln_assertion(make::image2d(vs_ref) == rhs);
+
+}
Index: trunk/milena/mln/level/replace.hh
===================================================================
--- trunk/milena/mln/level/replace.hh (revision 0)
+++ trunk/milena/mln/level/replace.hh (revision 1683)
@@ -0,0 +1,105 @@
+// Copyright (C) 2007, 2008 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_LEVEL_REPLACE_HH
+# define MLN_LEVEL_REPLACE_HH
+
+/*! \file mln/level/replace.hh
+ *
+ * \brief Replace the contents of an image into another one.
+ *
+ */
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/image_if.hh>
+
+# include <mln/level/fill.hh>
+# include <mln/pw/value.hh>
+# include <mln/pw/cst.hh>
+
+namespace mln
+{
+
+ namespace level
+ {
+
+ /*! Replace \p old_value by \p new_value in the image \p input
+ *
+ * \param[in] input The input image.
+ * \param[in] old_value The value to be replaced...
+ * \param[in] new_value ...by this one.
+ *
+ */
+ template <typename I>
+ void replace(Image<I>& input, const mln_value(I)& old_value,
+ const mln_value(I)& new_value);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I>
+ inline
+ void replace_(Image<I>& input_, const mln_value(I)& old_value,
+ const mln_value(I)& new_value)
+ {
+ trace::entering("level::impl::generic::replace");
+ level::fill(inplace(exact(input_) | pw::value(input_) == pw::cst(old_value)), new_value);
+ trace::exiting("level::impl::generic::replace");
+ }
+
+ } // end of namespace mln::level::impl::generic
+
+ } // end of namespace mln::level::impl
+
+
+ // Facade.
+ template <typename I>
+ void replace(Image<I>& input, const mln_value(I)& old_value,
+ const mln_value(I)& new_value)
+ {
+ trace::entering("level::replace");
+
+ mln_precondition(exact(input).has_data());
+
+ impl::generic::replace_<I>(exact(input), old_value, new_value);
+ trace::exiting("level::replace");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::level
+
+} // end of namespace mln
+
+
+#endif // ! MLN_LEVEL_REPLACE_HH