~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/modules/calib3d/src/upnp.cpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
  delete M;
 
118
 
 
119
  double l_6x12[6 * 12], rho[6];
 
120
  Mat L_6x12 = Mat(6, 12, CV_64F, l_6x12);
 
121
  Mat Rho    = Mat(6,  1, CV_64F, rho);
 
122
 
 
123
  compute_L_6x12(ut, l_6x12);
 
124
  compute_rho(rho);
 
125
 
 
126
  double Betas[3][4], Efs[3][1], rep_errors[3];
 
127
  double Rs[3][3][3], ts[3][3];
 
128
 
 
129
  find_betas_and_focal_approx_1(&Ut, &Rho, Betas[1], Efs[1]);
 
130
  gauss_newton(&L_6x12, &Rho, Betas[1], Efs[1]);
 
131
  rep_errors[1] = compute_R_and_t(ut, Betas[1], Rs[1], ts[1]);
 
132
 
 
133
  find_betas_and_focal_approx_2(&Ut, &Rho, Betas[2], Efs[2]);
 
134
  gauss_newton(&L_6x12, &Rho, Betas[2], Efs[2]);
 
135
  rep_errors[2] = compute_R_and_t(ut, Betas[2], Rs[2], ts[2]);
 
136
 
 
137
  int N = 1;
 
138
  if (rep_errors[2] < rep_errors[1]) N = 2;
 
139
 
 
140
  Mat(3, 1, CV_64F, ts[N]).copyTo(t);
 
141
  Mat(3, 3, CV_64F, Rs[N]).copyTo(R);
 
142
  fu = fv = Efs[N][0];
 
143
 
 
144
  return fu;
 
145
}
 
146
 
 
147
void upnp::copy_R_and_t(const double R_src[3][3], const double t_src[3],
 
148
     double R_dst[3][3], double t_dst[3])
 
149
{
 
150
  for(int i = 0; i < 3; i++) {
 
151
    for(int j = 0; j < 3; j++)
 
152
      R_dst[i][j] = R_src[i][j];
 
153
    t_dst[i] = t_src[i];
 
154
  }
 
155
}
 
156
 
 
157
void upnp::estimate_R_and_t(double R[3][3], double t[3])
 
158
{
 
159
  double pc0[3], pw0[3];
 
160
 
 
161
  pc0[0] = pc0[1] = pc0[2] = 0.0;
 
162
  pw0[0] = pw0[1] = pw0[2] = 0.0;
 
163
 
 
164
  for(int i = 0; i < number_of_correspondences; i++) {
 
165
    const double * pc = &pcs[3 * i];
 
166
    const double * pw = &pws[3 * i];
 
167
 
 
168
    for(int j = 0; j < 3; j++) {
 
169
      pc0[j] += pc[j];
 
170
      pw0[j] += pw[j];
 
171
    }
 
172
  }
 
173
  for(int j = 0; j < 3; j++) {
 
174
    pc0[j] /= number_of_correspondences;
 
175
    pw0[j] /= number_of_correspondences;
 
176
  }
 
177
 
 
178
  double abt[3 * 3], abt_d[3], abt_u[3 * 3], abt_v[3 * 3];
 
179
  Mat ABt   = Mat(3, 3, CV_64F, abt);
 
180
  Mat ABt_D = Mat(3, 1, CV_64F, abt_d);
 
181
  Mat ABt_U = Mat(3, 3, CV_64F, abt_u);
 
182
  Mat ABt_V = Mat(3, 3, CV_64F, abt_v);
 
183
 
 
184
  ABt.setTo(0.0);
 
185
  for(int i = 0; i < number_of_correspondences; i++) {
 
186
    double * pc = &pcs[3 * i];
 
187
    double * pw = &pws[3 * i];
 
188
 
 
189
    for(int j = 0; j < 3; j++) {
 
190
      abt[3 * j    ] += (pc[j] - pc0[j]) * (pw[0] - pw0[0]);
 
191
      abt[3 * j + 1] += (pc[j] - pc0[j]) * (pw[1] - pw0[1]);
 
192
      abt[3 * j + 2] += (pc[j] - pc0[j]) * (pw[2] - pw0[2]);
 
193
    }
 
194
  }
 
195
 
 
196
  SVD::compute(ABt, ABt_D, ABt_U, ABt_V, SVD::MODIFY_A);
 
197
  Mat(ABt_V.t()).copyTo(ABt_V);
 
198
 
 
199
  for(int i = 0; i < 3; i++)
 
200
    for(int j = 0; j < 3; j++)
 
201
      R[i][j] = dot(abt_u + 3 * i, abt_v + 3 * j);
 
202
 
 
203
  const double det =
 
204
    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] -
 
205
    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];
 
