geometry.cpp
Go to the documentation of this file.
00001 
00005 #include "geometry.hpp"
00006 
00008 int minProjections(int pairs) {
00009         double retVal = ( -1.0 + pow(1.0 + 8.0 * double(pairs), 0.5) ) / 2.0;
00010         //printf("%s << retVal(%d) = (%f)\n", __FUNCTION__, pairs, retVal);
00011         return int(ceil(retVal+1.0));
00012 }
00013 
00015 int possiblePairs(int projections) {
00016         double retVal = 0.5 * double(std::max(((int)projections-1),0)) * ( double(std::max(((int)projections-1),0)) + 1 );
00017         return int(retVal);
00018 }
00019 
00020 void transformPoints(cv::vector<cv::Point3d>& pts, int *options) {
00021         
00022         int signs[3];
00023         
00024         signs[0] = (options[2] == 0) - (options[2] == 1);
00025         signs[1] = (options[3] == 0) - (options[3] == 1);
00026         signs[2] = (options[4] == 0) - (options[4] == 1);
00027         
00028         for (unsigned int iii = 0; iii < pts.size(); iii++) {
00029                 
00030                 double x, y, z;
00031                 
00032                 if (options[0] == 0) {
00033                         x = pts.at(iii).x;
00034                         
00035                         if (options[1] == 0) {
00036                                 y = pts.at(iii).y;
00037                                 z = pts.at(iii).z;
00038                         } else {
00039                                 y = pts.at(iii).z;
00040                                 z = pts.at(iii).y;
00041                         }
00042                         
00043                 } else if (options[0] == 1) {
00044                         x = pts.at(iii).y;
00045                         
00046                         if (options[1] == 0) {
00047                                 y = pts.at(iii).x;
00048                                 z = pts.at(iii).z;
00049                         } else {
00050                                 y = pts.at(iii).z;
00051                                 z = pts.at(iii).x;
00052                         }
00053                         
00054                 } else  {
00055                         
00056                         if (options[0] != 2) { printf("%s << ERROR!\n", __FUNCTION__); }
00057                         x = pts.at(iii).z;
00058                         
00059                         if (options[1] == 0) {
00060                                 y = pts.at(iii).x;
00061                                 z = pts.at(iii).y;
00062                         } else {
00063                                 y = pts.at(iii).y;
00064                                 z = pts.at(iii).x;
00065                         }
00066                         
00067                 }
00068                 
00069                 pts.at(iii).x = signs[0] * x;
00070                 pts.at(iii).y = signs[1] * y;
00071                 pts.at(iii).z = signs[2] * z;
00072                         
00073         }
00074         
00075 }
00076 
00077 void transformPoints(cv::vector<cv::Point3d>& pts, unsigned int option) {
00078         
00079         
00080         for (unsigned int iii = 0; iii < pts.size(); iii++) {
00081                 
00082                 double x, y, z;
00083                 x = pts.at(iii).x;
00084                 y = pts.at(iii).y;
00085                 z = pts.at(iii).z;
00086                 
00087                 if (option == 0) {
00088                         pts.at(iii).x = x;
00089                         pts.at(iii).y = -y;
00090                         pts.at(iii).z = z;
00091                 } else if (option == 1) {       // This one seems to match what you do to pose!
00092                         pts.at(iii).x = -y;
00093                         pts.at(iii).y = -z;
00094                         pts.at(iii).z = x;
00095                 } else if (option == 2) {
00096                         pts.at(iii).x = z;
00097                         pts.at(iii).y = -x;
00098                         pts.at(iii).z = y;
00099                 } else if (option == 3) {
00100                         pts.at(iii).x = y;
00101                         pts.at(iii).y = -z;
00102                         pts.at(iii).z = x;
00103                 } else if (option == 4) {
00104                         pts.at(iii).x = -y;
00105                         pts.at(iii).y = z;
00106                         pts.at(iii).z = x;
00107 
00108                 }
00109         }
00110         
00111 }
00112 
00113 void assignPose(geometry_msgs::PoseStamped& pPose, cv::Mat& C, int idx, ros::Time timestamp, int mode) {
00114         
00115         pPose.header.seq = idx;
00116         pPose.header.stamp = timestamp;
00117    
00118         cv::Mat R, t;
00119         Eigen::Quaterniond Q;
00120                 
00121         decomposeTransform(C, R, t);
00122         matrixToQuaternion(R, Q);
00123         
00124         if (mode == MAPPER_ASSIGN_MODE) {
00125                 QuaternionDbl Qrot;
00126                 
00127                 /*
00128                 Qrot.x() = 0;
00129                 Qrot.y() = -0.70711;
00130                 Qrot.z() = 0;
00131                 Qrot.w() = 0.70711;
00132                 
00133                 Q = Q * Qrot;
00134                 */
00135                 
00136         }
00137    
00138         // tried: 1,0,2; 1,2,0; 0,2,1; 2,0,1; 2,1,0; 0,1,2
00139         // x-corresponds to graph -x; y to graph -z; z to graph -y
00140         
00141         // TRIED: 
00142         // 2,-0,-1
00143         // 2, 0, 1 (better)
00144         // 2, 0,-1
00145         // 2,-0, 1
00146         // 0, 1, 2
00147    
00148         if (mode == MAPPER_ASSIGN_MODE) {
00149                 pPose.pose.position.x = t.at<double>(0,0); //;
00150                 pPose.pose.position.y = t.at<double>(1,0); //t.at<double>(1,0);
00151                 pPose.pose.position.z = t.at<double>(2,0); //t.at<double>(2,0);
00152         
00153         } else {
00154                 
00155                 pPose.pose.position.x = t.at<double>(2,0); //;
00156                 pPose.pose.position.y = -t.at<double>(0,0); //t.at<double>(1,0);
00157                 pPose.pose.position.z = -t.at<double>(1,0); //t.at<double>(2,0);
00158            
00159         }
00160    
00161         if (abs(pPose.pose.position.x) > MAX_RVIZ_DISPLACEMENT) {
00162                         pPose.pose.position.x = 0.0;
00163         }
00164 
00165         if (abs(pPose.pose.position.y) > MAX_RVIZ_DISPLACEMENT) {
00166                         pPose.pose.position.y = 0.0;
00167         }
00168    
00169         if (abs(pPose.pose.position.z) > MAX_RVIZ_DISPLACEMENT) {
00170                         pPose.pose.position.z = 0.0;
00171         }
00172    
00173         //printf("%s << QUAT = (%f, %f, %f, %f)", __FUNCTION__, Q.x(), Q.y(), Q.z(), Q.w());
00174    
00175         // tried x,y,z,w
00176         
00177         if (mode == MAPPER_ASSIGN_MODE) {
00178                 pPose.pose.orientation.x = Q.x();
00179                 pPose.pose.orientation.y = Q.y();
00180                 pPose.pose.orientation.z = Q.z();
00181                 pPose.pose.orientation.w = Q.w();
00182         } else {
00183                 pPose.pose.orientation.x = Q.z();
00184                 pPose.pose.orientation.y = -Q.x();
00185                 pPose.pose.orientation.z = -Q.y();
00186                 pPose.pose.orientation.w = Q.w();
00187         }
00188 }
00189 
00190 void convertRmatTo3frm(const cv::Mat& R_src, Matrix3frm& R_dst) {
00191         R_dst(0,0) = R_src.at<double>(0,0);
00192         R_dst(0,1) = R_src.at<double>(0,1);
00193         R_dst(0,2) = R_src.at<double>(0,2);
00194         
00195         R_dst(1,0) = R_src.at<double>(1,0);
00196         R_dst(1,1) = R_src.at<double>(1,1);
00197         R_dst(1,2) = R_src.at<double>(1,2);
00198         
00199         R_dst(2,0) = R_src.at<double>(2,0);
00200         R_dst(2,1) = R_src.at<double>(2,1);
00201         R_dst(2,2) = R_src.at<double>(2,2);
00202 }
00203 
00204 void convertTvecToEigenvec(const cv::Mat& T_src, Eigen::Vector3f& T_dst) {
00205         T_dst[0] = T_src.at<double>(0,0);
00206         T_dst[1] = T_src.at<double>(1,0);
00207         T_dst[2] = T_src.at<double>(2,0);
00208 }
00209 
00210 void convertEigenvecToTvec(const Eigen::Vector3f& T_src, cv::Mat& T_dst) {
00211         T_dst = cv::Mat::zeros(3,1,CV_64FC1);
00212         
00213         T_dst.at<double>(0,0) = T_src[0];
00214         T_dst.at<double>(1,0) = T_src[1];
00215         T_dst.at<double>(2,0) = T_src[2];
00216 }
00217 
00218 void convert3frmToRmat(const Matrix3frm& R_src, cv::Mat& R_dst) {
00219         R_dst = cv::Mat::eye(3,3,CV_64FC1);
00220         
00221         R_dst.at<double>(0,0) = R_src(0,0);
00222         R_dst.at<double>(0,1) = R_src(0,1);
00223         R_dst.at<double>(0,2) = R_src(0,2);
00224         
00225         R_dst.at<double>(1,0) = R_src(1,0);
00226         R_dst.at<double>(1,1) = R_src(1,1);
00227         R_dst.at<double>(1,2) = R_src(1,2);
00228         
00229         R_dst.at<double>(2,0) = R_src(2,0);
00230         R_dst.at<double>(2,1) = R_src(2,1);
00231         R_dst.at<double>(2,2) = R_src(2,2);
00232 }
00233 
00234 void projectionToTransformation(const cv::Mat& proj, cv::Mat& trans) {
00235         trans = cv::Mat::eye(4, 4, CV_64FC1);
00236         
00237         trans.at<double>(0,0) = proj.at<double>(0,0);
00238         trans.at<double>(0,1) = proj.at<double>(0,1);
00239         trans.at<double>(0,2) = proj.at<double>(0,2);
00240         trans.at<double>(0,3) = proj.at<double>(0,3);
00241         
00242         trans.at<double>(1,0) = proj.at<double>(1,0);
00243         trans.at<double>(1,1) = proj.at<double>(1,1);
00244         trans.at<double>(1,2) = proj.at<double>(1,2);
00245         trans.at<double>(1,3) = proj.at<double>(1,3);
00246         
00247         trans.at<double>(2,0) = proj.at<double>(2,0);
00248         trans.at<double>(2,1) = proj.at<double>(2,1);
00249         trans.at<double>(2,2) = proj.at<double>(2,2);
00250         trans.at<double>(2,3) = proj.at<double>(2,3);
00251         
00252         trans.at<double>(3,0) = 0.0;
00253         trans.at<double>(3,1) = 0.0;
00254         trans.at<double>(3,2) = 0.0;
00255         trans.at<double>(3,3) = 1.0;
00256         
00257 }
00258 
00259 void transformationToProjection(const cv::Mat& trans, cv::Mat& proj) {
00260         proj = cv::Mat::zeros(3, 4, CV_64FC1);
00261         
00262         proj.at<double>(0,0) = trans.at<double>(0,0);
00263         proj.at<double>(0,1) = trans.at<double>(0,1);
00264         proj.at<double>(0,2) = trans.at<double>(0,2);
00265         proj.at<double>(0,3) = trans.at<double>(0,3);
00266         
00267         proj.at<double>(1,0) = trans.at<double>(1,0);
00268         proj.at<double>(1,1) = trans.at<double>(1,1);
00269         proj.at<double>(1,2) = trans.at<double>(1,2);
00270         proj.at<double>(1,3) = trans.at<double>(1,3);
00271         
00272         proj.at<double>(2,0) = trans.at<double>(2,0);
00273         proj.at<double>(2,1) = trans.at<double>(2,1);
00274         proj.at<double>(2,2) = trans.at<double>(2,2);
00275         proj.at<double>(2,3) = trans.at<double>(2,3);
00276                 
00277 }
00278 
00279 void projectionToRotation(const cv::Mat& src, cv::Mat& dst) {
00280         dst = cv::Mat(3, 3, CV_64FC1);
00281         
00282         dst.at<double>(0,0) = src.at<double>(0,0);
00283         dst.at<double>(0,1) = src.at<double>(0,1);
00284         dst.at<double>(0,2) = src.at<double>(0,2);
00285 
00286         dst.at<double>(1,0) = src.at<double>(1,0);
00287         dst.at<double>(1,1) = src.at<double>(1,1);
00288         dst.at<double>(1,2) = src.at<double>(1,2);
00289         
00290         dst.at<double>(2,0) = src.at<double>(2,0);
00291         dst.at<double>(2,1) = src.at<double>(2,1);
00292         dst.at<double>(2,2) = src.at<double>(2,2);
00293         
00294 }
00295 
00296 void rotationToProjection(const cv::Mat& src, cv::Mat& dst) {
00297         dst = cv::Mat(3, 4, CV_64FC1);
00298         
00299         dst.at<double>(0,0) = src.at<double>(0,0);
00300         dst.at<double>(0,1) = src.at<double>(0,1);
00301         dst.at<double>(0,2) = src.at<double>(0,2);
00302         
00303         dst.at<double>(1,0) = src.at<double>(1,0);
00304         dst.at<double>(1,1) = src.at<double>(1,1);
00305         dst.at<double>(1,2) = src.at<double>(1,2);
00306         
00307         dst.at<double>(2,0) = src.at<double>(2,0);
00308         dst.at<double>(2,1) = src.at<double>(2,1);
00309         dst.at<double>(2,2) = src.at<double>(2,2);
00310         
00311         dst.at<double>(0,3) = 0.0;      
00312         dst.at<double>(1,3) = 0.0;
00313         dst.at<double>(2,3) = 0.0;
00314         
00315 }
00316 
00317 void convertPoseFormat(const cv::Mat& t, const Eigen::Quaternion<double>& Q, geometry_msgs::Pose& pose) {
00318         
00319         pose.position.x = t.at<double>(0,0);
00320         pose.position.y = t.at<double>(1,0);
00321         pose.position.z = t.at<double>(2,0);
00322         
00323         pose.orientation.w = Q.w();
00324         pose.orientation.x = Q.x();
00325         pose.orientation.y = Q.y();
00326         pose.orientation.z = Q.z();
00327         
00328 }
00329 
00330 void convertPoseFormat(const geometry_msgs::Pose& pose, cv::Mat& t, Eigen::Quaternion<double>& Q) {
00331         
00332         t = cv::Mat(3,1, CV_64FC1);
00333         
00334         t.at<double>(0,0) = pose.position.x;
00335         t.at<double>(1,0) = pose.position.y;
00336         t.at<double>(2,0) = pose.position.z;
00337         
00338         Q = Eigen::Quaternion<double>(pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z);
00339         
00340 }
00341 
00342 void convertAndShiftPoseFormat(const geometry_msgs::Pose& pose, cv::Mat& t, Eigen::Quaternion<double>& Q) {
00343         
00344         t = cv::Mat(3,1, CV_64FC1);
00345         
00346         t.at<double>(2,0) = pose.position.x;
00347         t.at<double>(0,0) = -pose.position.y;
00348         t.at<double>(1,0) = -pose.position.z;
00349         
00350         Q = Eigen::Quaternion<double>(pose.orientation.w, pose.orientation.x, -pose.orientation.y, -pose.orientation.z);
00351         
00352 }
00353 
00354 void convertAndShiftPoseFormat(const cv::Mat& t, const Eigen::Quaternion<double>& Q, geometry_msgs::Pose& pose) {
00355         
00356         pose.position.x = t.at<double>(2,0);
00357         pose.position.y = -t.at<double>(0,0);
00358         pose.position.z = -t.at<double>(1,0);
00359         
00360         pose.orientation.x = Q.z();
00361         pose.orientation.y = -Q.x();
00362         pose.orientation.z = -Q.y();
00363         pose.orientation.w = Q.w();
00364         
00365 }
00366 
00367 void composeTransform(const cv::Mat& R, const cv::Mat& t, cv::Mat& c) {
00368         
00369         c = cv::Mat::zeros(4, 4, CV_64FC1);
00370         
00371         c.at<double>(0,0) = R.at<double>(0,0);
00372         c.at<double>(0,1) = R.at<double>(0,1);
00373         c.at<double>(0,2) = R.at<double>(0,2);
00374 
00375         c.at<double>(1,0) = R.at<double>(1,0);
00376         c.at<double>(1,1) = R.at<double>(1,1);
00377         c.at<double>(1,2) = R.at<double>(1,2);
00378 
00379         c.at<double>(2,0) = R.at<double>(2,0);
00380         c.at<double>(2,1) = R.at<double>(2,1);
00381         c.at<double>(2,2) = R.at<double>(2,2);
00382 
00383         c.at<double>(0,3) = t.at<double>(0,0);
00384         c.at<double>(1,3) = t.at<double>(1,0);
00385         c.at<double>(2,3) = t.at<double>(2,0);
00386         
00387         c.at<double>(3,0) = 0.0;
00388         c.at<double>(3,1) = 0.0;
00389         c.at<double>(3,2) = 0.0;
00390         c.at<double>(3,3) = 1.0;
00391 }
00392 
00393 void decomposeTransform(const cv::Mat& c, cv::Mat& R, cv::Mat& t) {
00394         
00395         R = cv::Mat::zeros(3, 3, CV_64FC1);
00396         t = cv::Mat::zeros(3, 1, CV_64FC1);
00397 
00398         R.at<double>(0,0) = c.at<double>(0,0);
00399         R.at<double>(0,1) = c.at<double>(0,1);
00400         R.at<double>(0,2) = c.at<double>(0,2);
00401 
00402         R.at<double>(1,0) = c.at<double>(1,0);
00403         R.at<double>(1,1) = c.at<double>(1,1);
00404         R.at<double>(1,2) = c.at<double>(1,2);
00405 
00406         R.at<double>(2,0) = c.at<double>(2,0);
00407         R.at<double>(2,1) = c.at<double>(2,1);
00408         R.at<double>(2,2) = c.at<double>(2,2);
00409 
00410         t.at<double>(0,0) = c.at<double>(0,3);
00411         t.at<double>(1,0) = c.at<double>(1,3);
00412         t.at<double>(2,0) = c.at<double>(2,3);
00413 
00414 }
00415 
00416 
00417 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ethan.htm
00418 void matrixToQuaternion(const cv::Mat& mat, Eigen::Quaternion<double>& quat) {
00419 
00420         // convert mat to Eigen::Matrix3d m;
00421         /*
00422         Eigen::Matrix3d m;
00423 
00424         m(0,0) = mat.at<double>(0,0);
00425         m(0,1) = mat.at<double>(0,1);
00426         m(0,2) = mat.at<double>(0,2);
00427 
00428         m(1,0) = mat.at<double>(1,0);
00429         m(1,1) = mat.at<double>(1,1);
00430         m(1,2) = mat.at<double>(1,2);
00431 
00432         m(2,0) = mat.at<double>(2,0);
00433         m(2,1) = mat.at<double>(2,1);
00434         m(2,2) = mat.at<double>(2,2);
00435 
00436         quat = Quaterniond(m);
00437 
00438         quat.normalize();
00439 
00440         return;
00441         */
00442         // printf("%s << Entered...\n", __FUNCTION__);
00443 
00444         double m00 = mat.at<double>(0,0);
00445         double m01 = mat.at<double>(0,1);
00446         double m02 = mat.at<double>(0,2);
00447 
00448         double m10 = mat.at<double>(1,0);
00449         double m11 = mat.at<double>(1,1);
00450         double m12 = mat.at<double>(1,2);
00451 
00452         double m20 = mat.at<double>(2,0);
00453         double m21 = mat.at<double>(2,1);
00454         double m22 = mat.at<double>(2,2);
00455 
00456         double qw, qx, qy, qz;
00457 
00458 
00459         // ALT 3
00460         // J.M.P. van Waveren
00461         /*
00462         float m[9], q[4];
00463         m[0] = m00; m[1] = m01; m[2] = m02;
00464         m[3] = m10; m[4] = m11; m[5] = m12;
00465         m[6] = m20; m[7] = m21; m[8] = m22;
00466 
00467         //const float *m = jointMats[i].mat;
00468         if ( m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] > 0.0f ) {
00469         float t = + m[0 * 4 + 0] + m[1 * 4 + 1] + m[2 * 4 + 2] + 1.0f;
00470         float s = ReciprocalSqrt( t ) * 0.5f;
00471         q[3] = s * t;
00472         q[2] = ( m[0 * 4 + 1] - m[1 * 4 + 0] ) * s;
00473         q[1] = ( m[2 * 4 + 0] - m[0 * 4 + 2] ) * s;
00474         q[0] = ( m[1 * 4 + 2] - m[2 * 4 + 1] ) * s;
00475         } else if ( m[0 * 4 + 0] > m[1 * 4 + 1] && m[0 * 4 + 0] > m[2 * 4 + 2] ) {
00476         float t = + m[0 * 4 + 0] - m[1 * 4 + 1] - m[2 * 4 + 2] + 1.0f;
00477         float s = ReciprocalSqrt( t ) * 0.5f;
00478         q[0] = s * t;
00479         q[1] = ( m[0 * 4 + 1] + m[1 * 4 + 0] ) * s;
00480         q[2] = ( m[2 * 4 + 0] + m[0 * 4 + 2] ) * s;
00481         q[3] = ( m[1 * 4 + 2] - m[2 * 4 + 1] ) * s;
00482         } else if ( m[1 * 4 + 1] > m[2 * 4 + 2] ) {
00483         float t = - m[0 * 4 + 0] + m[1 * 4 + 1] - m[2 * 4 + 2] + 1.0f;
00484         float s = ReciprocalSqrt( t ) * 0.5f;
00485         q[1] = s * t;
00486         q[0] = ( m[0 * 4 + 1] + m[1 * 4 + 0] ) * s;
00487         q[3] = ( m[2 * 4 + 0] - m[0 * 4 + 2] ) * s;
00488         q[2] = ( m[1 * 4 + 2] + m[2 * 4 + 1] ) * s;
00489         } else {
00490         float t = - m[0 * 4 + 0] - m[1 * 4 + 1] + m[2 * 4 + 2] + 1.0f;
00491         float s = ReciprocalSqrt( t ) * 0.5f;
00492         q[2] = s * t;
00493         q[3] = ( m[0 * 4 + 1] - m[1 * 4 + 0] ) * s;
00494         q[0] = ( m[2 * 4 + 0] + m[0 * 4 + 2] ) * s;
00495         q[1] = ( m[1 * 4 + 2] + m[2 * 4 + 1] ) * s;
00496         }
00497 
00498         qx = (double) q[0];
00499         qy = (double) q[1];
00500         qz = (double) q[2];
00501         qw = (double) q[3];
00502         */
00503 
00504         // ALT 2
00505         // http://www.koders.com/cpp/fid38F83F165ABF728D6046FD59CF21ECF65E30E2D4.aspx
00506         /*
00507         double tmp = abs(m00 + m11 + m22 + 1);
00508         double s = sqrt(tmp);
00509 
00510         if (s > 0.0001) {
00511         qx = (m21 - m12) / 4*s;
00512         qy = (m02 - m20) / 4*s;
00513         qx = (m10 - m01) / 4*s;
00514         } else {
00515         int s_iNext[3] = { 2, 3, 1 };
00516         int i = 1;
00517         if ( m11 > m00 ) {
00518         i = 2;
00519         }
00520 
00521         if ( m22 > m11 ) {
00522         i = 3;
00523         }
00524 
00525         int j = s_iNext[i-1];
00526         int k = s_iNext[j-1];
00527 
00528         double fRoot = sqrt(mat.at<double>(i-1,i-1) - mat.at<double>(j-1,j-1) - mat.at<double>(k-1,k-1) + 1.0);
00529 
00530         double *tmp[3] = { &qx, &qy, &qz };
00531         *tmp[i-1] = 0.5 * fRoot;
00532         s = (mat.at<double>(k-1,j-1)-mat.at<double>(j-1,k-1))*fRoot;
00533         *tmp[j-1] = (mat.at<double>(j-1,i-1)+mat.at<double>(i-1,j-1))*fRoot;
00534         *tmp[k-1] = (mat.at<double>(k-1,i-1)+mat.at<double>(i-1,k-1))*fRoot;
00535         }
00536 
00537         if ((qx*qx + qy*qy + qz*qz) != 1.0) {
00538         qw = sqrt(1 - qx*qx - qy*qy - qz*qz);
00539         } else {
00540         qw = 0.0;
00541         }
00542         */
00543 
00544         // ALT 1
00545 
00546         double tr1 = 1.0 + m00 - m11 - m22;
00547         double tr2 = 1.0 - m00 + m11 - m22;
00548         double tr3 = 1.0 - m00 - m11 + m22;
00549 
00550 
00551 
00552         //printf("%s << tr1, tr2, tr3 = (%f, %f, %f)\n", __FUNCTION__, tr1, tr2, tr3);
00553 
00554         if ((tr1 > tr2) && (tr1 > tr3)) {
00555         double S = sqrt(tr1) * 2.0; // S=4*qx
00556         //printf("%s << Case 1: %f\n", __FUNCTION__, S);
00557         qw = (m21 - m12) / S;
00558         qx = 0.25 * S;
00559         qy = (m01 + m10) / S;
00560         qz = (m02 + m20) / S;
00561         } else if ((tr2 > tr1) && (tr2 > tr3)) {
00562         double S = sqrt(tr2) * 2.0; // S=4*qy
00563         //printf("%s << Case 2: %f\n", __FUNCTION__, S);
00564         qw = (m02 - m20) / S;
00565         qx = (m01 + m10) / S;
00566         qy = 0.25 * S;
00567         qz = (m12 + m21) / S;
00568         } else if ((tr3 > tr1) && (tr3 > tr2)) {
00569         double S = sqrt(tr3) * 2.0; // S=4*qz
00570         //printf("%s << Case 3: %f\n", __FUNCTION__, S);
00571         qw = (m10 - m01) / S;
00572         qx = (m02 + m20) / S;
00573         qy = (m12 + m21) / S;
00574         qz = 0.25 * S;
00575         } else {
00576         //printf("%s << Case 4\n", __FUNCTION__);
00577         qw = 1.0;
00578         qx = 0.0;
00579         qy = 0.0;
00580         qz = 0.0;
00581         }
00582 
00583         
00584 
00585 
00586 
00587         quat.x() = qx;
00588         quat.y() = qy;
00589         quat.z() = qz;
00590         quat.w() = qw;
00591 
00592         //printf("%s << Quat = (%f, %f, %f, %f)\n", __FUNCTION__, qx, qy, qz, qw);
00593 
00594         quat.normalize();
00595 
00596         //printf("%s << Completed.\n", __FUNCTION__);
00597 }
00598 
00599 void quaternionToMatrix(const Eigen::Quaternion<double>& quat, cv::Mat& mat, bool handedness) {
00600         
00601         //QuaternionDbl eQuat;
00602         
00603         // eQuat.w()
00604 
00605         Eigen::Matrix3d eMat = quat.matrix();
00606         
00607         mat = cv::Mat::zeros(3, 3, CV_64FC1);
00608         
00609         if (handedness) {
00610                 mat.at<double>(0,0) = eMat(0,0);
00611                 mat.at<double>(0,1) = eMat(0,2);
00612                 mat.at<double>(0,2) = eMat(0,1);
00613                 
00614                 mat.at<double>(1,0) = eMat(2,0);
00615                 mat.at<double>(1,1) = eMat(2,2);
00616                 mat.at<double>(1,2) = eMat(2,1);
00617                 
00618                 mat.at<double>(2,0) = eMat(1,0);
00619                 mat.at<double>(2,1) = eMat(1,2);
00620                 mat.at<double>(2,2) = eMat(1,1);
00621         } else {
00622                 // Original
00623                 mat.at<double>(0,0) = eMat(0,0);
00624                 mat.at<double>(0,1) = eMat(0,1);
00625                 mat.at<double>(0,2) = eMat(0,2);
00626                 
00627                 mat.at<double>(1,0) = eMat(1,0);
00628                 mat.at<double>(1,1) = eMat(1,1);
00629                 mat.at<double>(1,2) = eMat(1,2);
00630                 
00631                 mat.at<double>(2,0) = eMat(2,0);
00632                 mat.at<double>(2,1) = eMat(2,1);
00633                 mat.at<double>(2,2) = eMat(2,2);
00634         }
00635         
00636         
00637         // Quaternion.toRotationMatrix()
00638 
00639 }
00640 
00641 double normalizedGRICdifference(std::vector<cv::Point2f>& pts1, std::vector<cv::Point2f>& pts2, cv::Mat& F, cv::Mat& H, cv::Mat& mask_F, cv::Mat& mask_H, double& F_GRIC, double& H_GRIC) {
00642         
00643         int d, k;
00644         double lambda_3 = 2.00;
00645         double r = 4.00;        // assuming always with 2-frames
00646         int distMethod;
00647         
00648         // determine d & k
00649         d = 2;
00650         k = 8;
00651         distMethod = LOURAKIS_DISTANCE;
00652         H_GRIC = calculateGRIC(pts1, pts2, H, mask_H, d, k, r, lambda_3, distMethod);
00653         
00654         d = 3;
00655         k = 7;
00656         distMethod = SAMPSON_DISTANCE;
00657         F_GRIC = calculateGRIC(pts1, pts2, F, mask_F, d, k, r, lambda_3, distMethod);
00658         
00659         double retVal = abs(F_GRIC - H_GRIC) / H_GRIC;
00660         
00661         return retVal;
00662         
00663         
00664 }
00665 
00666 double calculateGRIC(std::vector<cv::Point2f>& pts1, std::vector<cv::Point2f>& pts2, cv::Mat& rel, cv::Mat& mask, int d, double k, double r, double lambda_3, int distMethod) {
00667         
00668         double retVal = 0.00;
00669 
00670         int n = pts1.size(); // countNonZero(mask);
00671         
00672         double lambda_1 = log(r);
00673         double lambda_2 = log(r*((double)n));
00674         
00675         double *e_vals;
00676         e_vals = new double[n];
00677         
00678         // gotta calculate sig and e
00679         
00680         // they calculate 'e' using:
00681         //              for F: point to epipolar line cost
00682         //              for H: symmetric transfer error
00683         
00684         double e_mean = 0.00, sig = 0.00;
00685         
00686         for (unsigned int iii = 0; iii < pts1.size(); iii++) {
00687                 
00688                 e_vals[iii] = calcGeometryDistance(pts1.at(iii), pts2.at(iii), rel, distMethod);
00689                 e_mean += e_vals[iii] / ((double) n);
00690                 
00691         }
00692         
00693         // Calculate variance
00694         
00695         for (unsigned int iii = 0; iii < pts1.size(); iii++) {
00696                 sig += pow((e_vals[iii] - e_mean), 2.0) / ((double) n);
00697         }
00698         
00699         for (unsigned int iii = 0; iii < pts1.size(); iii++) {
00700                 retVal += calculateRho(e_vals[iii], sig, r, lambda_3, d);
00701         }
00702         
00703         retVal +=  lambda_1*((double) d)*n + lambda_2*((double) k);
00704 
00705         return retVal;
00706         
00707 }
00708 
00709 double calculateRho(double e, double sig, double r, double lambda_3, int d) {
00710         
00711         double val1 = pow(e, 2.0) / pow(sig, 2.0);
00712         double val2 = lambda_3 * (r - ((double) d));
00713         
00714         return std::min(val1, val2);
00715         
00716 }
00717 
00718 double calcGeometryDistance(cv::Point2f& pt1, cv::Point2f& pt2, cv::Mat& mat, int distMethod) {
00719         
00720         cv::Mat p1, p2;
00721         p1 = cv::Mat::ones(3,1,CV_64FC1);
00722         p2 = cv::Mat::ones(3,1,CV_64FC1);
00723         
00724         p1.at<double>(0,0) = (double) pt1.x;
00725         p1.at<double>(1,0) = (double) pt1.y;
00726         
00727         p2.at<double>(0,0) = (double) pt2.x;
00728         p2.at<double>(1,0) = (double) pt2.y;
00729         
00730         cv::Mat p2t;
00731         transpose(p2, p2t);
00732         
00733         double dist = 0.0;
00734         
00735         double ri;
00736         
00737         cv::Mat A;
00738         
00739         A = p2t * mat * p1; 
00740         ri = A.at<double>(0,0); 
00741         
00742         double r = abs(ri);     // not sure if this is correct and/or needed
00743                         
00744         double rx, ry, rxd, ryd;
00745         
00746         rx = mat.at<double>(0,0) * pt2.x + mat.at<double>(1,0) * pt2.y + mat.at<double>(2,0);
00747         ry = mat.at<double>(0,1) * pt2.x + mat.at<double>(1,1) * pt2.y + mat.at<double>(2,1);
00748         rxd = mat.at<double>(0,0) * pt1.x + mat.at<double>(0,1) * pt1.y + mat.at<double>(0,2);
00749         ryd = mat.at<double>(1,0) * pt1.x + mat.at<double>(1,1) * pt1.y + mat.at<double>(1,2);
00750         
00751         double e1, e2;
00752         
00753         e1 = r / pow( pow(rx, 2.0) + pow(ry, 2.0) , 0.5);
00754         e2 = r / pow( pow(rxd, 2.0) + pow(ryd, 2.0) , 0.5);
00755         
00756         double de;
00757         
00758         de = pow(pow(e1, 2.0) + pow(e2, 2.0), 0.5);
00759         
00760         double ds;
00761         
00762         ds = r * pow((1 / (pow(rx, 2.0) + pow(ry, 2.0) + pow(rxd, 2.0) + pow(ryd, 2.0))), 0.5);
00763         
00764         switch (distMethod) {
00765                 case SAMPSON_DISTANCE:
00766                         dist = ds;
00767                         break;
00768                 case ALGEBRAIC_DISTANCE: 
00769                         dist = r;
00770                         break;
00771                 case EPIPOLAR_DISTANCE:
00772                         dist = de;
00773                         break;
00774                 case LOURAKIS_DISTANCE:
00775                         dist = lourakisSampsonError(pt1, pt2, mat);
00776                         break;
00777                 default:
00778                         break;
00779         }
00780         
00781         return dist;
00782 }
00783 
00784 // http://www.ics.forth.gr/~lourakis/homest/
00785 double lourakisSampsonError(cv::Point2f& pt1, cv::Point2f& pt2, cv::Mat& H) {
00786         
00787         double error = 0.0;
00788         
00789         double t1, t10, t100, t104, t108, t112, t118, t12, t122, t125, t126, t129, t13, t139, t14, t141, t144, t15, t150, t153, t161, t167, t17, t174, t18, t19, t193, t199;
00790         double t2, t20, t201, t202, t21, t213, t219, t22, t220, t222, t225, t23, t236, t24, t243, t250, t253, t26, t260, t27, t271, t273, t28, t29, t296;
00791         double t3, t30, t303, t31, t317, t33, t331, t335, t339, t34, t342, t345, t35, t350, t354, t36, t361, t365, t37, t374, t39;
00792         double t4, t40, t41, t42, t43, t44, t45, t46, t47, t49, t51, t57;
00793         double t6, t65, t66, t68, t69;
00794         double t7, t72, t78;
00795         double t8, t86, t87, t90, t95;
00796         
00797         double h[9];
00798         
00799         for (int iii = 0; iii < 3; iii++) {
00800                 for (int jjj = 0; jjj < 3; jjj++) {
00801                         h[3*iii + jjj] = H.at<double>(iii,jjj);
00802                 }
00803         }
00804         
00805         double m1[2], m2[2];
00806         
00807         m1[0] = (double) pt1.x;
00808         m1[1] = (double) pt1.y;
00809         m2[0] = (double) pt2.x;
00810         m2[1] = (double) pt2.y;
00811         
00812         t1 = m2[0];
00813         t2 = h[6];
00814         t3 = t2*t1;
00815         t4 = m1[0];
00816         t6 = h[7];
00817         t7 = t1*t6;
00818         t8 = m1[1];
00819         t10 = h[8];
00820         t12 = h[0];
00821         t13 = t12*t4;
00822         t14 = h[1];
00823         t15 = t14*t8;
00824         t17 = t3*t4+t7*t8+t1*t10-t13-t15-h[2];
00825         t18 = m2[1];
00826         t19 = t18*t18;
00827         t20 = t2*t2;
00828         t21 = t19*t20;
00829         t22 = t18*t2;
00830         t23 = h[3];
00831         t24 = t23*t22;
00832         t26 = t23*t23;
00833         t27 = t6*t6;
00834         t28 = t19*t27;
00835         t29 = t18*t6;
00836         t30 = h[4];
00837         t31 = t29*t30;
00838         t33 = t30*t30;
00839         t34 = t4*t4;
00840         t35 = t20*t34;
00841         t36 = t2*t4;
00842         t37 = t6*t8;
00843         t39 = 2.0*t36*t37;
00844         t40 = t36*t10;
00845         t41 = 2.0*t40;
00846         t42 = t8*t8;
00847         t43 = t42*t27;
00848         t44 = t37*t10;
00849         t45 = 2.0*t44;
00850         t46 = t10*t10;
00851         t47 = t21-2.0*t24+t26+t28-2.0*t31+t33+t35+t39+t41+t43+t45+t46;
00852         t49 = t12*t12;
00853         t51 = t6*t30;
00854         t57 = t20*t2;
00855         t65 = t1*t1;
00856         t66 = t65*t20;
00857         t68 = t65*t57;
00858         t69 = t4*t10;
00859         t72 = t2*t49;
00860         t78 = t27*t6;
00861         t86 = t65*t78;
00862         t87 = t8*t10;
00863         t90 = t65*t27;
00864         t95 = -2.0*t49*t18*t51-2.0*t3*t12*t46-2.0*t1*t57*t12*t34-2.0*t3*t12*t33+t66
00865         *t43+2.0*t68*t69+2.0*t72*t69-2.0*t7*t14*t46-2.0*t1*t78*t14*t42-2.0*t7*t14*t26+
00866         2.0*t86*t87+t90*t35+2.0*t49*t6*t87;
00867         t100 = t14*t14;
00868         t104 = t100*t2;
00869         t108 = t2*t23;
00870         t112 = t78*t42*t8;
00871         t118 = t57*t34*t4;
00872         t122 = t10*t26;
00873         t125 = t57*t4;
00874         t126 = t10*t19;
00875         t129 = t78*t8;
00876         t139 = -2.0*t57*t34*t18*t23+2.0*t100*t6*t87+2.0*t104*t69-2.0*t100*t18*t108+
00877         4.0*t36*t112+6.0*t43*t35+4.0*t118*t37+t35*t28+2.0*t36*t122+2.0*t125*t126+2.0*
00878         t129*t126+2.0*t37*t122-2.0*t78*t42*t18*t30+t43*t21;
00879         t141 = t10*t33;
00880         t144 = t46*t18;
00881         t150 = t46*t19;
00882         t153 = t46*t10;
00883         t161 = t27*t27;
00884         t167 = 2.0*t36*t141-2.0*t144*t108+2.0*t37*t141+t66*t33+t150*t27+t150*t20+
00885         4.0*t37*t153+6.0*t43*t46+4.0*t112*t10+t43*t33+t161*t42*t19+t43*t26+4.0*t36*t153
00886         ;
00887         t174 = t20*t20;
00888         t193 = 6.0*t35*t46+4.0*t10*t118+t35*t33+t35*t26+t174*t34*t19+t100*t27*t42+
00889         t100*t20*t34+t100*t19*t20+t90*t46+t65*t161*t42+t90*t26+t49*t27*t42+t49*t20*t34+
00890         t49*t19*t27;
00891         t199 = t34*t34;
00892         t201 = t12*t23;
00893         t202 = t14*t30;
00894         t213 = t42*t42;
00895         t219 = t66*t46+t100*t26+t46*t100+t174*t199-2.0*t201*t202-2.0*t144*t51+t46*
00896         t26+t65*t174*t34+t49*t33+t49*t46+t46*t33+t161*t213-2.0*t7*t14*t20*t34;
00897         t220 = t1*t27;
00898         t222 = t36*t8;
00899         t225 = t7*t14;
00900         t236 = t4*t6*t8;
00901         t243 = t3*t12;
00902         t250 = t46*t46;
00903         t253 = t1*t20;
00904         t260 = -4.0*t220*t14*t222-4.0*t225*t40-4.0*t220*t15*t10+2.0*t90*t40+2.0*
00905         t225*t24+2.0*t72*t236-2.0*t3*t12*t27*t42-4.0*t243*t44+2.0*t66*t44+2.0*t243*t31+
00906         t250+2.0*t68*t236-4.0*t253*t12*t236-4.0*t253*t13*t10;
00907         t271 = t4*t20;
00908         t273 = t8*t18;
00909         t296 = t10*t18;
00910         t303 = 2.0*t104*t236-2.0*t35*t31+12.0*t35*t44+2.0*t125*t37*t19-4.0*t271*t6*
00911         t273*t23+2.0*t36*t37*t26+2.0*t36*t129*t19-4.0*t36*t27*t273*t30+2.0*t36*t37*t33+
00912         12.0*t36*t43*t10+12.0*t36*t37*t46-4.0*t271*t296*t23+2.0*t36*t126*t27;
00913         t317 = t18*t14;
00914         t331 = t14*t2;
00915         t335 = t12*t18;
00916         t339 = t220*t18;
00917         t342 = t7*t30;
00918         t345 = t317*t6;
00919         t350 = -4.0*t31*t40-2.0*t43*t24+2.0*t37*t126*t20-4.0*t44*t24-4.0*t27*t8*
00920         t296*t30-2.0*t253*t317*t30-2.0*t65*t2*t23*t6*t30+2.0*t3*t23*t14*t30-2.0*t12*t19
00921         *t331*t6+2.0*t335*t331*t30-2.0*t201*t339+2.0*t201*t342+2.0*t201*t345+2.0*t86*
00922         t222;
00923         t354 = 1/(t95+t139+t167+t193+t219+t260+t303+t350);
00924         t361 = t22*t4+t29*t8+t296-t23*t4-t30*t8-h[5];
00925         t365 = t253*t18-t3*t23-t335*t2+t201+t339-t342-t345+t202;
00926         t374 = t66-2.0*t243+t49+t90-2.0*t225+t100+t35+t39+t41+t43+t45+t46;
00927 
00928         error = sqrt((t17*t47*t354-t361*t365*t354)*t17+(-t17*t365*t354+t361*t374*
00929         t354)*t361);
00930 
00931         return error;
00932 }       
00933         
00934         


thermalvis
Author(s): Stephen Vidas
autogenerated on Sun Jan 5 2014 11:38:45