Commit 1f478867 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Add naive median to milena + fix problems with g++-2.95.

	* tests/window2d.cc: .
	* tests/median.cc: .
	* tests/box2d.cc: .
	* tests/naive_median.cc: New.
	* tests/histo.cc: .
	* tests/rectangle2d.cc: New.
	* mln/convert/to_dpoint.hh: Fix missing include.
	* mln/level/naive: New.
	* mln/level/naive/median.hh: New.
	* mln/level/median.hh: Update.
	* mln/io/save_pgm.hh,
	* mln/io/load_pgm.hh: Conform with g++-2.95.
	* mln/core/dpoint2d.hh (up, down, left, right): New.
	* mln/core/box.hh: Add impl inheritance.
	* mln/core/rectangle2d.hh: Fake typedef; add FIXME.
	(sym_): New.
	* mln/core/concept/window.hh (operator-): New.
	* mln/core/concept/doc/window.hh: Update.
	* mln/core/window.hh (sym_): New.
	(operators): Help g++-2.95.
	* mln/core/image2d_b.hh: Add impl inheritance.
	(init_with, bbox): New.
	(nrows, ncols): Remove; now inherited.
	* mln/core/internal/coord_impl.hh: Fix missing include.
	* mln/core/internal/box_impl.hh: New.
	* mln/core/internal/set_of.hh: Turn to lazy.
	(operator==): New.
	* mln/accu/median.hh: Conform with g++-2.95.
	* mln/value/viter.hh: Help g++-2.95.
	* mln/value/set.hh: Cosmetics.
	* mln/value/int_u.hh: Help g++-2.95.
	* mln/value/internal/value_like.hh (to_equiv): New.
	* mln/border/thickness.hh: Remove const.
	* img: New.
	* img/lena.pgm: New.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1006 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 9fe6c1fc
