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