URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-02-23 Frederic Bour <bour(a)lrde.epita.fr>
Work on meta-functions and overloading added..
* Makefile: .
* accu_trait.hh: Remove.
* accuprops.cc: Remove.
* accuprops2.cc: Remove.
* algebraic.cc: Remove.
* closing_area.cc: Remove.
* connected_filter.hh: Remove.
* leveling.cc: Remove.
* leveling_filter.hh: Remove.
* mean.hh: Remove.
* meantest.cc: Remove.
* old/accu_trait.hh: New.
* old/accuprops.cc: New.
* old/accuprops2.cc: New.
* old/algebraic.cc: New.
* old/closing_area.cc: New.
* old/connected_filter.hh: New.
* old/leveling.cc: New.
* old/leveling_filter.hh: New.
* old/mean.hh: New.
* old/meantest.cc: New.
* old/p2p: New.
* old/value_wrapper.hh: New.
* old: New.
* overload.cc: New.
* p2p: Remove.
* value_wrapper.hh: Remove.
---
Makefile | 2
old/accu_trait.hh | 94 ++++++++++
old/accuprops.cc | 331 +++++++++++++++++++++++++++++++++++
old/accuprops2.cc | 380 +++++++++++++++++++++++++++++++++++++++++
old/algebraic.cc | 406 ++++++++++++++++++++++++++++++++++++++++++++
old/closing_area.cc | 50 +++++
old/connected_filter.hh | 123 +++++++++++++
old/leveling.cc | 47 +++++
old/leveling_filter.hh | 381 +++++++++++++++++++++++++++++++++++++++++
old/mean.hh | 202 +++++++++++++++++++++
old/meantest.cc | 21 ++
old/p2p/Makefile | 12 +
old/p2p/compose_p2p.hh | 44 ++++
old/p2p/p2p_morpher.hh | 284 ++++++++++++++++++++++++++++++
old/p2p/symmetry_p2p.hh | 47 +++++
old/p2p/test_morph_image.cc | 62 ++++++
old/p2p/translate_p2p.hh | 43 ++++
old/value_wrapper.hh | 188 ++++++++++++++++++++
overload.cc | 283 ++++++++++++++++++++++++++++++
19 files changed, 2999 insertions(+), 1 deletion(-)
Index: trunk/milena/sandbox/fred/accuprops.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/meantest.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/accuprops2.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/connected_filter.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/leveling_filter.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/leveling.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/closing_area.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/value_wrapper.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/accu_trait.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/algebraic.cc (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/mean.hh (deleted)
===================================================================
Index: trunk/milena/sandbox/fred/overload.cc
===================================================================
--- trunk/milena/sandbox/fred/overload.cc (revision 0)
+++ trunk/milena/sandbox/fred/overload.cc (revision 3415)
@@ -0,0 +1,283 @@
+#include <mln/core/concept/function.hh>
+#include <mln/core/concept/value.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/trait/op/plus.hh>
+
+// Avantage de cette methode:
+// - la surcharge est rendue effectivement possible pour des familles de types
+// et permet de passer en argument une fonction meme s'il existe de multiple
definitions
+// (^^ sic pour la qualite de l'explication ^^)
+// - de maniere souple (set_previse_binary & set_binary).
+//
+// Inconvenients:
+// - beaucoup de code/verbeux
+// - necessite de reecrire la resolution a la main
+// - l'implementation des differentes surcharge n'est pas aussi intuitive
qu'en C++
+// naturel
+// - passage par les categories. Impossible de tirer parti de la hierarchie
+// "naturelle" des types en C++.
+//
+
+// INF
+namespace mln
+{
+
+ // Forward declaration.
+ namespace fun {
+ namespace vv2v {
+ template <typename T> struct inf;
+ }
+ }
+
+
+ namespace trait
+ {
+
+ // Default (whatever the category):
+ // "inf" performs a "min"!
+ template <template <class> class Category, typename T>
+ struct set_unary_< fun::vv2v::inf, Category, T >
+ {
+ typedef set_unary_< fun::vv2v::inf, Category, T > ret;
+
+ static T exec(const T& t1, const T& t2)
+ {
+ return t1 < t2 ? t1 : t2;
+ }
+
+ // In the case of a binary function with two different argument
+ // types, we shall instrument this definition with the result
+ // type...
+ };
+
+ } // mln::trait
+
+
+
+ namespace fun
+ {
+
+ namespace vv2v
+ {
+
+ // fun::vv2v::inf<T>
+
+ template <typename T>
+ struct inf : Function_vv2v< inf<T> >
+ {
+ typedef T result;
+
+ typedef mln_fun_internal_resolve(inf) impl;
+
+ T operator()(const T& t1, const T& t2) const
+ {
+ return impl::exec(t1, t2);
+ }
+ };
+
+
+ // fun::vv2v::meta::inf
+
+ namespace meta
+ {
+
+ struct inf
+ {
+
+ // A meta-fun can act as a function :-)
+
+ template <typename T>
+ T operator()(const T& t1, const T& t2) const
+ // Here, we know the result type of vv2v::inf<T> so
+ // we explictly write it.
+ {
+ fun::vv2v::inf<T> f;
+ return f(t1, t2);
+ }
+
+ // The "meta-fun -> fun" code is similar to the one in
+ // mln/accu/min.hh
+ template <typename T>
+ struct with
+ {
+ typedef fun::vv2v::inf<T> ret;
+ };
+ };
+
+ } // mln::fun::vv2v::meta
+
+ } // mln::fun::vv2v
+
+ } // mln::fun
+
+ // Yay! A special type equipped with a particular 'inf'.
+
+ struct rgb : Value<rgb>
+ {
+ typedef rgb enc;
+ typedef rgb equiv; // Those couple of typedefs are required by the concept.
+ rgb() {}
+ rgb(int r, int g, int b) : r(r), g(g), b(b) {}
+ int r, g, b;
+ };
+
+ std::ostream& operator<<(std::ostream& ostr, const rgb& c)
+ {
+ ostr << c.r << ' ' << c.g << ' ' <<
c.b;
+ }
+
+ namespace trait
+ {
+
+ template <>
+ struct set_precise_unary_< fun::vv2v::inf, rgb >
+ {
+ typedef set_precise_unary_< fun::vv2v::inf, rgb > ret;
+
+ static rgb exec(const rgb& c1, const rgb& c2)
+ {
+ // "Inf" is component-wise "min".
+ return rgb(c1.r < c2.r ? c1.r : c2.r,
+ c1.g < c2.g ? c1.g : c2.g,
+ c1.b < c2.b ? c1.b : c2.b);
+ }
+ };
+
+ } // mln::trait
+
+} // mln
+
+// PLUS
+namespace mln
+{
+
+ // Forward declaration.
+ namespace fun {
+ namespace vv2v {
+ template <typename L, typename R> struct plus;
+ }
+ }
+
+
+ namespace trait
+ {
+
+ // Default (whatever the category):
+ // "inf" performs a "min"!
+ template <template <class> class Category_L, typename L, template
<class> class Category_R, typename R>
+ struct set_binary_< fun::vv2v::plus, Category_L, L, Category_R, R>
+ {
+ typedef set_binary_< fun::vv2v::plus, Category_L, L, Category_R, R> ret;
+
+ static mln_trait_op_plus(L,R) exec(const L& t1, const R& t2)
+ {
+ return t1 + t2;
+ }
+
+ // In the case of a binary function with two different argument
+ // types, we shall instrument this definition with the result
+ // type...
+ };
+
+ } // mln::trait
+
+
+
+ namespace fun
+ {
+
+ namespace vv2v
+ {
+
+ // fun::vv2v::plus<L,R>
+
+ template <typename L, typename R>
+ struct plus : Function_vv2v< plus<L,R> >
+ {
+ typedef mln_trait_op_plus(L,R) result;
+
+ typedef mln_fun_internal_resolve(plus) impl;
+
+ result operator()(const L& t1, const R& t2) const
+ {
+ return impl::exec(t1, t2);
+ }
+ };
+
+
+ // fun::vv2v::meta::plus
+
+ namespace meta
+ {
+
+ struct plus
+ {
+
+ // A meta-fun can act as a function :-)
+
+ template <typename L, typename R>
+ typename fun::vv2v::plus<L,R>::result operator()(const L& t1, const R&
t2) const
+ // Here, we know the result type of vv2v::plus<L,R> so
+ // we explictly write it.
+ {
+ fun::vv2v::plus<L,R> f;
+ return f(t1, t2);
+ }
+
+ // The "meta-fun -> fun" code is similar to the one in
+ // mln/accu/min.hh
+ template <typename L, typename R>
+ struct with
+ {
+ typedef fun::vv2v::plus<L,R> ret;
+ };
+ };
+
+ } // mln::fun::vv2v::meta
+
+ } // mln::fun::vv2v
+
+ } // mln::fun
+
+ namespace trait
+ {
+
+ template <>
+ struct set_precise_binary_< fun::vv2v::plus, rgb, rgb >
+ {
+ typedef set_precise_binary_< fun::vv2v::plus, rgb, rgb > ret;
+
+ static rgb exec(const rgb& c1, const rgb& c2)
+ {
+ // "Inf" is component-wise "min".
+ return rgb(c1.r + c2.r,
+ c1.g + c2.g,
+ c1.b + c2.b);
+ }
+ };
+
+ template <>
+ struct set_precise_binary_< mln::trait::op::plus, rgb, rgb >
+ {
+ typedef rgb ret;
+ };
+
+ } // mln::trait
+
+} // mln
+
+using namespace mln;
+
+int main()
+{
+ fun::vv2v::meta::inf inf;
+ std::cout << inf(3, 5) << std::endl;
+
+ rgb c1(1, 2, 3), c2(2, 1, 2);
+ std::cout << inf(c1, c2) << std::endl;
+
+ fun::vv2v::meta::plus plus;
+ std::cout << plus(plus(3.1f, 5), 3.1415926535) << std::endl;
+
+ std::cout << plus(c1, c2) << std::endl;
+}
Index: trunk/milena/sandbox/fred/Makefile
===================================================================
--- trunk/milena/sandbox/fred/Makefile (revision 3414)
+++ trunk/milena/sandbox/fred/Makefile (revision 3415)
@@ -1,4 +1,4 @@
-TARGET=connected
+TARGET=overload
OBJS=$(TARGET).o
OLENADIR=../../..
Index: trunk/milena/sandbox/fred/old/p2p/compose_p2p.hh
===================================================================
--- trunk/milena/sandbox/fred/old/p2p/compose_p2p.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/p2p/compose_p2p.hh (revision 3415)
@@ -0,0 +1,44 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/macros.hh>
+#include <mln/core/alias/point2d.hh>
+#include <mln/core/alias/dpoint2d.hh>
+#include <mln/core/var.hh>
+
+namespace mln
+{
+
+ template <typename P, typename F, typename G>
+ class compose_t : public Function_p2p< compose_t<P, F, G> >
+ {
+ public:
+ typedef P result;
+ typedef compose_t<P, typename G::inverse, typename F::inverse> inverse;
+
+ compose_t (const F& f, const G& g)
+ : f_ (f), g_ (g) {};
+
+ P operator() (const P& point) const
+ {
+ return (f_ (g_ (point)));
+ };
+
+ inverse inv () const
+ {
+ inverse comp(g_.inv (), f_.inv ());
+ return comp;
+ };
+
+ private:
+ const F f_;
+ const G g_;
+ };
+
+ template <typename F, typename G>
+ compose_t<typename F::result, F, G> operator* (const Function_p2p< F >&
f,
+ const Function_p2p< G >& g)
+ {
+ compose_t<typename F::result, F, G> comp (exact (f), exact (g));
+ return comp;
+ }
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/old/p2p/symmetry_p2p.hh
===================================================================
--- trunk/milena/sandbox/fred/old/p2p/symmetry_p2p.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/p2p/symmetry_p2p.hh (revision 3415)
@@ -0,0 +1,47 @@
+#include <mln/core/contract.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/macros.hh>
+#include <mln/core/alias/point2d.hh>
+#include <mln/core/alias/dpoint2d.hh>
+#include <mln/core/var.hh>
+
+namespace mln
+{
+
+ template <typename P>
+ class symmetry_t : public Function_p2p< symmetry_t<P> >
+ {
+ public:
+ typedef P result;
+ typedef symmetry_t<P> inverse;
+
+ symmetry_t (unsigned dim)
+ : dim_ (dim)
+ {
+ mln_assertion(dim < P::dim);
+ };
+
+ P operator() (const P& point) const
+ {
+ P pt = point;
+ pt[dim_] = -pt[dim_];
+ return pt;
+ };
+
+ inverse inv () const
+ {
+ return *this;
+ };
+
+ private:
+ const unsigned dim_;
+ };
+
+ template <typename P>
+ symmetry_t<P> flip (unsigned dim)
+ {
+ symmetry_t<P> f (dim);
+ return f;
+ }
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/old/p2p/test_morph_image.cc
===================================================================
--- trunk/milena/sandbox/fred/old/p2p/test_morph_image.cc (revision 0)
+++ trunk/milena/sandbox/fred/old/p2p/test_morph_image.cc (revision 3415)
@@ -0,0 +1,62 @@
+// Copyright (C) 2007 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/core/image/t_image.cc
+ *
+ * \brief Tests on mln::t_image.
+ */
+
+#include <mln/core/image/image2d.hh>
+
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+
+#include "trans_image.hh"
+#include "translate_p2p.hh"
+#include "symmetry_p2p.hh"
+#include "compose_p2p.hh"
+
+#include <iostream>
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<int> I;
+
+ I ima(2, 3);
+ debug::iota(ima);
+ debug::println(ima);
+ // translate(dpoint2d(2,2)) *
+ mln_VAR(tr, transform_image(ima, flip<I::site>(0) * translate(dpoint2d(2,2)) *
flip<I::site>(1)));
+ debug::println(tr);
+
+ std::cout << ima.domain () << " => " << tr.domain ()
<< std::endl;
+
+ // FIXME: Enrich this test (exercise more features and write
+ // assertions).
+}
Index: trunk/milena/sandbox/fred/old/p2p/p2p_morpher.hh
===================================================================
--- trunk/milena/sandbox/fred/old/p2p/p2p_morpher.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/p2p/p2p_morpher.hh (revision 3415)
@@ -0,0 +1,284 @@
+// Copyright (C) 2007, 2008, 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
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_IMAGE_TRANS_IMAGE_HH
+# define MLN_CORE_IMAGE_TRANS_IMAGE_HH
+
+/*! \file sandbox/fred/trans_image.hh
+ *
+ * \brief Definition of the "transformed" image class mln::trans_image.
+ */
+
+# include <mln/core/internal/image_morpher.hh>
+# include <mln/core/site_set/box.hh>
+# include <mln/value/set.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/accu/bbox.hh>
+
+namespace mln
+{
+
+ // Fwd decl.
+ template <typename I, typename F> struct trans_image;
+
+ namespace internal
+ {
+
+ /// Data structure for \c mln::trans_image<I>.
+ template <typename I, typename F>
+ struct data< trans_image<I, F> >
+ {
+ /// \brief Build the data object held by a trans_image.
+ ///
+ /// \param ima The underlying image.
+ /// \param fun The underlying functor.
+ data(I& ima, const F& fun, const box<mln_psite(I)>& box);
+
+ /// Underlying image.
+ I ima_;
+ /// Underlying transformation function.
+ // FIXME: do we need to conserve original transformation or just inverse ?
+ //F fun_;
+ typename F::inverse funinv_;
+ /// The bounding box of the morphed image.
+ box<mln_psite(I)> box_;
+ };
+
+ } // end of namespace mln::internal
+
+
+ /*! \brief Transformed image class.
+ *
+ * Applies an fun::p2p functor to coordinates of image pixels.
+ *
+ * \warning This class only works on images whose domain is a box.
+ * \warning Transformation function must transform domain to a
+ * domain with same cardinality.
+ * \warning You need to give the INVERSE of the desired transformation.
+ */
+ template <typename I, typename F>
+ class trans_image
+ : public internal::image_morpher<I, mln_value(I), mln_pset(I), trans_image<I,
F> >
+ {
+ public:
+ /// Super type.
+ typedef internal::image_morpher< I, mln_value(I), mln_pset(I),
+ trans_image<I, F> > super_;
+
+ /// Point_Site associated type.
+ typedef mln_psite(I) psite;
+
+ /// Value associated type.
+ typedef mln_value(I) value;
+
+ /// Type returned by the read-write pixel value operator.
+ typedef mln_morpher_lvalue(I) lvalue;
+
+ /// Return type of read-only access.
+ typedef mln_rvalue(I) rvalue;
+
+ /// Skeleton.
+ typedef trans_image< tag::image_<I>, F > skeleton;
+
+ public:
+ /// \brief Build a transformation of an image.
+ ///
+ /// The trans_image morpher allows to apply a p2p functor to every cell
+ /// of an image.
+ /// The functor \a fun must transform points so that transformed \a ima
+ /// image domain remains a box with same cardinality.
+ ///
+ /// \param ima The underlying image.
+ /// \param fun p2p functor to apply.
+ trans_image(I& ima, const F& fun);
+
+ /// Initialize an empty image.
+ void init_(I& ima, const F& fun);
+
+ /// Test if this image has been initialized.
+ bool is_valid() const;
+
+ /// Test if a pixel value is accessible at \p p.
+ bool has(const mln_psite(I)& p) const;
+
+ /// Give the definition domain.
+ const box<mln_psite(I)>& domain() const;
+
+ /// Read-only access of pixel value at point site \p p.
+ mln_rvalue(I) operator()(const mln_psite(I)& p) const;
+
+ /// Read-write access of pixel value at point site \p p.
+ mln_morpher_lvalue(I) operator()(const mln_psite(I)& p);
+
+
+ protected:
+ /// Transform \a p point through functor.
+ mln_psite(I) transform_(const mln_psite(I)& p) const;
+ box<mln_psite(I)> transform_(const box<mln_psite(I)>& p) const;
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ // internal::data< trans_image<I,S> >
+
+ template <typename I, typename F>
+ inline
+ data< trans_image<I, F> >::data(I& ima, const F& fun, const
box<mln_psite(I)>& box)
+ : ima_ (ima),
+ // FIXME: do we need to conserve original transformation or just inverse ?
+ // fun_ (fun),
+ funinv_ (fun.inv ()),
+ box_ (box)
+ {
+ }
+
+ } // end of namespace mln::internal
+
+
+ template <typename I, typename F>
+ inline
+ trans_image<I, F>::trans_image(I& ima, const F& fun)
+ {
+ init_(ima, fun);
+ }
+
+ template <typename I, typename F>
+ inline
+ void
+ trans_image<I, F>::init_(I& ima, const F& fun)
+ {
+ typedef mln_psite(I) P;
+ mln_precondition(ima.is_valid());
+
+ /* FIXME: Add a precondition on the fact that the domain of ima is
+ a box. */
+
+ // Create transformed bounding box
+ accu::bbox<P> tbox;
+
+ tbox.take_as_init (fun (ima.domain ().pmin ()));
+ tbox.take (fun (ima.domain ().pmax ()));
+
+ this->data_ = new internal::data< trans_image<I, F> >(ima, fun,
tbox);
+ }
+
+
+ template <typename I, typename F>
+ inline
+ bool trans_image<I, F>::is_valid() const
+ {
+ mln_invariant(this->delegatee_()->is_valid());
+ return true;
+ }
+
+ template <typename I, typename F>
+ inline
+ bool
+ trans_image<I, F>::has(const mln_psite(I)& p) const
+ {
+ mln_precondition(this->is_valid());
+ return this->delegatee_()->has(transform_(p));
+ }
+
+ template <typename I, typename F>
+ inline
+ mln_psite(I)
+ trans_image<I, F>::transform_(const mln_psite(I)& p) const
+ {
+ return this->data_->funinv_(p);
+ }
+
+ template <typename I, typename F>
+ inline
+ box<mln_psite(I)>
+ trans_image<I, F>::transform_(const box<mln_psite(I)>& p) const
+ {
+ typedef mln_psite(I) P;
+
+ // Create transformed bounding box
+ accu::bbox<P> tbox;
+
+ tbox.take_as_init (this->data_->funinv_ (this->data_->ima_.domain ().pmin
()));
+ tbox.take (this->data_->funinv_ (this->data_->ima_.domain ().pmax ()));
+
+ return tbox;
+ }
+
+ template <typename I, typename F>
+ inline
+ const box<mln_psite(I)>&
+ trans_image<I, F>::domain() const
+ {
+ mln_precondition(this->is_valid());
+ return this->data_->box_;
+ }
+
+ template <typename I, typename F>
+ inline
+ mln_rvalue(I)
+ trans_image<I, F>::operator()(const mln_psite(I)& p) const
+ {
+ mln_precondition(this->has(p));
+ return (*this->delegatee_())(transform_(p));
+ }
+
+ template <typename I, typename F>
+ inline
+ mln_morpher_lvalue(I)
+ trans_image<I, F>::operator()(const mln_psite(I)& p)
+ {
+ mln_precondition(this->has(p));
+ return (*this->delegatee_())(transform_(p));
+ }
+
+ template <typename I, typename F>
+ inline
+ trans_image<I, F>
+ transform_image(Image<I>& ima, const Function_p2p<F>& fun)
+ {
+ trans_image<I, F> tmp(exact(ima), exact(fun));
+ return tmp;
+ }
+
+ template <typename I, typename F>
+ inline
+ trans_image<const I, F>
+ transform_image(const Image<I>& ima, const Function_p2p<F>& fun)
+ {
+ trans_image<const I, F> tmp(exact(ima), exact(fun));
+ return tmp;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_IMAGE_T_IMAGE_HH
Index: trunk/milena/sandbox/fred/old/p2p/translate_p2p.hh
===================================================================
--- trunk/milena/sandbox/fred/old/p2p/translate_p2p.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/p2p/translate_p2p.hh (revision 3415)
@@ -0,0 +1,43 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/core/macros.hh>
+#include <mln/core/alias/point2d.hh>
+#include <mln/core/alias/dpoint2d.hh>
+#include <mln/core/var.hh>
+
+namespace mln
+{
+
+ template <typename P>
+ class translate_t : public Function_p2p< translate_t<P> >
+ {
+ public:
+ typedef P result;
+ typedef translate_t<P> inverse;
+
+ translate_t (mln_delta(P) dp)
+ : dp_ (dp) {};
+
+ P operator() (const P& point) const
+ {
+ P pt = point;
+ return (pt + dp_);
+ };
+
+ inverse inv () const
+ {
+ translate_t<P> tmp(-dp_);
+ return tmp;
+ };
+
+ private:
+ const mln_delta(P) dp_;
+ };
+
+ template <typename D>
+ translate_t<mln_site(D)> translate (const Gdpoint<D>& delta)
+ {
+ translate_t<mln_site(D)> f (exact (delta));
+ return f;
+ }
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/old/p2p/Makefile
===================================================================
--- trunk/milena/sandbox/fred/old/p2p/Makefile (revision 0)
+++ trunk/milena/sandbox/fred/old/p2p/Makefile (revision 3415)
@@ -0,0 +1,12 @@
+SRC=test_trans_image.cc
+OBJ=${SRC:.cc=.o}
+CXXFLAGS=-I ~/lrde/olena/trunk/milena
+
+all: $(OBJ)
+ g++ $<
+
+%.o: %cc
+ g++ $(CXXFLAGS) -o$@ $<
+
+clean:
+ rm -f *~ *.o a.out
\ No newline at end of file
Index: trunk/milena/sandbox/fred/old/accuprops.cc
===================================================================
--- trunk/milena/sandbox/fred/old/accuprops.cc (revision 0)
+++ trunk/milena/sandbox/fred/old/accuprops.cc (revision 3415)
@@ -0,0 +1,331 @@
+# include <iostream>
+# include <string>
+
+# include <mln/trait/undef.hh>
+# include <mln/trait/image/props.hh>
+# include <mln/trait/value_.hh>
+
+# include <mln/metal/bexpr.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/is_const.hh>
+
+# include <mln/core/concept/image.hh>
+# include <mln/accu/all.hh>
+# include <mln/util/pix.hh>
+# include <mln/make/pix.hh>
+
+/// Shortcut to the accumulator property about untake method disponibility
+# define mln_trait_accu_has_untake(A) typename mln::trait::accu_< A >::has_untake
+
+/// Shortcut to the accumulator property about setvalue method disponibility
+# define mln_trait_accu_has_setvalue(A) typename mln::trait::accu_< A
>::has_setvalue
+
+/// Shortcut to the accumulator property about stop method disponibility
+# define mln_trait_accu_has_stop(A) typename mln::trait::accu_< A >::has_stop
+
+/// Shortcut to the accumulator property about behavior when pixel is given as take()
value
+/// Used for instance in mln::canvas::morpho::leveling
+# define mln_trait_accu_when_pix(A) typename mln::trait::accu_< A >::when_pix
+
+namespace mln {
+
+ namespace trait {
+
+ namespace accu {
+
+ // Basic accumulators properties
+
+ struct has_untake
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_untake::no"; }
};
+
+ struct yes : any { std::string name() const { return "has_untake::yes";
} };
+ };
+
+ struct has_stop
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_setvalue::no";
} };
+
+ struct yes : any { std::string name() const { return "has_stop::yes"; }
};
+ };
+
+ struct has_setvalue
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_setvalue::no";
} };
+
+ struct yes : any { std::string name() const { return
"has_setvalue::yes"; } };
+ };
+
+ // Morphological accumulators properties
+ struct when_pix
+ {
+ struct any { protected: any() {}; };
+
+ struct use_v : any { std::string name() const { return
"when_pix::use_v"; } };
+
+ struct use_p : any { std::string name() const { return
"when_pix::use_p"; } };
+
+ struct use_pix : any { std::string name() const { return
"when_pix::use_pix"; } };
+
+ struct not_ok : any { std::string name() const { return
"when_pix::not_ok"; } };
+ };
+
+ } // end of namespace mln::trait::accu
+
+ template <typename A>
+ struct undefined_accu_
+ {
+ // general
+ typedef undef has_untake;
+ typedef undef has_stop;
+ typedef undef has_setvalue;
+
+ // morpho
+ typedef accu::when_pix::not_ok when_pix;
+ // FIXME: should default be undef ?
+ };
+
+ template <typename A>
+ struct accu_ : undefined_accu_<A>
+ {
+ };
+
+ } // end of namespace mln::trait
+
+ namespace canvas {
+
+ namespace morpho {
+
+ namespace impl {
+
+ namespace generic {
+
+ template <typename I, template <typename P> class A>
+ inline
+ void
+ leveling(const Image<I>& input,
+ Accumulator< A< util::pix<I> > >& acc)
+ {
+ const I& ima = exact(input);
+ A< util::pix<I> >& a = exact(acc);
+
+ mln_piter(I) p(ima.domain());
+
+ for_all(p)
+ a.take(mln::make::pix(ima, p));
+ }
+
+ } // end of namespace mln::canvas::morpho::impl::generic
+
+ // fast implementation (only on values from pixter)
+ template <typename I, template <typename P> class A>
+ inline
+ void
+ leveling_fastest(const Image<I>& input,
+ Accumulator< A< util::pix<I> > >& acc)
+ {
+ const I& ima = exact(input);
+ A< util::pix<I> >& a = exact(acc);
+
+ mln_pixter(const I) px(ima);
+
+ for_all(px)
+ a.take(px.val());
+ }
+
+ } // end of namespace mln::canvas::morpho::impl
+
+ namespace internal {
+
+ template <typename I, typename A>
+ inline
+ void
+ leveling_dispatch(metal::false_,
+ const Image<I>& input,
+ Accumulator<A>& acc)
+ {
+ impl::generic::leveling(input, acc);
+ }
+
+ template <typename I, typename A>
+ inline
+ void
+ leveling_dispatch(metal::true_,
+ const Image<I>& input,
+ Accumulator<A>& acc)
+ {
+ impl::leveling_fastest(input, acc);
+ }
+
+ template <typename I, typename A>
+ inline
+ void
+ leveling_dispatch(const Image<I>& input,
+ Accumulator<A>& acc)
+ {
+ enum {
+ test = mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value
+ &&
+ mlc_equal(mln_trait_accu_when_pix(A),
+ trait::accu::when_pix::use_v)::value
+ };
+ internal::leveling_dispatch(metal::bool_<test>(),
+ input, acc);
+ }
+
+ } // end of namespace mln::canvas::morpho::internal
+
+ // Facade.
+ template <typename I, template <typename P> class A>
+ inline
+ void
+ leveling(const Image<I>& input,
+ Accumulator< A< util::pix<I> > >& acc)
+ {
+ internal::leveling_dispatch(input, acc);
+ }
+
+ } // end of namespace mln::canvas::morpho
+
+ } // end of namespace mln::canvas
+
+ namespace morpho {
+
+ namespace accu {
+
+ namespace internal {
+
+ template <typename V>
+ struct sum_handling_pixels
+ { typedef mln_sum(V) ret; };
+
+ template <typename I>
+ struct sum_handling_pixels< util::pix<I> >
+ { typedef mln_sum(mln_value(I)) ret; };
+
+ } // end of namespace mln::morpho::accu::internal
+
+ template <typename T>
+ /// Morphological (i.e. for pixel and pixel values) accumulator calculating mean.
+ /// FIXME: is inclusion polyphormism really appliable ?
+ struct mean : public mln::accu::mean<T, typename
internal::sum_handling_pixels<T>::ret>,
+ public Accumulator< mean<T> >
+ {
+ typedef mln::accu::mean<T, typename
internal::sum_handling_pixels<T>::ret> super;
+ typedef typename super::result result;
+
+ using super::operator result;
+ using super::take;
+
+ void take(const mean<T>& m);
+ };
+
+ template <typename I>
+ struct mean< util::pix<I> > : public mean< mln_value(I) >,
+ public Accumulator< mean< util::pix<I>
> >
+ {
+ typedef mean< mln_value(I) > super;
+ typedef util::pix<I> argument;
+ typedef typename super::result result;
+
+ using super::operator result;
+ using super::take;
+
+ void take(const argument& t);
+ void take(const mean< util::pix<I> >& m);
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ inline
+ void mean<T>::take(const mean<T>& m)
+ {
+ this->super::take(m);
+ }
+
+ template <typename I>
+ inline
+ void mean< util::pix<I> >::take(const mean< util::pix<I>
>::argument& t)
+ {
+ this->mean< mln_value(I) >::take(t.v());
+ }
+
+ template <typename I>
+ inline
+ void mean< util::pix<I> >::take(const mean< util::pix<I>
>& m)
+ {
+ this->super::take(m);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::accu
+
+ } // end of namespace mln::morpho
+
+ namespace trait {
+
+ template <typename I>
+ struct accu_< morpho::accu::mean< util::pix<I> > > :
+ public undefined_accu_ < morpho::accu::mean< util::pix<I> > >
+ {
+ typedef accu::when_pix::use_v when_pix;
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+# include <mln/accu/all.hh>
+# include <mln/core/image/image2d.hh>
+
+# include <mln/debug/iota.hh>
+# include <mln/debug/println.hh>
+# include <mln/core/var.hh>
+# include <mln/util/timer.hh>
+int main()
+{
+ typedef mln::image2d<int> I;
+
+ I ima(1000, 1000);
+ mln::morpho::accu::mean< mln::util::pix<I> > acc;
+
+ float elapsed;
+ mln::util::timer chrono;
+
+ mln::debug::iota(ima);
+ std::cout << "50 mean of a 1000x1000 image2d<int>" <<
std::endl;
+
+ acc.init();
+ chrono.start();
+ for (int i = 0; i < 50; i++)
+ mln::canvas::morpho::leveling(ima, acc);
+ elapsed = chrono.stop();
+
+ std::cout << "(auto) " << elapsed << "s : "
<< acc.to_result() << std::endl;
+
+ acc.init();
+ chrono.start();
+ for (int i = 0; i < 50; i++)
+ mln::canvas::morpho::impl::generic::leveling(ima, acc);
+ elapsed = chrono.stop();
+
+ std::cout << "(generic) " << elapsed << "s : "
<< acc.to_result() << std::endl;
+
+ acc.init();
+ chrono.start();
+ for (int i = 0; i < 50; i++)
+ mln::canvas::morpho::impl::leveling_fastest(ima, acc);
+ elapsed = chrono.stop();
+
+ std::cout << "(fast) " << elapsed << "s : "
<< acc.to_result() << std::endl;
+}
Index: trunk/milena/sandbox/fred/old/meantest.cc
===================================================================
--- trunk/milena/sandbox/fred/old/meantest.cc (revision 0)
+++ trunk/milena/sandbox/fred/old/meantest.cc (revision 3415)
@@ -0,0 +1,21 @@
+#include <iostream>
+#include <mln/core/image/image2d.hh>
+#include "mean.hh"
+
+int main()
+{
+ typedef mln::image2d<int> I;
+ mln::morpho::attribute::mean<I> m;
+
+ m.take (2);
+ m.take (3);
+ m.take (4);
+
+ std::cout << m.to_result () << std::endl;
+
+ m.set_value (6);
+ m.take (3);
+ m.take (9);
+
+ std::cout << m.to_result () << std::endl;
+}
Index: trunk/milena/sandbox/fred/old/accuprops2.cc
===================================================================
--- trunk/milena/sandbox/fred/old/accuprops2.cc (revision 0)
+++ trunk/milena/sandbox/fred/old/accuprops2.cc (revision 3415)
@@ -0,0 +1,380 @@
+# include <iostream>
+# include <string>
+
+# include <mln/trait/undef.hh>
+# include <mln/trait/image/props.hh>
+# include <mln/trait/value_.hh>
+
+# include <mln/metal/bexpr.hh>
+# include <mln/metal/equal.hh>
+# include <mln/metal/if.hh>
+# include <mln/metal/is_const.hh>
+
+# include <mln/core/concept/image.hh>
+# include <mln/accu/all.hh>
+# include <mln/util/pix.hh>
+# include <mln/make/pix.hh>
+
+/// Shortcut to the accumulator property about untake method disponibility
+# define mln_trait_accu_has_untake(A) typename mln::trait::accu_< A >::has_untake
+
+/// Shortcut to the accumulator property about setvalue method disponibility
+# define mln_trait_accu_has_setvalue(A) typename mln::trait::accu_< A
>::has_setvalue
+
+/// Shortcut to the accumulator property about stop method disponibility
+# define mln_trait_accu_has_stop(A) typename mln::trait::accu_< A >::has_stop
+
+/// Shortcut to the accumulator property about behavior when pixel is given as take()
value
+/// Used for instance in mln::canvas::morpho::leveling
+# define mln_trait_accu_when_pix(A) typename mln::trait::accu_< A >::when_pix
+
+namespace mln {
+
+ namespace trait {
+
+ namespace accu {
+
+ // Basic accumulators properties
+
+ struct has_untake
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_untake::no"; }
};
+
+ struct yes : any { std::string name() const { return "has_untake::yes";
} };
+ };
+
+ struct has_stop
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_setvalue::no";
} };
+
+ struct yes : any { std::string name() const { return "has_stop::yes"; }
};
+ };
+
+ struct has_setvalue
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_setvalue::no";
} };
+
+ struct yes : any { std::string name() const { return
"has_setvalue::yes"; } };
+ };
+
+ // Morphological accumulators properties
+ struct when_pix
+ {
+ struct any { protected: any() {}; };
+
+ struct use_v : any { std::string name() const { return
"when_pix::use_v"; } };
+
+ struct use_p : any { std::string name() const { return
"when_pix::use_p"; } };
+
+ struct use_pix : any { std::string name() const { return
"when_pix::use_pix"; } };
+
+ struct not_ok : any { std::string name() const { return
"when_pix::not_ok"; } };
+ };
+
+ } // end of namespace mln::trait::accu
+
+ template <typename A>
+ struct undefined_accu_
+ {
+ // general
+ typedef undef has_untake;
+ typedef undef has_stop;
+ typedef undef has_setvalue;
+
+ // morpho
+ typedef accu::when_pix::not_ok when_pix;
+ // FIXME: should default be undef ?
+ };
+
+ template <typename A>
+ struct accu_ : undefined_accu_<A>
+ {
+ };
+
+ } // end of namespace mln::trait
+
+ namespace canvas {
+
+ namespace morpho {
+
+ namespace impl {
+
+ namespace generic {
+
+ template <typename I, template <typename P> class A>
+ inline
+ void
+ leveling(const Image<I>& input,
+ Accumulator< A< util::pix<I> > >& acc)
+ {
+ const I& ima = exact(input);
+ A< util::pix<I> >& a = exact(acc);
+
+ mln_piter(I) p(ima.domain());
+
+ for_all(p)
+ a.take(mln::make::pix(ima, p));
+ }
+
+ } // end of namespace mln::canvas::morpho::impl::generic
+
+ // fast implementation (only on values from pixter)
+ template <typename I, template <typename P> class A>
+ inline
+ void
+ leveling_fastest(const Image<I>& input,
+ Accumulator< A< util::pix<I> > >& acc)
+ {
+ const I& ima = exact(input);
+ A< util::pix<I> >& a = exact(acc);
+
+ mln_pixter(const I) px(ima);
+
+ for_all(px)
+ a.take(px.val());
+ }
+
+ } // end of namespace mln::canvas::morpho::impl
+
+ namespace internal {
+
+ template <typename I, typename A>
+ inline
+ void
+ leveling_dispatch(metal::false_,
+ const Image<I>& input,
+ Accumulator<A>& acc)
+ {
+ impl::generic::leveling(input, acc);
+ }
+
+ template <typename I, typename A>
+ inline
+ void
+ leveling_dispatch(metal::true_,
+ const Image<I>& input,
+ Accumulator<A>& acc)
+ {
+ impl::leveling_fastest(input, acc);
+ }
+
+ template <typename I, typename A>
+ inline
+ void
+ leveling_dispatch(const Image<I>& input,
+ Accumulator<A>& acc)
+ {
+ enum {
+ test = mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value
+ &&
+ mlc_equal(mln_trait_accu_when_pix(A),
+ trait::accu::when_pix::use_v)::value
+ };
+ internal::leveling_dispatch(metal::bool_<test>(),
+ input, acc);
+ }
+
+ } // end of namespace mln::canvas::morpho::internal
+
+ // Facade.
+ template <typename I, template <typename P> class A>
+ inline
+ void
+ leveling(const Image<I>& input,
+ Accumulator< A< util::pix<I> > >& acc)
+ {
+ internal::leveling_dispatch(input, acc);
+ }
+
+ } // end of namespace mln::canvas::morpho
+
+ } // end of namespace mln::canvas
+
+ namespace morpho {
+
+ namespace accu {
+
+ // MEAN ACCUMULATOR
+ namespace internal {
+
+ template <typename V>
+ struct sum_handling_pixels
+ { typedef mln_sum(V) ret; };
+
+ template <typename I>
+ struct sum_handling_pixels< util::pix<I> >
+ { typedef mln_sum(mln_value(I)) ret; };
+
+ } // end of namespace mln::morpho::accu::internal
+
+ template <typename T>
+ /// Morphological (i.e. for pixel and pixel values) accumulator calculating mean.
+ /// FIXME: is inclusion polyphormism really appliable ?
+ struct mean : public mln::accu::mean<T, typename
internal::sum_handling_pixels<T>::ret>,
+ public Accumulator< mean<T> >
+ {
+ typedef mln::accu::mean<T, typename
internal::sum_handling_pixels<T>::ret> super;
+
+ using super::operator typename super::result;
+ using super::take;
+
+ void take(const mean<T>& m);
+ };
+
+ template <typename I>
+ struct mean< util::pix<I> > : public mean< mln_value(I) >,
+ public Accumulator< mean< util::pix<I>
> >
+ {
+ typedef mean< mln_value(I) > super;
+ typedef util::pix<I> argument;
+
+ using super::operator typename super::result;
+ using super::take;
+
+ void take(const argument& t);
+ void take(const mean< util::pix<I> >& m);
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename T>
+ inline
+ void mean<T>::take(const mean<T>& m)
+ {
+ this->super::take(m);
+ }
+
+ template <typename I>
+ inline
+ void mean< util::pix<I> >::take(const mean< util::pix<I>
>::argument& t)
+ {
+ this->mean< mln_value(I) >::take(t.v());
+ }
+
+ template <typename I>
+ inline
+ void mean< util::pix<I> >::take(const mean< util::pix<I>
>& m)
+ {
+ this->super::take(m);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ // FROM mln::accu:: TO mln::morpho::acu::
+
+ template <template <typename T> class A>
+ struct from_mln_accu
+ {
+ template <typename T>
+ struct ret;
+
+ template <typename I>
+ struct ret< util::pix<I> > : public A< mln_value(I) >,
+ public Accumulator< ret< util::pix<I>
> >
+ {
+ typedef A< mln_value(I) > super;
+ typedef typename super::result result;
+
+ typedef util::pix<I> argument;
+
+ using super::take;
+
+ void take(const argument& t);
+ void take(const ret< util::pix<I> >& m);
+ };
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <template <typename T> class A>
+ template <typename I>
+ inline
+ void from_mln_accu<A>::ret< util::pix<I> >::take(const
from_mln_accu<A>::ret< util::pix<I> >& m)
+ {
+ this->super::take(m);
+ }
+
+ template <template <typename T> class A>
+ template <typename I>
+ inline
+ void from_mln_accu<A>::ret< util::pix<I> >::take(const
from_mln_accu<A>::ret< util::pix<I> >::argument& t)
+ {
+ this->A< mln_value(I) >::take(t.v());
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::accu
+
+ } // end of namespace mln::morpho
+
+ namespace trait {
+
+ template <typename I>
+ struct accu_< morpho::accu::mean< util::pix<I> > > :
+ public undefined_accu_ < morpho::accu::mean< util::pix<I> > >
+ {
+ typedef accu::when_pix::use_v when_pix;
+ };
+
+ template <template <typename T> class A, typename I>
+ struct accu_< morpho::accu::from_mln_accu < A > :: ret < I > >
+ {
+ typedef accu::when_pix::use_v when_pix;
+ };
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+# include <mln/accu/all.hh>
+# include <mln/core/image/image2d.hh>
+
+# include <mln/debug/iota.hh>
+# include <mln/debug/println.hh>
+# include <mln/core/var.hh>
+# include <mln/util/timer.hh>
+int main()
+{
+ using namespace mln;
+ typedef image2d<int> I;
+
+ I ima(1000, 1000);
+ morpho::accu::from_mln_accu<accu::min>::ret<util::pix<I> > acc;
+
+ float elapsed;
+ mln::util::timer chrono;
+
+ debug::iota(ima);
+ std::cout << "50 mean of a 1000x1000 image2d<int>" <<
std::endl;
+
+ acc.init();
+ chrono.start();
+ for (int i = 0; i < 50; i++)
+ mln::canvas::morpho::leveling(ima, acc);
+ elapsed = chrono.stop();
+
+ std::cout << "(auto) " << elapsed << "s : "
<< acc.to_result() << std::endl;
+
+ acc.init();
+ chrono.start();
+ for (int i = 0; i < 50; i++)
+ mln::canvas::morpho::impl::generic::leveling(ima, acc);
+ elapsed = chrono.stop();
+
+ std::cout << "(generic) " << elapsed << "s : "
<< acc.to_result() << std::endl;
+
+ acc.init();
+ chrono.start();
+ for (int i = 0; i < 50; i++)
+ mln::canvas::morpho::impl::leveling_fastest(ima, acc);
+ elapsed = chrono.stop();
+
+ std::cout << "(fast) " << elapsed << "s : "
<< acc.to_result() << std::endl;
+}
Index: trunk/milena/sandbox/fred/old/connected_filter.hh
===================================================================
--- trunk/milena/sandbox/fred/old/connected_filter.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/connected_filter.hh (revision 3415)
@@ -0,0 +1,123 @@
+// 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
+// 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_CANVAS_MORPHO_CONNECTED_FILTER_HH
+# define MLN_CANVAS_MORPHO_CONNECTED_FILTER_HH
+
+/// \file mln/canvas/morpho/connected_filter.hh
+///
+/// Connected filters dispatch (algebraic & leveling filters).
+///
+
+# include "leveling_filter.hh"
+# include <mln/canvas/morpho/algebraic_filter.hh>
+# include <mln/trait/accumulators.hh>
+
+namespace mln {
+ namespace canvas {
+ namespace morpho {
+
+ // Facade Fwd Declaration
+ template <typename I, typename N, typename A>
+ mln_concrete(I)
+ connected_filter(const Image<I>& input, const Neighborhood<N>&
nbh,
+ const Accumulator<A>& a, const typename A::result& lambda, bool
increasing);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Dispatch.
+ namespace internal
+ {
+
+ template <typename I, typename N, typename A>
+ inline
+ mln_concrete(I)
+ connected_filter_dispatch(mln::trait::accumulator::when_pix::use_none,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing)
+ {
+ return algebraic_filter_dispatch(input, nbh, a, lambda, increasing);
+ }
+
+ template <typename I, typename N, typename A>
+ inline
+ mln_concrete(I)
+ connected_filter_dispatch(mln::trait::accumulator::when_pix::use_p,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing)
+ {
+ return algebraic_filter_dispatch(input, nbh, a, lambda, increasing);
+ }
+
+ template <typename I, typename N, typename A>
+ inline
+ mln_concrete(I)
+ connected_filter_dispatch(mln::trait::accumulator::when_pix::use_v,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing)
+ {
+ return leveling_filter_dispatch(input, nbh, a, lambda, increasing);
+ }
+
+ template <typename I, typename N, typename A>
+ inline
+ mln_concrete(I)
+ connected_filter_dispatch(mln::trait::accumulator::when_pix::use_pix,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing)
+ {
+ return leveling_filter_dispatch(input, nbh, a, lambda, increasing);
+ }
+
+ } // end of namespace mln::canvas::morpho::internal
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ // Facade.
+
+ template <typename I, typename N, typename A>
+ mln_concrete(I)
+ connected_filter(const Image<I>& input, const Neighborhood<N>&
nbh,
+ const Accumulator<A>& a, const typename A::result& lambda, bool
increasing)
+ {
+ return internal::connected_filter_dispatch(mln_trait_accu_when_pix(A)(),
+ input, nbh, a, lambda, increasing);
+ }
+
+
+ } // end of namespace mln::canvas::morpho
+ } // end of namespace mln::canvas
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_MORPHO_CONNECTED_FILTER_HH
Index: trunk/milena/sandbox/fred/old/leveling_filter.hh
===================================================================
--- trunk/milena/sandbox/fred/old/leveling_filter.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/leveling_filter.hh (revision 3415)
@@ -0,0 +1,381 @@
+// 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
+// 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_CANVAS_MORPHO_LEVELING_FILTER_HH
+# define MLN_CANVAS_MORPHO_LEVELING_FILTER_HH
+
+/// \file mln/canvas/morpho/leveling_filter.hh
+///
+/// Apply leveling connected filter to images.
+///
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/accumulator.hh>
+
+# include <mln/data/fill.hh>
+# include <mln/extension/adjust_fill.hh>
+
+# include <mln/level/sort_psites.hh>
+# include <mln/level/sort_offsets.hh>
+
+
+
+
+/*# include <mln/data/fill.hh>
+# include <mln/literal/zero.hh>
+# include <mln/convert/to_upper_window.hh>
+# include <mln/extension/adjust_fill.hh>
+# include <mln/util/pix.hh>
+*/
+
+namespace mln {
+ namespace canvas {
+ namespace morpho {
+
+ // Facade Fwd Declaration
+ template <typename I, typename N, typename A>
+ mln_concrete(I)
+ leveling_filter(const Image<I>& input, const Neighborhood<N>&
nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Implementations.
+
+ namespace impl {
+
+ namespace generic {
+
+ // Generic Version
+
+ template <typename I>
+ static inline
+ mln_psite(I)
+ find_root(I& parent, const mln_psite(I) & x)
+ {
+ if (parent(x) == x)
+ return x;
+ else
+ return parent(x) = find_root(parent, parent(x));
+ }
+
+ template <typename I, typename N, typename S, typename A>
+ mln_concrete(I)
+ leveling_filter(const Image<I>& input_, const Neighborhood<N>&
nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_, const typename A::result& lambda)
+ {
+ trace::entering("canvas::morpho::impl::generic::leveling_filter");
+ // FIXME: Test?!
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ // Initialization.
+ {
+ initialize(deja_vu, input);
+ mln::data::fill(deja_vu, false);
+ initialize(activity, input);
+ mln::data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ //a.init(); // init required.
+ }
+
+ // First pass.
+ {
+ mln_fwd_piter(S) p(s); // s required.
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ // Make set.
+ {
+ parent(p) = p;
+ data(p).take_as_init(make::pix(input, p));
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ //do_union(n, p);
+ P r = find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda))) //
Equiv(r, p)
+ // Either a flat zone or the component of r is still growing.
+ {
+ /* FIXME: Same remark as above concerning the
+ initialization of data(p); instead of
+
+ data(p).take(data(r));
+
+ we should (or could) have
+
+ unite_data(p, r);
+
+ so as to keep the generic aspect of this canvas
+ (as long as the set of acceptable types for the
+ template parameter A is not bound). */
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) == p) // p is root.
+ output(p) = input(p);
+ else
+ output(p) = output(parent(p));
+ }
+
+ trace::exiting("canvas::morpho::impl::generic::leveling_filter");
+ return output;
+ }
+
+ } // end of namespace mln::canvas::morpho::impl::generic
+
+
+ // Fastest version.
+
+
+ template <typename I>
+ inline
+ unsigned
+ find_root_fastest(I& parent, unsigned x)
+ {
+ if (parent.element(x) == x)
+ return x;
+ else
+ return parent.element(x) = find_root_fastest(parent, parent.element(x));
+ }
+
+ template <typename I, typename N, typename A>
+ mln_concrete(I)
+ leveling_filter_fastest(const Image<I>& input_, const
Neighborhood<N>& nbh_,
+ const util::array<unsigned>& s,
+ const Accumulator<A>& a_, const typename A::result& lambda)
+ {
+ trace::entering("canvas::morpho::impl::leveling_fastest");
+
+ // FIXME: Tests?
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, unsigned) parent;
+ mln_ch_value(I, A) data;
+
+ // Initialization.
+ {
+ initialize(deja_vu, input);
+ mln::data::fill(deja_vu, false);
+ initialize(activity, input);
+ mln::data::fill(activity, true);
+ initialize(parent, input);
+ mln::data::fill(parent, 0);
+ initialize(data, input);
+ }
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+ const unsigned n_points = s.nelements();
+
+ // First pass.
+ {
+
+ for (unsigned i = 0; i < n_points; ++i)
+ {
+ unsigned p = s[i]; // An offset.
+
+ // Make set.
+ parent.element(p) = p;
+ data.element(p).take_as_init(input.element(p));
+
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (!deja_vu.element(n))
+ continue;
+
+ unsigned r = find_root_fastest(parent, n);
+ if (r != p)
+ {
+ if (input.element(r) == input.element(p)
+ || (activity.element(r)
+ && (data.element(r) < lambda)))
+ {
+ data.element(p).take(data.element(r));
+ parent.element(r) = p;
+ if (activity.element(r) == false)
+ activity.element(p) = false;
+ }
+ else
+ activity.element(p) = false;
+ }
+ }
+
+ deja_vu.element(p) = true;
+ }
+
+ }
+
+ // Second pass.
+ {
+ for (int i = n_points - 1; i >= 0 ; --i)
+ {
+ unsigned p = s[i];
+ if (parent.element(p) == p) // p is root.
+ output.element(p) = input.element(p);
+ else
+ output.element(p) = output.element(parent.element(p));
+ }
+ }
+
+ trace::exiting("canvas::morpho::impl::leveling_fastest");
+ return output;
+ }
+
+ } // end of namespace mln::canvas::morpho::impl
+
+ // Dispatch.
+ namespace internal
+ {
+
+ // Leveling
+ template <typename I, typename N, typename A>
+ mln_concrete(I)
+ leveling_filter_dispatch(metal::false_,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing)
+ {
+ p_array < mln_psite(I) > s =
+ increasing ?
+ level::sort_psites_increasing(input) :
+ level::sort_psites_decreasing(input);
+ return impl::generic::leveling_filter(input, nbh, s, a, lambda);
+ }
+
+ template <typename I, typename N, typename A>
+ mln_concrete(I)
+ leveling_filter_dispatch(metal::true_,
+ const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing)
+ {
+ util::array<unsigned> s =
+ increasing ?
+ level::sort_offsets_increasing(input) :
+ level::sort_offsets_decreasing(input);
+ return impl::leveling_filter_fastest(input, nbh, s, a, lambda);
+ }
+
+ template <typename I, typename N, typename A>
+ inline
+ mln_concrete(I)
+ leveling_filter_dispatch(const Image<I>& input, const
Neighborhood<N>& nbh,
+ const Accumulator<A>& a, const typename A::result& lambda, bool
increasing)
+ {
+ enum
+ {
+ test = mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value
+ && mlc_equal(mln_trait_accumulator_when_pix(A),
+ trait::accumulator::when_pix::use_v)::value
+ && mln_is_simple_neighborhood(N)::value
+ };
+ return leveling_filter_dispatch(metal::bool_<test>(),
+ input, nbh, a, lambda, increasing);
+ }
+
+ } // end of namespace mln::canvas::morpho::internal
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+
+ // Facade.
+
+ template <typename I, typename N, typename A>
+ inline
+ mln_concrete(I)
+ leveling_filter(const Image<I>& input, const Neighborhood<N>&
nbh,
+ const Accumulator<A>& a, const typename A::result& lambda,
+ bool increasing)
+ {
+ //FIXME: Do we need to check input validity ?
+ return internal::leveling_filter_dispatch(input, nbh, a, lambda, increasing);
+ }
+
+ } // end of namespace mln::canvas::morpho
+ } // end of namespace mln::canvas
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_MORPHO_LEVELING_FILTER_HH
Index: trunk/milena/sandbox/fred/old/leveling.cc
===================================================================
--- trunk/milena/sandbox/fred/old/leveling.cc (revision 0)
+++ trunk/milena/sandbox/fred/old/leveling.cc (revision 3415)
@@ -0,0 +1,47 @@
+
+
+#include <mln/core/image/image2d.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/util/timer.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include "mean.hh"
+#include "leveling_filter.hh"
+
+int main(int argc, char** argv)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ std::cout << "Leveling filter test" << std::endl;
+
+ typedef mln::image2d<int_u8> I;
+ I lena;
+
+ float elapsed;
+ mln::util::timer chrono;
+ mln::morpho::attribute::mean<I> c;
+ int lambda = atoi(argv[1]);
+
+ mln::io::pgm::load(lena, "../../img/lena.pgm");
+ I out;
+
+ chrono.start();
+ out = mln::canvas::morpho::leveling_filter(lena, c4(), c, lambda, true);
+ elapsed = chrono.stop();
+ std::cout << "(auto) " << elapsed << "s" <<
std::endl;
+ mln::io::pgm::save(out, "auto.pgm");
+
+ chrono.start();
+ out = mln::canvas::morpho::internal::leveling_filter_dispatch(mln::metal::true_(),
lena, c4(), c, lambda, true);
+ elapsed = chrono.stop();
+ std::cout << "(fast) " << elapsed << "s" <<
std::endl;
+
+ mln::io::pgm::save(out, "fast.pgm");
+
+ chrono.start();
+ out = mln::canvas::morpho::internal::leveling_filter_dispatch(mln::metal::false_(),
lena, c4(), c, lambda, true);
+ elapsed = chrono.stop();
+ std::cout << "(slow) " << elapsed << "s" <<
std::endl;
+
+ mln::io::pgm::save(out, "slow.pgm");
+}
Index: trunk/milena/sandbox/fred/old/closing_area.cc
===================================================================
--- trunk/milena/sandbox/fred/old/closing_area.cc (revision 0)
+++ trunk/milena/sandbox/fred/old/closing_area.cc (revision 3415)
@@ -0,0 +1,50 @@
+// 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.
+
+/// \file tests/morpho/closing_area.cc
+///
+/// Test on mln::morpho::closing_area.
+
+#include <mln/core/image/image2d.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/core/alias/neighb2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/morpho/closing_area.hh>
+
+int main(int argc, char **argv)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ image2d<int_u8> lena;
+ io::pgm::load(lena, "../../img/lena.pgm");
+ io::pgm::save(morpho::closing_area(lena, c4(), atoi(argv[1])), "out.pgm");
+}
Index: trunk/milena/sandbox/fred/old/value_wrapper.hh
===================================================================
--- trunk/milena/sandbox/fred/old/value_wrapper.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/value_wrapper.hh (revision 3415)
@@ -0,0 +1,188 @@
+// 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
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_ATTRIBUTE_VALUE_WRAPPER_HH
+# define MLN_MORPHO_ATTRIBUTE_VALUE_WRAPPER_HH
+
+/// \file mln/morpho/attribute/volume.hh
+///
+/// Transform an accumulator to a value (when_pix::use_v) accumulator.
+
+# include <mln/accu/internal/base.hh>
+# include <mln/util/pix.hh>
+
+# define mln_morpho_attribute_use_v_(T) mln::morpho::attribute::value_wrapper< T >
+# define mln_morpho_attribute_use_v(T) mln::morpho::attribute::value_wrapper< T >
+
+namespace mln
+{
+
+ // Forward declaration.
+ namespace morpho {
+ namespace attribute {
+ template <typename T> class value_wrapper;
+ }
+ }
+
+
+ // Traits.
+
+ namespace trait
+ {
+
+ template <typename A>
+ struct accumulator_< morpho::attribute::value_wrapper<A> >
+ {
+ typedef accumulator::has_untake::no has_untake;
+ typedef accumulator::has_set_value::no has_set_value;
+ typedef accumulator::has_stop::no has_stop;
+ typedef accumulator::when_pix::use_v when_pix;
+ };
+
+ } // end of namespace mln::trait
+
+ namespace morpho
+ {
+
+ namespace attribute
+ {
+
+ /// Value wrapper accumulator meta-class.
+ ///
+ /// The parameter \p A is the base accumulator to wrap.
+ template <typename A>
+ struct value_wrapper
+ : public mln::accu::internal::base< typename A::result , value_wrapper<A> >
+ {
+ typedef typename A::argument argument;
+ typedef typename A::result result;
+
+ value_wrapper();
+
+ /// Manipulators.
+ /// \{
+ void init();
+
+ void take(const argument& v);
+ template <typename I>
+ void take(const util::pix<I>& px);
+ void take(const value_wrapper<A>& other);
+
+ void take_as_init(const argument& v);
+ template <typename I>
+ void take_as_init(const util::pix<I>& px);
+ /// \}
+
+ /// Get the value of the accumulator.
+ result to_result() const;
+
+ /// Check whether this accu is able to return a result.
+ bool is_valid() const;
+
+ protected:
+ /// Delegatee accumulator.
+ A accu_;
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename A>
+ value_wrapper<A>::value_wrapper()
+ : accu_()
+ {
+ }
+
+ template <typename A>
+ void
+ value_wrapper<A>::init()
+ {
+ accu_.init();
+ }
+
+ template <typename A>
+ void
+ value_wrapper<A>::take(const argument& v)
+ {
+ accu_.take(v);
+ }
+
+ template <typename A>
+ template <typename I>
+ void
+ value_wrapper<A>::take(const util::pix<I>& px)
+ {
+ take(px.v());
+ }
+
+ template <typename A>
+ void
+ value_wrapper<A>::take(const value_wrapper<A>& other)
+ {
+ accu_.take(other.accu_);
+ }
+
+ template <typename A>
+ void
+ value_wrapper<A>::take_as_init(const argument& v)
+ {
+ accu_.take_as_init(v);
+ }
+
+ template <typename A>
+ template <typename I>
+ void
+ value_wrapper<A>::take_as_init(const util::pix<I>& px)
+ {
+ accu_.take_as_init(px);
+ }
+
+ template <typename A>
+ typename value_wrapper<A>::result
+ value_wrapper<A>::to_result() const
+ {
+ return accu_.to_result();
+ }
+
+ template <typename A>
+ bool
+ value_wrapper<A>::is_valid() const
+ {
+ return accu_.is_valid();
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::attribute
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+
+#endif // ! MLN_MORPHO_ATTRIBUTE_VALUE_WRAPPER_HH
Index: trunk/milena/sandbox/fred/old/accu_trait.hh
===================================================================
--- trunk/milena/sandbox/fred/old/accu_trait.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/accu_trait.hh (revision 3415)
@@ -0,0 +1,94 @@
+#ifndef MLN_TRAIT_ACCU_HH
+# define MLN_TRAIT_ACCU_HH
+
+# include <string>
+# include <mln/trait/undef.hh>
+
+/// Shortcut to the accumulator property about untake method disponibility
+# define mln_trait_accu_has_untake(A) typename mln::trait::accu_< A >::has_untake
+
+/// Shortcut to the accumulator property about setvalue method disponibility
+# define mln_trait_accu_has_setvalue(A) typename mln::trait::accu_< A
>::has_setvalue
+
+/// Shortcut to the accumulator property about stop method disponibility
+# define mln_trait_accu_has_stop(A) typename mln::trait::accu_< A >::has_stop
+
+/// Shortcut to the accumulator property about behavior when pixel is given as take()
value
+/// Used for instance in mln::canvas::morpho::leveling
+# define mln_trait_accu_when_pix(A) typename mln::trait::accu_< A >::when_pix
+
+namespace mln {
+
+ namespace trait {
+
+ namespace accu {
+
+ // Basic accumulators properties
+
+ struct has_untake
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_untake::no"; }
};
+
+ struct yes : any { std::string name() const { return "has_untake::yes";
} };
+ };
+
+ struct has_stop
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_setvalue::no";
} };
+
+ struct yes : any { std::string name() const { return "has_stop::yes"; }
};
+ };
+
+ struct has_setvalue
+ {
+ struct any { protected: any() {}; };
+
+ struct no : any { std::string name() const { return "has_setvalue::no";
} };
+
+ struct yes : any { std::string name() const { return
"has_setvalue::yes"; } };
+ };
+
+ // Morphological accumulators properties
+ struct when_pix
+ {
+ struct any { protected: any() {}; };
+
+ struct use_only_v : any { std::string name() const { return
"when_pix::use_only_v"; } };
+
+ struct use_only_p : any { std::string name() const { return
"when_pix::use_only_p"; } };
+
+ struct use_pix : any { std::string name() const { return
"when_pix::use_pix"; } };
+
+ struct use_whatever : any { std::string name() const { return
"when_pix::use_whatever"; } };
+
+ struct not_ok : any { std::string name() const { return
"when_pix::not_ok"; } };
+ };
+
+ } // end of namespace mln::trait::accu
+
+ template <typename A>
+ struct undefined_accu_
+ {
+ // general
+ typedef undef has_untake;
+ typedef undef has_stop;
+ typedef undef has_setvalue;
+
+ // morpho
+ typedef accu::when_pix::use_pix when_pix;
+ };
+
+ template <typename A>
+ struct accu_ : public undefined_accu_<A>
+ {
+ };
+
+ } // end of namespace mln::trait
+
+} // end of namespace mln
+
+#endif /* !MLN_TRAIT_ACCU_HH */
Index: trunk/milena/sandbox/fred/old/algebraic.cc
===================================================================
--- trunk/milena/sandbox/fred/old/algebraic.cc (revision 0)
+++ trunk/milena/sandbox/fred/old/algebraic.cc (revision 3415)
@@ -0,0 +1,406 @@
+// 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
+// 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_CANVAS_ALGEBRAIC_HH
+# define MLN_CANVAS_ALGEBRAIC_HH
+
+/// \file mln/canvas/algebraic.hh
+///
+/// Apply algebraic connected filter to images.
+///
+/// \todo Test inputs validity.
+
+# include <mln/core/concept/image.hh>
+# include <mln/data/fill.hh>
+# include <mln/literal/zero.hh>
+# include <mln/convert/to_upper_window.hh>
+# include <mln/extension/adjust_fill.hh>
+
+# include <mln/level/sort_psites.hh>
+# include <mln/level/sort_offsets.hh>
+# include <mln/core/alias/neighb2d.hh>
+
+# include "../edwin/accu_trait.hh"
+# include "../edwin/card.hh"
+
+namespace mln
+{
+
+ namespace canvas
+ {
+
+ template < typename I, typename N, typename A, typename L>
+ mln_concrete(I)
+ algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
+ Accumulator<A>& a, L lambda, bool increasing);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Implementations.
+
+ namespace impl
+ {
+
+ namespace generic
+ {
+
+ template <typename I>
+ static inline
+ mln_psite(I)
+ find_root(I& parent, const mln_psite(I) & x)
+ {
+ if (parent(x) == x)
+ return x;
+ else
+ return parent(x) = find_root(parent, parent(x));
+ }
+
+ template < typename I, typename N, typename S, typename A, typename L>
+ mln_concrete(I)
+ algebraic(const Image<I>& input_, const Neighborhood<N>&
nbh_,
+ const Site_Set<S>& s_, const Accumulator<A>& a_, L
lambda)
+ {
+ trace::entering("canvas::impl::generic::algebraic");
+
+ // FIXME: Test?!
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ //const A& a = exact(a_);
+ (void)a_;
+ // Local type.
+ typedef mln_psite(I) P;
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, P) parent;
+ mln_ch_value(I, A) data;
+
+ // Initialization.
+ {
+ initialize(deja_vu, input);
+ mln::data::fill(deja_vu, false);
+ initialize(activity, input);
+ mln::data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+// a.init(); // init required.
+ }
+
+ // First pass.
+ {
+ mln_fwd_piter(S) p(s); // s required.
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ // Make set.
+ {
+ parent(p) = p;
+ data(p).take_as_init(p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ //do_union(n, p);
+ P r = find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) <
lambda))) // Equiv(r, p)
+ // Either a flat zone or the component of r is still growing.
+ {
+ /* FIXME: Same remark as above concerning the
+ initialization of data(p); instead of
+
+ data(p).take(data(r));
+
+ we should (or could) have
+
+ unite_data(p, r);
+
+ so as to keep the generic aspect of this canvas
+ (as long as the set of acceptable types for the
+ template parameter A is not bound). */
+ data(p).take(data(r));
+ parent(r) = p;
+ if (activity(r) == false)
+ activity(p) = false;
+ }
+ else
+ {
+ activity(p) = false;
+ }
+ }
+ }
+ deja_vu(p) = true;
+ }
+ }
+
+ // Second pass.
+ {
+ mln_bkd_piter(S) p(s);
+ for_all(p)
+ if (parent(p) == p) // p is root.
+ output(p) = input(p);
+ else
+ output(p) = output(parent(p));
+ }
+
+ trace::exiting("canvas::morpho::impl::generic::algebraic");
+ return output;
+ }
+
+ } // end of namespace mln::canvas::impl::generic
+
+ // Fastest version.
+ template <typename I>
+ inline
+ unsigned
+ find_root_fastest(I& parent, unsigned x)
+ {
+ if (parent.element(x) == x)
+ return x;
+ else
+ return parent.element(x) = find_root_fastest(parent, parent.element(x));
+ }
+
+ template < typename I, typename N, typename A, typename L>
+ mln_concrete(I)
+ algebraic_fastest(const Image<I>& input_, const
Neighborhood<N>& nbh_,
+ const util::array<unsigned>& s, const
Accumulator<A>& a_, L lambda)
+ {
+ trace::entering("canvas::impl::algebraic_fastest");
+
+ // FIXME: Tests?
+
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+
+ mln_concrete(I) output;
+ initialize(output, input);
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ // Auxiliary data.
+ mln_ch_value(I, bool) deja_vu;
+ mln_ch_value(I, bool) activity;
+ mln_ch_value(I, unsigned) parent;
+ mln_ch_value(I, A) data;
+
+ // Initialization.
+ {
+ initialize(deja_vu, input);
+ mln::data::fill(deja_vu, false);
+ initialize(activity, input);
+ mln::data::fill(activity, true);
+ initialize(parent, input);
+ mln::data::fill(parent, 0);
+ initialize(data, input);
+ }
+
+ util::array<int> dp = offsets_wrt(input, nbh);
+ const unsigned n_nbhs = dp.nelements();
+ const unsigned n_points = s.nelements();
+
+ // First pass.
+ {
+
+ for (unsigned i = 0; i < n_points; ++i)
+ {
+ unsigned p = s[i]; // An offset.
+
+ // Make set.
+ parent.element(p) = p;
+ data.element(p).take_as_init();
+
+ for (unsigned j = 0; j < n_nbhs; ++j)
+ {
+ unsigned n = p + dp[j];
+ if (!deja_vu.element(n))
+ continue;
+
+ unsigned r = find_root_fastest(parent, n);
+ if (r != p)
+ {
+ if (input.element(r) == input.element(p)
+ || (activity.element(r)
+ && (data.element(r) < lambda)))
+ {
+ data.element(p).take(data.element(r));
+ parent.element(r) = p;
+ if (activity.element(r) == false)
+ activity.element(p) = false;
+ }
+ else
+ activity.element(p) = false;
+ }
+ }
+
+ deja_vu.element(p) = true;
+ }
+
+ }
+
+ // Second pass.
+ {
+ for (int i = n_points - 1; i >= 0 ; --i)
+ {
+ unsigned p = s[i];
+ if (parent.element(p) == p) // p is root.
+ output.element(p) = input.element(p);
+ else
+ output.element(p) = output.element(parent.element(p));
+ }
+ }
+
+ trace::exiting("canvas::impl::algebraic_fastest");
+ return output;
+ }
+
+ } // end of namespace mln::canvas::impl
+
+ // Dispatch.
+ namespace internal
+ {
+
+ // Algebraic
+ template < typename I, typename N, typename A, typename L>
+ mln_concrete(I)
+ algebraic_dispatch(metal::false_,
+ const Image<I>& input, const
Neighborhood<N>& nbh,
+ const Accumulator<A>& a, L lambda, bool increasing)
+ {
+ p_array < mln_psite(I) > s =
+ increasing ?
+ level::sort_psites_increasing(input) :
+ level::sort_psites_decreasing(input);
+ return impl::generic::algebraic(input, nbh, s, a, lambda);
+ }
+
+ template < typename I, typename N, typename A, typename L>
+ mln_concrete(I)
+ algebraic_dispatch(metal::true_,
+ const Image<I>& input, const
Neighborhood<N>& nbh,
+ const Accumulator<A>& a, L lambda, bool increasing)
+ {
+ util::array<unsigned> s =
+ increasing ?
+ level::sort_offsets_increasing(input) :
+ level::sort_offsets_decreasing(input);
+ return impl::algebraic_fastest(input, nbh, s, a, lambda);
+ }
+
+ template < typename I, typename N, typename A, typename L>
+ inline
+ mln_concrete(I)
+ algebraic_dispatch(const Image<I>& input, const
Neighborhood<N>& nbh,
+ const Accumulator<A>& a, L lambda, bool increasing)
+ {
+ enum
+ {
+ test = mlc_equal(mln_trait_image_speed(I),
+ trait::image::speed::fastest)::value
+ && mlc_equal(mln_trait_accu_when_pix(A),
+ trait::accu::when_pix::use_whatever)::value
+ && mln_is_simple_neighborhood(N)::value
+ };
+ return algebraic_dispatch(metal::bool_<test>(),
+ input, nbh, a, lambda, increasing);
+ }
+
+
+ } // end of namespace mln::canvas::internal
+
+ // Facades.
+ template < typename I, typename N, typename A, typename L>
+ inline
+ mln_concrete(I)
+ algebraic(const Image<I>& input, const Neighborhood<N>& nbh,
+ const Accumulator<A>& a, L lambda, bool increasing)
+ {
+// FIXME: Do we need to check input validity ?
+ return internal::algebraic_dispatch(input, nbh, a, lambda, increasing);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::canvas
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CANVAS_ALGEBRAIC_HH
+
+#include <mln/core/image/image2d.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/util/timer.hh>
+
+int main(int argc, char **argv)
+{
+ using namespace mln;
+ using value::int_u8;
+
+ std::cout << "Algebraic filter test, reference: closing_area" <<
std::endl;
+
+ typedef mln::image2d<int_u8> I;
+ I lena;
+
+ float elapsed;
+ mln::util::timer chrono;
+
+ mln::io::pgm::load(lena, "../../img/lena.pgm");
+ I out;
+ int lambda = atoi(argv[1]);
+
+ chrono.start();
+ out = mln::canvas::algebraic (lena, c4(), mln::morpho::accu::card<I>(), lambda,
true);
+ elapsed = chrono.stop();
+ std::cout << "(auto) " << elapsed << "s" <<
std::endl;
+ mln::io::pgm::save(out, "auto.pgm");
+
+ chrono.start();
+ out = mln::canvas::internal::algebraic_dispatch(mln::metal::true_(), lena, c4(),
mln::morpho::accu::card<I>(), lambda, true);
+ elapsed = chrono.stop();
+ std::cout << "(fast) " << elapsed << "s" <<
std::endl;
+
+ mln::io::pgm::save(out, "fast.pgm");
+
+ chrono.start();
+ out = mln::canvas::internal::algebraic_dispatch(mln::metal::false_(), lena, c4(),
mln::morpho::accu::card<I>(), lambda, true);
+ elapsed = chrono.stop();
+ std::cout << "(slow) " << elapsed << "s" <<
std::endl;
+
+ mln::io::pgm::save(out, "slow.pgm");
+}
\ No newline at end of file
Index: trunk/milena/sandbox/fred/old/mean.hh
===================================================================
--- trunk/milena/sandbox/fred/old/mean.hh (revision 0)
+++ trunk/milena/sandbox/fred/old/mean.hh (revision 3415)
@@ -0,0 +1,202 @@
+// 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
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_MORPHO_ATTRIBUTE_MEAN_HH
+# define MLN_MORPHO_ATTRIBUTE_MEAN_HH
+
+/// \file mln/morpho/attribute/mean.hh
+///
+/// Define an accumulator that computes the mean of a
+/// component.
+///
+
+# include <mln/accu/internal/base.hh>
+# include <mln/accu/mean.hh>
+# include <mln/util/pix.hh>
+
+namespace mln {
+
+ // Forward declaration.
+
+ namespace morpho {
+ namespace attribute {
+ template <typename I> class mean;
+ }
+ }
+
+ // Traits
+
+ namespace trait {
+ template <typename I>
+ struct accumulator_< morpho::attribute::mean<I> >
+ {
+ typedef accumulator::has_untake::no has_untake;
+ typedef accumulator::has_set_value::yes has_set_value;
+ typedef accumulator::has_stop::no has_stop;
+ typedef accumulator::when_pix::use_v when_pix;
+ };
+ }
+
+
+ namespace morpho {
+
+ namespace attribute {
+
+ namespace internal {
+
+ template <typename T, typename S>
+ struct sum_set_value : public mln::accu::sum<T, S>
+ {
+ void set_value(const S& s);
+ };
+
+ }
+
+ /// Morphological (i.e. for pixel and pixel values) accumulator calculating mean.
+ /// Valid for leveling algorithm.
+ template <typename I>
+ class mean: public mln::accu::internal::base<mln_sum(mln_value(I)),
mean<I> >
+ {
+ public:
+ typedef util::pix<I> argument;
+ typedef mln_value(I) value;
+ typedef mln_sum(value) result;
+
+ mean();
+
+ /// Manipulators.
+ /// \{
+ void init();
+ void take(const value& v);
+ void take(const argument& t);
+ void take(const mean<I>& other);
+
+ void set_value(const result& r);
+ /// \}
+
+ /// Get the value of the accumulator.
+ result to_result() const;
+
+ /// Check whether this accu is able to return a result.
+ /// Always true here.
+ bool is_valid() const;
+
+ protected:
+
+ accu::count<value> count_;
+ internal::sum_set_value<value,result> sum_;
+ };
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal {
+
+ template <typename T, typename S>
+ void
+ sum_set_value<T, S>::set_value(const S& s)
+ {
+ this->s_ = s;
+ };
+
+ }
+
+ template <typename I>
+ inline
+ mean<I>::mean()
+ {
+ init();
+ }
+
+ template <typename I>
+ inline
+ void
+ mean<I>::init()
+ {
+ count_.init();
+ sum_.init();
+ }
+
+ template <typename I>
+ inline
+ void
+ mean<I>::take(const value& t)
+ {
+ count_.take(t);
+ sum_.take(t);
+ }
+
+ template <typename I>
+ inline
+ void
+ mean<I>::take(const argument& t)
+ {
+ take(t.v());
+ }
+
+ template <typename I>
+ inline
+ void
+ mean<I>::take(const mean<I>& other)
+ {
+ count_.take(other.count_);
+ sum_.take(other.sum_);
+ }
+
+ template <typename I>
+ void
+ mean<I>::set_value(const result& r)
+ {
+ sum_.set_value(r * count_.to_result());
+ };
+
+ template <typename I>
+ inline
+ typename mean<I>::result
+ mean<I>::to_result() const
+ {
+ unsigned n = count_.to_result();
+ return sum_.to_result() / n;
+ }
+
+ template <typename I>
+ inline
+ bool
+ mean<I>::is_valid() const
+ {
+ return count_.to_result() != 0;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::morpho::attribute
+
+ } // end of namespace mln::morpho
+
+} // end of namespace mln
+
+#endif /* ! MLN_MORPHO_ATTRIBUTE_MEAN_HH */