Transformations.cpp
Go to the documentation of this file.
00001 
00024 #include "Transformations.h"
00025 #include <opencv/cv.h>
00026 
00027 using namespace DUtilsCV;
00028 
00029 // ----------------------------------------------------------------------------
00030 
00031 cv::Mat Transformations::rotx(double theta, double X, double Y, double Z)
00032 {
00033   double c = cos(theta);
00034   double s = sin(theta);
00035   
00036   return (cv::Mat_<double>(4,4) <<
00037     1,  0,  0,  X,
00038     0,  c, -s,  Y,
00039     0,  s,  c,  Z,
00040     0,  0,  0,  1);
00041 }
00042 
00043 // ----------------------------------------------------------------------------
00044 
00045 cv::Mat Transformations::roty(double theta, double X, double Y, double Z)
00046 {
00047   double c = cos(theta);
00048   double s = sin(theta);
00049   
00050   return (cv::Mat_<double>(4,4) <<
00051     c,  0,  s,  X,
00052     0,  1,  0,  Y,
00053    -s,  0,  c,  Z,
00054     0,  0,  0,  1);
00055 }
00056 
00057 // ----------------------------------------------------------------------------
00058 
00059 cv::Mat Transformations::rotz(double theta, double X, double Y, double Z)
00060 {
00061   double c = cos(theta);
00062   double s = sin(theta);
00063   
00064   return (cv::Mat_<double>(4,4) <<
00065     c, -s,  0,  X,
00066     s,  c,  0,  Y,
00067     0,  0,  1,  Z,
00068     0,  0,  0,  1);
00069 }
00070 
00071 // ----------------------------------------------------------------------------
00072 
00073 cv::Mat Transformations::transl(double X, double Y, double Z)
00074 {
00075   return (cv::Mat_<double>(4,4) <<
00076     1, 0, 0, X,
00077     0, 1, 0, Y,
00078     0, 0, 1, Z,
00079     0, 0, 0, 1);
00080 }
00081 
00082 // ----------------------------------------------------------------------------
00083 
00084 cv::Mat Transformations::rotvec(const cv::Mat &axis, double theta)
00085 {
00086   double norm = cv::norm(axis);
00087   const cv::Mat ax = axis/norm;
00088   
00089   const double c = cos(theta);
00090   const double s = sin(theta);
00091   const double v = 1 - c;
00092     
00093   double r[3];
00094   if(ax.type() == CV_32F)
00095   {
00096     if(ax.rows > 1)
00097     {
00098       for(int i = 0; i < 3; ++i) r[i] = ax.at<float>(i,0);
00099     }else
00100     {
00101       for(int i = 0; i < 3; ++i) r[i] = ax.at<float>(0,i);
00102     }
00103   }else // assume double 
00104   {
00105     if(ax.rows > 1)
00106     {
00107       for(int i = 0; i < 3; ++i) r[i] = ax.at<double>(i,0);
00108     }else
00109     {
00110       for(int i = 0; i < 3; ++i) r[i] = ax.at<double>(0,i);
00111     }
00112   }
00113   
00114   const double xxv = r[0]*r[0]*v;
00115   const double xyv = r[0]*r[1]*v;
00116   const double xzv = r[0]*r[2]*v;
00117   const double yzv = r[1]*r[2]*v;
00118   
00119   const double yyv = r[1]*r[1]*v;
00120   const double zzv = r[2]*r[2]*v;
00121   
00122   const double xs = r[0]*s;
00123   const double ys = r[1]*s;
00124   const double zs = r[2]*s;
00125   
00126   return (cv::Mat_<double>(4,4) <<
00127     xxv+c,    xyv-zs,   xzv+ys,   0,
00128     xyv+zs,   yyv+c,    yzv-xs,   0,
00129     xzv-ys,   yzv+xs,   zzv+c,    0,
00130     0,        0,        0,        1);
00131 }
00132 
00133 // ----------------------------------------------------------------------------
00134 
00135 cv::Mat Transformations::inv(const cv::Mat &aTb)
00136 {
00137   // inv(T) = [R^t | -R^t p]
00138   const cv::Mat R = aTb.rowRange(0,3).colRange(0,3);
00139   const cv::Mat t = aTb.rowRange(0,3).colRange(3,4);
00140  
00141   cv::Mat Rt = R.t();
00142   cv::Mat t2 = -Rt*t;
00143   
00144   cv::Mat ret;
00145   if(aTb.type() == CV_32F)
00146   {
00147     ret = (cv::Mat_<float>(4,4) <<
00148       Rt.at<float>(0,0), Rt.at<float>(0,1), Rt.at<float>(0,2), t2.at<float>(0,0),
00149       Rt.at<float>(1,0), Rt.at<float>(1,1), Rt.at<float>(1,2), t2.at<float>(1,0),
00150       Rt.at<float>(2,0), Rt.at<float>(2,1), Rt.at<float>(2,2), t2.at<float>(2,0),
00151       0, 0, 0, 1);
00152   
00153   }else
00154   {
00155     ret = (cv::Mat_<double>(4,4) <<
00156       Rt.at<double>(0,0), Rt.at<double>(0,1), Rt.at<double>(0,2), t2.at<double>(0,0),
00157       Rt.at<double>(1,0), Rt.at<double>(1,1), Rt.at<double>(1,2), t2.at<double>(1,0),
00158       Rt.at<double>(2,0), Rt.at<double>(2,1), Rt.at<double>(2,2), t2.at<double>(2,0),
00159       0, 0, 0, 1);
00160   }
00161 
00162   return ret;
00163 }
00164 
00165 // ----------------------------------------------------------------------------
00166 
00167 cv::Mat Transformations::composeRt(const cv::Mat &r, const cv::Mat &t)
00168 {
00169   assert(r.type() == t.type());
00170   
00171   cv::Mat R;
00172   if(r.rows != 3 || r.cols != 3)
00173     cv::Rodrigues(r, R);
00174   else
00175     R = r;
00176 
00177   // normalization factor
00178   double vd = 1;
00179   if(t.rows > 3)
00180   {
00181     if(t.type() == CV_32F) vd = t.at<float>(3,0);
00182     else vd = t.at<double>(3,0);
00183   }
00184   else if(t.cols > 3)
00185   {
00186     if(t.type() == CV_32F) vd = t.at<float>(0,3);
00187     else vd = t.at<double>(0,3);
00188   }
00189 
00190   if(R.type() == CV_32F)
00191   {
00192     if(t.rows > 1)
00193     {    
00194       return (cv::Mat_<float>(4,4) << 
00195         R.at<float>(0,0), R.at<float>(0,1), R.at<float>(0,2), t.at<float>(0,0) / vd,
00196         R.at<float>(1,0), R.at<float>(1,1), R.at<float>(1,2), t.at<float>(1,0) / vd,
00197         R.at<float>(2,0), R.at<float>(2,1), R.at<float>(2,2), t.at<float>(2,0) / vd,
00198         0, 0, 0, 1
00199       );
00200     }
00201     else
00202     {
00203       return (cv::Mat_<float>(4,4) << 
00204         R.at<float>(0,0), R.at<float>(0,1), R.at<float>(0,2), t.at<float>(0,0) / vd,
00205         R.at<float>(1,0), R.at<float>(1,1), R.at<float>(1,2), t.at<float>(0,1) / vd,
00206         R.at<float>(2,0), R.at<float>(2,1), R.at<float>(2,2), t.at<float>(0,2) / vd,
00207         0, 0, 0, 1
00208       );
00209     }
00210   }
00211   else
00212   {
00213     if(t.rows > 1)
00214     {
00215       return (cv::Mat_<double>(4,4) << 
00216         R.at<double>(0,0), R.at<double>(0,1), R.at<double>(0,2), t.at<double>(0,0) / vd,
00217         R.at<double>(1,0), R.at<double>(1,1), R.at<double>(1,2), t.at<double>(1,0) / vd,
00218         R.at<double>(2,0), R.at<double>(2,1), R.at<double>(2,2), t.at<double>(2,0) / vd,
00219         0, 0, 0, 1
00220       );
00221     }
00222     else
00223     {
00224       return (cv::Mat_<double>(4,4) << 
00225         R.at<double>(0,0), R.at<double>(0,1), R.at<double>(0,2), t.at<double>(0,0),
00226         R.at<double>(1,0), R.at<double>(1,1), R.at<double>(1,2), t.at<double>(0,1),
00227         R.at<double>(2,0), R.at<double>(2,1), R.at<double>(2,2), t.at<double>(0,2),
00228         0, 0, 0, 1
00229       );
00230     }
00231   }
00232 }
00233 
00234 // ----------------------------------------------------------------------------
00235 
00236 void Transformations::decomposeRt(const cv::Mat &T, cv::Mat &R, cv::Mat &t)
00237 {
00238   R = T( cv::Range(0,3), cv::Range(0,3) );
00239   
00240   if(t.rows == 3 && t.cols == 1)
00241     t = T( cv::Range(0,3), cv::Range(3,4) );
00242   else
00243     t = T.col(3);
00244 }
00245 
00246 // ----------------------------------------------------------------------------
00247 


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:33:11