Berkeley SfM
Public Member Functions | List of all members
bsfm::EightPointAlgorithmSolver Class Reference

#include <eight_point_algorithm_solver.h>

Inheritance diagram for bsfm::EightPointAlgorithmSolver:
bsfm::FundamentalMatrixSolver

Public Member Functions

 EightPointAlgorithmSolver ()
 
virtual ~EightPointAlgorithmSolver ()
 
virtual bool ComputeFundamentalMatrix (const FeatureMatchList &matched_features, Matrix3d &fundamental_matrix) const
 
- Public Member Functions inherited from bsfm::FundamentalMatrixSolver
 FundamentalMatrixSolver ()
 
virtual ~FundamentalMatrixSolver ()
 
virtual void AddMatchedImagePair (const PairwiseImageMatch &matched_image_data)
 
virtual void AddMatchedImagePairs (const PairwiseImageMatchList &matched_image_data)
 
virtual void SetOptions (const FundamentalMatrixSolverOptions &options)
 
virtual bool ComputeFundamentalMatrices (std::vector< Matrix3d > &fundamental_matrices)
 

Additional Inherited Members

- Protected Attributes inherited from bsfm::FundamentalMatrixSolver
PairwiseImageMatchList matched_image_data_
 
FundamentalMatrixSolverOptions options_
 

Detailed Description

Definition at line 66 of file eight_point_algorithm_solver.h.

Constructor & Destructor Documentation

bsfm::EightPointAlgorithmSolver::EightPointAlgorithmSolver ( )
inline

Definition at line 68 of file eight_point_algorithm_solver.h.

68 { }
virtual bsfm::EightPointAlgorithmSolver::~EightPointAlgorithmSolver ( )
inlinevirtual

Definition at line 69 of file eight_point_algorithm_solver.h.

69 { }

Member Function Documentation

bool bsfm::EightPointAlgorithmSolver::ComputeFundamentalMatrix ( const FeatureMatchList matched_features,
Matrix3d &  fundamental_matrix 
) const
virtual

Implements bsfm::FundamentalMatrixSolver.

Definition at line 47 of file eight_point_algorithm_solver.cpp.

49  {
50  // Following: https://www8.cs.umu.se/kurser/TDBD19/VT05/reconstruct-4.pdf
51 
52  // First make sure we even have enough matches to run the eight-point
53  // algorithm.
54  if (matched_features.size() < 8) {
55  VLOG(1) << "Cannot use the eight-point algorithm with less than 8 feature "
56  "matches.";
57  return false;
58  }
59 
60  // Build the A matrix from matched features.
61  MatrixXd A;
62  A.resize(matched_features.size(), 9);
63 
64  // If requested, normalize feature positions prior to computing the A matrix.
65  Matrix3d T1(MatrixXd::Identity(3, 3));
66  Matrix3d T2(MatrixXd::Identity(3, 3));
68  T1 = ComputeNormalization(matched_features, true /*feature set 1*/);
69  T2 = ComputeNormalization(matched_features, false /*feature set 2*/);
70  }
71 
72  // Incrementally add rows to A.
73  for (size_t ii = 0; ii < matched_features.size(); ++ii) {
74  double u1 = matched_features[ii].feature1_.u_;
75  double v1 = matched_features[ii].feature1_.v_;
76  double u2 = matched_features[ii].feature2_.u_;
77  double v2 = matched_features[ii].feature2_.v_;
78 
80  u1 = T1(0, 0) * u1 + T1(0, 2);
81  v1 = T1(1, 1) * v1 + T1(1, 2);
82  u2 = T2(0, 0) * u2 + T2(0, 2);
83  v2 = T2(1, 1) * v2 + T2(1, 2);
84  }
85 
86  A(ii, 0) = u1*u2;
87  A(ii, 1) = v1*u2;
88  A(ii, 2) = u2;
89  A(ii, 3) = u1*v2;
90  A(ii, 4) = v1*v2;
91  A(ii, 5) = v2;
92  A(ii, 6) = u1;
93  A(ii, 7) = v1;
94  A(ii, 8) = 1;
95  }
96 
97  // Get svd(A). Save some time and compute a thin U. We still need a full V.
98  Eigen::JacobiSVD<Eigen::MatrixXd> svd;
99  svd.compute(A, Eigen::ComputeThinU | Eigen::ComputeFullV);
100  if (!svd.computeV()) {
101  VLOG(1) << "Failed to compute a singular value decomposition of A matrix.";
102  return false;
103  }
104 
105  // Get the fundamental matrix elements from the SVD decomposition.
106  const VectorXd f_vec = svd.matrixV().col(8);
107 
108  // Turn the elements of the fundamental matrix into an actual matrix.
109  fundamental_matrix.row(0) = f_vec.topRows(3).transpose();
110  fundamental_matrix.row(1) = f_vec.middleRows(3, 3).transpose();
111  fundamental_matrix.row(2) = f_vec.bottomRows(3).transpose();
112 
113  // If requested, make sure that the computed fundamental matrix has rank 2.
114  // This is step 2 of the eight-point algorithm from the slides.
116  // Get svd(F). We need full U and V to reconstruct the rank deficient F.
117  svd.compute(fundamental_matrix, Eigen::ComputeFullU | Eigen::ComputeFullV);
118  svd.compute(fundamental_matrix);
119  if (!svd.computeU() || !svd.computeV()) {
120  VLOG(1) << "Failed to compute a singular value decomposition of "
121  "fundamental matrix.";
122  return false;
123  }
124 
125  // Build a matrix of the first 8 singular values down the diagonal. Make the
126  // last diagonal entry 0.
127  MatrixXd S_deficient(MatrixXd::Zero(3, 3));
128  S_deficient(0, 0) = svd.singularValues()(0);
129  S_deficient(1, 1) = svd.singularValues()(1);
130  fundamental_matrix = svd.matrixU() * S_deficient * svd.matrixV().transpose();
131  }
132 
133  // If normalization was requested, we need to 'un-normalize' the fundamental
134  // matrix.
136  fundamental_matrix = T2.transpose() * fundamental_matrix * T1;
137  }
138 
139  return true;
140 }
Matrix3d ComputeNormalization(const FeatureMatchList &matched_features, bool use_feature_set1)
FundamentalMatrixSolverOptions options_

The documentation for this class was generated from the following files: