2974: Make morphological dilation use the general code.

https://svn.lrde.epita.fr/svn/oln/trunk/milena Index: ChangeLog from Thierry Geraud <thierry.geraud@lrde.epita.fr> Make morphological dilation use the general code. * mln/accu/lor.hh: New. * mln/accu/lor_basic.hh: New. * mln/accu/land_basic.hh: Fix guard. * mln/accu/land.hh: Fix guard. * mln/accu/all.hh: Update. * mln/morpho/includes.hh (include): Move accumulators to... * mln/morpho/erosion.hh: ...here and... * mln/morpho/dilation.hh: ...here. * mln/morpho/erosion.hh (todo): New. Copy this file to... * mln/morpho/dilation.hh: ...this revamped file. (todo): New. (dilation_op): New. (general_on_set_centered, general_on_set_centered_fastest): Up. (dilation): Use general. * mln/morpho/general.hh (general): Remove erroneous postcondition. * mln/morpho/all.hh: Update. * tests/morpho/general.cc (tiny): Replace by... (small): ...this. Augment with dilation. * tests/morpho/Makefile.am: Update. mln/accu/all.hh | 3 ++ mln/accu/land.hh | 5 ++- mln/accu/land_basic.hh | 5 ++- mln/accu/lor.hh | 69 +++++++++++++++++++++++----------------------- mln/accu/lor_basic.hh | 57 +++++++++++++++++++------------------- mln/morpho/all.hh | 1 mln/morpho/dilation.hh | 70 +++++++++++++++++++++++++---------------------- mln/morpho/erosion.hh | 8 ++++- mln/morpho/general.hh | 2 - mln/morpho/includes.hh | 7 ---- tests/morpho/Makefile.am | 2 + tests/morpho/general.cc | 54 ++++++++++++++++++++++++++++++++---- 12 files changed, 170 insertions(+), 113 deletions(-) Index: tests/morpho/general.cc --- tests/morpho/general.cc (revision 2973) +++ tests/morpho/general.cc (working copy) @@ -37,6 +37,7 @@ #include <mln/win/all.hh> #include <mln/morpho/erosion.hh> +#include <mln/morpho/dilation.hh> #include "tests/data.hh" @@ -56,13 +57,14 @@ win::octagon2d oct(2 * 3 + 1); morpho::erosion_op ero; + morpho::dilation_op dil; { image2d<int_u8> lena, out, ref; - io::pgm::load(lena, MLN_IMG_DIR "/tiny.pgm"); + io::pgm::load(lena, MLN_IMG_DIR "/small.pgm"); - // Rectangle. + // Rectangle (erosion). ref = morpho::impl::generic::general_on_function(ero, lena, rec); @@ -78,6 +80,23 @@ out = morpho::impl::general_directional(ero, lena, rec, 1); mln_assertion(out == ref); + + // Rectangle (dilation). + + ref = morpho::impl::generic::general_on_function(dil, lena, rec); + + out = morpho::impl::general_rectangle2d(dil, lena, rec); + mln_assertion(out == ref); + + out = morpho::impl::general_arbitrary_2d(dil, lena, rec); + mln_assertion(out == ref); + + out = morpho::impl::general_directional(dil, lena, rec, 0); + mln_assertion(out == ref); + + out = morpho::impl::general_directional(dil, lena, rec, 1); + mln_assertion(out == ref); + /* // Hline. @@ -106,9 +125,11 @@ trace::quiet = false; image2d<bool> pic; - io::pbm::load(pic, MLN_IMG_DIR "/tiny.pbm"); + io::pbm::load(pic, MLN_IMG_DIR "/small.pbm"); + // morpho::impl::general_on_set_centered_fastest(ero, pic, win::rectangle2d(3,3)); morpho::general(ero, pic, win::rectangle2d(3,3)); + morpho::general(dil, pic, win::rectangle2d(3,3)); trace::quiet = true; } @@ -118,9 +139,9 @@ { image2d<bool> pic, out, ref; - io::pbm::load(pic, MLN_IMG_DIR "/tiny.pbm"); + io::pbm::load(pic, MLN_IMG_DIR "/small.pbm"); - // Rectangle. + // Rectangle (erosion). ref = morpho::impl::generic::general_on_set(ero, pic, rec); @@ -141,6 +162,29 @@ out = morpho::impl::general_directional(ero, pic, rec, 1); mln_assertion(out == ref); + + + // Rectangle (dilation). + + ref = morpho::impl::generic::general_on_set(dil, pic, rec); + + out = morpho::impl::general_on_set_centered(dil, pic, rec); + mln_assertion(out == ref); + + out = morpho::impl::general_on_set_centered_fastest(dil, pic, rec); + mln_assertion(out == ref); + + out = morpho::impl::general_rectangle2d(dil, pic, rec); + mln_assertion(out == ref); + + out = morpho::impl::general_arbitrary_2d(dil, pic, rec); + mln_assertion(out == ref); + + out = morpho::impl::general_directional(dil, pic, rec, 0); + mln_assertion(out == ref); + + out = morpho::impl::general_directional(dil, pic, rec, 1); + mln_assertion(out == ref); } } Index: tests/morpho/Makefile.am --- tests/morpho/Makefile.am (revision 2973) +++ tests/morpho/Makefile.am (working copy) @@ -20,6 +20,7 @@ ## dilation_max_h \ erosion \ ## erosion_min_h \ + general \ gradient \ ## graph_image_morpho \ ## graph_image_wst \ @@ -56,6 +57,7 @@ opening_volume_SOURCES = opening_volume.cc contrast_SOURCES = contrast.cc +general_SOURCES = general.cc gradient_SOURCES = gradient.cc hit_or_miss_SOURCES = hit_or_miss.cc laplacian_SOURCES = laplacian.cc Index: mln/accu/lor.hh --- mln/accu/lor.hh (revision 2972) +++ mln/accu/lor.hh (working copy) @@ -26,14 +26,14 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_ACCU_LAND_HH -# define MLN_ACCU_LAND_HH +#ifndef MLN_ACCU_LOR_HH +# define MLN_ACCU_LOR_HH -/// \file mln/accu/land.hh +/// \file mln/accu/lor.hh /// -/// Define a 'logical-and' accumulator. +/// Define a 'logical-or' accumulator. /// -/// \todo Have land_basic be parameterized. +/// \todo Have lor be parameterized. # include <mln/accu/internal/base.hh> @@ -44,12 +44,12 @@ namespace accu { - /// "Logical-and" accumulator class. - struct land : public mln::accu::internal::base< bool, land > + /// "Logical-or" accumulator class. + struct lor : public mln::accu::internal::base< bool, lor > { typedef bool argument; - land(); + lor(); /// Manipulators. /// \{ @@ -57,10 +57,10 @@ void take_as_init(const argument& t); void take(const argument& t); - void take(const land& other); + void take(const lor& other); void untake(const argument& t); - void untake(const land& other); + void untake(const lor& other); /// \} /// Get the value of the accumulator. @@ -71,21 +71,21 @@ bool is_valid() const; protected: - unsigned nfalse_; + unsigned ntrue_; }; namespace meta { - /// Meta accumulator for land. + /// Meta accumulator for lor. - struct land : public Meta_Accumulator< land > + struct lor : public Meta_Accumulator< lor > { template <typename T> struct with { - typedef accu::land ret; + typedef accu::lor ret; }; }; @@ -96,63 +96,63 @@ # ifndef MLN_INCLUDE_ONLY inline - land::land() + lor::lor() { init(); } inline void - land::init() + lor::init() { - nfalse_ = 0; + ntrue_ = 0; } inline - void land::take_as_init(const argument& t) + void lor::take_as_init(const argument& t) { - nfalse_ = t ? 0 : 1; + ntrue_ = t ? 1 : 0; } inline - void land::take(const argument& t) + void lor::take(const argument& t) { - if (t == false) - ++nfalse_; + if (t == true) + ++ntrue_; } inline void - land::take(const land& other) + lor::take(const lor& other) { - nfalse_ += other.nfalse_; + ntrue_ += other.ntrue_; } inline - void land::untake(const argument& t) + void lor::untake(const argument& t) { - if (t == false) - --nfalse_; + if (t == true) + --ntrue_; } inline void - land::untake(const land& other) + lor::untake(const lor& other) { - mln_precondition(other.nfalse_ <= nfalse_); - nfalse_ -= other.nfalse_; + mln_precondition(other.ntrue_ <= ntrue_); + ntrue_ -= other.ntrue_; } inline bool - land::to_result() const + lor::to_result() const { - return nfalse_ == 0; + return ntrue_ != 0; } inline bool - land::is_valid() const + lor::is_valid() const { return true; } @@ -163,4 +163,5 @@ } // end of namespace mln -#endif // ! MLN_ACCU_AND_HH + +#endif // ! MLN_ACCU_LOR_HH Index: mln/accu/all.hh --- mln/accu/all.hh (revision 2973) +++ mln/accu/all.hh (working copy) @@ -63,7 +63,10 @@ # include <mln/accu/height.hh> # include <mln/accu/histo.hh> # include <mln/accu/land.hh> +# include <mln/accu/land_basic.hh> # include <mln/accu/line.hh> +# include <mln/accu/lor.hh> +# include <mln/accu/lor_basic.hh> # include <mln/accu/max.hh> # include <mln/accu/max_h.hh> # include <mln/accu/mean.hh> Index: mln/accu/land_basic.hh --- mln/accu/land_basic.hh (revision 2973) +++ mln/accu/land_basic.hh (working copy) @@ -44,7 +44,7 @@ namespace accu { - /// "Logical-and" accumulator class. Conversely to accu::lands, + /// "Logical-and" accumulator class. Conversely to accu::land, /// this version does not have the 'untake' method but features /// the 'can_stop' method. struct land_basic : public mln::accu::internal::base< bool, land_basic > @@ -159,4 +159,5 @@ } // end of namespace mln -#endif // ! MLN_ACCU_AND_HH + +#endif // ! MLN_ACCU_LAND_BASIC_HH Index: mln/accu/lor_basic.hh --- mln/accu/lor_basic.hh (revision 2972) +++ mln/accu/lor_basic.hh (working copy) @@ -26,14 +26,14 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_ACCU_LAND_BASIC_HH -# define MLN_ACCU_LAND_BASIC_HH +#ifndef MLN_ACCU_LOR_BASIC_HH +# define MLN_ACCU_LOR_BASIC_HH -/// \file mln/accu/land_basic.hh +/// \file mln/accu/lor_basic.hh /// -/// Define a basic 'logical-and' accumulator. +/// Define a basic 'logical-or' accumulator. /// -/// \todo Have land_basic be parameterized. +/// \todo Have lor_basic be parameterized. # include <mln/accu/internal/base.hh> @@ -44,14 +44,14 @@ namespace accu { - /// "Logical-and" accumulator class. Conversely to accu::lands, + /// "Logical-or" accumulator class. Conversely to accu::lor, /// this version does not have the 'untake' method but features /// the 'can_stop' method. - struct land_basic : public mln::accu::internal::base< bool, land_basic > + struct lor_basic : public mln::accu::internal::base< bool, lor_basic > { typedef bool argument; - land_basic(); + lor_basic(); /// Manipulators. /// \{ @@ -59,7 +59,7 @@ void take_as_init(const argument& t); void take(const argument& t); - void take(const land_basic& other); + void take(const lor_basic& other); /// \} /// Get the value of the accumulator. @@ -70,8 +70,8 @@ bool is_valid() const; /// Test if it is worth for this accumulator to take extra data. - /// If the result is already 'false' (because this accumulator - /// has already taken a 'false' value), can_stop returns true. + /// If the result is already 'true' (because this accumulator + /// has already taken a 'true' value), can_stop returns true. bool can_stop() const; protected: @@ -82,14 +82,14 @@ namespace meta { - /// Meta accumulator for land_basic. + /// Meta accumulator for lor_basic. - struct land_basic : public Meta_Accumulator< land_basic > + struct lor_basic : public Meta_Accumulator< lor_basic > { template <typename T> struct with { - typedef accu::land_basic ret; + typedef accu::lor_basic ret; }; }; @@ -100,57 +100,57 @@ # ifndef MLN_INCLUDE_ONLY inline - land_basic::land_basic() + lor_basic::lor_basic() { init(); } inline void - land_basic::init() + lor_basic::init() { - res_ = true; + res_ = false; } inline - void land_basic::take_as_init(const argument& t) + void lor_basic::take_as_init(const argument& t) { res_ = t; } inline - void land_basic::take(const argument& t) + void lor_basic::take(const argument& t) { - if (res_ == true && t == false) - res_ = false; + if (res_ == false && t == true) + res_ = true; } inline void - land_basic::take(const land_basic& other) + lor_basic::take(const lor_basic& other) { - res_ = res_ && other.res_; + res_ = res_ || other.res_; } inline bool - land_basic::to_result() const + lor_basic::to_result() const { return res_; } inline bool - land_basic::is_valid() const + lor_basic::is_valid() const { return true; } inline bool - land_basic::can_stop() const + lor_basic::can_stop() const { - return res_ == false; + return res_ == true; } # endif // ! MLN_INCLUDE_ONLY @@ -159,4 +159,5 @@ } // end of namespace mln -#endif // ! MLN_ACCU_AND_HH + +#endif // ! MLN_ACCU_LOR_BASIC_HH Index: mln/accu/land.hh --- mln/accu/land.hh (revision 2973) +++ mln/accu/land.hh (working copy) @@ -33,7 +33,7 @@ /// /// Define a 'logical-and' accumulator. /// -/// \todo Have land_basic be parameterized. +/// \todo Have land be parameterized. # include <mln/accu/internal/base.hh> @@ -163,4 +163,5 @@ } // end of namespace mln -#endif // ! MLN_ACCU_AND_HH + +#endif // ! MLN_ACCU_LAND_HH Index: mln/morpho/all.hh --- mln/morpho/all.hh (revision 2973) +++ mln/morpho/all.hh (working copy) @@ -63,6 +63,7 @@ # include <mln/morpho/dilation.hh> # include <mln/morpho/erosion_fast.hh> # include <mln/morpho/erosion.hh> +# include <mln/morpho/general.hh> # include <mln/morpho/gradient.hh> # include <mln/morpho/hit_or_miss.hh> # include <mln/morpho/includes.hh> Index: mln/morpho/erosion.hh --- mln/morpho/erosion.hh (revision 2973) +++ mln/morpho/erosion.hh (working copy) @@ -32,9 +32,15 @@ /// \file mln/morpho/erosion.hh /// /// Morphological erosion. +/// +/// \todo The overloads are hidden and I don't know why! # include <mln/morpho/includes.hh> # include <mln/morpho/general.hh> +# include <mln/accu/land.hh> +# include <mln/accu/land_basic.hh> +# include <mln/accu/min.hh> +# include <mln/accu/min_h.hh> namespace mln @@ -51,7 +57,6 @@ # ifndef MLN_INCLUDE_ONLY - struct erosion_op { @@ -153,6 +158,7 @@ } // end of namespace morpho::impl + template <typename I, typename W> inline mln_concrete(I) Index: mln/morpho/dilation.hh --- mln/morpho/dilation.hh (revision 2972) +++ mln/morpho/dilation.hh (working copy) @@ -26,15 +26,21 @@ // reasons why the executable file might be covered by the GNU General // Public License. -#ifndef MLN_MORPHO_EROSION_HH -# define MLN_MORPHO_EROSION_HH +#ifndef MLN_MORPHO_DILATION_HH +# define MLN_MORPHO_DILATION_HH -/// \file mln/morpho/erosion.hh +/// \file mln/morpho/dilation.hh /// -/// Morphological erosion. +/// Morphological dilation. +/// +/// \todo The overloads are hidden and I don't know why! # include <mln/morpho/includes.hh> # include <mln/morpho/general.hh> +# include <mln/accu/lor.hh> +# include <mln/accu/lor_basic.hh> +# include <mln/accu/max.hh> +# include <mln/accu/max_h.hh> namespace mln @@ -43,38 +49,38 @@ namespace morpho { - /// Morphological erosion. + /// Morphological dilation. template <typename I, typename W> mln_concrete(I) - erosion(const Image<I>& input, const Window<W>& win); + dilation(const Image<I>& input, const Window<W>& win); # ifndef MLN_INCLUDE_ONLY - struct erosion_op + struct dilation_op { template <typename I> - mln_morpho_select_accu(I, land_basic, min) + mln_morpho_select_accu(I, lor_basic, max) accu(const Image<I>&) const { - mln_morpho_select_accu(I, land_basic, min) tmp; + mln_morpho_select_accu(I, lor_basic, max) tmp; return tmp; } template <typename I> - mln_morpho_select_accu(I, land, min_h) + mln_morpho_select_accu(I, lor, max_h) accu_incr(const Image<I>&) const { - mln_morpho_select_accu(I, land, min_h) tmp; + mln_morpho_select_accu(I, lor, max_h) tmp; return tmp; } template <typename I> mln_value(I) neutral(const Image<I>&) const { - return internal::neutral<I>::supremum(); + return internal::neutral<I>::infimum(); } }; @@ -88,16 +94,16 @@ template <typename I, typename W> mln_concrete(I) - general_on_set_centered(const erosion_op&, + general_on_set_centered(const dilation_op&, const Image<I>& input_, const Window<W>& win_) { - trace::entering("morpho::impl::general_on_set_centered__erosion"); + trace::entering("morpho::impl::general_on_set_centered__dilation"); typedef mln_concrete(I) O; const I& input = exact(input_); const W& win = exact(win_); - extension::adjust_fill(input, win, true); + extension::adjust_fill(input, win, false); O output; output = clone(input); @@ -105,31 +111,31 @@ mln_piter(I) p(input.domain()); mln_qiter(W) q(win, p); for_all(p) - if (input(p) == true) + if (input(p) == false) for_all(q) if (input.has(q)) - if (input(q) == false) + if (input(q) == true) { - output(p) = false; + output(p) = true; break; } - trace::exiting("morpho::impl::general_on_set_centered__erosion"); + trace::exiting("morpho::impl::general_on_set_centered__dilation"); return output; } template <typename I, typename W> mln_concrete(I) - general_on_set_centered_fastest(const erosion_op&, + general_on_set_centered_fastest(const dilation_op&, const Image<I>& input_, const Window<W>& win_) { - trace::entering("morpho::impl::general_on_set_centered_fastest__erosion"); + trace::entering("morpho::impl::general_on_set_centered_fastest__dilation"); typedef mln_concrete(I) O; const I& input = exact(input_); const W& win = exact(win_); - extension::adjust_fill(input, win, true); + extension::adjust_fill(input, win, false); O output; output = clone(input); @@ -138,15 +144,15 @@ mln_qixter(const I, W) q(p, win); mln_pixter(O) p_out(output); for_all_2(p, p_out) - if (p.val() == true) + if (p.val() == false) for_all(q) - if (q.val() == false) + if (q.val() == true) { - p_out.val() = false; + p_out.val() = true; break; } - trace::exiting("morpho::impl::general_on_set_centered_fastest__erosion"); + trace::exiting("morpho::impl::general_on_set_centered_fastest__dilation"); return output; } @@ -156,18 +162,18 @@ template <typename I, typename W> inline mln_concrete(I) - erosion(const Image<I>& input, const Window<W>& win) + dilation(const Image<I>& input, const Window<W>& win) { - trace::entering("morpho::erosion"); + trace::entering("morpho::dilation"); mln_precondition(exact(input).has_data()); mln_precondition(! exact(win).is_empty()); - mln_concrete(I) output = general(erosion_op(), input, win); + mln_concrete(I) output = general(dilation_op(), input, win); if (exact(win).is_centered()) - mln_postcondition(output <= input); + mln_postcondition(output >= input); - trace::exiting("morpho::erosion"); + trace::exiting("morpho::dilation"); return output; } @@ -178,4 +184,4 @@ } // end of namespace mln -#endif // ! MLN_MORPHO_EROSION_HH +#endif // ! MLN_MORPHO_DILATION_HH Index: mln/morpho/includes.hh --- mln/morpho/includes.hh (revision 2973) +++ mln/morpho/includes.hh (working copy) @@ -42,13 +42,6 @@ # include <mln/value/ops.hh> -# include <mln/accu/land.hh> -# include <mln/accu/land_basic.hh> -// # include <mln/accu/lor.hh> -# include <mln/accu/min.hh> -# include <mln/accu/max.hh> -# include <mln/accu/min_h.hh> -# include <mln/accu/max_h.hh> # include <mln/accu/rank.hh> # include <mln/accu/transform.hh> Index: mln/morpho/general.hh --- mln/morpho/general.hh (revision 2973) +++ mln/morpho/general.hh (working copy) @@ -173,8 +173,6 @@ internal::general_tests(op, input, win); mln_concrete(I) output = internal::general_dispatch(op, input, win); - if (exact(win).is_centered()) - mln_postcondition(output <= input); trace::exiting("morpho::general"); return output; }
participants (1)
-
Thierry Geraud