1 //M*////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // 10 // License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000, Intel Corporation, all rights reserved. 14 // Copyright (C) 2013, OpenCV Foundation, all rights reserved. 15 // Third party copyrights are property of their respective owners. 16 // 17 // Redistribution and use in source and binary forms, with or without modification, 18 // are permitted provided that the following conditions are met: 19 // 20 // * Redistribution's of source code must retain the above copyright notice, 21 // this list of conditions and the following disclaimer. 22 // 23 // * Redistribution's in binary form must reproduce the above copyright notice, 24 // this list of conditions and the following disclaimer in the documentation 25 // and/or other materials provided with the distribution. 26 // 27 // * The name of the copyright holders may not be used to endorse or promote products 28 // derived from this software without specific prior written permission. 29 // 30 // This software is provided by the copyright holders and contributors "as is" and 31 // any express or implied warranties, including, but not limited to, the implied 32 // warranties of merchantability and fitness for a particular purpose are disclaimed. 33 // In no event shall the Intel Corporation or contributors be liable for any direct, 34 // indirect, incidental, special, exemplary, or consequential damages 35 // (including, but not limited to, procurement of substitute goods or services; 36 // loss of use, data, or profits; or business interruption) however caused 37 // and on any theory of liability, whether in contract, strict liability, 38 // or tort (including negligence or otherwise) arising in any way out of 39 // the use of this software, even if advised of the possibility of such damage. 40 // 41 //M*/ 42 43 /****************************************************************************************\ 44 * Exhaustive Linearization for Robust Camera Pose and Focal Length Estimation. 45 * Contributed by Edgar Riba 46 \****************************************************************************************/ 47 48 #include "precomp.hpp" 49 #include "upnp.h" 50 #include <limits> 51 52 using namespace std; 53 using namespace cv; 54 55 upnp::upnp(const Mat& cameraMatrix, const Mat& opoints, const Mat& ipoints) 56 { 57 if (cameraMatrix.depth() == CV_32F) 58 init_camera_parameters<float>(cameraMatrix); 59 else 60 init_camera_parameters<double>(cameraMatrix); 61 62 number_of_correspondences = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F)); 63 64 pws.resize(3 * number_of_correspondences); 65 us.resize(2 * number_of_correspondences); 66 67 if (opoints.depth() == ipoints.depth()) 68 { 69 if (opoints.depth() == CV_32F) 70 init_points<Point3f,Point2f>(opoints, ipoints); 71 else 72 init_points<Point3d,Point2d>(opoints, ipoints); 73 } 74 else if (opoints.depth() == CV_32F) 75 init_points<Point3f,Point2d>(opoints, ipoints); 76 else 77 init_points<Point3d,Point2f>(opoints, ipoints); 78 79 alphas.resize(4 * number_of_correspondences); 80 pcs.resize(3 * number_of_correspondences); 81 82 max_nr = 0; 83 A1 = NULL; 84 A2 = NULL; 85 } 86 87 upnp::~upnp() 88 { 89 if (A1) 90 delete[] A1; 91 if (A2) 92 delete[] A2; 93 } 94 95 double upnp::compute_pose(Mat& R, Mat& t) 96 { 97 choose_control_points(); 98 compute_alphas(); 99 100 Mat * M = new Mat(2 * number_of_correspondences, 12, CV_64F); 101 102 for(int i = 0; i < number_of_correspondences; i++) 103 { 104 fill_M(M, 2 * i, &alphas[0] + 4 * i, us[2 * i], us[2 * i + 1]); 105 } 106 107 double mtm[12 * 12], d[12], ut[12 * 12], vt[12 * 12]; 108 Mat MtM = Mat(12, 12, CV_64F, mtm); 109 Mat D = Mat(12, 1, CV_64F, d); 110 Mat Ut = Mat(12, 12, CV_64F, ut); 111 Mat Vt = Mat(12, 12, CV_64F, vt); 112 113 MtM = M->t() * (*M); 114 SVD::compute(MtM, D, Ut, Vt, SVD::MODIFY_A | SVD::FULL_UV); 115 Mat(Ut.t()).copyTo(Ut); 116 M->release(); 117 118 double l_6x12[6 * 12], rho[6]; 119 Mat L_6x12 = Mat(6, 12, CV_64F, l_6x12); 120 Mat Rho = Mat(6, 1, CV_64F, rho); 121 122 compute_L_6x12(ut, l_6x12); 123 compute_rho(rho); 124 125 double Betas[3][4], Efs[3][1], rep_errors[3]; 126 double Rs[3][3][3], ts[3][3]; 127 128 find_betas_and_focal_approx_1(&Ut, &Rho, Betas[1], Efs[1]); 129 gauss_newton(&L_6x12, &Rho, Betas[1], Efs[1]); 130 rep_errors[1] = compute_R_and_t(ut, Betas[1], Rs[1], ts[1]); 131 132 find_betas_and_focal_approx_2(&Ut, &Rho, Betas[2], Efs[2]); 133 gauss_newton(&L_6x12, &Rho, Betas[2], Efs[2]); 134 rep_errors[2] = compute_R_and_t(ut, Betas[2], Rs[2], ts[2]); 135 136 int N = 1; 137 if (rep_errors[2] < rep_errors[1]) N = 2; 138 139 Mat(3, 1, CV_64F, ts[N]).copyTo(t); 140 Mat(3, 3, CV_64F, Rs[N]).copyTo(R); 141 fu = fv = Efs[N][0]; 142 143 return fu; 144 } 145 146 void upnp::copy_R_and_t(const double R_src[3][3], const double t_src[3], 147 double R_dst[3][3], double t_dst[3]) 148 { 149 for(int i = 0; i < 3; i++) { 150 for(int j = 0; j < 3; j++) 151 R_dst[i][j] = R_src[i][j]; 152 t_dst[i] = t_src[i]; 153 } 154 } 155 156 void upnp::estimate_R_and_t(double R[3][3], double t[3]) 157 { 158 double pc0[3], pw0[3]; 159 160 pc0[0] = pc0[1] = pc0[2] = 0.0; 161 pw0[0] = pw0[1] = pw0[2] = 0.0; 162 163 for(int i = 0; i < number_of_correspondences; i++) { 164 const double * pc = &pcs[3 * i]; 165 const double * pw = &pws[3 * i]; 166 167 for(int j = 0; j < 3; j++) { 168 pc0[j] += pc[j]; 169 pw0[j] += pw[j]; 170 } 171 } 172 for(int j = 0; j < 3; j++) { 173 pc0[j] /= number_of_correspondences; 174 pw0[j] /= number_of_correspondences; 175 } 176 177 double abt[3 * 3], abt_d[3], abt_u[3 * 3], abt_v[3 * 3]; 178 Mat ABt = Mat(3, 3, CV_64F, abt); 179 Mat ABt_D = Mat(3, 1, CV_64F, abt_d); 180 Mat ABt_U = Mat(3, 3, CV_64F, abt_u); 181 Mat ABt_V = Mat(3, 3, CV_64F, abt_v); 182 183 ABt.setTo(0.0); 184 for(int i = 0; i < number_of_correspondences; i++) { 185 double * pc = &pcs[3 * i]; 186 double * pw = &pws[3 * i]; 187 188 for(int j = 0; j < 3; j++) { 189 abt[3 * j ] += (pc[j] - pc0[j]) * (pw[0] - pw0[0]); 190 abt[3 * j + 1] += (pc[j] - pc0[j]) * (pw[1] - pw0[1]); 191 abt[3 * j + 2] += (pc[j] - pc0[j]) * (pw[2] - pw0[2]); 192 } 193 } 194 195 SVD::compute(ABt, ABt_D, ABt_U, ABt_V, SVD::MODIFY_A); 196 Mat(ABt_V.t()).copyTo(ABt_V); 197 198 for(int i = 0; i < 3; i++) 199 for(int j = 0; j < 3; j++) 200 R[i][j] = dot(abt_u + 3 * i, abt_v + 3 * j); 201 202 const double det = 203 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] - 204 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]; 205 206 if (det < 0) { 207 R[2][0] = -R[2][0]; 208 R[2][1] = -R[2][1]; 209 R[2][2] = -R[2][2]; 210 } 211 212 t[0] = pc0[0] - dot(R[0], pw0); 213 t[1] = pc0[1] - dot(R[1], pw0); 214 t[2] = pc0[2] - dot(R[2], pw0); 215 } 216 217 void upnp::solve_for_sign(void) 218 { 219 if (pcs[2] < 0.0) { 220 for(int i = 0; i < 4; i++) 221 for(int j = 0; j < 3; j++) 222 ccs[i][j] = -ccs[i][j]; 223 224 for(int i = 0; i < number_of_correspondences; i++) { 225 pcs[3 * i ] = -pcs[3 * i]; 226 pcs[3 * i + 1] = -pcs[3 * i + 1]; 227 pcs[3 * i + 2] = -pcs[3 * i + 2]; 228 } 229 } 230 } 231 232 double upnp::compute_R_and_t(const double * ut, const double * betas, 233 double R[3][3], double t[3]) 234 { 235 compute_ccs(betas, ut); 236 compute_pcs(); 237 238 solve_for_sign(); 239 240 estimate_R_and_t(R, t); 241 242 return reprojection_error(R, t); 243 } 244 245 double upnp::reprojection_error(const double R[3][3], const double t[3]) 246 { 247 double sum2 = 0.0; 248 249 for(int i = 0; i < number_of_correspondences; i++) { 250 double * pw = &pws[3 * i]; 251 double Xc = dot(R[0], pw) + t[0]; 252 double Yc = dot(R[1], pw) + t[1]; 253 double inv_Zc = 1.0 / (dot(R[2], pw) + t[2]); 254 double ue = uc + fu * Xc * inv_Zc; 255 double ve = vc + fv * Yc * inv_Zc; 256 double u = us[2 * i], v = us[2 * i + 1]; 257 258 sum2 += sqrt( (u - ue) * (u - ue) + (v - ve) * (v - ve) ); 259 } 260 261 return sum2 / number_of_correspondences; 262 } 263 264 void upnp::choose_control_points() 265 { 266 for (int i = 0; i < 4; ++i) 267 cws[i][0] = cws[i][1] = cws[i][2] = 0.0; 268 cws[0][0] = cws[1][1] = cws[2][2] = 1.0; 269 } 270 271 void upnp::compute_alphas() 272 { 273 Mat CC = Mat(4, 3, CV_64F, &cws); 274 Mat PC = Mat(number_of_correspondences, 3, CV_64F, &pws[0]); 275 Mat ALPHAS = Mat(number_of_correspondences, 4, CV_64F, &alphas[0]); 276 277 Mat CC_ = CC.clone().t(); 278 Mat PC_ = PC.clone().t(); 279 280 Mat row14 = Mat::ones(1, 4, CV_64F); 281 Mat row1n = Mat::ones(1, number_of_correspondences, CV_64F); 282 283 CC_.push_back(row14); 284 PC_.push_back(row1n); 285 286 ALPHAS = Mat( CC_.inv() * PC_ ).t(); 287 } 288 289 void upnp::fill_M(Mat * M, const int row, const double * as, const double u, const double v) 290 { 291 double * M1 = M->ptr<double>(row); 292 double * M2 = M1 + 12; 293 294 for(int i = 0; i < 4; i++) { 295 M1[3 * i ] = as[i] * fu; 296 M1[3 * i + 1] = 0.0; 297 M1[3 * i + 2] = as[i] * (uc - u); 298 299 M2[3 * i ] = 0.0; 300 M2[3 * i + 1] = as[i] * fv; 301 M2[3 * i + 2] = as[i] * (vc - v); 302 } 303 } 304 305 void upnp::compute_ccs(const double * betas, const double * ut) 306 { 307 for(int i = 0; i < 4; ++i) 308 ccs[i][0] = ccs[i][1] = ccs[i][2] = 0.0; 309 310 int N = 4; 311 for(int i = 0; i < N; ++i) { 312 const double * v = ut + 12 * (9 + i); 313 for(int j = 0; j < 4; ++j) 314 for(int k = 0; k < 3; ++k) 315 ccs[j][k] += betas[i] * v[3 * j + k]; 316 } 317 318 for (int i = 0; i < 4; ++i) ccs[i][2] *= fu; 319 } 320 321 void upnp::compute_pcs(void) 322 { 323 for(int i = 0; i < number_of_correspondences; i++) { 324 double * a = &alphas[0] + 4 * i; 325 double * pc = &pcs[0] + 3 * i; 326 327 for(int j = 0; j < 3; j++) 328 pc[j] = a[0] * ccs[0][j] + a[1] * ccs[1][j] + a[2] * ccs[2][j] + a[3] * ccs[3][j]; 329 } 330 } 331 332 void upnp::find_betas_and_focal_approx_1(Mat * Ut, Mat * Rho, double * betas, double * efs) 333 { 334 Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<double>(11)); 335 Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<double>(0)); 336 337 Mat D = compute_constraint_distance_2param_6eq_2unk_f_unk( Kmf1 ); 338 Mat Dt = D.t(); 339 340 Mat A = Dt * D; 341 Mat b = Dt * dsq; 342 343 Mat x = Mat(2, 1, CV_64F); 344 solve(A, b, x); 345 346 betas[0] = sqrt( abs( x.at<double>(0) ) ); 347 betas[1] = betas[2] = betas[3] = 0.0; 348 349 efs[0] = sqrt( abs( x.at<double>(1) ) ) / betas[0]; 350 } 351 352 void upnp::find_betas_and_focal_approx_2(Mat * Ut, Mat * Rho, double * betas, double * efs) 353 { 354 double u[12*12]; 355 Mat U = Mat(12, 12, CV_64F, u); 356 Ut->copyTo(U); 357 358 Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<double>(10)); 359 Mat Kmf2 = Mat(12, 1, CV_64F, Ut->ptr<double>(11)); 360 Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<double>(0)); 361 362 Mat D = compute_constraint_distance_3param_6eq_6unk_f_unk( Kmf1, Kmf2 ); 363 364 Mat A = D; 365 Mat b = dsq; 366 367 double x[6]; 368 Mat X = Mat(6, 1, CV_64F, x); 369 370 solve(A, b, X, DECOMP_QR); 371 372 double solutions[18][3]; 373 generate_all_possible_solutions_for_f_unk(x, solutions); 374 375 // find solution with minimum reprojection error 376 double min_error = std::numeric_limits<double>::max(); 377 int min_sol = 0; 378 for (int i = 0; i < 18; ++i) { 379 380 betas[3] = solutions[i][0]; 381 betas[2] = solutions[i][1]; 382 betas[1] = betas[0] = 0.0; 383 fu = fv = solutions[i][2]; 384 385 double Rs[3][3], ts[3]; 386 double error_i = compute_R_and_t( u, betas, Rs, ts); 387 388 if( error_i < min_error) 389 { 390 min_error = error_i; 391 min_sol = i; 392 } 393 } 394 395 betas[0] = solutions[min_sol][0]; 396 betas[1] = solutions[min_sol][1]; 397 betas[2] = betas[3] = 0.0; 398 399 efs[0] = solutions[min_sol][2]; 400 } 401 402 Mat upnp::compute_constraint_distance_2param_6eq_2unk_f_unk(const Mat& M1) 403 { 404 Mat P = Mat(6, 2, CV_64F); 405 406 double m[13]; 407 for (int i = 1; i < 13; ++i) m[i] = *M1.ptr<double>(i-1); 408 409 double t1 = pow( m[4], 2 ); 410 double t4 = pow( m[1], 2 ); 411 double t5 = pow( m[5], 2 ); 412 double t8 = pow( m[2], 2 ); 413 double t10 = pow( m[6], 2 ); 414 double t13 = pow( m[3], 2 ); 415 double t15 = pow( m[7], 2 ); 416 double t18 = pow( m[8], 2 ); 417 double t22 = pow( m[9], 2 ); 418 double t26 = pow( m[10], 2 ); 419 double t29 = pow( m[11], 2 ); 420 double t33 = pow( m[12], 2 ); 421 422 *P.ptr<double>(0,0) = t1 - 2 * m[4] * m[1] + t4 + t5 - 2 * m[5] * m[2] + t8; 423 *P.ptr<double>(0,1) = t10 - 2 * m[6] * m[3] + t13; 424 *P.ptr<double>(1,0) = t15 - 2 * m[7] * m[1] + t4 + t18 - 2 * m[8] * m[2] + t8; 425 *P.ptr<double>(1,1) = t22 - 2 * m[9] * m[3] + t13; 426 *P.ptr<double>(2,0) = t26 - 2 * m[10] * m[1] + t4 + t29 - 2 * m[11] * m[2] + t8; 427 *P.ptr<double>(2,1) = t33 - 2 * m[12] * m[3] + t13; 428 *P.ptr<double>(3,0) = t15 - 2 * m[7] * m[4] + t1 + t18 - 2 * m[8] * m[5] + t5; 429 *P.ptr<double>(3,1) = t22 - 2 * m[9] * m[6] + t10; 430 *P.ptr<double>(4,0) = t26 - 2 * m[10] * m[4] + t1 + t29 - 2 * m[11] * m[5] + t5; 431 *P.ptr<double>(4,1) = t33 - 2 * m[12] * m[6] + t10; 432 *P.ptr<double>(5,0) = t26 - 2 * m[10] * m[7] + t15 + t29 - 2 * m[11] * m[8] + t18; 433 *P.ptr<double>(5,1) = t33 - 2 * m[12] * m[9] + t22; 434 435 return P; 436 } 437 438 Mat upnp::compute_constraint_distance_3param_6eq_6unk_f_unk(const Mat& M1, const Mat& M2) 439 { 440 Mat P = Mat(6, 6, CV_64F); 441 442 double m[3][13]; 443 for (int i = 1; i < 13; ++i) 444 { 445 m[1][i] = *M1.ptr<double>(i-1); 446 m[2][i] = *M2.ptr<double>(i-1); 447 } 448 449 double t1 = pow( m[1][4], 2 ); 450 double t2 = pow( m[1][1], 2 ); 451 double t7 = pow( m[1][5], 2 ); 452 double t8 = pow( m[1][2], 2 ); 453 double t11 = m[1][1] * m[2][1]; 454 double t12 = m[1][5] * m[2][5]; 455 double t15 = m[1][2] * m[2][2]; 456 double t16 = m[1][4] * m[2][4]; 457 double t19 = pow( m[2][4], 2 ); 458 double t22 = pow( m[2][2], 2 ); 459 double t23 = pow( m[2][1], 2 ); 460 double t24 = pow( m[2][5], 2 ); 461 double t28 = pow( m[1][6], 2 ); 462 double t29 = pow( m[1][3], 2 ); 463 double t34 = pow( m[1][3], 2 ); 464 double t36 = m[1][6] * m[2][6]; 465 double t40 = pow( m[2][6], 2 ); 466 double t41 = pow( m[2][3], 2 ); 467 double t47 = pow( m[1][7], 2 ); 468 double t48 = pow( m[1][8], 2 ); 469 double t52 = m[1][7] * m[2][7]; 470 double t55 = m[1][8] * m[2][8]; 471 double t59 = pow( m[2][8], 2 ); 472 double t62 = pow( m[2][7], 2 ); 473 double t64 = pow( m[1][9], 2 ); 474 double t68 = m[1][9] * m[2][9]; 475 double t74 = pow( m[2][9], 2 ); 476 double t78 = pow( m[1][10], 2 ); 477 double t79 = pow( m[1][11], 2 ); 478 double t84 = m[1][10] * m[2][10]; 479 double t87 = m[1][11] * m[2][11]; 480 double t90 = pow( m[2][10], 2 ); 481 double t95 = pow( m[2][11], 2 ); 482 double t99 = pow( m[1][12], 2 ); 483 double t101 = m[1][12] * m[2][12]; 484 double t105 = pow( m[2][12], 2 ); 485 486 *P.ptr<double>(0,0) = t1 + t2 - 2 * m[1][4] * m[1][1] - 2 * m[1][5] * m[1][2] + t7 + t8; 487 *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]; 488 *P.ptr<double>(0,2) = t19 - 2 * m[2][4] * m[2][1] + t22 + t23 + t24 - 2 * m[2][5] * m[2][2]; 489 *P.ptr<double>(0,3) = t28 + t29 - 2 * m[1][6] * m[1][3]; 490 *P.ptr<double>(0,4) = -2 * m[2][6] * m[1][3] + 2 * t34 - 2 * m[1][6] * m[2][3] + 2 * t36; 491 *P.ptr<double>(0,5) = -2 * m[2][6] * m[2][3] + t40 + t41; 492 493 *P.ptr<double>(1,0) = t8 - 2 * m[1][8] * m[1][2] - 2 * m[1][7] * m[1][1] + t47 + t48 + t2; 494 *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; 495 *P.ptr<double>(1,2) = -2 * m[2][8] * m[2][2] + t22 + t23 + t59 - 2 * m[2][7] * m[2][1] + t62; 496 *P.ptr<double>(1,3) = t29 + t64 - 2 * m[1][9] * m[1][3]; 497 *P.ptr<double>(1,4) = 2 * t34 + 2 * t68 - 2 * m[2][9] * m[1][3] - 2 * m[1][9] * m[2][3]; 498 *P.ptr<double>(1,5) = -2 * m[2][9] * m[2][3] + t74 + t41; 499 500 *P.ptr<double>(2,0) = -2 * m[1][11] * m[1][2] + t2 + t8 + t78 + t79 - 2 * m[1][10] * m[1][1]; 501 *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; 502 *P.ptr<double>(2,2) = t90 + t22 - 2 * m[2][10] * m[2][1] + t23 - 2 * m[2][11] * m[2][2] + t95; 503 *P.ptr<double>(2,3) = -2 * m[1][12] * m[1][3] + t99 + t29; 504 *P.ptr<double>(2,4) = 2 * t34 + 2 * t101 - 2 * m[2][12] * m[1][3] - 2 * m[1][12] * m[2][3]; 505 *P.ptr<double>(2,5) = t41 + t105 - 2 * m[2][12] * m[2][3]; 506 507 *P.ptr<double>(3,0) = t48 + t1 - 2 * m[1][8] * m[1][5] + t7 - 2 * m[1][7] * m[1][4] + t47; 508 *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; 509 *P.ptr<double>(3,2) = t24 - 2 * m[2][8] * m[2][5] + t19 - 2 * m[2][7] * m[2][4] + t62 + t59; 510 *P.ptr<double>(3,3) = -2 * m[1][9] * m[1][6] + t64 + t28; 511 *P.ptr<double>(3,4) = 2 * t68 + 2 * t36 - 2 * m[2][9] * m[1][6] - 2 * m[1][9] * m[2][6]; 512 *P.ptr<double>(3,5) = t40 + t74 - 2 * m[2][9] * m[2][6]; 513 514 *P.ptr<double>(4,0) = t1 - 2 * m[1][10] * m[1][4] + t7 + t78 + t79 - 2 * m[1][11] * m[1][5]; 515 *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; 516 *P.ptr<double>(4,2) = t19 + t24 - 2 * m[2][10] * m[2][4] - 2 * m[2][11] * m[2][5] + t95 + t90; 517 *P.ptr<double>(4,3) = t28 - 2 * m[1][12] * m[1][6] + t99; 518 *P.ptr<double>(4,4) = 2 * t101 + 2 * t36 - 2 * m[2][12] * m[1][6] - 2 * m[1][12] * m[2][6]; 519 *P.ptr<double>(4,5) = t105 - 2 * m[2][12] * m[2][6] + t40; 520 521 *P.ptr<double>(5,0) = -2 * m[1][10] * m[1][7] + t47 + t48 + t78 + t79 - 2 * m[1][11] * m[1][8]; 522 *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]; 523 *P.ptr<double>(5,2) = -2 * m[2][10] * m[2][7] - 2 * m[2][11] * m[2][8] + t62 + t59 + t90 + t95; 524 *P.ptr<double>(5,3) = t64 - 2 * m[1][12] * m[1][9] + t99; 525 *P.ptr<double>(5,4) = 2 * t68 - 2 * m[2][12] * m[1][9] - 2 * m[1][12] * m[2][9] + 2 * t101; 526 *P.ptr<double>(5,5) = t105 - 2 * m[2][12] * m[2][9] + t74; 527 528 return P; 529 } 530 531 void upnp::generate_all_possible_solutions_for_f_unk(const double betas[5], double solutions[18][3]) 532 { 533 int matrix_to_resolve[18][9] = { 534 { 2, 0, 0, 1, 1, 0, 2, 0, 2 }, { 2, 0, 0, 1, 1, 0, 1, 1, 2 }, 535 { 2, 0, 0, 1, 1, 0, 0, 2, 2 }, { 2, 0, 0, 0, 2, 0, 2, 0, 2 }, 536 { 2, 0, 0, 0, 2, 0, 1, 1, 2 }, { 2, 0, 0, 0, 2, 0, 0, 2, 2 }, 537 { 2, 0, 0, 2, 0, 2, 1, 1, 2 }, { 2, 0, 0, 2, 0, 2, 0, 2, 2 }, 538 { 2, 0, 0, 1, 1, 2, 0, 2, 2 }, { 1, 1, 0, 0, 2, 0, 2, 0, 2 }, 539 { 1, 1, 0, 0, 2, 0, 1, 1, 2 }, { 1, 1, 0, 2, 0, 2, 0, 2, 2 }, 540 { 1, 1, 0, 2, 0, 2, 1, 1, 2 }, { 1, 1, 0, 2, 0, 2, 0, 2, 2 }, 541 { 1, 1, 0, 1, 1, 2, 0, 2, 2 }, { 0, 2, 0, 2, 0, 2, 1, 1, 2 }, 542 { 0, 2, 0, 2, 0, 2, 0, 2, 2 }, { 0, 2, 0, 1, 1, 2, 0, 2, 2 } 543 }; 544 545 int combination[18][3] = { 546 { 1, 2, 4 }, { 1, 2, 5 }, { 1, 2, 6 }, { 1, 3, 4 }, 547 { 1, 3, 5 }, { 1, 3, 6 }, { 1, 4, 5 }, { 1, 4, 6 }, 548 { 1, 5, 6 }, { 2, 3, 4 }, { 2, 3, 5 }, { 2, 3, 6 }, 549 { 2, 4, 5 }, { 2, 4, 6 }, { 2, 5, 6 }, { 3, 4, 5 }, 550 { 3, 4, 6 }, { 3, 5, 6 } 551 }; 552 553 for (int i = 0; i < 18; ++i) { 554 double matrix[9], independent_term[3]; 555 Mat M = Mat(3, 3, CV_64F, matrix); 556 Mat I = Mat(3, 1, CV_64F, independent_term); 557 Mat S = Mat(1, 3, CV_64F); 558 559 for (int j = 0; j < 9; ++j) matrix[j] = (double)matrix_to_resolve[i][j]; 560 561 independent_term[0] = log( abs( betas[ combination[i][0]-1 ] ) ); 562 independent_term[1] = log( abs( betas[ combination[i][1]-1 ] ) ); 563 independent_term[2] = log( abs( betas[ combination[i][2]-1 ] ) ); 564 565 exp( Mat(M.inv() * I), S); 566 567 solutions[i][0] = S.at<double>(0); 568 solutions[i][1] = S.at<double>(1) * sign( betas[1] ); 569 solutions[i][2] = abs( S.at<double>(2) ); 570 } 571 } 572 573 void upnp::gauss_newton(const Mat * L_6x12, const Mat * Rho, double betas[4], double * f) 574 { 575 const int iterations_number = 50; 576 577 double a[6*4], b[6], x[4]; 578 Mat * A = new Mat(6, 4, CV_64F, a); 579 Mat * B = new Mat(6, 1, CV_64F, b); 580 Mat * X = new Mat(4, 1, CV_64F, x); 581 582 for(int k = 0; k < iterations_number; k++) 583 { 584 compute_A_and_b_gauss_newton(L_6x12->ptr<double>(0), Rho->ptr<double>(0), betas, A, B, f[0]); 585 qr_solve(A, B, X); 586 for(int i = 0; i < 3; i++) 587 betas[i] += x[i]; 588 f[0] += x[3]; 589 } 590 591 if (f[0] < 0) f[0] = -f[0]; 592 fu = fv = f[0]; 593 594 } 595 596 void upnp::compute_A_and_b_gauss_newton(const double * l_6x12, const double * rho, 597 const double betas[4], Mat * A, Mat * b, double const f) 598 { 599 600 for(int i = 0; i < 6; i++) { 601 const double * rowL = l_6x12 + i * 12; 602 double * rowA = A->ptr<double>(i); 603 604 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] ); 605 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] ); 606 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] ); 607 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] ) ; 608 609 *b->ptr<double>(i) = rho[i] - 610 ( 611 rowL[0] * betas[0] * betas[0] + 612 rowL[1] * betas[0] * betas[1] + 613 rowL[2] * betas[0] * betas[2] + 614 rowL[3] * betas[1] * betas[1] + 615 rowL[4] * betas[1] * betas[2] + 616 rowL[5] * betas[2] * betas[2] + 617 f*f * rowL[6] * betas[0] * betas[0] + 618 f*f * rowL[7] * betas[0] * betas[1] + 619 f*f * rowL[8] * betas[0] * betas[2] + 620 f*f * rowL[9] * betas[1] * betas[1] + 621 f*f * rowL[10] * betas[1] * betas[2] + 622 f*f * rowL[11] * betas[2] * betas[2] 623 ); 624 } 625 } 626 627 void upnp::compute_L_6x12(const double * ut, double * l_6x12) 628 { 629 const double * v[3]; 630 631 v[0] = ut + 12 * 9; 632 v[1] = ut + 12 * 10; 633 v[2] = ut + 12 * 11; 634 635 double dv[3][6][3]; 636 637 for(int i = 0; i < 3; i++) { 638 int a = 0, b = 1; 639 for(int j = 0; j < 6; j++) { 640 dv[i][j][0] = v[i][3 * a ] - v[i][3 * b]; 641 dv[i][j][1] = v[i][3 * a + 1] - v[i][3 * b + 1]; 642 dv[i][j][2] = v[i][3 * a + 2] - v[i][3 * b + 2]; 643 644 b++; 645 if (b > 3) { 646 a++; 647 b = a + 1; 648 } 649 } 650 } 651 652 for(int i = 0; i < 6; i++) { 653 double * row = l_6x12 + 12 * i; 654 655 row[0] = dotXY(dv[0][i], dv[0][i]); 656 row[1] = 2.0f * dotXY(dv[0][i], dv[1][i]); 657 row[2] = dotXY(dv[1][i], dv[1][i]); 658 row[3] = 2.0f * dotXY(dv[0][i], dv[2][i]); 659 row[4] = 2.0f * dotXY(dv[1][i], dv[2][i]); 660 row[5] = dotXY(dv[2][i], dv[2][i]); 661 662 row[6] = dotZ(dv[0][i], dv[0][i]); 663 row[7] = 2.0f * dotZ(dv[0][i], dv[1][i]); 664 row[8] = 2.0f * dotZ(dv[0][i], dv[2][i]); 665 row[9] = dotZ(dv[1][i], dv[1][i]); 666 row[10] = 2.0f * dotZ(dv[1][i], dv[2][i]); 667 row[11] = dotZ(dv[2][i], dv[2][i]); 668 } 669 } 670 671 void upnp::compute_rho(double * rho) 672 { 673 rho[0] = dist2(cws[0], cws[1]); 674 rho[1] = dist2(cws[0], cws[2]); 675 rho[2] = dist2(cws[0], cws[3]); 676 rho[3] = dist2(cws[1], cws[2]); 677 rho[4] = dist2(cws[1], cws[3]); 678 rho[5] = dist2(cws[2], cws[3]); 679 } 680 681 double upnp::dist2(const double * p1, const double * p2) 682 { 683 return 684 (p1[0] - p2[0]) * (p1[0] - p2[0]) + 685 (p1[1] - p2[1]) * (p1[1] - p2[1]) + 686 (p1[2] - p2[2]) * (p1[2] - p2[2]); 687 } 688 689 double upnp::dot(const double * v1, const double * v2) 690 { 691 return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; 692 } 693 694 double upnp::dotXY(const double * v1, const double * v2) 695 { 696 return v1[0] * v2[0] + v1[1] * v2[1]; 697 } 698 699 double upnp::dotZ(const double * v1, const double * v2) 700 { 701 return v1[2] * v2[2]; 702 } 703 704 double upnp::sign(const double v) 705 { 706 return ( v < 0.0 ) ? -1.0 : ( v > 0.0 ) ? 1.0 : 0.0; 707 } 708 709 void upnp::qr_solve(Mat * A, Mat * b, Mat * X) 710 { 711 const int nr = A->rows; 712 const int nc = A->cols; 713 714 if (max_nr != 0 && max_nr < nr) 715 { 716 delete [] A1; 717 delete [] A2; 718 } 719 if (max_nr < nr) 720 { 721 max_nr = nr; 722 A1 = new double[nr]; 723 A2 = new double[nr]; 724 } 725 726 double * pA = A->ptr<double>(0), * ppAkk = pA; 727 for(int k = 0; k < nc; k++) 728 { 729 double * ppAik1 = ppAkk, eta = fabs(*ppAik1); 730 for(int i = k + 1; i < nr; i++) 731 { 732 double elt = fabs(*ppAik1); 733 if (eta < elt) eta = elt; 734 ppAik1 += nc; 735 } 736 if (eta == 0) 737 { 738 A1[k] = A2[k] = 0.0; 739 //cerr << "God damnit, A is singular, this shouldn't happen." << endl; 740 return; 741 } 742 else 743 { 744 double * ppAik2 = ppAkk, sum2 = 0.0, inv_eta = 1. / eta; 745 for(int i = k; i < nr; i++) 746 { 747 *ppAik2 *= inv_eta; 748 sum2 += *ppAik2 * *ppAik2; 749 ppAik2 += nc; 750 } 751 double sigma = sqrt(sum2); 752 if (*ppAkk < 0) 753 sigma = -sigma; 754 *ppAkk += sigma; 755 A1[k] = sigma * *ppAkk; 756 A2[k] = -eta * sigma; 757 for(int j = k + 1; j < nc; j++) 758 { 759 double * ppAik = ppAkk, sum = 0; 760 for(int i = k; i < nr; i++) 761 { 762 sum += *ppAik * ppAik[j - k]; 763 ppAik += nc; 764 } 765 double tau = sum / A1[k]; 766 ppAik = ppAkk; 767 for(int i = k; i < nr; i++) 768 { 769 ppAik[j - k] -= tau * *ppAik; 770 ppAik += nc; 771 } 772 } 773 } 774 ppAkk += nc + 1; 775 } 776 777 // b <- Qt b 778 double * ppAjj = pA, * pb = b->ptr<double>(0); 779 for(int j = 0; j < nc; j++) 780 { 781 double * ppAij = ppAjj, tau = 0; 782 for(int i = j; i < nr; i++) 783 { 784 tau += *ppAij * pb[i]; 785 ppAij += nc; 786 } 787 tau /= A1[j]; 788 ppAij = ppAjj; 789 for(int i = j; i < nr; i++) 790 { 791 pb[i] -= tau * *ppAij; 792 ppAij += nc; 793 } 794 ppAjj += nc + 1; 795 } 796 797 // X = R-1 b 798 double * pX = X->ptr<double>(0); 799 pX[nc - 1] = pb[nc - 1] / A2[nc - 1]; 800 for(int i = nc - 2; i >= 0; i--) 801 { 802 double * ppAij = pA + i * nc + (i + 1), sum = 0; 803 804 for(int j = i + 1; j < nc; j++) 805 { 806 sum += *ppAij * pX[j]; 807 ppAij++; 808 } 809 pX[i] = (pb[i] - sum) / A2[i]; 810 } 811 } 812