206
 
 
207
  if (det < 0) {
 
208
    R[2][0] = -R[2][0];
 
209
    R[2][1] = -R[2][1];
 
210
    R[2][2] = -R[2][2];
 
211
  }
 
212
 
 
213
  t[0] = pc0[0] - dot(R[0], pw0);
 
214
  t[1] = pc0[1] - dot(R[1], pw0);
 
215
  t[2] = pc0[2] - dot(R[2], pw0);
 
216
}
 
217
 
 
218
void upnp::solve_for_sign(void)
 
219
{
 
220
  if (pcs[2] < 0.0) {
 
221
    for(int i = 0; i < 4; i++)
 
222
      for(int j = 0; j < 3; j++)
 
223
        ccs[i][j] = -ccs[i][j];
 
224
 
 
225
    for(int i = 0; i < number_of_correspondences; i++) {
 
226
      pcs[3 * i    ] = -pcs[3 * i];
 
227
      pcs[3 * i + 1] = -pcs[3 * i + 1];
 
228
      pcs[3 * i + 2] = -pcs[3 * i + 2];
 
229
    }
 
230
  }
 
231
}
 
232
 
 
233
double upnp::compute_R_and_t(const double * ut, const double * betas,
 
234
         double R[3][3], double t[3])
 
235
{
 
236
  compute_ccs(betas, ut);
 
237
  compute_pcs();
 
238
 
 
239
  solve_for_sign();
 
240
 
 
241
  estimate_R_and_t(R, t);
 
242
 
 
243
  return reprojection_error(R, t);
 
244
}
 
245
 
 
246
double upnp::reprojection_error(const double R[3][3], const double t[3])
 
247
{
 
248
  double sum2 = 0.0;
 
249
 
 
250
  for(int i = 0; i < number_of_correspondences; i++) {
 
251
    double * pw = &pws[3 * i];
 
252
    double Xc = dot(R[0], pw) + t[0];
 
253
    double Yc = dot(R[1], pw) + t[1];
 
254
    double inv_Zc = 1.0 / (dot(R[2], pw) + t[2]);
 
255
    double ue = uc + fu * Xc * inv_Zc;
 
256
    double ve = vc + fv * Yc * inv_Zc;
 
257
    double u = us[2 * i], v = us[2 * i + 1];
 
258
 
 
259
    sum2 += sqrt( (u - ue) * (u - ue) + (v - ve) * (v - ve) );
 
260
  }
 
261
 
 
262
  return sum2 / number_of_correspondences;
 
263
}
 
264
 
 
265
void upnp::choose_control_points()
 
266
{
 
267
    for (int i = 0; i < 4; ++i)
 
268
      cws[i][0] = cws[i][1] = cws[i][2] = 0.0;
 
269
    cws[0][0] = cws[1][1] = cws[2][2] = 1.0;
 
270
}
 
271
 
 
272
void upnp::compute_alphas()
 
273
{
 
274
    Mat CC = Mat(4, 3, CV_64F, &cws);
 
275
    Mat PC = Mat(number_of_correspondences, 3, CV_64F, &pws[0]);
 
276
    Mat ALPHAS = Mat(number_of_correspondences, 4, CV_64F, &alphas[0]);
 
277
 
 
278
    Mat CC_ = CC.clone().t();
 
279
    Mat PC_ = PC.clone().t();
 
280
 
 
281
    Mat row14 = Mat::ones(1, 4, CV_64F);
 
282
    Mat row1n = Mat::ones(1, number_of_correspondences, CV_64F);
 
283
 
 
284
    CC_.push_back(row14);
 
285
    PC_.push_back(row1n);
 
286
 
 
287
    ALPHAS = Mat( CC_.inv() * PC_ ).t();
 
288
}
 
289
 
 
290
void upnp::fill_M(Mat * M, const int row, const double * as, const double u, const double v)
 
291
{
 
292
  double * M1 = M->ptr<double>(row);
 
293
  double * M2 = M1 + 12;
 
294
 
 
295
  for(int i = 0; i < 4; i++) {
 
296
    M1[3 * i    ] = as[i] * fu;
 
297
    M1[3 * i + 1] = 0.0;
 
298
    M1[3 * i + 2] = as[i] * (uc - u);
 
299
 
 
300
    M2[3 * i    ] = 0.0;
 
301
    M2[3 * i + 1] = as[i] * fv;
 
302
    M2[3 * i + 2] = as[i] * (vc - v);
 
303
  }
 
304
}
 
305
 
 
306
void upnp::compute_ccs(const double * betas, const double * ut)
 
