TuttleOFX
1
|
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