Blender  V3.3
libmv/multiview/homography.cc
Go to the documentation of this file.
1 // Copyright (c) 2008, 2009 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"
27 
28 namespace libmv {
47  const Mat& x1, const Mat& x2, Mat3* H, double expected_precision) {
48  assert(2 == x1.rows());
49  assert(4 <= x1.cols());
50  assert(x1.rows() == x2.rows());
51  assert(x1.cols() == x2.cols());
52 
53  int n = x1.cols();
54  MatX8 L = Mat::Zero(n * 3, 8);
55  Mat b = Mat::Zero(n * 3, 1);
56  for (int i = 0; i < n; ++i) {
57  int j = 3 * i;
58  L(j, 0) = x1(0, i); // a
59  L(j, 1) = x1(1, i); // b
60  L(j, 2) = 1.0; // c
61  L(j, 6) = -x2(0, i) * x1(0, i); // g
62  L(j, 7) = -x2(0, i) * x1(1, i); // h
63  b(j, 0) = x2(0, i); // i
64 
65  ++j;
66  L(j, 3) = x1(0, i); // d
67  L(j, 4) = x1(1, i); // e
68  L(j, 5) = 1.0; // f
69  L(j, 6) = -x2(1, i) * x1(0, i); // g
70  L(j, 7) = -x2(1, i) * x1(1, i); // h
71  b(j, 0) = x2(1, i); // i
72 
73  // This ensures better stability
74  // TODO(julien) make a lite version without this 3rd set
75  ++j;
76  L(j, 0) = x2(1, i) * x1(0, i); // a
77  L(j, 1) = x2(1, i) * x1(1, i); // b
78  L(j, 2) = x2(1, i); // c
79  L(j, 3) = -x2(0, i) * x1(0, i); // d
80  L(j, 4) = -x2(0, i) * x1(1, i); // e
81  L(j, 5) = -x2(0, i); // f
82  }
83  // Solve Lx=B
84  Vec h = L.fullPivLu().solve(b);
86  if ((L * h).isApprox(b, expected_precision)) {
87  return true;
88  } else {
89  return false;
90  }
91 }
92 
93 // clang-format off
102 // clang-format on
104  const Mat& x2,
105  Mat3* H,
106  double expected_precision) {
107  if (x1.rows() == 2) {
109  x1, x2, H, expected_precision);
110  }
111  assert(3 == x1.rows());
112  assert(4 <= x1.cols());
113  assert(x1.rows() == x2.rows());
114  assert(x1.cols() == x2.cols());
115 
116  const int x = 0;
117  const int y = 1;
118  const int w = 2;
119  int n = x1.cols();
120  MatX8 L = Mat::Zero(n * 3, 8);
121  Mat b = Mat::Zero(n * 3, 1);
122  for (int i = 0; i < n; ++i) {
123  int j = 3 * i;
124  L(j, 0) = x2(w, i) * x1(x, i); // a
125  L(j, 1) = x2(w, i) * x1(y, i); // b
126  L(j, 2) = x2(w, i) * x1(w, i); // c
127  L(j, 6) = -x2(x, i) * x1(x, i); // g
128  L(j, 7) = -x2(x, i) * x1(y, i); // h
129  b(j, 0) = x2(x, i) * x1(w, i);
130 
131  ++j;
132  L(j, 3) = x2(w, i) * x1(x, i); // d
133  L(j, 4) = x2(w, i) * x1(y, i); // e
134  L(j, 5) = x2(w, i) * x1(w, i); // f
135  L(j, 6) = -x2(y, i) * x1(x, i); // g
136  L(j, 7) = -x2(y, i) * x1(y, i); // h
137  b(j, 0) = x2(y, i) * x1(w, i);
138 
139  // This ensures better stability
140  ++j;
141  L(j, 0) = x2(y, i) * x1(x, i); // a
142  L(j, 1) = x2(y, i) * x1(y, i); // b
143  L(j, 2) = x2(y, i) * x1(w, i); // c
144  L(j, 3) = -x2(x, i) * x1(x, i); // d
145  L(j, 4) = -x2(x, i) * x1(y, i); // e
146  L(j, 5) = -x2(x, i) * x1(w, i); // f
147  }
148  // Solve Lx=B
149  Vec h = L.fullPivLu().solve(b);
150  if ((L * h).isApprox(b, expected_precision)) {
152  return true;
153  } else {
154  return false;
155  }
156 }
157 
158 // Default settings for homography estimation which should be suitable
159 // for a wide range of use cases.
161  : use_normalization(true),
162  max_num_iterations(50),
163  expected_average_symmetric_distance(1e-16) {
164 }
165 
166 namespace {
167 void GetNormalizedPoints(const Mat& original_points,
168  Mat* normalized_points,
169  Mat3* normalization_matrix) {
170  IsotropicPreconditionerFromPoints(original_points, normalization_matrix);
172  original_points, *normalization_matrix, normalized_points);
173 }
174 
175 // Cost functor which computes symmetric geometric distance
176 // used for homography matrix refinement.
177 class HomographySymmetricGeometricCostFunctor {
178  public:
179  HomographySymmetricGeometricCostFunctor(const Vec2& x, const Vec2& y)
180  : x_(x), y_(y) {}
181 
182  template <typename T>
183  bool operator()(const T* homography_parameters, T* residuals) const {
184  typedef Eigen::Matrix<T, 3, 3> Mat3;
185  typedef Eigen::Matrix<T, 3, 1> Vec3;
186 
187  Mat3 H(homography_parameters);
188 
189  Vec3 x(T(x_(0)), T(x_(1)), T(1.0));
190  Vec3 y(T(y_(0)), T(y_(1)), T(1.0));
191 
192  Vec3 H_x = H * x;
193  Vec3 Hinv_y = H.inverse() * y;
194 
195  H_x /= H_x(2);
196  Hinv_y /= Hinv_y(2);
197 
198  // This is a forward error.
199  residuals[0] = H_x(0) - T(y_(0));
200  residuals[1] = H_x(1) - T(y_(1));
201 
202  // This is a backward error.
203  residuals[2] = Hinv_y(0) - T(x_(0));
204  residuals[3] = Hinv_y(1) - T(x_(1));
205 
206  return true;
207  }
208 
209  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
210 
211  const Vec2 x_;
212  const Vec2 y_;
213 };
214 
215 // Termination checking callback used for homography estimation.
216 // It finished the minimization as soon as actual average of
217 // symmetric geometric distance is less or equal to the expected
218 // average value.
219 class TerminationCheckingCallback : public ceres::IterationCallback {
220  public:
221  TerminationCheckingCallback(const Mat& x1,
222  const Mat& x2,
223  const EstimateHomographyOptions& options,
224  Mat3* H)
225  : options_(options), x1_(x1), x2_(x2), H_(H) {}
226 
227  virtual ceres::CallbackReturnType operator()(
228  const ceres::IterationSummary& summary) {
229  // If the step wasn't successful, there's nothing to do.
230  if (!summary.step_is_successful) {
231  return ceres::SOLVER_CONTINUE;
232  }
233 
234  // Calculate average of symmetric geometric distance.
235  double average_distance = 0.0;
236  for (int i = 0; i < x1_.cols(); i++) {
237  average_distance =
238  SymmetricGeometricDistance(*H_, x1_.col(i), x2_.col(i));
239  }
240  average_distance /= x1_.cols();
241 
242  if (average_distance <= options_.expected_average_symmetric_distance) {
243  return ceres::SOLVER_TERMINATE_SUCCESSFULLY;
244  }
245 
246  return ceres::SOLVER_CONTINUE;
247  }
248 
249  private:
250  const EstimateHomographyOptions& options_;
251  const Mat& x1_;
252  const Mat& x2_;
253  Mat3* H_;
254 };
255 } // namespace
256 
261  const Mat& x1,
262  const Mat& x2,
264  Mat3* H) {
265  // TODO(sergey): Support homogenous coordinates, not just euclidean.
266 
267  assert(2 == x1.rows());
268  assert(4 <= x1.cols());
269  assert(x1.rows() == x2.rows());
270  assert(x1.cols() == x2.cols());
271 
272  Mat3 T1 = Mat3::Identity(), T2 = Mat3::Identity();
273 
274  // Step 1: Algebraic homography estimation.
275  Mat x1_normalized, x2_normalized;
276 
277  if (options.use_normalization) {
278  LG << "Estimating homography using normalization.";
279  GetNormalizedPoints(x1, &x1_normalized, &T1);
280  GetNormalizedPoints(x2, &x2_normalized, &T2);
281  } else {
282  x1_normalized = x1;
283  x2_normalized = x2;
284  }
285 
286  // Assume algebraic estiation always suceeds,
287  Homography2DFromCorrespondencesLinear(x1_normalized, x2_normalized, H);
288 
289  // Denormalize the homography matrix.
290  if (options.use_normalization) {
291  *H = T2.inverse() * (*H) * T1;
292  }
293 
294  LG << "Estimated matrix after algebraic estimation:\n" << *H;
295 
296  // Step 2: Refine matrix using Ceres minimizer.
297  ceres::Problem problem;
298  for (int i = 0; i < x1.cols(); i++) {
299  HomographySymmetricGeometricCostFunctor*
300  homography_symmetric_geometric_cost_function =
301  new HomographySymmetricGeometricCostFunctor(x1.col(i), x2.col(i));
302 
303  problem.AddResidualBlock(
304  new ceres::AutoDiffCostFunction<HomographySymmetricGeometricCostFunctor,
305  4, // num_residuals
306  9>(
307  homography_symmetric_geometric_cost_function),
308  NULL,
309  H->data());
310  }
311 
312  // Configure the solve.
313  ceres::Solver::Options solver_options;
314  solver_options.linear_solver_type = ceres::DENSE_QR;
315  solver_options.max_num_iterations = options.max_num_iterations;
316  solver_options.update_state_every_iteration = true;
317 
318  // Terminate if the average symmetric distance is good enough.
319  TerminationCheckingCallback callback(x1, x2, options, H);
320  solver_options.callbacks.push_back(&callback);
321 
322  // Run the solve.
323  ceres::Solver::Summary summary;
324  ceres::Solve(solver_options, &problem, &summary);
325 
326  VLOG(1) << "Summary:\n" << summary.FullReport();
327 
328  LG << "Final refined matrix:\n" << *H;
329 
330  return summary.IsSolutionUsable();
331 }
332 
333 // clang-format off
361 // clang-format on
363  const Mat& x2,
364  Mat4* H,
365  double expected_precision) {
366  assert(4 == x1.rows());
367  assert(5 <= x1.cols());
368  assert(x1.rows() == x2.rows());
369  assert(x1.cols() == x2.cols());
370  const int x = 0;
371  const int y = 1;
372  const int z = 2;
373  const int w = 3;
374  int n = x1.cols();
375  MatX15 L = Mat::Zero(n * 6, 15);
376  Mat b = Mat::Zero(n * 6, 1);
377  for (int i = 0; i < n; ++i) {
378  int j = 6 * i;
379  L(j, 0) = -x2(w, i) * x1(x, i); // a
380  L(j, 1) = -x2(w, i) * x1(y, i); // b
381  L(j, 2) = -x2(w, i) * x1(z, i); // c
382  L(j, 3) = -x2(w, i) * x1(w, i); // d
383  L(j, 12) = x2(x, i) * x1(x, i); // m
384  L(j, 13) = x2(x, i) * x1(y, i); // n
385  L(j, 14) = x2(x, i) * x1(z, i); // o
386  b(j, 0) = -x2(x, i) * x1(w, i);
387 
388  ++j;
389  L(j, 4) = -x2(z, i) * x1(x, i); // e
390  L(j, 5) = -x2(z, i) * x1(y, i); // f
391  L(j, 6) = -x2(z, i) * x1(z, i); // g
392  L(j, 7) = -x2(z, i) * x1(w, i); // h
393  L(j, 8) = x2(y, i) * x1(x, i); // i
394  L(j, 9) = x2(y, i) * x1(y, i); // j
395  L(j, 10) = x2(y, i) * x1(z, i); // k
396  L(j, 11) = x2(y, i) * x1(w, i); // l
397 
398  ++j;
399  L(j, 0) = -x2(z, i) * x1(x, i); // a
400  L(j, 1) = -x2(z, i) * x1(y, i); // b
401  L(j, 2) = -x2(z, i) * x1(z, i); // c
402  L(j, 3) = -x2(z, i) * x1(w, i); // d
403  L(j, 8) = x2(x, i) * x1(x, i); // i
404  L(j, 9) = x2(x, i) * x1(y, i); // j
405  L(j, 10) = x2(x, i) * x1(z, i); // k
406  L(j, 11) = x2(x, i) * x1(w, i); // l
407 
408  ++j;
409  L(j, 4) = -x2(w, i) * x1(x, i); // e
410  L(j, 5) = -x2(w, i) * x1(y, i); // f
411  L(j, 6) = -x2(w, i) * x1(z, i); // g
412  L(j, 7) = -x2(w, i) * x1(w, i); // h
413  L(j, 12) = x2(y, i) * x1(x, i); // m
414  L(j, 13) = x2(y, i) * x1(y, i); // n
415  L(j, 14) = x2(y, i) * x1(z, i); // o
416  b(j, 0) = -x2(y, i) * x1(w, i);
417 
418  ++j;
419  L(j, 0) = -x2(y, i) * x1(x, i); // a
420  L(j, 1) = -x2(y, i) * x1(y, i); // b
421  L(j, 2) = -x2(y, i) * x1(z, i); // c
422  L(j, 3) = -x2(y, i) * x1(w, i); // d
423  L(j, 4) = x2(x, i) * x1(x, i); // e
424  L(j, 5) = x2(x, i) * x1(y, i); // f
425  L(j, 6) = x2(x, i) * x1(z, i); // g
426  L(j, 7) = x2(x, i) * x1(w, i); // h
427 
428  ++j;
429  L(j, 8) = -x2(w, i) * x1(x, i); // i
430  L(j, 9) = -x2(w, i) * x1(y, i); // j
431  L(j, 10) = -x2(w, i) * x1(z, i); // k
432  L(j, 11) = -x2(w, i) * x1(w, i); // l
433  L(j, 12) = x2(z, i) * x1(x, i); // m
434  L(j, 13) = x2(z, i) * x1(y, i); // n
435  L(j, 14) = x2(z, i) * x1(z, i); // o
436  b(j, 0) = -x2(z, i) * x1(w, i);
437  }
438  // Solve Lx=B
439  Vec h = L.fullPivLu().solve(b);
440  if ((L * h).isApprox(b, expected_precision)) {
442  return true;
443  } else {
444  return false;
445  }
446 }
447 
449  const Vec2& x1,
450  const Vec2& x2) {
451  Vec3 x(x1(0), x1(1), 1.0);
452  Vec3 y(x2(0), x2(1), 1.0);
453 
454  Vec3 H_x = H * x;
455  Vec3 Hinv_y = H.inverse() * y;
456 
457  H_x /= H_x(2);
458  Hinv_y /= Hinv_y(2);
459 
460  return (H_x.head<2>() - y.head<2>()).squaredNorm() +
461  (Hinv_y.head<2>() - x.head<2>()).squaredNorm();
462 }
463 
464 } // 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 z
_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
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SIMD_FORCE_INLINE btVector3 operator()(const btVector3 &x) const
Return the transform of the vector.
Definition: btTransform.h:90
static void To(const Parameters &p, Parameterized *h)
Convert from the 8 parameters to a H matrix.
static void To(const Parameters &p, Parameterized *h)
Convert from the 15 parameters to a H matrix.
CCL_NAMESPACE_BEGIN struct Options options
DEGForeachIDComponentCallback callback
float[3][3] Mat3
Definition: gpu_matrix.cc:27
#define LG
EIGEN_MAKE_ALIGNED_OPERATOR_NEW const Vec2 x_
const Vec2 y_
#define VLOG(severity)
Definition: log.h:37
#define T
#define L
#define T2
Definition: md5.cpp:18
#define T1
Definition: md5.cpp:17
#define H(x, y, z)
Eigen::VectorXd Vec
Definition: numeric.h:61
Eigen::Matrix< double, Eigen::Dynamic, 15 > MatX15
Definition: numeric.h:102
Eigen::Matrix< double, 3, 3 > Mat3
Definition: numeric.h:72
Eigen::Vector2d Vec2
Definition: numeric.h:105
Eigen::MatrixXd Mat
Definition: numeric.h:60
Eigen::Matrix< double, Eigen::Dynamic, 8 > MatX8
Definition: numeric.h:100
void ApplyTransformationToPoints(const Mat &points, const Mat3 &T, Mat *transformed_points)
Definition: conditioning.cc:69
bool Homography2DFromCorrespondencesLinear(const Mat &x1, const Mat &x2, Mat3 *H, double expected_precision)
bool EstimateHomography2DFromCorrespondences(const Mat &x1, const Mat &x2, const EstimateHomographyOptions &options, Mat3 *H)
Eigen::Vector3d Vec3
Definition: numeric.h:106
bool Homography3DFromCorrespondencesLinear(const Mat &x1, const Mat &x2, Mat4 *H, double expected_precision)
double SymmetricGeometricDistance(const Mat3 &H, const Vec2 &x1, const Vec2 &x2)
static bool Homography2DFromCorrespondencesLinearEuc(const Mat &x1, const Mat &x2, Mat3 *H, double expected_precision)
void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T)
Definition: conditioning.cc:48
static const pxr::TfToken b("b", pxr::TfToken::Immortal)