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