
https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena Index: ChangeLog from Ugo Jardonnet <ugo.jardonnet@lrde.epita.fr> Add interpolation function. Revamp lazy_image. * mln/core/image/lazy_image.hh: Fix traits, Add init_. * mln/fun/x2x/all.hh: Upgrade. * mln/fun/x2x/geom: New. * mln/fun/x2x/composed.hh: Move and update ... * mln/fun/x2x/geom/composed.hh: ... here. * mln/fun/x2x/translation.hh: Move and update ... * mln/fun/x2x/geom/translation.hh: ... here. * mln/fun/x2x/rotation.hh: Move and update ... * mln/fun/x2x/geom/rotation.hh: ... here. * mln/fun/x2x/interpol: New. * mln/fun/x2x/interpol/bilinear.hh: New interpolation. * mln/fun/x2x/interpol/linear.hh: New interpolation. * mln/draw/plot.hh: Fix doxygen. core/image/lazy_image.hh | 32 ++-- draw/plot.hh | 5 fun/x2x/all.hh | 9 - fun/x2x/geom/composed.hh | 285 +++++++++++++++++++++++++++++++++++++++++++ fun/x2x/geom/rotation.hh | 243 ++++++++++++++++++++++++++++++++++++ fun/x2x/geom/translation.hh | 152 ++++++++++++++++++++++ fun/x2x/interpol/bilinear.hh | 139 ++++++++++++++++++++ fun/x2x/interpol/linear.hh | 124 ++++++++++++++++++ fun/x2x/interpol/test.cc | 14 ++ 9 files changed, 982 insertions(+), 21 deletions(-) Index: mln/core/image/lazy_image.hh --- mln/core/image/lazy_image.hh (revision 2450) +++ mln/core/image/lazy_image.hh (working copy) @@ -37,7 +37,6 @@ # include <mln/core/internal/image_identity.hh> # include <mln/core/alias/box2d.hh> -# include <mln/core/line_piter.hh> namespace mln @@ -69,19 +68,11 @@ { template <typename I, typename F, typename B> - struct image_< lazy_image<I,F,B> > : default_image_morpher_< I, mln_value(I), + struct image_< lazy_image<I,F,B> > : default_image_morpher< I, mln_value(I), lazy_image<I,F,B> > { typedef trait::image::category::domain_morpher category; - - typedef mln_trait_image_access(I) access; - typedef mln_trait_image_space(I) space; - typedef mln_trait_image_size(I) size; - typedef mln_trait_image_support(I) support; - typedef mln_trait_image_border(I) border; - typedef mln_trait_image_io_from_(I) io; - typedef mln_trait_image_data_from_(I) data; - + typedef trait::image::value_io::read_only value_io; }; } // end of namespace mln::trait @@ -100,15 +91,13 @@ */ template <typename I, typename F, typename B> struct lazy_image : - public mln::internal::image_identity_< mln_ch_value(I, mln_result(F)), + public mln::internal::image_identity< mln_ch_value(I, mln_result(F)), mln_pset(I), lazy_image<I, F,B> > { - typedef mln::internal::image_identity_< mln_ch_value(I, mln_result(F)), + typedef mln::internal::image_identity< mln_ch_value(I, mln_result(F)), mln_pset(I), lazy_image<I, F,B> > super_; - typedef line_piter_<mln_psite(I)> line_piter; - /// Return type of read access. typedef mln_result(F) rvalue; @@ -122,8 +111,14 @@ using super_::has_data; /// Constructors. + lazy_image(); + + /// Constructors. lazy_image(const F& fun, const B& box); + /// Initialize an empty image. + void init_(const F& fun, const B& box); + /// Return domain of lazyd_image. const box2d& domain() const; @@ -164,6 +159,13 @@ template <typename I, typename F, typename B> inline + void lazy_image<I,F,B>::init_(const F& fun, const B& box) + { + this->data_ = new internal::data< lazy_image<I,F,B> >(fun, box); + } + + template <typename I, typename F, typename B> + inline bool lazy_image<I,F,B>::has(const mln_psite(I)& p) const { return this->data_->ima_.has(p); Index: mln/draw/plot.hh --- mln/draw/plot.hh (revision 2450) +++ mln/draw/plot.hh (working copy) @@ -46,8 +46,7 @@ namespace draw { - /*! Plot a point at level \p v in image \p ima between the points - * \p beg and \p end. + /*! Plot a point at level \p v in image \p ima * * \param[in,out] ima The image to be drawn. * \param[in] p The point to be plotted. @@ -68,7 +67,7 @@ template <typename I> inline void plot(Image<I>& ima, - const mln_point(I)& p, + const mln_psite(I)& p, const mln_value(I)& v) { mln_precondition(exact(ima).has_data()); Index: mln/fun/x2x/all.hh --- mln/fun/x2x/all.hh (revision 2450) +++ mln/fun/x2x/all.hh (working copy) @@ -54,9 +54,12 @@ } -# include <mln/fun/x2x/composed.hh> -# include <mln/fun/x2x/rotation.hh> -# include <mln/fun/x2x/translation.hh> +# include <mln/fun/x2x/geom/composed.hh> +# include <mln/fun/x2x/geom/rotation.hh> +# include <mln/fun/x2x/geom/translation.hh> + +# include <mln/fun/x2x/interpol/linear.hh> +# include <mln/fun/x2x/interpol/bilinear.hh> Index: mln/fun/x2x/geom/composed.hh --- mln/fun/x2x/geom/composed.hh (revision 0) +++ mln/fun/x2x/geom/composed.hh (revision 0) @@ -0,0 +1,285 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_FUN_X2X_GEOM_COMPOSED_HH +# define MLN_FUN_X2X_GEOM_COMPOSED_HH + +/*! \file mln/fun/x2x/composed.hh + * + * \brief Definition of a composed transformation. + */ + +# include <mln/core/concept/function.hh> +# include <mln/fun/internal/x2x_linear_impl.hh> +# include <mln/algebra/vec.hh> +# include <mln/metal/is.hh> +# include <mln/metal/bexpr.hh> +# include <mln/algebra/h_mat.hh> + + +namespace mln +{ + + namespace fun + { + + namespace x2x + { + + namespace geom + { + + // Fwd decl. + template <typename F, typename G> + struct composed; + + namespace internal + { + template <typename F, typename G, typename E, bool is_bij> + struct helper_composed_; + + + /// Helper for describing a bijective composition. + template <typename F, typename G, typename E> + struct helper_composed_< F, G, E, true> + : public fun::internal::x2x_linear_impl_<mln_result(F), E >, + public Bijection_x2x<E> + { + typedef fun::internal::x2x_linear_impl_<typename F::result, E > super_; + + using super_::dim; + + /// Constructor without argument. + helper_composed_(); + /// Constructor with the two transformation to be composed. + helper_composed_(const F& f, const G& g); + + using super_::operator(); + + /// Set the new first transformation. + void set_first(const F& f); + /// Set the new second transformation. + void set_second(const G& g); + + /// Type of the inverse function. + typedef composed<mln_invert(G),mln_invert(F)> invert; + /// Return the inverse function. + invert inv() const; + + protected: + + F f_; + G g_; + }; + + /// Helper for describing a non bijective composition. + template <typename F, typename G, typename E> + struct helper_composed_< F, G, E, false> + : public fun::internal::x2x_linear_impl_<mln_result(F), E >, + public Function_x2x<E> + { + typedef fun::internal::x2x_linear_impl_<typename F::result, E > super_; + + using super_::dim; + + /// Constructor without argument. + helper_composed_(); + /// Constructor with the two transformation to be composed. + helper_composed_(const F& f, const G& g); + + using super_::operator(); + + /// Set the new first transformation. + void set_first(const F& f); + /// Set the new second transformation. + void set_second(const G& g); + + protected: + + F f_; + G g_; + }; + + } // end of namespace mln::fun::x2x::geom::internal + + + /*! \brief Represent a composition of two transformations. + * + */ + template <typename F, typename G> + struct composed + : public internal::helper_composed_<F, G, composed<F,G>, + mlc_is(F, Bijection_x2x<F>)::value && + mlc_is(G, Bijection_x2x<G>)::value>, + private metal::and_< metal::bool_<(F::dim == G::dim)>, + metal::is<mln_argument(F), mln_result(G)> + >::check_t + { + /// Constructor without argument. + composed() {} + + /// Constructor with the two transformation to be composed. + composed(const F& f, const G& g) + : internal::helper_composed_<F, G, composed<F,G>, + mlc_is(F, Bijection_x2x<F>)::value && + mlc_is(G, Bijection_x2x<G>)::value>(f, g) + { + } + }; + + } // end of namespace mln::fun::x2x::geom + + } // end of namespace mln::fun::x2x + + } // end of namespace mln::fun + + + /*! \brief Do a composition of two transformations + * + * \param[in] f The first transformation. + * \param[in] g The second transformation. + * + * \return The composed transformation fog. + */ + template <typename F, typename G> + fun::x2x::geom::composed<F,G> compose(F f, G g); + +# ifndef MLN_INCLUDE_ONLY + + namespace fun + { + + namespace x2x + { + + namespace geom + { + + namespace internal + { + + // Implementation of the bijective version. + + template <typename F, typename G, typename E> + inline + helper_composed_<F,G,E,true>::helper_composed_() + { + } + + template <typename F, typename G, typename E> + inline + helper_composed_<F,G,E,true>::helper_composed_(const F& f, const G& g) + :f_(f), + g_(g) + { + this->m_ = f_.mat() * g_.mat(); + } + + template <typename F, typename G, typename E> + inline + typename helper_composed_<F,G,E,true>::invert + helper_composed_<F,G,E,true>::inv() const + { + return compose(g_.inv(), f_.inv()); + } + + template <typename F, typename G, typename E> + inline + void + helper_composed_<F,G,E,true>::set_first(const F& f) + { + this->f_ = f; + this->m_ = this->f_.mat() * this->g_.mat(); + } + + template <typename F, typename G, typename E> + inline + void + helper_composed_<F,G,E,true>::set_second(const G& g) + { + this->g_ = g; + this->m_ = this->f_.mat() * this->g_.mat(); + } + + // Implementation of the non bijective version. + template <typename F, typename G, typename E> + inline + helper_composed_<F,G,E,false>::helper_composed_() + { + } + + template <typename F, typename G, typename E> + inline + helper_composed_<F,G,E,false>::helper_composed_(const F& f, const G& g) + :f_(f), + g_(g) + { + this->m_ = f_.mat() * g_.mat(); + } + + template <typename F, typename G, typename E> + inline + void + helper_composed_<F,G,E,false>::set_first(const F& f) + { + this->f_ = f; + this->m_ = this->f_.mat() * this->g_.mat(); + } + + template <typename F, typename G, typename E> + inline + void + helper_composed_<F,G,E,false>::set_second(const G& g) + { + this->g_ = g; + this->m_ = this->f_.mat() * this->g_.mat(); + } + + } // end of namespace mln::fun::x2x::geom::internal + + } // end of namespace mln::fun::x2x::geom + + } // end of namespace mln::fun::x2x + + } // end of namespace mln::fun + + template <typename F, typename G> + inline + fun::x2x::geom::composed<F,G> compose(F f, G g) + { + trace::entering("fun::x2x::compose"); + fun::x2x::geom::composed<F,G> comp(f, g); + trace::exiting("fun::x2x::compose"); + return comp; + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + +#endif // ! MLN_FUN_X2X_GEOM_COMPOSED_HH Index: mln/fun/x2x/geom/translation.hh --- mln/fun/x2x/geom/translation.hh (revision 0) +++ mln/fun/x2x/geom/translation.hh (revision 0) @@ -0,0 +1,152 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_FUN_X2X_TRANSLATION_HH +# define MLN_FUN_X2X_TRANSLATION_HH + +/*! \file mln/fun/x2x/translation.hh + * + * \brief Define a translation function. + */ + +# include <mln/core/concept/function.hh> +# include <mln/fun/internal/x2x_linear_impl.hh> +# include <mln/algebra/vec.hh> +# include <mln/algebra/h_mat.hh> +# include <mln/fun/i2v/all.hh> + +namespace mln +{ + + namespace fun + { + + namespace x2x + { + + namespace geom + { + + /*! \brief Represent a translation function. + * + */ + template <unsigned n, typename C> + struct translation + : fun::internal::x2x_linear_impl_< algebra::vec<n,C>, translation<n,C> > + , public Bijection_x2x< translation<n,C> > + { + typedef fun::internal::x2x_linear_impl_< algebra::vec<n,C>, translation<n,C> > super_; + + /// Type of the inverse function. + typedef translation<n,C> invert; + /// Return the inverse function. + invert inv() const; + + /// Constructor without argument. + translation(); + /// Constructor with the translation vector. + translation(const algebra::vec<n,C>& t); + + using super_::operator(); + /// Perform the translation of the given vector + algebra::vec<n,C> operator()(const algebra::vec<n,C>& v) const; + + /// Set a net translation vector. + void set_t(const algebra::vec<n,C>& t); + + protected: + void update(); + + algebra::vec<n,C> t_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, typename C> + inline + translation<n,C>::translation() + { + } + + template <unsigned n, typename C> + inline + translation<n,C>::translation(const algebra::vec<n,C>& t) + :t_(t) + { + this->update(); + } + + template <unsigned n, typename C> + inline + algebra::vec<n,C> + translation<n,C>::operator()(const algebra::vec<n,C>& v) const + { + return v + t_; + } + + template <unsigned n, typename C> + inline + translation<n,C> + translation<n,C>::inv() const + { + typename translation::invert res(-t_); + + return res; + } + + template <unsigned n, typename C> + inline + void + translation<n,C>::set_t(const algebra::vec<n,C>& t) + { + this->t_ = t; + this->update(); + } + + template <unsigned n, typename C> + inline + void + translation<n,C>::update() + { + this->m_ = algebra::h_mat<n,C>::Id; + for (unsigned i = 0; i < n; ++i) + this->m_(i,n) = this->t_[i]; + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::x2x::geom + + } // end of namespace mln::fun::x2x + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_X2X_TRANSLATION_HH Index: mln/fun/x2x/geom/rotation.hh --- mln/fun/x2x/geom/rotation.hh (revision 0) +++ mln/fun/x2x/geom/rotation.hh (revision 0) @@ -0,0 +1,243 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_FUN_X2X_ROTATION_HH +# define MLN_FUN_X2X_ROTATION_HH + +/*! \file mln/fun/x2x/rotation.hh + * + * \brief Define a rotation function. + */ + +# include <mln/core/concept/function.hh> +# include <mln/fun/internal/x2x_linear_impl.hh> +# include <mln/algebra/vec.hh> +# include <mln/algebra/mat.hh> +# include <cmath> + +namespace mln +{ + + namespace fun + { + + namespace x2x + { + + namespace geom + { + + namespace internal + { + template < unsigned n, typename C > + algebra::h_mat<n, C> + get_rot_h_mat(const float alpha_, const algebra::vec<3,C>& axis_) + { + assert(!"get_h_mat : n not implemented"); + } + + template <typename C > + algebra::h_mat<3, C> + get_rot_h_mat(const float alpha_, const algebra::vec<3,C>& axis_) + { + algebra::h_mat<3, C> m_; + + const float cos_a = cos(alpha_); + const float sin_a = sin(alpha_); + const float u = axis_[0]; + const float v = axis_[1]; + const float w = axis_[2]; + const float u2 = u * u; + const float v2 = v * v; + const float w2 = w * w; + const float uvw2 = u2 + v2 + w2; + + m_(0,0) = (u2 + (v2 + w2) * cos_a) / uvw2; + m_(0,1) = (u*v * (1 - cos_a) - u * std::sqrt(uvw2) * sin_a) / uvw2; + m_(0,2) = (u*w * (1 - cos_a) + v * std::sqrt(uvw2) * sin_a) / uvw2; + m_(0,3) = 0; + + m_(1,0) = (u*v * (1 - cos_a) + w * std::sqrt(uvw2) * sin_a) / uvw2; + m_(1,1) = (v2 + (u2 + w2) * cos_a) / uvw2; + m_(1,2) = (v*w * (1 - cos_a) - u * std::sqrt(uvw2) * sin_a) / uvw2; + m_(1,3) = 0; + + m_(2,0) = (u*w * (1 - cos_a) - v * std::sqrt(uvw2) * sin_a) / uvw2; + m_(2,1) = (v*w * (1 - cos_a) + u * std::sqrt(uvw2) * sin_a) / uvw2; + m_(2,1) = (u2 + (u2 + v2) * cos_a) / uvw2; + m_(2,3) = 0; + + m_(2,0) = 0; + m_(2,1) = 0; + m_(2,1) = 0; + m_(2,3) = 1; + + return m_; + } + + template <typename C > + algebra::h_mat<2, C> + get_rot_h_mat(const float alpha_, const algebra::vec<2,C>&) + { + algebra::h_mat<2, C> m_; + + const float cos_a = cos(alpha_); + const float sin_a = sin(alpha_); + + m_(0,0) = cos_a; m_(0,1) = -sin_a; m_(0,2) = 0; + + m_(1,0) = sin_a; m_(1,1) = cos_a; m_(1,2) = 0; + + m_(2,0) = 0; m_(2,1) = 0; m_(2,2) = 1; + + return m_; + } + } + + + /*! \brief Represent a rotation function. + * + */ + template <unsigned n, typename C> + struct rotation + : fun::internal::x2x_linear_impl_< algebra::vec<n,C>, rotation<n,C> > + , public Bijection_x2x< rotation<n,C> > + { + typedef fun::internal::x2x_linear_impl_< algebra::vec<n,C>, rotation<n,C> > super_; + + /// Type of the inverse function. + typedef rotation<n,C> invert; + /// Return the invere function. + invert inv() const; + + /// Constructor without argument. + rotation(); + /// Constructor with grade alpha and a facultative direction (rotation axis). + rotation(float alpha, const algebra::vec<n,float>& axis); + + using super_::operator(); + /// Perform the rotation of the given vector. + algebra::vec<n,C> operator()(const algebra::vec<n,C>& v) const; + + /// Set a new grade alpha. + void set_alpha(float alpha); + /// Set a new rotation axis. + void set_dir(unsigned dir); + + protected: + void update(); + + float alpha_; + algebra::vec <n,float> axis_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, typename C> + inline + rotation<n,C>::rotation() + { + } + + template <unsigned n, typename C> + inline + rotation<n,C>::rotation(float alpha, const algebra::vec<n,float>& axis) + :alpha_(alpha), + axis_(axis) + { + this->m_ = algebra::h_mat<n,C>::Id; + update(); + } + + template <unsigned n, typename C> + inline + algebra::vec<n,C> + rotation<n,C>::operator()(const algebra::vec<n,C>& v) const + { + algebra::mat<n+1,1,C> hmg; + algebra::mat<n+1,1,C> tmp; + algebra::vec<n,C> res; + + for (unsigned i = 0; i < n; ++i) + hmg(i,0) = v[i]; + hmg(n,0) = 1; + tmp = this->m_ * hmg; + mln_assertion(tmp(n,0) == 1); + for (unsigned i = 0; i < n; ++i) + res[i] = tmp(i,0); + return res; + } + + template <unsigned n, typename C> + inline + rotation<n,C> + rotation<n,C>::inv() const + { + typename rotation::invert res(-alpha_, axis_); + return res; + } + + template <unsigned n, typename C> + inline + void + rotation<n,C>::set_alpha(float alpha) + { + alpha_ = alpha; + update(); + } + + template <unsigned n, typename C> + inline + void + rotation<n,C>::set_dir(unsigned dir) + { + update(); + } + + // Homogenous matrix for a rotation of a point (x,y,z) + // about the vector (u,v,w) by the angle alpha + template <unsigned n, typename C> + inline + void + rotation<n,C>::update() + { + this->m_ = internal::get_rot_h_mat(alpha_, axis_); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::x2x::geom + + } // end of namespace mln::fun::x2x + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_X2X_ROTATION_HH Index: mln/fun/x2x/interpol/bilinear.hh --- mln/fun/x2x/interpol/bilinear.hh (revision 0) +++ mln/fun/x2x/interpol/bilinear.hh (revision 0) @@ -0,0 +1,139 @@ +// Copyright (C) 2008 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_FUN_X2X_INTERPOL_BILINEAR_HH +# define MLN_FUN_X2X_INTERPOL_BILINEAR_HH + +# include <mln/core/image/image2d.hh> +# include <mln/core/concept/function.hh> +# include <mln/fun/internal/selector.hh> + +/*! \file mln/fun/x2x/interpol/bilinear.hh + * + * \brief Define a bilinear interpolation of values from an underlying image + */ + +namespace mln +{ + + namespace fun + { + + namespace x2x + { + + namespace interpol + { + + + /*! \brief Represent a bilinear interolation of values from an underlying image + * + */ + template < typename I > + struct bilinear + : public fun::internal::selector_<const algebra::vec<3,float>, + // 3,float is a dummy parameter (real is n,T) + mln_value(I), bilinear<I> >::ret + { + typedef mln_value(I) result; + + bilinear(const I& ima); + + template <unsigned n, typename T> + mln_value(I) + operator()(const algebra::vec<n,T>& v) const; + + const I& ima; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + bilinear<I>::bilinear(const I& ima) : ima(ima) + { + mlc_bool(I::psite::dim == 2)::check(); + } + + template <typename I> + template <unsigned n, typename T> + mln_value(I) + bilinear<I>::operator()(const algebra::vec<n,T>& v) const + { + typedef mln_sum(mln_value(I)) vsum; + + // q12----r2----q22 + // | | | + // | x | + // | | | + // q11----r1----q21 + + // looking for img(P(x,y)) + double x = v[0]; + double y = v[1]; + + double x1 = std::floor(v[0]); + double x2 = std::floor(v[0]) + 1; + double y1 = std::floor(v[1]); + double y2 = std::floor(v[1]) + 1; + + //if (not ima.has(point2d(x1, y1))) return mln_value(I)(); + vsum q11 = ima(point2d(x1, y1)); + vsum q12 = ima(point2d(x1, y2)); + vsum q21 = ima(point2d(x2, y1)); + vsum q22 = ima(point2d(x2, y2)); + + double x2_x1 = x2 - x1; + double y2_y1 = y2 - y1; + + // linear interpolation #1 + vsum img_r1 = q11 * (x2 - x) / (x2_x1) + + q21 * (x - x1) / (x2_x1); + + // linear interpolation #2 + vsum img_r2 = q12 * (x2 - x) / (x2_x1) + q22 * (x - x1) / (x2_x1); + + // interpolating in y direction + vsum res = (img_r1 * (y2 - y) / (y2_y1) + + img_r2 * (y - y1) / (y2_y1)); + + return convert::to<mln_value(I)>(res); + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::x2x::interpol + + } // end of namespace mln::fun::x2x + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_X2X_INTERPOL_BILINEAR_HH Index: mln/fun/x2x/interpol/test.cc --- mln/fun/x2x/interpol/test.cc (revision 0) +++ mln/fun/x2x/interpol/test.cc (revision 0) @@ -0,0 +1,14 @@ +#include "bilinear.hh" +#include "linear.hh" + +int main() +{ + typedef mln::image2d<int> I; + typedef mln::image1d<int> II; + + I ima2d; + II ima1d; + + mln::fun::x2x::interpol::bilinear<I> interp(ima2d); + mln::fun::x2x::interpol::linear<II> interp3(ima1d); +} Index: mln/fun/x2x/interpol/linear.hh --- mln/fun/x2x/interpol/linear.hh (revision 0) +++ mln/fun/x2x/interpol/linear.hh (revision 0) @@ -0,0 +1,124 @@ +// Copyright (C) 2008 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_FUN_X2X_INTERPOL_LINEAR_HH +# define MLN_FUN_X2X_INTERPOL_LINEAR_HH + +/*! \file mln/fun/x2x/interpol/linear.hh + * + * \brief Define a linear interpolation of values from an underlying image + */ + +# include <mln/core/image/image1d.hh> +# include <mln/core/concept/function.hh> +# include <mln/fun/internal/selector.hh> + +namespace mln +{ + + namespace fun + { + + namespace x2x + { + + namespace interpol + { + + + /*! \brief Represent a linear interolation of values from an underlying image + * + */ + template < typename I > + struct linear + : public fun::internal::selector_<const algebra::vec<1,float>, + // float is a dummy parameter (real is C) + mln_value(I), linear<I> >::ret + { + typedef mln_value(I) result; + + /// Constructor with the underlying image + linear(const I& ima); + + /// Return the interpolated value in the underlying image + /// at the given 'point' v. + template <typename C> + mln_value(I) + operator()(const algebra::vec<1,C>& v) const; + + /// Underlying image + const I& ima; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <typename I> + linear<I>::linear(const I& ima) : ima(ima) + { + mlc_bool(I::psite::dim == 1)::check(); + } + + template <typename I> + template <typename C> + mln_value(I) + linear<I>::operator()(const algebra::vec<1,C>& v) const + { + typedef mln_sum(mln_value(I)) vsum; + + // looking for img(x); + double x = v[0]; + + // p1 + double xa = mln_point(I)::coord(v[0]); + vsum ya = ima(point1d(xa)); + + // x makes sens in img + if (x == xa) + return ima(xa); + + // p2 + double xb = mln_point(I)::coord(v[0] + 1); + vsum yb = ima(point1d(xb)); + + // Taylor-young + return convert::to<mln_value(I)> + (ya + (x - xa) * (yb - ya) / (xb - xa)); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::x2x::interpol + + } // end of namespace mln::fun::x2x + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_X2X_INTERPOL_HH Index: mln/util/array.hh