TuttleOFX  1
pinning.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_GEOMETRY_PINNING_HPP_
00002 #define _TERRY_GEOMETRY_PINNING_HPP_
00003 
00004 #include <boost/numeric/ublas/matrix.hpp>
00005 
00006 namespace terry {
00007 namespace geometry {
00008 
00009 template<typename Scalar>
00010 struct PinningPerspective
00011 {
00012         double _width, _height;
00013         boost::numeric::ublas::bounded_matrix<Scalar,3,3> _matrix;
00014 };
00015 
00016 template<typename Scalar>
00017 struct PinningBilinear
00018 {
00019         double _width, _height;
00020         boost::numeric::ublas::bounded_matrix<Scalar,2,4> _matrix;
00021 };
00022 
00023 
00024 /**
00025  * @brief Perspective transformation functor.
00026  * @param[in] t: the transformation 3x3 matrix
00027  * @param[in] src: 2D source point
00028  */
00029 template <typename F, typename F2>
00030 inline boost::gil::point2<F> transform( const PinningPerspective<F>& t, const boost::gil::point2<F2>& src )
00031 {
00032         using namespace boost::numeric::ublas;
00033         bounded_vector<F,3> pIn;
00034 
00035         F hCenter = ((0.5*t._height)/t._width); ///@todo tuttle: modify the matrix instead
00036 
00037         pIn[0] = (src.x / t._width) - 0.5;
00038         pIn[1] = (src.y / t._width) - hCenter;
00039         pIn[2] = 1.0;
00040 
00041         bounded_vector<F,3> pOut = prod( t._matrix, pIn );
00042 
00043         boost::gil::point2<F> res;
00044         res.x = pOut[0] / pOut[2];
00045         res.y = pOut[1] / pOut[2];
00046         //res.x = (t._matrix(0, 0) * pIn[0] + t._matrix(0, 1) * pIn[1] + t._matrix(0, 2)) / (t._matrix(2, 0) * pIn[0] + t._matrix(2, 1) * pIn[1] + t._matrix(2, 2));
00047         //res.y = (t._matrix(1, 0) * pIn[0] + t._matrix(1, 1) * pIn[1] + t._matrix(1, 2)) / (t._matrix(2, 0) * pIn[0] + t._matrix(2, 1) * pIn[1] + t._matrix(2, 2));
00048 
00049         res.x = (res.x + 0.5) * t._width;
00050         res.y = (res.y + hCenter) * t._width;
00051         
00052         return res;
00053 }
00054 
00055 /**
00056  * @brief Bilinear transformation functor.
00057  * @param[in] t: the transformation 2x4 matrix
00058  * @param[in] src: 2D source point
00059  *
00060  * @f[
00061  * x' = c[0,0]x + c[0,1]y + c[0,2]xy + c[0,3]
00062  * y' = c[1,0]x + c[1,1]y + c[1,2]xy + c[1,3]
00063  * @f]
00064  */
00065 template <typename F, typename F2>
00066 inline boost::gil::point2<F> transform( const PinningBilinear<F>& t, const boost::gil::point2<F2>& src )
00067 {
00068         boost::gil::point2<F> res;
00069 
00070         F hCenter = ((0.5*t._height)/t._width);
00071         boost::gil::point2<F> in( (src.x / t._width) - 0.5, (src.y / t._width) - hCenter );
00072 
00073         res.x = t._matrix(0, 0) * in.x + t._matrix(0, 1) * in.y + t._matrix(0, 2) * in.x * in.y + t._matrix(0, 3);
00074         res.y = t._matrix(1, 0) * in.x + t._matrix(1, 1) * in.y + t._matrix(1, 2) * in.x * in.y + t._matrix(1, 3);
00075 
00076         res.x = (res.x + 0.5) * t._width;
00077         res.y = (res.y + hCenter) * t._width;
00078         return res;
00079 }
00080 
00081 }
00082 }
00083 
00084 #endif
00085