60 #include <mrpt/otherlibs/do_opencv_includes.h>    63 #include <mrpt/config.h>    64 #if MRPT_HAS_OPENCV && MRPT_OPENCV_VERSION_NUM<0x240    65 #       undef MRPT_HAS_OPENCV    66 #       define MRPT_HAS_OPENCV 0    79     upnp::upnp(
const Mat& cameraMatrix, 
const Mat& opoints, 
const Mat& ipoints)
    81       if (cameraMatrix.depth() == CV_32F)
    82         init_camera_parameters<float>(cameraMatrix);
    84         init_camera_parameters<double>(cameraMatrix);
    86       number_of_correspondences = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
    88       pws.resize(3 * number_of_correspondences);
    89       us.resize(2 * number_of_correspondences);
    91       if (opoints.depth() == ipoints.depth())
    93         if (opoints.depth() == CV_32F)
    94           init_points<Point3f,Point2f>(opoints, ipoints);
    96           init_points<Point3d,Point2d>(opoints, ipoints);
    98       else if (opoints.depth() == CV_32F)
    99         init_points<Point3f,Point2d>(opoints, ipoints);
   101         init_points<Point3d,Point2f>(opoints, ipoints);
   103       alphas.resize(4 * number_of_correspondences);
   104       pcs.resize(3 * number_of_correspondences);
   119     double upnp::compute_pose(Mat& 
R, Mat& 
t)
   121       choose_control_points();
   124       Mat * M = 
