ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
image.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 // clang-format off
11 #include "util/alignment.h"
12 // clang-format on
13 
14 #include <string>
15 #include <vector>
16 
17 #include "base/camera.h"
18 #include "base/point2d.h"
20 #include "util/logging.h"
21 #include "util/math.h"
22 #include "util/types.h"
23 
24 namespace colmap {
25 
26 // Class that holds information about an image. An image is the product of one
27 // camera shot at a certain location (parameterized as the pose). An image may
28 // share a camera with multiple other images, if its intrinsics are the same.
29 class Image {
30 public:
31  Image();
32 
33  // Setup / tear down the image and necessary internal data structures before
34  // and after being used in reconstruction.
35  void SetUp(const Camera& camera);
36  void TearDown();
37 
38  // Access the unique identifier of the image.
39  inline image_t ImageId() const;
40  inline void SetImageId(const image_t image_id);
41 
42  // Access the name of the image.
43  inline const std::string& Name() const;
44  inline std::string& Name();
45  inline void SetName(const std::string& name);
46 
47  // Access the unique identifier of the camera. Note that multiple images
48  // might share the same camera.
49  inline camera_t CameraId() const;
50  inline void SetCameraId(const camera_t camera_id);
51  // Check whether identifier of camera has been set.
52  inline bool HasCamera() const;
53 
54  // Check if image is registered.
55  inline bool IsRegistered() const;
56  inline void SetRegistered(const bool registered);
57 
58  // Get the number of image points.
59  inline point2D_t NumPoints2D() const;
60 
61  // Get the number of triangulations, i.e. the number of points that
62  // are part of a 3D point track.
63  inline point2D_t NumPoints3D() const;
64 
65  // Get the number of observations, i.e. the number of image points that
66  // have at least one correspondence to another image.
67  inline point2D_t NumObservations() const;
68  inline void SetNumObservations(const point2D_t num_observations);
69 
70  // Get the number of correspondences for all image points.
71  inline point2D_t NumCorrespondences() const;
72  inline void SetNumCorrespondences(const point2D_t num_observations);
73 
74  // Get the number of observations that see a triangulated point, i.e. the
75  // number of image points that have at least one correspondence to a
76  // triangulated point in another image.
77  inline point2D_t NumVisiblePoints3D() const;
78 
79  // Get the score of triangulated observations. In contrast to
80  // `NumVisiblePoints3D`, this score also captures the distribution
81  // of triangulated observations in the image. This is useful to select
82  // the next best image in incremental reconstruction, because a more
83  // uniform distribution of observations results in more robust registration.
84  inline size_t Point3DVisibilityScore() const;
85 
86  // Access the number of correspondences that have a 3D point per image
87  // point.
88  inline const std::vector<point2D_t>& NumCorrespondencesHavePoint3D() const;
89  inline std::vector<point2D_t>& NumCorrespondencesHavePoint3D();
90 
91  // Access the visibility pyramid for triangulated correspondences.
92  inline const VisibilityPyramid& Point3DVisibilityPyramid() const;
94 
95  // Access quaternion vector as (qw, qx, qy, qz) specifying the rotation of
96  // the pose which is defined as the transformation from world to image
97  // space.
98  inline const Eigen::Vector4d& Qvec() const;
99  inline Eigen::Vector4d& Qvec();
100  inline double Qvec(const size_t idx) const;
101  inline double& Qvec(const size_t idx);
102  inline void SetQvec(const Eigen::Vector4d& qvec);
103 
104  // Quaternion prior, e.g. given by EXIF gyroscope tag.
105  inline const Eigen::Vector4d& QvecPrior() const;
106  inline Eigen::Vector4d& QvecPrior();
107  inline double QvecPrior(const size_t idx) const;
108  inline double& QvecPrior(const size_t idx);
109  inline bool HasQvecPrior() const;
110  inline void SetQvecPrior(const Eigen::Vector4d& qvec);
111 
112  // Access translation vector as (tx, ty, tz) specifying the translation of
113  // the pose which is defined as the transformation from world to image
114  // space.
115  inline const Eigen::Vector3d& Tvec() const;
116  inline Eigen::Vector3d& Tvec();
117  inline double Tvec(const size_t idx) const;
118  inline double& Tvec(const size_t idx);
119  inline void SetTvec(const Eigen::Vector3d& tvec);
120 
121  // Translation prior, e.g. given by EXIF GPS tag.
122  inline const Eigen::Vector3d& TvecPrior() const;
123  inline Eigen::Vector3d& TvecPrior();
124  inline double TvecPrior(const size_t idx) const;
125  inline double& TvecPrior(const size_t idx);
126  inline bool HasTvecPrior() const;
127  inline void SetTvecPrior(const Eigen::Vector3d& tvec);
128 
129  // Access the coordinates of image points.
130  inline const class Point2D& Point2D(const point2D_t point2D_idx) const;
131  inline class Point2D& Point2D(const point2D_t point2D_idx);
132  inline const std::vector<class Point2D>& Points2D() const;
133  void SetPoints2D(const std::vector<Eigen::Vector2d>& points);
134  void SetPoints2D(const std::vector<class Point2D>& points);
135 
136  // Set the point as triangulated, i.e. it is part of a 3D point track.
137  void SetPoint3DForPoint2D(const point2D_t point2D_idx,
138  const point3D_t point3D_id);
139 
140  // Set the point as not triangulated, i.e. it is not part of a 3D point
141  // track.
142  void ResetPoint3DForPoint2D(const point2D_t point2D_idx);
143 
144  // Check whether an image point has a correspondence to an image point in
145  // another image that has a 3D point.
146  inline bool IsPoint3DVisible(const point2D_t point2D_idx) const;
147 
148  // Check whether one of the image points is part of the 3D point track.
149  bool HasPoint3D(const point3D_t point3D_id) const;
150 
151  // Indicate that another image has a point that is triangulated and has
152  // a correspondence to this image point. Note that this must only be called
153  // after calling `SetUp`.
154  void IncrementCorrespondenceHasPoint3D(const point2D_t point2D_idx);
155 
156  // Indicate that another image has a point that is not triangulated any more
157  // and has a correspondence to this image point. This assumes that
158  // `IncrementCorrespondenceHasPoint3D` was called for the same image point
159  // and correspondence before. Note that this must only be called
160  // after calling `SetUp`.
161  void DecrementCorrespondenceHasPoint3D(const point2D_t point2D_idx);
162 
163  // Normalize the quaternion vector.
164  void NormalizeQvec();
165 
166  // Compose the projection matrix from world to image space.
168 
169  // Compose the inverse projection matrix from image to world space
171 
172  // Compose rotation matrix from quaternion vector.
173  Eigen::Matrix3d RotationMatrix() const;
174 
175  // Extract the projection center in world space.
176  Eigen::Vector3d ProjectionCenter() const;
177 
178  // Extract the viewing direction of the image.
179  Eigen::Vector3d ViewingDirection() const;
180 
181  // The number of levels in the 3D point multi-resolution visibility pyramid.
183 
184 private:
185  // Identifier of the image, if not specified `kInvalidImageId`.
186  image_t image_id_;
187 
188  // The name of the image, i.e. the relative path.
189  std::string name_;
190 
191  // The identifier of the associated camera. Note that multiple images might
192  // share the same camera. If not specified `kInvalidCameraId`.
193  camera_t camera_id_;
194 
195  // Whether the image is successfully registered in the reconstruction.
196  bool registered_;
197 
198  // The number of 3D points the image observes, i.e. the sum of its
199  // `points2D` where `point3D_id != kInvalidPoint3DId`.
200  point2D_t num_points3D_;
201 
202  // The number of image points that have at least one correspondence to
203  // another image.
204  point2D_t num_observations_;
205 
206  // The sum of correspondences per image point.
207  point2D_t num_correspondences_;
208 
209  // The number of 2D points, which have at least one corresponding 2D point
210  // in another image that is part of a 3D point track, i.e. the sum of
211  // `points2D` where `num_tris > 0`.
212  point2D_t num_visible_points3D_;
213 
214  // The pose of the image, defined as the transformation from world to image.
215  Eigen::Vector4d qvec_;
216  Eigen::Vector3d tvec_;
217 
218  // The pose prior of the image, e.g. extracted from EXIF tags.
219  Eigen::Vector4d qvec_prior_;
220  Eigen::Vector3d tvec_prior_;
221 
222  // All image points, including points that are not part of a 3D point track.
223  std::vector<class Point2D> points2D_;
224 
225  // Per image point, the number of correspondences that have a 3D point.
226  std::vector<point2D_t> num_correspondences_have_point3D_;
227 
228  // Data structure to compute the distribution of triangulated
229  // correspondences in the image. Note that this structure is only usable
230  // after `SetUp`.
231  VisibilityPyramid point3D_visibility_pyramid_;
232 };
233 
235 // Implementation
237 
238 image_t Image::ImageId() const { return image_id_; }
239 
240 void Image::SetImageId(const image_t image_id) { image_id_ = image_id; }
241 
242 const std::string& Image::Name() const { return name_; }
243 
244 std::string& Image::Name() { return name_; }
245 
246 void Image::SetName(const std::string& name) { name_ = name; }
247 
248 inline camera_t Image::CameraId() const { return camera_id_; }
249 
250 inline void Image::SetCameraId(const camera_t camera_id) {
251  CHECK_NE(camera_id, kInvalidCameraId);
252  camera_id_ = camera_id;
253 }
254 
255 inline bool Image::HasCamera() const { return camera_id_ != kInvalidCameraId; }
256 
257 bool Image::IsRegistered() const { return registered_; }
258 
259 void Image::SetRegistered(const bool registered) { registered_ = registered; }
260 
262  return static_cast<point2D_t>(points2D_.size());
263 }
264 
265 point2D_t Image::NumPoints3D() const { return num_points3D_; }
266 
267 point2D_t Image::NumObservations() const { return num_observations_; }
268 
269 void Image::SetNumObservations(const point2D_t num_observations) {
270  num_observations_ = num_observations;
271 }
272 
273 point2D_t Image::NumCorrespondences() const { return num_correspondences_; }
274 
275 void Image::SetNumCorrespondences(const point2D_t num_correspondences) {
276  num_correspondences_ = num_correspondences;
277 }
278 
279 point2D_t Image::NumVisiblePoints3D() const { return num_visible_points3D_; }
280 
282  return point3D_visibility_pyramid_.Score();
283 }
284 
285 const std::vector<point2D_t>& Image::NumCorrespondencesHavePoint3D() const {
286  return num_correspondences_have_point3D_;
287 }
288 
289 std::vector<point2D_t>& Image::NumCorrespondencesHavePoint3D() {
290  return num_correspondences_have_point3D_;
291 }
292 
294  return point3D_visibility_pyramid_;
295 }
296 
298  return point3D_visibility_pyramid_;
299 }
300 
301 const Eigen::Vector4d& Image::Qvec() const { return qvec_; }
302 
303 Eigen::Vector4d& Image::Qvec() { return qvec_; }
304 
305 inline double Image::Qvec(const size_t idx) const { return qvec_(idx); }
306 
307 inline double& Image::Qvec(const size_t idx) { return qvec_(idx); }
308 
309 void Image::SetQvec(const Eigen::Vector4d& qvec) { qvec_ = qvec; }
310 
311 const Eigen::Vector4d& Image::QvecPrior() const { return qvec_prior_; }
312 
313 Eigen::Vector4d& Image::QvecPrior() { return qvec_prior_; }
314 
315 inline double Image::QvecPrior(const size_t idx) const {
316  return qvec_prior_(idx);
317 }
318 
319 inline double& Image::QvecPrior(const size_t idx) { return qvec_prior_(idx); }
320 
321 inline bool Image::HasQvecPrior() const { return !IsNaN(qvec_prior_.sum()); }
322 
323 void Image::SetQvecPrior(const Eigen::Vector4d& qvec) { qvec_prior_ = qvec; }
324 
325 const Eigen::Vector3d& Image::Tvec() const { return tvec_; }
326 
327 Eigen::Vector3d& Image::Tvec() { return tvec_; }
328 
329 inline double Image::Tvec(const size_t idx) const { return tvec_(idx); }
330 
331 inline double& Image::Tvec(const size_t idx) { return tvec_(idx); }
332 
333 void Image::SetTvec(const Eigen::Vector3d& tvec) { tvec_ = tvec; }
334 
335 const Eigen::Vector3d& Image::TvecPrior() const { return tvec_prior_; }
336 
337 Eigen::Vector3d& Image::TvecPrior() { return tvec_prior_; }
338 
339 inline double Image::TvecPrior(const size_t idx) const {
340  return tvec_prior_(idx);
341 }
342 
343 inline double& Image::TvecPrior(const size_t idx) { return tvec_prior_(idx); }
344 
345 inline bool Image::HasTvecPrior() const { return !IsNaN(tvec_prior_.sum()); }
346 
347 void Image::SetTvecPrior(const Eigen::Vector3d& tvec) { tvec_prior_ = tvec; }
348 
349 const class Point2D& Image::Point2D(const point2D_t point2D_idx) const {
350  return points2D_.at(point2D_idx);
351 }
352 
353 class Point2D& Image::Point2D(const point2D_t point2D_idx) {
354  return points2D_.at(point2D_idx);
355 }
356 
357 const std::vector<class Point2D>& Image::Points2D() const { return points2D_; }
358 
359 bool Image::IsPoint3DVisible(const point2D_t point2D_idx) const {
360  return num_correspondences_have_point3D_.at(point2D_idx) > 0;
361 }
362 
363 } // namespace colmap
std::string name
int points
std::string name_
Definition: FilePLY.cpp:33
point2D_t NumPoints3D() const
Definition: image.h:265
void TearDown()
Definition: image.cc:67
static const int kNumPoint3DVisibilityPyramidLevels
Definition: image.h:182
image_t ImageId() const
Definition: image.h:238
void SetName(const std::string &name)
Definition: image.h:246
Eigen::Matrix3x4d ProjectionMatrix() const
Definition: image.cc:140
point2D_t NumCorrespondences() const
Definition: image.h:273
void NormalizeQvec()
Definition: image.cc:138
void SetPoints2D(const std::vector< Eigen::Vector2d > &points)
Definition: image.cc:71
const Eigen::Vector3d & TvecPrior() const
Definition: image.h:335
void SetRegistered(const bool registered)
Definition: image.h:259
void ResetPoint3DForPoint2D(const point2D_t point2D_idx)
Definition: image.cc:97
const Eigen::Vector3d & Tvec() const
Definition: image.h:325
bool IsPoint3DVisible(const point2D_t point2D_idx) const
Definition: image.h:359
point2D_t NumObservations() const
Definition: image.h:267
const std::vector< point2D_t > & NumCorrespondencesHavePoint3D() const
Definition: image.h:285
void SetTvecPrior(const Eigen::Vector3d &tvec)
Definition: image.h:347
void DecrementCorrespondenceHasPoint3D(const point2D_t point2D_idx)
Definition: image.cc:125
size_t Point3DVisibilityScore() const
Definition: image.h:281
Eigen::Matrix3x4d InverseProjectionMatrix() const
Definition: image.cc:144
Eigen::Vector3d ViewingDirection() const
Definition: image.cc:156
bool HasPoint3D(const point3D_t point3D_id) const
Definition: image.cc:105
const std::vector< class Point2D > & Points2D() const
Definition: image.h:357
bool HasCamera() const
Definition: image.h:255
const Eigen::Vector4d & QvecPrior() const
Definition: image.h:311
void SetImageId(const image_t image_id)
Definition: image.h:240
void SetCameraId(const camera_t camera_id)
Definition: image.h:250
const class Point2D & Point2D(const point2D_t point2D_idx) const
Definition: image.h:349
void SetQvec(const Eigen::Vector4d &qvec)
Definition: image.h:309
const std::string & Name() const
Definition: image.h:242
void SetUp(const Camera &camera)
Definition: image.cc:60
void IncrementCorrespondenceHasPoint3D(const point2D_t point2D_idx)
Definition: image.cc:112
void SetNumObservations(const point2D_t num_observations)
Definition: image.h:269
Eigen::Matrix3d RotationMatrix() const
Definition: image.cc:148
bool HasQvecPrior() const
Definition: image.h:321
const Eigen::Vector4d & Qvec() const
Definition: image.h:301
bool IsRegistered() const
Definition: image.h:257
void SetQvecPrior(const Eigen::Vector4d &qvec)
Definition: image.h:323
Eigen::Vector3d ProjectionCenter() const
Definition: image.cc:152
point2D_t NumPoints2D() const
Definition: image.h:261
camera_t CameraId() const
Definition: image.h:248
point2D_t NumVisiblePoints3D() const
Definition: image.h:279
void SetPoint3DForPoint2D(const point2D_t point2D_idx, const point3D_t point3D_id)
Definition: image.cc:87
bool HasTvecPrior() const
Definition: image.h:345
void SetTvec(const Eigen::Vector3d &tvec)
Definition: image.h:333
void SetNumCorrespondences(const point2D_t num_observations)
Definition: image.h:275
const VisibilityPyramid & Point3DVisibilityPyramid() const
Definition: image.h:293
Matrix< double, 3, 4 > Matrix3x4d
Definition: types.h:39
uint64_t point3D_t
Definition: types.h:72
const camera_t kInvalidCameraId
Definition: types.h:75
uint32_t point2D_t
Definition: types.h:67
uint32_t image_t
Definition: types.h:61
bool IsNaN(const float x)
Definition: math.h:160
uint32_t camera_t
Definition: types.h:58