Commit 9fe6c1fc authored by Thierry Geraud's avatar Thierry Geraud
Browse files

Better milena median.

	* tests/median.cc: Update.
	* mln/convert/to_dpoint.hh: New.
	* mln/debug/println.hh (println): Add endl.
	* mln/level/median.hh: New.
	* mln/io/save_pgm.hh: New.
	* mln/io/load_pgm.hh: New.
	* mln/core/box.hh (len): New.
	* mln/core/concept/box.hh: Likewise.
	* mln/core/point.hh (zero): New.
	* mln/core/dpoint.hh: Likewise.
	* mln/core/concept/window.hh (dpoint, point): New.
	* mln/core/window.hh,
	* mln/core/rectangle2d.hh: Update.
	* mln/core/concept/genpoint.hh: Remove dead line.
	* mln/core/concept/dpoint.hh (operator+): New.
	* mln/core/image2d_b.hh: .
	* mln/core/internal/force_exact.hh: Avoid obj creation.
	* mln/accu: New.
	* mln/value/histo.hh: Rename as...
	* mln/value/median.hh: ...this.
	* mln/accu/histo.hh: Rename as...
	* mln/accu/median.hh: ...this.
	* mln/accu/median_alt.hh: New.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1005 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 3c42c279
2007-07-11 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Better milena median.
* tests/median.cc: Update.
* mln/convert/to_dpoint.hh: New.
* mln/debug/println.hh (println): Add endl.
* mln/level/median.hh: New.
* mln/io/save_pgm.hh: New.
* mln/io/load_pgm.hh: New.
* mln/core/box.hh (len): New.
* mln/core/concept/box.hh: Likewise.
* mln/core/point.hh (zero): New.
* mln/core/dpoint.hh: Likewise.
* mln/core/concept/window.hh (dpoint, point): New.
* mln/core/window.hh,
* mln/core/rectangle2d.hh: Update.
* mln/core/concept/genpoint.hh: Remove dead line.
* mln/core/concept/dpoint.hh (operator+): New.
* mln/core/image2d_b.hh: .
* mln/core/internal/force_exact.hh: Avoid obj creation.
* mln/accu: New.
* mln/value/histo.hh: Rename as...
* mln/value/median.hh: ...this.
* mln/accu/histo.hh: Rename as...
* mln/accu/median.hh: ...this.
* mln/accu/median_alt.hh: New.
2007-07-11 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add border to milena 2D image.
......
......@@ -25,8 +25,8 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_VALUE_HISTO_HH
# define MLN_VALUE_HISTO_HH
#ifndef MLN_ACCU_HISTO_HH
# define MLN_ACCU_HISTO_HH
/*! \file mln/value/histo.hh
*
......@@ -43,7 +43,7 @@
namespace mln
{
namespace value
namespace accu
{
......@@ -58,7 +58,7 @@ namespace mln
void take(const value& v);
void untake(const value& v);
void clear();
void init();
std::size_t operator()(const value& v) const;
std::size_t operator[](std::size_t i) const;
......@@ -86,7 +86,7 @@ namespace mln
/*! Generic histogram class over the set of values of type \c T.
*/
template <typename T>
struct histo_on_type : public histo_on_set< set_<T> >
struct histo_on_type : public histo_on_set< value::set_<T> >
{
histo_on_type();
};
......@@ -127,9 +127,10 @@ namespace mln
template <typename S>
void
histo_on_set<S>::clear()
histo_on_set<S>::init()
{
std::fill(h_.begin(), h_.end(), 0);
sum_ = 0;
}
template <typename S>
......@@ -180,7 +181,8 @@ namespace mln
{
mln_viter(S) v(h.vset());
for_all(v)
ostr << v << ':' << h(v) << ' ';
if (h(v) != 0)
ostr << v << ':' << h(v) << ' ';
ostr << std::endl;
return ostr;
}
......@@ -190,7 +192,7 @@ namespace mln
template <typename T>
histo_on_type<T>::histo_on_type()
: histo_on_set< set_<T> >(set_<T>::the())
: histo_on_set< value::set_<T> >(value::set_<T>::the())
{
}
......@@ -198,9 +200,9 @@ namespace mln
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::value
} // end of namespace mln::accu
} // end of namespace mln
#endif // ! MLN_VALUE_HISTO_HH
#endif // ! MLN_ACCU_HISTO_HH
// 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_ACCU_MEDIAN_HH
# define MLN_ACCU_MEDIAN_HH
/*! \file mln/accu/median.hh
*
* \brief Define FIXME
*/
# include <mln/accu/histo.hh>
namespace mln
{
namespace accu
{
/*! Generic median function based on histogram over a value set
* with type \c S.
*/
template <typename S>
struct median
{
typedef mln_value(S) value;
median(const Value_Set<S>& s);
void take(const value& v);
void untake(const value& v);
void init();
unsigned card() const { return h_.sum(); }
operator value() const;
value to_value() const;
const histo_on_set<S>& histo() const;
// FIXME: remove
void debug__() const
{
std::cout << " i = " << i_
<< " v = " << v_
<< " s = " << sum_minus_ << " ; " << h_[i_] << " ; " << sum_plus_ << " = " << h_.sum()
<< std::endl;
}
protected:
mutable histo_on_set<S> h_;
const S& s_; // derived from h_
mutable std::size_t sum_minus_, sum_plus_;
mutable bool valid_;
mutable std::size_t i_; // the median index
mutable value v_; // the median value
// Auxiliary methods
void update_() const;
void go_minus_() const;
void go_plus_() const;
};
template <typename T>
struct median_on : public median< value::set_<T> >
{
median_on()
: median< value::set_<T> >(value::set_<T>::the())
{
}
};
# ifndef MLN_INCLUDE_ONLY
template <typename S>
median<S>::median(const Value_Set<S>& s)
: h_(s),
s_(h_.vset())
{
init();
}
template <typename S>
void
median<S>::take(const value& v)
{
h_.take(v);
if (v < v_)
++sum_minus_;
else if (v > v_)
++sum_plus_;
if (valid_)
valid_ = false;
}
template <typename S>
void
median<S>::untake(const value& v)
{
mln_precondition(h_(v) != 0);
h_.untake(v);
if (v < v_)
--sum_minus_;
else if (v > v_)
--sum_plus_;
if (valid_)
valid_ = false;
}
template <typename S>
void
median<S>::update_() const
{
valid_ = true;
if (h_.sum() == 0)
return;
if (2 * sum_minus_ > h_.sum())
go_minus_();
else
if (2 * sum_plus_ > h_.sum())
go_plus_();
else
if (h_[i_] == 0)
{
// go to the heaviest side
if (sum_plus_ > sum_minus_)
go_plus_();
else
go_minus_(); // default when both sides are balanced
}
}
template <typename S>
void
median<S>::go_minus_() const
{
do
{
sum_plus_ += h_[i_];
do
--i_;
while (h_[i_] == 0);
sum_minus_ -= h_[i_];
}
while (2 * sum_minus_ > h_.sum());
v_ = s_[i_];
}
template <typename S>
void
median<S>::go_plus_() const
{
do
{
sum_minus_ += h_[i_];
do
++i_;
while (h_[i_] == 0);
sum_plus_ -= h_[i_];
}
while (2 * sum_plus_ > h_.sum());
v_ = s_[i_];
}
template <typename S>
void
median<S>::init()
{
h_.init();
sum_minus_ = 0;
sum_plus_ = 0;
i_ = (mln_max(value) - mln_min(value)) / 2;
v_ = s_[i_];
valid_ = true;
}
template <typename S>
median<S>::operator typename median<S>::value () const
{
return to_value();
}
template <typename S>
typename median<S>::value
median<S>::to_value() const
{
if (not valid_)
update_();
return v_;
}
template <typename S>
const histo_on_set<S>&
median<S>::histo() const
{
return h_;
}
template <typename S>
std::ostream& operator<<(std::ostream& ostr, const median<S>& m)
{
m.debug__();
return ostr << m.to_value();
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::accu
} // end of namespace mln
#endif // ! MLN_ACCU_MEDIAN_HH
......@@ -25,37 +25,37 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_VALUE_MEDIAN_HH
# define MLN_VALUE_MEDIAN_HH
#ifndef MLN_ACCU_MEDIAN_ALT_HH
# define MLN_ACCU_MEDIAN_ALT_HH
/*! \file mln/value/median.hh
/*! \file mln/accu/median_alt.hh
*
* \brief Define FIXME
*/
# include <mln/value/histo.hh>
# include <mln/accu/histo.hh>
namespace mln
{
namespace value
namespace accu
{
/*! Generic median function based on histogram over a value set
/*! Generic median_alt function based on histogram over a value set
* with type \c S.
*/
template <typename S>
struct median
struct median_alt
{
typedef mln_value(S) value;
median(const Value_Set<S>& s);
median_alt(const Value_Set<S>& s);
void take(const value& v);
void untake(const value& v);
void clear();
void init();
operator value() const;
value to_value() const;
......@@ -85,22 +85,31 @@ namespace mln
};
template <typename T>
struct median_alt_on : public median_alt< value::set_<T> >
{
median_alt_on()
: median_alt< value::set_<T> >(value::set_<T>::the())
{
}
};
# ifndef MLN_INCLUDE_ONLY
template <typename S>
median<S>::median(const Value_Set<S>& s)
median_alt<S>::median_alt(const Value_Set<S>& s)
: h_(s),
s_(h_.vset())
{
clear();
init();
}
template <typename S>
void
median<S>::take(const value& v)
median_alt<S>::take(const value& v)
{
// update h_
h_.take(v);
......@@ -143,7 +152,7 @@ namespace mln
template <typename S>
void
median<S>::untake(const value& v)
median_alt<S>::untake(const value& v)
{
mln_precondition(h_(v) != 0);
......@@ -154,7 +163,7 @@ namespace mln
// the only value has been removed
if (h_.sum() == 0)
{
clear();
init();
return;
}
......@@ -196,7 +205,7 @@ namespace mln
template <typename S>
void
median<S>::go_minus_()
median_alt<S>::go_minus_()
{
do
{
......@@ -213,7 +222,7 @@ namespace mln
template <typename S>
void
median<S>::go_plus_()
median_alt<S>::go_plus_()
{
do
{
......@@ -230,9 +239,9 @@ namespace mln
template <typename S>
void
median<S>::clear()
median_alt<S>::init()
{
h_.clear();
h_.init();
sum_minus_ = 0;
sum_plus_ = 0;
i_ = (mln_max(value) - mln_min(value)) / 2;
......@@ -240,20 +249,20 @@ namespace mln
}
template <typename S>
median<S>::operator typename median<S>::value () const
median_alt<S>::operator typename median_alt<S>::value () const
{
return v_;
}
template <typename S>
typename median<S>::value
median<S>::to_value() const
typename median_alt<S>::value
median_alt<S>::to_value() const
{
return v_;
}
template <typename S>
std::ostream& operator<<(std::ostream& ostr, const median<S>& m)
std::ostream& operator<<(std::ostream& ostr, const median_alt<S>& m)
{
m.debug__();
return ostr << m.to_value();
......@@ -262,9 +271,9 @@ namespace mln
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::value
} // end of namespace mln::accu
} // end of namespace mln
#endif // ! MLN_VALUE_MEDIAN_HH
#endif // ! MLN_ACCU_MEDIAN_ALT_HH
// 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_CONVERT_TO_DPOINT_HH
# define MLN_CONVERT_TO_DPOINT_HH
/*! \file mln/convert/to_dpoint.hh
*
* \brief Convertions to mln::Dpoint.
*/
namespace mln
{
namespace convert
{
template <typename P>
mln_dpoint(P) to_dpoint(const GenPoint<P>& p);
# ifndef MLN_INCLUDE_ONLY
template <typename P>
mln_dpoint(P) to_dpoint(const GenPoint<P>& p_)
{
const P& p = p_.force_exact_();
mln_dpoint(P) tmp;
for (unsigned i = 0; i < P::dim; ++i)
tmp[i] = p[i];
return tmp;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::convert
} // end of namespace mln
#endif // ! MLN_CONVERT_TO_DPOINT_HH
......@@ -88,6 +88,11 @@ namespace mln
*/
P& pmax();
/*! \brief Give the length of the \p i-th side.
* \pre i < dim
*/
unsigned len(unsigned i) const;
/*! \brief Constructor without argument.
*/
box_();
......@@ -150,6 +155,14 @@ namespace mln
return pmax_;
}
template <typename P>
unsigned
box_<P>::len(unsigned i) const
{
mln_precondition(i < P::dim);
return 1 + pmax_[i] - pmin_[i];
}
template <typename P>
box_<P>::box_()
{
......
......@@ -52,6 +52,7 @@ namespace mln
/*
const point& pmin() const;
const point& pmax() const;
unsigned len(unsigned i) const; // FIXME: Doc!
*/