URL:
https://svn.lrde.epita.fr/svn/oln/trunk
ChangeLog:
2009-03-01 Frederic Bour <bour(a)lrde.epita.fr>
Add rush/exo3.
* milena/mln/canvas/morpho/attribute_filter.hh: Add one missing include.
* milena/sandbox/theo/rush/exo3/Makefile: New.
* milena/sandbox/theo/rush/exo3/exo3_1.cc: New.
* milena/sandbox/theo/rush/exo3/exo3_2.cc: New.
* milena/sandbox/theo/rush/exo3/inverse.cc: New.
* milena/sandbox/theo/rush/exo3: New.
---
mln/canvas/morpho/attribute_filter.hh | 7
sandbox/theo/rush/exo3/Makefile | 28 ++
sandbox/theo/rush/exo3/exo3_1.cc | 296 +++++++++++++++++++++++++++++
sandbox/theo/rush/exo3/exo3_2.cc | 346 ++++++++++++++++++++++++++++++++++
sandbox/theo/rush/exo3/inverse.cc | 84 ++++++++
5 files changed, 755 insertions(+), 6 deletions(-)
Index: trunk/milena/mln/canvas/morpho/attribute_filter.hh
===================================================================
--- trunk/milena/mln/canvas/morpho/attribute_filter.hh (revision 3447)
+++ trunk/milena/mln/canvas/morpho/attribute_filter.hh (revision 3448)
@@ -43,6 +43,7 @@
# include <mln/util/pix.hh>
# include <mln/data/fill.hh>
+# include <mln/level/sort_psites.hh>
namespace mln {
namespace canvas {
@@ -55,12 +56,6 @@
const Accumulator<A>& a, const typename A::result& lambda,
bool increasing);
- template <typename I, typename N, typename A>
- mln_concrete(I)
- algebraic_filter(const Image<I>& input, const Neighborhood<N>&
nbh,
- const Accumulator<A>& a, const typename A::result& lambda,
- bool increasing);
-
# ifndef MLN_INCLUDE_ONLY
namespace impl {
Index: trunk/milena/sandbox/theo/rush/exo3/inverse.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/inverse.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/inverse.cc (revision 3448)
@@ -0,0 +1,84 @@
+#include <mln/fun/all.hh>
+
+// Some definitions
+struct not_found {};
+struct impossible {};
+
+namespace inverse
+{
+ template <typename F>
+ struct solve_inverse
+ {
+ typedef not_found ret;
+ typedef not_found inversekind;
+ };
+
+ struct FInvKind_
+ {
+ struct lazy
+ {
+ };
+
+ struct computed
+ {
+ };
+
+ struct computed_w
+ {
+ };
+
+ };
+
+ namespace decompose
+ {
+ template <typename Class, typename Member>
+ struct Functor;
+
+ template <typename Class, typename Res, typename Arg>
+ struct Functor<Class, Result (Class::*)(Arg)>
+ {
+ typedef Res fun_result;
+ typedef Arg fun_argument;
+ };
+
+ template <typename T>
+ struct Dec
+ {
+ typedef Functor<T, &(const T)::operator() > const_tool;
+ typedef Functor<T, &T::operator() > mutab_tool;
+
+ typedef tool::fun_result result;
+ typedef tool::fun_argument argument;
+
+ T inst_;
+
+ result
+ operator() (argument a) const
+ {
+ return inst_(a);
+ };
+
+ result
+ operator() (argument a)
+ {
+ return inst_(a);
+ };
+ };
+
+ }
+
+ template <typename F, typename F_1 = typename solve_inverse<F>::ret,
+ typename InvKind = typename solve_inverse<F>::InvKind>
+ struct invertible : typename solve_kind<InvKind, invertible>::ret
+ {
+
+ typedef invertible<F_1, F> inverse;
+ };
+}
+
+int main()
+{
+ using namespace mln;
+
+
+};
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_1.cc (revision 3448)
@@ -0,0 +1,296 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/trait/all.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+#include <mln/trait/op/all.hh>
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct area;
+ }
+
+ /// Meta function for area calculation
+ namespace meta
+ {
+
+ struct area
+ {
+ template <typename T>
+ typename fun::v2v::area<T>::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::area<T> f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::area<T> ret;
+ };
+ };
+
+ } // end of namespace mln::fun::meta
+
+ /// Function for area calculation
+ namespace v2v
+ {
+
+ template <typename T>
+ struct area : mln::Function_v2v< area<T> >
+ {
+ typedef mln_fun_internal_resolve(area) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const T& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ } // end of namespace mln::fun::v2v
+
+ /// Function_p2v composition
+ namespace p2v
+ {
+ template <typename F, typename G>
+ struct composition_t
+ : mln::Function_p2v< composition_t<F, G> >
+ {
+ typedef typename F::result result;
+
+ composition_t() {}
+ composition_t(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+ } // end of namespace mln::fun::p2v
+
+ } // end of namespace mln::fun
+
+ /// fun::v2v::area trait for composition
+ namespace trait
+ {
+ template <typename T>
+ struct set_unary_< fun::v2v::area, Accumulator, T >
+ {
+ typedef set_unary_< fun::v2v::area, Accumulator, T > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const T& t1)
+ {
+ return t1.area();
+ }
+ };
+
+ template <typename I>
+ struct set_precise_unary_< fun::v2v::area, mln::morpho::attribute::card<I>
>
+ {
+ typedef set_precise_unary_< fun::v2v::area,
mln::morpho::attribute::card<I> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const mln::morpho::attribute::card<I>& t1)
+ {
+ return t1.to_result();
+ }
+ };
+
+ template <typename G>
+ struct set_unary_<fun::v2v::area, mln::Function_p2v, G>
+ {
+ typedef set_unary_<fun::v2v::area, mln::Function_p2v, G> ret;
+ typedef fun::p2v::composition_t<fun::v2v::area<typename G::result>, G>
result;
+
+ static
+ result
+ exec(const G& g)
+ {
+ return fun::p2v::composition_t<fun::v2v::area<typename G::result>, G>
+ (fun::v2v::area<typename G::result>(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+// for purpose of testing.
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ 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;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ 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)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+} // end of namespace exo3_filter
+
+namespace exo3_filter
+{
+ // Le but est de surcharger les operateurs uniquement pour les Built_In<>...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les Function<> utilisant
mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<value::int_u8> I;
+
+ I lena;
+ io::pgm::load(lena, "./affiche2.pgm");
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(lena, c4(),
+ level::sort_psites_decreasing(lena),
+ morpho::attribute::sharpness<I>(), 0.2));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::area area;
+ io::pbm::save((area(s) > 1500U && area(s) < 2000U) | lena.domain(),
"out.pbm");
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/exo3_2.cc (revision 3448)
@@ -0,0 +1,346 @@
+#include <mln/core/image/image2d.hh>
+#include <mln/morpho/attribute/sharpness.hh>
+#include <mln/pw/all.hh>
+#include <mln/io/pgm/all.hh>
+#include <mln/io/pbm/all.hh>
+#include <mln/core/var.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/trait/all.hh>
+#include <mln/core/concept/function.hh>
+#include <mln/fun/internal/resolve.hh>
+#include <mln/morpho/attribute/card.hh>
+#include <mln/level/sort_offsets.hh>
+#include <mln/canvas/morpho/attribute_filter.hh>
+#include <mln/canvas/morpho/internal/find_root.hh>
+#include <mln/trait/op/all.hh>
+
+namespace exo3
+{
+ // Se code est un peu ... sale, et tente de répondre aux problèmes
+ // techniques apparus lors de la présentation (bonus ?).
+
+ // mln::trait::solve se spécialise pour des template <class T>
+ // en premier paramètre.
+ // Afin de transmettre plusieurs types, on passe par
+ // T = couple<TExact, TAux>. On 'hérite' de la catégorie de TExact.
+ // Utiliser pour le générateur de (méta)fonctions.
+ template <typename TExact, typename TAux>
+ struct couple
+ {
+ typedef TExact Exact;
+ typedef typename mln::category<Exact>::ret category;
+
+ typedef TAux Aux;
+ };
+
+ // Crée un type unique vide pour un type donné, évite une instantation ?!
+ // (inutile probablement, dans le doute...).
+ template <typename U>
+ struct uniq
+ {
+ };
+
+ // Get attribute from attribute "E" exact.
+ template <typename E>
+ typename E::result
+ get_attribute(uniq<E>, const E& exact)
+ {
+ return exact.to_result();
+ }
+
+ // area
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::card<I> >, const
E& exact)
+ {
+ return exact.area();
+ }
+
+ // volume
+ template <typename I, typename E>
+ unsigned get_attribute(uniq< mln::morpho::attribute::volume<I> >, const
E& exact)
+ {
+ return exact.volume();
+ }
+}
+
+namespace mln
+{
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T> struct from_accu_t;
+ template <typename T> struct solve_from_accu;
+ }
+
+ namespace meta
+ {
+ template <template <class> class A>
+ struct from_accu
+ {
+ template <typename T>
+ typename fun::v2v::from_accu_t< exo3::couple<T, A<T> >
>::result
+ operator()(const T& t1) const
+ {
+ fun::v2v::from_accu_t< exo3::couple<T, A<T> > > f;
+ return f(t1);
+ }
+
+ template <typename T>
+ struct with
+ {
+ typedef fun::v2v::from_accu_t< exo3::couple<T, A<T> > > ret;
+ };
+ };
+ }
+ }
+
+ namespace trait
+ {
+ template <typename TE, typename TA>
+ struct set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE, TA>
>
+ {
+ typedef set_unary_< fun::v2v::from_accu_t, Accumulator, exo3::couple<TE,
TA> > ret;
+ typedef unsigned result;
+
+ static
+ result
+ exec(const TE& t1)
+ {
+ return exo3::get_attribute(exo3::uniq<TA>(), t1);
+ }
+ };
+
+ } // mln::trait
+
+ namespace fun
+ {
+ namespace v2v
+ {
+ template <typename T>
+ struct from_accu_t;
+
+ template <typename TE, typename TA>
+ struct from_accu_t< exo3::couple<TE, TA> > : mln::Function_v2v<
from_accu_t< exo3::couple<TE, TA> > >
+ {
+ typedef mln_fun_internal_resolve(from_accu_t) impl;
+ typedef typename impl::result result;
+
+ result
+ operator()(const TE& t1) const
+ {
+ return impl::exec(t1);
+ }
+ };
+
+ template <typename A>
+ struct solve_from_accu
+ {
+ // FIXME: Not sure whether inheritance is the right way...
+ // But templated typedef are not currently available.
+ template <typename E>
+ struct ret : from_accu_t< exo3::couple< E, A > >
+ {
+ };
+ };
+ }
+ }
+
+}
+
+namespace exo3
+{
+ template <typename F, typename G>
+ struct functors_compose_
+ : mln::Function_p2v< functors_compose_<F, G> >
+ {
+ typedef typename F::result result;
+
+ functors_compose_() {}
+ functors_compose_(const F& f, const G& g)
+ : f_(f), g_(g)
+ {
+ }
+
+ template <typename T>
+ result
+ operator()(const T& p) const
+ {
+ return f_(g_(p));
+ }
+
+ protected:
+ F f_;
+ G g_;
+ };
+
+}
+
+namespace mln
+{
+
+ namespace trait
+ {
+
+ template <typename TG, typename TA>
+ struct set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG,
TA> >
+ {
+ typedef set_unary_<fun::v2v::from_accu_t, mln::Function_p2v, exo3::couple<TG,
TA> > ret;
+ typedef exo3::functors_compose_<fun::v2v::from_accu_t<
exo3::couple<typename TG::result, TA> >, TG> result;
+
+ static
+ result
+ exec(const TG& g)
+ {
+ return exo3::functors_compose_<fun::v2v::from_accu_t< exo3::couple<typename
TG::result, TA> >, TG>
+ (fun::v2v::from_accu_t<exo3::couple<typename TG::result, TA> >(), g);
+ }
+ };
+ }
+
+}
+
+// Modified copy of mln::canvas::morpho::attribute_filter
+namespace exo3_filter
+{
+ using namespace mln;
+
+ template <typename I, typename N, typename S, typename A>
+ mln_ch_value(I, A)
+ attribute_filter (const Image<I>& input_,
+ const Neighborhood<N>& nbh_,
+ const Site_Set<S>& s_,
+ const Accumulator<A>& a_,
+ const typename A::result& lambda)
+ {
+ const I& input = exact(input_);
+ const N& nbh = exact(nbh_);
+ const S& s = exact(s_);
+ (void)a_; // To avoid warning at compilation
+
+ // Local type.
+ typedef mln_psite(I) P;
+
+ 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;
+
+ {
+ initialize(deja_vu, input);
+ data::fill(deja_vu, false);
+ initialize(activity, input);
+ data::fill(activity, true);
+ initialize(parent, input);
+ initialize(data, input);
+ }
+ {
+ mln_fwd_piter(S) p(s);
+ mln_niter(N) n(nbh, p);
+
+ for_all(p)
+ {
+ {
+ parent(p) = p;
+ mln::canvas::morpho::impl::take_as_init (data(p), input, p);
+ }
+
+ for_all(n)
+ if (input.domain().has(n) && deja_vu(n))
+ {
+ P r = mln::canvas::morpho::impl::generic::find_root(parent, n);
+ if (r != p)
+ {
+ if (input(r) == input(p) || (activity(r) && (data(r) < lambda)))
+ {
+ 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)
+ data(p) = data(parent(p));
+ }
+ return data;
+ }
+
+ // Surcharger les operateurs uniquement pour les builtins...
+ // l'idée est de provoquer une sfinae. J'ai pas trouvé mieux :(
+ // (pas vu d'opérateurs <, >, ... pour les fonctions utilisant
mln::trait::solve)
+
+ // C is Category, R is return type
+ template <typename C, typename R>
+ struct ret_builtin;
+ template <typename T, typename R>
+ struct ret_builtin< value::Built_In< T > , R>
+ {
+ typedef R ret;
+ };
+
+} // end of namespace exo3_filter
+
+#define templatize(...) __VA_ARGS__
+
+#define op_for_cst(name, op) \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ F, \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret) \
+ ) \
+ operator op (const mln::Function_p2v<F>& f, const C& c) \
+ { \
+ return exact(f) op mln::pw::cst(c); \
+ } \
+ \
+ template <typename F, typename C> \
+ mln_trait_op_##name( \
+ templatize(typename exo3_filter::ret_builtin< typename mln::category< C
>::ret, mln::pw::cst_<C> >::ret), \
+ F \
+ ) \
+ operator op (const C& c, const mln::Function_p2v<F>& f) \
+ { \
+ return mln::pw::cst(c) or exact(f); \
+ }
+
+op_for_cst(less, <)
+op_for_cst(greater, >)
+op_for_cst(leq, <=)
+op_for_cst(geq, >=)
+op_for_cst(eq, ==)
+op_for_cst(neq, !=)
+
+#undef op_for_cst
+
+int main()
+{
+ using namespace mln;
+
+ typedef image2d<value::int_u8> I;
+
+ I lena;
+ io::pgm::load(lena, "/home/defre/affiche2.pgm");
+
+ mln_VAR(sharp, exo3_filter::attribute_filter(lena, c4(),
+ level::sort_psites_decreasing(lena),
+ morpho::attribute::sharpness<I>(), 0.2));
+
+ mln_VAR(s, pw::value(sharp));
+
+ mln::fun::meta::from_accu< mln::morpho::attribute::volume > vol;
+ io::pbm::save((vol(s) > 1500U && vol(s) < 2000U) | lena.domain(),
"out.pbm");
+
+}
\ No newline at end of file
Index: trunk/milena/sandbox/theo/rush/exo3/Makefile
===================================================================
--- trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 0)
+++ trunk/milena/sandbox/theo/rush/exo3/Makefile (revision 3448)
@@ -0,0 +1,28 @@
+TARGETS=exo3_1 exo3_2 inverse
+
+OLENADIR=../../../../..
+MILENADIR=$(OLENADIR)/milena
+
+CXXFLAGS=-I$(MILENADIR) -I./ -W -Wall -O2
+CXX=g++
+LD=g++
+LDFLAGS=
+RM=rm
+
+all: $(TARGETS)
+
+exo3_1: exo3_1.o
+exo3_2: exo3_2.o
+inverse: inverse.o
+
+$(TARGETS):
+ $(LD) $(LDFLAGS) -o $@ $<
+
+%.o: %.cc
+ $(CXX) $(CXXFLAGS) -c $<
+
+%.o: %.hh
+ $(CXX) $(CXXFLAGS) -c $<
+
+clean:
+ $(RM) -f $(TARGETS) *.o *~