Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-04-29 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Debugging fixed segmentation.
* fabien/igr/seg_fixed.cc: Debugging, crash at runtime.
---
seg_fixed.cc | 39 +++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
Index: trunk/milena/sandbox/fabien/igr/seg_fixed.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/seg_fixed.cc (revision 3727)
+++ trunk/milena/sandbox/fabien/igr/seg_fixed.cc (revision 3728)
@@ -8,7 +8,9 @@
#include <mln/core/routine/duplicate.hh>
#include <mln/io/dump/all.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/value/int_u8.hh>
#include <mln/value/int_u12.hh>
#include <mln/accu/sum.hh>
@@ -16,10 +18,14 @@
#include <mln/debug/quiet.hh>
#include <mln/convert/from_to.hh>
#include <mln/level/compute.hh>
+#include <mln/level/stretch.hh>
#include <mln/util/array.hh>
+#include <mln/world/inter_pixel/display_edge.hh>
+
using namespace mln;
+using value::int_u8;
using value::int_u12;
@@ -56,13 +62,20 @@
{
float res = 0.f;
- if (!ima_sum.bbox().has(n))
- return res;
-
+ std::cout << "computing..." << std::endl;
+ std::cout << "ima_arr.bbox(): " << ima_arr.bbox() << std::endl;
+ std::cout << "ima_arr(p).nelements(): " << ima_arr(p).nelements() << std::endl;
+ std::cout << "ima_arr(n).nelements(): " << ima_arr(n).nelements() << std::endl;
for (unsigned i = 0; i < ima_arr(p).nelements(); ++i)
res += std::min(ima_arr(p)[i], ima_arr(n)[i]);
+
+ float max = std::max(ima_sum(p), ima_sum(n));
+ if (max)
res /= std::max(ima_sum(p), ima_sum(n));
+ else
+ res = 0.f;
+ //std::cout << "\t" << res << std::endl;
return res;
}
@@ -88,6 +101,7 @@
box2d b = ima_arr.bbox();
image2d<float> edges(make::box2d(2 * b.pmin()[0], 2 * b.pmin()[1],
2 * b.pmax()[0], 2 * b.pmax()[1]));
+ box2d edge_b = edges.bbox();
data::fill(edges, -1.f);
image2d<float> ima_sum;
initialize(ima_sum, ima_arr);
@@ -100,9 +114,17 @@
for_all(n)
{
point2d location = get_edge_location(p, n);
- //std::cout << "p: " << p << " | n: " << n << " | e: " << location << std::endl;
- if (edges(location) == -1.f)
- edges(location) = compute_dist(ima_arr, ima_sum, p, n);
+ if (b.has(n) && edge_b.has(location) && edges(location) == -1.f)
+ {
+ std::cout << "p: " << p << " | n: " << n << " | e: " << location << std::endl;
+ std::cout << "will compute..." << std::endl;
+ float res = compute_dist(ima_arr, ima_sum, p, n);
+ std::cout << "has computed" << std::endl << std::endl;
+ std::cout << "\t" << res << std::endl;
+ edges(location) = res;
+ }
+ else
+ std::cout << "." << std::endl;
}
}
@@ -124,6 +146,7 @@
if (argc != 2)
return usage(argv[0]);
+ // Initialization.
image3d<int_u12> input;
io::dump::load(input, argv[1]);
image2d<util::array<int_u12> > ima_arr;
@@ -136,7 +159,11 @@
ima_arr(p).append(tmp_slice(p));
}
+ // Edges computation.
image2d<float> edges = dist_on_edges(ima_arr);
+ // Display.
+ io::pgm::save(level::stretch(int_u8(), world::inter_pixel::display_edge(edges, 0.0, 3)), "edges.pgm");
+
return 0;
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Turn take_as_init as a 'template method' pattern.
* mln/core/concept/accumulator.hh
(take_as_init): Rename as...
(take_as_init_): ...this. This is default implementation.
(take_as_init): New. Dispatch to take_as_init_.
Now, we have the "template method" method pattern. It is
cleaner since we do not have any overriding for the
client-side method.
(take_n_times, take_n_times_): New.
* mln/accu/nil.hh,
* mln/accu/tuple.hh,
* mln/accu/pair.hh,
* mln/accu/lor.hh,
* mln/accu/sum.hh,
* mln/accu/inf.hh,
* mln/accu/land_basic.hh,
* mln/accu/min.hh,
* mln/accu/max.hh,
* mln/accu/bbox.hh,
* mln/accu/min_h.hh,
* mln/accu/max_h.hh,
* mln/accu/lor_basic.hh,
* mln/accu/p.hh,
* mln/accu/rms.hh,
* mln/accu/rank_high_quant.hh,
* mln/accu/v.hh,
* mln/accu/rank_bool.hh,
* mln/accu/sup.hh,
* mln/accu/land.hh,
* mln/morpho/attribute/sum.hh,
* mln/morpho/attribute/count_adjacent_vertices.hh,
* mln/morpho/attribute/sharpness.hh,
* mln/morpho/attribute/volume.hh,
* mln/morpho/attribute/height.hh,
* mln/morpho/attribute/card.hh (take_as_init): Update.
Rename as...
(take_as_init_): ...this overriding name.
* tests/accu/count.cc: Update.
mln/accu/bbox.hh | 4 -
mln/accu/inf.hh | 4 -
mln/accu/land.hh | 4 -
mln/accu/land_basic.hh | 4 -
mln/accu/lor.hh | 4 -
mln/accu/lor_basic.hh | 4 -
mln/accu/max.hh | 4 -
mln/accu/max_h.hh | 6 +-
mln/accu/min.hh | 4 -
mln/accu/min_h.hh | 6 +-
mln/accu/nil.hh | 4 -
mln/accu/p.hh | 6 +-
mln/accu/pair.hh | 8 +-
mln/accu/rank_bool.hh | 4 -
mln/accu/rank_high_quant.hh | 4 -
mln/accu/rms.hh | 4 -
mln/accu/sum.hh | 4 -
mln/accu/sup.hh | 4 -
mln/accu/tuple.hh | 14 ++--
mln/accu/v.hh | 12 ++--
mln/core/concept/accumulator.hh | 72 +++++++++++++++++++++++-
mln/morpho/attribute/card.hh | 14 ++--
mln/morpho/attribute/count_adjacent_vertices.hh | 4 -
mln/morpho/attribute/height.hh | 12 ++--
mln/morpho/attribute/sharpness.hh | 10 +--
mln/morpho/attribute/sum.hh | 12 ++--
mln/morpho/attribute/volume.hh | 12 ++--
tests/accu/count.cc | 39 ++++++++-----
28 files changed, 182 insertions(+), 101 deletions(-)
Index: mln/core/concept/accumulator.hh
--- mln/core/concept/accumulator.hh (revision 3726)
+++ mln/core/concept/accumulator.hh (working copy)
@@ -97,10 +97,30 @@
bool is_valid() const;
*/
- // Default impl.
+ /// Take as initialization the value \p t.
+ ///
+ /// Dev note: this is a final method; override if needed
+ /// by take_as_init_ (ending with '_').
template <typename T>
void take_as_init(const T& t); // 't' is either argument or E.
+ /// Default implementation of "take as initialization".
+ template <typename T>
+ void take_as_init_(const T& t);
+
+
+ /// Take \p n times the value \p t.
+ ///
+ /// Dev note: this is a final method; override if needed
+ /// by take_as_init_ (ending with '_').
+ template <typename T>
+ void take_n_times(unsigned n, const T& t);
+
+ /// Default implementation of "take n times".
+ template <typename T>
+ void take_n_times_(unsigned n, const T& t);
+
+
protected:
Accumulator();
};
@@ -160,15 +180,63 @@
m6 = 0;
}
+
+ // take_as_init
+
template <typename E>
template <typename T>
void
- Accumulator<E>::take_as_init(const T& t) // either argument or E
+ Accumulator<E>::take_as_init(const T& t)
{
+ typedef mln_exact(T) T_;
+ typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
+ typedef mlc_converts_to(T_, E) t_is_accumulator;
+ mlc_or(t_is_argument, t_is_accumulator)::check();
+
+ // Dispatch.
+ exact(this)->take_as_init_(t);
+ }
+
+ template <typename E>
+ template <typename T>
+ void
+ Accumulator<E>::take_as_init_(const T& t)
+ {
+ // Default impl.
exact(this)->init();
exact(this)->take(t);
}
+
+ // take n times
+
+ template <typename E>
+ template <typename T>
+ void
+ Accumulator<E>::take_n_times(unsigned n, const T& t)
+ {
+ typedef mln_exact(T) T_;
+ typedef mlc_converts_to(T_, mln_argument(E)) t_is_argument;
+ typedef mlc_converts_to(T_, E) t_is_accumulator;
+ mlc_or(t_is_argument, t_is_accumulator)::check();
+
+ if (n == 0u)
+ return;
+
+ // Dispatch.
+ exact(this)->take_n_times_(n, t);
+ }
+
+ template <typename E>
+ template <typename T>
+ void
+ Accumulator<E>::take_n_times_(unsigned n, const T& t)
+ {
+ // Default impl.
+ for (unsigned i = 0; i < n; ++i)
+ exact(this)->take(t);
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
Index: mln/accu/nil.hh
--- mln/accu/nil.hh (revision 3726)
+++ mln/accu/nil.hh (working copy)
@@ -58,7 +58,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument&);
+ void take_as_init_(const argument&);
void take(const argument&);
void take(const nil<T>&);
/// \}
@@ -114,7 +114,7 @@
template <typename T>
inline
void
- nil<T>::take_as_init(const argument&)
+ nil<T>::take_as_init_(const argument&)
{
}
Index: mln/accu/tuple.hh
--- mln/accu/tuple.hh (revision 3726)
+++ mln/accu/tuple.hh (working copy)
@@ -85,7 +85,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const tuple<A, n, BOOST_PP_ENUM_PARAMS(10, T)>& other);
/// \}
@@ -148,10 +148,10 @@
tuplehelper<n - 1, T>::init(a);
}
- static void take_as_init(typename T::intern& a, const typename T::argument& argument)
+ static void take_as_init_(typename T::intern& a, const typename T::argument& argument)
{
- boost::get<n - 1>(a).take_as_init(argument);
- tuplehelper<n - 1, T>::take_as_init(a, argument);
+ boost::get<n - 1>(a).take_as_init_(argument);
+ tuplehelper<n - 1, T>::take_as_init_(a, argument);
}
static void take(typename T::intern& a, const typename T::argument& argument)
@@ -177,7 +177,7 @@
struct tuplehelper<0, T>
{
static void init(typename T::intern&) {}
- static void take_as_init(typename T::intern&, const typename T::argument&) {}
+ static void take_as_init_(typename T::intern&, const typename T::argument&) {}
static void take(typename T::intern&, const typename T::argument) {}
static void take(typename T::intern&, const typename T::intern&) {}
static void to_result(const typename T::intern&, typename T::result&) {}
@@ -202,9 +202,9 @@
template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
inline
void
- tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take_as_init(const argument& t)
+ tuple<A,n,BOOST_PP_ENUM_PARAMS(10,T) >::take_as_init_(const argument& t)
{
- internal::tuplehelper<n, self>::take_as_init(this->a_, t);
+ internal::tuplehelper<n, self>::take_as_init_(this->a_, t);
}
template <typename A, unsigned n, BOOST_PP_ENUM_PARAMS(10, typename T)>
Index: mln/accu/pair.hh
--- mln/accu/pair.hh (revision 3726)
+++ mln/accu/pair.hh (working copy)
@@ -70,7 +70,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const pair<A1,A2,T>& other);
/// \}
@@ -135,10 +135,10 @@
template <typename A1, typename A2, typename T>
inline
void
- pair<A1,A2,T>::take_as_init(const argument& t)
+ pair<A1,A2,T>::take_as_init_(const argument& t)
{
- a1_.take_as_init(t);
- a2_.take_as_init(t);
+ a1_.take_as_init_(t);
+ a2_.take_as_init_(t);
}
template <typename A1, typename A2, typename T>
Index: mln/accu/lor.hh
--- mln/accu/lor.hh (revision 3726)
+++ mln/accu/lor.hh (working copy)
@@ -55,7 +55,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const lor& other);
@@ -110,7 +110,7 @@
}
inline
- void lor::take_as_init(const argument& t)
+ void lor::take_as_init_(const argument& t)
{
ntrue_ = t ? 1 : 0;
}
Index: mln/accu/sum.hh
--- mln/accu/sum.hh (revision 3726)
+++ mln/accu/sum.hh (working copy)
@@ -67,7 +67,7 @@
/// \{
void init();
void take(const argument& t);
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const sum<T,S>& other);
/// \}
@@ -129,7 +129,7 @@
template <typename T, typename S>
inline
- void sum<T,S>::take_as_init(const argument& t)
+ void sum<T,S>::take_as_init_(const argument& t)
{
s_ = static_cast<S>(t);
}
Index: mln/accu/inf.hh
--- mln/accu/inf.hh (revision 3726)
+++ mln/accu/inf.hh (working copy)
@@ -60,7 +60,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const inf<T>& other);
/// \}
@@ -120,7 +120,7 @@
template <typename T>
inline
- void inf<T>::take_as_init(const argument& t)
+ void inf<T>::take_as_init_(const argument& t)
{
t_ = t;
}
Index: mln/accu/land_basic.hh
--- mln/accu/land_basic.hh (revision 3726)
+++ mln/accu/land_basic.hh (working copy)
@@ -57,7 +57,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const land_basic& other);
@@ -114,7 +114,7 @@
}
inline
- void land_basic::take_as_init(const argument& t)
+ void land_basic::take_as_init_(const argument& t)
{
res_ = t;
}
Index: mln/accu/min.hh
--- mln/accu/min.hh (revision 3726)
+++ mln/accu/min.hh (working copy)
@@ -60,7 +60,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const min<T>& other);
/// \}
@@ -119,7 +119,7 @@
template <typename T>
inline
- void min<T>::take_as_init(const argument& t)
+ void min<T>::take_as_init_(const argument& t)
{
t_ = t;
}
Index: mln/accu/max.hh
--- mln/accu/max.hh (revision 3726)
+++ mln/accu/max.hh (working copy)
@@ -58,7 +58,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const max<T>& other);
/// \}
@@ -117,7 +117,7 @@
template <typename T>
inline
void
- max<T>::take_as_init(const argument& t)
+ max<T>::take_as_init_(const argument& t)
{
t_ = t;
}
Index: mln/accu/bbox.hh
--- mln/accu/bbox.hh (revision 3726)
+++ mln/accu/bbox.hh (working copy)
@@ -58,7 +58,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const P& p);
+ void take_as_init_(const P& p);
void take(const P& p);
void take(const bbox<P>& other);
void take(const box<P>& b);
@@ -114,7 +114,7 @@
template <typename P>
inline
void
- bbox<P>::take_as_init(const P& p)
+ bbox<P>::take_as_init_(const P& p)
{
b_.pmin() = p;
b_.pmax() = p;
Index: mln/accu/min_h.hh
--- mln/accu/min_h.hh (revision 3726)
+++ mln/accu/min_h.hh (working copy)
@@ -58,7 +58,7 @@
/// \{
void init();
void take(const argument& t);
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const min_h<V>& other);
void untake(const argument& t);
/// \}
@@ -132,7 +132,7 @@
{
if (h_.sum() == 0)
{
- this->take_as_init(t);
+ this->take_as_init_(t);
return;
}
h_.take(t);
@@ -233,7 +233,7 @@
template <typename V>
inline
void
- min_h<V>::take_as_init(const argument& t)
+ min_h<V>::take_as_init_(const argument& t)
{
h_.take(t);
sum_ = 0;
Index: mln/accu/max_h.hh
--- mln/accu/max_h.hh (revision 3726)
+++ mln/accu/max_h.hh (working copy)
@@ -57,7 +57,7 @@
/// \{
void init();
void take(const argument& t);
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const max_h<V>& other);
void untake(const argument& t);
/// \}
@@ -131,7 +131,7 @@
{
if (h_.sum() == 0)
{
- this->take_as_init(t);
+ this->take_as_init_(t);
return;
}
h_.take(t);
@@ -232,7 +232,7 @@
template <typename V>
inline
void
- max_h<V>::take_as_init(const argument& t)
+ max_h<V>::take_as_init_(const argument& t)
{
h_.take(t);
sum_ = 0;
Index: mln/accu/lor_basic.hh
--- mln/accu/lor_basic.hh (revision 3726)
+++ mln/accu/lor_basic.hh (working copy)
@@ -57,7 +57,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const lor_basic& other);
@@ -114,7 +114,7 @@
}
inline
- void lor_basic::take_as_init(const argument& t)
+ void lor_basic::take_as_init_(const argument& t)
{
res_ = t;
}
Index: mln/accu/p.hh
--- mln/accu/p.hh (revision 3726)
+++ mln/accu/p.hh (working copy)
@@ -60,7 +60,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const p<A>& other);
/// \}
@@ -123,9 +123,9 @@
template <typename A>
inline
void
- p<A>::take_as_init(const argument& t)
+ p<A>::take_as_init_(const argument& t)
{
- a_.take_as_init(t.p()); // FIXME: Generalize with "psite(t)".
+ a_.take_as_init_(t.p()); // FIXME: Generalize with "psite(t)".
}
template <typename A>
Index: mln/accu/rms.hh
--- mln/accu/rms.hh (revision 3726)
+++ mln/accu/rms.hh (working copy)
@@ -58,7 +58,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const T& p);
+ void take_as_init_(const T& p);
void take(const T& p);
void take(const rms<T,V>& other);
/// \}
@@ -118,7 +118,7 @@
template <typename T, typename V>
inline
void
- rms<T,V>::take_as_init(const T& t)
+ rms<T,V>::take_as_init_(const T& t)
{
v_ += t * t;
++count_;
Index: mln/accu/rank_high_quant.hh
--- mln/accu/rank_high_quant.hh (revision 3726)
+++ mln/accu/rank_high_quant.hh (working copy)
@@ -61,7 +61,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const rank<T>& other);
void sort();
@@ -139,7 +139,7 @@
template <typename T>
inline
- void rank<T>::take_as_init(const argument& t)
+ void rank<T>::take_as_init_(const argument& t)
{
elts_.push_back(t);
is_sorted_ = false;
Index: mln/accu/v.hh
--- mln/accu/v.hh (revision 3726)
+++ mln/accu/v.hh (working copy)
@@ -60,11 +60,11 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const val<A>& other);
template <typename I>
- void take_as_init(const util::pix<I>& pix);
+ void take_as_init_(const util::pix<I>& pix);
template <typename I>
void take(const util::pix<I>& pix);
/// \}
@@ -127,9 +127,9 @@
template <typename A>
inline
void
- val<A>::take_as_init(const argument& t)
+ val<A>::take_as_init_(const argument& t)
{
- a_.take_as_init(t);
+ a_.take_as_init_(t);
}
template <typename A>
@@ -152,9 +152,9 @@
template <typename I>
inline
void
- val<A>::take_as_init(const util::pix<I>& pix)
+ val<A>::take_as_init_(const util::pix<I>& pix)
{
- a_.take_as_init(pix.v()); // FIXME: Generalize with "value(pix)".
+ a_.take_as_init_(pix.v()); // FIXME: Generalize with "value(pix)".
}
template <typename A>
Index: mln/accu/rank_bool.hh
--- mln/accu/rank_bool.hh (revision 3726)
+++ mln/accu/rank_bool.hh (working copy)
@@ -62,7 +62,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const rank<bool>& other);
void untake(const argument& t);
@@ -105,7 +105,7 @@
}
inline
- void rank<bool>::take_as_init(const argument& t)
+ void rank<bool>::take_as_init_(const argument& t)
{
nfalse_ = t ? 0 : 1;
}
Index: mln/accu/sup.hh
--- mln/accu/sup.hh (revision 3726)
+++ mln/accu/sup.hh (working copy)
@@ -60,7 +60,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const sup<T>& other);
/// \}
@@ -120,7 +120,7 @@
template <typename T>
inline
- void sup<T>::take_as_init(const argument& t)
+ void sup<T>::take_as_init_(const argument& t)
{
t_ = t;
}
Index: mln/accu/land.hh
--- mln/accu/land.hh (revision 3726)
+++ mln/accu/land.hh (working copy)
@@ -55,7 +55,7 @@
/// Manipulators.
/// \{
void init();
- void take_as_init(const argument& t);
+ void take_as_init_(const argument& t);
void take(const argument& t);
void take(const land& other);
@@ -110,7 +110,7 @@
}
inline
- void land::take_as_init(const argument& t)
+ void land::take_as_init_(const argument& t)
{
nfalse_ = t ? 0 : 1;
}
Index: mln/morpho/attribute/sum.hh
--- mln/morpho/attribute/sum.hh (revision 3726)
+++ mln/morpho/attribute/sum.hh (working copy)
@@ -96,8 +96,8 @@
void take(const util::pix<I>& px);
void take(const sum<I,S>& other);
- void take_as_init(const argument& v);
- void take_as_init(const util::pix<I>& px);
+ void take_as_init_(const argument& v);
+ void take_as_init_(const util::pix<I>& px);
/// \}
/// Get the value of the accumulator.
@@ -167,12 +167,12 @@
s_ += other.s_;
}
- // take_as_init.
+ // take_as_init_.
template <typename I, typename S>
inline
void
- sum<I,S>::take_as_init(const argument& v)
+ sum<I,S>::take_as_init_(const argument& v)
{
s_ = v;
}
@@ -180,9 +180,9 @@
template <typename I, typename S>
inline
void
- sum<I,S>::take_as_init(const util::pix<I>& px)
+ sum<I,S>::take_as_init_(const util::pix<I>& px)
{
- take_as_init(px.v());
+ take_as_init_(px.v());
}
template <typename I, typename S>
Index: mln/morpho/attribute/count_adjacent_vertices.hh
--- mln/morpho/attribute/count_adjacent_vertices.hh (revision 3726)
+++ mln/morpho/attribute/count_adjacent_vertices.hh (working copy)
@@ -98,7 +98,7 @@
void take(const argument& px);
void take(const count_adjacent_vertices<I>& other);
- void take_as_init(const argument& px);
+ void take_as_init_(const argument& px);
/// \}
/// Get the value of the accumulator.
@@ -160,7 +160,7 @@
template <typename I>
inline
void
- count_adjacent_vertices<I>::take_as_init(const argument& px)
+ count_adjacent_vertices<I>::take_as_init_(const argument& px)
{
vertices_.clear();
take(px);
Index: mln/morpho/attribute/sharpness.hh
--- mln/morpho/attribute/sharpness.hh (revision 3726)
+++ mln/morpho/attribute/sharpness.hh (working copy)
@@ -94,7 +94,7 @@
void take(const mln_value(I)& v);
void take(const sharpness<I>& other);
- void take_as_init(const mln_value(I)& v);
+ void take_as_init_(const mln_value(I)& v);
/// \}
/// Get the value of the accumulator.
@@ -146,7 +146,7 @@
{
if (! is_valid())
{
- take_as_init(v);
+ take_as_init_(v);
return;
}
volume_.take(v);
@@ -166,10 +166,10 @@
template <typename I>
inline
void
- sharpness<I>::take_as_init(const mln_value(I)& v)
+ sharpness<I>::take_as_init_(const mln_value(I)& v)
{
- volume_.take_as_init(v);
- height_.take_as_init(v);
+ volume_.take_as_init_(v);
+ height_.take_as_init_(v);
}
template <typename I>
Index: mln/morpho/attribute/volume.hh
--- mln/morpho/attribute/volume.hh (revision 3726)
+++ mln/morpho/attribute/volume.hh (working copy)
@@ -93,8 +93,8 @@
void take(const util::pix<I>& px);
void take(const volume<I>& other);
- void take_as_init(const mln_value(I)& v);
- void take_as_init(const util::pix<I>& px);
+ void take_as_init_(const mln_value(I)& v);
+ void take_as_init_(const util::pix<I>& px);
/// \}
/// Get the value of the accumulator.
@@ -143,7 +143,7 @@
mln_invariant(volume_ != mln_max(unsigned));
if (! is_valid())
{
- take_as_init(v);
+ take_as_init_(v);
return;
}
++area_;
@@ -176,7 +176,7 @@
template <typename I>
inline
void
- volume<I>::take_as_init(const mln_value(I)& v)
+ volume<I>::take_as_init_(const mln_value(I)& v)
{
cur_level_ = v;
area_ = 1;
@@ -186,9 +186,9 @@
template <typename I>
inline
void
- volume<I>::take_as_init(const util::pix<I>& px)
+ volume<I>::take_as_init_(const util::pix<I>& px)
{
- take_as_init(px.v());
+ take_as_init_(px.v());
}
template <typename I>
Index: mln/morpho/attribute/height.hh
--- mln/morpho/attribute/height.hh (revision 3726)
+++ mln/morpho/attribute/height.hh (working copy)
@@ -93,8 +93,8 @@
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);
+ 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.
@@ -139,7 +139,7 @@
{
if (!is_valid ())
{
- take_as_init(v);
+ take_as_init_(v);
}
cur_ = v;
}
@@ -182,7 +182,7 @@
template <typename I>
inline
void
- height<I>::take_as_init(const mln_value(I)& v)
+ height<I>::take_as_init_(const mln_value(I)& v)
{
cur_ = ref_ = v;
initialized_ = true;
@@ -191,9 +191,9 @@
template <typename I>
inline
void
- height<I>::take_as_init(const util::pix<I>& px)
+ height<I>::take_as_init_(const util::pix<I>& px)
{
- take_as_init(px.v());
+ take_as_init_(px.v());
}
Index: mln/morpho/attribute/card.hh
--- mln/morpho/attribute/card.hh (revision 3726)
+++ mln/morpho/attribute/card.hh (working copy)
@@ -94,9 +94,9 @@
void take(const util::pix<I>& px);
void take(const card<I>& other);
- void take_as_init();
- void take_as_init(const util::pix<I>& px);
- using super_::take_as_init;
+ void take_as_init_();
+ void take_as_init_(const util::pix<I>& px);
+ using super_::take_as_init_;
/// \}
/// Get the value of the accumulator.
@@ -164,12 +164,12 @@
c_ += other.c_;
}
- // take_as_init.
+ // take_as_init_.
template <typename I>
inline
void
- card<I>::take_as_init()
+ card<I>::take_as_init_()
{
init();
take();
@@ -178,9 +178,9 @@
template <typename I>
inline
void
- card<I>::take_as_init(const util::pix<I>&)
+ card<I>::take_as_init_(const util::pix<I>&)
{
- take_as_init();
+ take_as_init_();
}
template <typename I>
Index: tests/accu/count.cc
--- tests/accu/count.cc (revision 3726)
+++ tests/accu/count.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007 EPITA Research and Development Laboratory
+// Copyright (C) 2007, 2009 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
@@ -25,30 +25,43 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/accu/count.cc
- *
- * \brief Tests on mln::accu::count.
- */
-
-#include <mln/value/int_u8.hh>
+/// \file tests/accu/count.cc
+///
+/// Tests on mln::accu::count.
#include <mln/accu/count.hh>
+struct toto {};
+
+
int main()
{
using namespace mln;
{
- accu::count<value::int_u8> accu;
- mln_assertion(accu.to_result() == 0);
+ // The code below do not compile, as expected :-)
+ // accu::count<int> a;
+ // a.take_as_init(toto());
}
-
{
- accu::count<value::int_u8> accu;
+ accu::count<int> a;
+ mln_assertion(a.to_result() == 0);
+ }
+ {
+ accu::count<int> a;
for (int i = 0; i < 200; i++)
- accu.take(i);
- mln_assertion(accu.to_result() == 200);
+ a.take(i);
+ mln_assertion(a.to_result() == 200);
}
+ {
+ accu::count<int> a, a_;
+ a.take_as_init(1);
+ mln_assertion(a == 1);
+ a.take(2);
+ mln_assertion(a == 2);
+ a_.take_as_init(a);
+ mln_assertion(a_ == 2);
+ }
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Start cleaning up linear gaussian filters.
* mln/linear/gaussian: New directory.
* mln/linear/gaussian/internal: New directory.
* mln/linear/gaussian.hh: Split code into...
* mln/linear/gaussian/impl.hh,
* mln/linear/gaussian/filter.hh,
* mln/linear/gaussian/internal/coefficients.hh:
...those new files.
* tests/linear/gaussian: New directory.
* tests/linear/Makefile.am: Update.
* tests/linear/gaussian/Makefile.am: New.
* tests/linear/gaussian/filter.cc: New.
Misc.
* mln/labeling/compute.hh: .
* mln/labeling/pack.hh (relabel_inplace): Fix missing
renaming into...
(pack_inplace): ...this.
mln/labeling/compute.hh | 2
mln/labeling/pack.hh | 3
mln/linear/gaussian/filter.hh | 735 -------------------------
mln/linear/gaussian/impl.hh | 427 ---------------
mln/linear/gaussian/internal/coefficients.hh | 768 ++++-----------------------
tests/linear/Makefile.am | 4
tests/linear/gaussian/Makefile.am | 4
tests/linear/gaussian/filter.cc | 27
8 files changed, 185 insertions(+), 1785 deletions(-)
Index: mln/linear/gaussian/impl.hh
--- mln/linear/gaussian/impl.hh (revision 0)
+++ mln/linear/gaussian/impl.hh (working copy)
@@ -26,12 +26,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_LINEAR_GAUSSIAN_HH
-# define MLN_LINEAR_GAUSSIAN_HH
+#ifndef MLN_LINEAR_GAUSSIAN_IMPL_HH
+# define MLN_LINEAR_GAUSSIAN_IMPL_HH
-/// \file mln/linear/gaussian.hh
+/// \file mln/linear/gaussian/impl.hh
///
-/// Gaussian filter.
+/// Gaussian filter implementation.
///
/// \todo Add a clean reference Rachid Deriche
/// Recursively implementing the gaussian and its derivatives (1993)
@@ -52,6 +52,8 @@
# include <mln/level/stretch.hh>
# include <mln/algebra/vec.hh>
+# include <mln/linear/gaussian/internal/coefficients.hh>
+
namespace mln
{
@@ -59,117 +61,20 @@
namespace linear
{
- /// Gaussian filter of an image \p input
- ///
- /// \pre output.domain = input.domain
- ///
- template <typename I>
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma);
-
-
- template <typename I>
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma, int dir);
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- namespace impl
- {
-
- typedef float norm_fun(float, float,
- float, float,
- float, float,
- float, float,
- float, float,
- int&);
-
- struct recursivefilter_coef_
+ namespace gaussian
{
- ///
- /// Constructor.
- ///
- recursivefilter_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float w0, float w1,
- float s, norm_fun norm);
- std::vector<float> n, d, nm, dm;
- };
-
- inline
- recursivefilter_coef_::recursivefilter_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float w0, float w1,
- float s, norm_fun norm)
- {
- n.reserve(5);
- d.reserve(5);
- nm.reserve(5);
- dm.reserve(5);
-
- b0 /= s;
- b1 /= s;
- w0 /= s;
- w1 /= s;
-
- float sin0 = std::sin(w0);
- float sin1 = std::sin(w1);
- float cos0 = std::cos(w0);
- float cos1 = std::cos(w1);
-
- int sign = 1;
- float n_ = norm(a0, a1, b0, b1, c0, c1, cos0, sin0, cos1, sin1, sign);
-
- a0 /= n_;
- a1 /= n_;
- c0 /= n_;
- c1 /= n_;
-
- n[3] =
- std::exp(-b1 - 2*b0) * (c1 * sin1 - cos1 * c0) +
- std::exp(-b0 - 2*b1) * (a1 * sin0 - cos0 * a0);
- n[2] =
- 2 * std::exp(-b0 - b1) * ((a0 + c0) * cos1 * cos0 -
- cos1 * a1 * sin0 -
- cos0 * c1 * sin1) +
- c0 * std::exp(-2*b0) + a0 * std::exp(-2*b1);
- n[1] =
- std::exp(-b1) * (c1 * sin1 - (c0 + 2 * a0) * cos1) +
- std::exp(-b0) * (a1 * sin0 - (2 * c0 + a0) * cos0);
- n[0] =
- a0 + c0;
-
- d[4] =
- std::exp(-2 * b0 - 2 * b1);
- d[3] =
- -2 * cos0 * std::exp(-b0 - 2*b1) -
- 2 * cos1 * std::exp(-b1 - 2*b0);
- d[2] =
- 4 * cos1 * cos0 * std::exp(-b0 - b1) +
- std::exp(-2*b1) + std::exp(-2*b0);
- d[1] =
- -2 * std::exp(-b1) * cos1 - 2 * std::exp(-b0) * cos0;
-
- for (unsigned i = 1; i <= 3; ++i)
+ namespace impl
{
- dm[i] = d[i];
- nm[i] = float(sign) * (n[i] - d[i] * n[0]);
- }
- dm[4] = d[4];
- nm[4] = float(sign) * (-d[4] * n[0]);
- }
+# ifndef MLN_INCLUDE_ONLY
template <class WorkType, class I>
inline
void
recursivefilter_(I& ima,
- const recursivefilter_coef_& c,
+ const internal::coefficients& c,
const mln_psite(I)& start,
const mln_psite(I)& finish,
int len,
@@ -264,104 +169,6 @@
}
- inline
- float gaussian_norm_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
- int& sign)
- {
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
-
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
- float scaleA = 2 * a1 * sin0 * expb0 - a0 * (1 - exp2b0);
-
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
-
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
- float scaleC = 2 * c1 * sin1 * expb1 - c0 * (1 - exp2b1);
-
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
-
- sign = 1;
-
- return (sumA + sumC);
- }
-
- inline
- float gaussian_1st_deriv_coef_norm_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
- int& sign)
- {
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
-
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
- scale0 *= scale0;
- float scaleA = - 2 * a1 * sin0 * expb0 * (1 - exp2b0) +
- 2 * a0 * expb0 * (2 * expb0 - cos0 * (1 + exp2b0));
-
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
-
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
- scale1 *= scale1;
- float scaleC = - 2 * c1 * sin1 * expb1 * (1 - exp2b1) +
- 2 * c0 * expb1 * (2 * expb1 - cos1 * (1 + exp2b1));
-
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
-
- sign = -1;
-
- return (sumA + sumC);
- }
-
- inline
- float gaussian_2nd_deriv_coef_norm_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
- int& sign)
- {
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
-
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
- scale0 *= scale0 * scale0;
-
- float scaleA = a1 * sin0 * expb0 *
- (1 + expb0 * (2 * cos0 * (1 + exp2b0) + exp2b0 - 6)) +
- a0 * expb0 * (2 * expb0 * (2 - cos0 * cos0) *
- (1 - exp2b0) - cos0 * (1 - exp2b0 * exp2b0));
-
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
-
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
- scale1 *= scale1 * scale1;
-
- float scaleC = c1 * sin1 * expb1 *
- (1 + expb1 * (2 * cos1 * (1 + exp2b1) + exp2b1 - 6)) +
- c0 * expb1 * (2 * expb1 * (2 - cos1 * cos1) *
- (1 - exp2b1) - cos1 * (1 - exp2b1 * exp2b1));
-
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
- sign = 1;
-
- return (sumA + sumC);
- }
-
-
template <class I, class F>
inline
void
@@ -493,10 +300,10 @@
generic_filter_common_(trait::value::nature::floating,
const Image<I>& in,
const F& coef,
- float sigma,
+ double sigma,
Image<O>& out)
{
- mln_ch_value(O, float) work_img(exact(in).domain());
+ mln_ch_value(O, double) work_img(exact(in).domain());
data::paste(in, work_img);
extension::adjust_fill(work_img, 4, 0);
@@ -517,11 +324,11 @@
generic_filter_common_(trait::value::nature::floating,
const Image<I>& in,
const F& coef,
- float sigma,
+ double sigma,
Image<O>& out,
int dir)
{
- mln_ch_value(O, float) work_img(exact(in).domain());
+ mln_ch_value(O, double) work_img(exact(in).domain());
data::paste(in, work_img);
extension::adjust_fill(work_img, 4, 0);
@@ -542,10 +349,10 @@
generic_filter_common_(trait::value::nature::scalar,
const Image<I>& in,
const F& coef,
- float sigma,
+ double sigma,
Image<O>& out)
{
- mln_ch_value(O, float) work_img(exact(in).domain());
+ mln_ch_value(O, double) work_img(exact(in).domain());
data::paste(in, work_img);
extension::adjust_fill(work_img, 4, 0);
@@ -566,11 +373,11 @@
generic_filter_common_(trait::value::nature::scalar,
const Image<I>& in,
const F& coef,
- float sigma,
+ double sigma,
Image<O>& out,
int dir)
{
- mln_ch_value(O, float) work_img(exact(in).domain());
+ mln_ch_value(O, double) work_img(exact(in).domain());
data::paste(in, work_img);
extension::adjust_fill(work_img, 4, 0);
@@ -592,10 +399,10 @@
generic_filter_common_(trait::value::nature::vectorial,
const Image<I>& in,
const F& coef,
- float sigma,
+ double sigma,
Image<O>& out)
{
- // typedef algebra::vec<3, float> vec3f;
+ // typedef algebra::vec<3, double> vec3f;
// mln_ch_value(O, vec3f) work_img(exact(in).domain());
// FIXME : paste does not work (rgb8 -> vec3f).
data::paste(in, out);
@@ -614,11 +421,11 @@
generic_filter_common_(trait::value::nature::vectorial,
const Image<I>& in,
const F& coef,
- float sigma,
+ double sigma,
Image<O>& out,
int dir)
{
- // typedef algebra::vec<3, float> vec3f;
+ // typedef algebra::vec<3, double> vec3f;
// mln_ch_value(O, vec3f) work_img(exact(in).domain());
// FIXME : paste does not work (rgb8 -> vec3f).
data::paste(in, out);
@@ -630,199 +437,17 @@
out, coef, dir);
}
- } // end of namespace mln::linear::impl
-
- // Facade.
- /*! Apply an approximated gaussian filter of \p sigma on \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma, int dir)
- {
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
-
- mln_concrete(I) output;
- initialize(output, input);
- impl::recursivefilter_coef_ coef(1.68f, 3.735f,
- 1.783f, 1.723f,
- -0.6803f, -0.2598f,
- 0.6318f, 1.997f,
- sigma, impl::gaussian_norm_coef_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
- return output;
- }
-
-
- /*! Apply an approximated first derivative gaussian filter of \p sigma on
- * \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_1st_derivative(const Image<I>& input, float sigma, int dir)
- {
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(-0.6472f, -4.531f,
- 1.527f, 1.516f,
- 0.6494f, 0.9557f,
- 0.6719f, 2.072f,
- sigma, impl::gaussian_1st_deriv_coef_norm_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
- return output;
- }
-
- /*! Apply an approximated second derivative gaussian filter of \p sigma on
- * \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_2nd_derivative(const Image<I>& input, float sigma, int dir)
- {
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(-1.331f, 3.661f,
- 1.24f, 1.314f,
- 0.3225f, -1.738f,
- 0.748f, 2.166f,
- sigma, impl::gaussian_2nd_deriv_coef_norm_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
- return output;
- }
-
-
-
-
-
- /*! Apply an approximated gaussian filter of \p sigma on \p input.
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma)
- {
- mln_precondition(exact(input).is_valid());
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(1.68f, 3.735f,
- 1.783f, 1.723f,
- -0.6803f, -0.2598f,
- 0.6318f, 1.997f,
- sigma, impl::gaussian_norm_coef_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
-
- return output;
- }
-
-
- /*! Apply an approximated first derivative gaussian filter of \p sigma on
- * \p input
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_1st_derivative(const Image<I>& input, float sigma)
- {
- mln_precondition(exact(input).is_valid());
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(-0.6472f, -4.531f,
- 1.527f, 1.516f,
- 0.6494f, 0.9557f,
- 0.6719f, 2.072f,
- sigma, impl::gaussian_1st_deriv_coef_norm_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
- return output;
- }
-
-
- /*! Apply an approximated second derivative gaussian filter of \p sigma on
- * \p input
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_2nd_derivative(const Image<I>& input, float sigma)
- {
- mln_precondition(exact(input).is_valid());
+# endif // ! MLN_INCLUDE_ONLY
- mln_concrete(I) output;
- initialize(output, input);
- impl::recursivefilter_coef_
- coef(-1.331f, 3.661f,
- 1.24f, 1.314f,
- 0.3225f, -1.738f,
- 0.748f, 2.166f,
- sigma, impl::gaussian_2nd_deriv_coef_norm_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
- return output;
- }
+ } // end of namespace mln::linear::gaussian::impl
-# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::linear::gaussian
} // end of namespace mln::linear
} // end of namespace mln
-#endif // ! MLN_LINEAR_GAUSSIAN_HH
+#endif // ! MLN_LINEAR_GAUSSIAN_IMPL_HH
Property changes on: mln/linear/gaussian/impl.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/linear/gaussian/filter.hh
--- mln/linear/gaussian/filter.hh (revision 0)
+++ mln/linear/gaussian/filter.hh (working copy)
@@ -26,31 +26,19 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_LINEAR_GAUSSIAN_HH
-# define MLN_LINEAR_GAUSSIAN_HH
+#ifndef MLN_LINEAR_GAUSSIAN_FILTER_HH
+# define MLN_LINEAR_GAUSSIAN_FILTER_HH
-/// \file mln/linear/gaussian.hh
+/// \file mln/linear/gaussian/filter.hh
///
/// Gaussian filter.
///
/// \todo Add a clean reference Rachid Deriche
/// Recursively implementing the gaussian and its derivatives (1993)
-# include <vector>
-# include <cmath>
-
# include <mln/core/concept/image.hh>
-# include <mln/core/alias/point2d.hh>
-# include <mln/core/alias/dpoint1d.hh>
-# include <mln/core/alias/dpoint3d.hh>
-# include <mln/extension/adjust_fill.hh>
-# include <mln/geom/ncols.hh>
-# include <mln/geom/nrows.hh>
-# include <mln/geom/ninds.hh>
-# include <mln/geom/nslis.hh>
-# include <mln/data/paste.hh>
-# include <mln/level/stretch.hh>
-# include <mln/algebra/vec.hh>
+# include <mln/linear/gaussian/impl.hh>
+# include <mln/linear/gaussian/internal/coefficients.hh>
namespace mln
@@ -59,580 +47,28 @@
namespace linear
{
+ namespace gaussian
+ {
+
/// Gaussian filter of an image \p input
///
/// \pre output.domain = input.domain
///
template <typename I>
mln_concrete(I)
- gaussian(const Image<I>& input, float sigma);
+ filter(const Image<I>& input, double sigma);
template <typename I>
mln_concrete(I)
- gaussian(const Image<I>& input, float sigma, int dir);
-
-
-# ifndef MLN_INCLUDE_ONLY
-
- namespace impl
- {
-
- typedef float norm_fun(float, float,
- float, float,
- float, float,
- float, float,
- float, float,
- int&);
-
- struct recursivefilter_coef_
- {
-
- ///
- /// Constructor.
- ///
- recursivefilter_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float w0, float w1,
- float s, norm_fun norm);
- std::vector<float> n, d, nm, dm;
- };
-
- inline
- recursivefilter_coef_::recursivefilter_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float w0, float w1,
- float s, norm_fun norm)
- {
- n.reserve(5);
- d.reserve(5);
- nm.reserve(5);
- dm.reserve(5);
-
- b0 /= s;
- b1 /= s;
- w0 /= s;
- w1 /= s;
-
- float sin0 = std::sin(w0);
- float sin1 = std::sin(w1);
- float cos0 = std::cos(w0);
- float cos1 = std::cos(w1);
-
- int sign = 1;
- float n_ = norm(a0, a1, b0, b1, c0, c1, cos0, sin0, cos1, sin1, sign);
-
- a0 /= n_;
- a1 /= n_;
- c0 /= n_;
- c1 /= n_;
-
- n[3] =
- std::exp(-b1 - 2*b0) * (c1 * sin1 - cos1 * c0) +
- std::exp(-b0 - 2*b1) * (a1 * sin0 - cos0 * a0);
- n[2] =
- 2 * std::exp(-b0 - b1) * ((a0 + c0) * cos1 * cos0 -
- cos1 * a1 * sin0 -
- cos0 * c1 * sin1) +
- c0 * std::exp(-2*b0) + a0 * std::exp(-2*b1);
- n[1] =
- std::exp(-b1) * (c1 * sin1 - (c0 + 2 * a0) * cos1) +
- std::exp(-b0) * (a1 * sin0 - (2 * c0 + a0) * cos0);
- n[0] =
- a0 + c0;
-
- d[4] =
- std::exp(-2 * b0 - 2 * b1);
- d[3] =
- -2 * cos0 * std::exp(-b0 - 2*b1) -
- 2 * cos1 * std::exp(-b1 - 2*b0);
- d[2] =
- 4 * cos1 * cos0 * std::exp(-b0 - b1) +
- std::exp(-2*b1) + std::exp(-2*b0);
- d[1] =
- -2 * std::exp(-b1) * cos1 - 2 * std::exp(-b0) * cos0;
-
- for (unsigned i = 1; i <= 3; ++i)
- {
- dm[i] = d[i];
- nm[i] = float(sign) * (n[i] - d[i] * n[0]);
- }
- dm[4] = d[4];
- nm[4] = float(sign) * (-d[4] * n[0]);
- }
-
-
-
- template <class WorkType, class I>
- inline
- void
- recursivefilter_(I& ima,
- const recursivefilter_coef_& c,
- const mln_psite(I)& start,
- const mln_psite(I)& finish,
- int len,
- const mln_deduce(I, psite, delta)& d)
- {
- std::vector<WorkType> tmp1(len);
- std::vector<WorkType> tmp2(len);
-
- // The fourth degree approximation implies to have a special
- // look on the four first points we consider that there is
- // no signal before 0 (to be discussed)
-
- // --
- // Causal part
-
- tmp1[0] =
- c.n[0] * ima(start);
-
- tmp1[1] =
- c.n[0] * ima(start + d)
- + c.n[1] * ima(start)
- - c.d[1] * tmp1[0];
-
- tmp1[2] =
- c.n[0] * ima(start + d + d)
- + c.n[1] * ima(start + d)
- + c.n[2] * ima(start)
- - c.d[1] * tmp1[1]
- - c.d[2] * tmp1[0];
-
- tmp1[3] =
- c.n[0] * ima(start + d + d + d)
- + c.n[1] * ima(start + d + d)
- + c.n[2] * ima(start + d)
- + c.n[3] * ima(start)
- - c.d[1] * tmp1[2] - c.d[2] * tmp1[1]
- - c.d[3] * tmp1[0];
-
- mln_psite(I) current(start + d + d + d + d);
- for (mln_deduce(I, site, coord) i = 4; i < len; ++i)
- {
- tmp1[i] =
- c.n[0] * ima(current)
- + c.n[1] * ima(current - d)
- + c.n[2] * ima(current - d - d)
- + c.n[3] * ima(current - d - d - d)
- - c.d[1] * tmp1[i - 1] - c.d[2] * tmp1[i - 2]
- - c.d[3] * tmp1[i - 3] - c.d[4] * tmp1[i - 4];
- current = current + d;
- }
-
- // Non causal part
-
- tmp2[len - 1] = WorkType(); // FIXME : = 0, literal::zero ...?
-
- tmp2[len - 2] =
- c.nm[1] * ima(finish);
-
- tmp2[len - 3] =
- c.nm[1] * ima(finish - d)
- + c.nm[2] * ima(finish)
- - c.dm[1] * tmp2[len - 2];
-
- tmp2[len - 4] =
- c.nm[1] * ima(finish - d - d)
- + c.nm[2] * ima(finish - d)
- + c.nm[3] * ima(finish)
- - c.dm[1] * tmp2[len - 3]
- - c.dm[2] * tmp2[len - 2];
-
- current = finish - d - d - d ;
-
- for (int i = len - 5; i >= 0; --i)
- {
- tmp2[i] =
- c.nm[1] * ima(current)
- + c.nm[2] * ima(current + d)
- + c.nm[3] * ima(current + d + d)
- + c.nm[4] * ima(current + d + d + d)
- - c.dm[1] * tmp2[i + 1] - c.dm[2] * tmp2[i + 2]
- - c.dm[3] * tmp2[i + 3] - c.dm[4] * tmp2[i + 4];
- current = current - d;
- }
-
- // Combine results from causal and non-causal parts.
- current = start;
- for (int i = 0; i < len; ++i)
- {
- ima(current) = tmp1[i] + tmp2[i];
- current = current + d;
- }
- }
-
-
- inline
- float gaussian_norm_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
- int& sign)
- {
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
-
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
- float scaleA = 2 * a1 * sin0 * expb0 - a0 * (1 - exp2b0);
-
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
-
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
- float scaleC = 2 * c1 * sin1 * expb1 - c0 * (1 - exp2b1);
-
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
-
- sign = 1;
-
- return (sumA + sumC);
- }
-
- inline
- float gaussian_1st_deriv_coef_norm_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
- int& sign)
- {
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
-
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
- scale0 *= scale0;
- float scaleA = - 2 * a1 * sin0 * expb0 * (1 - exp2b0) +
- 2 * a0 * expb0 * (2 * expb0 - cos0 * (1 + exp2b0));
+ filter(const Image<I>& input, double sigma, int dir);
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
- scale1 *= scale1;
- float scaleC = - 2 * c1 * sin1 * expb1 * (1 - exp2b1) +
- 2 * c0 * expb1 * (2 * expb1 - cos1 * (1 + exp2b1));
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
-
- sign = -1;
-
- return (sumA + sumC);
- }
-
- inline
- float gaussian_2nd_deriv_coef_norm_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
- int& sign)
- {
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
-
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
- scale0 *= scale0 * scale0;
-
- float scaleA = a1 * sin0 * expb0 *
- (1 + expb0 * (2 * cos0 * (1 + exp2b0) + exp2b0 - 6)) +
- a0 * expb0 * (2 * expb0 * (2 - cos0 * cos0) *
- (1 - exp2b0) - cos0 * (1 - exp2b0 * exp2b0));
-
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
-
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
- scale1 *= scale1 * scale1;
-
- float scaleC = c1 * sin1 * expb1 *
- (1 + expb1 * (2 * cos1 * (1 + exp2b1) + exp2b1 - 6)) +
- c0 * expb1 * (2 * expb1 * (2 - cos1 * cos1) *
- (1 - exp2b1) - cos1 * (1 - exp2b1 * exp2b1));
-
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
- sign = 1;
-
- return (sumA + sumC);
- }
-
-
- template <class I, class F>
- inline
- void
- generic_filter_(trait::image::dimension::one_d,
- Image<I>& img_, const F& coef, int dir)
- {
- I& img = exact(img_);
- mln_precondition(dir < I::site::dim);
-
-
- recursivefilter_<mln_value(I)>(img, coef,
- point1d(static_cast<def::coord>(-img.border())),
- point1d(static_cast<def::coord>(geom::ninds(img) - 1 +
- img.border())),
- geom::ninds(img) + 2 * img.border(),
- dpoint1d(1));
- }
-
- template <class I, class F>
- inline
- void
- generic_filter_(trait::image::dimension::two_d,
- Image<I>& img_, const F& coef, int dir)
- {
- I& img = exact(img_);
-
- mln_precondition(dir < I::site::dim);
-
-
- if (dir == 0)
- {
- // Apply on rows.
- for (unsigned j = 0; j < geom::ncols(img); ++j)
- recursivefilter_<mln_value(I)>(img, coef,
- point2d(static_cast<def::coord>(-img.border()),
- static_cast<def::coord>(j)),
- point2d(static_cast<def::coord>(geom::nrows(img) - 1 +
- img.border()),
- static_cast<def::coord>(j)),
- geom::nrows(img) + 2 * img.border(),
- dpoint2d(1, 0));
- }
-
- if (dir == 1)
- {
- // Apply on columns.
- for (unsigned i = 0; i < geom::nrows(img); ++i)
- recursivefilter_<mln_value(I)>(img, coef,
- point2d(static_cast<def::coord>(i),
- static_cast<def::coord>(-img.border())),
- point2d(static_cast<def::coord>(i),
- static_cast<def::coord>(geom::ncols(img) - 1 +
- img.border())),
- geom::ncols(img) + 2 * img.border(),
- dpoint2d(0, 1));
- }
- }
-
- template <class I, class F>
- inline
- void
- generic_filter_(trait::image::dimension::three_d,
- Image<I>& img_, const F& coef, int dir)
- {
- I& img = exact(img_);
- mln_precondition(dir < I::site::dim);
-
- if (dir == 0)
- {
- // Apply on slices.
- for (unsigned j = 0; j < geom::nrows(img); ++j)
- for (unsigned k = 0; k < geom::ncols(img); ++k)
- recursivefilter_<mln_value(I)>(img, coef,
- point3d(static_cast<def::coord>(-img.border()),
- static_cast<def::coord>(j),
- static_cast<def::coord>(k)),
- point3d(static_cast<def::coord>(geom::nslis(img) - 1 +
- img.border()),
- static_cast<def::coord>(j),
- static_cast<def::coord>(k)),
- geom::nslis(img) + 2 *
- img.border(),
- dpoint3d(1, 0, 0));
- }
-
-
- if (dir == 1)
- {
- // Apply on rows.
- for (unsigned i = 0; i < geom::nslis(img); ++i)
- for (unsigned k = 0; k < geom::ncols(img); ++k)
- recursivefilter_<mln_value(I)>(img, coef,
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(-img.border()),
- static_cast<def::coord>(k)),
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(geom::nrows(img) - 1 +
- img.border()),
- static_cast<def::coord>(k)),
- geom::nrows(img) + 2 *
- img.border(),
- dpoint3d(0, 1, 0));
- }
-
- if (dir == 2)
- {
- // Apply on columns.
- for (unsigned i = 0; i < geom::nslis(img); ++i)
- for (unsigned j = 0; j < geom::nrows(img); ++i)
- recursivefilter_<mln_value(I)>(img, coef,
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(j),
- static_cast<def::coord>(-img.border())),
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(j),
- static_cast<def::coord>(geom::ncols(img) -
- 1 + img.border())),
- geom::ncols(img) + 2 *
- img.border(),
- dpoint3d(0, 0, 1));
- }
- }
-
-
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::floating,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- for (int i = 0; i < I::site::dim; ++i)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, i);
-
- // We don't need to convert work_img
- data::paste(work_img, out);
- }
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::floating,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out,
- int dir)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, dir);
-
- // We don't need to convert work_img
- data::paste(work_img, out);
- }
-
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::scalar,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- for (int i = 0; i < I::site::dim; ++i)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, i);
-
- // Convert work_img into result type
- data::paste(level::stretch(mln_value(I)(), work_img), out);
- }
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::scalar,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out,
- int dir)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, dir);
-
- // Convert work_img into result type
- data::paste(level::stretch(mln_value(I)(), work_img), out);
- }
-
-
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::vectorial,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out)
- {
- // typedef algebra::vec<3, float> vec3f;
- // mln_ch_value(O, vec3f) work_img(exact(in).domain());
- // FIXME : paste does not work (rgb8 -> vec3f).
- data::paste(in, out);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- for (int i = 0; i < I::site::dim; ++i)
- generic_filter_(mln_trait_image_dimension(I)(),
- out, coef, i);
- }
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::vectorial,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out,
- int dir)
- {
- // typedef algebra::vec<3, float> vec3f;
- // mln_ch_value(O, vec3f) work_img(exact(in).domain());
- // FIXME : paste does not work (rgb8 -> vec3f).
- data::paste(in, out);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- generic_filter_(mln_trait_image_dimension(I)(),
- out, coef, dir);
- }
+# ifndef MLN_INCLUDE_ONLY
- } // end of namespace mln::linear::impl
- // Facade.
+ // Facades.
/*! Apply an approximated gaussian filter of \p sigma on \p input.
* on a specific direction \p dir
@@ -646,95 +82,28 @@
template <typename I>
inline
mln_concrete(I)
- gaussian(const Image<I>& input, float sigma, int dir)
+ filter(const Image<I>& input, double sigma, int dir)
{
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
+ trace::entering("linear::gaussian::filter");
- mln_concrete(I) output;
- initialize(output, input);
- impl::recursivefilter_coef_ coef(1.68f, 3.735f,
- 1.783f, 1.723f,
- -0.6803f, -0.2598f,
- 0.6318f, 1.997f,
- sigma, impl::gaussian_norm_coef_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
- return output;
- }
-
-
- /*! Apply an approximated first derivative gaussian filter of \p sigma on
- * \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_1st_derivative(const Image<I>& input, float sigma, int dir)
- {
mln_precondition(exact(input).is_valid());
mln_precondition(dir < I::site::dim);
mln_concrete(I) output;
initialize(output, input);
- impl::recursivefilter_coef_
- coef(-0.6472f, -4.531f,
- 1.527f, 1.516f,
- 0.6494f, 0.9557f,
- 0.6719f, 2.072f,
- sigma, impl::gaussian_1st_deriv_coef_norm_);
+ internal::coefficients coef = internal::coefficients_not_derivative(sigma);
impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
input, coef, sigma, output, dir);
- return output;
- }
-
- /*! Apply an approximated second derivative gaussian filter of \p sigma on
- * \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_2nd_derivative(const Image<I>& input, float sigma, int dir)
- {
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(-1.331f, 3.661f,
- 1.24f, 1.314f,
- 0.3225f, -1.738f,
- 0.748f, 2.166f,
- sigma, impl::gaussian_2nd_deriv_coef_norm_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
+ trace::exiting("linear::gaussian::filter");
return output;
}
-
/*! Apply an approximated gaussian filter of \p sigma on \p input.
* This filter is applied in all the input image direction.
*
@@ -743,86 +112,32 @@
template <typename I>
inline
mln_concrete(I)
- gaussian(const Image<I>& input, float sigma)
+ filter(const Image<I>& input, double sigma)
{
- mln_precondition(exact(input).is_valid());
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(1.68f, 3.735f,
- 1.783f, 1.723f,
- -0.6803f, -0.2598f,
- 0.6318f, 1.997f,
- sigma, impl::gaussian_norm_coef_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
+ trace::entering("linear::gaussian::filter");
- return output;
- }
-
-
- /*! Apply an approximated first derivative gaussian filter of \p sigma on
- * \p input
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_1st_derivative(const Image<I>& input, float sigma)
- {
mln_precondition(exact(input).is_valid());
mln_concrete(I) output;
initialize(output, input);
- impl::recursivefilter_coef_
- coef(-0.6472f, -4.531f,
- 1.527f, 1.516f,
- 0.6494f, 0.9557f,
- 0.6719f, 2.072f,
- sigma, impl::gaussian_1st_deriv_coef_norm_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
- return output;
- }
-
-
- /*! Apply an approximated second derivative gaussian filter of \p sigma on
- * \p input
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_2nd_derivative(const Image<I>& input, float sigma)
- {
- mln_precondition(exact(input).is_valid());
-
- mln_concrete(I) output;
- initialize(output, input);
+ internal::coefficients coef = internal::coefficients_not_derivative(sigma);
- impl::recursivefilter_coef_
- coef(-1.331f, 3.661f,
- 1.24f, 1.314f,
- 0.3225f, -1.738f,
- 0.748f, 2.166f,
- sigma, impl::gaussian_2nd_deriv_coef_norm_);
impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
input, coef, sigma, output);
+
+ trace::exiting("linear::gaussian::filter");
return output;
}
+
# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::linear::gaussian
+
} // end of namespace mln::linear
} // end of namespace mln
-#endif // ! MLN_LINEAR_GAUSSIAN_HH
+#endif // ! MLN_LINEAR_GAUSSIAN_FILTER_HH
Property changes on: mln/linear/gaussian/filter.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/linear/gaussian/internal/coefficients.hh
--- mln/linear/gaussian/internal/coefficients.hh (revision 0)
+++ mln/linear/gaussian/internal/coefficients.hh (working copy)
@@ -26,12 +26,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_LINEAR_GAUSSIAN_HH
-# define MLN_LINEAR_GAUSSIAN_HH
+#ifndef MLN_LINEAR_GAUSSIAN_INTERNAL_COEFFICIENTS_HH
+# define MLN_LINEAR_GAUSSIAN_INTERNAL_COEFFICIENTS_HH
-/// \file mln/linear/gaussian.hh
+/// \file mln/linear/gaussian/internal/coefficients.hh
///
-/// Gaussian filter.
+/// Compute coefficients for recursive Gaussian filtering.
///
/// \todo Add a clean reference Rachid Deriche
/// Recursively implementing the gaussian and its derivatives (1993)
@@ -39,18 +39,6 @@
# include <vector>
# include <cmath>
-# include <mln/core/concept/image.hh>
-# include <mln/core/alias/point2d.hh>
-# include <mln/core/alias/dpoint1d.hh>
-# include <mln/core/alias/dpoint3d.hh>
-# include <mln/extension/adjust_fill.hh>
-# include <mln/geom/ncols.hh>
-# include <mln/geom/nrows.hh>
-# include <mln/geom/ninds.hh>
-# include <mln/geom/nslis.hh>
-# include <mln/data/paste.hh>
-# include <mln/level/stretch.hh>
-# include <mln/algebra/vec.hh>
namespace mln
@@ -59,52 +47,48 @@
namespace linear
{
- /// Gaussian filter of an image \p input
- ///
- /// \pre output.domain = input.domain
- ///
- template <typename I>
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma);
-
-
- template <typename I>
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma, int dir);
-
-
-# ifndef MLN_INCLUDE_ONLY
+ namespace gaussian
+ {
- namespace impl
+ namespace internal
{
- typedef float norm_fun(float, float,
- float, float,
- float, float,
- float, float,
- float, float,
+
+ typedef double norm_fun(double, double,
+ double, double,
+ double, double,
+ double, double,
+ double, double,
int&);
- struct recursivefilter_coef_
+ struct coefficients
{
-
- ///
/// Constructor.
- ///
- recursivefilter_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float w0, float w1,
- float s, norm_fun norm);
- std::vector<float> n, d, nm, dm;
+ //
+ coefficients(double a0, double a1,
+ double b0, double b1,
+ double c0, double c1,
+ double w0, double w1,
+ double s, norm_fun norm);
+ std::vector<double> n, d, nm, dm;
};
+
+ coefficients coefficients_not_derivative(double sigma);
+ coefficients coefficients_1st_derivative(double sigma);
+ coefficients coefficients_2nd_derivative(double sigma);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
inline
- recursivefilter_coef_::recursivefilter_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float w0, float w1,
- float s, norm_fun norm)
+ coefficients::coefficients(double a0, double a1,
+ double b0, double b1,
+ double c0, double c1,
+ double w0, double w1,
+ double s, norm_fun norm)
{
n.reserve(5);
d.reserve(5);
@@ -116,13 +100,13 @@
w0 /= s;
w1 /= s;
- float sin0 = std::sin(w0);
- float sin1 = std::sin(w1);
- float cos0 = std::cos(w0);
- float cos1 = std::cos(w1);
+ double sin0 = std::sin(w0);
+ double sin1 = std::sin(w1);
+ double cos0 = std::cos(w0);
+ double cos1 = std::cos(w1);
int sign = 1;
- float n_ = norm(a0, a1, b0, b1, c0, c1, cos0, sin0, cos1, sin1, sign);
+ double n_ = norm(a0, a1, b0, b1, c0, c1, cos0, sin0, cos1, sin1, sign);
a0 /= n_;
a1 /= n_;
@@ -157,672 +141,160 @@
for (unsigned i = 1; i <= 3; ++i)
{
dm[i] = d[i];
- nm[i] = float(sign) * (n[i] - d[i] * n[0]);
+ nm[i] = double(sign) * (n[i] - d[i] * n[0]);
}
dm[4] = d[4];
- nm[4] = float(sign) * (-d[4] * n[0]);
- }
-
-
-
- template <class WorkType, class I>
- inline
- void
- recursivefilter_(I& ima,
- const recursivefilter_coef_& c,
- const mln_psite(I)& start,
- const mln_psite(I)& finish,
- int len,
- const mln_deduce(I, psite, delta)& d)
- {
- std::vector<WorkType> tmp1(len);
- std::vector<WorkType> tmp2(len);
-
- // The fourth degree approximation implies to have a special
- // look on the four first points we consider that there is
- // no signal before 0 (to be discussed)
-
- // --
- // Causal part
-
- tmp1[0] =
- c.n[0] * ima(start);
-
- tmp1[1] =
- c.n[0] * ima(start + d)
- + c.n[1] * ima(start)
- - c.d[1] * tmp1[0];
-
- tmp1[2] =
- c.n[0] * ima(start + d + d)
- + c.n[1] * ima(start + d)
- + c.n[2] * ima(start)
- - c.d[1] * tmp1[1]
- - c.d[2] * tmp1[0];
-
- tmp1[3] =
- c.n[0] * ima(start + d + d + d)
- + c.n[1] * ima(start + d + d)
- + c.n[2] * ima(start + d)
- + c.n[3] * ima(start)
- - c.d[1] * tmp1[2] - c.d[2] * tmp1[1]
- - c.d[3] * tmp1[0];
-
- mln_psite(I) current(start + d + d + d + d);
- for (mln_deduce(I, site, coord) i = 4; i < len; ++i)
- {
- tmp1[i] =
- c.n[0] * ima(current)
- + c.n[1] * ima(current - d)
- + c.n[2] * ima(current - d - d)
- + c.n[3] * ima(current - d - d - d)
- - c.d[1] * tmp1[i - 1] - c.d[2] * tmp1[i - 2]
- - c.d[3] * tmp1[i - 3] - c.d[4] * tmp1[i - 4];
- current = current + d;
- }
-
- // Non causal part
-
- tmp2[len - 1] = WorkType(); // FIXME : = 0, literal::zero ...?
-
- tmp2[len - 2] =
- c.nm[1] * ima(finish);
-
- tmp2[len - 3] =
- c.nm[1] * ima(finish - d)
- + c.nm[2] * ima(finish)
- - c.dm[1] * tmp2[len - 2];
-
- tmp2[len - 4] =
- c.nm[1] * ima(finish - d - d)
- + c.nm[2] * ima(finish - d)
- + c.nm[3] * ima(finish)
- - c.dm[1] * tmp2[len - 3]
- - c.dm[2] * tmp2[len - 2];
-
- current = finish - d - d - d ;
-
- for (int i = len - 5; i >= 0; --i)
- {
- tmp2[i] =
- c.nm[1] * ima(current)
- + c.nm[2] * ima(current + d)
- + c.nm[3] * ima(current + d + d)
- + c.nm[4] * ima(current + d + d + d)
- - c.dm[1] * tmp2[i + 1] - c.dm[2] * tmp2[i + 2]
- - c.dm[3] * tmp2[i + 3] - c.dm[4] * tmp2[i + 4];
- current = current - d;
+ nm[4] = double(sign) * (-d[4] * n[0]);
}
- // Combine results from causal and non-causal parts.
- current = start;
- for (int i = 0; i < len; ++i)
- {
- ima(current) = tmp1[i] + tmp2[i];
- current = current + d;
- }
- }
inline
- float gaussian_norm_coef_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
+ double norm_not_derivative(double a0, double a1,
+ double b0, double b1,
+ double c0, double c1,
+ double cos0, double sin0,
+ double cos1, double sin1,
int& sign)
{
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
+ double expb0 = std::exp(b0);
+ double exp2b0 = std::exp(2.f * b0);
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
- float scaleA = 2 * a1 * sin0 * expb0 - a0 * (1 - exp2b0);
+ double scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
+ double scaleA = 2 * a1 * sin0 * expb0 - a0 * (1 - exp2b0);
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
+ double expb1 = std::exp(b1);
+ double exp2b1 = std::exp(2.f * b1);
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
- float scaleC = 2 * c1 * sin1 * expb1 - c0 * (1 - exp2b1);
+ double scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
+ double scaleC = 2 * c1 * sin1 * expb1 - c0 * (1 - exp2b1);
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
+ double sumA = scaleA / scale0;
+ double sumC = scaleC / scale1;
sign = 1;
- return (sumA + sumC);
+ return sumA + sumC;
}
+
inline
- float gaussian_1st_deriv_coef_norm_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
+ double norm_1st_derivative(double a0, double a1,
+ double b0, double b1,
+ double c0, double c1,
+ double cos0, double sin0,
+ double cos1, double sin1,
int& sign)
{
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
+ double expb0 = std::exp(b0);
+ double exp2b0 = std::exp(2.f * b0);
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
+ double scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
scale0 *= scale0;
- float scaleA = - 2 * a1 * sin0 * expb0 * (1 - exp2b0) +
+ double scaleA = - 2 * a1 * sin0 * expb0 * (1 - exp2b0) +
2 * a0 * expb0 * (2 * expb0 - cos0 * (1 + exp2b0));
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
+ double expb1 = std::exp(b1);
+ double exp2b1 = std::exp(2.f * b1);
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
+ double scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
scale1 *= scale1;
- float scaleC = - 2 * c1 * sin1 * expb1 * (1 - exp2b1) +
+ double scaleC = - 2 * c1 * sin1 * expb1 * (1 - exp2b1) +
2 * c0 * expb1 * (2 * expb1 - cos1 * (1 + exp2b1));
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
+ double sumA = scaleA / scale0;
+ double sumC = scaleC / scale1;
sign = -1;
- return (sumA + sumC);
+ return sumA + sumC;
}
+
inline
- float gaussian_2nd_deriv_coef_norm_(float a0, float a1,
- float b0, float b1,
- float c0, float c1,
- float cos0, float sin0,
- float cos1, float sin1,
+ double norm_2nd_derivative(double a0, double a1,
+ double b0, double b1,
+ double c0, double c1,
+ double cos0, double sin0,
+ double cos1, double sin1,
int& sign)
{
- float expb0 = std::exp(b0);
- float exp2b0 = std::exp(2.f * b0);
+ double expb0 = std::exp(b0);
+ double exp2b0 = std::exp(2.f * b0);
- float scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
+ double scale0 = 1 + exp2b0 - 2 * cos0 * expb0;
scale0 *= scale0 * scale0;
- float scaleA = a1 * sin0 * expb0 *
+ double scaleA = a1 * sin0 * expb0 *
(1 + expb0 * (2 * cos0 * (1 + exp2b0) + exp2b0 - 6)) +
a0 * expb0 * (2 * expb0 * (2 - cos0 * cos0) *
(1 - exp2b0) - cos0 * (1 - exp2b0 * exp2b0));
- float expb1 = std::exp(b1);
- float exp2b1 = std::exp(2.f * b1);
+ double expb1 = std::exp(b1);
+ double exp2b1 = std::exp(2.f * b1);
- float scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
+ double scale1 = 1 + exp2b1 - 2 * cos1 * expb1;
scale1 *= scale1 * scale1;
- float scaleC = c1 * sin1 * expb1 *
+ double scaleC = c1 * sin1 * expb1 *
(1 + expb1 * (2 * cos1 * (1 + exp2b1) + exp2b1 - 6)) +
c0 * expb1 * (2 * expb1 * (2 - cos1 * cos1) *
(1 - exp2b1) - cos1 * (1 - exp2b1 * exp2b1));
- float sumA = scaleA / scale0;
- float sumC = scaleC / scale1;
+ double sumA = scaleA / scale0;
+ double sumC = scaleC / scale1;
sign = 1;
- return (sumA + sumC);
+ return sumA + sumC;
}
- template <class I, class F>
inline
- void
- generic_filter_(trait::image::dimension::one_d,
- Image<I>& img_, const F& coef, int dir)
- {
- I& img = exact(img_);
- mln_precondition(dir < I::site::dim);
-
-
- recursivefilter_<mln_value(I)>(img, coef,
- point1d(static_cast<def::coord>(-img.border())),
- point1d(static_cast<def::coord>(geom::ninds(img) - 1 +
- img.border())),
- geom::ninds(img) + 2 * img.border(),
- dpoint1d(1));
- }
-
- template <class I, class F>
- inline
- void
- generic_filter_(trait::image::dimension::two_d,
- Image<I>& img_, const F& coef, int dir)
- {
- I& img = exact(img_);
-
- mln_precondition(dir < I::site::dim);
-
-
- if (dir == 0)
- {
- // Apply on rows.
- for (unsigned j = 0; j < geom::ncols(img); ++j)
- recursivefilter_<mln_value(I)>(img, coef,
- point2d(static_cast<def::coord>(-img.border()),
- static_cast<def::coord>(j)),
- point2d(static_cast<def::coord>(geom::nrows(img) - 1 +
- img.border()),
- static_cast<def::coord>(j)),
- geom::nrows(img) + 2 * img.border(),
- dpoint2d(1, 0));
- }
-
- if (dir == 1)
+ coefficients coefficients_not_derivative(double sigma)
{
- // Apply on columns.
- for (unsigned i = 0; i < geom::nrows(img); ++i)
- recursivefilter_<mln_value(I)>(img, coef,
- point2d(static_cast<def::coord>(i),
- static_cast<def::coord>(-img.border())),
- point2d(static_cast<def::coord>(i),
- static_cast<def::coord>(geom::ncols(img) - 1 +
- img.border())),
- geom::ncols(img) + 2 * img.border(),
- dpoint2d(0, 1));
- }
+ coefficients tmp(+1.6800, +3.7350,
+ +1.7830, +1.7230,
+ -0.6803, -0.2598,
+ +0.6318, +1.9970,
+ sigma,
+ norm_not_derivative);
+ return tmp;
}
- template <class I, class F>
- inline
- void
- generic_filter_(trait::image::dimension::three_d,
- Image<I>& img_, const F& coef, int dir)
- {
- I& img = exact(img_);
- mln_precondition(dir < I::site::dim);
-
- if (dir == 0)
- {
- // Apply on slices.
- for (unsigned j = 0; j < geom::nrows(img); ++j)
- for (unsigned k = 0; k < geom::ncols(img); ++k)
- recursivefilter_<mln_value(I)>(img, coef,
- point3d(static_cast<def::coord>(-img.border()),
- static_cast<def::coord>(j),
- static_cast<def::coord>(k)),
- point3d(static_cast<def::coord>(geom::nslis(img) - 1 +
- img.border()),
- static_cast<def::coord>(j),
- static_cast<def::coord>(k)),
- geom::nslis(img) + 2 *
- img.border(),
- dpoint3d(1, 0, 0));
- }
-
-
- if (dir == 1)
- {
- // Apply on rows.
- for (unsigned i = 0; i < geom::nslis(img); ++i)
- for (unsigned k = 0; k < geom::ncols(img); ++k)
- recursivefilter_<mln_value(I)>(img, coef,
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(-img.border()),
- static_cast<def::coord>(k)),
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(geom::nrows(img) - 1 +
- img.border()),
- static_cast<def::coord>(k)),
- geom::nrows(img) + 2 *
- img.border(),
- dpoint3d(0, 1, 0));
- }
-
- if (dir == 2)
- {
- // Apply on columns.
- for (unsigned i = 0; i < geom::nslis(img); ++i)
- for (unsigned j = 0; j < geom::nrows(img); ++i)
- recursivefilter_<mln_value(I)>(img, coef,
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(j),
- static_cast<def::coord>(-img.border())),
- point3d(static_cast<def::coord>(i),
- static_cast<def::coord>(j),
- static_cast<def::coord>(geom::ncols(img) -
- 1 + img.border())),
- geom::ncols(img) + 2 *
- img.border(),
- dpoint3d(0, 0, 1));
- }
- }
-
-
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::floating,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- for (int i = 0; i < I::site::dim; ++i)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, i);
-
- // We don't need to convert work_img
- data::paste(work_img, out);
- }
- template <class I, class F, class O>
inline
- void
- generic_filter_common_(trait::value::nature::floating,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out,
- int dir)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, dir);
-
- // We don't need to convert work_img
- data::paste(work_img, out);
- }
-
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::scalar,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- for (int i = 0; i < I::site::dim; ++i)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, i);
-
- // Convert work_img into result type
- data::paste(level::stretch(mln_value(I)(), work_img), out);
- }
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::scalar,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out,
- int dir)
- {
- mln_ch_value(O, float) work_img(exact(in).domain());
- data::paste(in, work_img);
- extension::adjust_fill(work_img, 4, 0);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- generic_filter_(mln_trait_image_dimension(I)(),
- work_img, coef, dir);
-
- // Convert work_img into result type
- data::paste(level::stretch(mln_value(I)(), work_img), out);
- }
-
-
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::vectorial,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out)
- {
- // typedef algebra::vec<3, float> vec3f;
- // mln_ch_value(O, vec3f) work_img(exact(in).domain());
- // FIXME : paste does not work (rgb8 -> vec3f).
- data::paste(in, out);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- for (int i = 0; i < I::site::dim; ++i)
- generic_filter_(mln_trait_image_dimension(I)(),
- out, coef, i);
- }
-
- template <class I, class F, class O>
- inline
- void
- generic_filter_common_(trait::value::nature::vectorial,
- const Image<I>& in,
- const F& coef,
- float sigma,
- Image<O>& out,
- int dir)
- {
- // typedef algebra::vec<3, float> vec3f;
- // mln_ch_value(O, vec3f) work_img(exact(in).domain());
- // FIXME : paste does not work (rgb8 -> vec3f).
- data::paste(in, out);
-
- // On tiny sigma, Derich algorithm doesn't work.
- // It is the same thing that to convolve with a Dirac.
- if (sigma > 0.006)
- generic_filter_(mln_trait_image_dimension(I)(),
- out, coef, dir);
- }
-
- } // end of namespace mln::linear::impl
-
- // Facade.
-
- /*! Apply an approximated gaussian filter of \p sigma on \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma, int dir)
+ coefficients coefficients_1st_derivative(double sigma)
{
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
-
- mln_concrete(I) output;
- initialize(output, input);
- impl::recursivefilter_coef_ coef(1.68f, 3.735f,
- 1.783f, 1.723f,
- -0.6803f, -0.2598f,
- 0.6318f, 1.997f,
- sigma, impl::gaussian_norm_coef_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
- return output;
+ coefficients tmp(-0.6472, -4.5310,
+ +1.5270, +1.5160,
+ +0.6494, +0.9557,
+ +0.6719, +2.0720,
+ sigma,
+ norm_1st_derivative);
+ return tmp;
}
- /*! Apply an approximated first derivative gaussian filter of \p sigma on
- * \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
inline
- mln_concrete(I)
- gaussian_1st_derivative(const Image<I>& input, float sigma, int dir)
+ coefficients coefficients_2nd_derivative(double sigma)
{
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(-0.6472f, -4.531f,
- 1.527f, 1.516f,
- 0.6494f, 0.9557f,
- 0.6719f, 2.072f,
- sigma, impl::gaussian_1st_deriv_coef_norm_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
- return output;
+ coefficients tmp(-1.3310, +3.661,
+ +1.2400, +1.314,
+ +0.3225, -1.738,
+ +0.7480, +2.166,
+ sigma,
+ norm_2nd_derivative);
}
- /*! Apply an approximated second derivative gaussian filter of \p sigma on
- * \p input.
- * on a specific direction \p dir
- * if \p dir = 0, the filter is applied on the first image dimension.
- * if \p dir = 1, the filter is applied on the second image dimension.
- * And so on...
- *
- * \pre input.is_valid
- * \pre dir < dimension(input)
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_2nd_derivative(const Image<I>& input, float sigma, int dir)
- {
- mln_precondition(exact(input).is_valid());
- mln_precondition(dir < I::site::dim);
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(-1.331f, 3.661f,
- 1.24f, 1.314f,
- 0.3225f, -1.738f,
- 0.748f, 2.166f,
- sigma, impl::gaussian_2nd_deriv_coef_norm_);
-
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output, dir);
- return output;
- }
-
-
-
-
-
- /*! Apply an approximated gaussian filter of \p sigma on \p input.
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian(const Image<I>& input, float sigma)
- {
- mln_precondition(exact(input).is_valid());
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(1.68f, 3.735f,
- 1.783f, 1.723f,
- -0.6803f, -0.2598f,
- 0.6318f, 1.997f,
- sigma, impl::gaussian_norm_coef_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
-
- return output;
- }
-
-
- /*! Apply an approximated first derivative gaussian filter of \p sigma on
- * \p input
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_1st_derivative(const Image<I>& input, float sigma)
- {
- mln_precondition(exact(input).is_valid());
-
- mln_concrete(I) output;
- initialize(output, input);
-
- impl::recursivefilter_coef_
- coef(-0.6472f, -4.531f,
- 1.527f, 1.516f,
- 0.6494f, 0.9557f,
- 0.6719f, 2.072f,
- sigma, impl::gaussian_1st_deriv_coef_norm_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
- return output;
- }
-
-
- /*! Apply an approximated second derivative gaussian filter of \p sigma on
- * \p input
- * This filter is applied in all the input image direction.
- *
- * \pre input.is_valid
- */
- template <typename I>
- inline
- mln_concrete(I)
- gaussian_2nd_derivative(const Image<I>& input, float sigma)
- {
- mln_precondition(exact(input).is_valid());
-
- mln_concrete(I) output;
- initialize(output, input);
+# endif // ! MLN_INCLUDE_ONLY
- impl::recursivefilter_coef_
- coef(-1.331f, 3.661f,
- 1.24f, 1.314f,
- 0.3225f, -1.738f,
- 0.748f, 2.166f,
- sigma, impl::gaussian_2nd_deriv_coef_norm_);
- impl::generic_filter_common_(mln_trait_value_nature(mln_value(I))(),
- input, coef, sigma, output);
- return output;
- }
+ } // end of namespace mln::linear::gaussian::internal
-# endif // ! MLN_INCLUDE_ONLY
+ } // end of namespace mln::linear::gaussian
} // end of namespace mln::linear
} // end of namespace mln
-#endif // ! MLN_LINEAR_GAUSSIAN_HH
+#endif // ! MLN_LINEAR_GAUSSIAN_INTERNAL_COEFFICIENTS_HH
Property changes on: mln/linear/gaussian/internal/coefficients.hh
___________________________________________________________________
Added: svn:mergeinfo
Index: mln/labeling/compute.hh
--- mln/labeling/compute.hh (revision 3725)
+++ mln/labeling/compute.hh (working copy)
@@ -128,7 +128,7 @@
const mln_value(L)& nlabels)
{
mln_precondition(exact(label).is_valid());
- mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
+ // mlc_is_a(mln_value(L), mln::value::Symbolic)::check();
(void) a;
(void) label;
(void) nlabels;
Index: mln/labeling/pack.hh
--- mln/labeling/pack.hh (revision 3725)
+++ mln/labeling/pack.hh (working copy)
@@ -34,7 +34,6 @@
/// Remove components and relabel a labeled image in order to have a
/// contiguous labeling.
-
# include <mln/core/concept/image.hh>
# include <mln/make/relabelfun.hh>
@@ -71,7 +70,7 @@
//
template <typename I>
void
- relabel_inplace(Image<I>& label, mln_value(I)& new_nlabels);
+ pack_inplace(Image<I>& label, mln_value(I)& new_nlabels);
Index: tests/linear/Makefile.am
--- tests/linear/Makefile.am (revision 3725)
+++ tests/linear/Makefile.am (working copy)
@@ -2,7 +2,9 @@
include $(top_srcdir)/milena/tests/tests.mk
-SUBDIRS = local
+SUBDIRS = \
+ gaussian \
+ local
check_PROGRAMS = \
convolve \
Index: tests/linear/gaussian/Makefile.am
--- tests/linear/gaussian/Makefile.am (revision 0)
+++ tests/linear/gaussian/Makefile.am (working copy)
@@ -3,8 +3,8 @@
include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
- convolve
+ filter
-convolve_SOURCES = convolve.cc
+filter_SOURCES = filter.cc
TESTS = $(check_PROGRAMS)
Property changes on: tests/linear/gaussian/Makefile.am
___________________________________________________________________
Added: svn:mergeinfo
Index: tests/linear/gaussian/filter.cc
--- tests/linear/gaussian/filter.cc (revision 0)
+++ tests/linear/gaussian/filter.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
@@ -26,27 +26,20 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file tests/linear/gaussian.cc
+/// \file tests/linear/gaussian/filter.cc
///
-/// Test on mln::linear::gaussian.
+/// Test on mln::linear::gaussian::filter.
#include <mln/core/image/image2d.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/int_u_sat.hh>
+#include <mln/value/int_u8.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
-#include <mln/level/transform.hh>
-#include <mln/data/paste.hh>
-#include <mln/math/round.hh>
-
-#include <mln/linear/gaussian.hh>
+#include <mln/linear/gaussian/filter.hh>
#include "tests/data.hh"
-#include <mln/trace/all.hh>
-
int main()
@@ -56,12 +49,6 @@
image2d<value::int_u8> lena;
io::pgm::load(lena, MLN_IMG_DIR "/lena.pgm");
- image2d<value::int_u8> out = linear::gaussian(lena, 5.1f);
+ image2d<value::int_u8> out = linear::gaussian::filter(lena, 5.1f);
io::pgm::save(out, "out.pgm");
-
-
- image2d<float> lenaf(lena.domain());
- data::paste(lena, lenaf);
-
- image2d<float> outf = linear::gaussian(lenaf, 5.1f);
}
Property changes on: tests/linear/gaussian/filter.cc
___________________________________________________________________
Added: svn:mergeinfo
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-04-29 Etienne FOLIO <folio(a)lrde.epita.fr>
Histograms update.
* folio/mln/histo/compute_histo.hh: Some brainstorming.
* folio/mln/histo/compute_histo_3d.hh: Some corrections from compute_histo.
---
compute_histo.hh | 60 +++++++++++++++++++++++++++++++++++-----------------
compute_histo_3d.hh | 34 +++++++++++++++++++++++------
2 files changed, 68 insertions(+), 26 deletions(-)
Index: trunk/milena/sandbox/folio/mln/histo/compute_histo.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/histo/compute_histo.hh (revision 3724)
+++ trunk/milena/sandbox/folio/mln/histo/compute_histo.hh (revision 3725)
@@ -6,42 +6,64 @@
#include <mln/core/image/image.hh>
#include <mln/trait/value/comp.hh>
-#include <mln/trait/image_from_grid.hh>
-
namespace mln
{
namespace histo
{
- template <typename C, typename I>
- Image<C> compute_histo(Image<I> ima_)
+ template <typename I>
+ struct compute_histo
+ {
+ Image<unsigned> operator()(const Image<I>& ima_) const;
+
+ namespace internal
+ {
+ }
+
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename I>
+ inline
+ ImageNd<dim, unsigned> // ? dim? imageNd?
+ operator()(const Image<I>& ima_) const
{
I ima = exact(ima);
typedef mln_value(I) V;
- typedef mln_regular_grid_from_dim(V::dim + 1) G;
- typedef mln_image_from_grid(G, C) O;
- O out;
- for (unsigned i = 0; i < V::dim + 1; ++i)
+ // Create image Nd from value types of ima.
+ algebra::vec<V::dim, unsigned> pmin, pmax;
+ for (unsigned i = 0; i < V::dim; ++i)
{
- typedef mln_trait_value_comp(I, i)::enc enc[i];
- // FIXME: define here the domain of `out'.
- // out(mln_max(enc[0]) + abs(mln_min(enc[0])) + 1,
- // mln_max(enc[1]) + abs(mln_min(enc[1])) + 1,
- // mln_max(enc[2]) + abs(mln_min(enc[2])) + 1);
+ typedef mln_trait_value_comp(V, i)::enc enc;
+ pmin[i] = mln_min(enc);
+ pmax[i] = mln_max(enc);
}
- data::fill(out, mln_min(C));
- // count
+ typedef box<site> _box; // ? site?
+ _box box(pmin, pmax);
+ ImageNd<V::dim, unsigned> out(box); // ? ImageNd?
+
+
+ // Count occurences.
+ data::fill(out, 0);
+
mln_fwd_piter(box2d) p(ima.domain());
for_all(p)
- // FIXME: call macro comp()?
- // FIXME: pointnd
- ++out(point3d(ima(p).comp(0), ima(p).comp(1), ima(p).comp(2)));
+ {
+ algebra::vec<V::dim, site> // ? site?
+ for (unsigned i = 0; i < V::dim; ++i)
+ // comp() not implemented everywhere!
+ pt[i] = ima(p).comp(i);
+ ++out(pointNd(pt)); // ? pointNd?
+ }
- // return
return out;
}
+# endif // !MLN_INCLUDE_ONLY
+
}
}
Index: trunk/milena/sandbox/folio/mln/histo/compute_histo_3d.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/histo/compute_histo_3d.hh (revision 3724)
+++ trunk/milena/sandbox/folio/mln/histo/compute_histo_3d.hh (revision 3725)
@@ -12,27 +12,47 @@
namespace histo
{
- template <typename C, typename T>
- image3d<C> compute_histo_3d(image2d<T> ima)
+ template <typename T>
+ struct compute_histo_3d
+ {
+ image3d<unsigned> operator()(const image2d<T>& ima) const;
+
+ namespace internal
+ {
+ }
+
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ inline
+ image3d<unsigned>
+ operator()(const image2d<T>& ima) const
{
- // out
typedef mln_trait_value_comp(T, 0)::enc enc_0;
typedef mln_trait_value_comp(T, 1)::enc enc_1;
typedef mln_trait_value_comp(T, 2)::enc enc_2;
- image3d<C> out(mln_max(enc_0) + abs(mln_min(enc_0)) + 1,
+
+ // FIXME: wrong for negative sites!
+ image3d<unsigned> out(mln_max(enc_0) + abs(mln_min(enc_0)) + 1,
mln_max(enc_1) + abs(mln_min(enc_1)) + 1,
mln_max(enc_2) + abs(mln_min(enc_2)) + 1);
- data::fill(out, mln_min(C));
- // count
+ // Count occurences.
+ data::fill(out, 0);
+
mln_fwd_piter(box2d) p(ima.domain());
for_all(p)
- // FIXME: call macro comp()?
+ // comp() not implemented everywhere!
++out(point3d(ima(p).comp(0), ima(p).comp(1), ima(p).comp(2)));
// return
return out;
}
+# endif // !MLN_INCLUDE_ONLY
+
}
}
1
0
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
New shell script dedicated to fast word segmentation.
* icdar/2009/hsc/first_attempts/words_25p.sh: New.
This version works on images reduced by 25%.
* icdar/2009/hsc/ws_to_wsl.hh: Add log.
first_attempts/words_25p.sh | 11 +++++++++++
ws_to_wsl.hh | 21 +++++++++++++++++++++
2 files changed, 32 insertions(+)
Index: icdar/2009/hsc/first_attempts/words_25p.sh
--- icdar/2009/hsc/first_attempts/words_25p.sh (revision 0)
+++ icdar/2009/hsc/first_attempts/words_25p.sh (revision 0)
@@ -0,0 +1,11 @@
+#! /bin/sh
+
+bin_rep='/home/theo/lrde/olena/trunk/milena/sandbox/theo/+bin'
+
+convert -geometry 25% +compress -depth 8 $1 tmp_small.pgm
+convert -negate -geometry 25% +compress $1 tmp_small.pbm
+$bin_rep/closing_rectangle tmp_small.pbm 1 7 tmp_small_clo.pbm
+$bin_rep/distance_thick tmp_small_clo.pbm tmp_dist.pgm
+$bin_rep/closing_area tmp_dist.pgm 125 tmp_clo.pgm
+$bin_rep/watershed_flooding tmp_clo.pgm tmp_ws.pgm
+$bin_rep/watershed_superpose tmp_small.pgm tmp_ws.pgm tmp_out.ppm
Property changes on: icdar/2009/hsc/first_attempts/words_25p.sh
___________________________________________________________________
Added: svn:executable
+ *
Index: icdar/2009/hsc/ws_to_wsl.hh
--- icdar/2009/hsc/ws_to_wsl.hh (revision 3723)
+++ icdar/2009/hsc/ws_to_wsl.hh (working copy)
@@ -18,6 +18,8 @@
#include <mln/algebra/mat.hh>
#include <mln/make/region_adjacency_graph.hh>
+#include <mln/make/p_vertices_with_mass_centers.hh>
+#include <mln/debug/draw_graph.hh>
#include <mln/core/site_set/p_edges.hh>
#include <mln/core/site_set/p_vertices.hh>
@@ -301,6 +303,25 @@
}
+#ifdef LOG
+ {
+ image2d<value::rgb8> cool(small.domain());
+ data::fill(cool, literal::white);
+ data::fill((cool | (pw::value(ws) == pw::cst(0))).rw(),
+ literal::red);
+
+ typedef p_vertices< G, fun::i2v::array<point2d> > pv_t;
+ pv_t pv = make::p_vertices_with_mass_centers(ws, n_basins, gr);
+
+ debug::draw_graph(cool, pv,
+ literal::green,
+ literal::black);
+
+ io::ppm::save(cool, "temp_cool.ppm");
+ }
+#endif // LOG
+
+
util::array<unsigned>
v_left (n_basins + 1),
v_right(n_basins + 1);
1
0
URL: https://svn.lrde.epita.fr/svn/scool/branches/scool-ng
ChangeLog:
2009-04-29 Warren Seine <soow(a)lrde.epita.fr>
mini-std: Improve the hierarchy.
* mini-std.hh: Still not compiling.
Added Object (root of the hierarchy).
Replaced Exact with E in templates (was SCOOP2).
Added standard traits.
Removed "automatic implementations" (was SCOOP2).
Added Iterator abstraction.
Added comments refering to Milena hierarchy.
Replaced stc_typename's with typedef's when needed (was SCOOP2).
Removed "impl_" prefix (was SCOOP2).
Removed "bridge" (what?!).
---
mini-std.hh | 474 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 419 insertions(+), 55 deletions(-)
Index: branches/scool-ng/examples/mini-std/c++/mini-std.hh
===================================================================
--- branches/scool-ng/examples/mini-std/c++/mini-std.hh (revision 150)
+++ branches/scool-ng/examples/mini-std/c++/mini-std.hh (revision 151)
@@ -34,7 +34,29 @@
namespace mstd
{
- // Add #include's here
+ // Fwd decl.
+ template <typename E> struct Object;
+
+ // Object category flag type.
+ template <>
+ struct Object<void>
+ {
+ // typedef Unknown<void> super; // LOL !?
+ };
+
+
+ /*! \brief Base class for almost every class defined in Milena.
+ *
+ * The parameter \a E is the exact type.
+ */
+ template <typename E>
+ struct Object
+ {
+ typedef E exact_t;
+ typedef Object<void> category; // Default.
+ protected:
+ Object() {}
+ };
} // End of namespace mstd
@@ -52,13 +74,10 @@
namespace mstd
{
// Forward declaration.
- template <typename Exact>
+ template <typename E>
struct Container;
- template <typename Exact>
- struct ForwardContainer;
-
- template <typename Exact>
+ template <typename E>
struct Iterator;
// Container category flag type.
@@ -67,6 +86,13 @@
{
typedef Object<void> super;
};
+
+ // Container category flag type.
+ template <>
+ struct Iterator<void>
+ {
+ typedef Object<void> super;
+ };
}
@@ -76,14 +102,64 @@
namespace mstd
{
- namespace trait // mln/core/image/image2d.hh:94
+ namespace trait // See: mln/trait/image/props.hh:352
{
// Undefined property tag
struct undef { std::string name() const { return "undef"; } };
+ namespace container
+ {
+ struct category
+ {
+ struct any
+ { protected: any() {} };
+
+ struct primary : any
+ { std::string name() const { return "category::primary"; } };
+
+ struct morpher : any
+ { protected: morpher() {} };
- template <typename C>
- struct undefined_container_ // mln/trait/images.hh:134
+ struct x_morpher : morpher
+ { std::string name() const { return "category::x_morpher"; } };
+ };
+
+ struct speed
+ {
+ struct any
+ { protected: any() {} };
+
+ struct slow : any
+ { std::string name() const { return "speed::slow"; } };
+
+ struct fast : any
+ { std::string name() const { return "speed::fast"; } };
+
+ struct fastest : fast
+ { std::string name() const { return "speed::fastest"; } };
+ };
+
+ struct size
+ {
+ struct any
+ { protected: any() {} };
+
+ struct huge : any
+ { std::string name() const { return "size::huge"; } };
+
+ struct regular : any
+ { std::string name() const { return "size::regular"; } };
+ };
+ }
+ }
+}
+
+namespace mstd
+{
+ namespace trait // See: mln/core/image/image2d.hh:94
+ {
+ template <typename T>
+ struct undefined_container_ // See: mln/trait/images.hh:134
{
// misc
typedef undef category;
@@ -91,35 +167,46 @@
typedef undef size;
// data (I::value)
- typedef undef kind;
- typedef undef nature;
- typedef undef quant;
+ // typedef undef kind;
+ // typedef undef nature;
+ // typedef undef quant;
};
- template <typename C>
- struct container_ : undefined_container_<C>
+ template <typename T>
+ struct container_ : undefined_container_<T>
{
};
- template <typename T, typename C>
- struct default_container_ : undefined_container_<C>
+ template <typename T>
+ struct default_container_ : undefined_container_<T>
{
+ public:
+ typedef trait::container::speed::fast speed;
};
- }
-}
-/*----------------------------.
-| Automatic implementations. |
-`----------------------------*/
+ template <typename T>
+ struct undefined_iterator_
+ {
+ };
-namespace mstd
+
+ template <typename T>
+ struct iterator_ : undefined_iterator_<T>
{
};
+ template <typename T>
+ struct default_iterator_ : undefined_iterator_<T>
+ {
+ };
+ }
+}
+
+
/*---------------.
| Abstractions. |
`---------------*/
@@ -130,6 +217,78 @@
// Iterator. //
// ---------- //
+ // Base class for implementation of iterator classes
+
+ template <typename E>
+ struct Iterator :
+ public Object<E>
+ {
+ /*
+ bool is_valid() const;
+ void invalidate();
+ void start();
+ void next_();
+ */
+
+ Iterator()
+ {
+ bool (E::*m1)() const = & E::is_valid;
+ m1 = 0;
+ void (E::*m2)() = & E::invalidate;
+ m2 = 0;
+ void (E::*m3)() = & E::start;
+ m3 = 0;
+ void (E::*m4)() = & E::next_;
+ m4 = 0;
+ }
+
+ template <typename J>
+ Container<E>& operator=(const J& rhs)
+ {
+ /// You are assigning an iterator of a concrete type to
+ /// an iterator with a concept type. It does NOT work.
+ ///
+ /// You forgot a call to exact() on the left operand!
+
+ // FIXME: Add the following check:
+ // mlc_abort(E)::check();
+ return *this;
+ }
+
+ // value_t operator*()
+ // {
+ // return *(exact(this));
+ // }
+
+ // bool operator==(const Exact& it)
+ // {
+ // return exact(this) == it;
+ // }
+
+ // bool operator!=(const Exact& it)
+ // {
+ // return exact(this) == it;
+ // }
+
+ /*! \brief Go to the next element.
+ *
+ * \warning This is a final method; iterator classes should not
+ * re-defined this method. The actual "next" operation has to be
+ * defined through the \em next_ method.
+ *
+ * \pre The iterator is valid.
+ */
+ void next()
+ {
+ assert(exact(this)->is_valid());
+ exact(this)->next_();
+ }
+
+ protected:
+ Iterator();
+ };
+
+
// ----------- //
// Container. //
// ----------- //
@@ -137,59 +296,109 @@
// Base class for implementation of container classes
template <typename E>
- struct Container : public Object< E >
+ struct Container :
+ public Object<E>
{
typedef Container<void> category;
+ template <typename J>
+ Container<E>& operator=(const J& rhs)
+ {
+ /// You are assigning an container of a concrete type to
+ /// an container with a concept type. It does NOT work.
+ ///
+ /// You forgot a call to exact() on the left operand!
+
+ // FIXME: Add the following check:
+ // mlc_abort(E)::check();
+ return *this;
+ }
+
/*
// provided by internal::container_base:
- typedef value_t;
typedef size_t;
typedef stdcontainer_t;
+ size_t size() const;
+
+ bool empty() const;
+
+ void clear();
+
+ stdcontainer_t& get_stdcontainer();
+
+
+ // to be provided in concrete container classes:
+
+ typedef value_t;
*/
protected:
Container()
{
- // FIXME: Add check just like in mln/core/concept/image.hh
+ // See: mln/core/concept/image.hh:199
+
+ // FIXME: Add new checks like above
+
+ // size_t (E::*m1)() const = & E::size;
+ // m1 = 0;
+
+ // provided by internal::container_base:
+
+ typedef typename E::value_t value_t;
}
};
- template <typename E> struct Container;
-
- template <typename Exact>
- struct Container : virtual public Any<Exact>,
- virtual public automatic::set_impl< Container, behavior::identity, Exact >
- //automatic::get_impl<Container, Exact>
+ namespace internal
+ {
+ /// A base class for containers.
+ /// Parameter \p T is the container value type.
+ template <typename T, typename E>
+ struct container_base :
+ public Container<E>
{
- stc_typename(value_t);
- stc_typename(size_t);
- stc_typename(stdcontainer_t);
+ typedef std::size_t size_t;
+ typedef typename mstd::trait::container_<E>::stdcontainer_t stdcontainer_t;
size_t size() const
{
- return exact(this)->impl_size();
+ return exact(this)->size();
}
bool empty() const
{
- return exact(this)->impl_empty();
+ return exact(this)->empty();
}
void clear()
{
- exact(this)->impl_clear();
+ exact(this)->clear();
}
stdcontainer_t& get_stdcontainer()
{
- return exact(this)->impl_get_stdcontainer();
+ return exact(this)->get_stdcontainer();
}
+
+ protected:
+
+ /// Constructor without argument.
+ container_base();
};
+ /// A base class for primary containers.
+ /// Parameter \p T is the container value type.
+ template <typename T, typename E>
+ struct container_primary : public container_base<T, E>
+ {
+ protected:
+ container_primary() { }
+ };
+ }
+
+
// ----------------- //
// SortedContainer. //
// ----------------- //
@@ -206,16 +415,16 @@
// ForwardContainer. //
// ------------------ //
- template <typename Exact>
- struct ForwardContainer : public virtual Container<Exact>,
- public virtual automatic::set_impl<ForwardContainer, behavior::identity, Exact>
+ template <typename E>
+ struct ForwardContainer : public Container<E>
{
- typedef Container<Exact> super;
- stc_typename(iter_t);
+ typedef Container<E> super;
+
+ typedef typename mstd::trait::container_<E>::iter_t iter_t;
iter_t begin()
{
- return exact(this)->impl_begin();
+ return exact(this)->begin();
}
};
@@ -242,13 +451,6 @@
} // End of namespace mstd.
-/*---------.
-| Bridge. |
-`---------*/
-namespace mstd
-{
- // FIXME
-} // End of namespace mstd.
/*------------------.
| Implementations. |
@@ -256,7 +458,82 @@
namespace mstd
{
- // FIXME: Iterators
+ // ------------------ //
+ // Forward_Iterator. //
+ // ------------------ //
+
+ // Forward declarations.
+ template <typename T, typename E>
+ struct Forward_Iterator;
+
+
+ namespace trait
+ {
+ template <typename E>
+ struct iterator_< Forward_Iterator<E> > :
+ public default_iterator_< Forward_Iterator<E> >
+ {
+ typedef T container_t;
+
+ typedef typename container_t::value_t value_t;
+ };
+ }
+
+
+ template <typename T, typename E>
+ struct Forward_Iterator :
+ public Iterator< Forward_Iterator<T> >
+ {
+ typedef mstd::trait::iterator_<E>::container_t container_t;
+
+ Forward_Iterator(container_t& c) :
+ c_ (c),
+ iter_ (c.get_stdcontainer().begin())
+ {
+ }
+
+ value_t& operator*()
+ {
+ return *iter_;
+ }
+
+ Forward_Iterator<T, E>& operator++()
+ {
+ iter_++;
+ return *exact(this);
+ }
+
+ Forward_Iterator<T, E> operator++(int)
+ {
+ current ret = *exact(this);
+ ++iter_;
+ return ret;
+ }
+
+ void to_begin()
+ {
+ iter_ = c_.get_stdcontainer().begin();
+ }
+
+ void to_end()
+ {
+ iter_ = c_.get_stdcontainer().end();
+ }
+
+ bool operator==(const Forward_Iterator<T, E>& it)
+ {
+ return this->iter_ == it.iter_;
+ }
+
+ bool operator!=(const Forward_Iterator<T, E>& it)
+ {
+ return this->iter_ != it.iter_;
+ }
+
+ protected:
+ container_t& c_;
+ iter_t iter_;
+ };
// ------ //
@@ -267,18 +544,105 @@
template <typename T>
struct list;
- namespace trait // mln/core/image/image2d.hh:94
+
+ namespace trait // See: mln/core/image/image2d.hh:94
{
template <typename T>
- struct container_< list<T> > : default_container_< T, list<T> >
+ struct container_< list<T> > :
+ public default_container_< T, list<T> >
{
// misc
typedef trait::container::category::primary category;
+
+ // typedef mlc::true_ is_isfrontinsertion;
+ // typedef mlc::true_ is_isbackinsertion;
+
+ // typedef mlc::true_ is_mutable;
+
+ typedef T value_t;
+
+ typedef bi_dir_iterator< list<T> > iter_t;
+
+ typedef std::list<T> stdcontainer_t;
};
}
- // FIXME: List implementation
+ template <typename T>
+ class list :
+ public internal::container_primary< T, list<T> >
+ {
+ public:
+ typedef T value_t;
+
+ /// Constructor without argument.
+ list();
+
+ size_t size() const
+ {
+ return list_.size();
+ }
+
+ bool empty() const
+ {
+ return list_.empty();
+ }
+
+ void clear()
+ {
+ list_.clear();
+ }
+
+ stdcontainer_t& get_stdcontainer()
+ {
+ return list_;
+ }
+
+ void push_front(value_t& v)
+ {
+ list_.push_front(v);
+ }
+
+ void pop_front()
+ {
+ list_.pop_front();
+ }
+
+ void push_back(value_t& v)
+ {
+ list_.push_back(v);
+ }
+
+ void pop_back()
+ {
+ list_.pop_back();
+ }
+
+ iter_t begin()
+ {
+ return iter_t(*this);
+ }
+
+ iter_t end()
+ {
+ iter_t it(*this);
+ it.to_end();
+ return it;
+ }
+
+ value_t& front()
+ {
+ return list_.front();
+ }
+
+ value_t& back()
+ {
+ return list_.back();
+ }
+
+ protected:
+ stdcontainer_t list_;
+ };
// ---------- //
// Morphers. //
--
:: Warren Seine // SooW ::
:: warren.seine @ gmail.com ::
:: EPITA CSI 2010 ::
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-04-29 Etienne FOLIO <folio(a)lrde.epita.fr>
HSV type.
* folio/mln/fun/v2v/rgb_to_hsv.hh: New conversions.
* folio/mln/fun/v2v: New folder.
* folio/mln/fun: New folder.
* folio/mln/value/circular.hh: Comment a part of unused code.
* folio/mln/value/hsv.hh: New HSV type.
* folio/test/value/hsv.cc: New tests file for HSV type.
---
mln/fun/v2v/rgb_to_hsv.hh | 148 ++++++++++++++++
mln/value/circular.hh | 4
mln/value/hsv.hh | 419 ++++++++++++++++++++++++++++++++++++++++++++++
test/value/hsv.cc | 13 +
4 files changed, 582 insertions(+), 2 deletions(-)
Index: trunk/milena/sandbox/folio/test/value/hsv.cc
===================================================================
--- trunk/milena/sandbox/folio/test/value/hsv.cc (revision 0)
+++ trunk/milena/sandbox/folio/test/value/hsv.cc (revision 3723)
@@ -0,0 +1,13 @@
+
+#include <mln/core/image/image2d.hh>
+#include "../../mln/value/hsv.hh"
+#include "../../mln/value/circular.hh"
+
+int main()
+{
+ using namespace mln;
+ using namespace mln::value;
+
+ image2d< hsv_< circular<16, 0, 360>, float, float > > ima;
+
+}
Index: trunk/milena/sandbox/folio/mln/fun/v2v/rgb_to_hsv.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/fun/v2v/rgb_to_hsv.hh (revision 0)
+++ trunk/milena/sandbox/folio/mln/fun/v2v/rgb_to_hsv.hh (revision 3723)
@@ -0,0 +1,148 @@
+// Copyright (C) 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.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/// \file mln/fin/v2v/rgb_to_hsv.hh
+///
+/// Conversion between RGB and HSV.
+///
+/// \todo Write a better doc.
+/// \todo Correct/write preconditions.
+
+
+#ifndef MLN_FUN_V2V_RGB_TO_HSV_HH
+# define MLN_FUN_V2V_RGB_TO_HSV_HH
+
+# include <cmath>
+
+# include <mln/trait/value_.hh>
+# include <mln/math/max.hh>
+# include <mln/math/min.hh>
+
+# include <mln/value/rgb.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ namespace v2v
+ {
+
+ template <typename T_hsv>
+ struct f_rgb_to_hsv_ : public Function_v2v< f_rgb_to_hsv_<T_hsv> >
+ {
+ typedef T_hsv result;
+
+ template <typename T_rgb>
+ T_hsv operator()(const T_rgb& rgb) const;
+ };
+
+ template <typename T_rgb>
+ struct f_hsv_to_rgb_ : public Function_v2v< f_hsv_to_rgb_<T_rgb> >
+ {
+ typedef T_rgb result;
+
+ template <typename T_hsv>
+ T_rgb operator()(const T_hsv& hsv) const;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename T_hsv>
+ template <typename T_rgb>
+ inline
+ T_hsv
+ f_rgb_to_hsv_<T_hsv>::operator()(const T_rgb& rgb) const
+ {
+ T_hsv hsv;
+
+ // FIXME: take rgb [[0..1], [0..1], [0..1]]
+
+ typename T_rgb::red_t rmax =
+ math::max(rgb.red(), math::max(rgb.green(), rgb.blue()));
+
+ typename T_rgb::red_t rmin =
+ math::min(rgb.red(), math::min(rgb.green(), rgb.blue()));
+
+ if (rmax == rmin)
+ hsv.hue() = 0;
+ else if (rmax == rgb.red())
+ hsv.hue() = (60. * (rgb.green() - rgb.blue()) / (rmax - rmin));
+ else if (rmax == rgb.green())
+ hsv.hue() = (60. * (rgb.blue() - rgb.red()) / (rmax - rmin)) + 120.;
+ else if (rmax == rgb.blue())
+ hsv.hue() = (60. * (rgb.red() - rgb.green()) / (rmax - rmin)) + 240.;
+
+ hsv.sat() = (rmax == 0) ? 0 : (1 - rmin / rmax);
+ hsv.val() = rmax;
+
+ // return hsv [[0..360], [0..1], [0..1]]
+ return hsv;
+ }
+
+
+ template <typename T_rgb>
+ template <typename T_hsv>
+ inline
+ T_rgb
+ f_hsv_to_rgb_<T_rgb>::operator()(const T_hsv& hsv) const
+ {
+ // take hsv [[0..360], [0..1], [0..1]]
+
+ float i = floor(hsv.hue() / 60);
+ float f = hsv.hue() / 60 - i;
+ float p = hsv.val() * (1 - hsv.sat());
+ float q = hsv.val() * (1 - f * hsv.sat());
+ float t = hsv.val() * (1 - (1 - f) * hsv.sat());
+
+ T_rgb rgb;
+ switch(i)
+ {
+ case 0: rgb = T_rgb(hsv.val(), t, p); break;
+ case 1: rgb = T_rgb(q, hsv.val(), p); break;
+ case 2: rgb = T_rgb(p, hsv.val(), t); break;
+ case 3: rgb = T_rgb(p, q, hsv.val()); break;
+ case 4: rgb = T_rgb(t, p, hsv.val()); break;
+ case 5: rgb = T_rgb(hsv.val(), p, q); break;
+ }
+
+ // FIXME: return rgb [[0..1], [0..1], [0..1]]
+ return rgb;
+ }
+
+# endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace fun::v2v
+
+ } // end of namespace fun
+
+} // end of namespace mln
+
+#endif // ! MLN_FUN_V2V_RGB_TO_HSV_HH
Index: trunk/milena/sandbox/folio/mln/value/circular.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/value/circular.hh (revision 3722)
+++ trunk/milena/sandbox/folio/mln/value/circular.hh (revision 3723)
@@ -153,8 +153,8 @@
template <unsigned n, int inf, int sup>
std::ostream& operator<<(std::ostream& ostr, const circular<n, inf, sup>& f);
- template <unsigned n, int inf, int sup, unsigned m, int inf2, int sup2>
- bool approx_equal(const circular<n, inf, sup>& lhs, const circular<m, inf2, sup2>& rhs);
+ // template <unsigned n, int inf, int sup, unsigned m, int inf2, int sup2>
+ // bool approx_equal(const circular<n, inf, sup>& lhs, const circular<m, inf2, sup2>& rhs);
template <unsigned n, int inf, int sup>
bool approx_equal(const circular<n, inf, sup>& lhs, const float f);
Index: trunk/milena/sandbox/folio/mln/value/hsv.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/value/hsv.hh (revision 0)
+++ trunk/milena/sandbox/folio/mln/value/hsv.hh (revision 3723)
@@ -0,0 +1,419 @@
+// Copyright (C) 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
+// 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 mln/value/hsv.hh
+///
+/// Color class.
+///
+/// \todo Write a better doc.
+/// \todo Cleanup/Revamp!
+/// \todo Need for more preconditions?
+
+#ifndef MLN_VALUE_HSV_HH
+# define MLN_VALUE_HSV_HH
+
+#include <mln/value/ops.hh>
+
+#include <mln/value/concept/vectorial.hh>
+#include <mln/value/int_u.hh>
+#include <mln/algebra/vec.hh>
+
+#include "circular.hh"
+
+// Used in from_to
+#include "../fun/v2v/rgb_to_hsv.hh"
+
+
+namespace mln
+{
+
+ // Forward declarations.
+ namespace value
+ {
+
+ template <typename H, typename S, typename V>
+ class hsv_;
+
+ }
+
+
+
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ // ?
+ template <int n>
+ void
+ from_to_(const value::rgb<n>& from,
+ value::hsv_<value::circular<n, 0, 360>, float, float>& to);
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+
+
+
+ namespace trait
+ {
+
+ // ?
+
+ template <typename H, typename S, typename V>
+ struct set_precise_binary_< op::plus,
+ mln::value::hsv_<H, S, V>,
+ mln::value::hsv_<H, S, V> >
+ {
+ typedef mln::value::hsv_<H, S, V> ret;
+ };
+
+ template <typename H, typename S, typename V>
+ struct set_precise_binary_< op::minus,
+ mln::value::hsv_<H, S, V>,
+ mln::value::hsv_<H, S, V> >
+ {
+ typedef mln::value::hsv_<H, S, V> ret;
+ };
+
+ template <typename H, typename S, typename V, typename S2>
+ struct set_precise_binary_< op::times,
+ mln::value::hsv_<H, S, V>,
+ mln::value::scalar_<S2> >
+ {
+ typedef mln::value::hsv_<H, S, V> ret;
+ };
+
+ template <typename H, typename S, typename V, typename S2>
+ struct set_precise_binary_< op::div,
+ mln::value::hsv_<H, S, V>,
+ mln::value::scalar_<S2> >
+ {
+ typedef mln::value::hsv_<H, S, V> ret;
+ };
+
+
+ // FIXME : Is there any way more generic? a way to factor
+ // set_precise_binary_< op::div,
+ // mln::value::hsv_<H, S, V>,
+ // mln::value::scalar_<S> >
+ // and
+ // set_precise_binary_< op::div,
+ // mln::value::hsv_<H, S, V>,
+ // mln::value::int_u<m> >
+ // as for op::times.
+
+ template <typename H, typename S, typename V, unsigned m>
+ struct set_precise_binary_< op::times,
+ mln::value::hsv_<H, S, V>,
+ mln::value::int_u<m> >
+ {
+ typedef mln::value::hsv_<H, S, V> ret;
+ };
+
+ template <typename H, typename S, typename V, unsigned m>
+ struct set_precise_binary_< op::div,
+ mln::value::hsv_<H, S, V>,
+ mln::value::int_u<m> >
+ {
+ typedef mln::value::hsv_<H, S, V> ret;
+ };
+
+
+ template <typename H, typename S, typename V>
+ struct value_< mln::value::hsv_<H, S, V> >
+ {
+ enum {
+ dim = 3,
+ nbits = (sizeof (H) + sizeof (S) + sizeof (V)) * 8, // ?
+ card = mln_value_card_from_(nbits)
+ };
+
+ typedef trait::value::nature::vectorial nature;
+ typedef trait::value::kind::color kind;
+ typedef mln_value_quant_from_(card) quant;
+
+ typedef H comp_0;
+ typedef S comp_1;
+ typedef V comp_2;
+
+ typedef mln::value::hsv_<H, S, V> sum;
+ };
+
+ } // end of namespace trait
+
+
+ namespace value
+ {
+
+ // ?
+ template <typename E>
+ struct HSV : Object<E>
+ {
+ };
+
+
+ template <typename H, typename S, typename V>
+ class hsv_ : public HSV< hsv_<H, S, V> >
+ {
+ public:
+
+ /// Constructor without argument.
+ hsv_()
+ {
+ }
+
+ hsv_(const literal::zero_t&)
+ : hue_(0),
+ sat_(0),
+ val_(0)
+ {
+ }
+
+ /// Constructor from component values.
+ hsv_(const H& hue, const S& sat, const V& lum)
+ {
+ mln_precondition(hue >= 0);
+ mln_precondition(sat >= 0);
+ mln_precondition(val >= 0);
+ mln_precondition(hue <= 1.); // ?
+ mln_precondition(sat <= 1.);
+ mln_precondition(val <= 1.);
+ hue_ = hue;
+ sat_ = sat;
+ val_ = val;
+ }
+
+ /// Read-only access to the hue component.
+ const H& hue() const;
+ const S& sat() const;
+ const V& val() const;
+
+ // ?
+ // hue(float), hue(H) instead?
+
+ /// Read-write access to the hue component.
+ H& hue();
+ S& sat();
+ V& val();
+
+ private:
+ H hue_;
+ S sat_;
+ V val_;
+ };
+
+ /// Print an hsv \p c into the output stream \p ostr.
+ ///
+ /// \param[in,out] ostr An output stream.
+ /// \param[in] c An rgb.
+ ///
+ /// \return The modified output stream \p ostr.
+ template <typename H, typename S, typename V>
+ std::ostream& operator<<(std::ostream& ostr, const hsv_<H, S, V>& c);
+
+
+ /// Addition.
+ /// {
+ template <typename H, typename S, typename V>
+ hsv_<H, S, V>
+ operator+(const hsv_<H, S, V>& lhs, const hsv_<H, S, V>& rhs);
+ /// \}
+
+ /// Subtraction.
+ /// \{
+ template <typename H, typename S, typename V>
+ hsv_<H, S, V>
+ operator-(const hsv_<H, S, V>& lhs, const hsv_<H, S, V>& rhs);
+ /// \}
+
+ /// Product.
+ /// \{
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H, S, V>
+ operator*(const hsv_<H, S, V>& lhs, const mln::value::scalar_<S2>& s);
+ /// \}
+
+ /// Division.
+ /// \{
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H, S, V>
+ operator/(const hsv_<H, S, V>& lhs, const mln::value::scalar_<S2>& s);
+ /// \}
+
+ } // end of namespace mln::value
+
+
+
+ // More forward declarations
+ namespace fun
+ {
+ namespace v2v
+ {
+
+ template <typename T_hsv>
+ struct f_rgb_to_hsv_;
+
+// typedef f_rgb_to_hsv_<value::hsv_f> f_rgb_to_hsv_f_t;
+// extern f_rgb_to_hsv_f_t f_rgb_to_hsv_f;
+
+ }
+
+ }
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ namespace value
+ {
+
+ template <typename H, typename S, typename V>
+ const H&
+ hsv_<H, S, V>::hue() const
+ {
+ return this->hue_;
+ }
+
+ template <typename H, typename S, typename V>
+ const S&
+ hsv_<H, S, V>::sat() const
+ {
+ return this->sat_;
+ }
+
+ template <typename H, typename S, typename V>
+ const V&
+ hsv_<H, S, V>::val() const
+ {
+ return this->val_;
+ }
+
+ template <typename H, typename S, typename V>
+ H&
+ hsv_<H, S, V>::hue()
+ {
+ return this->hue_;
+ }
+
+ template <typename H, typename S, typename V>
+ S&
+ hsv_<H, S, V>::sat()
+ {
+ return this->sat_;
+ }
+
+ template <typename H, typename S, typename V>
+ V&
+ hsv_<H, S, V>::val()
+ {
+ return this->val_;
+ }
+
+
+ template <typename H, typename S, typename V>
+ inline
+ std::ostream& operator<<(std::ostream& ostr, const hsv_<H, S, V>& v)
+ {
+ return ostr << '(' << debug::format(v.hue())
+ << ',' << debug::format(v.sat())
+ << ',' << debug::format(v.val())
+ << ')';
+ }
+
+
+ template <typename H, typename S, typename V>
+ hsv_<H, S, V>
+ operator+(const hsv_<H, S, V>& lhs, const hsv_<H, S, V>& rhs)
+ {
+ return hsv_<H, S, V>(lhs.hue() + rhs.hue(),
+ lhs.sat() + rhs.sat(),
+ lhs.val() + rhs.val());
+ }
+
+
+ template <typename H, typename S, typename V>
+ hsv_<H, S, V>
+ operator-(const hsv_<H, S, V>& lhs, const hsv_<H, S, V>& rhs)
+ {
+ return hsv_<H, S, V>(lhs.hue() - rhs.hue(),
+ lhs.sat() - rhs.sat(),
+ lhs.val() - rhs.val());
+ }
+
+
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H, S, V>
+ operator*(const hsv_<H, S, V>& lhs, const mln::value::scalar_<S2>& s)
+ {
+ return hsv_<H, S, V>(lhs.hue() * s,
+ lhs.sat() * s,
+ lhs.val() * s);
+ }
+
+
+ template <typename H, typename S, typename V, typename S2>
+ hsv_<H, S, V>
+ operator/(const hsv_<H, S, V>& lhs, const mln::value::scalar_<S2>& s)
+ {
+ return hsv_<H, S, V>(lhs.hue() / s,
+ lhs.sat() / s,
+ lhs.val() / s);
+ }
+
+ } // end of namespace mln::value
+
+
+ namespace convert
+ {
+
+ namespace over_load
+ {
+
+ // ?
+ template <int n>
+ inline
+ void
+ from_to_(const value::rgb<n>& from,
+ value::hsv_<value::circular<n, 0, 360>, float, float>& to)
+ {
+ to = fun::v2v::f_rgb_to_hsv_<
+ value::hsv_<value::circular<n, 0, 360>, float, float> >(from);
+ }
+
+ } // end of namespace mln::convert::over_load
+
+ } // end of namespace mln::convert
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+} // end of namespace mln
+
+#endif // ! MLN_VALUE_HSV_HH
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk
ChangeLog:
2009-04-28 Frederic Bour <bour(a)lrde.epita.fr>
Correct bugs, point functions.
* milena/mln/fun/point/col.hh: New.
* milena/mln/fun/point/row.hh: New.
* milena/mln/fun/point/sli.hh: New.
* milena/mln/fun/point: New.
* milena/mln/fun/spe/unary.hh: Improved proxy support.
* milena/mln/fun/unary.hh: Improved proxy support.
* milena/mln/trait/next/solve_proxy.hh: Typo errors correction.
* milena/sandbox/fred/tests/fun.cc,
* milena/sandbox/fred/tests/thru.cc: Add some tests for proxy.
---
mln/fun/point/col.hh | 84 ++++++++++++++++++++++++++++++++++++++++++
mln/fun/point/row.hh | 84 ++++++++++++++++++++++++++++++++++++++++++
mln/fun/point/sli.hh | 84 ++++++++++++++++++++++++++++++++++++++++++
mln/fun/spe/unary.hh | 26 ++++++++++++-
mln/fun/unary.hh | 2 -
mln/trait/next/solve_proxy.hh | 15 ++-----
sandbox/fred/tests/fun.cc | 2 -
sandbox/fred/tests/thru.cc | 12 ++++++
8 files changed, 295 insertions(+), 14 deletions(-)
Index: trunk/milena/mln/trait/next/solve_proxy.hh
===================================================================
--- trunk/milena/mln/trait/next/solve_proxy.hh (revision 3721)
+++ trunk/milena/mln/trait/next/solve_proxy.hh (revision 3722)
@@ -25,17 +25,12 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_CONCEPT_PROXY_HH
-# define MLN_CORE_CONCEPT_PROXY_HH
+#ifndef MLN_TRAIT_NEXT_SOLVE_PROXY_HH
+# define MLN_TRAIT_NEXT_SOLVE_PROXY_HH
-/*! \file mln/core/concept/proxy.hh
+/*! \file mln/trait/next/solve_proxy.hh
*
- * \brief Definition of the concept of mln::Proxy.
- *
- * \todo preinc and predec are not tested; post-like ops are not handled.
- *
- * \todo add "op=(T)" when possible, so add a constness property.
- * \todo add "opT()const" when possible.
+ * \brief Proxy support for "next" trait solver.
*/
# include <mln/core/concept/object.hh>
@@ -99,4 +94,4 @@
} // end of namespace mln
-#endif // ! MLN_CORE_CONCEPT_PROXY_HH
+#endif // ! MLN_TRAIT_NEXT_SOLVE_PROXY_HH
Index: trunk/milena/mln/fun/spe/unary.hh
===================================================================
--- trunk/milena/mln/fun/spe/unary.hh (revision 3721)
+++ trunk/milena/mln/fun/spe/unary.hh (revision 3722)
@@ -202,9 +202,20 @@
using super::operator ();
+ lresult apply_rw(typename super::argument& value) const
+ {
+ return lresult(exact(*this), value);
+ }
+
+ template <typename U>
+ typename lresult_with<U>::ret apply_rw(U& value) const
+ {
+ return typename lresult_with<U>::ret(exact(*this), value);
+ }
+
lresult operator () (typename super::argument& value) const
{
- return lresult(this, value);
+ return apply_rw(value);
}
};
@@ -256,10 +267,21 @@
using super::operator ();
- lresult operator () (typename super::argument& value) const
+ lresult apply_rw(typename super::argument& value) const
{
return lresult(exact(*this), value);
}
+
+ template <typename U>
+ typename lresult_with<U>::ret apply_rw(U& value) const
+ {
+ return typename lresult_with<U>::ret(exact(*this), value);
+ }
+
+ lresult operator () (typename super::argument& value) const
+ {
+ return apply_rw(value);
+ }
};
} // end of namespace mln::fun::spe::impl
Index: trunk/milena/mln/fun/point/row.hh
===================================================================
--- trunk/milena/mln/fun/point/row.hh (revision 0)
+++ trunk/milena/mln/fun/point/row.hh (revision 3722)
@@ -0,0 +1,84 @@
+// 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 rowistribute 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_FUN_POINT_ROW_HH
+# define MLN_FUN_POINT_ROW_HH
+
+/// \file mln/fun/point/row.hh
+///
+/// Meta function to retrieve/modify the row coord of a point.
+
+# include <mln/fun/unary.hh>
+# include <mln/core/point.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ struct row : unary<row> {};
+
+ } // end of namespace mln::fun
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ template <typename G, typename C>
+ struct set_precise_unary_<mln::fun::row, mln::point<G,C> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::point<G,C> argument;
+ typedef typename argument::coord result;
+ typedef argument& lvalue;
+
+ static result read(const argument& p)
+ {
+ return p.row();
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l.row() = r;
+ }
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // MLN_FUN_POINT_ROW_HH
Index: trunk/milena/mln/fun/point/sli.hh
===================================================================
--- trunk/milena/mln/fun/point/sli.hh (revision 0)
+++ trunk/milena/mln/fun/point/sli.hh (revision 3722)
@@ -0,0 +1,84 @@
+// 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 rowistribute 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_FUN_POINT_SLI_HH
+# define MLN_FUN_POINT_SLI_HH
+
+/// \file mln/fun/point/sli.hh
+///
+/// Meta function to retrieve/modify the sli coord of a point.
+
+# include <mln/fun/unary.hh>
+# include <mln/core/point.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ struct sli : unary<sli> {};
+
+ } // end of namespace mln::fun
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ template <typename G, typename C>
+ struct set_precise_unary_<mln::fun::col, mln::point<G, C> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::point<G,C> argument;
+ typedef typename argument::coord result;
+ typedef argument& lvalue;
+
+ static result read(const argument& p)
+ {
+ return p.sli();
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l.sli() = r;
+ }
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // MLN_FUN_POINT_SLI_HH
Index: trunk/milena/mln/fun/point/col.hh
===================================================================
--- trunk/milena/mln/fun/point/col.hh (revision 0)
+++ trunk/milena/mln/fun/point/col.hh (revision 3722)
@@ -0,0 +1,84 @@
+// 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 rowistribute 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_FUN_POINT_COL_HH
+# define MLN_FUN_POINT_COL_HH
+
+/// \file mln/fun/point/col.hh
+///
+/// Meta function to retrieve/modify the col coord of a point.
+
+# include <mln/fun/unary.hh>
+# include <mln/core/point.hh>
+
+namespace mln
+{
+
+ namespace fun
+ {
+
+ struct col : unary<col> {};
+
+ } // end of namespace mln::fun
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace trait
+ {
+
+ namespace next
+ {
+
+ template <typename G, typename C>
+ struct set_precise_unary_<mln::fun::col, mln::point<G, C> >
+ {
+ typedef set_precise_unary_ ret;
+ typedef mln::point<G,C> argument;
+ typedef typename argument::coord result;
+ typedef argument& lvalue;
+
+ static result read(const argument& p)
+ {
+ return p.col();
+ }
+
+ static void write(lvalue l, const result& r)
+ {
+ l.col() = r;
+ }
+ };
+
+ } // end of namespace mln::trait::next
+
+ } // end of namespace mln::trait
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+#endif // MLN_FUN_POINT_COL_HH
Index: trunk/milena/mln/fun/unary.hh
===================================================================
--- trunk/milena/mln/fun/unary.hh (revision 3721)
+++ trunk/milena/mln/fun/unary.hh (revision 3722)
@@ -71,7 +71,7 @@
template <typename T>
typename with<T>::ret::template lresult_with<T>::ret operator()(T& v) const
{
- return typename with<T>::ret(storage_get())(v);
+ return typename with<T>::ret(storage_get()).apply_rw(v);
}
template <typename T, typename R>
Index: trunk/milena/sandbox/fred/tests/thru.cc
===================================================================
--- trunk/milena/sandbox/fred/tests/thru.cc (revision 3721)
+++ trunk/milena/sandbox/fred/tests/thru.cc (revision 3722)
@@ -6,11 +6,16 @@
#include <mln/core/var.hh>
#include <mln/core/image/image2d.hh>
+
+#include <mln/fun/point/row.hh>
+
#include <mln/value/int_u8.hh>
#include <mln/debug/all.hh>
#include <iostream>
#include <typeinfo>
+#include <mln/trait/next/solve_proxy.hh>
+
#define dbg_print(val) std::cout << #val << "\n\t -> \t" << (val) << std::endl
int main()
@@ -32,5 +37,12 @@
data::fill_with_image(ima2, tmp);
+ mln::fun::row row;
+
+ mln_piter_(I) p(ima.domain());
+
+ for_all(p)
+ std::cout << row(p);
+
debug::println(ima2);
}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/tests/fun.cc
===================================================================
--- trunk/milena/sandbox/fred/tests/fun.cc (revision 3721)
+++ trunk/milena/sandbox/fred/tests/fun.cc (revision 3722)
@@ -2,10 +2,10 @@
#include <mln/fun/math/abs.hh>
#include <mln/fun/math/cos.hh>
#include <mln/fun/math/norm.hh>
-// #include <mln/fun/math/inc.hh>
#include <mln/fun/component/red.hh>
#include <mln/fun/component/comp.hh>
#include <mln/value/rgb8.hh>
+
#include <iostream>
#define dbg_print(val) std::cout << #val << "\n\t -> \t" << (val) << std::endl
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-04-28 Etienne FOLIO <folio(a)lrde.epita.fr>
Circular value type.
* folio/mln/value/circular.hh: New type.
* folio/test/value/circular.cc: New tests.
---
mln/value/circular.hh | 268 +++++++++++++++++++++++++++++++++++++++++++++++++
test/value/circular.cc | 48 ++++++++
2 files changed, 316 insertions(+)
Index: trunk/milena/sandbox/folio/test/value/circular.cc
===================================================================
--- trunk/milena/sandbox/folio/test/value/circular.cc (revision 0)
+++ trunk/milena/sandbox/folio/test/value/circular.cc (revision 3721)
@@ -0,0 +1,48 @@
+
+#include <mln/value/float01.hh>
+
+#include "../../mln/value/circular.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using namespace mln::value;
+
+ circular<12, 0, 360> inter(21);
+ std::cout << "21: " << inter << " " << float(inter) << std::endl;
+ inter = 0;
+ std::cout << "0: " << inter << std::endl;
+ inter = 42;
+ std::cout << "42: " << inter << std::endl;
+ inter = 359;
+ std::cout << "359: " << inter << std::endl;
+ inter = 359.5;
+ std::cout << "359.5: " << inter << std::endl;
+ inter = 360;
+ std::cout << "360: " << inter << std::endl;
+ inter = 360.5;
+ std::cout << "360.5: " << inter << std::endl;
+ inter = 361;
+ std::cout << "361: " << inter << std::endl;
+ inter = 372;
+ std::cout << "372: " << inter << std::endl;
+ inter = 972;
+ std::cout << "972: " << inter << std::endl;
+ inter = -0.2;
+ std::cout << "-0.2: " << inter << std::endl;
+ inter = -1;
+ std::cout << "-1: " << inter << std::endl;
+ inter = -1;
+ std::cout << "-1: " << inter << std::endl;
+ inter = -359;
+ std::cout << "-359: " << inter << std::endl;
+ inter = -359.5;
+ std::cout << "-359.5: " << inter << std::endl;
+ inter = -360;
+ std::cout << "-360: " << inter << std::endl;
+ inter = -360.5;
+ std::cout << "-360.5: " << inter << std::endl;
+ inter = -361;
+ std::cout << "-361: " << inter << std::endl;
+}
Index: trunk/milena/sandbox/folio/mln/value/circular.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/value/circular.hh (revision 0)
+++ trunk/milena/sandbox/folio/mln/value/circular.hh (revision 3721)
@@ -0,0 +1,268 @@
+// Copyright (C) 2006, 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_VALUE_CIRCULAR_HH
+# define MLN_VALUE_CIRCULAR_HH
+
+/*! \file mln/value/circular.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <iostream>
+# include <math.h>
+# include <mln/core/contract.hh>
+# include <mln/metal/math/pow.hh>
+# include <mln/metal/bexpr.hh>
+
+# include <mln/value/int_u.hh>
+# include <mln/value/concept/floating.hh>
+# include <mln/value/internal/convert.hh>
+# include <mln/trait/value_.hh>
+
+
+
+namespace mln
+{
+
+ // Fwd decls.
+ namespace value {
+ template <unsigned n, int inf, int sup> struct circular;
+ }
+
+
+ namespace trait
+ {
+
+ template <unsigned n, int inf, int sup>
+ struct value_< mln::value::circular<n, inf, sup> >
+ {
+ enum constants_ {
+ dim = 1,
+ nbits = n,
+ card = mln_value_card_from_(nbits)
+ };
+
+ typedef trait::value::nature::floating nature;
+ typedef trait::value::kind::data kind;
+ typedef mln_value_quant_from_(card) quant;
+
+ static float min() { return 0.f; }
+ static float max() { return 1.f; }
+ static float epsilon() { return 0.f; }
+
+ typedef float comp;
+
+ typedef float sum;
+ };
+
+ } // end of namespace trait
+
+
+ namespace value
+ {
+
+ /// General class for the interval [0,1] of |R made discrete (quantized with n bits).
+ template <unsigned n, int inf, int sup>
+ struct circular
+
+ : public Floating< circular<n, inf, sup> >,
+
+ public internal::value_like_< float, // Equivalent. // FIXME: Why not circular?
+ mln_enc(int_u<n>), // Encoding.
+ float, // Interoperation.
+ circular<n, inf, sup> > // Exact.
+ {
+ /// Constructor without argument.
+ circular();
+
+ /// Constructor from a float.
+ circular(float val);
+
+ /// Assigment from a float.
+ circular<n, inf, sup>& operator=(float val);
+
+ /// Access to std type.
+ float value() const;
+
+ /// Set value to the \p val th position in the quantized interval.
+ void set_ind(unsigned long val);
+
+ /// Conversion to a float.
+ operator float() const;
+
+ private:
+ typedef mln_enc(int_u<n>) enc_;
+
+ float
+ circle(const float i) const;
+
+ float float01encode(const float i) const;
+ float float01decode(const float i) const;
+
+ };
+
+
+ namespace internal
+ {
+
+ template <unsigned n, int inf, int sup>
+ struct convert_< circular<n, inf, sup> >
+ {
+ static circular<n, inf, sup> value_at_index(unsigned i)
+ {
+ circular<n, inf, sup> tmp;
+ tmp.set_ind(i);
+ return tmp;
+ }
+
+ static unsigned index_of_value(const circular<n, inf, sup>& v)
+ {
+ return v.to_enc();
+ }
+ };
+ }
+
+
+ /// Op<<.
+ template <unsigned n, int inf, int sup>
+ std::ostream& operator<<(std::ostream& ostr, const circular<n, inf, sup>& f);
+
+ template <unsigned n, int inf, int sup, unsigned m, int inf2, int sup2>
+ bool approx_equal(const circular<n, inf, sup>& lhs, const circular<m, inf2, sup2>& rhs);
+
+ template <unsigned n, int inf, int sup>
+ bool approx_equal(const circular<n, inf, sup>& lhs, const float f);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Circular<n, inf, sup>.
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>::circular()
+ {
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::float01encode(const float i) const
+ {
+ return circle((i - inf) / (sup - inf));
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::float01decode(const float i) const
+ {
+ return i * (sup - inf) + inf;
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>::circular(float val)
+ {
+ this->v_ = static_cast<enc_>(float01encode(val) * (float(mln_max(enc_)) - 1.f)); // FIXME
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::circle(const float i) const
+ {
+ return (int(floor(i)) - inf) % (sup - inf) + inf + (i - floor(i));
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::value() const
+ {
+ return float(float01decode(this->v_)) / (float(mln_max(enc_)) - 1.f); // FIXME
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ void
+ circular<n, inf, sup>::set_ind(unsigned long val)
+ {
+ this->v_ = static_cast<enc_>(val);
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>&
+ circular<n, inf, sup>::operator=(float val)
+ {
+ this->v_ = static_cast<enc_>(float01encode(val) * (float(mln_max(enc_)) - 1.f)); // FIXME
+ return *this;
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>::operator float() const
+ {
+ return float(float01decode(this->v_)) / (float(mln_max(enc_)) - 1.f);
+ }
+
+
+ // Operators.
+
+ template <unsigned n, int inf, int sup>
+ inline
+ std::ostream& operator<<(std::ostream& ostr, const circular<n, inf, sup>& f)
+ {
+ return ostr << f.value();
+ }
+
+ // template <unsigned n, int inf, int sup, unsigned m, int inf2, int sup2>
+ // inline
+ // bool approx_equal(const circular<n, inf, sup>& lhs, const circular<m, inf2, sup2>& rhs)
+ // {
+ // return circular<n, inf, sup>(lhs) == circular<>(rhs);
+ // }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ bool approx_equal(const circular<n, inf, sup>& lhs, float f)
+ {
+ return circular<n, inf, sup>(lhs) == circular<n, inf, sup>(f);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+#endif // ! MLN_VALUE_CIRCULAR_HH
1
0
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-04-28 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add world/ directory for inter_pixel images.
* mln/arith/all.hh: Update.
* mln/arith/div.hh: New div operator.
* mln/arith/div.spe.hh: New div operator.
* mln/io/magick/save.hh: Update.
* mln/io/plot/save.hh: Update.
* mln/world/inter_pixel/full.hh: Convert standard image
to inter_pixel image.
* mln/world/inter_pixel/neighb2d.hh: Define standard
inter_pixel neighborhood.
---
arith/all.hh | 1
arith/div.hh | 289 ++++++++++++++++++++++++++++++++++++++++++
arith/div.spe.hh | 121 +++++++++++++++++
io/magick/save.hh | 2
io/plot/save.hh | 4
world/inter_pixel/full.hh | 77 +++++++++++
world/inter_pixel/neighb2d.hh | 83 ++++++++++++
7 files changed, 574 insertions(+), 3 deletions(-)
Index: trunk/milena/mln/world/inter_pixel/full.hh
===================================================================
--- trunk/milena/mln/world/inter_pixel/full.hh (revision 0)
+++ trunk/milena/mln/world/inter_pixel/full.hh (revision 3720)
@@ -0,0 +1,77 @@
+// 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.
+
+#ifndef MLN_WORLD_INTER_PIXEL_FULL_HH
+# define MLN_WORLD_INTER_PIXEL_FULL_HH
+
+/// \file mln/world/inter_pixel/full.hh
+///
+/// FIXME: insert comment.
+
+# include <mln/core/image/image2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace inter_pixel
+ {
+
+ template <typename T>
+ image2d<T>
+ image2full(const image2d<T>& input)
+ {
+ image2d<T> output(2 * input.nrows() - 1,
+ 2 * input.ncols() - 1);
+ for (int row = 0; row < input.nrows(); ++row)
+ for (int col = 0; col < input.ncols(); ++col)
+ opt::at(output, 2 * row, 2 * col) = opt::at(input, row, col);
+ return output;
+ }
+
+ template <typename T>
+ image2d<T>
+ full2image(const image2d<T>& input)
+ {
+ image2d<T> output((input.nrows() + 1) / 2,
+ (input.ncols() + 1) / 2);
+ for (int row = 0; row < input.nrows(); row += 2)
+ for (int col = 0; col < input.ncols(); col += 2)
+ opt::at(output, row / 2, col / 2) =
+ opt::at(input, row, col);
+ return output;
+ }
+
+ } // end of namespace mln::world::inter_pixel
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_INTER_PIXEL_FULL
Index: trunk/milena/mln/world/inter_pixel/neighb2d.hh
===================================================================
--- trunk/milena/mln/world/inter_pixel/neighb2d.hh (revision 0)
+++ trunk/milena/mln/world/inter_pixel/neighb2d.hh (revision 3720)
@@ -0,0 +1,83 @@
+// 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.
+
+#ifndef MLN_WORLD_INTER_PIXEL_NEIGHB2D_HH
+# define MLN_WORLD_INTER_PIXEL_NEIGHB2D_HH
+
+/// \file mln/world/inter_pixel/neighb2d.hh
+///
+/// FIXME: insert comment.
+
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/make/double_neighb2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace inter_pixel
+ {
+
+ typedef neighb< win::multiple<window2d, bool(*)(const point2d&)> > dbl_neighb2d;
+
+ const dbl_neighb2d& e2c()
+ {
+ static bool e2c_h[] = { 0, 1, 0,
+ 0, 0, 0,
+ 0, 1, 0 };
+ static bool e2c_v[] = { 0, 0, 0,
+ 1, 0, 1,
+ 0, 0, 0 };
+ static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2c_h, e2c_v);
+ return nbh;
+ }
+
+ const dbl_neighb2d& e2e()
+ {
+ static bool e2e_h[] = { 0, 0, 1, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 0, 0, 1, 0, 0 };
+ static bool e2e_v[] = { 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0,
+ 1, 0, 0, 0, 1,
+ 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0 };
+ static dbl_neighb2d nbh = make::double_neighb2d(is_row_odd, e2e_h, e2e_v);
+ return nbh;
+ }
+
+ } // end of namespace mln::world::inter_pixel
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_INTER_PIXEL_NEIGHB2D
Index: trunk/milena/mln/arith/div.hh
===================================================================
--- trunk/milena/mln/arith/div.hh (revision 0)
+++ trunk/milena/mln/arith/div.hh (revision 3720)
@@ -0,0 +1,289 @@
+// 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_ARITH_DIV_HH
+# define MLN_ARITH_DIV_HH
+
+/// \file mln/arith/div.hh
+///
+/// Point-wise division between images.
+///
+/// \todo Speedup; some versions are not optimal.
+
+# include <mln/arith/includes.hh>
+
+// Specializations are in:
+# include <mln/arith/div.spe.hh>
+
+
+namespace mln
+{
+
+
+ namespace trait
+ {
+
+ template <typename L, typename R>
+ struct set_binary_< op::div, Image, L, Image, R >
+ {
+ typedef mln_trait_op_div(mln_value(L), mln_value(R)) value;
+ typedef mln_ch_value(L, value) ret;
+ };
+
+ template <typename I, typename S>
+ struct set_binary_< op::div, Image, I, mln::value::Scalar, S >
+ {
+ typedef mln_trait_op_div(mln_value(I), S) value;
+ typedef mln_ch_value(I, value) ret;
+ };
+
+ } // end of namespace mln::trait
+
+
+
+ template <typename L, typename R>
+ mln_trait_op_div(L,R)
+ operator/(const Image<L>& lhs, const Image<R>& rhs);
+
+ template <typename L, typename R>
+ L&
+ operator/=(Image<L>& lhs, const Image<R>& rhs);
+
+
+ template <typename I, typename S>
+ mln_trait_op_div(I,S)
+ operator/(const Image<I>& ima, const value::Scalar<S>& s);
+
+ template <typename I, typename S>
+ I&
+ operator/=(Image<I>& ima, const value::Scalar<S>& s);
+
+
+
+ namespace arith
+ {
+
+ /// Point-wise division of images \p lhs and \p rhs.
+ /*!
+ * \param[in] lhs First operand image.
+ * \param[in] rhs Second operand image.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain == \p lhs.domain == \p rhs.domain
+ */
+ template <typename L, typename R, typename O>
+ void div(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output);
+
+
+ /// Point-wise division of the value \p val to image \p input.
+ /*!
+ * \param[in] input The image.
+ * \param[in] val The value.
+ * \param[out] output The result image.
+ *
+ * \pre \p output.domain == \p input.domain
+ */
+ template <typename I, typename V, typename O>
+ void div_cst(const Image<I>& input, const V& val, Image<O>& output);
+
+
+ /// Point-wise division of image \p rhs in image \p lhs.
+ /*!
+ * \param[in] lhs First operand image (subject to division).
+ * \param[in,out] rhs Second operand image (to div \p lhs).
+ *
+ * This addition performs: \n
+ * for all p of rhs.domain \n
+ * lhs(p) /= rhs(p)
+ *
+ * \pre \p rhs.domain <= \p lhs.domain
+ */
+ template <typename L, typename R>
+ void div_inplace(Image<L>& lhs, const Image<R>& rhs);
+
+
+ } // end of namespace mln::arith
+
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ template <typename L, typename R>
+ inline
+ mln_trait_op_div(L,R)
+ operator/(const Image<L>& lhs, const Image<R>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() == exact(lhs).domain());
+ mln_trait_op_div(L,R) tmp;
+ initialize(tmp, lhs);
+ arith::div(lhs, rhs, tmp);
+ return tmp;
+ }
+
+ template <typename L, typename R>
+ inline
+ L&
+ operator/=(Image<L>& lhs, const Image<R>& rhs)
+ {
+ mln_precondition(exact(rhs).domain() == exact(lhs).domain());
+ arith::div_inplace(lhs, rhs);
+ return exact(lhs);
+ }
+
+
+ template <typename I, typename S>
+ inline
+ mln_trait_op_div(I,S)
+ operator/(const Image<I>& ima, const value::Scalar<S>& s)
+ {
+ mln_precondition(exact(ima).is_valid());
+ mln_precondition(s != 0);
+ mln_trait_op_div(I,S) tmp;
+ initialize(tmp, ima);
+ arith::div_cst(ima, exact(s), tmp);
+ return tmp;
+ }
+
+ template <typename I, typename S>
+ inline
+ I&
+ operator/=(Image<I>& ima, const value::Scalar<S>& s)
+ {
+ mln_precondition(exact(ima).is_valid());
+ arith::div_cst(ima, exact(s), ima);
+ return exact(ima);
+ }
+
+
+
+ namespace arith
+ {
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename L, typename R, typename O>
+ inline
+ void div_(const L& lhs, const R& rhs, O& output)
+ {
+ trace::entering("arith::impl::generic::div_");
+
+ mln_piter(L) p(lhs.domain());
+ for_all(p)
+ output(p) = lhs(p) / rhs(p);
+
+ trace::exiting("arith::impl::generic::div_");
+ }
+
+ template <typename L, typename R>
+ inline
+ void div_inplace_(L& lhs, const R& rhs)
+ {
+ trace::entering("arith::impl::generic::div_inplace_");
+
+ mln_piter(R) p(rhs.domain());
+ for_all(p)
+ lhs(p) /= rhs(p);
+
+ trace::exiting("arith::impl::generic::div_inplace_");
+ }
+
+ } // end of namespace mln::arith::impl::generic
+
+ } // end of namespace mln::arith::impl
+
+
+ // Facades.
+
+ template <typename L, typename R, typename O>
+ inline
+ void div(const Image<L>& lhs, const Image<R>& rhs, Image<O>& output)
+ {
+ trace::entering("arith::div");
+
+ mln_precondition(exact(rhs).domain() == exact(lhs).domain());
+ mln_precondition(exact(output).domain() == exact(lhs).domain());
+ impl::div_(mln_trait_image_speed(L)(), exact(lhs),
+ mln_trait_image_speed(R)(), exact(rhs),
+ mln_trait_image_speed(O)(), exact(output));
+
+ trace::exiting("arith::div");
+ }
+
+ template <typename I, typename V, typename O>
+ inline
+ void div_cst(const Image<I>& input, const V& val, Image<O>& output)
+ {
+ trace::entering("arith::div_cst");
+
+ mln_precondition(exact(output).domain() == exact(input).domain());
+ div(input, pw::cst(val) | exact(input).domain(), output);
+ // Calls the previous version.
+
+ trace::exiting("arith::div_cst");
+ }
+
+ template <typename L, typename R>
+ inline
+ void div_inplace(Image<L>& lhs, const Image<R>& rhs)
+ {
+ trace::entering("arith::div_inplace");
+
+ mln_precondition(exact(rhs).domain() <= exact(lhs).domain());
+ impl::div_inplace_(mln_trait_image_speed(L)(), exact(lhs),
+ mln_trait_image_speed(R)(), exact(rhs));
+
+ trace::exiting("arith::div_inplace");
+ }
+
+ template <typename I, typename V>
+ inline
+ void div_cst_inplace(Image<I>& input, const V& val)
+ {
+ trace::entering("arith::div_cst_inplace");
+
+ mln_precondition(exact(input).is_valid());
+ div_inplace(input, pw::cst(val) | exact(input).domain());
+ // Calls the previous version.
+
+ trace::exiting("arith::div_cst_inplace");
+ }
+
+ } // end of namespace mln::arith
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_ARITH_DIV_HH
Index: trunk/milena/mln/arith/all.hh
===================================================================
--- trunk/milena/mln/arith/all.hh (revision 3719)
+++ trunk/milena/mln/arith/all.hh (revision 3720)
@@ -55,6 +55,7 @@
}
# include <mln/arith/diff_abs.hh>
+# include <mln/arith/div.hh>
# include <mln/arith/min.hh>
# include <mln/arith/minus.hh>
# include <mln/arith/plus.hh>
Index: trunk/milena/mln/arith/div.spe.hh
===================================================================
--- trunk/milena/mln/arith/div.spe.hh (revision 0)
+++ trunk/milena/mln/arith/div.spe.hh (revision 3720)
@@ -0,0 +1,121 @@
+// 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_ARITH_DIV_SPE_HH
+# define MLN_ARITH_DIV_SPE_HH
+
+/// \file mln/arith/div.spe.hh
+///
+/// Specializations for mln::arith::div.
+
+# ifndef MLN_ARITH_DIV_HH
+# error "Forbidden inclusion of *.spe.hh"
+# endif // ! MLN_ARITH_DIV_HH
+
+# include <mln/arith/includes.hh>
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+namespace mln
+{
+
+ namespace arith
+ {
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+ template <typename L, typename R, typename O>
+ void div_(const L& lhs, const R& rhs, O& output);
+
+ template <typename L, typename R>
+ void div_inplace_(L& lhs, const R& rhs);
+
+ }
+
+ template <typename L, typename R, typename O>
+ inline
+ void div_(trait::image::speed::any, const L& lhs,
+ trait::image::speed::any, const R& rhs,
+ trait::image::speed::any, O& output)
+ {
+ generic::div_(lhs, rhs, output);
+ }
+
+ template <typename L, typename R, typename O>
+ inline
+ void div_(trait::image::speed::fastest, const L& lhs,
+ trait::image::speed::fastest, const R& rhs,
+ trait::image::speed::fastest, O& output)
+ {
+ trace::entering("arith::impl::div_");
+
+ mln_pixter(const L) lp(lhs);
+ mln_pixter(const R) rp(rhs);
+ mln_pixter(O) op(output);
+ for_all_3(lp, rp, op)
+ op.val() = lp.val() / rp.val();
+
+ trace::exiting("arith::impl::div_");
+ }
+
+ template <typename L, typename R>
+ inline
+ void div_inplace_(trait::image::speed::any, L& lhs,
+ trait::image::speed::any, const R& rhs)
+ {
+ generic::div_inplace_(lhs, rhs);
+ }
+
+ template <typename L, typename R>
+ inline
+ void div_inplace_(trait::image::speed::fastest, L& lhs,
+ trait::image::speed::fastest, const R& rhs)
+ {
+ trace::entering("arith::impl::div_inplace_");
+
+ mln_pixter(L) lp(lhs);
+ mln_pixter(const R) rp(rhs);
+ for_all_2(rp, lp)
+ lp.val() /= rp.val();
+
+ trace::exiting("arith::impl::div_inplace_");
+ }
+
+ } // end of namespace mln::arith::impl
+
+ } // end of namespace mln::arith
+
+} // end of namespace mln
+
+# endif // ! MLN_INCLUDE_ONLY
+
+#endif // ! MLN_ARITH_DIV_SPE_HH
Index: trunk/milena/mln/io/magick/save.hh
===================================================================
--- trunk/milena/mln/io/magick/save.hh (revision 3719)
+++ trunk/milena/mln/io/magick/save.hh (revision 3720)
@@ -102,7 +102,7 @@
mln::metal::equal<mln_value(I), value::rgb8>::value))
{
std::cerr << "error: trying to save an unsupported format" << std::endl;
- std::cerr << "formats supported: binary, 8bits grayscale (int_u8), 8bits truecolor (rgb8)" << std::endl;
+ std::cerr << "supported formats: binary, 8bits grayscale (int_u8), 8bits truecolor (rgb8)" << std::endl;
abort();
}
Index: trunk/milena/mln/io/plot/save.hh
===================================================================
--- trunk/milena/mln/io/plot/save.hh (revision 3719)
+++ trunk/milena/mln/io/plot/save.hh (revision 3720)
@@ -87,7 +87,7 @@
trace::entering("mln::io::plot::save");
std::ofstream file_out(filename.c_str());
- for (int i = 0; i < ima.ninds(); ++i)
+ for (unsigned i = 0; i < ima.ninds(); ++i)
file_out << start_value + i << ", " << ima.at_(i) << std::endl;
trace::exiting("mln::io::plot::save");
@@ -101,7 +101,7 @@
trace::entering("mln::io::plot::save");
std::ofstream file_out(filename.c_str());
- for (int i = 0; i < arr.nelements(); ++i)
+ for (unsigned i = 0; i < arr.nelements(); ++i)
file_out << start_value + i << ", " << arr[i] << std::endl;
trace::exiting("mln::io::plot::save");
1
0