ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
two_view_geometry.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include "base/camera.h"
11 #include "feature/types.h"
12 #include "optim/ransac.h"
13 #include "util/alignment.h"
14 #include "util/logging.h"
15 
16 namespace colmap {
17 
18 // Two-view geometry estimator.
20  // The configuration of the estimated two-view geometry.
22  UNDEFINED = 0,
23  // Degenerate configuration (e.g., no overlap or not enough inliers).
25  // Essential matrix.
27  // Fundamental matrix.
29  // Homography, planar scene with baseline.
30  PLANAR = 4,
31  // Homography, pure rotation without baseline.
32  PANORAMIC = 5,
33  // Homography, planar or panoramic.
35  // Watermark, pure 2D translation in image borders.
36  WATERMARK = 7,
37  // Multi-model configuration, i.e. the inlier matches result from
38  // multiple individual, non-degenerate configurations.
39  MULTIPLE = 8,
40  };
41 
42  // Estimation options.
43  struct Options {
44  // Minimum number of inliers for non-degenerate two-view geometry.
45  size_t min_num_inliers = 15;
46 
47  // In case both cameras are calibrated, the calibration is verified by
48  // estimating an essential and fundamental matrix and comparing their
49  // fractions of number of inliers. If the essential matrix produces
50  // a similar number of inliers (`min_E_F_inlier_ratio * F_num_inliers`),
51  // the calibration is assumed to be correct.
52  double min_E_F_inlier_ratio = 0.95;
53 
54  // In case an epipolar geometry can be verified, it is checked whether
55  // the geometry describes a planar scene or panoramic view (pure
56  // rotation) described by a homography. This is a degenerate case, since
57  // epipolar geometry is only defined for a moving camera. If the inlier
58  // ratio of a homography comes close to the inlier ratio of the epipolar
59  // geometry, a planar or panoramic configuration is assumed.
60  double max_H_inlier_ratio = 0.8;
61 
62  // In case of valid two-view geometry, it is checked whether the
63  // geometry describes a pure translation in the border region of the
64  // image. If more than a certain ratio of inlier points conform with a
65  // pure image translation, a watermark is assumed.
67 
68  // Watermark matches have to be in the border region of the image. The
69  // border region is defined as the area around the image borders and
70  // is defined as a fraction of the image diagonal.
71  double watermark_border_size = 0.1;
72 
73  // Whether to enable watermark detection. A watermark causes a pure
74  // translation in the image space with inliers in the border region.
75  bool detect_watermark = true;
76 
77  // Whether to ignore watermark models in multiple model estimation.
79 
80  // Options used to robustly estimate the geometry.
82 
83  void Check() const {
84  CHECK_GE(min_num_inliers, 0);
85  CHECK_GE(min_E_F_inlier_ratio, 0);
86  CHECK_LE(min_E_F_inlier_ratio, 1);
87  CHECK_GE(max_H_inlier_ratio, 0);
88  CHECK_LE(max_H_inlier_ratio, 1);
89  CHECK_GE(watermark_min_inlier_ratio, 0);
90  CHECK_LE(watermark_min_inlier_ratio, 1);
91  CHECK_GE(watermark_border_size, 0);
92  CHECK_LE(watermark_border_size, 1);
94  }
95  };
96 
99  E(Eigen::Matrix3d::Zero()),
100  F(Eigen::Matrix3d::Zero()),
101  H(Eigen::Matrix3d::Zero()),
102  qvec(Eigen::Vector4d::Zero()),
103  tvec(Eigen::Vector3d::Zero()),
104  tri_angle(0) {}
105 
106  // Invert the two-view geometry in-place.
107  void Invert();
108 
109  // Estimate two-view geometry from calibrated or uncalibrated image pair,
110  // depending on whether a prior focal length is given or not.
111  //
112  // @param camera1 Camera of first image.
113  // @param points1 Feature points in first image.
114  // @param camera2 Camera of second image.
115  // @param points2 Feature points in second image.
116  // @param matches Feature matches between first and second image.
117  // @param options Two-view geometry estimation options.
118  void Estimate(const Camera& camera1,
119  const std::vector<Eigen::Vector2d>& points1,
120  const Camera& camera2,
121  const std::vector<Eigen::Vector2d>& points2,
122  const FeatureMatches& matches,
123  const Options& options);
124 
125  // Recursively estimate multiple configurations by removing the previous set
126  // of inliers from the matches until not enough inliers are found. Inlier
127  // matches are concatenated and the configuration type is `MULTIPLE` if
128  // multiple models could be estimated. This is useful to estimate the
129  // two-view geometry for images with large distortion or multiple rigidly
130  // moving objects in the scene.
131  //
132  // Note that in case the model type is `MULTIPLE`, only the `inlier_matches`
133  // field will be initialized.
134  //
135  // @param camera1 Camera of first image.
136  // @param points1 Feature points in first image.
137  // @param camera2 Camera of second image.
138  // @param points2 Feature points in second image.
139  // @param matches Feature matches between first and second image.
140  // @param options Two-view geometry estimation options.
141  void EstimateMultiple(const Camera& camera1,
142  const std::vector<Eigen::Vector2d>& points1,
143  const Camera& camera2,
144  const std::vector<Eigen::Vector2d>& points2,
145  const FeatureMatches& matches,
146  const Options& options);
147 
148  // Estimate two-view geometry and its relative pose from a calibrated or an
149  // uncalibrated image pair.
150  //
151  // @param camera1 Camera of first image.
152  // @param points1 Feature points in first image.
153  // @param camera2 Camera of second image.
154  // @param points2 Feature points in second image.
155  // @param matches Feature matches between first and second image.
156  // @param options Two-view geometry estimation options.
157  bool EstimateRelativePose(const Camera& camera1,
158  const std::vector<Eigen::Vector2d>& points1,
159  const Camera& camera2,
160  const std::vector<Eigen::Vector2d>& points2);
161 
162  // Estimate two-view geometry from calibrated image pair.
163  //
164  // @param camera1 Camera of first image.
165  // @param points1 Feature points in first image.
166  // @param camera2 Camera of second image.
167  // @param points2 Feature points in second image.
168  // @param matches Feature matches between first and second image.
169  // @param options Two-view geometry estimation options.
170  void EstimateCalibrated(const Camera& camera1,
171  const std::vector<Eigen::Vector2d>& points1,
172  const Camera& camera2,
173  const std::vector<Eigen::Vector2d>& points2,
174  const FeatureMatches& matches,
175  const Options& options);
176 
177  // Estimate two-view geometry from uncalibrated image pair.
178  //
179  // @param camera1 Camera of first image.
180  // @param points1 Feature points in first image.
181  // @param camera2 Camera of second image.
182  // @param points2 Feature points in second image.
183  // @param matches Feature matches between first and second image.
184  // @param options Two-view geometry estimation options.
185  void EstimateUncalibrated(const Camera& camera1,
186  const std::vector<Eigen::Vector2d>& points1,
187  const Camera& camera2,
188  const std::vector<Eigen::Vector2d>& points2,
189  const FeatureMatches& matches,
190  const Options& options);
191 
192  // Detect if inlier matches are caused by a watermark.
193  // A watermark causes a pure translation in the border are of the image.
194  static bool DetectWatermark(const Camera& camera1,
195  const std::vector<Eigen::Vector2d>& points1,
196  const Camera& camera2,
197  const std::vector<Eigen::Vector2d>& points2,
198  const size_t num_inliers,
199  const std::vector<char>& inlier_mask,
200  const Options& options);
201 
202  // One of `ConfigurationType`.
203  int config;
204 
205  // Essential matrix.
206  Eigen::Matrix3d E;
207  // Fundamental matrix.
208  Eigen::Matrix3d F;
209  // Homography matrix.
210  Eigen::Matrix3d H;
211 
212  // Relative pose.
213  Eigen::Vector4d qvec;
214  Eigen::Vector3d tvec;
215 
216  // Inlier matches of the configuration.
218 
219  // Median triangulation angle.
220  double tri_angle;
221 };
222 
223 } // namespace colmap
224 
225 // EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION_CUSTOM(colmap::TwoViewGeometry)
Definition: Eigen.h:103
std::vector< FeatureMatch > FeatureMatches
Definition: types.h:80
void Check() const
Definition: ransac.h:43
void EstimateUncalibrated(const Camera &camera1, const std::vector< Eigen::Vector2d > &points1, const Camera &camera2, const std::vector< Eigen::Vector2d > &points2, const FeatureMatches &matches, const Options &options)
void EstimateCalibrated(const Camera &camera1, const std::vector< Eigen::Vector2d > &points1, const Camera &camera2, const std::vector< Eigen::Vector2d > &points2, const FeatureMatches &matches, const Options &options)
void EstimateMultiple(const Camera &camera1, const std::vector< Eigen::Vector2d > &points1, const Camera &camera2, const std::vector< Eigen::Vector2d > &points2, const FeatureMatches &matches, const Options &options)
static bool DetectWatermark(const Camera &camera1, const std::vector< Eigen::Vector2d > &points1, const Camera &camera2, const std::vector< Eigen::Vector2d > &points2, const size_t num_inliers, const std::vector< char > &inlier_mask, const Options &options)
void Estimate(const Camera &camera1, const std::vector< Eigen::Vector2d > &points1, const Camera &camera2, const std::vector< Eigen::Vector2d > &points2, const FeatureMatches &matches, const Options &options)
bool EstimateRelativePose(const Camera &camera1, const std::vector< Eigen::Vector2d > &points1, const Camera &camera2, const std::vector< Eigen::Vector2d > &points2)