307
{
 
308
    for(int i = 0; i < 4; ++i)
 
309
      ccs[i][0] = ccs[i][1] = ccs[i][2] = 0.0;
 
310
 
 
311
    int N = 4;
 
312
    for(int i = 0; i < N; ++i) {
 
313
      const double * v = ut + 12 * (9 + i);
 
314
      for(int j = 0; j < 4; ++j)
 
315
        for(int k = 0; k < 3; ++k)
 
316
          ccs[j][k] += betas[i] * v[3 * j + k];
 
317
    }
 
318
 
 
319
    for (int i = 0; i < 4; ++i) ccs[i][2] *= fu;
 
320
}
 
321
 
 
322
void upnp::compute_pcs(void)
 
323
{
 
324
  for(int i = 0; i < number_of_correspondences; i++) {
 
325
    double * a = &alphas[0] + 4 * i;
 
326
    double * pc = &pcs[0] + 3 * i;
 
327
 
 
328
    for(int j = 0; j < 3; j++)
 
329
      pc[j] = a[0] * ccs[0][j] + a[1] * ccs[1][j] + a[2] * ccs[2][j] + a[3] * ccs[3][j];
 
330
  }
 
331
}
 
332
 
 
333
void upnp::find_betas_and_focal_approx_1(Mat * Ut, Mat * Rho, double * betas, double * efs)
 
334
{
 
335
  Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<double>(11));
 
336
  Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<double>(0));
 
337
 
 
338
  Mat D = compute_constraint_distance_2param_6eq_2unk_f_unk( Kmf1 );
 
339
  Mat Dt = D.t();
 
340
 
 
341
  Mat A = Dt * D;
 
342
  Mat b = Dt * dsq;
 
343
 
 
344
  Mat x = Mat(2, 1, CV_64F);
 
345
  solve(A, b, x);
 
346
 
 
347
  betas[0] = sqrt( abs( x.at<double>(0) ) );
 
348
  betas[1] = betas[2] = betas[3] = 0.0;
 
349
 
 
350
  efs[0] = sqrt( abs( x.at<double>(1) ) ) / betas[0];
 
351
}
 
352
 
 
353
void upnp::find_betas_and_focal_approx_2(Mat * Ut, Mat * Rho, double * betas, double * efs)
 
354
{
 
355
  double u[12*12];
 
356
  Mat U = Mat(12, 12, CV_64F, u);
 
357
  Ut->copyTo(U);
 
358
 
 
359
  Mat Kmf1 = Mat(12, 1, CV_64F, Ut->ptr<double>(10));
 
360
  Mat Kmf2 = Mat(12, 1, CV_64F, Ut->ptr<double>(11));
 
361
  Mat dsq = Mat(6, 1, CV_64F, Rho->ptr<double>(0));
 
362
 
 
363
  Mat D = compute_constraint_distance_3param_6eq_6unk_f_unk( Kmf1, Kmf2 );
 
364
 
 
365
  Mat A = D;
 
366
  Mat b = dsq;
 
367
 
 
368
  double x[6];
 
369
  Mat X = Mat(6, 1, CV_64F, x);
 
370
 
 
371
  solve(A, b, X, DECOMP_QR);
 
372
 
 
373
  double solutions[18][3];
 
374
  generate_all_possible_solutions_for_f_unk(x, solutions);
 
375
 
 
376
  // find solution with minimum reprojection error
 
377
  double min_error = std::numeric_limits<double>::max();
 
378
  int min_sol = 0;
 
379
  for (int i = 0; i < 18; ++i) {
 
380
 
 
381
    betas[3] = solutions[i][0];
 
382
    betas[2] = solutions[i][1];
 
383
    betas[1] = betas[0] = 0.0;
 
384
    fu = fv = solutions[i][2];
 
385
 
 
386
    double Rs[3][3], ts[3];
 
387
    double error_i = compute_R_and_t( u, betas, Rs, ts);
 
388
 
 
389
    if( error_i < min_error)
 
390
    {
 
391
      min_error = error_i;
 
392
      min_sol = i;
 
393
    }
 
394
}
 
395
 
 
396
  betas[0] = solutions[min_sol][0];
 
397
  betas[1] = solutions[min_sol][1];
 
398
  betas[2] = betas[3] = 0.0;
 
399
 
 
400
  efs[0] = solutions[min_sol][2];
 
401
}
 
402
 
 
403
Mat upnp::compute_constraint_distance_2param_6eq_2unk_f_unk(const Mat& M1)
 
