
https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Augment morphology. * mln/value/cast.hh: Rename as... * mln/core/cast_image.hh: ...this. Update. * mln/core/concept/value.hh (cast): Move to and rename as... * mln/value/cast.hh (cast_image): ...this, here. * tests/cast_image.cc: Update. * mln/morpho/thickening.hh: New. * mln/morpho/laplacian.hh: New. * mln/morpho/thick_miss.hh: New. * mln/morpho/thin_fit.hh: New. * mln/morpho/thinning.hh: New. * tests/morpho_thinning.cc: New. * tests/morpho_laplacian.cc: New. * tests/morpho_hit_or_miss.cc: Update. * mln/morpho/plus.hh (mln_postcondition): Remove. * mln/morpho/minus.hh: Remove dead lines. * mln/morpho/hit_or_miss.hh: Augment doc. Add postconditions. Add a FIXME. * mln/io/save_pgm.hh: Rewrite. * mln/arith/plus.hh (plus_cst, plus_cst_inplace): New. * img/picasso.pgm: Invert. img/picasso.pgm | 0 mln/arith/plus.hh | 31 ++++++++++++++ mln/core/cast_image.hh | 50 +++++++++++------------- mln/core/concept/value.hh | 48 +---------------------- mln/io/save_pgm.hh | 72 +++++++++++++++++++++++++++++++--- mln/morpho/hit_or_miss.hh | 41 +++++++++++++++---- mln/morpho/laplacian.hh | 83 ++++++++++++++++++++++++++++++++++++++++ mln/morpho/minus.hh | 3 - mln/morpho/plus.hh | 3 - mln/morpho/thick_miss.hh | 79 ++++++++++++++++++++++++++++++++++++++ mln/morpho/thickening.hh | 79 ++++++++++++++++++++++++++++++++++++++ mln/morpho/thin_fit.hh | 79 ++++++++++++++++++++++++++++++++++++++ mln/morpho/thinning.hh | 91 ++++++++++++++++++++++++++++++++++++++++++++ tests/cast_image.cc | 6 +- tests/morpho_hit_or_miss.cc | 6 +- tests/morpho_laplacian.cc | 63 ++++++++++++++++++++++++++++++ tests/morpho_thinning.cc | 69 +++++++++++++++++++++++++++++++++ 17 files changed, 705 insertions(+), 98 deletions(-) Index: tests/cast_image.cc --- tests/cast_image.cc (revision 1063) +++ tests/cast_image.cc (working copy) @@ -27,14 +27,14 @@ /*! \file tests/cast_image.cc * - * \brief Tests on mln::value::cast_image. + * \brief Tests on mln::cast_image. */ #include <mln/core/image2d_b.hh> #include <mln/fun/p2b/chess.hh> #include <mln/level/fill.hh> #include <mln/debug/println.hh> -#include <mln/value/cast.hh> +#include <mln/core/cast_image.hh> int main() @@ -44,5 +44,5 @@ image2d_b<bool> ima(8, 8); level::fill(ima, fun::p2b::chess); debug::println(ima); - debug::println( value::cast<int>(ima) ); + debug::println( cast_image<int>(ima) ); } Index: tests/morpho_thinning.cc --- tests/morpho_thinning.cc (revision 0) +++ tests/morpho_thinning.cc (revision 0) @@ -0,0 +1,69 @@ +// 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/morpho_thinning.cc + * + * \brief Test on mln::morpho::thinning. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/value/int_u8.hh> + +#include <mln/core/win/rectangle2d.hh> +#include <mln/core/window2d.hh> + +#include <mln/io/load_pgm.hh> +#include <mln/io/save_pgm.hh> + +#include <mln/morpho/thinning.hh> + + +int main() +{ + using namespace mln; + using value::int_u8; + + bool fg[] = { 0, 0, 0, + 0, 1, 0, + 0, 0, 0 }; + window2d win_fg = make::window2d(fg); + + bool bg[] = { 0, 0, 0, + 1, 0, 1, + 0, 0, 0 }; + window2d win_bg = make::window2d(bg); + + border::thickness = 2; + + image2d_b<int_u8> + pic = io::load_pgm("../img/picasso.pgm"), + out(pic.domain()); + + morpho::thinning(pic, win_fg, win_bg, out); + + io::save_pgm(out, "out.pgm"); +} Index: tests/morpho_hit_or_miss.cc --- tests/morpho_hit_or_miss.cc (revision 1063) +++ tests/morpho_hit_or_miss.cc (working copy) @@ -76,10 +76,10 @@ border::thickness = 2; image2d_b<int_u8> - lena = io::load_pgm("../img/picasso.pgm"), - out(lena.domain()); + pic = io::load_pgm("../img/picasso.pgm"), + out(pic.domain()); - morpho::hit_or_miss(lena, win_hit, win_miss, out); + morpho::hit_or_miss(pic, win_hit, win_miss, out); io::save_pgm(out, "out.pgm"); } Index: tests/morpho_laplacian.cc --- tests/morpho_laplacian.cc (revision 0) +++ tests/morpho_laplacian.cc (revision 0) @@ -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/morpho_laplacian.cc + * + * \brief Test on mln::morpho::laplacian. + */ + +#include <mln/core/image2d_b.hh> +#include <mln/core/win/rectangle2d.hh> + +#include <mln/io/load_pgm.hh> +#include <mln/io/save_pgm.hh> + +#include <mln/value/int_u_sat.hh> +#include <mln/core/cast_image.hh> +#include <mln/pw/image.hh> +#include <mln/arith/plus.hh> + +#include <mln/morpho/laplacian.hh> + + + +int main() +{ + using namespace mln; + using value::int_u8; + + win::rectangle2d rect(5, 5); + border::thickness = 2; + + image2d_b<int_u8> lena = io::load_pgm("../img/tiny.pgm"); + image2d_b<int> lap(lena.domain()); + morpho::laplacian(lena, rect, lap); + + image2d_b< value::int_u_sat<8> > out(lena.domain()); + arith::plus_cst(lap, 128, out); + io::save_pgm(out, "out.pgm"); +} Index: mln/core/cast_image.hh --- mln/core/cast_image.hh (revision 1063) +++ mln/core/cast_image.hh (working copy) @@ -25,29 +25,27 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_VALUE_CAST_HH -# define MLN_VALUE_CAST_HH +#ifndef MLN_CORE_CAST_IMAGE_HH +# define MLN_CORE_CAST_IMAGE_HH -/*! \file mln/value/cast.hh +/*! \file mln/core/cast_image.hh * * \brief Definition of an image class FIXME */ # include <mln/core/concept/image.hh> # include <mln/value/set.hh> +# include <mln/value/cast.hh> namespace mln { - namespace value - { - /*! \brief FIXME * */ template <typename T, typename I> - struct cast_image : public mln::internal::image_base_< mln_pset(I), cast_image<T,I> > + struct cast_image_ : public mln::internal::image_base_< mln_pset(I), cast_image_<T,I> > { /// Point_Site associated type. typedef mln_psite(I) psite; @@ -62,14 +60,14 @@ typedef T rvalue; /// Return type of read-write access. - typedef void lvalue; // FIXME + typedef T lvalue; /// Value set associated type. typedef mln::value::set<T> vset; /// Constructor. - cast_image(const Image<I>& ima); + cast_image_(const Image<I>& ima); /// Test if this image has been initialized. @@ -84,8 +82,8 @@ /// Read-only access of pixel value at point site \p p. T operator()(const psite& p) const; - /// Read-write access is present but disabled. - void operator()(const psite&); + /// Mutable access is only OK for reading (not writing). + T operator()(const psite& p); /// Give the set of values of the image. const vset& values() const; @@ -104,11 +102,11 @@ template <typename T, typename I> - cast_image<T,I> - cast(const Image<I>& ima) + cast_image_<T,I> + cast_image(const Image<I>& ima) { mln_precondition(exact(ima).has_data()); - cast_image<T,I> tmp(ima); + cast_image_<T,I> tmp(ima); return tmp; } @@ -117,59 +115,57 @@ # ifndef MLN_INCLUDE_ONLY template <typename T, typename I> - cast_image<T,I>::cast_image(const Image<I>& ima) + cast_image_<T,I>::cast_image_(const Image<I>& ima) : ima_(exact(ima)) { mln_precondition(exact(ima).has_data()); } template <typename T, typename I> - bool cast_image<T,I>::has_data() const + bool cast_image_<T,I>::has_data() const { mln_invariant(ima_.has_data()); return true; } template <typename T, typename I> - bool cast_image<T,I>::owns_(const psite& p) const + bool cast_image_<T,I>::owns_(const psite& p) const { return ima_.owns_(p); } template <typename T, typename I> const mln_pset(I)& - cast_image<T,I>::domain() const + cast_image_<T,I>::domain() const { return ima_.domain(); } template <typename T, typename I> T - cast_image<T,I>::operator()(const psite& p) const + cast_image_<T,I>::operator()(const psite& p) const { mln_precondition(ima_.owns_(p)); - return ima_(p); + return mln::value::cast<T>( ima_(p) ); } template <typename T, typename I> - void - cast_image<T,I>::operator()(const psite&) + T + cast_image_<T,I>::operator()(const psite& p) { - mln_invariant(0); // FIXME: Turn into a compile-time error... + return mln::value::cast<T>( ima_(p) ); } template <typename T, typename I> const mln::value::set<T>& - cast_image<T,I>::values() const + cast_image_<T,I>::values() const { return vset::the(); } # endif // ! MLN_INCLUDE_ONLY - } // end of namespace mln::value - } // end of namespace mln -#endif // ! MLN_VALUE_CAST_HH +#endif // ! MLN_CORE_CAST_IMAGE_HH Index: mln/core/concept/value.hh --- mln/core/concept/value.hh (revision 1063) +++ mln/core/concept/value.hh (working copy) @@ -63,17 +63,6 @@ - namespace value - { - - /// Cast a value \p src from type \c Src to type \c Dest. - template <typename Dest, typename Src> - Dest cast(const Src& src); - - } // end of namespace mln::value - - - # ifndef MLN_INCLUDE_ONLY template <typename E> @@ -99,43 +88,12 @@ return exact(*this); } - - namespace value - { - - namespace internal - { - - template <typename S> - const S& - cast_(const S& src, ...) - { - return src; - } - - template <typename T, typename S> - typename S::equiv - cast_(const T&, const Value<S>& src) - { - return exact(src); - } - - } // end of namespace mln::value::internal - - - template <typename Dest, typename Src> - Dest cast(const Src& src) - { - return internal::cast_(src, src); - } - - - } // end of namespace mln::value - - # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln +# include <mln/value/cast.hh> + + #endif // ! MLN_CORE_CONCEPT_VALUE_HH Index: mln/morpho/thickening.hh --- mln/morpho/thickening.hh (revision 0) +++ mln/morpho/thickening.hh (revision 0) @@ -0,0 +1,79 @@ +// 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. + +#ifndef MLN_MORPHO_THICKENING_HH +# define MLN_MORPHO_THICKENING_HH + +/*! \file mln/morpho/thickening.hh + * + * \brief Morphological thickening. + */ + +# include <mln/morpho/hit_or_miss.hh> + + +namespace mln +{ + + namespace morpho + { + + + /*! Morphological thickening. + * + * This operator is THICK_B = Id + HMT_B, where B = (Bfg, Bbg). + */ + template <typename I, typename Wfg, typename Wbg, typename O> + void thickening(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename Wfg, typename Wbg, typename O> + void thickening(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + mln_precondition(exact(win_bg).is_centered()); + mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + + O temp(exact(input).domain()); + hit_or_miss(input, win_fg, win_bg, temp); + morpho::plus(input, temp, output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_THICKENING_HH Index: mln/morpho/plus.hh --- mln/morpho/plus.hh (revision 1063) +++ mln/morpho/plus.hh (working copy) @@ -85,10 +85,7 @@ { mln_precondition(exact(rhs).domain() = exact(lhs).domain()); mln_precondition(exact(output).domain() = exact(lhs).domain()); - impl::plus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output); - - mln_postcondition(output <= lhs); } template <typename I, typename J> Index: mln/morpho/laplacian.hh --- mln/morpho/laplacian.hh (revision 0) +++ mln/morpho/laplacian.hh (revision 0) @@ -0,0 +1,83 @@ +// 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. + +#ifndef MLN_MORPHO_LAPLACIAN_HH +# define MLN_MORPHO_LAPLACIAN_HH + +/*! \file mln/morpho/laplacian.hh + * + * \brief Morphological laplacian. + * + * \todo Save memory. + */ + +# include <mln/morpho/includes.hh> + + +namespace mln +{ + + namespace morpho + { + + /*! Morphological laplacian. + * + * This operator is (d_B - Id) - (Id - e_B). + */ + template <typename I, typename W, typename O> + void laplacian(const Image<I>& input, const Window<W>& win, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename W, typename O> + void laplacian(const Image<I>& input, const Window<W>& win, Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + mln_precondition(! exact(win).is_empty()); + + dilation(input, win, output); // output = dilation + morpho::minus_inplace(output, input); // now output = dilation - input + + O temp(exact(input).domain()); + { + O temp_(exact(input).domain()); + erosion(input, win, temp_); // temp_ = erosion + morpho::minus(input, temp_, temp); // temp = input - erosion + } + morpho::minus_inplace(output, temp); // now output = (dilation - input) - (input - erosion) + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_LAPLACIAN_HH Index: mln/morpho/minus.hh --- mln/morpho/minus.hh (revision 1063) +++ mln/morpho/minus.hh (working copy) @@ -64,9 +64,7 @@ const Image<I>& lhs, const Image<J>& rhs, Image<O>& output) { - // FIXME: mln_precondition(rhs <= lhs); return logical::and_not(lhs, rhs, output); - // FIXME: mln_postcondition(output <= lhs); } template <typename K, typename I, typename J, typename O> @@ -87,7 +85,6 @@ { mln_precondition(exact(rhs).domain() = exact(lhs).domain()); mln_precondition(exact(output).domain() = exact(lhs).domain()); - impl::minus_(mln_value_kind(I)(), exact(lhs), exact(rhs), output); } Index: mln/morpho/thick_miss.hh --- mln/morpho/thick_miss.hh (revision 0) +++ mln/morpho/thick_miss.hh (revision 0) @@ -0,0 +1,79 @@ +// 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. + +#ifndef MLN_MORPHO_THICK_MISS_HH +# define MLN_MORPHO_THICK_MISS_HH + +/*! \file mln/morpho/thick_miss.hh + * + * \brief Morphological thick-miss. + */ + +# include <mln/morpho/hit_or_miss.hh> + + +namespace mln +{ + + namespace morpho + { + + + /*! Morphological thick-miss. + * + * This operator is THICK_B = Id + HMTopeBG_B, where B = (Bfg, Bbg). + */ + template <typename I, typename Wfg, typename Wbg, typename O> + void thick_miss(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename Wfg, typename Wbg, typename O> + void thick_miss(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + mln_precondition(exact(win_miss).is_centered()); + mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + + O temp(exact(input).domain()); + hit_or_miss_background_opening(input, win_fg, win_bg, temp); + morpho::plus(input, temp, output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_THICK_MISS_HH Index: mln/morpho/thin_fit.hh --- mln/morpho/thin_fit.hh (revision 0) +++ mln/morpho/thin_fit.hh (revision 0) @@ -0,0 +1,79 @@ +// 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. + +#ifndef MLN_MORPHO_THIN_FIT_HH +# define MLN_MORPHO_THIN_FIT_HH + +/*! \file mln/morpho/thin_fit.hh + * + * \brief Morphological thin-fit. + */ + +# include <mln/morpho/hit_or_miss.hh> + + +namespace mln +{ + + namespace morpho + { + + + /*! Morphological thin-fit. + * + * This operator is THIN_B = Id - HMTope_B where B = (Bfg, Bbg). + */ + template <typename I, typename Wfg, typename Wbg, typename O> + void thin_fit(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename Wfg, typename Wbg, typename O> + void thin_fit(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + mln_precondition(exact(win_fg).is_centered()); + mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + + O temp(exact(input).domain()); + hit_or_miss_opening(input, win_fg, win_bg, temp); + morpho::minus(input, temp, output); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_THIN_FIT_HH Index: mln/morpho/thinning.hh --- mln/morpho/thinning.hh (revision 0) +++ mln/morpho/thinning.hh (revision 0) @@ -0,0 +1,91 @@ +// 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. + +#ifndef MLN_MORPHO_THINNING_HH +# define MLN_MORPHO_THINNING_HH + +/*! \file mln/morpho/thinning.hh + * + * \brief Morphological thinning. + */ + +# include <mln/morpho/hit_or_miss.hh> +# include <mln/morpho/thickening.hh> + + +namespace mln +{ + + namespace morpho + { + + + /*! Morphological thinning. + * + * This operator is THIN_B = Id - HMT_B, where B = (Bfg, Bbg). + */ + template <typename I, typename Wfg, typename Wbg, typename O> + void thinning(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output); + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I, typename Wfg, typename Wbg, typename O> + void thinning(const Image<I>& input, + const Window<Wfg>& win_fg, const Window<Wbg>& win_bg, + Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + mln_precondition(exact(win_fg).is_centered()); + mln_precondition(set::inter(exact(win_fg), exact(win_bg)).is_empty()); + + O temp(exact(input).domain()); + hit_or_miss(input, win_fg, win_bg, temp); + morpho::minus(input, temp, output); + // FIXME: Pass postcondition! +# ifndef NDEBUG + { + O temp(exact(input).domain()); + complementation(input, temp); + O output_(exact(input).domain()); + thickening(temp, win_bg, win_fg, output_); + complementation_inplace(output_); + mln_postcondition(output_ = output); + } +# endif // ! NDEBUG + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::morpho + +} // end of namespace mln + + +#endif // ! MLN_MORPHO_THINNING_HH Index: mln/morpho/hit_or_miss.hh --- mln/morpho/hit_or_miss.hh (revision 1063) +++ mln/morpho/hit_or_miss.hh (working copy) @@ -61,7 +61,7 @@ /*! Morphological hit-or-miss opening. * - * This operator is d_(-Bh) o HMT_(Bh,Bm). + * This operator is HMTope_(Bh,Bm) = d_(-Bh) o HMT_(Bh,Bm). */ template <typename I, typename Wh, typename Wm, typename O> void hit_or_miss_opening(const Image<I>& input, @@ -70,7 +70,7 @@ /*! Morphological hit-or-miss opening of the background. * - * This operator is FIXME. + * This operator is HMTopeBG = HMTope_(Bm,Bh) o C = d_(-Bm) o HMT_(Bh,Bm). */ template <typename I, typename Wh, typename Wm, typename O> void hit_or_miss_background_opening(const Image<I>& input, @@ -79,7 +79,7 @@ /*! Morphological hit-or-miss closing. * - * This operator is FIXME. + * This operator is C o HMTope o C. */ template <typename I, typename Wh, typename Wm, typename O> void hit_or_miss_closing(const Image<I>& input, @@ -88,7 +88,7 @@ /*! Morphological hit-or-miss closing of the background. * - * This operator is FIXME. + * This operator is C o HMTopeBG o C. */ template <typename I, typename Wh, typename Wm, typename O> void hit_or_miss_background_closing(const Image<I>& input, @@ -150,7 +150,8 @@ erosion(input, win_hit, ero_fg); dilation(input, win_miss, dil_bg); level::fill(output, - fun::p2v::ternary(pw::value(input) = pw::value(ero_fg) && pw::value(dil_bg) < pw::value(input), + fun::p2v::ternary(pw::value(input) = pw::value(ero_fg) + && pw::value(dil_bg) < pw::value(input), pw::value(input) - pw::value(dil_bg), pw::cst(V::zero))); } @@ -160,12 +161,13 @@ erosion(input, win_miss, ero_bg); dilation(input, win_hit, dil_fg); level::fill(output, - fun::p2v::ternary(pw::value(input) = pw::value(dil_fg) && pw::value(ero_bg) > pw::value(input), + fun::p2v::ternary(pw::value(input) = pw::value(dil_fg) + && pw::value(ero_bg) > pw::value(input), pw::value(ero_bg) - pw::value(input), pw::cst(V::zero))); } else - level::fill(output, pw::cst(V::zero)); + level::fill(output, V::zero); } else // Unconstrained: UHMT. { @@ -201,6 +203,7 @@ O temp(exact(input).domain()); hit_or_miss(input, win_hit, win_miss, temp); dilation(temp, geom::sym(win_hit), output); + // FIXME: Postcondition. } template <typename I, typename Wh, typename Wm, typename O> @@ -209,7 +212,18 @@ Image<O>& output) { impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output); - hit_or_miss_opening(input, win_miss, win_hit, output); + O temp(exact(input).domain()); + complementation(input, temp); + hit_or_miss_opening(temp, win_miss, win_hit, output); +# ifndef NDEBUG + { + O temp(exact(input).domain()); + hit_or_miss(input, win_hit, win_miss, temp); + O output_(exact(input).domain()); + dilation(temp, geom::sym(win_miss), output_); + mln_postcondition(output_ = output); + } +# endif // ! NDEBUG } template <typename I, typename Wh, typename Wm, typename O> @@ -222,6 +236,7 @@ complementation(input, temp); hit_or_miss_opening(temp, win_hit, win_miss, output); complementation_inplace(output); + // FIXME: Postcondition. } template <typename I, typename Wh, typename Wm, typename O> @@ -231,6 +246,16 @@ { impl::hit_or_miss_preconditions_(input, win_hit, win_miss, output); hit_or_miss_closing(input, win_miss, win_hit, output); +# ifndef NDEBUG + { + O temp(exact(input).domain()); + complementation(input, temp); + O output_(exact(input).domain()); + hit_or_miss_background_opening(temp, win_hit, win_miss, output_); + complementation_inplace(output_); + mln_postcondition(output_ = output); + } +# endif // ! NDEBUG } # endif // ! MLN_INCLUDE_ONLY Index: mln/io/save_pgm.hh --- mln/io/save_pgm.hh (revision 1063) +++ mln/io/save_pgm.hh (working copy) @@ -32,20 +32,37 @@ # include <iostream> # include <fstream> -# include <mln/core/image2d_b.hh> # include <mln/geom/size2d.hh> -# include <mln/value/int_u8.hh> +# include <mln/metal/equal.hh> +# include <mln/metal/bexpr.hh> namespace mln { + // Fwd decl. + namespace value { + template <unsigned> class int_u; + template <unsigned> class int_u_sat; + } + + namespace io { - void save_pgm(const image2d_b<value::int_u8>& ima, const std::string& filename) + template <typename I> + void save_pgm(const Image<I>& ima, const std::string& filename); + + +# ifndef MLN_INCLUDE_ONLY + + namespace impl + { + + template <typename I> + void save_pgm_header_(const I& ima, const std::string& filename, + std::ofstream& file) { - std::ofstream file(filename.c_str()); if (! file) { std::cerr << "error: cannot open file '" << filename @@ -53,14 +70,22 @@ abort(); } file << "P5" << std::endl; - file << "# olena" << std::endl; + file << "# milena" << std::endl; file << geom::ncols(ima) << ' ' << geom::nrows(ima) << std::endl; file << "255" << std::endl; + } + + template <typename I> + void save_pgm_(const Fast_Image<I>& ima_, const std::string& filename) + { + const I& ima = exact(ima_); + std::ofstream file(filename.c_str()); + save_pgm_header_(ima, filename, file); const int min_row = geom::min_row(ima), max_row = geom::max_row(ima); point2d p; - if (sizeof(value::int_u8) = 1) + if (sizeof(mln_value(I)) = 1) { p.col() = geom::min_col(ima); size_t len = geom::ncols(ima); @@ -82,6 +107,41 @@ } } + template <typename I> + void save_pgm_(const Image<I>& ima_, const std::string& filename) + { + const I& ima = exact(ima_); + std::ofstream file(filename.c_str()); + save_pgm_header_(ima, filename, file); + const int + min_row = geom::min_row(ima), + max_row = geom::max_row(ima), + min_col = geom::min_col(ima), + max_col = geom::max_col(ima); + point2d p; + for (p.row() = min_row; p.row() <= max_row; ++p.row()) + for (p.col() = min_col; p.col() <= max_col; ++p.col()) + { + unsigned char c = ima(p); + file.write((char*)(&c), 1); + } + } + + } // end of namespace mln::io::impl + + + template <typename I> + void save_pgm(const Image<I>& ima, const std::string& filename) + { + mln::metal::or_< + mln::metal::equal<mln_value(I), value::int_u<8> >, + mln::metal::equal<mln_value(I), value::int_u_sat<8> > + >::check(); + impl::save_pgm_(exact(ima), filename); + } + +# endif // ! MLN_INCLUDE_ONLY + } // end of namespace mln::io } // end of namespace mln Index: mln/arith/plus.hh --- mln/arith/plus.hh (revision 1063) +++ mln/arith/plus.hh (working copy) @@ -31,10 +31,15 @@ /*! \file mln/arith/plus.hh * * \brief Point-wise addition between images. + * + * \todo Speedup versions with cst. */ # include <mln/core/concept/image.hh> +# include <mln/pw/cst.hh> +# include <mln/pw/image.hh> + namespace mln { @@ -54,6 +59,18 @@ void plus(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output); + /*! Point-wise addition of the value \p val to image \p input. + * + * \param[in] input The image. + * \param[in] val The value. + * \param[out] output The result image. + * + * \pre \p output.domain = \p input.domain + */ + template <typename I, typename V, typename O> + void plus_cst(const Image<I>& input, const V& val, Image<O>& output); + + /*! Point-wise addition of image \p rhs in image \p lhs. * * \param[in] lhs First operand image (subject to addition). @@ -127,6 +144,13 @@ impl::plus_(exact(lhs), exact(rhs), exact(output)); } + template <typename I, typename V, typename O> + void plus_cst(const Image<I>& input, const V& val, Image<O>& output) + { + mln_precondition(exact(output).domain() = exact(input).domain()); + plus(input, pw::cst(val) | exact(input).domain(), output); // Calls the previous version. + } + template <typename L, typename R> void plus_inplace(Image<L>& lhs, const Image<R>& rhs) { @@ -134,6 +158,13 @@ impl::plus_inplace_(exact(lhs), exact(rhs)); } + template <typename I, typename V> + void plus_cst_inplace(Image<I>& input, const V& val) + { + mln_precondition(exact(input).has_data()); + plus_inplace(input, pw::cst(val) | exact(input).domain()); // Calls the previous version. + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::arith Index: img/picasso.pgm Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream