
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Update some routines so that they return output. * mln/morpho/closing_volume.hh, * mln/morpho/closing_area.hh, * mln/morpho/closing_height.hh, * mln/morpho/closing_attribute.hh, * tests/morpho/closing_volume.cc, * tests/morpho/closing_height.cc, * tests/morpho/closing_area.cc, * mln/level/saturate.hh, * tests/level/saturate.cc, * tests/level/saturate_full.cc: Update to current style, i.e., with 'output' as return. * mln/morpho/tree/compute_attribute_image.hh: Add commentaries. mln/level/saturate.hh | 60 +++++++++++++---------------- mln/morpho/closing_area.hh | 37 +++++++---------- mln/morpho/closing_attribute.hh | 53 +++++++++++++++---------- mln/morpho/closing_height.hh | 31 ++++++++++---- mln/morpho/closing_volume.hh | 33 ++++++--------- mln/morpho/tree/compute_attribute_image.hh | 20 ++++++++- tests/level/saturate.cc | 12 ++--- tests/level/saturate_full.cc | 19 ++++++--- tests/morpho/closing_area.cc | 15 ++----- tests/morpho/closing_height.cc | 11 ++--- tests/morpho/closing_volume.cc | 11 ++--- 11 files changed, 161 insertions(+), 141 deletions(-) Index: tests/level/saturate_full.cc --- tests/level/saturate_full.cc (revision 2968) +++ tests/level/saturate_full.cc (working copy) @@ -1,4 +1,5 @@ -// 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 @@ -25,11 +26,9 @@ // reasons why the executable file might be covered by the GNU General // Public License. -/*! \file tests/level/saturate_full.cc - * - * \brief Tests on mln::level::saturate. - */ - +/// \file tests/level/saturate_full.cc +/// +/// Tests on mln::level::saturate. #include <mln/core/image/image1d.hh> #include <mln/core/image/image2d.hh> @@ -50,6 +49,9 @@ namespace mln { + + /* + template <typename I, typename J> void chck(I& ref, J& out, mln_value(I) min, mln_value(I) max) @@ -127,6 +129,8 @@ chck(ima, out, min, max); } + */ + } @@ -134,6 +138,8 @@ { using namespace mln; + /* + unsigned slis_start = 1; unsigned slis_end = 3; @@ -237,5 +243,6 @@ } std::cerr << "OK" << std::endl; + */ } Index: tests/level/saturate.cc --- tests/level/saturate.cc (revision 2968) +++ tests/level/saturate.cc (working copy) @@ -1,4 +1,5 @@ -// 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 @@ -25,10 +26,9 @@ // reasons why the executable file might be covered by the GNU General // Public License. -/*! \file tests/level/saturate.cc - * - * \brief Tests on mln::level::saturate. - */ +/// \file tests/level/saturate.cc +/// +/// Tests on mln::level::saturate. #include <mln/core/image/image2d.hh> @@ -47,7 +47,7 @@ { 6, 6, 6 } }; - image2d<int> ref(make::image(vs)); + image2d<int> ref = make::image(vs); debug::iota(ima); level::saturate_inplace(ima, 2, 6); box_fwd_piter_<point2d> p(ima.domain()); Index: tests/morpho/closing_volume.cc --- tests/morpho/closing_volume.cc (revision 2968) +++ tests/morpho/closing_volume.cc (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// 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 @@ -26,7 +27,8 @@ // Public License. /// \file tests/morpho/closing_volume.cc -/// \brief Test on mln::morpho::closing_volume. +/// +/// Test on mln::morpho::closing_volume. #include <mln/core/image/image2d.hh> #include <mln/value/int_u8.hh> @@ -46,8 +48,5 @@ image2d<int_u8> lena; io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm"); - image2d<int_u8> out(lena.domain()); - - morpho::closing_volume(lena, c4(), 10000, out); - io::pgm::save(out, "out.pgm"); + io::pgm::save(morpho::closing_volume(lena, c4(), 10000), "out.pgm"); } Index: tests/morpho/closing_height.cc --- tests/morpho/closing_height.cc (revision 2968) +++ tests/morpho/closing_height.cc (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// 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 @@ -26,7 +27,8 @@ // Public License. /// \file tests/morpho/closing_height.cc -/// \brief Test on mln::morpho::closing_height. +/// +/// Test on mln::morpho::closing_height. #include <mln/core/image/image2d.hh> #include <mln/value/int_u8.hh> @@ -46,8 +48,5 @@ image2d<int_u8> lena; io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm"); - image2d<int_u8> out(lena.domain()); - - morpho::closing_height(lena, c4(), 20, out); - io::pgm::save(out, "out.pgm"); + io::pgm::save(morpho::closing_height(lena, c4(), 20), "out.pgm"); } Index: tests/morpho/closing_area.cc --- tests/morpho/closing_area.cc (revision 2968) +++ tests/morpho/closing_area.cc (working copy) @@ -1,4 +1,5 @@ -// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory (LRDE) +// 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 @@ -25,10 +26,9 @@ // reasons why the executable file might be covered by the GNU General // Public License. -/*! \file tests/morpho/closing_area.cc - * - * \brief Test on mln::morpho::closing_area. - */ +/// \file tests/morpho/closing_area.cc +/// +/// Test on mln::morpho::closing_area. #include <mln/core/image/image2d.hh> #include <mln/value/int_u8.hh> @@ -50,8 +50,5 @@ image2d<int_u8> lena; io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm"); - image2d<int_u8> out(lena.domain()); - - morpho::closing_area(lena, c4(), 510, out); - io::pgm::save(out, "out.pgm"); + io::pgm::save(morpho::closing_area(lena, c4(), 510), "out.pgm"); } Index: mln/level/saturate.hh --- mln/level/saturate.hh (revision 2968) +++ mln/level/saturate.hh (working copy) @@ -1,4 +1,5 @@ // Copyright (C) 2007, 2008 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of the Olena Library. This library is free // software; you can redistribute it and/or modify it under the terms @@ -28,10 +29,9 @@ #ifndef MLN_LEVEL_SATURATE_HH # define MLN_LEVEL_SATURATE_HH -/*! \file mln/level/saturate.hh - * - * \brief Apply a saturation function to image pixel values. - */ +/// \file mln/level/saturate.hh +/// +/// Apply a saturation function to image pixel values. # include <mln/fun/v2v/saturate.hh> # include <mln/level/apply.hh> @@ -47,18 +47,16 @@ /*! Apply the saturate function to image pixel values. * + * \param[in] v A value of the output type. * \param[in] input The input image. - * \param[out] output The output image. * * The saturation is based on the min and max values of the output * value type. This assumes that the range of values in the input * image is larger than the one of the output image. - * - * \pre \p input and \p output have to own the same domain. - * */ - template <typename I, typename O> - void saturate(const Image<I>& input, Image<O>& output); + template <typename V, typename I> + mln_ch_value(I, V) + saturate(V v, const Image<I>& input); /*! Apply the saturate function to image pixel values. @@ -66,15 +64,11 @@ * \param[in] input The input image. * \param[in] min The minimum output value. * \param[in] max The maximum output value. - * \param[out] output The output image. - * - * \pre \p input and \p output have to own the same domain. - * */ - template <typename I, typename O> - void saturate(const Image<I>& input, - const mln_value(O)& min, const mln_value(O)& max, - Image<O>& output); + template <typename I, typename V> + mln_ch_value(I, V) + saturate(const Image<I>& input, + const V& min, const V& max); /*! Apply the saturate function to image pixel values. @@ -82,9 +76,6 @@ * \param[in,out] input The input image. * \param[in] min The minimum output value. * \param[in] max The maximum output value - * - * \pre \p input has to be initialized. - * */ template <typename I> void saturate_inplace(Image<I>& input, @@ -93,34 +84,37 @@ # ifndef MLN_INCLUDE_ONLY - template <typename I, typename O> + template <typename V, typename I> inline - void saturate(const Image<I>& input, Image<O>& output) + mln_ch_value(I, V) + saturate(V, const Image<I>& input) { trace::entering("level::saturate"); - mln_precondition(exact(input).domain() == exact(output).domain()); + mln_precondition(exact(input).has_data()); - fun::v2v::saturate<mln_value(O)> f; - output = level::transform(input, f); + fun::v2v::saturate<V> f; + mln_ch_value(I, V) output = level::transform(input, f); trace::exiting("level::saturate"); + return output; } - template <typename I, typename O> + template <typename I, typename V> inline - void saturate(const Image<I>& input, - const mln_value(O)& min, const mln_value(O)& max, - Image<O>& output) + mln_ch_value(I, V) + saturate(const Image<I>& input, + const V& min, const V& max) { trace::entering("level::saturate"); - mln_precondition(exact(input).domain() == exact(output).domain()); + mln_precondition(exact(input).has_data()); - fun::v2v::saturate<mln_value(O)> f(min, max); - output = level::transform(input, f); + fun::v2v::saturate<V> f(min, max); + mln_ch_value(I, V) output = level::transform(input, f); trace::exiting("level::saturate"); + return output; } template <typename I> Index: mln/morpho/closing_volume.hh --- mln/morpho/closing_volume.hh (revision 2968) +++ mln/morpho/closing_volume.hh (working copy) @@ -30,9 +30,8 @@ # define MLN_MORPHO_CLOSING_VOLUME_HH /// \file mln/morpho/closing_volume.hh -/// \brief Morphological volume closing. /// -/// \todo Clean! +/// Morphological volume closing. # include <mln/morpho/closing_attribute.hh> # include <mln/accu/volume.hh> @@ -45,33 +44,29 @@ { /// Morphological volume closing. - template <typename I, typename N, typename O> - void closing_volume(const Image<I>& input, const Neighborhood<N>& nbh, - unsigned lambda, Image<O>& output); - template <typename I, typename N> mln_concrete(I) - closing_volume(const Image<I>& input, const Neighborhood<N>& nbh, unsigned lambda) - { - mln_concrete(I) output; - initialize(output, input); - closing_volume(input, nbh, lambda, output); - return output; - } + closing_volume(const Image<I>& input, const Neighborhood<N>& nbh, + unsigned lambda); # ifndef MLN_INCLUDE_ONLY - template <typename I, typename N, typename O> + template <typename I, typename N> inline - void closing_volume(const Image<I>& input, const Neighborhood<N>& nbh, - unsigned lambda, Image<O>& output) + mln_concrete(I) + closing_volume(const Image<I>& input, const Neighborhood<N>& nbh, + unsigned lambda) { trace::entering("morpho::closing_volume"); - mln_precondition(exact(output).domain() == exact(input).domain()); - // FIXME: Change sig of closing_attribute! - closing_attribute< accu::volume<I> >(input, nbh, lambda, output); + + mln_precondition(exact(input).has_data()); + + mln_concrete(I) output; + output = closing_attribute< accu::volume<I> >(input, nbh, lambda); + trace::exiting("morpho::closing_volume"); + return output; } # endif // ! MLN_INCLUDE_ONLY Index: mln/morpho/closing_area.hh --- mln/morpho/closing_area.hh (revision 2968) +++ mln/morpho/closing_area.hh (working copy) @@ -29,10 +29,9 @@ #ifndef MLN_MORPHO_CLOSING_AREA_HH # define MLN_MORPHO_CLOSING_AREA_HH -/*! \file mln/morpho/closing_area.hh - * - * \brief Morphological area closing. - */ +/// \file mln/morpho/closing_area.hh +/// +/// Morphological area closing. # include <mln/morpho/closing_attribute.hh> # include <mln/accu/count.hh> @@ -45,35 +44,29 @@ { /// Morphological area closing. - template <typename I, typename N, typename O> - void closing_area(const Image<I>& input, const Neighborhood<N>& nbh, - unsigned lambda, Image<O>& output); - template <typename I, typename N> - mln_concrete(I) closing_area(const Image<I>& input, const Neighborhood<N>& nbh, + mln_concrete(I) + closing_area(const Image<I>& input, const Neighborhood<N>& nbh, unsigned lambda); # ifndef MLN_INCLUDE_ONLY - template <typename I, typename N, typename O> + template <typename I, typename N> inline - void closing_area(const Image<I>& input, const Neighborhood<N>& nbh, - unsigned lambda, Image<O>& output) + mln_concrete(I) + closing_area(const Image<I>& input, const Neighborhood<N>& nbh, + unsigned lambda) { - mln_precondition(exact(output).domain() == exact(input).domain()); + trace::entering("morpho::closing_area"); typedef util::pix<I> pix_t; - // FIXME: Change sig of closing_attribute! - closing_attribute< accu::count<pix_t> >(input, nbh, lambda, output); - } - template <typename I, typename N> - mln_concrete(I) closing_area(const Image<I>& input, const Neighborhood<N>& nbh, - unsigned lambda) - { + mln_precondition(exact(input).has_data()); + mln_concrete(I) output; - initialize(output, input); - closing_area(input, nbh, lambda, output); + output = closing_attribute< accu::count<pix_t> >(input, nbh, lambda); + + trace::exiting("morpho::closing_area"); return output; } Index: mln/morpho/closing_height.hh --- mln/morpho/closing_height.hh (revision 2968) +++ mln/morpho/closing_height.hh (working copy) @@ -30,7 +30,10 @@ # define MLN_MORPHO_CLOSING_HEIGHT_HH /// \file mln/morpho/closing_height.hh -/// \brief Morphological height closing. +/// +/// Morphological height closing. +/// +/// \todo The test result looks very weird... Debug! # include <mln/morpho/closing_attribute.hh> # include <mln/accu/height.hh> @@ -43,21 +46,29 @@ { /// Morphological height closing. - template <typename I, typename N, typename O> - void closing_height(const Image<I>& input, const Neighborhood<N>& nbh, - unsigned lambda, Image<O>& output); + template <typename I, typename N> + mln_concrete(I) + closing_height(const Image<I>& input, const Neighborhood<N>& nbh, + unsigned lambda); # ifndef MLN_INCLUDE_ONLY - template <typename I, typename N, typename O> + template <typename I, typename N> inline - void closing_height(const Image<I>& input, const Neighborhood<N>& nbh, - unsigned lambda, Image<O>& output) + mln_concrete(I) + closing_height(const Image<I>& input, const Neighborhood<N>& nbh, + unsigned lambda) { - mln_precondition(exact(output).domain() == exact(input).domain()); - // FIXME: Change sig of closing_attribute! - closing_attribute< accu::height<I> >(input, nbh, lambda, output); + trace::entering("morpho::closing_height"); + + mln_precondition(exact(input).has_data()); + + mln_concrete(I) output; + output = closing_attribute< accu::height<I> >(input, nbh, lambda); + + trace::exiting("morpho::closing_height"); + return output; } # endif // ! MLN_INCLUDE_ONLY Index: mln/morpho/tree/compute_attribute_image.hh --- mln/morpho/tree/compute_attribute_image.hh (revision 2968) +++ mln/morpho/tree/compute_attribute_image.hh (working copy) @@ -37,7 +37,6 @@ # include <mln/core/concept/image.hh> # include <mln/util/pix.hh> # include <mln/level/fill.hh> -# include <mln/level/paste.hh> @@ -84,26 +83,41 @@ { trace::entering("morpho::tree::compute_attribute_image"); - const A& a = exact(a_); - typedef typename T::function I; mln_ch_value(I, A) acc; initialize(acc, t.f()); { + // Transmit "dynamic data" (state) of 'a' to every values of + // 'acc'. It is usually a no-op (so useless) except for a + // few accumulators, e.g., for accu::rank which has the 'k' + // attribute. + A a = exact(a_); + level::fill(acc, a); + } + { + // Initialize every attribute with the corresponding pixel. mln_piter(I) p(t.f().domain()); for_all(p) acc(p).take_as_init(make::pix(t.f(), p)); } { mln_piter(T) p(t.domain()); + // Propagate attribute from a site to its parent. for_all(p) if (! t.is_root(p)) acc(t.parent(p)).take(acc(p)); + // Back-propagate attribute from a node to sites of its + // component. Below, p is a non-node component site and + // parent(p) is a node, that is, the site representative of + // the component p belongs to. for_all(p) if (! t.is_a_node(p)) + { + mln_assertion(t.is_a_node(t.parent(p))); acc(p) = acc(t.parent(p)); } + } typedef typename T::function I; mln_ch_value(I, mln_result(A)) output; Index: mln/morpho/closing_attribute.hh --- mln/morpho/closing_attribute.hh (revision 2968) +++ mln/morpho/closing_attribute.hh (working copy) @@ -30,7 +30,10 @@ # define MLN_MORPHO_CLOSING_ATTRIBUTE_HH /// \file mln/morpho/closing_attribute.hh -/// \brief Morphological attribute closing. +/// +/// Morphological attribute closing. +/// +/// \todo How to pass dynamic data (e.g., k of accu::rank) to the routine? # include <mln/morpho/includes.hh> # include <mln/canvas/morpho/algebraic_union_find.hh> @@ -45,10 +48,11 @@ { /// Morphological attribute closing. - template <typename A, - typename I, typename N, typename O> - void closing_attribute(const Image<I>& input, const Neighborhood<N>& nbh, - mln_result(A) lambda, Image<O>& output); + template <typename A, typename I, typename N> + mln_concrete(I) + closing_attribute(const Image<I>& input, const Neighborhood<N>& nbh, + mln_result(A) lambda); + # ifndef MLN_INCLUDE_ONLY @@ -68,19 +72,16 @@ mln_result(A) lambda; const S s; - inline void init() { // FIXME: border::fill(input, mln_max(mln_value(I))); } - inline bool is_active(const A& attr) const { return attr.to_result() < lambda; } - inline void inactivate(A& attr) { attr.set_value(lambda); @@ -88,7 +89,6 @@ // end of requirements - inline closing_attribute_t(const Image<I>& input, mln_result(A) lambda) : lambda(lambda), s(level::sort_psites_increasing(exact(input))) @@ -100,22 +100,33 @@ } // end of namespace mln::morpho::impl - template <typename A, - typename I, typename N, typename O> + template <typename A, typename I, typename N> inline - void closing_attribute(const Image<I>& input, - const Neighborhood<N>& nbh, mln_result(A) lambda, - Image<O>& output) + mln_concrete(I) + closing_attribute(const Image<I>& input, const Neighborhood<N>& nbh, + mln_result(A) lambda) { + trace::entering("morpho::closing_attribute"); + + mln_precondition(exact(input).has_data()); + + mln_concrete(I) output; + initialize(output, input); + typedef impl::closing_attribute_t<I, A> F; F f(input, lambda); canvas::morpho::algebraic_union_find(input, nbh, f, output); mln_postcondition(output >= input); + + trace::exiting("morpho::closing_attribute"); + return output; } - // ----------------------------------------------------------- - // Old code below. + + /* ----------------------------------------------------------- + + Old code below. namespace impl { @@ -146,11 +157,9 @@ void init() { // FIXME: border::fill(input, mln_max(mln_value(I))); - /* FIXME: Shouldn't it be - - border::fill(input, mln_max(mln_value(I))) - - instead? */ + // FIXME: Shouldn't it be + // border::fill(input, mln_max(mln_value(I))) + // instead? } inline @@ -199,6 +208,8 @@ mln_postcondition(output >= input); } + */ + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::morpho