404
{
 
405
  Mat P = Mat(6, 2, CV_64F);
 
406
 
 
407
  double m[13];
 
408
  for (int i = 1; i < 13; ++i) m[i] = *M1.ptr<double>(i-1);
 
409
 
 
410
  double t1 = pow( m[4], 2 );
 
411
  double t4 = pow( m[1], 2 );
 
412
  double t5 = pow( m[5], 2 );
 
413
  double t8 = pow( m[2], 2 );
 
414
  double t10 = pow( m[6], 2 );
 
415
  double t13 = pow( m[3], 2 );
 
416
  double t15 = pow( m[7], 2 );
 
417
  double t18 = pow( m[8], 2 );
 
418
  double t22 = pow( m[9], 2 );
 
419
  double t26 = pow( m[10], 2 );
 
420
  double t29 = pow( m[11], 2 );
 
421
  double t33 = pow( m[12], 2 );
 
422
 
 
423
  *P.ptr<double>(0,0) = t1 - 2 * m[4] * m[1] + t4 + t5 - 2 * m[5] * m[2] + t8;
 
424
  *P.ptr<double>(0,1) = t10 - 2 * m[6] * m[3] + t13;
 
425
  *P.ptr<double>(1,0) = t15 - 2 * m[7] * m[1] + t4 + t18 - 2 * m[8] * m[2] + t8;
 
426
  *P.ptr<double>(1,1) = t22 - 2 * m[9] * m[3] + t13;
 
427
  *P.ptr<double>(2,0) = t26 - 2 * m[10] * m[1] + t4 + t29 - 2 * m[11] * m[2] + t8;
 
428
  *P.ptr<double>(2,1) = t33 - 2 * m[12] * m[3] + t13;
 
429
  *P.ptr<double>(3,0) = t15 - 2 * m[7] * m[4] + t1 + t18 - 2 * m[8] * m[5] + t5;
 
430
  *P.ptr<double>(3,1) = t22 - 2 * m[9] * m[6] + t10;
 
431
  *P.ptr<double>(4,0) = t26 - 2 * m[10] * m[4] + t1 + t29 - 2 * m[11] * m[5] + t5;
 
432
  *P.ptr<double>(4,1) = t33 - 2 * m[12] * m[6] + t10;
 
433
  *P.ptr<double>(5,0) = t26 - 2 * m[10] * m[7] + t15 + t29 - 2 * m[11] * m[8] + t18;
 
434
  *P.ptr<double>(5,1) = t33 - 2 * m[12] * m[9] + t22;
 
435
 
 
436
  return P;
 
437
}
 
438
 
 
439
Mat upnp::compute_constraint_distance_3param_6eq_6unk_f_unk(const Mat& M1, const Mat& M2)
 
440
{
 
441
  Mat P = Mat(6, 6, CV_64F);
 
442
 
 
443
  double m[3][13];
 
444
  for (int i = 1; i < 13; ++i)
 
445
  {
 
446
    m[1][i] = *M1.ptr<double>(i-1);
 
447
    m[2][i] = *M2.ptr<double>(i-1);
 
448
  }
 
449
 
 
450
  double t1 = pow( m[1][4], 2 );
 
451
  double t2 = pow( m[1][1], 2 );
 
452
  double t7 = pow( m[1][5], 2 );
 
453
  double t8 = pow( m[1][2], 2 );
 
454
  double t11 = m[1][1] * m[2][1];
 
455
  double t12 = m[1][5] * m[2][5];
 
456
  double t15 = m[1][2] * m[2][2];
 
457
  double t16 = m[1][4] * m[2][4];
 
458
  double t19 = pow( m[2][4], 2 );
 
459
  double t22 = pow( m[2][2], 2 );
 
460
  double t23 = pow( m[2][1], 2 );
 
461
  double t24 = pow( m[2][5], 2 );
 
462
  double t28 = pow( m[1][6], 2 );
 
463
  double t29 = pow( m[1][3], 2 );
 
464
  double t34 = pow( m[1][3], 2 );
 
465
  double t36 = m[1][6] * m[2][6];
 
466
  double t40 = pow( m[2][6], 2 );
 
467
  double t41 = pow( m[2][3], 2 );
 
468
  double t47 = pow( m[1][7], 2 );
 
469
  double t48 = pow( m[1][8], 2 );
 
470
  double t52 = m[1][7] * m[2][7];
 
471
  double t55 = m[1][8] * m[2][8];
 
472
  double t59 = pow( m[2][8], 2 );
 
473
  double t62 = pow( m[2][7], 2 );
 
474
  double t64 = pow( m[1][9], 2 );
 
475
  double t68 = m[1][9] * m[2][9];
 
476
  double t74 = pow( m[2][9], 2 );
 
477
  double t78 = pow( m[1][10], 2 );
 
478
  double t79 = pow( m[1][11], 2 );
 
479
  double t84 = m[1][10] * m[2][10];
 
480
  double t87 = m[1][11] * m[2][11];
 
481
  double t90 = pow( m[2][10], 2 );
 
482
  double t95 = pow( m[2][11], 2 );
 
483
  double t99 = pow( m[1][12], 2 );
 
484
  double t101 = m[1][12] * m[2][12];
 
485
  double t105 = pow( m[2][12], 2 );
 
486
 
 
487
  *P.ptr<double>(0,0) = t1 + t2 - 2 * m[1][4] * m[1][1] - 2 * m[1][5] * m[1][2] + t7 + t8;
 
488
  *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];
 
489
  *P.ptr<double>(0,2) = t19 - 2 * m[2][4] * m[2][1] + t22 + t23 + t24 - 2 * m[2][5] * m[2][2];
 
490
  *P.ptr<double>(0,3) = t28 + t29 - 2 * m[1][6] * m[1][3];
 
491
  *P.ptr<double>(0,4) = -2 * m[2][6] * m[1][3] + 2 * t34 - 2 * m[1][6] * m[2][3] + 2 * t36;
 
492
  *P.ptr<double>(0,5) = -2 * m[2][6] * m[2][3] + t40 + t41;
 
493
 
 
494
  *P.ptr<double>(1,0) = t8 - 2 * m[1][8] * m[1][2] - 2 * m[1][7] * m[1][1] + t47 + t48 + t2;
 
495
  *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;
 
496
  *P.ptr<double>(1,2) = -2 * m[2][8] * m[2][2] + t22 + t23 + t59 - 2 * m[2][7] * m[2][1] + t62;
 
497
  *P.ptr<double>(1,3) = t29 + t64 - 2 * m[1][9] * m[1][3];
 
498
  *P.ptr<double>(1,4) = 2 * t34 + 2 * t68 - 2 * m[2][9] * m[1][3] - 2 * m[1][9] * m[2][3];
 
499
  *P.ptr<double>(1,5) = -2 * m[2][9] * m[2][3] + t74 + t41;
 
500
 
 
501
  *P.ptr<double>(2,0) = -2 * m[1][11] * m[1][2] + t2 + t8 + t78 + t79 - 2 * m[1][10] * m[1][1];
 
502
  *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;
 
503
  *P.ptr<double>(2,2) = t90 + t22 - 2 * m[2][10] * m[2][1] + t23 - 2 * m[2][11] * m[2][2] + t95;
 
504
  *P.ptr<double>(2,3) = -2 * m[1][12] * m[1][3] + t99 + t29;
 
505
  *P.ptr<double>(2,4) = 2 * t34 + 2 * t101 - 2 * m[2][12] * m[1][3] - 2 * m[1][12] * m[2][3];
 
506
  *P.ptr<double>(2,5) = t41 + t105 - 2 * m[2][12] * m[2][3];
 
507
 
 
508
  *P.ptr<double>(3,0) = t48 + t1 - 2 * m[1][8] * m[1][5] + t7 - 2 * m[1][7] * m[1][4] + t47;
 
509
  *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;
 
510
  *P.ptr<double>(3,2) = t24 - 2 * m[2][8] * m[2][5] + t19 - 2 * m[2][7] * m[2][4] + t62 + t59;
 
511
  *P.ptr<double>(3,3) = -2 * m[1][9] * m[1][6] + t64 + t28;
 
512
  *P.ptr<double>(3,4) = 2 * t68 + 2 * t36 - 2 * m[2][9] * m[1][6] - 2 * m[1][9] * m[2][6];
 
513
  *P.ptr<double>(3,5) = t40 + t74 - 2 * m[2][9] * m[2][6];
 
514
 
 
515
  *P.ptr<double>(4,0) = t1 - 2 * m[1][10] * m[1][4] + t7 + t78 + t79 - 2 * m[1][11] * m[1][5];
 
516
  *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;
 
517
  *P.ptr<double>(4,2) = t19 + t24 - 2 * m[2][10] * m[2][4] - 2 * m[2][11] * m[2][5] + t95 + t90;
 
518
  *P.ptr<double>(4,3) = t28 - 2 * m[1][12] * m[1][6] + t99;
 
519
  *P.ptr<double>(4,4) = 2 * t101 + 2 * t36 - 2 * m[2][12] * m[1][6] - 2 * m[1][12] * m[2][6];
 
520
  *P.ptr<double>(4,5) = t105 - 2 * m[2][12] * m[2][6] + t40;
 
521
 
 
522
  *P.ptr<double>(5,0) = -2 * m[1][10] * m[1][7] + t47 + t48 + t78 + t79 - 2 * m[1][11] * m[1][8];
 
523
  *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];
 
524
  *P.ptr<double>(5,2) = -2 * m[2][10] * m[2][7] - 2 * m[2][11] * m[2][8] + t62 + t59 + t90 + t95;
 
525
  *P.ptr<double>(5,3) = t64 - 2 * m[1][12] * m[1][9] + t99;
 
526
  *P.ptr<double>(5,4) = 2 * t68 - 2 * m[2][12] * m[1][9] - 2 * m[1][12] * m[2][9] + 2 * t101;
 
527
  *P.ptr<double>(5,5) = t105 - 2 * m[2][12] * m[2][9] + t74;
 
528
 
 
529
  return P;
 
530
}
 
531
 
 
532
void upnp::generate_all_possible_solutions_for_f_unk(const double betas[5], double solutions[18][3])
 
533
{
 
534
  int matrix_to_resolve[18][9] = {
 
535
    { 2, 0, 0, 1, 1, 0, 2, 0, 2 }, { 2, 0, 0, 1, 1, 0, 1, 1, 2 },
 
536
    { 2, 0, 0, 1, 1, 0, 0, 2, 2 }, { 2, 0, 0, 0, 2, 0, 2, 0, 2 },
 
537
    { 2, 0, 0, 0, 2, 0, 1, 1, 2 }, { 2, 0, 0, 0, 2, 0, 0, 2, 2 },
 
538
    { 2, 0, 0, 2, 0, 2, 1, 1, 2 }, { 2, 0, 0, 2, 0, 2, 0, 2, 2 },
 
539
    { 2, 0, 0, 1, 1, 2, 0, 2, 2 }, { 1, 1, 0, 0, 2, 0, 2, 0, 2 },
 
540
    { 1, 1, 0, 0, 2, 0, 1, 1, 2 }, { 1, 1, 0, 2, 0, 2, 0, 2, 2 },
 
541
    { 1, 1, 0, 2, 0, 2, 1, 1, 2 }, { 1, 1, 0, 2, 0, 2, 0, 2, 2 },
 
542
    { 1, 1, 0, 1, 1, 2, 0, 2, 2 }, { 0, 2, 0, 2, 0, 2, 1, 1, 2 },
 
543
    { 0, 2, 0, 2, 0, 2, 0, 2, 2 }, { 0, 2, 0, 1, 1, 2, 0, 2, 2 }
 
544
  };
 
545
 
 
546
  int combination[18][3] = {
 
547
    { 1, 2, 4 }, { 1, 2, 5 }, { 1, 2, 6 }, { 1, 3, 4 },
 
548
    { 1, 3, 5 }, { 1, 3, 6 }, { 1, 4, 5 }, { 1, 4, 6 },
 
549
    { 1, 5, 6 }, { 2, 3, 4 }, { 2, 3, 5 }, { 2, 3, 6 },
 
550
    { 2, 4, 5 }, { 2, 4, 6 }, { 2, 5, 6 }, { 3, 4, 5 },
 
551
    { 3, 4, 6 }, { 3, 5, 6 }
 
552
  };
 
553
 
 
554
  for (int i = 0; i < 18; ++i) {
 
555
    double matrix[9], independent_term[3];
 
556
    Mat M = Mat(3, 3, CV_64F, matrix);
 
557
    Mat I = Mat(3, 1, CV_64F, independent_term);
 
558
    Mat S = Mat(1, 3, CV_64F);
 
559
 
 
560
    for (int j = 0; j < 9; ++j) matrix[j] = (double)matrix_to_resolve[i][j];
 
561
 
 
562
    independent_term[0] = log( abs( betas[ combination[i][0]-1 ] ) );
 
563
    independent_term[1] = log( abs( betas[ combination[i][1]-1 ] ) );
 
564
    independent_term[2] = log( abs( betas[ combination[i][2]-1 ] ) );
 
565
 
 
566
    exp( Mat(M.inv() * I), S);
 
567
 
 
568
    solutions[i][0] = S.at<double>(0);
 
569
    solutions[i][1] = S.at<double>(1) * sign( betas[1] );
 
570
    solutions[i][2] = abs( S.at<double>(2) );
 
571
  }
 
572
}
 
573
 
 
574
void upnp::gauss_newton(const Mat * L_6x12, const Mat * Rho, double betas[4], double * f)
 
575
{
 
576
  const int iterations_number = 50;
 
577
 
 
578
  double a[6*4], b[6], x[4];
 
579
  Mat * A = new Mat(6, 4, CV_64F, a);
 
580
  Mat * B = new Mat(6, 1, CV_64F, b);
 
581
  Mat * X = new Mat(4, 1, CV_64F, x);
 
582
 
 
583
  for(int k = 0; k < iterations_number; k++)
 
584
  {
 
585
    compute_A_and_b_gauss_newton(L_6x12->ptr<double>(0), Rho->ptr<double>(0), betas, A, B, f[0]);
 
586
    qr_solve(A, B, X);
 
587
    for(int i = 0; i < 3; i++)
 
588
      betas[i] += x[i];
 
589
    f[0] += x[3];
 
590
  }
 
591
 
 
592
  if (f[0] < 0) f[0] = -f[0];
 
593
  fu = fv = f[0];
 
594
 
 
595
  A->release();
 
596
  delete A;
 
597
 
 
598
  B->release();
 
599
  delete B;
 
600
 
 
601
  X->release();
 
602
  delete X;
 
603
 
 
604
}
 
605
 
 
606
void upnp::compute_A_and_b_gauss_newton(const double * l_6x12, const double * rho,
 
607
        const double betas[4], Mat * A, Mat * b, double const f)
 
608
{
 
609
 
 
610
  for(int i = 0; i < 6; i++) {
 
611
    const double * rowL = l_6x12 + i * 12;
 
612
    double * rowA = A->ptr<double>(i);
 
613
 
 
614
    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] );
 
615
    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] );
 
616
    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] );
 
617
    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] ) ;
 
618
 
 
619
    *b->ptr<double>(i) = rho[i] -
 
620
    (
 
621
      rowL[0] * betas[0] * betas[0] +
 
622
      rowL[1] * betas[0] * betas[1] +
 
623
      rowL[2] * betas[0] * betas[2] +
 
624
      rowL[3] * betas[1] * betas[1] +
 
625
      rowL[4] * betas[1] * betas[2] +
 
626
      rowL[5] * betas[2] * betas[2] +
 
627
      f*f * rowL[6] * betas[0] * betas[0] +
 
628
      f*f * rowL[7] * betas[0] * betas[1] +
 
629
      f*f * rowL[8] * betas[0] * betas[2] +
 
630
      f*f * rowL[9] * betas[1] * betas[1] +
 
631
      f*f * rowL[10] * betas[1] * betas[2] +
 
632
      f*f * rowL[11] * betas[2] * betas[2]
 
633
     );
 
634
  }
 
635
}
 
636
 
 
637
void upnp::compute_L_6x12(const double * ut, double * l_6x12)
 
638
{
 
639
  const double * v[3];
 
640
 
 
641
  v[0] = ut + 12 * 9;
 
642
  v[1] = ut + 12 * 10;
 
643
  v[2] = ut + 12 * 11;
 
644
 
 
645
  double dv[3][6][3];
 
646
 
 
647
  for(int i = 0; i < 3; i++) {
 
648
    int a = 0, b = 1;
 
649
    for(int j = 0; j < 6; j++) {
 
650
      dv[i][j][0] = v[i][3 * a    ] - v[i][3 * b];
 
651
      dv[i][j][1] = v[i][3 * a + 1] - v[i][3 * b + 1];
 
652
      dv[i][j][2] = v[i][3 * a + 2] - v[i][3 * b + 2];
 
653
 
 
654
      b++;
 
655
      if (b > 3) {
 
656
        a++;
 
657
        b = a + 1;
 
658
      }
 
659
    }
 
660
  }
 
661
 
 
662
  for(int i = 0; i < 6; i++) {
 
663
    double * row = l_6x12 + 12 * i;
 
664
 
 
665
    row[0] =         dotXY(dv[0][i], dv[0][i]);
 
666
    row[1] =  2.0f * dotXY(dv[0][i], dv[1][i]);
 
667
    row[2] =         dotXY(dv[1][i], dv[1][i]);
 
668
    row[3] =  2.0f * dotXY(dv[0][i], dv[2][i]);
 
669
    row[4] =  2.0f * dotXY(dv[1][i], dv[2][i]);
 
670
    row[5] =         dotXY(dv[2][i], dv[2][i]);
 
671
 
 
672
    row[6] =         dotZ(dv[0][i], dv[0][i]);
 
673
    row[7] =  2.0f * dotZ(dv[0][i], dv[1][i]);
 
674
    row[8] =  2.0f * dotZ(dv[0][i], dv[2][i]);
 
675
    row[9] =         dotZ(dv[1][i], dv[1][i]);
 
676
    row[10] = 2.0f * dotZ(dv[1][i], dv[2][i]);
 
677
    row[11] =        dotZ(dv[2][i], dv[2][i]);
 
678
  }
 
679
}
 
680
 
 
681
void upnp::compute_rho(double * rho)
 
682
{
 
683
  rho[0] = dist2(cws[0], cws[1]);
 
684
  rho[1] = dist2(cws[0], cws[2]);
 
685
  rho[2] = dist2(cws[0], cws[3]);
 
686
  rho[3] = dist2(cws[1], cws[2]);
 
687
  rho[4] = dist2(cws[1], cws[3]);
 
688
  rho[5] = dist2(cws[2], cws[3]);
 
689
}
 
690
 
 
691
double upnp::dist2(const double * p1, const double * p2)
 
692
{
 
693
  return
 
694
    (p1[0] - p2[0]) * (p1[0] - p2[0]) +
 
695
    (p1[1] - p2[1]) * (p1[1] - p2[1]) +
 
696
    (p1[2] - p2[2]) * (p1[2] - p2[2]);
 
697
}
 
698
 
 
699
double upnp::dot(const double * v1, const double * v2)
 
700
{
 
701
  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
 
702
}
 
703
 
 
704
double upnp::dotXY(const double * v1, const double * v2)
 
705
{
 
706
  return v1[0] * v2[0] + v1[1] * v2[1];
 
707
}
 
708
 
 
709
double upnp::dotZ(const double * v1, const double * v2)
 
710
{
 
711
  return v1[2] * v2[2];
 
712
}
 
713
 
 
714
double upnp::sign(const double v)
 
715
{
 
716
  return ( v < 0.0 ) ? -1.0 : ( v > 0.0 ) ? 1.0 : 0.0;
 
717
}
 
718
 
 
719
void upnp::qr_solve(Mat * A, Mat * b, Mat * X)
 
720
{
 
721
  const int nr = A->rows;
 
722
  const int nc = A->cols;
 
723
 
 
724
  if (max_nr != 0 && max_nr < nr)
 
725
  {
 
726
    delete [] A1;
 
727
    delete [] A2;
 
728
  }
 
729
  if (max_nr < nr)
 
730
  {
 
731
    max_nr = nr;
 
732
    A1 = new double[nr];
 
733
    A2 = new double[nr];
 
734
  }
 
735
 
 
736
  double * pA = A->ptr<double>(0), * ppAkk = pA;
 
737
  for(int k = 0; k < nc; k++)
 
738
  {
 
739
    double * ppAik1 = ppAkk, eta = fabs(*ppAik1);
 
740
    for(int i = k + 1; i < nr; i++)
 
741
    {
 
742
      double elt = fabs(*ppAik1);
 
743
      if (eta < elt) eta = elt;
 
744
      ppAik1 += nc;
 
745
    }
 
746
    if (eta == 0)
 
747
    {
 
748
      A1[k] = A2[k] = 0.0;
 
749
      //cerr << "God damnit, A is singular, this shouldn't happen." << endl;
 
750
      return;
 
751
    }
 
752
    else
 
753
    {
 
754
     double * ppAik2 = ppAkk, sum2 = 0.0, inv_eta = 1. / eta;
 
755
     for(int i = k; i < nr; i++)
 
756
     {
 
757
       *ppAik2 *= inv_eta;
 
758
       sum2 += *ppAik2 * *ppAik2;
 
759
       ppAik2 += nc;
 
760
     }
 
761
     double sigma = sqrt(sum2);
 
762
     if (*ppAkk < 0)
 
763
     sigma = -sigma;
 
764
     *ppAkk += sigma;
 
765
     A1[k] = sigma * *ppAkk;
 
766
     A2[k] = -eta * sigma;
 
767
     for(int j = k + 1; j < nc; j++)
 
768
     {
 
769
       double * ppAik = ppAkk, sum = 0;
 
770
       for(int i = k; i < nr; i++)
 
771
       {
 
772
        sum += *ppAik * ppAik[j - k];
 
773
        ppAik += nc;
 
774
       }
 
775
       double tau = sum / A1[k];
 
776
       ppAik = ppAkk;
 
777
       for(int i = k; i < nr; i++)
 
778
       {
 
779
        ppAik[j - k] -= tau * *ppAik;
 
780
        ppAik += nc;
 
781
       }
 
782
     }
 
783
    }
 
784
    ppAkk += nc + 1;
 
785
  }
 
786
 
 
787
  // b <- Qt b
 
788
  double * ppAjj = pA, * pb = b->ptr<double>(0);
 
789
  for(int j = 0; j < nc; j++)
 
790
  {
 
791
    double * ppAij = ppAjj, tau = 0;
 
792
    for(int i = j; i < nr; i++)
 
793
    {
 
794
     tau += *ppAij * pb[i];
 
795
     ppAij += nc;
 
796
    }
 
797
    tau /= A1[j];
 
798
    ppAij = ppAjj;
 
799
    for(int i = j; i < nr; i++)
 
800
    {
 
801
     pb[i] -= tau * *ppAij;
 
802
     ppAij += nc;
 
803
    }
 
804
    ppAjj += nc + 1;
 
805
  }
 
806
 
 
807
  // X = R-1 b
 
808
  double * pX = X->ptr<double>(0);
 
809
  pX[nc - 1] = pb[nc - 1] / A2[nc - 1];
 
810
  for(int i = nc - 2; i >= 0; i--)
 
811
  {
 
812
    double * ppAij = pA + i * nc + (i + 1), sum = 0;
 
813
 
 
814
    for(int j = i + 1; j < nc; j++)
 
815
    {
 
816
     sum += *ppAij * pX[j];
 
817
     ppAij++;
 
818
    }
 
819
    pX[i] = (pb[i] - sum) / A2[i];
 
820
  }
 
821
}