Berkeley SfM
Namespaces | Classes | Typedefs | Functions | Variables
bsfm Namespace Reference

Namespaces

 drawing
 
 math
 
 strings
 
 util
 

Classes

class  BundleAdjuster
 
struct  BundleAdjustmentError
 
struct  BundleAdjustmentOptions
 
class  Camera
 
class  CameraExtrinsics
 
class  CameraIntrinsics
 
class  Covariance3D
 
class  DescriptorExtractor
 
class  DistanceMetric
 
class  EightPointAlgorithmSolver
 
class  EssentialMatrixSolver
 
struct  Feature
 
struct  FeatureMatch
 
class  FeatureMatcher
 
struct  FeatureMatcherOptions
 
class  FlannDescriptorKDTree
 
struct  FundamentalMatrixRansacModel
 
class  FundamentalMatrixRansacProblem
 
class  FundamentalMatrixSolver
 
struct  FundamentalMatrixSolverOptions
 
struct  GeometricError
 
class  Image
 
class  KeypointDetector
 
class  Landmark
 
struct  LightFeatureMatch
 
class  NaiveMatcher2D2D
 
class  NaiveMatcher2D3D
 
class  Observation
 
struct  PairwiseImageMatch
 
struct  PnPRansacModel
 
class  PnPRansacProblem
 
class  Point3D
 
class  Pose
 
class  PoseEstimator2D3D
 
class  Ransac
 
struct  RansacModel
 
struct  RansacOptions
 
class  RansacProblem
 
class  View
 

Typedefs

typedef std::vector< Point3DPoint3DList
 
typedef std::vector< FeatureFeatureList
 
typedef std::vector< FeatureMatchFeatureMatchList
 
typedef std::vector< LightFeatureMatchLightFeatureMatchList
 
typedef std::vector< PairwiseImageMatchPairwiseImageMatchList
 
typedef unsigned int ViewIndex
 
typedef unsigned int LandmarkIndex
 
typedef ::cv::Mat DescriptorList
 
typedef ::cv::KeyPoint Keypoint
 
typedef ::std::vector< KeypointKeypointList
 
typedef ::Eigen::Matrix< double, Eigen::Dynamic, 1 > Descriptor
 
typedef ::Eigen::Matrix< double, 3, 4 > Matrix34d
 

Functions

Matrix3d ComputeNormalization (const FeatureMatchList &matched_features, bool use_feature_set1)
 
Matrix3d ComputeNormalization (const FeatureList &features)
 
Matrix4d ComputeNormalization (const Point3DList &points)
 
Matrix3d EulerAnglesToMatrix (double phi, double theta, double psi)
 
Matrix3d EulerAnglesToMatrix (const Vector3d &euler_angles)
 
Vector3d MatrixToEulerAngles (const Matrix3d &R)
 
double Roll (const Matrix3d &R)
 
double Pitch (const Matrix3d &R)
 
double Yaw (const Matrix3d &R)
 
double Unroll (double angle)
 
double Normalize (double angle)
 
double S1Distance (double from, double to)
 
double D2R (double angle)
 
double R2D (double angle)
 
double SO3Error (const Matrix3d &R1, const Matrix3d &R2)
 
bool Triangulate (const FeatureList &features, const std::vector< Camera > &cameras, Point3D &point)
 
bool Triangulate (const FeatureMatch &feature_match, const Camera &camera1, const Camera &camera2, Point3D &point)
 
bool Triangulate (const FeatureMatchList &feature_matches, const Camera &camera1, const Camera &camera2, Point3DList &points)
 
template<typename T >
void OpenCVToEigenMat (const cv::Mat &cv_mat, Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &eigen_mat)
 
template<typename T >
void EigenMatToOpenCV (const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &eigen_mat, cv::Mat &cv_mat)
 

Variables

static constexpr ViewIndex kInvalidView = std::numeric_limits<ViewIndex>::max()
 
static constexpr LandmarkIndex kInvalidLandmark
 

Typedef Documentation

typedef ::Eigen::Matrix<double, Eigen::Dynamic, 1> bsfm::Descriptor

Definition at line 83 of file types.h.

typedef ::cv::Mat bsfm::DescriptorList

Definition at line 76 of file types.h.

typedef std::vector<Feature> bsfm::FeatureList

Definition at line 65 of file feature.h.

typedef std::vector<FeatureMatch> bsfm::FeatureMatchList

Definition at line 99 of file feature_match.h.

typedef ::cv::KeyPoint bsfm::Keypoint

