
URL: https://svn.lrde.epita.fr/svn/oln/trunk ChangeLog: 2009-03-01 Frederic Bour <bour@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 *~
participants (1)
-
Frederic Bour