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
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) {
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
00129
00130
00131
00132
00133
00134
00135
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
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);
00151 pPose.pose.position.z = 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);
00157 pPose.pose.position.z = -t.at<double>(1,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
00174
00175
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
00418 void matrixToQuaternion(const cv::Mat& mat, Eigen::Quaternion<double>& quat) {
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
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
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
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
00553
00554 if ((tr1 > tr2) && (tr1 > tr3)) {
00555 double S = sqrt(tr1) * 2.0;
00556
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;
00563
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;
00570
00571 qw = (m10 - m01) / S;
00572 qx = (m02 + m20) / S;
00573 qy = (m12 + m21) / S;
00574 qz = 0.25 * S;
00575 } else {
00576
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
00593
00594 quat.normalize();
00595
00596
00597 }
00598
00599 void quaternionToMatrix(const Eigen::Quaternion<double>& quat, cv::Mat& mat, bool handedness) {
00600
00601
00602
00603
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
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
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;
00646 int distMethod;
00647
00648
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();
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
00679
00680
00681
00682
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
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);
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
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