Definition at line 79 of file types.h.

typedef ::std::vector<Keypoint> bsfm::KeypointList

Definition at line 80 of file types.h.

typedef unsigned int bsfm::LandmarkIndex

Definition at line 62 of file types.h.

Definition at line 100 of file feature_match.h.

typedef ::Eigen::Matrix<double, 3, 4> bsfm::Matrix34d

Definition at line 87 of file types.h.

Definition at line 69 of file pairwise_image_match.h.

typedef std::vector<Point3D> bsfm::Point3DList

Definition at line 100 of file point_3d.h.

typedef unsigned int bsfm::ViewIndex

Definition at line 58 of file types.h.

Function Documentation

Matrix3d bsfm::ComputeNormalization ( const FeatureMatchList matched_features,
bool  use_feature_set1 
)

Definition at line 44 of file normalization.cpp.

45  {
46  if (matched_features.empty()) {
47  LOG(WARNING) << "Received no data to normalize. Returning identity.";
48  return MatrixXd::Identity(3, 3);
49  }
50 
51  // Compute a mean translation from the origin.
52  double mean_u = 0.0;
53  double mean_v = 0.0;
54  for (size_t ii = 0; ii < matched_features.size(); ++ii) {
55  if (use_feature_set1) {
56  mean_u += matched_features[ii].feature1_.u_;
57  mean_v += matched_features[ii].feature1_.v_;
58  } else {
59  mean_u += matched_features[ii].feature2_.u_;
60  mean_v += matched_features[ii].feature2_.v_;
61  }
62  }
63  mean_u /= static_cast<double>(matched_features.size());
64  mean_v /= static_cast<double>(matched_features.size());
65 
66  // Compute a scale factor such that after translation, all points will be an
67  // average distance of sqrt(2) away from the origin.
68  // This uses Eqs. 1.28 - 1.37 from here:
69  // http://www.ecse.rpi.edu/Homepages/qji/CV/8point.pdf
70  double scale = 0.0;
71  for (size_t ii = 0; ii < matched_features.size(); ++ii) {
72  double u = 0.0, v = 0.0;
73  if (use_feature_set1) {
74  u = matched_features[ii].feature1_.u_;
75  v = matched_features[ii].feature1_.v_;
76  } else {
77  u = matched_features[ii].feature2_.u_;
78  v = matched_features[ii].feature2_.v_;
79  }
80 
81  scale += sqrt((u - mean_u) * (u - mean_u) + (v - mean_v) * (v - mean_v));
82  }
83  scale /= static_cast<double>(matched_features.size());
84  scale /= sqrt(2.0);
85 
86  // If the calculated scale, for some reason, is ridiculously small (i.e.
87  // dividing by zero), return an identity output matrix. This will make us not
88  // normalize the data, but we should still get an okay fundamental matrix.
89  if (scale < 1e-4) {
90  LOG(WARNING)
91  << "When normalizing feature coordinates scale factor was nearly zero. "
92  "Proceeding without normalizing data.";
93  return MatrixXd::Identity(3, 3);
94  }
95 
96  // Populate the output matrix.
97  Matrix3d T(MatrixXd::Identity(3, 3));
98  T(0, 0) = 1.0 / scale;
99  T(1, 1) = 1.0 / scale;
100  T(0, 2) = -mean_u / scale;
101  T(1, 2) = -mean_v / scale;
102 
103  return T;
104 }
Matrix3d bsfm::ComputeNormalization ( const FeatureList features)

Definition at line 106 of file normalization.cpp.

106  {
107  if (features.empty()) {
108  LOG(WARNING) << "Received no data to normalize. Returning identity.";
109  return MatrixXd::Identity(3, 3);
110  }
111 
112  // Compute a mean translation from the origin.
113  double mean_u = 0.0;
114  double mean_v = 0.0;
115  for (size_t ii = 0; ii < features.size(); ++ii) {
116  mean_u += features[ii].u_;
117  mean_v += features[ii].v_;
118  }
119  mean_u /= static_cast<double>(features.size());
120  mean_v /= static_cast<double>(features.size());
121 
122  // Compute a scale factor such that after translation, all points will be an
123  // average distance of sqrt(2) away from the origin.
124  // This uses Eqs. 1.28 - 1.37 from here:
125  // http://www.ecse.rpi.edu/Homepages/qji/CV/8point.pdf
126  double scale = 0.0;
127  for (size_t ii = 0; ii < features.size(); ++ii) {
128  double u = 0.0, v = 0.0;
129  u = features[ii].u_;
130  v = features[ii].v_;
131 
132  scale += sqrt((u - mean_u) * (u - mean_u) + (v - mean_v) * (v - mean_v));
133  }
134  scale /= static_cast<double>(features.size());
135  scale /= sqrt(2.0);
136 
137  // If the calculated scale, for some reason, is ridiculously small (i.e.
138  // dividing by zero), return an identity output matrix. This will make us not
139  // normalize the data, but we should still get an okay fundamental matrix.
140  if (scale < 1e-4) {
141  LOG(WARNING)
142  << "When normalizing feature coordinates scale factor was nearly zero. "
143  "Proceeding without normalizing data.";
144  return MatrixXd::Identity(3, 3);
145  }
146 
147  // Populate the output matrix.
148  Matrix3d T(MatrixXd::Identity(3, 3));
149  T(0, 0) = 1.0 / scale;
150  T(1, 1) = 1.0 / scale;
151  T(0, 2) = -mean_u / scale;
152  T(1, 2) = -mean_v / scale;
153 
154  return T;
155 }
Matrix4d bsfm::ComputeNormalization ( const Point3DList points)

Definition at line 157 of file normalization.cpp.

157  {
158  if (points.empty()) {
159  LOG(WARNING) << "Received no data to normalize. Returning identity.";
160  return MatrixXd::Identity(4, 4);
161  }
162 
163  // Compute a mean translation from the origin.
164  double mean_x = 0.0;
165  double mean_y = 0.0;
166  double mean_z = 0.0;
167  for (size_t ii = 0; ii < points.size(); ++ii) {
168  mean_x += points[ii].X();
169  mean_y += points[ii].Y();
170  mean_z += points[ii].Z();
171  }
172  mean_x /= static_cast<double>(points.size());
173  mean_y /= static_cast<double>(points.size());
174  mean_z /= static_cast<double>(points.size());
175 
176  // Compute a scale factor such that after translation, all points will be an
177  // average distance of sqrt(2) away from the origin.
178  // This uses Eqs. 1.28 - 1.37 from here:
179  // http://www.ecse.rpi.edu/Homepages/qji/CV/8point.pdf
180  double scale = 0.0;
181  for (size_t ii = 0; ii < points.size(); ++ii) {
182  double x = 0.0, y = 0.0, z = 0.0;
183  x = points[ii].X();
184  y = points[ii].Y();
185  z = points[ii].Z();
186 
187  scale += sqrt((x - mean_x) * (x - mean_x)
188  + (y - mean_y) * (y - mean_y)
189  + (z - mean_z) * (z - mean_z));
190  }
191  scale /= static_cast<double>(points.size());
192  scale /= sqrt(2.0);
193 
194  // If the calculated scale, for some reason, is ridiculously small (i.e.
195  // dividing by zero), return an identity output matrix. This will make us not
196  // normalize the data, but we should still get an okay fundamental matrix.
197  if (scale < 1e-4) {
198  LOG(WARNING)
199  << "When normalizing feature coordinates scale factor was nearly zero. "
200  "Proceeding without normalizing data.";
201  return MatrixXd::Identity(4, 4);
202  }
203 
204  // Populate the output matrix.
205  Matrix4d T(MatrixXd::Identity(4, 4));
206  T(0, 0) = 1.0 / scale;
207  T(1, 1) = 1.0 / scale;
208  T(2, 2) = 1.0 / scale;
209  T(0, 3) = -mean_x / scale;
210  T(1, 3) = -mean_y / scale;
211  T(2, 3) = -mean_z / scale;
212 
213  return T;
214 }
double bsfm::D2R ( double  angle)

Definition at line 153 of file rotation.cpp.

153  {
154  return angle * M_PI / 180.0;
155 }
template<typename T >
void bsfm::EigenMatToOpenCV ( const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &  eigen_mat,
cv::Mat &  cv_mat 
)
inline

Definition at line 175 of file image.h.

177  {
178  cv::eigen2cv(eigen_mat, cv_mat);
179 }
Matrix3d bsfm::EulerAnglesToMatrix ( double  phi,
double  theta,
double  psi 
)

Definition at line 49 of file rotation.cpp.

49  {
50  double c1 = std::cos(phi);
51  double c2 = std::cos(theta);
52  double c3 = std::cos(psi);
53  double s1 = std::sin(phi);
54  double s2 = std::sin(theta);
55  double s3 = std::sin(psi);
56 
57  Matrix3d R;
58  R(0, 0) = c2*c3;
59  R(0, 1) = c3*s1*s2 - c1*s3;
60  R(0, 2) = s1*s3 + c1*c3*s2;
61  R(1, 0) = c2*s3;
62  R(1, 1) = c1*c3 + s1*s2*s3;
63  R(1, 2) = c1*s2*s3 - c3*s1;
64  R(2, 0) = -s2;
65  R(2, 1) = c2*s1;
66  R(2, 2) = c1*c2;
67 
68  return R;
69 }
Matrix3d bsfm::EulerAnglesToMatrix ( const Vector3d &  euler_angles)

Definition at line 72 of file rotation.cpp.

72  {
73  return EulerAnglesToMatrix(euler_angles(0), euler_angles(1), euler_angles(2));
74 }
Matrix3d EulerAnglesToMatrix(const Vector3d &euler_angles)
Definition: rotation.cpp:72
Vector3d bsfm::MatrixToEulerAngles ( const Matrix3d &  R)

Definition at line 81 of file rotation.cpp.

81  {
82  // Make sure R is actually a rotation matrix.
83  if (std::abs(R.determinant() - 1) > 1e-4) {
84  LOG(WARNING) << "R does not have a determinant of 1.";
85  return Vector3d::Zero();
86  }
87 
88  double theta = -std::asin(R(2, 0));
89 
90  if (std::abs(cos(theta)) < 1e-8) {
91  LOG(WARNING) << "Theta is approximately +/- PI/2, which yields a "
92  "singularity. Cannot decompose matrix into Euler angles.";
93  return Vector3d(theta, 0.0, 0.0);
94  }
95 
96  double phi = std::atan2(R(2, 1), R(2, 2));
97  double psi = std::atan2(R(1, 0) / std::cos(theta), R(0, 0) / std::cos(theta));
98 
99  return Vector3d(phi, theta, psi);
100 }
double bsfm::Normalize ( double  angle)

Definition at line 135 of file rotation.cpp.

135  {
136  angle = fmod(angle + M_PI, 2.0 * M_PI);
137  if (angle < 0)
138  angle += 2.0 * M_PI;
139  return angle - M_PI;
140 }
template<typename T >
void bsfm::OpenCVToEigenMat ( const cv::Mat &  cv_mat,
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &  eigen_mat 
)
inline

Definition at line 160 of file image.h.

162  {
163  // Make sure the data is grayscale before converting to an eigen matrix.
164  if (cv_mat.channels() != 1) {
165  cv::Mat grayscale_mat;
166  cv::cvtColor(cv_mat, grayscale_mat, CV_RGB2GRAY);
167  cv::cv2eigen(grayscale_mat, eigen_mat);
168  } else {
169  cv::cv2eigen(cv_mat, eigen_mat);
170  }
171 }
double bsfm::Pitch ( const Matrix3d &  R)

Definition at line 113 of file rotation.cpp.

113  {
114  return -std::asin(R(2, 0));
115 }
double bsfm::R2D ( double  angle)

Definition at line 158 of file rotation.cpp.

158  {
159  return angle * 180.0 / M_PI;
160 }
double bsfm::Roll ( const Matrix3d &  R)

Definition at line 104 of file rotation.cpp.

104  {
105  double theta = -std::asin(R(2, 0));
106  if (std::abs(std::cos(theta)) < 1e-8)
107  return 0.0;
108  return std::atan2(R(2, 1), R(2, 2));
109 }
double bsfm::S1Distance ( double  from,
double  to 
)

Definition at line 145 of file rotation.cpp.

145  {
146  double d = Unroll(Unroll(to) - Unroll(from));
147  if (d > M_PI)
148  d -= 2.0*M_PI;
149  return Normalize(d);
150 }
double Normalize(double angle)
Definition: rotation.cpp:135
double Unroll(double angle)
Definition: rotation.cpp:127
double bsfm::SO3Error ( const Matrix3d &  R1,
const Matrix3d &  R2 
)

Definition at line 163 of file rotation.cpp.

163  {
164  const Matrix3d R_error = R1.transpose()*R2 - R2.transpose()*R1;
165 
166  // 'vee' is the inverse of the hat operator, and extracts a vector from a
167  // cross-product matrix.
168  const Vector3d R_vee(R_error(2,1), R_error(0,2), R_error(1,0));
169  return (0.5 * R_vee).norm();
170 }
bool bsfm::Triangulate ( const FeatureList features,
const std::vector< Camera > &  cameras,
Point3D point 
)

Definition at line 52 of file triangulation.cpp.

53  {
54  if (features.size() != cameras.size()) {
55  LOG(WARNING)
56  << "Number of features does not match number of cameras.";
57  return false;
58  }
59 
60  if (features.size() < 2) {
61  LOG(WARNING) << "Need at least two features and cameras to triangulate.";
62  return false;
63  }
64 
65  // Construct the A matrix on page 312.
66  MatrixXd A;
67  A.resize(features.size() * 2, 4);
68  for (size_t ii = 0; ii < features.size(); ++ii) {
69  double u = features[ii].u_;
70  double v = features[ii].v_;
71 
72  const Matrix34d P = cameras[ii].P();
73  A.row(2*ii+0) = u * P.row(2) - P.row(0);
74  A.row(2*ii+1) = v * P.row(2) - P.row(1);
75  }
76 
77  // Get svd(A). Save some time and compute a thin U. We still need a full V.
78  Eigen::JacobiSVD<MatrixXd> svd;
79  svd.compute(A, Eigen::ComputeThinU | Eigen::ComputeFullV);
80  if (!svd.computeV()) {
81  VLOG(1) << "Failed to compute a singular value decomposition of A matrix.";
82  return false;
83  }
84 
85  // The 3D point is the eigenvector corresponding to the minimum eigenvalue.
86  point = Point3D(svd.matrixV().block(0, 3, 3, 1) / svd.matrixV()(3,3));
87 
88  // Return false if the point is not visible from all cameras.
89  for (size_t ii = 0; ii < cameras.size(); ++ii) {
90  double u = 0.0, v = 0.0;
91  if (!cameras[ii].WorldToImage(point.X(), point.Y(), point.Z(), &u, &v)) {
92  return false;
93  }
94  }
95 
96  return true;
97 }
::Eigen::Matrix< double, 3, 4 > Matrix34d
Definition: types.h:87
bool bsfm::Triangulate ( const FeatureMatch feature_match,
const Camera camera1,
const Camera camera2,
Point3D point 
)

Definition at line 101 of file triangulation.cpp.

102  {
103  FeatureList features;
104  features.push_back(feature_match.feature1_);
105  features.push_back(feature_match.feature2_);
106 
107  std::vector<Camera> cameras;
108  cameras.push_back(camera1);
109  cameras.push_back(camera2);
110 
111  return Triangulate(features, cameras, point);
112 }
bool Triangulate(const FeatureMatchList &feature_matches, const Camera &camera1, const Camera &camera2, Point3DList &points)
std::vector< Feature > FeatureList
Definition: feature.h:65
bool bsfm::Triangulate ( const FeatureMatchList feature_matches,
const Camera camera1,
const Camera camera2,
Point3DList points 
)

Definition at line 117 of file triangulation.cpp.

118  {
119  // Clear output.
120  points.clear();
121 
122  bool triangulated_all_points = true;
123  for (size_t ii = 0; ii < feature_matches.size(); ++ii) {
124  Point3D point;
125 
126  // Continue on failure, but store (0, 0, 0).
127  if (!Triangulate(feature_matches[ii], camera1, camera2, point)) {
128  triangulated_all_points = false;
129  point = Point3D();
130  }
131  points.push_back(point);
132  }
133 
134  return triangulated_all_points;
135 }
bool Triangulate(const FeatureMatchList &feature_matches, const Camera &camera1, const Camera &camera2, Point3DList &points)
double bsfm::Unroll ( double  angle)

Definition at line 127 of file rotation.cpp.

127  {
128  angle = fmod(angle, 2.0 * M_PI);
129  if (angle < 0)
130  angle += 2.0 * M_PI;
131  return angle;
132 }
double bsfm::Yaw ( const Matrix3d &  R)

Definition at line 119 of file rotation.cpp.

119  {
120  double theta = -std::asin(R(2, 0));
121  if (std::abs(std::cos(theta)) < 1e-8)
122  return 0.0;
123  return std::atan2(R(1, 0) / std::cos(theta), R(0, 0) / std::cos(theta));
124 }

Variable Documentation

constexpr LandmarkIndex bsfm::kInvalidLandmark
static
Initial value:
=
std::numeric_limits<LandmarkIndex>::max()

Definition at line 66 of file types.h.

constexpr ViewIndex bsfm::kInvalidView = std::numeric_limits<ViewIndex>::max()
static

Definition at line 65 of file types.h.