~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to extern/libmv/libmv/multiview/euclidean_resection.cc

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
bool EuclideanResection(const Mat2X &x_camera, 
38
38
                        const Mat3X &X_world,
39
39
                        Mat3 *R, Vec3 *t,
40
 
                        ResectionMethod method) {
 
40
                        ResectionMethod method,
 
41
                        double success_threshold) {
41
42
  switch (method) {
42
43
    case RESECTION_ANSAR_DANIILIDIS:
43
44
      EuclideanResectionAnsarDaniilidis(x_camera, X_world, R, t);
44
45
      break;
45
46
    case RESECTION_EPNP:
46
 
      return EuclideanResectionEPnP(x_camera, X_world, R, t);      
 
47
      return EuclideanResectionEPnP(x_camera, X_world, R, t, success_threshold);
47
48
      break;
48
49
    default:
49
50
      LOG(FATAL) << "Unknown resection method.";
351
352
}
352
353
 
353
354
// Selects 4 virtual control points using mean and PCA.
354
 
void SelectControlPoints(const Mat3X &X_world, 
355
 
                         Mat *X_centered, 
356
 
                         Mat34 *X_control_points) {
 
355
static void SelectControlPoints(const Mat3X &X_world,
 
356
                                Mat *X_centered,
 
357
                                Mat34 *X_control_points) {
357
358
  size_t num_points = X_world.cols();
358
359
 
359
360
  // The first virtual control point, C0, is the centroid.
377
378
}
378
379
 
379
380
// Computes the barycentric coordinates for all real points
380
 
void ComputeBarycentricCoordinates(const Mat3X &X_world_centered, 
381
 
                                   const Mat34 &X_control_points,
382
 
                                   Mat4X *alphas) {
 
381
static void ComputeBarycentricCoordinates(const Mat3X &X_world_centered,
 
382
                                          const Mat34 &X_control_points,
 
383
                                          Mat4X *alphas) {
383
384
  size_t num_points = X_world_centered.cols();
384
385
  Mat3 C2 ;
385
386
  for (size_t c = 1; c < 4; c++) {
398
399
}
399
400
 
400
401
// Estimates the coordinates of all real points in the camera coordinate frame
401
 
void ComputePointsCoordinatesInCameraFrame(
 
402
static void ComputePointsCoordinatesInCameraFrame(
402
403
    const Mat4X &alphas, 
403
404
    const Vec4 &betas,
404
405
    const Eigen::Matrix<double, 12, 12> &U,
435
436
}
436
437
 
437
438
bool EuclideanResectionEPnP(const Mat2X &x_camera,
438
 
                            const Mat3X &X_world, 
439
 
                            Mat3 *R, Vec3 *t) {
 
439
                            const Mat3X &X_world,
 
440
                            Mat3 *R, Vec3 *t,
 
441
                            double success_threshold) {
440
442
  CHECK(x_camera.cols() == X_world.cols());
441
443
  CHECK(x_camera.cols() > 3);
442
444
  size_t num_points = X_world.cols();
535
537
  vector<Vec3> ts(3);
536
538
  Vec rmse(3);
537
539
 
538
 
  // TODO(julien): Document where the "1e-3" magical constant comes from below.
 
540
  // At one point this threshold was 1e-3, and caused no end of problems in
 
541
  // Blender by causing frames to not resect when they would have worked fine.
 
542
  // When the resect failed, the projective followup is run leading to worse
 
543
  // results, and often the dreaded "flipping" where objects get flipped
 
544
  // between frames. Instead, disable the check for now, always succeeding. The
 
545
  // ultimate check is always reprojection error anyway.
 
546
  //
 
547
  // TODO(keir): Decide if setting this to infinity, effectively disabling the
 
548
  // check, is the right approach. So far this seems the case.
 
549
  //
 
550
  // TODO(sergey): Made it an option for now, in some cases it makes sense to
 
551
  // still fallback to reprojection solution (see bug [#32765] from Blender bug tracker)
 
552
 
 
553
  // double kSuccessThreshold = std::numeric_limits<double>::max();
 
554
  double kSuccessThreshold = success_threshold;
539
555
 
540
556
  // Find the first possible solution for R, t corresponding to:
541
557
  // Betas          = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
548
564
  Eigen::JacobiSVD<Mat> svd_of_l4(l_6x4, 
549
565
                                  Eigen::ComputeFullU | Eigen::ComputeFullV);
550
566
  Vec4 b4 = svd_of_l4.solve(rho);
551
 
  if ((l_6x4 * b4).isApprox(rho, 1e-3)) {
 
567
  if ((l_6x4 * b4).isApprox(rho, kSuccessThreshold)) {
552
568
    if (b4(0) < 0) {
553
569
      b4 = -b4;
554
570
    } 
574
590
  Vec3 b3 = svdOfL3.solve(rho);
575
591
  VLOG(2) << " rho = " << rho;
576
592
  VLOG(2) << " l_6x3 * b3 = " << l_6x3 * b3;
577
 
  if ((l_6x3 * b3).isApprox(rho, 1e-3)) {
 
593
  if ((l_6x3 * b3).isApprox(rho, kSuccessThreshold)) {
578
594
    if (b3(0) < 0) {
579
595
      betas(0) = std::sqrt(-b3(0));
580
596
      betas(1) = (b3(2) < 0) ? std::sqrt(-b3(2)) : 0;
605
621
  Eigen::JacobiSVD<Mat> svdOfL5(l_6x5, 
606
622
                                Eigen::ComputeFullU | Eigen::ComputeFullV);
607
623
  Vec5 b5 = svdOfL5.solve(rho);
608
 
  if ((l_6x5 * b5).isApprox(rho, 1e-3)) {
 
624
  if ((l_6x5 * b5).isApprox(rho, kSuccessThreshold)) {
609
625
    if (b5(0) < 0) {
610
626
      betas(0) = std::sqrt(-b5(0));
611
627
      if (b5(2) < 0) {