Blender  V3.3
keyframe_selection.cc
Go to the documentation of this file.
1 // Copyright (c) 2012 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 #include "libmv/numeric/numeric.h"
30 
31 #include <Eigen/Eigenvalues>
32 
33 namespace libmv {
34 namespace {
35 
36 Mat3 IntrinsicsNormalizationMatrix(const CameraIntrinsics& intrinsics) {
37  Mat3 T = Mat3::Identity(), S = Mat3::Identity();
38 
39  T(0, 2) = -intrinsics.principal_point_x();
40  T(1, 2) = -intrinsics.principal_point_y();
41 
42  S(0, 0) /= intrinsics.focal_length_x();
43  S(1, 1) /= intrinsics.focal_length_y();
44 
45  return S * T;
46 }
47 
48 // P.H.S. Torr
49 // Geometric Motion Segmentation and Model Selection
50 //
51 // http://reference.kfupm.edu.sa/content/g/e/geometric_motion_segmentation_and_model__126445.pdf
52 //
53 // d is the number of dimensions modeled
54 // (d = 3 for a fundamental matrix or 2 for a homography)
55 // k is the number of degrees of freedom in the model
56 // (k = 7 for a fundamental matrix or 8 for a homography)
57 // r is the dimension of the data
58 // (r = 4 for 2D correspondences between two frames)
59 double GRIC(const Vec& e, int d, int k, int r) {
60  int n = e.rows();
61  double lambda1 = log(static_cast<double>(r));
62  double lambda2 = log(static_cast<double>(r * n));
63 
64  // lambda3 limits the residual error, and this paper
65  // http://elvera.nue.tu-berlin.de/files/0990Knorr2006.pdf
66  // suggests using lambda3 of 2
67  // same value is used in Torr's Problem of degeneracy in structure
68  // and motion recovery from uncalibrated image sequences
69  // http://www.robots.ox.ac.uk/~vgg/publications/papers/torr99.ps.gz
70  double lambda3 = 2.0;
71 
72  // Variance of tracker position. Physically, this is typically about 0.1px,
73  // and when squared becomes 0.01 px^2.
74  double sigma2 = 0.01;
75 
76  // Finally, calculate the GRIC score.
77  double gric = 0.0;
78  for (int i = 0; i < n; i++) {
79  gric += std::min(e(i) * e(i) / sigma2, lambda3 * (r - d));
80  }
81  gric += lambda1 * d * n;
82  gric += lambda2 * k;
83  return gric;
84 }
85 
86 // Compute a generalized inverse using eigen value decomposition, clamping the
87 // smallest eigenvalues if requested. This is needed to compute the variance of
88 // reconstructed 3D points.
89 //
90 // TODO(keir): Consider moving this into the numeric code, since this is not
91 // related to keyframe selection.
92 Mat PseudoInverseWithClampedEigenvalues(const Mat& matrix,
93  int num_eigenvalues_to_clamp) {
94  Eigen::EigenSolver<Mat> eigen_solver(matrix);
95  Mat D = eigen_solver.pseudoEigenvalueMatrix();
96  Mat V = eigen_solver.pseudoEigenvectors();
97 
98  // Clamp too-small singular values to zero to prevent numeric blowup.
100  for (int i = 0; i < D.cols(); ++i) {
101  if (D(i, i) > epsilon) {
102  D(i, i) = 1.0 / D(i, i);
103  } else {
104  D(i, i) = 0.0;
105  }
106  }
107 
108  // Apply the clamp.
109  for (int i = D.cols() - num_eigenvalues_to_clamp; i < D.cols(); ++i) {
110  D(i, i) = 0.0;
111  }
112  return V * D * V.inverse();
113 }
114 
115 void FilterZeroWeightMarkersFromTracks(const Tracks& tracks,
116  Tracks* filtered_tracks) {
117  vector<Marker> all_markers = tracks.AllMarkers();
118 
119  for (int i = 0; i < all_markers.size(); ++i) {
120  Marker& marker = all_markers[i];
121  if (marker.weight != 0.0) {
122  filtered_tracks->Insert(
123  marker.image, marker.track, marker.x, marker.y, marker.weight);
124  }
125  }
126 }
127 
128 } // namespace
129 
131  const CameraIntrinsics& intrinsics,
132  vector<int>& keyframes) {
133  // Mirza Tahir Ahmed, Matthew N. Dailey
134  // Robust key frame extraction for 3D reconstruction from video streams
135  //
136  // http://www.cs.ait.ac.th/~mdailey/papers/Tahir-KeyFrame.pdf
137 
138  Tracks filtered_tracks;
139  FilterZeroWeightMarkersFromTracks(_tracks, &filtered_tracks);
140 
141  int max_image = filtered_tracks.MaxImage();
142  int next_keyframe = 1;
143  int number_keyframes = 0;
144 
145  // Limit correspondence ratio from both sides.
146  // On the one hand if number of correspondent features is too low,
147  // triangulation will suffer.
148  // On the other hand high correspondence likely means short baseline.
149  // which also will affect om accuracy
150  const double Tmin = 0.8;
151  const double Tmax = 1.0;
152 
153  Mat3 N = IntrinsicsNormalizationMatrix(intrinsics);
154  Mat3 N_inverse = N.inverse();
155 
156  double Sc_best = std::numeric_limits<double>::max();
157  double success_intersects_factor_best = 0.0f;
158 
159  while (next_keyframe != -1) {
160  int current_keyframe = next_keyframe;
161  double Sc_best_candidate = std::numeric_limits<double>::max();
162 
163  LG << "Found keyframe " << next_keyframe;
164 
165  number_keyframes++;
166  next_keyframe = -1;
167 
168  for (int candidate_image = current_keyframe + 1;
169  candidate_image <= max_image;
170  candidate_image++) {
171  // Conjunction of all markers from both keyframes
172  vector<Marker> all_markers = filtered_tracks.MarkersInBothImages(
173  current_keyframe, candidate_image);
174 
175  // Match keypoints between frames current_keyframe and candidate_image
176  vector<Marker> tracked_markers =
177  filtered_tracks.MarkersForTracksInBothImages(current_keyframe,
178  candidate_image);
179 
180  // Correspondences in normalized space
181  Mat x1, x2;
182  CoordinatesForMarkersInImage(tracked_markers, current_keyframe, &x1);
183  CoordinatesForMarkersInImage(tracked_markers, candidate_image, &x2);
184 
185  LG << "Found " << x1.cols() << " correspondences between "
186  << current_keyframe << " and " << candidate_image;
187 
188  // Not enough points to construct fundamental matrix
189  if (x1.cols() < 8 || x2.cols() < 8)
190  continue;
191 
192  // STEP 1: Correspondence ratio constraint
193  int Tc = tracked_markers.size();
194  int Tf = all_markers.size();
195  double Rc = static_cast<double>(Tc) / Tf;
196 
197  LG << "Correspondence between " << current_keyframe << " and "
198  << candidate_image << ": " << Rc;
199 
200  if (Rc < Tmin || Rc > Tmax)
201  continue;
202 
203  Mat3 H, F;
204 
205  // Estimate homography using default options.
206  EstimateHomographyOptions estimate_homography_options;
208  x1, x2, estimate_homography_options, &H);
209 
210  // Convert homography to original pixel space.
211  H = N_inverse * H * N;
212 
213  EstimateFundamentalOptions estimate_fundamental_options;
215  x1, x2, estimate_fundamental_options, &F);
216 
217  // Convert fundamental to original pixel space.
218  F = N_inverse * F * N;
219 
220  // TODO(sergey): STEP 2: Discard outlier matches
221 
222  // STEP 3: Geometric Robust Information Criteria
223 
224  // Compute error values for homography and fundamental matrices
225  Vec H_e, F_e;
226  H_e.resize(x1.cols());
227  F_e.resize(x1.cols());
228  for (int i = 0; i < x1.cols(); i++) {
229  Vec2 current_x1, current_x2;
230 
231  intrinsics.NormalizedToImageSpace(
232  x1(0, i), x1(1, i), &current_x1(0), &current_x1(1));
233 
234  intrinsics.NormalizedToImageSpace(
235  x2(0, i), x2(1, i), &current_x2(0), &current_x2(1));
236 
237  H_e(i) = SymmetricGeometricDistance(H, current_x1, current_x2);
238  F_e(i) = SymmetricEpipolarDistance(F, current_x1, current_x2);
239  }
240 
241  LG << "H_e: " << H_e.transpose();
242  LG << "F_e: " << F_e.transpose();
243 
244  // Degeneracy constraint
245  double GRIC_H = GRIC(H_e, 2, 8, 4);
246  double GRIC_F = GRIC(F_e, 3, 7, 4);
247 
248  LG << "GRIC values for frames " << current_keyframe << " and "
249  << candidate_image << ", H-GRIC: " << GRIC_H << ", F-GRIC: " << GRIC_F;
250 
251  if (GRIC_H <= GRIC_F)
252  continue;
253 
254  // TODO(sergey): STEP 4: PELC criterion
255 
256  // STEP 5: Estimation of reconstruction error
257  //
258  // Uses paper Keyframe Selection for Camera Motion and Structure
259  // Estimation from Multiple Views
260  // Uses ftp://ftp.tnt.uni-hannover.de/pub/papers/2004/ECCV2004-TTHBAW.pdf
261  // Basically, equation (15)
262  //
263  // TODO(sergey): separate all the constraints into functions,
264  // this one is getting to much cluttered already
265 
266  // Definitions in equation (15):
267  // - I is the number of 3D feature points
268  // - A is the number of essential parameters of one camera
269 
271 
272  // The F matrix should be an E matrix, but squash it just to be sure
273 
274  // Reconstruction should happen using normalized fundamental matrix
275  Mat3 F_normal = N * F * N_inverse;
276 
277  Mat3 E;
278  FundamentalToEssential(F_normal, &E);
279 
280  // Recover motion between the two images. Since this function assumes a
281  // calibrated camera, use the identity for K
282  Mat3 R;
283  Vec3 t;
284  Mat3 K = Mat3::Identity();
285 
287  E, K, x1.col(0), K, x2.col(0), &R, &t)) {
288  LG << "Failed to compute R and t from E and K";
289  continue;
290  }
291 
292  LG << "Camera transform between frames " << current_keyframe << " and "
293  << candidate_image << ":\nR:\n"
294  << R << "\nt:" << t.transpose();
295 
296  // First camera is identity, second one is relative to it
298  current_keyframe, Mat3::Identity(), Vec3::Zero());
299  reconstruction.InsertCamera(candidate_image, R, t);
300 
301  // Reconstruct 3D points
302  int intersects_total = 0, intersects_success = 0;
303  for (int i = 0; i < tracked_markers.size(); i++) {
304  if (!reconstruction.PointForTrack(tracked_markers[i].track)) {
305  vector<Marker> reconstructed_markers;
306 
307  int track = tracked_markers[i].track;
308 
309  reconstructed_markers.push_back(tracked_markers[i]);
310 
311  // We know there're always only two markers for a track
312  // Also, we're using brute-force search because we don't
313  // actually know about markers layout in a list, but
314  // at this moment this cycle will run just once, which
315  // is not so big deal
316 
317  for (int j = i + 1; j < tracked_markers.size(); j++) {
318  if (tracked_markers[j].track == track) {
319  reconstructed_markers.push_back(tracked_markers[j]);
320  break;
321  }
322  }
323 
324  intersects_total++;
325 
326  if (EuclideanIntersect(reconstructed_markers, &reconstruction)) {
327  LG << "Ran Intersect() for track " << track;
328  intersects_success++;
329  } else {
330  LG << "Filed to intersect track " << track;
331  }
332  }
333  }
334 
335  double success_intersects_factor =
336  (double)intersects_success / intersects_total;
337 
338  if (success_intersects_factor < success_intersects_factor_best) {
339  LG << "Skip keyframe candidate because of "
340  "lower successful intersections ratio";
341 
342  continue;
343  }
344 
345  success_intersects_factor_best = success_intersects_factor;
346 
347  Tracks two_frames_tracks(tracked_markers);
348  PolynomialCameraIntrinsics empty_intrinsics;
349  BundleEvaluation evaluation;
350  evaluation.evaluate_jacobian = true;
351 
352  EuclideanBundleCommonIntrinsics(two_frames_tracks,
356  &empty_intrinsics,
357  &evaluation);
358 
359  Mat& jacobian = evaluation.jacobian;
360 
361  Mat JT_J = jacobian.transpose() * jacobian;
362  // There are 7 degrees of freedom, so clamp them out.
363  Mat JT_J_inv = PseudoInverseWithClampedEigenvalues(JT_J, 7);
364 
365  Mat temp_derived = JT_J * JT_J_inv * JT_J;
366  bool is_inversed = (temp_derived - JT_J).cwiseAbs2().sum() <
367  1e-4 * std::min(temp_derived.cwiseAbs2().sum(),
368  JT_J.cwiseAbs2().sum());
369 
370  LG << "Check on inversed: " << (is_inversed ? "true" : "false")
371  << ", det(JT_J): " << JT_J.determinant();
372 
373  if (!is_inversed) {
374  LG << "Ignoring candidature due to poor jacobian stability";
375  continue;
376  }
377 
378  Mat Sigma_P;
379  Sigma_P = JT_J_inv.bottomRightCorner(evaluation.num_points * 3,
380  evaluation.num_points * 3);
381 
382  int I = evaluation.num_points;
383  int A = 12;
384 
385  double Sc = static_cast<double>(I + A) / Square(3 * I) * Sigma_P.trace();
386 
387  LG << "Expected estimation error between " << current_keyframe << " and "
388  << candidate_image << ": " << Sc;
389 
390  // Pairing with a lower Sc indicates a better choice
391  if (Sc > Sc_best_candidate)
392  continue;
393 
394  Sc_best_candidate = Sc;
395 
396  next_keyframe = candidate_image;
397  }
398 
399  // This is a bit arbitrary and main reason of having this is to deal
400  // better with situations when there's no keyframes were found for
401  // current keyframe this could happen when there's no so much parallax
402  // in the beginning of image sequence and then most of features are
403  // getting occluded. In this case there could be good keyframe pair in
404  // the middle of the sequence
405  //
406  // However, it's just quick hack and smarter way to do this would be nice
407  if (next_keyframe == -1) {
408  next_keyframe = current_keyframe + 10;
409  number_keyframes = 0;
410 
411  if (next_keyframe >= max_image)
412  break;
413 
414  LG << "Starting searching for keyframes starting from " << next_keyframe;
415  } else {
416  // New pair's expected reconstruction error is lower
417  // than existing pair's one.
418  //
419  // For now let's store just one candidate, easy to
420  // store more candidates but needs some thoughts
421  // how to choose best one automatically from them
422  // (or allow user to choose pair manually).
423  if (Sc_best > Sc_best_candidate) {
424  keyframes.clear();
425  keyframes.push_back(current_keyframe);
426  keyframes.push_back(next_keyframe);
427  Sc_best = Sc_best_candidate;
428  }
429  }
430  }
431 }
432 
433 } // namespace libmv
#define D
typedef double(DMatrix)[4][4]
#define K(key)
_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 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
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
#define A
void NormalizedToImageSpace(double normalized_x, double normalized_y, double *image_x, double *image_y) const
ProjectivePoint * PointForTrack(int track)
Returns a pointer to the point corresponding to track.
vector< Marker > MarkersInBothImages(int image1, int image2) const
Returns all the markers visible in image1 and image2.
vector< Marker > MarkersForTracksInBothImages(int image1, int image2) const
int MaxImage() const
Returns the maximum image identifier used.
float[3][3] Mat3
Definition: gpu_matrix.cc:27
const ProjectiveReconstruction & reconstruction
Definition: intersect.cc:198
#define LG
ccl_device_inline float3 log(float3 v)
Definition: math_float3.h:397
#define N
#define T
#define F
#define R
#define H(x, y, z)
static double epsilon
T Square(T x)
Definition: numeric.h:247
Eigen::VectorXd Vec
Definition: numeric.h:61
@ BUNDLE_NO_CONSTRAINTS
Definition: bundle.h:117
bool EstimateFundamentalFromCorrespondences(const Mat &x1, const Mat &x2, const EstimateFundamentalOptions &options, Mat3 *F)
Definition: fundamental.cc:492
@ BUNDLE_NO_INTRINSICS
Definition: bundle.h:100
Eigen::Matrix< double, 3, 3 > Mat3
Definition: numeric.h:72
Eigen::Vector2d Vec2
Definition: numeric.h:105
void SelectKeyframesBasedOnGRICAndVariance(const Tracks &_tracks, const CameraIntrinsics &intrinsics, vector< int > &keyframes)
Eigen::MatrixXd Mat
Definition: numeric.h:60
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
bool EuclideanIntersect(const vector< Marker > &markers, EuclideanReconstruction *reconstruction)
Definition: intersect.cc:69
bool EstimateHomography2DFromCorrespondences(const Mat &x1, const Mat &x2, const EstimateHomographyOptions &options, Mat3 *H)
Eigen::Vector3d Vec3
Definition: numeric.h:106
void EuclideanBundleCommonIntrinsics(const Tracks &tracks, const int bundle_intrinsics, const int bundle_constraints, EuclideanReconstruction *reconstruction, CameraIntrinsics *intrinsics, BundleEvaluation *evaluation)
Definition: bundle.cc:661
double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2)
Definition: fundamental.cc:253
void CoordinatesForMarkersInImage(const vector< Marker > &markers, int image, Mat *coordinates)
void FundamentalToEssential(const Mat3 &F, Mat3 *E)
Definition: fundamental.cc:393
double SymmetricGeometricDistance(const Mat3 &H, const Vec2 &x1, const Vec2 &x2)
#define I
#define min(a, b)
Definition: sort.c:35
ListBase tracks
Definition: tracking.c:60
float max
CCL_NAMESPACE_BEGIN struct Window V