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

#include <essential_matrix_solver.h>

Public Member Functions

 EssentialMatrixSolver ()
 
 ~EssentialMatrixSolver ()
 
Matrix3d ComputeEssentialMatrix (const Matrix3d &F, const CameraIntrinsics &intrinsics1, const CameraIntrinsics &intrinsics2)
 
bool ComputeExtrinsics (const Matrix3d &E, const FeatureMatchList &matches, const CameraIntrinsics &intrinsics1, const CameraIntrinsics &intrinsics2, Pose &relative_pose)
 

Detailed Description

Definition at line 62 of file essential_matrix_solver.h.

Constructor & Destructor Documentation

bsfm::EssentialMatrixSolver::EssentialMatrixSolver ( )
inline

Definition at line 66 of file essential_matrix_solver.h.

66 {}
bsfm::EssentialMatrixSolver::~EssentialMatrixSolver ( )
inline

Definition at line 67 of file essential_matrix_solver.h.

67 {}

Member Function Documentation

Matrix3d bsfm::EssentialMatrixSolver::ComputeEssentialMatrix ( const Matrix3d &  F,
const CameraIntrinsics intrinsics1,
const CameraIntrinsics intrinsics2 
)

Definition at line 66 of file essential_matrix_solver.cpp.

68  {
69  // Extract intrinsics matrices.
70  Matrix3d K1(intrinsics1.K());
71  Matrix3d K2(intrinsics2.K());
72 
73  // Calculate the essential matrix.
74  return K2.transpose() * F * K1;
75 }
bool bsfm::EssentialMatrixSolver::ComputeExtrinsics ( const Matrix3d &  E,
const FeatureMatchList matches,
const CameraIntrinsics intrinsics1,
const CameraIntrinsics intrinsics2,
Pose relative_pose 
)

Definition at line 81 of file essential_matrix_solver.cpp.

84  {
85  // Initialize the W matrix.
86  Matrix3d W;
87  W << 0.0, -1.0, 0.0,
88  1.0, 0.0, 0.0,
89  0.0, 0.0, 1.0;
90 
91  // Perform an SVD on the essential matrix.
92  Eigen::JacobiSVD<Matrix3d> svd;
93  svd.compute(E, Eigen::ComputeFullU | Eigen::ComputeFullV);
94  if (!svd.computeU() || !svd.computeV()) {
95  VLOG(1) << "Failed to compute a singular value decomposition of "
96  << "the essential matrix.";
97  return false;
98  }
99 
100  // The essential matrix must satisfy E = U * diag(1, 1, 0) * V^T. Use U and V
101  // to get a new E, run another SVD, and get the normalized U and V.
102  Matrix3d sigma(Matrix3d::Identity());
103  sigma(2, 2) = 0;
104  Matrix3d E_augmented = svd.matrixU() * sigma * svd.matrixV().transpose();
105 
106  svd.compute(E_augmented, Eigen::ComputeFullU | Eigen::ComputeFullV);
107  if (!svd.computeU() || !svd.computeV()) {
108  VLOG(1) << "Failed to compute a singular value decomposition of "
109  << "the essential matrix.";
110  return false;
111  }
112 
113  // Compute two possibilities for rotation.
114  Matrix3d R1 = svd.matrixU() * W * svd.matrixV().transpose();
115  Matrix3d R2 = svd.matrixU() * W.transpose() * svd.matrixV().transpose();
116 
117  // Ensure positive determinants.
118  if (R1.determinant() < 0)
119  R1 = -R1;
120  if (R2.determinant() < 0)
121  R2 = -R2;
122 
123  // Compute two possibilities for translation
124  Vector3d t1, t2;
125  t1 = svd.matrixU().col(2);
126  t2 = -t1;
127 
128  // Build four possible Poses.
129  std::vector<Pose> poses;
130  poses.push_back(Pose(R1, t1));
131  poses.push_back(Pose(R1, t2));
132  poses.push_back(Pose(R2, t1));
133  poses.push_back(Pose(R2, t2));
134 
135  // Set the first camera's position to identity in rotation and translation.
136  CameraExtrinsics extrinsics1;
137  extrinsics1.SetWorldToCamera(Pose());
138 
139  Camera camera1;
140  camera1.SetExtrinsics(extrinsics1);
141  camera1.SetIntrinsics(intrinsics1);
142 
143  // Test how many points are in front of each pose and the identity pose.
144  Pose best_pose;
145  int best_num_points = -1;
146 
147  double u = 0.0, v = 0.0;
148  for (int ii = 0; ii < poses.size(); ii++) {
149  int num_points = 0;
150 
151  CameraExtrinsics extrinsics2;
152  extrinsics2.SetWorldToCamera(poses[ii]);
153 
154  Camera camera2;
155  camera2.SetExtrinsics(extrinsics2);
156  camera2.SetIntrinsics(intrinsics2);
157 
158  for (int jj = 0; jj < matches.size(); jj++) {
159  // Triangulate points and test if the 3D estimate is in front of both
160  // cameras.
161  Point3D point;
162  if (!Triangulate(matches[jj], camera1, camera2, point)) {
163  continue;
164  }
165 
166  num_points++;
167  }
168 
169  // Update best_cnt and best_pose.
170  if (num_points > best_num_points) {
171  best_num_points = num_points;
172  best_pose = poses[ii];
173  }
174  }
175 
176  // Return with false if not enough points found in front of the cameras.
177  if (best_num_points < FLAGS_min_points_visible_ratio * matches.size()) {
178  VLOG(1) << "Did not find enough points in front of both cameras.";
179  return false;
180  }
181 
182  relative_pose = best_pose;
183 
184  return true;
185 }
bool Triangulate(const FeatureList &features, const std::vector< Camera > &cameras, Point3D &point)

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