Commit 6a149af2 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Add height attribute, and implement untake and set_value method.

	* mln/morpho/attribute/height.hh: New.
	* mln/morpho/attribute/sum.hh: Implements untake and set_value
	methods.
	* mln/morpho/attribute/volume.hh: s/level_/cur_level_.
	* tests/morpho/attribute/Makefile.am:
	* tests/morpho/attribute/height.cc: Add height test file.

git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@3436 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent a611e863
2009-02-28 Edwin Carlinet <carlinet@lrde.epita.fr>
Add height attribute, and implement untake and set_value method.
* mln/morpho/attribute/height.hh: New.
* mln/morpho/attribute/sum.hh: Implements untake and set_value
methods.
* mln/morpho/attribute/volume.hh: s/level_/cur_level_.
* tests/morpho/attribute/Makefile.am:
* tests/morpho/attribute/height.cc: Add height test file.
2009-02-28 Edwin Carlinet <carlinet@lrde.epita.fr>
 
Clean and separate connected (leveling/algebraic) filters.
// 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
// 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_ATTRIBUTE_HEIGHT_HH
# define MLN_MORPHO_ATTRIBUTE_HEIGHT_HH
/// \file mln/morpho/attribute/height.hh
/// Define an accumulator that computes the height of a
/// component through one of its pixels.
# include <mln/accu/internal/base.hh>
# include <mln/util/pix.hh>
# include <mln/math/diff_abs.hh>
# include <mln/math/min.hh>
# include <mln/math/max.hh>
namespace mln {
// 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 {
/// Height accumulator class.
///
/// The parameter \p I is the image type on which the accumulator
/// of pixels is built.
template <typename I>
struct height
: public mln::accu::internal::base< unsigned , height<I> >
{
typedef mln_value(I) argument;
height();
/// Manipulators.
/// \{
void init();
void take(const mln_value(I)& v);
void take(const util::pix<I>& v);
void take(const height<I>& other);
void take_as_init(const mln_value(I)& v);
void take_as_init(const util::pix<I>& px);
/// \}
/// Check whether this accu is able to return a result.
/// Always true here.
bool is_valid() const;
/// Get the value of the accumulator.
unsigned to_result() const;
protected:
/// The reference level in the component.
unsigned ref_;
/// The current level in the component.
unsigned cur_;
/// Mark of initialization
bool initialized_;
};
# ifndef MLN_INCLUDE_ONLY
template <typename I>
inline
height<I>::height()
: initialized_ (false)
{
}
template <typename I>
inline
void
height<I>::init()
{
mln_invariant(0);
}
template <typename I>
inline
void
height<I>::take(const mln_value(I)& v)
{
if (!is_valid ())
{
take_as_init(v);
}
cur_ = v;
}
template <typename I>
inline
void
height<I>::take(const util::pix<I>& px)
{
take(px.v());
}
template <typename I>
inline
void
height<I>::take(const height<I>& other)
{
mln_invariant(ref_ < cur_ xor other.ref_ > other.cur_);
if (!is_valid())
{
ref_ = other.ref_;
cur_ = other.cur_;
}
else if (ref_ < cur_)
{
// Values are increasing.
ref_ = math::min(ref_, other.ref_);
cur_ = math::max(cur_, other.cur_);
}
else
{
// Values are decreasing.
ref_ = math::max(ref_, other.ref_);
cur_ = math::min(cur_, other.cur_);
}
}
template <typename I>
inline
void
height<I>::take_as_init(const mln_value(I)& v)
{
cur_ = ref_ = v;
initialized_ = true;
}
template <typename I>
inline
void
height<I>::take_as_init(const util::pix<I>& px)
{
take_as_init(px.v());
}
template <typename I>
inline
unsigned
height<I>::to_result() const
{
mln_invariant(initialized_);
if (is_valid())
return math::diff_abs(ref_, cur_);
}
template <typename I>
inline
bool
height<I>::is_valid() const
{
return initialized_;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::morpho::attribute
} // end of namespace mln::morpho
} // end of namespace mln
#endif // ! MLN_MORPHO_ATTRIBUTE_HEIGHT_HH
......@@ -61,10 +61,10 @@ namespace mln
template <typename I, typename S>
struct accumulator_< morpho::attribute::sum<I,S> >
{
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;
typedef accumulator::has_untake::yes has_untake;
typedef accumulator::has_set_value::yes has_set_value;
typedef accumulator::has_stop::no has_stop;
typedef accumulator::when_pix::use_v when_pix;
};
} // end of namespace mln::trait
......@@ -107,6 +107,15 @@ namespace mln
/// Return always true.
bool is_valid() const;
/// Untake a value from the accumulator.
void untake(const argument& v);
void untake(const util::pix<I>& px);
/// Set the return value of the accumalator.
void set_value(const argument& v);
void set_value(const util::pix<I>& px);
protected:
/// The sum value.
......@@ -176,6 +185,38 @@ namespace mln
take_as_init(px.v());
}
template <typename I, typename S>
inline
void
sum<I,S>::untake(const argument& v)
{
s_ -= v;
}
template <typename I, typename S>
inline
void
sum<I,S>::untake(const util::pix<I>& px)
{
untake(px.v());
}
template <typename I, typename S>
inline
void
sum<I,S>::set_value(const argument& v)
{
s_ = v;
}
template <typename I, typename S>
inline
void
sum<I,S>::set_value(const util::pix<I>& px)
{
set_value(px.v());
}
template <typename I, typename S>
inline
S
......
......@@ -109,7 +109,7 @@ namespace mln
protected:
/// The current level.
mln_value(I) level_;
mln_value(I) cur_level_;
/// The area of the component.
unsigned area_;
/// The volume of the component.
......@@ -147,8 +147,8 @@ namespace mln
return;
}
++area_;
volume_ += 1 + math::diff_abs(v, level_);
level_ = v;
volume_ += 1 + math::diff_abs(v, cur_level_);
cur_level_ = v;
}
template <typename I>
......@@ -169,8 +169,8 @@ namespace mln
area_ += other.area_;
volume_ +=
other.volume_ +
other.area_ * math::diff_abs(other.level_, level_);
// level_ do not change.
other.area_ * math::diff_abs(other.cur_level_, cur_level_);
// cur_level_ do not change.
}
template <typename I>
......@@ -178,7 +178,7 @@ namespace mln
void
volume<I>::take_as_init(const mln_value(I)& v)
{
level_ = v;
cur_level_ = v;
area_ = 1;
volume_ = 1;
}
......
......@@ -57,6 +57,7 @@ namespace mln
} // mln
using namespace mln;
int echo = 0;
template <typename I, typename A>
......@@ -64,7 +65,6 @@ inline
void
create_tree_and_compute(Image<I>& f_, Accumulator<A> a_, float lambda, float lambda2 = mln_max(float))
{
using namespace mln;
using value::int_u8;
I f = exact(f_);
......@@ -100,7 +100,6 @@ void usage(char* argv[])
int main(int argc, char* argv[])
{
using namespace mln;
using value::int_u8;
mln_VAR(nbh, c4());
......@@ -127,21 +126,35 @@ int main(int argc, char* argv[])
IM img(6);
morpho::attribute::volume<IM> accu;
img.element(0) = 50;
img.element(1) = 40;
img.element(2) = 20;
img.element(3) = 20;
img.element(4) = 40;
img.element(5) = 50;
img.element(1) = 50;
img.element(2) = 40;
img.element(3) = 40;
img.element(4) = 20;
img.element(5) = 20;
mln_piter_(image1d<int>) p(img.domain());
for_all(p)
accu.take(img(p));
int tab[6] = { 50, 50, 40, 40, 20, 20 };
for (int i = 0; i < 6; i++)
{
accu.take(tab[i]);
std::cout << "(" << tab[i] << "," << accu.to_result() << "):";
}
std::cout << "Volume:" << accu.to_result() << std::endl;
accu.init ();
for (int i = 5; i >= 0; i--)
{
accu.take(tab[i]);
std::cout << "(" << tab[i] << "," << accu.to_result() << "):";
}
std::cout << "Volume:" << accu.to_result() << std::endl;
//create_tree_and_compute(img, morpho::attribute::volume<I2>());
//
create_tree_and_compute(f, morpho::attribute::coccupation<I>(), lambda1, lambda2);
create_tree_and_compute(f, morpho::attribute::occupation<I>(), lambda1, lambda2);
}
......@@ -5,10 +5,12 @@ include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
card \
sum \
volume
volume \
height
card_SOURCES = card.cc
sum_SOURCES = sum.cc
volume_SOURCES = volume.cc
height_SOURCES = height.cc
TESTS = $(check_PROGRAMS)
// Copyright (C) 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
// 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/attribute/height.cc
///
/// Test on mln::morpho::attribute::height.
#include <mln/core/image/image1d.hh>
#include <mln/morpho/attribute/height.hh>
#include <iostream>
int main()
{
using namespace mln;
int t[5] = {3, 3, 8, 9, 10};
typedef morpho::attribute::height< image1d<int> > A;
A accu;
for (int i = 0; i < 5; i++)
accu.take(t[i]);
mln_assertion(accu.to_result() == 7);
A accu2;
accu = A();
for (int i = 4; i >= 0; i--)
{
accu.take(t[i] + 2);
accu2.take(t[i] - 2);
}
mln_assertion(accu.to_result() == 7);
mln_assertion(accu2.to_result() == 7);
accu.take(accu2);
mln_assertion(accu.to_result() == 11);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment