Blender  V3.3
fundamental.cc
Go to the documentation of this file.
1 // Copyright (c) 2007, 2008 libmv authors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to
5 // deal in the Software without restriction, including without limitation the
6 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 // sell copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 // IN THE SOFTWARE.
20 
22 
23 #include "ceres/ceres.h"
24 #include "libmv/logging/logging.h"
28 #include "libmv/numeric/numeric.h"
29 #include "libmv/numeric/poly.h"
30 
31 namespace libmv {
32 
33 static void EliminateRow(const Mat34& P, int row, Mat* X) {
34  X->resize(2, 4);
35 
36  int first_row = (row + 1) % 3;
37  int second_row = (row + 2) % 3;
38 
39  for (int i = 0; i < 4; ++i) {
40  (*X)(0, i) = P(first_row, i);
41  (*X)(1, i) = P(second_row, i);
42  }
43 }
44 
45 void ProjectionsFromFundamental(const Mat3& F, Mat34* P1, Mat34* P2) {
46  *P1 << Mat3::Identity(), Vec3::Zero();
47  Vec3 e2;
48  Mat3 Ft = F.transpose();
49  Nullspace(&Ft, &e2);
50  *P2 << CrossProductMatrix(e2) * F, e2;
51 }
52 
53 // Addapted from vgg_F_from_P.
54 void FundamentalFromProjections(const Mat34& P1, const Mat34& P2, Mat3* F) {
55  Mat X[3];
56  Mat Y[3];
57  Mat XY;
58 
59  for (int i = 0; i < 3; ++i) {
60  EliminateRow(P1, i, X + i);
61  EliminateRow(P2, i, Y + i);
62  }
63 
64  for (int i = 0; i < 3; ++i) {
65  for (int j = 0; j < 3; ++j) {
66  VerticalStack(X[j], Y[i], &XY);
67  (*F)(i, j) = XY.determinant();
68  }
69  }
70 }
71 
72 // HZ 11.1 pag.279 (x1 = x, x2 = x')
73 // http://www.cs.unc.edu/~marc/tutorial/node54.html
74 static double EightPointSolver(const Mat& x1, const Mat& x2, Mat3* F) {
75  DCHECK_EQ(x1.rows(), 2);
76  DCHECK_GE(x1.cols(), 8);
77  DCHECK_EQ(x1.rows(), x2.rows());
78  DCHECK_EQ(x1.cols(), x2.cols());
79 
80  int n = x1.cols();
81  Mat A(n, 9);
82  for (int i = 0; i < n; ++i) {
83  A(i, 0) = x2(0, i) * x1(0, i);
84  A(i, 1) = x2(0, i) * x1(1, i);
85  A(i, 2) = x2(0, i);
86  A(i, 3) = x2(1, i) * x1(0, i);
87  A(i, 4) = x2(1, i) * x1(1, i);
88  A(i, 5) = x2(1, i);
89  A(i, 6) = x1(0, i);
90  A(i, 7) = x1(1, i);
91  A(i, 8) = 1;
92  }
93 
94  Vec9 f;
95  double smaller_singular_value = Nullspace(&A, &f);
96  *F = Map<RMat3>(f.data());
97  return smaller_singular_value;
98 }
99 
100 // HZ 11.1.1 pag.280
102  Eigen::JacobiSVD<Mat3> USV(*F, Eigen::ComputeFullU | Eigen::ComputeFullV);
103  Vec3 d = USV.singularValues();
104  d(2) = 0.0;
105  *F = USV.matrixU() * d.asDiagonal() * USV.matrixV().transpose();
106 }
107 
108 // HZ 11.2 pag.281 (x1 = x, x2 = x')
109 double NormalizedEightPointSolver(const Mat& x1, const Mat& x2, Mat3* F) {
110  DCHECK_EQ(x1.rows(), 2);
111  DCHECK_GE(x1.cols(), 8);
112  DCHECK_EQ(x1.rows(), x2.rows());
113  DCHECK_EQ(x1.cols(), x2.cols());
114 
115  // Normalize the data.
116  Mat3 T1, T2;
119  Mat x1_normalized, x2_normalized;
120  ApplyTransformationToPoints(x1, T1, &x1_normalized);
121  ApplyTransformationToPoints(x2, T2, &x2_normalized);
122 
123  // Estimate the fundamental matrix.
124  double smaller_singular_value =
125  EightPointSolver(x1_normalized, x2_normalized, F);
127 
128  // Denormalize the fundamental matrix.
129  *F = T2.transpose() * (*F) * T1;
130 
131  return smaller_singular_value;
132 }
133 
134 // Seven-point algorithm.
135 // http://www.cs.unc.edu/~marc/tutorial/node55.html
137  const Mat& x2,
138  std::vector<Mat3>* F) {
139  DCHECK_EQ(x1.rows(), 2);
140  DCHECK_EQ(x1.cols(), 7);
141  DCHECK_EQ(x1.rows(), x2.rows());
142  DCHECK_EQ(x2.cols(), x2.cols());
143 
144  // Build a 9 x n matrix from point matches, where each row is equivalent to
145  // the equation x'T*F*x = 0 for a single correspondence pair (x', x). The
146  // domain of the matrix is a 9 element vector corresponding to F. The
147  // nullspace should be rank two; the two dimensions correspond to the set of
148  // F matrices satisfying the epipolar geometry.
149  Matrix<double, 7, 9> A;
150  for (int ii = 0; ii < 7; ++ii) {
151  A(ii, 0) = x1(0, ii) * x2(0, ii); // 0 represents x coords,
152  A(ii, 1) = x1(1, ii) * x2(0, ii); // 1 represents y coords.
153  A(ii, 2) = x2(0, ii);
154  A(ii, 3) = x1(0, ii) * x2(1, ii);
155  A(ii, 4) = x1(1, ii) * x2(1, ii);
156  A(ii, 5) = x2(1, ii);
157  A(ii, 6) = x1(0, ii);
158  A(ii, 7) = x1(1, ii);
159  A(ii, 8) = 1.0;
160  }
161 
162  // Find the two F matrices in the nullspace of A.
163  Vec9 f1, f2;
164  double s = Nullspace2(&A, &f1, &f2);
165  Mat3 F1 = Map<RMat3>(f1.data());
166  Mat3 F2 = Map<RMat3>(f2.data());
167 
168  // Then, use the condition det(F) = 0 to determine F. In other words, solve
169  // det(F1 + a*F2) = 0 for a.
170  double a = F1(0, 0), j = F2(0, 0);
171  double b = F1(0, 1), k = F2(0, 1);
172  double c = F1(0, 2), l = F2(0, 2);
173  double d = F1(1, 0), m = F2(1, 0);
174  double e = F1(1, 1), n = F2(1, 1);
175  double f = F1(1, 2), o = F2(1, 2);
176  double g = F1(2, 0), p = F2(2, 0);
177  double h = F1(2, 1), q = F2(2, 1);
178  double i = F1(2, 2), r = F2(2, 2);
179 
180  // Run fundamental_7point_coeffs.py to get the below coefficients.
181  // The coefficients are in ascending powers of alpha, i.e. P[N]*x^N.
182  double P[4] = {
183  a * e * i + b * f * g + c * d * h - a * f * h - b * d * i - c * e * g,
184  a * e * r + a * i * n + b * f * p + b * g * o + c * d * q + c * h * m +
185  d * h * l + e * i * j + f * g * k - a * f * q - a * h * o -
186  b * d * r - b * i * m - c * e * p - c * g * n - d * i * k -
187  e * g * l - f * h * j,
188  a * n * r + b * o * p + c * m * q + d * l * q + e * j * r + f * k * p +
189  g * k * o + h * l * m + i * j * n - a * o * q - b * m * r -
190  c * n * p - d * k * r - e * l * p - f * j * q - g * l * n -
191  h * j * o - i * k * m,
192  j * n * r + k * o * p + l * m * q - j * o * q - k * m * r - l * n * p,
193  };
194 
195  // Solve for the roots of P[3]*x^3 + P[2]*x^2 + P[1]*x + P[0] = 0.
196  double roots[3];
197  int num_roots = SolveCubicPolynomial(P, roots);
198 
199  // Build the fundamental matrix for each solution.
200  for (int kk = 0; kk < num_roots; ++kk) {
201  F->push_back(F1 + roots[kk] * F2);
202  }
203  return s;
204 }
205 
207  const Mat& x2,
208  std::vector<Mat3>* F) {
209  DCHECK_EQ(x1.rows(), 2);
210  DCHECK_GE(x1.cols(), 7);
211  DCHECK_EQ(x1.rows(), x2.rows());
212  DCHECK_EQ(x1.cols(), x2.cols());
213 
214  // Normalize the data.
215  Mat3 T1, T2;
218  Mat x1_normalized, x2_normalized;
219  ApplyTransformationToPoints(x1, T1, &x1_normalized);
220  ApplyTransformationToPoints(x2, T2, &x2_normalized);
221 
222  // Estimate the fundamental matrix.
223  double smaller_singular_value = FundamentalFrom7CorrespondencesLinear(
224  x1_normalized, x2_normalized, &(*F));
225 
226  for (int k = 0; k < F->size(); ++k) {
227  Mat3& Fmat = (*F)[k];
228  // Denormalize the fundamental matrix.
229  Fmat = T2.transpose() * Fmat * T1;
230  }
231  return smaller_singular_value;
232 }
233 
234 void NormalizeFundamental(const Mat3& F, Mat3* F_normalized) {
235  *F_normalized = F / FrobeniusNorm(F);
236  if ((*F_normalized)(2, 2) < 0) {
237  *F_normalized *= -1;
238  }
239 }
240 
241 double SampsonDistance(const Mat& F, const Vec2& x1, const Vec2& x2) {
242  Vec3 x(x1(0), x1(1), 1.0);
243  Vec3 y(x2(0), x2(1), 1.0);
244 
245  Vec3 F_x = F * x;
246  Vec3 Ft_y = F.transpose() * y;
247  double y_F_x = y.dot(F_x);
248 
249  return Square(y_F_x) /
250  (F_x.head<2>().squaredNorm() + Ft_y.head<2>().squaredNorm());
251 }
252 
253 double SymmetricEpipolarDistance(const Mat& F, const Vec2& x1, const Vec2& x2) {
254  Vec3 x(x1(0), x1(1), 1.0);
255  Vec3 y(x2(0), x2(1), 1.0);
256 
257  Vec3 F_x = F * x;
258  Vec3 Ft_y = F.transpose() * y;
259  double y_F_x = y.dot(F_x);
260 
261  return Square(y_F_x) *
262  (1 / F_x.head<2>().squaredNorm() + 1 / Ft_y.head<2>().squaredNorm());
263 }
264 
265 // HZ 9.6 pag 257 (formula 9.12)
267  const Mat3& K1,
268  const Mat3& K2,
269  Mat3* E) {
270  *E = K2.transpose() * F * K1;
271 }
272 
273 // HZ 9.6 pag 257 (formula 9.12)
274 // Or http://ai.stanford.edu/~birch/projective/node20.html
276  const Mat3& K1,
277  const Mat3& K2,
278  Mat3* F) {
279  *F = K2.inverse().transpose() * E * K1.inverse();
280 }
281 
282 void RelativeCameraMotion(const Mat3& R1,
283  const Vec3& t1,
284  const Mat3& R2,
285  const Vec3& t2,
286  Mat3* R,
287  Vec3* t) {
288  *R = R2 * R1.transpose();
289  *t = t2 - (*R) * t1;
290 }
291 
292 // HZ 9.6 pag 257
294  const Mat3& R1, const Vec3& t1, const Mat3& R2, const Vec3& t2, Mat3* E) {
295  Mat3 R;
296  Vec3 t;
297  RelativeCameraMotion(R1, t1, R2, t2, &R, &t);
298  Mat3 Tx = CrossProductMatrix(t);
299  *E = Tx * R;
300 }
301 
302 // HZ 9.6 pag 259 (Result 9.19)
303 void MotionFromEssential(const Mat3& E,
304  std::vector<Mat3>* Rs,
305  std::vector<Vec3>* ts) {
306  Eigen::JacobiSVD<Mat3> USV(E, Eigen::ComputeFullU | Eigen::ComputeFullV);
307  Mat3 U = USV.matrixU();
308  Mat3 Vt = USV.matrixV().transpose();
309 
310  // Last column of U is undetermined since d = (a a 0).
311  if (U.determinant() < 0) {
312  U.col(2) *= -1;
313  }
314  // Last row of Vt is undetermined since d = (a a 0).
315  if (Vt.determinant() < 0) {
316  Vt.row(2) *= -1;
317  }
318 
319  Mat3 W;
320  // clang-format off
321  W << 0, -1, 0,
322  1, 0, 0,
323  0, 0, 1;
324  // clang-format on
325 
326  Mat3 U_W_Vt = U * W * Vt;
327  Mat3 U_Wt_Vt = U * W.transpose() * Vt;
328 
329  Rs->resize(4);
330  (*Rs)[0] = U_W_Vt;
331  (*Rs)[1] = U_W_Vt;
332  (*Rs)[2] = U_Wt_Vt;
333  (*Rs)[3] = U_Wt_Vt;
334 
335  ts->resize(4);
336  (*ts)[0] = U.col(2);
337  (*ts)[1] = -U.col(2);
338  (*ts)[2] = U.col(2);
339  (*ts)[3] = -U.col(2);
340 }
341 
342 int MotionFromEssentialChooseSolution(const std::vector<Mat3>& Rs,
343  const std::vector<Vec3>& ts,
344  const Mat3& K1,
345  const Vec2& x1,
346  const Mat3& K2,
347  const Vec2& x2) {
348  DCHECK_EQ(4, Rs.size());
349  DCHECK_EQ(4, ts.size());
350 
351  Mat34 P1, P2;
352  Mat3 R1;
353  Vec3 t1;
354  R1.setIdentity();
355  t1.setZero();
356  P_From_KRt(K1, R1, t1, &P1);
357  for (int i = 0; i < 4; ++i) {
358  const Mat3& R2 = Rs[i];
359  const Vec3& t2 = ts[i];
360  P_From_KRt(K2, R2, t2, &P2);
361  Vec3 X;
362  TriangulateDLT(P1, x1, P2, x2, &X);
363  double d1 = Depth(R1, t1, X);
364  double d2 = Depth(R2, t2, X);
365  // Test if point is front to the two cameras.
366  if (d1 > 0 && d2 > 0) {
367  return i;
368  }
369  }
370  return -1;
371 }
372 
374  const Mat3& K1,
375  const Vec2& x1,
376  const Mat3& K2,
377  const Vec2& x2,
378  Mat3* R,
379  Vec3* t) {
380  std::vector<Mat3> Rs;
381  std::vector<Vec3> ts;
382  MotionFromEssential(E, &Rs, &ts);
383  int solution = MotionFromEssentialChooseSolution(Rs, ts, K1, x1, K2, x2);
384  if (solution >= 0) {
385  *R = Rs[solution];
386  *t = ts[solution];
387  return true;
388  } else {
389  return false;
390  }
391 }
392 
393 void FundamentalToEssential(const Mat3& F, Mat3* E) {
394  Eigen::JacobiSVD<Mat3> svd(F, Eigen::ComputeFullU | Eigen::ComputeFullV);
395 
396  // See Hartley & Zisserman page 294, result 11.1, which shows how to get the
397  // closest essential matrix to a matrix that is "almost" an essential matrix.
398  double a = svd.singularValues()(0);
399  double b = svd.singularValues()(1);
400  double s = (a + b) / 2.0;
401 
402  LG << "Initial reconstruction's rotation is non-euclidean by "
403  << (((a - b) / std::max(a, b)) * 100)
404  << "%; singular values:" << svd.singularValues().transpose();
405 
406  Vec3 diag;
407  diag << s, s, 0;
408 
409  *E = svd.matrixU() * diag.asDiagonal() * svd.matrixV().transpose();
410 }
411 
412 // Default settings for fundamental estimation which should be suitable
413 // for a wide range of use cases.
415  : max_num_iterations(50), expected_average_symmetric_distance(1e-16) {
416 }
417 
418 namespace {
419 // Cost functor which computes symmetric epipolar distance
420 // used for fundamental matrix refinement.
421 class FundamentalSymmetricEpipolarCostFunctor {
422  public:
423  FundamentalSymmetricEpipolarCostFunctor(const Vec2& x, const Vec2& y)
424  : x_(x), y_(y) {}
425 
426  template <typename T>
427  bool operator()(const T* fundamental_parameters, T* residuals) const {
428  typedef Eigen::Matrix<T, 3, 3> Mat3;
429  typedef Eigen::Matrix<T, 3, 1> Vec3;
430 
431  Mat3 F(fundamental_parameters);
432 
433  Vec3 x(T(x_(0)), T(x_(1)), T(1.0));
434  Vec3 y(T(y_(0)), T(y_(1)), T(1.0));
435 
436  Vec3 F_x = F * x;
437  Vec3 Ft_y = F.transpose() * y;
438  T y_F_x = y.dot(F_x);
439 
440  residuals[0] = y_F_x * T(1) / F_x.head(2).norm();
441  residuals[1] = y_F_x * T(1) / Ft_y.head(2).norm();
442 
443  return true;
444  }
445 
446  const Mat x_;
447  const Mat y_;
448 };
449 
450 // Termination checking callback used for fundamental estimation.
451 // It finished the minimization as soon as actual average of
452 // symmetric epipolar distance is less or equal to the expected
453 // average value.
454 class TerminationCheckingCallback : public ceres::IterationCallback {
455  public:
456  TerminationCheckingCallback(const Mat& x1,
457  const Mat& x2,
458  const EstimateFundamentalOptions& options,
459  Mat3* F)
460  : options_(options), x1_(x1), x2_(x2), F_(F) {}
461 
462  virtual ceres::CallbackReturnType operator()(
463  const ceres::IterationSummary& summary) {
464  // If the step wasn't successful, there's nothing to do.
465  if (!summary.step_is_successful) {
466  return ceres::SOLVER_CONTINUE;
467  }
468 
469  // Calculate average of symmetric epipolar distance.
470  double average_distance = 0.0;
471  for (int i = 0; i < x1_.cols(); i++) {
472  average_distance = SymmetricEpipolarDistance(*F_, x1_.col(i), x2_.col(i));
473  }
474  average_distance /= x1_.cols();
475 
476  if (average_distance <= options_.expected_average_symmetric_distance) {
477  return ceres::SOLVER_TERMINATE_SUCCESSFULLY;
478  }
479 
480  return ceres::SOLVER_CONTINUE;
481  }
482 
483  private:
484  const EstimateFundamentalOptions& options_;
485  const Mat& x1_;
486  const Mat& x2_;
487  Mat3* F_;
488 };
489 } // namespace
490 
491 /* Fundamental transformation estimation. */
493  const Mat& x1,
494  const Mat& x2,
496  Mat3* F) {
497  // Step 1: Algebraic fundamental estimation.
498 
499  // Assume algebraic estiation always succeeds,
501 
502  LG << "Estimated matrix after algebraic estimation:\n" << *F;
503 
504  // Step 2: Refine matrix using Ceres minimizer.
505  ceres::Problem problem;
506  for (int i = 0; i < x1.cols(); i++) {
507  FundamentalSymmetricEpipolarCostFunctor*
508  fundamental_symmetric_epipolar_cost_function =
509  new FundamentalSymmetricEpipolarCostFunctor(x1.col(i), x2.col(i));
510 
511  problem.AddResidualBlock(
512  new ceres::AutoDiffCostFunction<FundamentalSymmetricEpipolarCostFunctor,
513  2, // num_residuals
514  9>(
515  fundamental_symmetric_epipolar_cost_function),
516  NULL,
517  F->data());
518  }
519 
520  // Configure the solve.
521  ceres::Solver::Options solver_options;
522  solver_options.linear_solver_type = ceres::DENSE_QR;
523  solver_options.max_num_iterations = options.max_num_iterations;
524  solver_options.update_state_every_iteration = true;
525 
526  // Terminate if the average symmetric distance is good enough.
527  TerminationCheckingCallback callback(x1, x2, options, F);
528  solver_options.callbacks.push_back(&callback);
529 
530  // Run the solve.
531  ceres::Solver::Summary summary;
532  ceres::Solve(solver_options, &problem, &summary);
533 
534  VLOG(1) << "Summary:\n" << summary.FullReport();
535 
536  LG << "Final refined matrix:\n" << *F;
537 
538  return summary.IsSolutionUsable();
539 }
540 
541 } // namespace libmv
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
#define X
Definition: GeomUtils.cpp:199
#define Y
Definition: GeomUtils.cpp:200
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
#define XY(_x, _y)
#define A
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btVector3 operator()(const btVector3 &x) const
Return the transform of the vector.
Definition: btTransform.h:90
CCL_NAMESPACE_BEGIN struct Options options
DEGForeachIDComponentCallback callback
const Mat y_
Definition: fundamental.cc:447
const Mat x_
Definition: fundamental.cc:446
float[3][3] Mat3
Definition: gpu_matrix.cc:27
#define LG
#define VLOG(severity)
Definition: log.h:37
#define DCHECK_EQ(a, b)
Definition: log.h:64
#define DCHECK_GE(a, b)
Definition: log.h:62
static float P(float k)
Definition: math_interp.c:25
#define T
#define F
#define R
#define T2
Definition: md5.cpp:18
#define T1
Definition: md5.cpp:17
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
T Square(T x)
Definition: numeric.h:247
double FundamentalFrom7CorrespondencesLinear(const Mat &x1, const Mat &x2, std::vector< Mat3 > *F)
Definition: fundamental.cc:136
int SolveCubicPolynomial(Real a, Real b, Real c, Real *x0, Real *x1, Real *x2)
Definition: poly.h:39
void EssentialFromRt(const Mat3 &R1, const Vec3 &t1, const Mat3 &R2, const Vec3 &t2, Mat3 *E)
Definition: fundamental.cc:293
double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2)
Definition: fundamental.cc:241
double Nullspace(TMat *A, TVec *nullspace)
Definition: numeric.h:158
void FundamentalFromEssential(const Mat3 &E, const Mat3 &K1, const Mat3 &K2, Mat3 *F)
Definition: fundamental.cc:275
void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F)
Definition: fundamental.cc:54
bool EstimateFundamentalFromCorrespondences(const Mat &x1, const Mat &x2, const EstimateFundamentalOptions &options, Mat3 *F)
Definition: fundamental.cc:492
Mat3 CrossProductMatrix(const Vec3 &x)
Definition: numeric.cc:80
static void EliminateRow(const Mat34 &P, int row, Mat *X)
Definition: fundamental.cc:33
void PreconditionerFromPoints(const Mat &points, Mat3 *T)
Definition: conditioning.cc:27
void VerticalStack(const TTop &top, const TBot &bottom, TStacked *stacked)
Definition: numeric.h:416
Eigen::Matrix< double, 3, 3 > Mat3
Definition: numeric.h:72
Eigen::Vector2d Vec2
Definition: numeric.h:105
void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, const Mat34 &P2, const Vec2 &x2, Vec4 *X_homogeneous)
void EnforceFundamentalRank2Constraint(Mat3 *F)
Definition: fundamental.cc:101
Eigen::MatrixXd Mat
Definition: numeric.h:60
double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X)
Definition: projection.cc:229
void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2)
Definition: fundamental.cc:45
void MotionFromEssential(const Mat3 &E, std::vector< Mat3 > *Rs, std::vector< Vec3 > *ts)
Definition: fundamental.cc:303
bool MotionFromEssentialAndCorrespondence(const Mat3 &E, const Mat3 &K1, const Vec2 &x1, const Mat3 &K2, const Vec2 &x2, Mat3 *R, Vec3 *t)
Definition: fundamental.cc:373
Eigen::Matrix< double, 3, 4 > Mat34
Definition: numeric.h:73
void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized)
Definition: fundamental.cc:234
void ApplyTransformationToPoints(const Mat &points, const Mat3 &T, Mat *transformed_points)
Definition: conditioning.cc:69
int MotionFromEssentialChooseSolution(const std::vector< Mat3 > &Rs, const std::vector< Vec3 > &ts, const Mat3 &K1, const Vec2 &x1, const Mat3 &K2, const Vec2 &x2)
Definition: fundamental.cc:342
void EssentialFromFundamental(const Mat3 &F, const Mat3 &K1, const Mat3 &K2, Mat3 *E)
Definition: fundamental.cc:266
double NormalizedEightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F)
Definition: fundamental.cc:109
void RelativeCameraMotion(const Mat3 &R1, const Vec3 &t1, const Mat3 &R2, const Vec3 &t2, Mat3 *R, Vec3 *t)
Definition: fundamental.cc:282
Eigen::Vector3d Vec3
Definition: numeric.h:106
static double EightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F)
Definition: fundamental.cc:74
double FrobeniusNorm(const TMat &A)
Definition: numeric.h:271
double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2)
Definition: fundamental.cc:253
void FundamentalToEssential(const Mat3 &F, Mat3 *E)
Definition: fundamental.cc:393
Eigen::Matrix< double, 9, 1 > Vec9
Definition: numeric.h:112
double FundamentalFromCorrespondences7Point(const Mat &x1, const Mat &x2, std::vector< Mat3 > *F)
Definition: fundamental.cc:206
double Nullspace2(TMat *A, TVec1 *x1, TVec2 *x2)
Definition: numeric.h:173
void P_From_KRt(const Mat3 &K, const Mat3 &R, const Vec3 &t, Mat34 *P)
Definition: projection.cc:26
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
float max