new Mat(2 * number_of_correspondences, 12, CV_64F);
   126       for(
int i = 0; i < number_of_correspondences; i++)
   128         fill_M(M, 2 * i, &alphas[0] + 4 * i, us[2 * i], us[2 * i + 1]);
   131       double mtm[12 * 12], d[12], ut[12 * 12], vt[12 * 12];
   132       Mat MtM = Mat(12, 12, CV_64F, mtm);
   133       Mat D   = Mat(12,  1, CV_64F, d);
   134       Mat Ut  = Mat(12, 12, CV_64F, ut);
   135       Mat Vt  = Mat(12, 12, CV_64F, vt);
   138       SVD::compute(MtM, D, Ut, Vt, SVD::MODIFY_A | SVD::FULL_UV);
   139       Mat(Ut.t()).copyTo(Ut);
   143       double l_6x12[6 * 12], rho[6];
   144       Mat L_6x12 = Mat(6, 12, CV_64F, l_6x12);
   145       Mat Rho    = Mat(6,  1, CV_64F, rho);
   147       compute_L_6x12(ut, l_6x12);
   150       double Betas[3][4], Efs[3][1], rep_errors[3];
   151       double Rs[3][3][3], ts[3][3];
   153       find_betas_and_focal_approx_1(&Ut, &Rho, Betas[1], Efs[1]);
   154       gauss_newton(&L_6x12, &Rho, Betas[1], Efs[1]);
   155       rep_errors[1] = compute_R_and_t(ut, Betas[1], Rs[1], ts[1]);
   157       find_betas_and_focal_approx_2(&Ut, &Rho, Betas[2], Efs[2]);
   158       gauss_newton(&L_6x12, &Rho, Betas[2], Efs[2]);
   159       rep_errors[2] = compute_R_and_t(ut, Betas[2], Rs[2], ts[2]);
   162       if (rep_errors[2] < rep_errors[1]) N = 2;
   164       Mat(3, 1, CV_64F, ts[N]).copyTo(
t);
   165       Mat(3, 3, CV_64F, Rs[N]).copyTo(
R);
   171     void upnp::copy_R_and_t(
const double R_src[3][3], 
const double t_src[3],
   172          double R_dst[3][3], 
double t_dst[3])
   174       for(
int i = 0; i < 3; i++) {
   175         for(
int j = 0; j < 3; j++)
   176           R_dst[i][j] = R_src[i][j];
   181     void upnp::estimate_R_and_t(
double R[3][3], 
double t[3])
   183       double pc0[3], pw0[3];
   185       pc0[0] = pc0[1] = pc0[2] = 0.0;
   186       pw0[0] = pw0[1] = pw0[2] = 0.0;
   188       for(
int i = 0; i < number_of_correspondences; i++) {
   189         const double * pc = &pcs[3 * i];
   190         const double * pw = &pws[3 * i];
   192         for(
int j = 0; j < 3; j++) {
   197       for(
int j = 0; j < 3; j++) {
   198         pc0[j] /= number_of_correspondences;
   199         pw0[j] /= number_of_correspondences;
   202       double abt[3 * 3], abt_d[3], abt_u[3 * 3], abt_v[3 * 3];
   203       Mat ABt   = Mat(3, 3, CV_64F, abt);
   204       Mat ABt_D = Mat(3, 1, CV_64F, abt_d);
   205       Mat ABt_U = Mat(3, 3, CV_64F, abt_u);
   206       Mat ABt_V = Mat(3, 3, CV_64F, abt_v);
   209       for(
int i = 0; i < number_of_correspondences; i++) {
   210         double * pc = &pcs[3 * i];
   211         double * pw = &pws[3 * i];
   213         for(
int j = 0; j < 3; j++) {
   214           abt[3 * j    ] += (pc[j] - pc0[j]) * (pw[0] - pw0[0]);
   215           abt[3 * j + 1] += (pc[j] - pc0[j]) * (pw[1] - pw0[1]);
   216           abt[3 * j + 2] += (pc[j] - pc0[j]) * (pw[2] - pw0[2]);
   220       SVD::compute(ABt, ABt_D, ABt_U, ABt_V, SVD::MODIFY_A);
   221       Mat(ABt_V.t()).copyTo(ABt_V);
   223       for(
int i = 0; i < 3; i++)
   224         for(
int j = 0; j < 3; j++)
   225           R[i][j] = dot(abt_u + 3 * i, abt_v + 3 * j);
   228         R[0][0] * 
R[1][1] * 
R[2][2] + 
R[0][1] * 
R[1][2] * 
R[2][0] + 
R[0][2] * 
R[1][0] * 
R[2][1] -
   229         R[0][2] * 
R[1][1] * 
R[2][0] - 
R[0][1] * 
R[1][0] * 
R[2][2] - 
R[0][0] * 
R[1][2] * 
R[2][1];
   237       t[0] = pc0[0] - dot(
R[0], pw0);
   238       t[1] = pc0[1] - dot(
R[1], pw0);
   239       t[2] = pc0[2] - dot(
R[2], pw0);
   242     void upnp::solve_for_sign(
void)
   245         for(
int i = 0; i < 4; i++)
   246           for(
int j = 0; j < 3; j++)
   247             ccs[i][j] = -ccs[i][j];
   249         for(
int i = 0; i < number_of_correspondences; i++) {
   250           pcs[3 * i    ] = -pcs[3 * i];
   251           pcs[3 * i + 1] = -pcs[3 * i + 1];
   252           pcs[3 * i + 2] = -pcs[3 * i + 2];
   257     double upnp::compute_R_and_t(
const double * ut, 
const double * betas,
   258              double R[3][3], 
double t[3])
   260       compute_ccs(betas, ut);
   265       estimate_R_and_t(
R, 
t);
   267       return reprojection_error(
R, 
t);
   270     double upnp::reprojection_error(
const double R[3][3], 
const double t[3])
   274       for(
int i = 0; i < number_of_correspondences; i++) {
   275         double * pw = &pws[3 * i];
   276         double Xc = dot(
R[0], pw) + 
t[0];
   277         double Yc = dot(
R[1], pw) + 
t[1];
   278         double inv_Zc = 1.0 / (dot(
R[2], pw) + 
t[2]);
   279         double ue = uc + fu * Xc * inv_Zc;
   280         double ve = vc + fv * Yc * inv_Zc;
   281         double u = us[2 * i], 
v = us[2 * i + 1];
   283         sum2 += sqrt( (u - ue) * (u - ue) + (
v - ve) * (
v - ve) );
   286       return sum2 / number_of_correspondences;
   289     void upnp::choose_control_points()
   291         for (
int i = 0; i < 4; ++i)
   292           cws[i][0] = cws[i][1] = cws[i][2] = 0.0;
   293         cws[0][0] = cws[1][1] = cws[2][2] = 1.0;
   296     void upnp::compute_alphas()
   298         Mat CC = Mat(4, 3, CV_64F, &cws);
   299         Mat PC = Mat(number_of_correspondences, 3, CV_64F, &pws[0]);
   300         Mat ALPHAS = Mat(number_of_correspondences, 4, CV_64F, &alphas[0]);
   302         Mat CC_ = CC.clone().t();
   303         Mat PC_ = PC.clone().t();
   306         Mat row1n = 
Mat::ones(1, number_of_correspondences, CV_64F);
   308         CC_.push_back(row14);
   309         PC_.push_back(row1n);
   311         ALPHAS = Mat( CC_.inv() * PC_ ).
t();
   314     void upnp::fill_M(Mat * M, 
const int row, 
const double * as, 
const double u, 
const double v)
   316       double * M1 = M->ptr<
double>(
row);
   317       double * M2 = M1 + 12;
   319       for(
int i = 0; i < 4; i++) {
   320         M1[3 * i    ] = as[i] * fu;
   322         M1[3 * i + 2] = as[i] * (uc - u);
   325         M2[3 * i + 1] = as[i] * fv;
   326         M2[3 * i + 2] = as[i] * (vc - 
v);
   330     void upnp::compute_ccs(
const double * betas, 
const double * ut)
   332         for(
int i = 0; i < 4; ++i)
   333           ccs[i][0] = ccs[i][1] = ccs[i][2] = 0.0;
   336         for(
int i = 0; i < N; ++i) {
   337           const double * 
v = ut + 12 * (9 + i);
   338           for(
int j = 0; j < 4; ++j)
   339             for(
int k = 0; k < 3; ++k)
   340               ccs[j][k] += betas[i] * 
v[3 * j + k];
   343         for (
int i = 0; i < 4; ++i) ccs[i][2] *= fu;
   346     void upnp::compute_pcs(
void)
   348       for(
int i = 0; i < number_of_correspondences; i++) {
   349         double * 
a = &alphas[0] + 4 * i;
   350         double * pc = &pcs[0] + 3 * i;
   352         for(
int j = 0; j < 3; j++)
   353           pc[j] = 
a[0] * ccs[0][j] + 
a[1] * ccs[1][j] + 
a[2] * ccs[2][j] + 
a[3] * ccs[3][j];
   357     void upnp::find_betas_and_focal_approx_1(Mat * Ut, Mat * Rho, 
double * betas, 
double * efs)
   359       Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<
double>(11));
   360       Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<
double>(0));
   362       Mat D = compute_constraint_distance_2param_6eq_2unk_f_unk( Kmf1 );
   368       Mat 
x = Mat(2, 1, CV_64F);
   371       betas[0] = sqrt( abs( 
x.at<
double>(0) ) );
   372       betas[1] = betas[2] = betas[3] = 0.0;
   374       efs[0] = sqrt( abs( 
x.at<
double>(1) ) ) / betas[0];
   377     void upnp::find_betas_and_focal_approx_2(Mat * Ut, Mat * Rho, 
double * betas, 
double * efs)
   380       Mat U = Mat(12, 12, CV_64F, u);
   383       Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<
double>(10));
   384       Mat Kmf2 = Mat(12, 1, CV_64F, Ut->ptr<
double>(11));
   385       Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<
double>(0));
   387       Mat D = compute_constraint_distance_3param_6eq_6unk_f_unk( Kmf1, Kmf2 );
   393       Mat X = Mat(6, 1, CV_64F, 
x);
   395       solve(A, 
b, X, DECOMP_QR);
   397       double solutions[18][3];
   398       generate_all_possible_solutions_for_f_unk(
x, solutions);
   401       double min_error = std::numeric_limits<double>::max();
   403       for (
int i = 0; i < 18; ++i) {
   405         betas[3] = solutions[i][0];
   406         betas[2] = solutions[i][1];
   407         betas[1] = betas[0] = 0.0;
   408         fu = fv = solutions[i][2];
   410         double Rs[3][3], ts[3];
   411         double error_i = compute_R_and_t( u, betas, Rs, ts);
   413         if( error_i < min_error)
   420       betas[0] = solutions[min_sol][0];
   421       betas[1] = solutions[min_sol][1];
   422       betas[2] = betas[3] = 0.0;
   424       efs[0] = solutions[min_sol][2];
   427     Mat upnp::compute_constraint_distance_2param_6eq_2unk_f_unk(
const Mat& M1)
   429       Mat P = Mat(6, 2, CV_64F);
   432       for (
int i = 1; i < 13; ++i) m[i] = *M1.ptr<
double>(i-1);
   434       double t1 = pow( m[4], 2 );
   435       double t4 = pow( m[1], 2 );
   436       double t5 = pow( m[5], 2 );
   437       double t8 = pow( m[2], 2 );
   438       double t10 = pow( m[6], 2 );
   439       double t13 = pow( m[3], 2 );
   440       double t15 = pow( m[7], 2 );
   441       double t18 = pow( m[8], 2 );
   442       double t22 = pow( m[9], 2 );
   443       double t26 = pow( m[10], 2 );
   444       double t29 = pow( m[11], 2 );
   445       double t33 = pow( m[12], 2 );
   447       *P.ptr<
double>(0,0) = t1 - 2 * m[4] * m[1] + t4 + t5 - 2 * m[5] * m[2] + t8;
   448       *P.ptr<
double>(0,1) = t10 - 2 * m[6] * m[3] + t13;
   449       *P.ptr<
double>(1,0) = t15 - 2 * m[7] * m[1] + t4 + t18 - 2 * m[8] * m[2] + t8;
   450       *P.ptr<
double>(1,1) = t22 - 2 * m[9] * m[3] + t13;
   451       *P.ptr<
double>(2,0) = t26 - 2 * m[10] * m[1] + t4 + t29 - 2 * m[11] * m[2] + t8;
   452       *P.ptr<
double>(2,1) = t33 - 2 * m[12] * m[3] + t13;
   453       *P.ptr<
double>(3,0) = t15 - 2 * m[7] * m[4] + t1 + t18 - 2 * m[8] * m[5] + t5;
   454       *P.ptr<
double>(3,1) = t22 - 2 * m[9] * m[6] + t10;
   455       *P.ptr<
double>(4,0) = t26 - 2 * m[10] * m[4] + t1 + t29 - 2 * m[11] * m[5] + t5;
   456       *P.ptr<
double>(4,1) = t33 - 2 * m[12] * m[6] + t10;
   457       *P.ptr<
double>(5,0) = t26 - 2 * m[10] * m[7] + t15 + t29 - 2 * m[11] * m[8] + t18;
   458       *P.ptr<
double>(5,1) = t33 - 2 * m[12] * m[9] + t22;
   463     Mat upnp::compute_constraint_distance_3param_6eq_6unk_f_unk(
const Mat& M1, 
const Mat& M2)
   465       Mat P = Mat(6, 6, CV_64F);
   468       for (
int i = 1; i < 13; ++i)
   470         m[1][i] = *M1.ptr<
double>(i-1);
   471         m[2][i] = *M2.ptr<
double>(i-1);
   474       double t1 = pow( m[1][4], 2 );
   475       double t2 = pow( m[1][1], 2 );
   476       double t7 = pow( m[1][5], 2 );
   477       double t8 = pow( m[1][2], 2 );
   478       double t11 = m[1][1] * m[2][1];
   479       double t12 = m[1][5] * m[2][5];
   480       double t15 = m[1][2] * m[2][2];
   481       double t16 = m[1][4] * m[2][4];
   482       double t19 = pow( m[2][4], 2 );
   483       double t22 = pow( m[2][2], 2 );
   484       double t23 = pow( m[2][1], 2 );
   485       double t24 = pow( m[2][5], 2 );
   486       double t28 = pow( m[1][6], 2 );
   487       double t29 = pow( m[1][3], 2 );
   488       double t34 = pow( m[1][3], 2 );
   489       double t36 = m[1][6] * m[2][6];
   490       double t40 = pow( m[2][6], 2 );
   491       double t41 = pow( m[2][3], 2 );
   492       double t47 = pow( m[1][7], 2 );
   493       double t48 = pow( m[1][8], 2 );
   494       double t52 = m[1][7] * m[2][7];
   495       double t55 = m[1][8] * m[2][8];
   496       double t59 = pow( m[2][8], 2 );
   497       double t62 = pow( m[2][7], 2 );
   498       double t64 = pow( m[1][9], 2 );
   499       double t68 = m[1][9] * m[2][9];
   500       double t74 = pow( m[2][9], 2 );
   501       double t78 = pow( m[1][10], 2 );
   502       double t79 = pow( m[1][11], 2 );
   503       double t84 = m[1][10] * m[2][10];
   504       double t87 = m[1][11] * m[2][11];
   505       double t90 = pow( m[2][10], 2 );
   506       double t95 = pow( m[2][11], 2 );
   507       double t99 = pow( m[1][12], 2 );
   508       double t101 = m[1][12] * m[2][12];
   509       double t105 = pow( m[2][12], 2 );
   511       *P.ptr<
double>(0,0) = t1 + t2 - 2 * m[1][4] * m[1][1] - 2 * m[1][5] * m[1][2] + t7 + t8;
   512       *P.ptr<
double>(0,1) = -2 * m[2][4] * m[1][1] + 2 * t11 + 2 * t12 - 2 * m[1][4] * m[2][1] - 2 * m[2][5] * m[1][2] + 2 * t15 + 2 * t16 - 2 * m[1][5] * m[2][2];
   513       *P.ptr<
double>(0,2) = t19 - 2 * m[2][4] * m[2][1] + t22 + t23 + t24 - 2 * m[2][5] * m[2][2];
   514       *P.ptr<
double>(0,3) = t28 + t29 - 2 * m[1][6] * m[1][3];
   515       *P.ptr<
double>(0,4) = -2 * m[2][6] * m[1][3] + 2 * t34 - 2 * m[1][6] * m[2][3] + 2 * t36;
   516       *P.ptr<
double>(0,5) = -2 * m[2][6] * m[2][3] + t40 + t41;
   518       *P.ptr<
double>(1,0) = t8 - 2 * m[1][8] * m[1][2] - 2 * m[1][7] * m[1][1] + t47 + t48 + t2;
   519       *P.ptr<
double>(1,1) = 2 * t15 - 2 * m[1][8] * m[2][2] - 2 * m[2][8] * m[1][2] + 2 * t52 - 2 * m[1][7] * m[2][1] - 2 * m[2][7] * m[1][1] + 2 * t55 + 2 * t11;
   520       *P.ptr<
double>(1,2) = -2 * m[2][8] * m[2][2] + t22 + t23 + t59 - 2 * m[2][7] * m[2][1] + t62;
   521       *P.ptr<
double>(1,3) = t29 + t64 - 2 * m[1][9] * m[1][3];
   522       *P.ptr<
double>(1,4) = 2 * t34 + 2 * t68 - 2 * m[2][9] * m[1][3] - 2 * m[1][9] * m[2][3];
   523       *P.ptr<
double>(1,5) = -2 * m[2][9] * m[2][3] + t74 + t41;
   525       *P.ptr<
double>(2,0) = -2 * m[1][11] * m[1][2] + t2 + t8 + t78 + t79 - 2 * m[1][10] * m[1][1];
   526       *P.ptr<
double>(2,1) = 2 * t15 - 2 * m[1][11] * m[2][2] + 2 * t84 - 2 * m[1][10] * m[2][1] - 2 * m[2][10] * m[1][1] + 2 * t87 - 2 * m[2][11] * m[1][2]+ 2 * t11;
   527       *P.ptr<
double>(2,2) = t90 + t22 - 2 * m[2][10] * m[2][1] + t23 - 2 * m[2][11] * m[2][2] + t95;
   528       *P.ptr<
double>(2,3) = -2 * m[1][12] * m[1][3] + t99 + t29;
   529       *P.ptr<
double>(2,4) = 2 * t34 + 2 * t101 - 2 * m[2][12] * m[1][3] - 2 * m[1][12] * m[2][3];
   530       *P.ptr<
double>(2,5) = t41 + t105 - 2 * m[2][12] * m[2][3];
   532       *P.ptr<
double>(3,0) = t48 + t1 - 2 * m[1][8] * m[1][5] + t7 - 2 * m[1][7] * m[1][4] + t47;
   533       *P.ptr<
double>(3,1) = 2 * t16 - 2 * m[1][7] * m[2][4] + 2 * t55 + 2 * t52 - 2 * m[1][8] * m[2][5] - 2 * m[2][8] * m[1][5] - 2 * m[2][7] * m[1][4] + 2 * t12;
   534       *P.ptr<
double>(3,2) = t24 - 2 * m[2][8] * m[2][5] + t19 - 2 * m[2][7] * m[2][4] + t62 + t59;
   535       *P.ptr<
double>(3,3) = -2 * m[1][9] * m[1][6] + t64 + t28;
   536       *P.ptr<
double>(3,4) = 2 * t68 + 2 * t36 - 2 * m[2][9] * m[1][6] - 2 * m[1][9] * m[2][6];
   537       *P.ptr<
double>(3,5) = t40 + t74 - 2 * m[2][9] * m[2][6];
   539       *P.ptr<
double>(4,0) = t1 - 2 * m[1][10] * m[1][4] + t7 + t78 + t79 - 2 * m[1][11] * m[1][5];
   540       *P.ptr<
double>(4,1) = 2 * t84 - 2 * m[1][11] * m[2][5] - 2 * m[1][10] * m[2][4] + 2 * t16 - 2 * m[2][11] * m[1][5] + 2 * t87 - 2 * m[2][10] * m[1][4] + 2 * t12;
   541       *P.ptr<
double>(4,2) = t19 + t24 - 2 * m[2][10] * m[2][4] - 2 * m[2][11] * m[2][5] + t95 + t90;
   542       *P.ptr<
double>(4,3) = t28 - 2 * m[1][12] * m[1][6] + t99;
   543       *P.ptr<
double>(4,4) = 2 * t101 + 2 * t36 - 2 * m[2][12] * m[1][6] - 2 * m[1][12] * m[2][6];
   544       *P.ptr<
double>(4,5) = t105 - 2 * m[2][12] * m[2][6] + t40;
   546       *P.ptr<
double>(5,0) = -2 * m[1][10] * m[1][7] + t47 + t48 + t78 + t79 - 2 * m[1][11] * m[1][8];
   547       *P.ptr<
double>(5,1) = 2 * t84 + 2 * t87 - 2 * m[2][11] * m[1][8] - 2 * m[1][10] * m[2][7] - 2 * m[2][10] * m[1][7] + 2 * t55 + 2 * t52 - 2 * m[1][11] * m[2][8];
   548       *P.ptr<
double>(5,2) = -2 * m[2][10] * m[2][7] - 2 * m[2][11] * m[2][8] + t62 + t59 + t90 + t95;
   549       *P.ptr<
double>(5,3) = t64 - 2 * m[1][12] * m[1][9] + t99;
   550       *P.ptr<
double>(5,4) = 2 * t68 - 2 * m[2][12] * m[1][9] - 2 * m[1][12] * m[2][9] + 2 * t101;
   551       *P.ptr<
double>(5,5) = t105 - 2 * m[2][12] * m[2][9] + t74;
   556     void upnp::generate_all_possible_solutions_for_f_unk(
const double betas[5], 
double solutions[18][3])
   558       int matrix_to_resolve[18][9] = {
   559         { 2, 0, 0, 1, 1, 0, 2, 0, 2 }, { 2, 0, 0, 1, 1, 0, 1, 1, 2 },
   560         { 2, 0, 0, 1, 1, 0, 0, 2, 2 }, { 2, 0, 0, 0, 2, 0, 2, 0, 2 },
   561         { 2, 0, 0, 0, 2, 0, 1, 1, 2 }, { 2, 0, 0, 0, 2, 0, 0, 2, 2 },
   562         { 2, 0, 0, 2, 0, 2, 1, 1, 2 }, { 2, 0, 0, 2, 0, 2, 0, 2, 2 },
   563         { 2, 0, 0, 1, 1, 2, 0, 2, 2 }, { 1, 1, 0, 0, 2, 0, 2, 0, 2 },
   564         { 1, 1, 0, 0, 2, 0, 1, 1, 2 }, { 1, 1, 0, 2, 0, 2, 0, 2, 2 },
   565         { 1, 1, 0, 2, 0, 2, 1, 1, 2 }, { 1, 1, 0, 2, 0, 2, 0, 2, 2 },
   566         { 1, 1, 0, 1, 1, 2, 0, 2, 2 }, { 0, 2, 0, 2, 0, 2, 1, 1, 2 },
   567         { 0, 2, 0, 2, 0, 2, 0, 2, 2 }, { 0, 2, 0, 1, 1, 2, 0, 2, 2 }
   570       int combination[18][3] = {
   571         { 1, 2, 4 }, { 1, 2, 5 }, { 1, 2, 6 }, { 1, 3, 4 },
   572         { 1, 3, 5 }, { 1, 3, 6 }, { 1, 4, 5 }, { 1, 4, 6 },
   573         { 1, 5, 6 }, { 2, 3, 4 }, { 2, 3, 5 }, { 2, 3, 6 },
   574         { 2, 4, 5 }, { 2, 4, 6 }, { 2, 5, 6 }, { 3, 4, 5 },
   575         { 3, 4, 6 }, { 3, 5, 6 }
   578       for (
int i = 0; i < 18; ++i) {
   579         double matrix[9], independent_term[3];
   580         Mat M = Mat(3, 3, CV_64F, 
matrix);
   581         Mat I = Mat(3, 1, CV_64F, independent_term);
   582         Mat S = Mat(1, 3, CV_64F);
   584         for (
int j = 0; j < 9; ++j) 
matrix[j] = (
double)matrix_to_resolve[i][j];
   586         independent_term[0] = log( abs( betas[ combination[i][0]-1 ] ) );
   587         independent_term[1] = log( abs( betas[ combination[i][1]-1 ] ) );
   588         independent_term[2] = log( abs( betas[ combination[i][2]-1 ] ) );
   590         exp( Mat(M.inv() * I), S);
   592         solutions[i][0] = S.at<
double>(0);
   593         solutions[i][1] = S.at<
double>(1) * 
sign( betas[1] );
   594         solutions[i][2] = abs( S.at<
double>(2) );
   598     void upnp::gauss_newton(
const Mat * L_6x12, 
const Mat * Rho, 
double betas[4], 
double * f)
   600       const int iterations_number = 50;
   602       double a[6*4], 
b[6], 
x[4];
   603       Mat * A = 
new Mat(6, 4, CV_64F, 
a);
   604       Mat * B = 
new Mat(6, 1, CV_64F, 
b);
   605       Mat * X = 
new Mat(4, 1, CV_64F, 
x);
   607       for(
int k = 0; k < iterations_number; k++)
   609         compute_A_and_b_gauss_newton(L_6x12->ptr<
double>(0), Rho->ptr<
double>(0), betas, A, B, f[0]);
   611         for(
int i = 0; i < 3; i++)
   616       if (f[0] < 0) f[0] = -f[0];
   630     void upnp::compute_A_and_b_gauss_newton(
const double * l_6x12, 
const double * rho,
   631             const double betas[4], Mat * A, Mat * 
b, 
double const f)
   634       for(
int i = 0; i < 6; i++) {
   635         const double * rowL = l_6x12 + i * 12;
   636         double * rowA = A->ptr<
double>(i);
   638         rowA[0] = 2 * rowL[0] * betas[0] +    rowL[1] * betas[1] +    rowL[2] * betas[2] + f*f * ( 2 * rowL[6]*betas[0] +    rowL[7]*betas[1]  +    rowL[8]*betas[2] );
   639         rowA[1] =    rowL[1] * betas[0] + 2 * rowL[3] * betas[1] +    rowL[4] * betas[2] + f*f * (    rowL[7]*betas[0] + 2 * rowL[9]*betas[1]  +    rowL[10]*betas[2] );
   640         rowA[2] =    rowL[2] * betas[0] +    rowL[4] * betas[1] + 2 * rowL[5] * betas[2] + f*f * (    rowL[8]*betas[0] +    rowL[10]*betas[1] + 2 * rowL[11]*betas[2] );
   641         rowA[3] = 2*f * ( rowL[6]*betas[0]*betas[0] + rowL[7]*betas[0]*betas[1] + rowL[8]*betas[0]*betas[2] + rowL[9]*betas[1]*betas[1] + rowL[10]*betas[1]*betas[2] + rowL[11]*betas[2]*betas[2] ) ;
   643         *
b->ptr<
double>(i) = rho[i] -
   645           rowL[0] * betas[0] * betas[0] +
   646           rowL[1] * betas[0] * betas[1] +
   647           rowL[2] * betas[0] * betas[2] +
   648           rowL[3] * betas[1] * betas[1] +
   649           rowL[4] * betas[1] * betas[2] +
   650           rowL[5] * betas[2] * betas[2] +
   651           f*f * rowL[6] * betas[0] * betas[0] +
   652           f*f * rowL[7] * betas[0] * betas[1] +
   653           f*f * rowL[8] * betas[0] * betas[2] +
   654           f*f * rowL[9] * betas[1] * betas[1] +
   655           f*f * rowL[10] * betas[1] * betas[2] +
   656           f*f * rowL[11] * betas[2] * betas[2]
   661     void upnp::compute_L_6x12(
const double * ut, 
double * l_6x12)
   671       for(
int i = 0; i < 3; i++) {
   673         for(
int j = 0; j < 6; j++) {
   674           dv[i][j][0] = 
v[i][3 * 
a    ] - 
v[i][3 * 
b];
   675           dv[i][j][1] = 
v[i][3 * 
a + 1] - 
v[i][3 * 
b + 1];
   676           dv[i][j][2] = 
v[i][3 * 
a + 2] - 
v[i][3 * 
b + 2];
   686       for(
int i = 0; i < 6; i++) {
   687         double * 
row = l_6x12 + 12 * i;
   689         row[0] =         dotXY(dv[0][i], dv[0][i]);
   690         row[1] =  2.0f * dotXY(dv[0][i], dv[1][i]);
   691         row[2] =         dotXY(dv[1][i], dv[1][i]);
   692         row[3] =  2.0f * dotXY(dv[0][i], dv[2][i]);
   693         row[4] =  2.0f * dotXY(dv[1][i], dv[2][i]);
   694         row[5] =         dotXY(dv[2][i], dv[2][i]);
   696         row[6] =         dotZ(dv[0][i], dv[0][i]);
   697         row[7] =  2.0f * dotZ(dv[0][i], dv[1][i]);
   698         row[8] =  2.0f * dotZ(dv[0][i], dv[2][i]);
   699         row[9] =         dotZ(dv[1][i], dv[1][i]);
   700         row[10] = 2.0f * dotZ(dv[1][i], dv[2][i]);
   701         row[11] =        dotZ(dv[2][i], dv[2][i]);
   705     void upnp::compute_rho(
double * rho)
   707       rho[0] = dist2(cws[0], cws[1]);
   708       rho[1] = dist2(cws[0], cws[2]);
   709       rho[2] = dist2(cws[0], cws[3]);
   710       rho[3] = dist2(cws[1], cws[2]);
   711       rho[4] = dist2(cws[1], cws[3]);
   712       rho[5] = dist2(cws[2], cws[3]);
   715     double upnp::dist2(
const double * p1, 
const double * p2)
   718         (p1[0] - p2[0]) * (p1[0] - p2[0]) +
   719         (p1[1] - p2[1]) * (p1[1] - p2[1]) +
   720         (p1[2] - p2[2]) * (p1[2] - p2[2]);
   723     double upnp::dot(
const double * 
v1, 
const double * 
v2)
   728     double upnp::dotXY(
const double * 
v1, 
const double * 
v2)
   730       return v1[0] * 
v2[0] + 
v1[1] * 
v2[1];
   733     double upnp::dotZ(
const double * 
v1, 
const double * 
v2)
   735       return v1[2] * 
v2[2];
   740       return ( 
v < 0.0 ) ? -1.0 : ( 
v > 0.0 ) ? 1.0 : 0.0;
   743     void upnp::qr_solve(Mat * A, Mat * 
b, Mat * X)
   745       const int nr = A->rows;
   746       const int nc = A->cols;
   748       if (max_nr != 0 && max_nr < nr)
   760       double * pA = A->ptr<
double>(0), * ppAkk = pA;
   761       for(
int k = 0; k < nc; k++)
   763         double * ppAik1 = ppAkk, eta = fabs(*ppAik1);
   764         for(
int i = k + 1; i < nr; i++)
   766           double elt = fabs(*ppAik1);
   767           if (eta < elt) eta = elt;
   778          double * ppAik2 = ppAkk, sum2 = 0.0, inv_eta = 1. / eta;
   779          for(
int i = k; i < nr; i++)
   782            sum2 += *ppAik2 * *ppAik2;
   785          double sigma = sqrt(sum2);
   789          A1[k] = sigma * *ppAkk;
   790          A2[k] = -eta * sigma;
   791          for(
int j = k + 1; j < nc; j++)
   793            double * ppAik = ppAkk, 
sum = 0;
   794            for(
int i = k; i < nr; i++)
   796             sum += *ppAik * ppAik[j - k];
   799            double tau = 
sum / 
A1[k];
   801            for(
int i = k; i < nr; i++)
   803             ppAik[j - k] -= tau * *ppAik;
   812       double * ppAjj = pA, * pb = 
b->ptr<
double>(0);
   813       for(
int j = 0; j < nc; j++)
   815         double * ppAij = ppAjj, tau = 0;
   816         for(
int i = j; i < nr; i++)
   818          tau += *ppAij * pb[i];
   823         for(
int i = j; i < nr; i++)
   825          pb[i] -= tau * *ppAij;
   832       double * pX = X->ptr<
double>(0);
   833       pX[nc - 1] = pb[nc - 1] / A2[nc - 1];
   834       for(
int i = nc - 2; i >= 0; i--)
   836         double * ppAij = pA + i * nc + (i + 1), 
sum = 0;
   838         for(
int j = i + 1; j < nc; j++)
   840          sum += *ppAij * pX[j];
   843         pX[i] = (pb[i] - 
sum) / A2[i];
 EIGEN_STRONG_INLINE Scalar det() const
 
Unified PnP - Eigen Wrapper for OpenCV function. 
 
Perspective n Point (PnP) Algorithms toolkit for MRPT. 
 
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements. 
 
int sign(T x)
Returns the sign of X as "1" or "-1". 
 
double A1
UTC constant and 1st order terms. 
 
GLenum GLenum GLvoid * row
 
GLfloat GLfloat GLfloat v2
 
EIGEN_STRONG_INLINE void ones(const size_t row, const size_t col)
Resize matrix and set all elements to one. 
 
GLubyte GLubyte GLubyte a