66 #include <mrpt/otherlibs/do_opencv_includes.h> 70 #include <mrpt/config.h> 71 #if MRPT_HAS_OPENCV && MRPT_OPENCV_VERSION_NUM < 0x240 72 #undef MRPT_HAS_OPENCV 73 #define MRPT_HAS_OPENCV 0 85 upnp::upnp(
const Mat& cameraMatrix,
const Mat& opoints,
const Mat& ipoints)
87 if (cameraMatrix.depth() == CV_32F)
88 init_camera_parameters<float>(cameraMatrix);
90 init_camera_parameters<double>(cameraMatrix);
92 number_of_correspondences = std::max(
93 opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
95 pws.resize(3 * number_of_correspondences);
96 us.resize(2 * number_of_correspondences);
98 if (opoints.depth() == ipoints.depth())
100 if (opoints.depth() == CV_32F)
101 init_points<Point3f, Point2f>(opoints, ipoints);
103 init_points<Point3d, Point2d>(opoints, ipoints);
105 else if (opoints.depth() == CV_32F)
106 init_points<Point3f, Point2d>(opoints, ipoints);
108 init_points<Point3d, Point2f>(opoints, ipoints);
110 alphas.resize(4 * number_of_correspondences);
111 pcs.resize(3 * number_of_correspondences);
124 double upnp::compute_pose(Mat&
R, Mat&
t)
126 choose_control_points();
129 Mat* M =
new Mat(2 * number_of_correspondences, 12, CV_64F);
131 for (
int i = 0; i < number_of_correspondences; i++)
133 fill_M(M, 2 * i, &alphas[0] + 4 * i, us[2 * i], us[2 * i + 1]);
136 double mtm[12 * 12], d[12], ut[12 * 12], vt[12 * 12];
137 Mat MtM = Mat(12, 12, CV_64F, mtm);
138 Mat D = Mat(12, 1, CV_64F, d);
139 Mat Ut = Mat(12, 12, CV_64F, ut);
140 Mat Vt = Mat(12, 12, CV_64F, vt);
143 SVD::compute(MtM, D, Ut, Vt, SVD::MODIFY_A | SVD::FULL_UV);
144 Mat(Ut.t()).copyTo(Ut);
148 double l_6x12[6 * 12], rho[6];
149 Mat L_6x12 = Mat(6, 12, CV_64F, l_6x12);
150 Mat Rho = Mat(6, 1, CV_64F, rho);
152 compute_L_6x12(ut, l_6x12);
155 double Betas[3][4], Efs[3][1], rep_errors[3];
156 double Rs[3][3][3], ts[3][3];
158 find_betas_and_focal_approx_1(&Ut, &Rho, Betas[1], Efs[1]);
159 gauss_newton(&L_6x12, &Rho, Betas[1], Efs[1]);
160 rep_errors[1] = compute_R_and_t(ut, Betas[1], Rs[1], ts[1]);
162 find_betas_and_focal_approx_2(&Ut, &Rho, Betas[2], Efs[2]);
163 gauss_newton(&L_6x12, &Rho, Betas[2], Efs[2]);
164 rep_errors[2] = compute_R_and_t(ut, Betas[2], Rs[2], ts[2]);
167 if (rep_errors[2] < rep_errors[1]) N = 2;
169 Mat(3, 1, CV_64F, ts[N]).copyTo(
t);
170 Mat(3, 3, CV_64F, Rs[N]).copyTo(
R);
176 void upnp::copy_R_and_t(
177 const double R_src[3][3],
const double t_src[3],
double R_dst[3][3],
180 for (
int i = 0; i < 3; i++)
182 for (
int j = 0; j < 3; j++) R_dst[i][j] = R_src[i][j];
187 void upnp::estimate_R_and_t(
double R[3][3],
double t[3])
189 double pc0[3], pw0[3];
191 pc0[0] = pc0[1] = pc0[2] = 0.0;
192 pw0[0] = pw0[1] = pw0[2] = 0.0;
194 for (
int i = 0; i < number_of_correspondences; i++)
196 const double* pc = &pcs[3 * i];
197 const double* pw = &pws[3 * i];
199 for (
int j = 0; j < 3; j++)
205 for (
int j = 0; j < 3; j++)
207 pc0[j] /= number_of_correspondences;
208 pw0[j] /= number_of_correspondences;
211 double abt[3 * 3], abt_d[3], abt_u[3 * 3], abt_v[3 * 3];
212 Mat ABt = Mat(3, 3, CV_64F, abt);
213 Mat ABt_D = Mat(3, 1, CV_64F, abt_d);
214 Mat ABt_U = Mat(3, 3, CV_64F, abt_u);
215 Mat ABt_V = Mat(3, 3, CV_64F, abt_v);
218 for (
int i = 0; i < number_of_correspondences; i++)
220 double* pc = &pcs[3 * i];
221 double* pw = &pws[3 * i];
223 for (
int j = 0; j < 3; j++)
225 abt[3 * j] += (pc[j] - pc0[j]) * (pw[0] - pw0[0]);
226 abt[3 * j + 1] += (pc[j] - pc0[j]) * (pw[1] - pw0[1]);
227 abt[3 * j + 2] += (pc[j] - pc0[j]) * (pw[2] - pw0[2]);
231 SVD::compute(ABt, ABt_D, ABt_U, ABt_V, SVD::MODIFY_A);
232 Mat(ABt_V.t()).copyTo(ABt_V);
234 for (
int i = 0; i < 3; i++)
235 for (
int j = 0; j < 3; j++)
R[i][j] = dot(abt_u + 3 * i, abt_v + 3 * j);
238 R[0][0] *
R[1][1] *
R[2][2] +
R[0][1] *
R[1][2] *
R[2][0] +
239 R[0][2] *
R[1][0] *
R[2][1] -
R[0][2] *
R[1][1] *
R[2][0] -
240 R[0][1] *
R[1][0] *
R[2][2] -
R[0][0] *
R[1][2] *
R[2][1];
249 t[0] = pc0[0] - dot(
R[0], pw0);
250 t[1] = pc0[1] - dot(
R[1], pw0);
251 t[2] = pc0[2] - dot(
R[2], pw0);
254 void upnp::solve_for_sign(
void)
258 for (
int i = 0; i < 4; i++)
259 for (
int j = 0; j < 3; j++) ccs[i][j] = -ccs[i][j];
261 for (
int i = 0; i < number_of_correspondences; i++)
263 pcs[3 * i] = -pcs[3 * i];
264 pcs[3 * i + 1] = -pcs[3 * i + 1];
265 pcs[3 * i + 2] = -pcs[3 * i + 2];
270 double upnp::compute_R_and_t(
271 const double* ut,
const double* betas,
double R[3][3],
double t[3])
273 compute_ccs(betas, ut);
278 estimate_R_and_t(
R,
t);
280 return reprojection_error(
R,
t);
283 double upnp::reprojection_error(
const double R[3][3],
const double t[3])
287 for (
int i = 0; i < number_of_correspondences; i++)
289 double* pw = &pws[3 * i];
290 double Xc = dot(
R[0], pw) +
t[0];
291 double Yc = dot(
R[1], pw) +
t[1];
292 double inv_Zc = 1.0 / (dot(
R[2], pw) +
t[2]);
293 double ue = uc + fu * Xc * inv_Zc;
294 double ve = vc + fv * Yc * inv_Zc;
295 double u = us[2 * i],
v = us[2 * i + 1];
297 sum2 += sqrt((u - ue) * (u - ue) + (
v - ve) * (
v - ve));
300 return sum2 / number_of_correspondences;
303 void upnp::choose_control_points()
305 for (
int i = 0; i < 4; ++i) cws[i][0] = cws[i][1] = cws[i][2] = 0.0;
306 cws[0][0] = cws[1][1] = cws[2][2] = 1.0;
309 void upnp::compute_alphas()
311 Mat CC = Mat(4, 3, CV_64F, &cws);
312 Mat PC = Mat(number_of_correspondences, 3, CV_64F, &pws[0]);
313 Mat ALPHAS = Mat(number_of_correspondences, 4, CV_64F, &alphas[0]);
315 Mat CC_ = CC.clone().t();
316 Mat PC_ = PC.clone().t();
319 Mat row1n =
Mat::ones(1, number_of_correspondences, CV_64F);
321 CC_.push_back(row14);
322 PC_.push_back(row1n);
324 ALPHAS = Mat(CC_.inv() * PC_).
t();
328 Mat* M,
const int row,
const double* as,
const double u,
const double v)
330 double* M1 = M->ptr<
double>(
row);
331 double* M2 = M1 + 12;
333 for (
int i = 0; i < 4; i++)
335 M1[3 * i] = as[i] * fu;
337 M1[3 * i + 2] = as[i] * (uc - u);
340 M2[3 * i + 1] = as[i] * fv;
341 M2[3 * i + 2] = as[i] * (vc -
v);
345 void upnp::compute_ccs(
const double* betas,
const double* ut)
347 for (
int i = 0; i < 4; ++i) ccs[i][0] = ccs[i][1] = ccs[i][2] = 0.0;
350 for (
int i = 0; i < N; ++i)
352 const double*
v = ut + 12 * (9 + i);
353 for (
int j = 0; j < 4; ++j)
354 for (
int k = 0; k < 3; ++k) ccs[j][k] += betas[i] *
v[3 * j + k];
357 for (
int i = 0; i < 4; ++i) ccs[i][2] *= fu;
360 void upnp::compute_pcs(
void)
362 for (
int i = 0; i < number_of_correspondences; i++)
364 double*
a = &alphas[0] + 4 * i;
365 double* pc = &pcs[0] + 3 * i;
367 for (
int j = 0; j < 3; j++)
368 pc[j] =
a[0] * ccs[0][j] +
a[1] * ccs[1][j] +
a[2] * ccs[2][j] +
373 void upnp::find_betas_and_focal_approx_1(
374 Mat* Ut, Mat* Rho,
double* betas,
double* efs)
376 Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<
double>(11));
377 Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<
double>(0));
379 Mat D = compute_constraint_distance_2param_6eq_2unk_f_unk(Kmf1);
385 Mat
x = Mat(2, 1, CV_64F);
388 betas[0] = sqrt(abs(
x.at<
double>(0)));
389 betas[1] = betas[2] = betas[3] = 0.0;
391 efs[0] = sqrt(abs(
x.at<
double>(1))) / betas[0];
394 void upnp::find_betas_and_focal_approx_2(
395 Mat* Ut, Mat* Rho,
double* betas,
double* efs)
398 Mat U = Mat(12, 12, CV_64F, u);
401 Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<
double>(10));
402 Mat Kmf2 = Mat(12, 1, CV_64F, Ut->ptr<
double>(11));
403 Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<
double>(0));
405 Mat D = compute_constraint_distance_3param_6eq_6unk_f_unk(Kmf1, Kmf2);
411 Mat X = Mat(6, 1, CV_64F,
x);
413 solve(A,
b, X, DECOMP_QR);
415 double solutions[18][3];
416 generate_all_possible_solutions_for_f_unk(
x, solutions);
419 double min_error = std::numeric_limits<double>::max();
421 for (
int i = 0; i < 18; ++i)
423 betas[3] = solutions[i][0];
424 betas[2] = solutions[i][1];
425 betas[1] = betas[0] = 0.0;
426 fu = fv = solutions[i][2];
428 double Rs[3][3], ts[3];
429 double error_i = compute_R_and_t(u, betas, Rs, ts);
431 if (error_i < min_error)
438 betas[0] = solutions[min_sol][0];
439 betas[1] = solutions[min_sol][1];
440 betas[2] = betas[3] = 0.0;
442 efs[0] = solutions[min_sol][2];
445 Mat upnp::compute_constraint_distance_2param_6eq_2unk_f_unk(
const Mat& M1)
447 Mat P = Mat(6, 2, CV_64F);
450 for (
int i = 1; i < 13; ++i) m[i] = *M1.ptr<
double>(i - 1);
452 double t1 = pow(m[4], 2);
453 double t4 = pow(m[1], 2);
454 double t5 = pow(m[5], 2);
455 double t8 = pow(m[2], 2);
456 double t10 = pow(m[6], 2);
457 double t13 = pow(m[3], 2);
458 double t15 = pow(m[7], 2);
459 double t18 = pow(m[8], 2);
460 double t22 = pow(m[9], 2);
461 double t26 = pow(m[10], 2);
462 double t29 = pow(m[11], 2);
463 double t33 = pow(m[12], 2);
465 *P.ptr<
double>(0, 0) =
466 t1 - 2 * m[4] * m[1] + t4 + t5 - 2 * m[5] * m[2] + t8;
467 *P.ptr<
double>(0, 1) = t10 - 2 * m[6] * m[3] + t13;
468 *P.ptr<
double>(1, 0) =
469 t15 - 2 * m[7] * m[1] + t4 + t18 - 2 * m[8] * m[2] + t8;
470 *P.ptr<
double>(1, 1) = t22 - 2 * m[9] * m[3] + t13;
471 *P.ptr<
double>(2, 0) =
472 t26 - 2 * m[10] * m[1] + t4 + t29 - 2 * m[11] * m[2] + t8;
473 *P.ptr<
double>(2, 1) = t33 - 2 * m[12] * m[3] + t13;
474 *P.ptr<
double>(3, 0) =
475 t15 - 2 * m[7] * m[4] + t1 + t18 - 2 * m[8] * m[5] + t5;
476 *P.ptr<
double>(3, 1) = t22 - 2 * m[9] * m[6] + t10;
477 *P.ptr<
double>(4, 0) =
478 t26 - 2 * m[10] * m[4] + t1 + t29 - 2 * m[11] * m[5] + t5;
479 *P.ptr<
double>(4, 1) = t33 - 2 * m[12] * m[6] + t10;
480 *P.ptr<
double>(5, 0) =
481 t26 - 2 * m[10] * m[7] + t15 + t29 - 2 * m[11] * m[8] + t18;
482 *P.ptr<
double>(5, 1) = t33 - 2 * m[12] * m[9] + t22;
487 Mat upnp::compute_constraint_distance_3param_6eq_6unk_f_unk(
488 const Mat& M1,
const Mat& M2)
490 Mat P = Mat(6, 6, CV_64F);
493 for (
int i = 1; i < 13; ++i)
495 m[1][i] = *M1.ptr<
double>(i - 1);
496 m[2][i] = *M2.ptr<
double>(i - 1);
499 double t1 = pow(m[1][4], 2);
500 double t2 = pow(m[1][1], 2);
501 double t7 = pow(m[1][5], 2);
502 double t8 = pow(m[1][2], 2);
503 double t11 = m[1][1] * m[2][1];
504 double t12 = m[1][5] * m[2][5];
505 double t15 = m[1][2] * m[2][2];
506 double t16 = m[1][4] * m[2][4];
507 double t19 = pow(m[2][4], 2);
508 double t22 = pow(m[2][2], 2);
509 double t23 = pow(m[2][1], 2);
510 double t24 = pow(m[2][5], 2);
511 double t28 = pow(m[1][6], 2);
512 double t29 = pow(m[1][3], 2);
513 double t34 = pow(m[1][3], 2);
514 double t36 = m[1][6] * m[2][6];
515 double t40 = pow(m[2][6], 2);
516 double t41 = pow(m[2][3], 2);
517 double t47 = pow(m[1][7], 2);
518 double t48 = pow(m[1][8], 2);
519 double t52 = m[1][7] * m[2][7];
520 double t55 = m[1][8] * m[2][8];
521 double t59 = pow(m[2][8], 2);
522 double t62 = pow(m[2][7], 2);
523 double t64 = pow(m[1][9], 2);
524 double t68 = m[1][9] * m[2][9];
525 double t74 = pow(m[2][9], 2);
526 double t78 = pow(m[1][10], 2);
527 double t79 = pow(m[1][11], 2);
528 double t84 = m[1][10] * m[2][10];
529 double t87 = m[1][11] * m[2][11];
530 double t90 = pow(m[2][10], 2);
531 double t95 = pow(m[2][11], 2);
532 double t99 = pow(m[1][12], 2);
533 double t101 = m[1][12] * m[2][12];
534 double t105 = pow(m[2][12], 2);
536 *P.ptr<
double>(0, 0) =
537 t1 + t2 - 2 * m[1][4] * m[1][1] - 2 * m[1][5] * m[1][2] + t7 + t8;
538 *P.ptr<
double>(0, 1) = -2 * m[2][4] * m[1][1] + 2 * t11 + 2 * t12 -
539 2 * m[1][4] * m[2][1] - 2 * m[2][5] * m[1][2] +
540 2 * t15 + 2 * t16 - 2 * m[1][5] * m[2][2];
541 *P.ptr<
double>(0, 2) =
542 t19 - 2 * m[2][4] * m[2][1] + t22 + t23 + t24 - 2 * m[2][5] * m[2][2];
543 *P.ptr<
double>(0, 3) = t28 + t29 - 2 * m[1][6] * m[1][3];
544 *P.ptr<
double>(0, 4) =
545 -2 * m[2][6] * m[1][3] + 2 * t34 - 2 * m[1][6] * m[2][3] + 2 * t36;
546 *P.ptr<
double>(0, 5) = -2 * m[2][6] * m[2][3] + t40 + t41;
548 *P.ptr<
double>(1, 0) =
549 t8 - 2 * m[1][8] * m[1][2] - 2 * m[1][7] * m[1][1] + t47 + t48 + t2;
550 *P.ptr<
double>(1, 1) =
551 2 * t15 - 2 * m[1][8] * m[2][2] - 2 * m[2][8] * m[1][2] + 2 * t52 -
552 2 * m[1][7] * m[2][1] - 2 * m[2][7] * m[1][1] + 2 * t55 + 2 * t11;
553 *P.ptr<
double>(1, 2) =
554 -2 * m[2][8] * m[2][2] + t22 + t23 + t59 - 2 * m[2][7] * m[2][1] + t62;
555 *P.ptr<
double>(1, 3) = t29 + t64 - 2 * m[1][9] * m[1][3];
556 *P.ptr<
double>(1, 4) =
557 2 * t34 + 2 * t68 - 2 * m[2][9] * m[1][3] - 2 * m[1][9] * m[2][3];
558 *P.ptr<
double>(1, 5) = -2 * m[2][9] * m[2][3] + t74 + t41;
560 *P.ptr<
double>(2, 0) =
561 -2 * m[1][11] * m[1][2] + t2 + t8 + t78 + t79 - 2 * m[1][10] * m[1][1];
562 *P.ptr<
double>(2, 1) = 2 * t15 - 2 * m[1][11] * m[2][2] + 2 * t84 -
563 2 * m[1][10] * m[2][1] - 2 * m[2][10] * m[1][1] +
564 2 * t87 - 2 * m[2][11] * m[1][2] + 2 * t11;
565 *P.ptr<
double>(2, 2) =
566 t90 + t22 - 2 * m[2][10] * m[2][1] + t23 - 2 * m[2][11] * m[2][2] + t95;
567 *P.ptr<
double>(2, 3) = -2 * m[1][12] * m[1][3] + t99 + t29;
568 *P.ptr<
double>(2, 4) =
569 2 * t34 + 2 * t101 - 2 * m[2][12] * m[1][3] - 2 * m[1][12] * m[2][3];
570 *P.ptr<
double>(2, 5) = t41 + t105 - 2 * m[2][12] * m[2][3];
572 *P.ptr<
double>(3, 0) =
573 t48 + t1 - 2 * m[1][8] * m[1][5] + t7 - 2 * m[1][7] * m[1][4] + t47;
574 *P.ptr<
double>(3, 1) = 2 * t16 - 2 * m[1][7] * m[2][4] + 2 * t55 + 2 * t52 -
575 2 * m[1][8] * m[2][5] - 2 * m[2][8] * m[1][5] -
576 2 * m[2][7] * m[1][4] + 2 * t12;
577 *P.ptr<
double>(3, 2) =
578 t24 - 2 * m[2][8] * m[2][5] + t19 - 2 * m[2][7] * m[2][4] + t62 + t59;
579 *P.ptr<
double>(3, 3) = -2 * m[1][9] * m[1][6] + t64 + t28;
580 *P.ptr<
double>(3, 4) =
581 2 * t68 + 2 * t36 - 2 * m[2][9] * m[1][6] - 2 * m[1][9] * m[2][6];
582 *P.ptr<
double>(3, 5) = t40 + t74 - 2 * m[2][9] * m[2][6];
584 *P.ptr<
double>(4, 0) =
585 t1 - 2 * m[1][10] * m[1][4] + t7 + t78 + t79 - 2 * m[1][11] * m[1][5];
586 *P.ptr<
double>(4, 1) =
587 2 * t84 - 2 * m[1][11] * m[2][5] - 2 * m[1][10] * m[2][4] + 2 * t16 -
588 2 * m[2][11] * m[1][5] + 2 * t87 - 2 * m[2][10] * m[1][4] + 2 * t12;
589 *P.ptr<
double>(4, 2) =
590 t19 + t24 - 2 * m[2][10] * m[2][4] - 2 * m[2][11] * m[2][5] + t95 + t90;
591 *P.ptr<
double>(4, 3) = t28 - 2 * m[1][12] * m[1][6] + t99;
592 *P.ptr<
double>(4, 4) =
593 2 * t101 + 2 * t36 - 2 * m[2][12] * m[1][6] - 2 * m[1][12] * m[2][6];
594 *P.ptr<
double>(4, 5) = t105 - 2 * m[2][12] * m[2][6] + t40;
596 *P.ptr<
double>(5, 0) = -2 * m[1][10] * m[1][7] + t47 + t48 + t78 + t79 -
597 2 * m[1][11] * m[1][8];
598 *P.ptr<
double>(5, 1) = 2 * t84 + 2 * t87 - 2 * m[2][11] * m[1][8] -
599 2 * m[1][10] * m[2][7] - 2 * m[2][10] * m[1][7] +
600 2 * t55 + 2 * t52 - 2 * m[1][11] * m[2][8];
601 *P.ptr<
double>(5, 2) = -2 * m[2][10] * m[2][7] - 2 * m[2][11] * m[2][8] +
602 t62 + t59 + t90 + t95;
603 *P.ptr<
double>(5, 3) = t64 - 2 * m[1][12] * m[1][9] + t99;
604 *P.ptr<
double>(5, 4) =
605 2 * t68 - 2 * m[2][12] * m[1][9] - 2 * m[1][12] * m[2][9] + 2 * t101;
606 *P.ptr<
double>(5, 5) = t105 - 2 * m[2][12] * m[2][9] + t74;
611 void upnp::generate_all_possible_solutions_for_f_unk(
612 const double betas[5],
double solutions[18][3])
614 int matrix_to_resolve[18][9] = {
615 {2, 0, 0, 1, 1, 0, 2, 0, 2}, {2, 0, 0, 1, 1, 0, 1, 1, 2},
616 {2, 0, 0, 1, 1, 0, 0, 2, 2}, {2, 0, 0, 0, 2, 0, 2, 0, 2},
617 {2, 0, 0, 0, 2, 0, 1, 1, 2}, {2, 0, 0, 0, 2, 0, 0, 2, 2},
618 {2, 0, 0, 2, 0, 2, 1, 1, 2}, {2, 0, 0, 2, 0, 2, 0, 2, 2},
619 {2, 0, 0, 1, 1, 2, 0, 2, 2}, {1, 1, 0, 0, 2, 0, 2, 0, 2},
620 {1, 1, 0, 0, 2, 0, 1, 1, 2}, {1, 1, 0, 2, 0, 2, 0, 2, 2},
621 {1, 1, 0, 2, 0, 2, 1, 1, 2}, {1, 1, 0, 2, 0, 2, 0, 2, 2},
622 {1, 1, 0, 1, 1, 2, 0, 2, 2}, {0, 2, 0, 2, 0, 2, 1, 1, 2},
623 {0, 2, 0, 2, 0, 2, 0, 2, 2}, {0, 2, 0, 1, 1, 2, 0, 2, 2}};
625 int combination[18][3] = {
626 {1, 2, 4}, {1, 2, 5}, {1, 2, 6}, {1, 3, 4}, {1, 3, 5}, {1, 3, 6},
627 {1, 4, 5}, {1, 4, 6}, {1, 5, 6}, {2, 3, 4}, {2, 3, 5}, {2, 3, 6},
628 {2, 4, 5}, {2, 4, 6}, {2, 5, 6}, {3, 4, 5}, {3, 4, 6}, {3, 5, 6}};
630 for (
int i = 0; i < 18; ++i)
632 double matrix[9], independent_term[3];
633 Mat M = Mat(3, 3, CV_64F,
matrix);
634 Mat I = Mat(3, 1, CV_64F, independent_term);
635 Mat S = Mat(1, 3, CV_64F);
637 for (
int j = 0; j < 9; ++j)
matrix[j] = (
double)matrix_to_resolve[i][j];
639 independent_term[0] = log(abs(betas[combination[i][0] - 1]));
640 independent_term[1] = log(abs(betas[combination[i][1] - 1]));
641 independent_term[2] = log(abs(betas[combination[i][2] - 1]));
643 exp(Mat(M.inv() * I), S);
645 solutions[i][0] = S.at<
double>(0);
646 solutions[i][1] = S.at<
double>(1) *
sign(betas[1]);
647 solutions[i][2] = abs(S.at<
double>(2));
651 void upnp::gauss_newton(
652 const Mat* L_6x12,
const Mat* Rho,
double betas[4],
double* f)
654 const int iterations_number = 50;
656 double a[6 * 4],
b[6],
x[4];
657 Mat* A =
new Mat(6, 4, CV_64F,
a);
658 Mat* B =
new Mat(6, 1, CV_64F,
b);
659 Mat* X =
new Mat(4, 1, CV_64F,
x);
661 for (
int k = 0; k < iterations_number; k++)
663 compute_A_and_b_gauss_newton(
664 L_6x12->ptr<
double>(0), Rho->ptr<
double>(0), betas, A, B, f[0]);
666 for (
int i = 0; i < 3; i++) betas[i] +=
x[i];
670 if (f[0] < 0) f[0] = -f[0];
683 void upnp::compute_A_and_b_gauss_newton(
684 const double* l_6x12,
const double* rho,
const double betas[4], Mat* A,
685 Mat*
b,
double const f)
687 for (
int i = 0; i < 6; i++)
689 const double* rowL = l_6x12 + i * 12;
690 double* rowA = A->ptr<
double>(i);
692 rowA[0] = 2 * rowL[0] * betas[0] + rowL[1] * betas[1] +
694 f * f * (2 * rowL[6] * betas[0] + rowL[7] * betas[1] +
696 rowA[1] = rowL[1] * betas[0] + 2 * rowL[3] * betas[1] +
698 f * f * (rowL[7] * betas[0] + 2 * rowL[9] * betas[1] +
699 rowL[10] * betas[2]);
700 rowA[2] = rowL[2] * betas[0] + rowL[4] * betas[1] +
701 2 * rowL[5] * betas[2] +
702 f * f * (rowL[8] * betas[0] + rowL[10] * betas[1] +
703 2 * rowL[11] * betas[2]);
706 (rowL[6] * betas[0] * betas[0] + rowL[7] * betas[0] * betas[1] +
707 rowL[8] * betas[0] * betas[2] + rowL[9] * betas[1] * betas[1] +
708 rowL[10] * betas[1] * betas[2] + rowL[11] * betas[2] * betas[2]);
712 (rowL[0] * betas[0] * betas[0] + rowL[1] * betas[0] * betas[1] +
713 rowL[2] * betas[0] * betas[2] + rowL[3] * betas[1] * betas[1] +
714 rowL[4] * betas[1] * betas[2] + rowL[5] * betas[2] * betas[2] +
715 f * f * rowL[6] * betas[0] * betas[0] +
716 f * f * rowL[7] * betas[0] * betas[1] +
717 f * f * rowL[8] * betas[0] * betas[2] +
718 f * f * rowL[9] * betas[1] * betas[1] +
719 f * f * rowL[10] * betas[1] * betas[2] +
720 f * f * rowL[11] * betas[2] * betas[2]);
724 void upnp::compute_L_6x12(
const double* ut,
double* l_6x12)
734 for (
int i = 0; i < 3; i++)
737 for (
int j = 0; j < 6; j++)
739 dv[i][j][0] =
v[i][3 *
a] -
v[i][3 *
b];
740 dv[i][j][1] =
v[i][3 *
a + 1] -
v[i][3 *
b + 1];
741 dv[i][j][2] =
v[i][3 *
a + 2] -
v[i][3 *
b + 2];
752 for (
int i = 0; i < 6; i++)
754 double*
row = l_6x12 + 12 * i;
756 row[0] = dotXY(dv[0][i], dv[0][i]);
757 row[1] = 2.0f * dotXY(dv[0][i], dv[1][i]);
758 row[2] = dotXY(dv[1][i], dv[1][i]);
759 row[3] = 2.0f * dotXY(dv[0][i], dv[2][i]);
760 row[4] = 2.0f * dotXY(dv[1][i], dv[2][i]);
761 row[5] = dotXY(dv[2][i], dv[2][i]);
763 row[6] = dotZ(dv[0][i], dv[0][i]);
764 row[7] = 2.0f * dotZ(dv[0][i], dv[1][i]);
765 row[8] = 2.0f * dotZ(dv[0][i], dv[2][i]);
766 row[9] = dotZ(dv[1][i], dv[1][i]);
767 row[10] = 2.0f * dotZ(dv[1][i], dv[2][i]);
768 row[11] = dotZ(dv[2][i], dv[2][i]);
772 void upnp::compute_rho(
double* rho)
774 rho[0] = dist2(cws[0], cws[1]);
775 rho[1] = dist2(cws[0], cws[2]);
776 rho[2] = dist2(cws[0], cws[3]);
777 rho[3] = dist2(cws[1], cws[2]);
778 rho[4] = dist2(cws[1], cws[3]);
779 rho[5] = dist2(cws[2], cws[3]);
782 double upnp::dist2(
const double* p1,
const double* p2)
784 return (p1[0] - p2[0]) * (p1[0] - p2[0]) +
785 (p1[1] - p2[1]) * (p1[1] - p2[1]) +
786 (p1[2] - p2[2]) * (p1[2] - p2[2]);
789 double upnp::dot(
const double*
v1,
const double*
v2)
794 double upnp::dotXY(
const double*
v1,
const double*
v2)
796 return v1[0] *
v2[0] +
v1[1] *
v2[1];
799 double upnp::dotZ(
const double*
v1,
const double*
v2) {
return v1[2] *
v2[2]; }
802 return (
v < 0.0) ? -1.0 : (
v > 0.0) ? 1.0 : 0.0;
805 void upnp::qr_solve(Mat* A, Mat*
b, Mat* X)
807 const int nr = A->rows;
808 const int nc = A->cols;
810 if (max_nr != 0 && max_nr < nr)
822 double *pA = A->ptr<
double>(0), *ppAkk = pA;
823 for (
int k = 0; k < nc; k++)
825 double *ppAik1 = ppAkk, eta = fabs(*ppAik1);
826 for (
int i = k + 1; i < nr; i++)
828 double elt = fabs(*ppAik1);
829 if (eta < elt) eta = elt;
841 double *ppAik2 = ppAkk, sum2 = 0.0, inv_eta = 1. / eta;
842 for (
int i = k; i < nr; i++)
845 sum2 += *ppAik2 * *ppAik2;
848 double sigma = sqrt(sum2);
849 if (*ppAkk < 0) sigma = -sigma;
851 A1[k] = sigma * *ppAkk;
852 A2[k] = -eta * sigma;
853 for (
int j = k + 1; j < nc; j++)
855 double *ppAik = ppAkk,
sum = 0;
856 for (
int i = k; i < nr; i++)
858 sum += *ppAik * ppAik[j - k];
861 double tau =
sum /
A1[k];
863 for (
int i = k; i < nr; i++)
865 ppAik[j - k] -= tau * *ppAik;
874 double *ppAjj = pA, *pb =
b->ptr<
double>(0);
875 for (
int j = 0; j < nc; j++)
877 double *ppAij = ppAjj, tau = 0;
878 for (
int i = j; i < nr; i++)
880 tau += *ppAij * pb[i];
885 for (
int i = j; i < nr; i++)
887 pb[i] -= tau * *ppAij;
894 double* pX = X->ptr<
double>(0);
895 pX[nc - 1] = pb[nc - 1] / A2[nc - 1];
896 for (
int i = nc - 2; i >= 0; i--)
898 double *ppAij = pA + i * nc + (i + 1),
sum = 0;
900 for (
int j = i + 1; j < nc; j++)
902 sum += *ppAij * pX[j];
905 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 mrpt_vision_grp.
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".
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