2007-07-12 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add naive median to milena + fix problems with g++-2.95.
* tests/window2d.cc: .
* tests/median.cc: .
* tests/box2d.cc: .
* tests/naive_median.cc: New.
* tests/histo.cc: .
* tests/rectangle2d.cc: New.
* mln/convert/to_dpoint.hh: Fix missing include.
* mln/level/naive: New.
* mln/level/naive/median.hh: New.
* mln/level/median.hh: Update.
* mln/io/save_pgm.hh,
* mln/io/load_pgm.hh: Conform with g++-2.95.
* mln/core/dpoint2d.hh (up, down, left, right): New.
* mln/core/box.hh: Add impl inheritance.
* mln/core/rectangle2d.hh: Fake typedef; add FIXME.
(sym_): New.
* mln/core/concept/window.hh (operator-): New.
* mln/core/concept/doc/window.hh: Update.
* mln/core/window.hh (sym_): New.
(operators): Help g++-2.95.
* mln/core/image2d_b.hh: Add impl inheritance.
(init_with, bbox): New.
(nrows, ncols): Remove; now inherited.
* mln/core/internal/coord_impl.hh: Fix missing include.
* mln/core/internal/box_impl.hh: New.
* mln/core/internal/set_of.hh: Turn to lazy.
(operator==): New.
* mln/accu/median.hh: Conform with g++-2.95.
* mln/value/viter.hh: Help g++-2.95.
* mln/value/set.hh: Cosmetics.
* mln/value/int_u.hh: Help g++-2.95.
* mln/value/internal/value_like.hh (to_equiv): New.
* mln/border/thickness.hh: Remove const.
* img: New.
* img/lena.pgm: New.
2007-07-11 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Better milena median.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -220,7 +220,7 @@ namespace mln
template <typename S>
median<S>::operator typename median<S>::value () const
median<S>::operator mln_value(S) () const
{
return to_value();
}
......@@ -229,7 +229,7 @@ namespace mln
typename median<S>::value
median<S>::to_value() const
{
if (not valid_)
if (! valid_)
update_();
return v_;
}
......
......@@ -40,7 +40,7 @@ namespace mln
namespace border
{
const unsigned thickness = 3;
unsigned thickness = 3;
} // end of namespace mln::border
......
......@@ -33,6 +33,8 @@
* \brief Convertions to mln::Dpoint.
*/
# include <mln/core/concept/genpoint.hh>
namespace mln
{
......@@ -40,6 +42,7 @@ namespace mln
namespace convert
{
/// Convert a generalized point \p p into a delta-point.
template <typename P>
mln_dpoint(P) to_dpoint(const GenPoint<P>& p);
......
......@@ -34,6 +34,7 @@
*/
# include <mln/core/concept/box.hh>
# include <mln/core/internal/box_impl.hh>
# include <mln/core/point.hh>
......@@ -50,7 +51,8 @@ namespace mln
* Parameter \c P is the corresponding type of point.
*/
template <typename P>
struct box_ : public Box< box_<P> >
struct box_ : public Box< box_<P> >,
public internal::box_impl_< P::dim, mln_coord(P), box_<P> >
{
/*! \brief Psite associated type.
*/
......
......@@ -75,6 +75,10 @@ namespace mln
/*! \brief Test if the window is symmetric.
*/
bool is_symmetric() const;
/*! \brief Give the symmetrical window.
*/
E sym_() const;
};
} // end of namespace mln::doc
......
......@@ -33,6 +33,7 @@
*/
# include <mln/core/concept/object.hh>
# include <mln/core/concept/iterator.hh>
namespace mln
......@@ -57,6 +58,8 @@ namespace mln
bool is_empty() const;
bool is_centered() const;
bool is_symmetric() const;
E sym_() const;
*/
protected:
......@@ -64,6 +67,14 @@ namespace mln
};
/*! \brief Compute the symmetrical window of \p rhs.
*
* \relates mln::Window
*/
template <typename W>
W operator-(const Window<W>& rhs);
# ifndef MLN_INCLUDE_ONLY
template <typename E>
......@@ -82,6 +93,14 @@ namespace mln
m2 = 0;
bool (E::*m3)() const = & E::is_symmetric;
m3 = 0;
E (E::*m4)() const = & E::sym_;
m4 = 0;
}
template <typename W>
W operator-(const Window<W>& rhs)
{
return exact(rhs).sym_();
}
# endif // ! MLN_INCLUDE_ONLY
......
......@@ -53,6 +53,17 @@ namespace mln
*
* \return A 2D delta-point.
*/
dpoint2d mk_dpoint2d(int row, int col);
const dpoint2d up = mk_dpoint2d( -1, 0 );
const dpoint2d down = mk_dpoint2d( +1, 0 );
const dpoint2d left = mk_dpoint2d( 0, -1 );
const dpoint2d right = mk_dpoint2d( 0, +1 );
# ifndef MLN_INCLUDE_ONLY
dpoint2d mk_dpoint2d(int row, int col)
{
dpoint2d tmp;
......@@ -61,6 +72,8 @@ namespace mln
return tmp;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
......
......@@ -34,6 +34,7 @@
*/
# include <mln/core/internal/image_base.hh>
# include <mln/core/internal/box_impl.hh>
# include <mln/core/box2d.hh>
# include <mln/border/thickness.hh>
......@@ -50,7 +51,8 @@ namespace mln
* thickness around data.
*/
template <typename T>
struct image2d_b : public internal::image_base_< box2d, image2d_b<T> >
struct image2d_b : public internal::image_base_< box2d, image2d_b<T> >,
public internal::box_impl_< 2, int, image2d_b<T> >
{
// warning: just to make effective types appear in Doxygen
......@@ -79,6 +81,7 @@ namespace mln
typedef image2d_b<U> ret;
};
/// Constructor without argument.
image2d_b();
......@@ -96,6 +99,14 @@ namespace mln
/// Assignment operator.
image2d_b& operator=(const image2d_b<T>& rhs);
/// Initialize an empty image.
void init_with(int nrows, int ncols, unsigned bdr = border::thickness);
/// Initialize an empty image.
void init_with(const box2d& b, unsigned bdr = border::thickness);
/// Test if \p p is valid.
bool owns_(const point2d& p) const;
......@@ -105,15 +116,12 @@ namespace mln
/// Give the definition domain.
const box2d& domain() const;
/// Give a bounding box.
const box2d& bbox() const;
/// Give the border thickness.
unsigned border() const;
/// Give the number of rows (not including the border).
unsigned nrows() const;
/// Give the number of cols (not including the border).
unsigned ncols() const;
/// Give the number of cells (points including border ones).
std::size_t ncells() const;
......@@ -128,9 +136,10 @@ namespace mln
private:
box2d b_; // theoretical box
T* buffer_;
T* buffer_;
T** array_;
box2d b_; // theoretical box
unsigned bdr_;
box2d vb_; // virtual box, i.e., box including the virtual border
......@@ -148,15 +157,25 @@ namespace mln
template <typename T>
image2d_b<T>::image2d_b()
: buffer_(0),
array_ (0)
{
buffer_ = 0;
array_ = 0;
bdr_ = border::thickness; // default value in ctors.
bdr_ = border::thickness; // default value in ctors.
}
template <typename T>
image2d_b<T>::image2d_b(int nrows, int ncols, unsigned bdr)
: buffer_(0),
array_ (0)
{
init_with(nrows, ncols, bdr);
}
template <typename T>
void
image2d_b<T>::init_with(int nrows, int ncols, unsigned bdr)
{
mln_precondition(! this->has_data());
b_ = mk_box2d(nrows, ncols);
bdr_ = bdr;
allocate_();
......@@ -164,9 +183,18 @@ namespace mln
template <typename T>
image2d_b<T>::image2d_b(const box2d& b, unsigned bdr)
: b_(b),
bdr_(bdr)
: buffer_(0),
array_ (0)
{
init_with(b, bdr);
}
template <typename T>
void
image2d_b<T>::init_with(const box2d& b, unsigned bdr)
{
mln_precondition(! this->has_data());
b_ = b;
bdr_ = bdr;
allocate_();
}
......@@ -189,7 +217,7 @@ namespace mln
image2d_b<T>&
image2d_b<T>::operator=(const image2d_b<T>& rhs)
{
assert(rhs.has_data());
mln_precondition(rhs.has_data());
if (& rhs == this)
return *this;
if (this->has_data())
......@@ -221,27 +249,19 @@ namespace mln
}
template <typename T>
unsigned
image2d_b<T>::border() const
{
mln_precondition(this->has_data());
return bdr_;
}
template <typename T>
unsigned
image2d_b<T>::nrows() const
const box2d&
image2d_b<T>::bbox() const
{
mln_precondition(this->has_data());
return b_.len(0);
return b_;
}
template <typename T>
unsigned
image2d_b<T>::ncols() const
image2d_b<T>::border() const
{
mln_precondition(this->has_data());
return b_.len(1);
return bdr_;
}
template <typename T>
......@@ -309,8 +329,8 @@ namespace mln
buf += nc;
}
array_ -= vb_.pmin().row();
mln_postcondition(vb_.len(0) == b_.nrows() + 2 * bdr_);
mln_postcondition(vb_.len(1) == b_.ncols() + 2 * bdr_);
mln_postcondition(vb_.len(0) == b_.len(0) + 2 * bdr_);
mln_postcondition(vb_.len(1) == b_.len(1) + 2 * bdr_);
}
template <typename T>
......
// 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_CORE_INTERNAL_BOX_IMPL_HH
# define MLN_CORE_INTERNAL_BOX_IMPL_HH
/*! \file mln/core/internal/box_impl.hh
*
* \internal
*
* \brief Define some implementation classes to provide methods
* related to classes having a bounding box.
*/
# include <mln/core/internal/force_exact.hh>
namespace mln
{
namespace internal
{
template <typename E>
struct box_impl_base_
{
mln_internal_add_force_exact_(box_impl_base_<E>)
};
// box_impl
/*! \brief Implementation class to equip objects having a bounding
* box with methods.
*
* \internal
*/
template <unsigned n, typename C, typename E>
struct box_impl_;
template <typename C, typename E> // FIXME: Add an extra param to replace 'unsigned'.
struct box_impl_<2, C, E>
: box_impl_base_<E>
{
/// Give the number of rows.
unsigned nrows() const;
/// Give the minimum row.
C min_row() const;
/// Give the minimum row.
C max_row() const;
/// Give the number of cols.
unsigned ncols() const;
/// Give the minimum col.
C min_col() const;
/// Give the minimum col.
C max_col() const;
};
# ifndef MLN_INCLUDE_ONLY
// box_impl
// 2
template <typename C, typename E>
unsigned box_impl_<2, C, E>::nrows() const
{
return this->force_exact_().bbox().len(0);
}
template <typename C, typename E>
C box_impl_<2, C, E>::min_row() const
{
return this->force_exact_().bbox().pmin()[0];
}
template <typename C, typename E>
C box_impl_<2, C, E>::max_row() const
{
return this->force_exact_().bbox().pmax()[0];
}
template <typename C, typename E>
unsigned box_impl_<2, C, E>::ncols() const
{
return this->force_exact_().bbox().len(1);
}
template <typename C, typename E>
C box_impl_<2, C, E>::min_col() const
{
return this->force_exact_().bbox().pmin()[1];
}
template <typename C, typename E>
C box_impl_<2, C, E>::max_col() const
{
return this->force_exact_().bbox().pmax()[1];
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::internal
} // end of namespace mln
#endif // ! MLN_CORE_INTERNAL_BOX_IMPL_HH
......@@ -36,7 +36,6 @@
*/
# include <mln/core/internal/force_exact.hh>
# include <mln/core/concept/object.hh>
namespace mln
......
......@@ -44,15 +44,14 @@ namespace mln
namespace internal
{
/*! \brief An "efficient" mathematical set class.
*
* \internal
*
* This set class is designed to store a mathematical set and to
* present it to the user as a linear array.
* present it to the user as a linear array (std::vector).
*
* Elements are stored by copy.
* Elements are stored by copy. Implementation is lazy.
*
* \invariant \a v_.size() == s_.size()
*
......@@ -122,30 +121,35 @@ namespace mln
*/
const std::vector<E>& vec() const;
protected:
/// Constructor without arguments.
set_of_();
private:
/*! \brief Array of elements.
*
* This structure is always up-to-date so that the access method
* vec is as fastest as possible.
* This structure is only updated (if required) when elements
* are accessed.
*/
std::vector<E> v_;
mutable std::vector<E> v_;
private:
/*! \brief Set of elements.
*
* This is an auxiliary structure.
* This structure is always up-to-date w.r.t. the set contents.
*/
std::set<E> s_;
/*! \brief Update both attributes.
/*! \brief Update \a v_ from \a s_.
*
* FIXME: explain.
*/
void update_();
void update_() const;
/// Tell if \a v_ needs to be updated.
mutable bool needs_update_;
};
......@@ -163,14 +167,32 @@ namespace mln
std::ostream& operator<<(std::ostream& ostr, const set_of_<E>& s);
/*! \brief Test if both sets \p lhs and \p rhs are equal.
*
* \param[in] lhs A set.
* \param[in] rhs Another set.
*
* \relates mln::internal::set_of_
*/
template <typename E>
bool operator==(const set_of_<E>& lhs, const set_of_<E>& rhs);
# ifndef MLN_INCLUDE_ONLY
template <typename E>
set_of_<E>::set_of_()
{
needs_update_ = false;
}
template <typename E>
void
set_of_<E>::insert(const E& elt)
{
s_.insert(elt);
update_();
if (needs_update_ == false)
needs_update_ = true;
}
template <typename E>
......@@ -178,6 +200,8 @@ namespace mln
set_of_<E>::element(unsigned i) const
{
assert(i < v_.size());
if (needs_update_)
update_();
return v_[i];
}
......@@ -185,6 +209,8 @@ namespace mln
unsigned
set_of_<E>::nelements() const
{
if (needs_update_)
update_();
return v_.size();
}
......@@ -199,7 +225,7 @@ namespace mln
bool
set_of_<E>::is_empty() const
{