https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Add morpho algebraic closing.
* mln/morpho/attribute/volume.hh: New.
* mln/morpho/closing_algebraic.hh: Copy to...
* mln/morpho/opening_algebraic.hh: ...this new file.
Make it a closing.
* mln/canvas/morpho/algebraic_filter.hh (todo): New.
* tests/morpho/closing_volume.cc: Test that the new version
with morpho::attribute::volume gives the same result as the
former version.
mln/canvas/morpho/algebraic_filter.hh | 2
mln/morpho/attribute/volume.hh | 172 +++++++++++++++++-----------------
mln/morpho/opening_algebraic.hh | 24 ++--
tests/morpho/closing_volume.cc | 16 ++-
4 files changed, 113 insertions(+), 101 deletions(-)
Index: mln/morpho/attribute/volume.hh
--- mln/morpho/attribute/volume.hh (revision 3334)
+++ mln/morpho/attribute/volume.hh (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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,33 +26,50 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_ACCU_VOLUME_HH
-# define MLN_ACCU_VOLUME_HH
+#ifndef MLN_MORPHO_ATTRIBUTE_VOLUME_HH
+# define MLN_MORPHO_ATTRIBUTE_VOLUME_HH
-/// \file mln/accu/volume.hh
+/// \file mln/morpho/attribute/volume.hh
+///
/// Define an accumulator that computes the volume of a
-/// component through one of its pixels.
-/*!
- This accumulator uses an mln::util::pix (pixel) to update the
- reference level, area and volume information of the component.
-
- The class mln/accu/volume is not a general-purpose accumulator;
- it is used to implement volume-based connected filters.
- \see mln::morpho::closing_volume
- \see mln::morpho::opening_volume
-*/
+/// component.
# include <mln/accu/internal/base.hh>
-# include <mln/core/concept/meta_accumulator.hh>
# include <mln/math/diff_abs.hh>
-# include <mln/util/pix.hh>
-# include <mln/literal/zero.hh>
namespace mln
{
- namespace accu
+ // Forward declaration.
+ namespace morpho {
+ namespace attribute {
+ template <typename I> class volume;
+ }
+ }
+
+
+ // Traits.
+
+ namespace trait
+ {
+
+ template <typename I>
+ struct accumulator_< morpho::attribute::volume<I> >
+ {
+ typedef accumulator::has_untake::no has_untake;
+ typedef accumulator::has_set_value::no has_set_value;
+ typedef accumulator::has_stop::no has_stop;
+ typedef accumulator::when_pix::use_v when_pix;
+ };
+
+ } // end of namespace mln::trait
+
+
+ namespace morpho
+ {
+
+ namespace attribute
{
/// Volume accumulator class.
@@ -63,26 +80,20 @@
struct volume
: public mln::accu::internal::base< unsigned , volume<I> >
{
- /// The accumulated data type.
- ///
- /// The volume of component is represented by the volume of its
- /// root pixel. See mln::morpho::closing_volume and
- /// mln::morpho::opening_volume for actual uses of this
- /// accumulator.
- typedef util::pix<I> argument;
- /// The value type associated to the pixel type.
- typedef typename argument::value value;
+ typedef mln_value(I) argument;
volume();
/// Manipulators.
/// \{
void init();
- void take(const argument& pixel);
+
+ void take(const mln_value(I)& v);
+ void take(const util::pix<I>& px);
void take(const volume<I>& other);
- /// Force the value of the counter to \a v.
- void set_value(unsigned v);
+ void take_as_init(const mln_value(I)& v);
+ void take_as_init(const util::pix<I>& px);
/// \}
/// Get the value of the accumulator.
@@ -93,31 +104,15 @@
bool is_valid() const;
protected:
- /// The reference level (the level of the component's root).
- value ref_level__;
+ /// The current level.
+ mln_value(I) level_;
/// The area of the component.
- unsigned area__;
+ unsigned area_;
/// The volume of the component.
unsigned volume_;
};
- namespace meta
- {
-
- /// Meta accumulator for volume.
-
- struct volume : public Meta_Accumulator< volume >
- {
- template <typename I>
- struct with
- {
- typedef accu::volume<I> ret;
- };
- };
-
- } // end of namespace mln::accu::meta
-
# ifndef MLN_INCLUDE_ONLY
@@ -133,32 +128,32 @@
void
volume<I>::init()
{
- ref_level__ = literal::zero;
volume_ = 0;
- area__ = 0;
}
template <typename I>
inline
void
- volume<I>::take(const argument& pixel)
+ volume<I>::take(const mln_value(I)& v)
{
- /* FIXME: Growing a component using this particular `take'
- routine won't work, since the update does not take care of
- the reference level to compute the new volume. Maybe we
- could distinguish two cases:
-
- 1. the empty accumulator case (which corresponds to the
- following code);
- 2. the non-empty accumulator case (which sohuld act as in
- `take(const volume<I>& other)').
+ mln_invariant(volume_ != mln_max(unsigned));
+ if (! is_valid())
+ {
+ take_as_init(v);
+ return;
+ }
+ ++area_;
+ volume_ += 1 + math::diff_abs(v, level_);
+ level_ = v;
+ }
- Currently, the implementation is only valid if the
- accumulator was initialy empty before the call to
- `take(const argument&)'. */
- ref_level__ = pixel.v();
- ++area__;
- ++volume_;
+ template <typename I>
+ inline
+ void
+ volume<I>::take(const util::pix<I>& px)
+ {
+ mln_invariant(volume_ != mln_max(unsigned));
+ take(px.v());
}
template <typename I>
@@ -166,33 +161,38 @@
void
volume<I>::take(const volume<I>& other)
{
- area__ += other.area__;
- /* FIXME: Is it `t.area__' or `area__' ? Th�o said it was
- the latter, but both the ISMM 2005 paper and Olena 0.11 use
- the former. */
+ mln_invariant(volume_ != mln_max(unsigned));
+ area_ += other.area_;
volume_ +=
other.volume_ +
- other.area__ * math::diff_abs(other.ref_level__, ref_level__);
- // Member ref_level__ is not touched.
+ other.area_ * math::diff_abs(other.level_, level_);
+ // level_ do not change.
}
template <typename I>
inline
- unsigned
- volume<I>::to_result() const
+ void
+ volume<I>::take_as_init(const mln_value(I)& v)
{
- return volume_;
+ level_ = v;
+ area_ = 1;
+ volume_ = 1;
}
template <typename I>
inline
void
- volume<I>::set_value(unsigned v)
+ volume<I>::take_as_init(const util::pix<I>& px)
+ {
+ take_as_init(px.v());
+ }
+
+ template <typename I>
+ inline
+ unsigned
+ volume<I>::to_result() const
{
- volume_ = v;
- // Reset the other members.
- ref_level__ = literal::zero;
- area__ = 0;
+ return volume_;
}
template <typename I>
@@ -200,14 +200,16 @@
bool
volume<I>::is_valid() const
{
- return true;
+ return volume_ != 0;
}
# endif // ! MLN_INCLUDE_ONLY
- } // end of namespace mln::accu
+ } // end of namespace mln::morpho::attribute
+
+ } // end of namespace mln::morpho
} // end of namespace mln
-#endif // ! MLN_ACCU_VOLUME_HH
+#endif // ! MLN_MORPHO_ATTRIBUTE_VOLUME_HH
Property changes on: mln/morpho/attribute/volume.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/morpho/opening_algebraic.hh
--- mln/morpho/opening_algebraic.hh (revision 3334)
+++ mln/morpho/opening_algebraic.hh (working copy)
@@ -26,12 +26,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_MORPHO_CLOSING_ALGEBRAIC_HH
-# define MLN_MORPHO_CLOSING_ALGEBRAIC_HH
+#ifndef MLN_MORPHO_OPENING_ALGEBRAIC_HH
+# define MLN_MORPHO_OPENING_ALGEBRAIC_HH
-/// \file mln/morpho/closing_algebraic.hh
+/// \file mln/morpho/opening_algebraic.hh
///
-/// Morphological algebraic closing.
+/// Morphological algebraic opening.
# include <mln/morpho/includes.hh>
# include <mln/canvas/morpho/algebraic_filter.hh>
@@ -43,10 +43,10 @@
namespace morpho
{
- /// Morphological algebraic closing.
+ /// Morphological algebraic opening.
template <typename I, typename N, typename A>
mln_concrete(I)
- closing_algebraic(const Image<I>& input, const Neighborhood<N>&
nbh,
+ opening_algebraic(const Image<I>& input, const Neighborhood<N>&
nbh,
const Accumulator<A>& accu, const mln_result(A)& lambda);
@@ -58,20 +58,20 @@
template <typename I, typename N, typename A>
inline
mln_concrete(I)
- closing_algebraic(const Image<I>& input, const Neighborhood<N>&
nbh,
+ opening_algebraic(const Image<I>& input, const Neighborhood<N>&
nbh,
const Accumulator<A>& accu, const mln_result(A)& lambda)
{
- trace::entering("morpho::closing_algebraic");
+ trace::entering("morpho::opening_algebraic");
mln_precondition(exact(input).is_valid());
mln_concrete(I) output;
output = canvas::morpho::algebraic_filter(input, nbh, accu, lambda,
- /* increasing = */ true);
+ /* increasing = */ false);
- mln_postcondition(output >= input);
+ mln_postcondition(output <= input);
- trace::exiting("morpho::closing_algebraic");
+ trace::exiting("morpho::opening_algebraic");
return output;
}
@@ -83,4 +83,4 @@
} // end of namespace mln
-#endif // ! MLN_MORPHO_CLOSING_ALGEBRAIC_HH
+#endif // ! MLN_MORPHO_OPENING_ALGEBRAIC_HH
Index: mln/canvas/morpho/algebraic_filter.hh
--- mln/canvas/morpho/algebraic_filter.hh (revision 3343)
+++ mln/canvas/morpho/algebraic_filter.hh (working copy)
@@ -32,6 +32,8 @@
/// \file mln/canvas/morpho/algebraic_filter.hh
///
/// Canvas for morphological algebraic filters.
+///
+/// \todo Add a version without 'activity' thanx to set_value.
# include <mln/core/concept/image.hh>
# include <mln/core/concept/neighborhood.hh>
Index: tests/morpho/closing_volume.cc
--- tests/morpho/closing_volume.cc (revision 3343)
+++ tests/morpho/closing_volume.cc (working copy)
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2007, 2008, 2009 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
@@ -38,15 +38,23 @@
#include <mln/io/pgm/save.hh>
#include <mln/morpho/closing_volume.hh>
+#include <mln/morpho/attribute/volume.hh>
#include "tests/data.hh"
+
int main()
{
using namespace mln;
using value::int_u8;
- image2d<int_u8> lena;
+ typedef image2d<int_u8> I;
+ I lena;
io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
- io::pgm::save(morpho::closing_volume(lena, c4(), 10000), "out.pgm");
+ io::pgm::save(morpho::closing_volume(lena, c4(), 10000),
+ "ref.pgm");
+
+ typedef morpho::attribute::volume<I> A;
+ io::pgm::save(morpho::closing_attribute<A>(lena, c4(), 10000),
+ "out.pgm");
}