ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
reconstruction.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 <tuple>
15 #include <unordered_map>
16 #include <unordered_set>
17 #include <vector>
18 
19 #include "base/camera.h"
20 #include "base/database.h"
21 #include "base/image.h"
22 #include "base/point2d.h"
23 #include "base/point3d.h"
25 #include "base/track.h"
27 #include "optim/loransac.h"
28 #include "util/types.h"
29 
30 namespace colmap {
31 
32 struct PlyPoint;
33 struct RANSACOptions;
34 class DatabaseCache;
35 class CorrespondenceGraph;
36 
37 // Reconstruction class holds all information about a single reconstructed
38 // model. It is used by the mapping and bundle adjustment classes and can be
39 // written to and read from disk.
41 public:
42  struct ImagePairStat {
43  // The number of triangulated correspondences between two images.
44  size_t num_tri_corrs = 0;
45  // The number of total correspondences/matches between two images.
46  size_t num_total_corrs = 0;
47  };
48 
50 
51  // Copy construct/assign. Updates camera pointers.
52  Reconstruction(const Reconstruction& other);
54 
55  // Get number of objects.
56  inline size_t NumCameras() const;
57  inline size_t NumImages() const;
58  inline size_t NumRegImages() const;
59  inline size_t NumPoints3D() const;
60  inline size_t NumImagePairs() const;
61  inline size_t NumAddedPoints3D() const;
62 
63  // Get const objects.
64  inline const class Camera& Camera(const camera_t camera_id) const;
65  inline const class Image& Image(const image_t image_id) const;
66  inline const class Point3D& Point3D(const point3D_t point3D_id) const;
67  inline const ImagePairStat& ImagePair(const image_pair_t pair_id) const;
68  inline ImagePairStat& ImagePair(const image_t image_id1,
69  const image_t image_id2);
70 
71  // Get mutable objects.
72  inline class Camera& Camera(const camera_t camera_id);
73  inline class Image& Image(const image_t image_id);
74  inline class Point3D& Point3D(const point3D_t point3D_id);
75  inline ImagePairStat& ImagePair(const image_pair_t pair_id);
76  inline const ImagePairStat& ImagePair(const image_t image_id1,
77  const image_t image_id2) const;
78 
79  // Get reference to all objects.
80  inline const std::unordered_map<camera_t, class Camera>& Cameras() const;
81  inline const std::unordered_map<image_t, class Image>& Images() const;
82  inline const std::vector<image_t>& RegImageIds() const;
83  inline const std::unordered_map<point3D_t, class Point3D>& Points3D() const;
84  inline const std::unordered_map<image_pair_t, ImagePairStat>& ImagePairs()
85  const;
86 
87  // Identifiers of all 3D points.
88  std::unordered_set<point3D_t> Point3DIds() const;
89 
90  // Check whether specific object exists.
91  inline bool ExistsCamera(const camera_t camera_id) const;
92  inline bool ExistsImage(const image_t image_id) const;
93  inline bool ExistsPoint3D(const point3D_t point3D_id) const;
94  inline bool ExistsImagePair(const image_pair_t pair_id) const;
95 
96  // Load data from given `DatabaseCache`.
97  void Load(const DatabaseCache& database_cache);
98 
99  // Setup all relevant data structures before reconstruction. Note the
100  // correspondence graph object must live until `TearDown` is called.
101  void SetUp(const CorrespondenceGraph* correspondence_graph);
102 
103  // Finalize the Reconstruction after the reconstruction has finished.
104  //
105  // Once a scene has been finalized, it cannot be used for reconstruction.
106  //
107  // This removes all not yet registered images and unused cameras, in order
108  // to save memory.
109  void TearDown();
110 
111  // Add new camera. There is only one camera per image, while multiple images
112  // might be taken by the same camera.
113  void AddCamera(const class Camera& camera);
114 
115  // Add new image.
116  void AddImage(const class Image& image);
117 
118  // Add new 3D object, and return its unique ID.
120  const Eigen::Vector3d& xyz,
121  const Track& track,
122  const Eigen::Vector3ub& color = Eigen::Vector3ub::Zero());
123 
124  // Add observation to existing 3D point.
125  void AddObservation(const point3D_t point3D_id,
126  const TrackElement& track_el);
127 
128  // Merge two 3D points and return new identifier of new 3D point.
129  // The location of the merged 3D point is a weighted average of the two
130  // original 3D point's locations according to their track lengths.
131  point3D_t MergePoints3D(const point3D_t point3D_id1,
132  const point3D_t point3D_id2);
133 
134  // Delete a 3D point, and all its references in the observed images.
135  void DeletePoint3D(const point3D_t point3D_id);
136 
137  // Delete one observation from an image and the corresponding 3D point.
138  // Note that this deletes the entire 3D point, if the track has two elements
139  // prior to calling this method.
140  void DeleteObservation(const image_t image_id, const point2D_t point2D_idx);
141 
142  // Delete all 2D points of all images and all 3D points.
144 
145  // Register an existing image.
146  void RegisterImage(const image_t image_id);
147 
148  // De-register an existing image, and all its references.
149  void DeRegisterImage(const image_t image_id);
150 
151  // Check if image is registered.
152  inline bool IsImageRegistered(const image_t image_id) const;
153 
154  // Normalize scene by scaling and translation to avoid degenerate
155  // visualization after bundle adjustment and to improve numerical
156  // stability of algorithms.
157  //
158  // Translates scene such that the mean of the camera centers or point
159  // locations are at the origin of the coordinate system.
160  //
161  // Scales scene such that the minimum and maximum camera centers are at the
162  // given `extent`, whereas `p0` and `p1` determine the minimum and
163  // maximum percentiles of the camera centers considered.
164  void Normalize(const double extent = 10.0,
165  const double p0 = 0.1,
166  const double p1 = 0.9,
167  const bool use_images = true);
168 
169  // Compute the centroid of the 3D points
170  Eigen::Vector3d ComputeCentroid(const double p0 = 0.1,
171  const double p1 = 0.9) const;
172 
173  // Compute the bounding box corners of the 3D points
174  std::pair<Eigen::Vector3d, Eigen::Vector3d> ComputeBoundingBox(
175  const double p0 = 0.0, const double p1 = 1.0) const;
176 
177  // Apply the 3D similarity transformation to all images and points.
178  void Transform(const SimilarityTransform3& tform);
179 
180  // Creates a cropped reconstruction using the input bounds as corner points
181  // of the bounding box containing the included 3D points of the new
182  // reconstruction. Only the cameras and images of the included points are
183  // registered.
185  const std::pair<Eigen::Vector3d, Eigen::Vector3d>& bbox) const;
186 
187  // Merge the given reconstruction into this reconstruction by registering
188  // the images registered in the given but not in this reconstruction and by
189  // merging the two clouds and their tracks. The coordinate frames of the two
190  // reconstructions are aligned using the projection centers of common
191  // registered images. Return true if the two reconstructions could be
192  // merged.
193  bool Merge(const Reconstruction& reconstruction,
194  const double max_reproj_error);
195 
196  // Align the given reconstruction with a set of pre-defined camera
197  // positions. Assuming that locations[i] gives the 3D coordinates of the
198  // center of projection of the image with name image_names[i].
199  template <bool kEstimateScale = true>
200  bool Align(const std::vector<std::string>& image_names,
201  const std::vector<Eigen::Vector3d>& locations,
202  const int min_common_images,
203  SimilarityTransform3* tform = nullptr);
204 
205  // Robust alignment using RANSAC.
206  template <bool kEstimateScale = true>
207  bool AlignRobust(const std::vector<std::string>& image_names,
208  const std::vector<Eigen::Vector3d>& locations,
209  const int min_common_images,
210  const RANSACOptions& ransac_options,
211  SimilarityTransform3* tform = nullptr);
212 
213  // Find specific image by name. Note that this uses linear search.
214  const class Image* FindImageWithName(const std::string& name) const;
215 
216  // Find images that are both present in this and the given reconstruction.
217  std::vector<image_t> FindCommonRegImageIds(
218  const Reconstruction& reconstruction) const;
219 
220  // Update the image identifiers to match the ones in the database by
221  // matching the names of the images.
222  void TranscribeImageIdsToDatabase(const Database& database);
223 
224  // Filter 3D points with large reprojection error, negative depth, or
225  // insufficient triangulation angle.
226  //
227  // @param max_reproj_error The maximum reprojection error.
228  // @param min_tri_angle The minimum triangulation angle.
229  // @param point3D_ids The points to be filtered.
230  //
231  // @return The number of filtered observations.
232  size_t FilterPoints3D(const double max_reproj_error,
233  const double min_tri_angle,
234  const std::unordered_set<point3D_t>& point3D_ids);
235  size_t FilterPoints3DInImages(const double max_reproj_error,
236  const double min_tri_angle,
237  const std::unordered_set<image_t>& image_ids);
238  size_t FilterAllPoints3D(const double max_reproj_error,
239  const double min_tri_angle);
240 
241  // Filter observations that have negative depth.
242  //
243  // @return The number of filtered observations.
245 
246  // Filter images without observations or bogus camera parameters.
247  //
248  // @return The identifiers of the filtered images.
249  std::vector<image_t> FilterImages(const double min_focal_length_ratio,
250  const double max_focal_length_ratio,
251  const double max_extra_param);
252 
253  // Compute statistics for scene.
254  size_t ComputeNumObservations() const;
255  double ComputeMeanTrackLength() const;
256  double ComputeMeanObservationsPerRegImage() const;
257  double ComputeMeanReprojectionError() const;
258 
259  // Read data from text or binary file. Prefer binary data if it exists.
260  void Read(const std::string& path);
261  void Write(const std::string& path) const;
262 
263  // Read data from binary/text file.
264  void ReadText(const std::string& path);
265  void ReadBinary(const std::string& path);
266 
267  // Write data from binary/text file.
268  void WriteText(const std::string& path) const;
269  void WriteBinary(const std::string& path) const;
270 
271  // Convert 3D points in reconstruction to PLY point cloud.
272  std::vector<PlyPoint> ConvertToPLY() const;
273 
274  // Import from other data formats. Note that these import functions are
275  // only intended for visualization of data and usable for reconstruction.
276  void ImportPLY(const std::string& path);
277  void ImportPLY(const std::vector<PlyPoint>& ply_points);
278 
279  // Export to other data formats.
280 
281  // Exports in NVM format http://ccwu.me/vsfm/doc.html#nvm. Only supports
282  // SIMPLE_RADIAL camera model when exporting distortion parameters. When
283  // skip_distortion == true it supports all camera models with the caveat
284  // that it's using the mean focal length which will be inaccurate for camera
285  // models with two focal lengths and distortion.
286  bool ExportNVM(const std::string& path, bool skip_distortion = false) const;
287 
288  // Exports in CAM format which is a simple text file that contains pose
289  // information and camera intrinsics for each image and exports one file per
290  // image; it does not include information on the 3D points. The format is as
291  // follows (2 lines of text with space separated numbers):
292  // <Tvec; 3 values> <Rotation matrix in row-major format; 9 values>
293  // <focal_length> <k1> <k2> 1.0 <principal point X> <principal point Y>
294  // Note that focal length is relative to the image max(width, height),
295  // and principal points x and y are relative to width and height
296  // respectively.
297  //
298  // Only supports SIMPLE_RADIAL and RADIAL camera models when exporting
299  // distortion parameters. When skip_distortion == true it supports all
300  // camera models with the caveat that it's using the mean focal length which
301  // will be inaccurate for camera models with two focal lengths and
302  // distortion.
303  bool ExportCam(const std::string& path, bool skip_distortion = false) const;
304 
305  // Exports in Recon3D format which consists of three text files with the
306  // following format and content:
307  // 1) imagemap_0.txt: a list of image numeric IDs with one entry per line.
308  // 2) urd-images.txt: A list of images with one entry per line as:
309  // <image file name> <width> <height>
310  // 3) synth_0.out: Contains information for image poses, camera intrinsics,
311  // and 3D points as:
312  // <N; num images> <M; num points>
313  // <N lines of image entries>
314  // <M lines of point entries>
315  //
316  // Each image entry consists of 5 lines as:
317  // <focal length> <k1> <k2>
318  // <Rotation matrix; 3x3 array>
319  // <Tvec; 3 values>
320  // Note that the focal length is scaled by 1 / max(width, height)
321  //
322  // Each point entry consists of 3 lines as:
323  // <point x, y, z coordinates>
324  // <point RGB color>
325  // <K; num track elements> <Track Element 1> ... <Track Element K>
326  //
327  // Each track elemenet is a sequence of 5 values as:
328  // <image ID> <2D point ID> -1.0 <X> <Y>
329  // Note that the 2D point coordinates are centered around the principal
330  // point and scaled by 1 / max(width, height).
331  //
332  // When skip_distortion == true it supports all camera models with the
333  // caveat that it's using the mean focal length which will be inaccurate
334  // for camera models with two focal lengths and distortion.
335  bool ExportRecon3D(const std::string& path,
336  bool skip_distortion = false) const;
337 
338  // Exports in Bundler format https://www.cs.cornell.edu/~snavely/bundler/.
339  // Supports SIMPLE_PINHOLE, PINHOLE, SIMPLE_RADIAL and RADIAL camera models
340  // when exporting distortion parameters. When skip_distortion == true it
341  // supports all camera models with the caveat that it's using the mean focal
342  // length which will be inaccurate for camera models with two focal lengths
343  // and distortion.
344  bool ExportBundler(const std::string& path,
345  const std::string& list_path,
346  bool skip_distortion = false) const;
347 
348  // Exports 3D points only in PLY format.
349  void ExportPLY(const std::string& path) const;
350 
351  // Exports in VRML format https://en.wikipedia.org/wiki/VRML.
352  void ExportVRML(const std::string& images_path,
353  const std::string& points3D_path,
354  const double image_scale,
355  const Eigen::Vector3d& image_rgb) const;
356 
357  // Extract colors for 3D points of given image. Colors will be extracted
358  // only for 3D points which are completely black.
359  //
360  // @param image_id Identifier of the image for which to extract colors.
361  // @param path Absolute or relative path to root folder of image.
362  // The image path is determined by concatenating the
363  // root path and the name of the image.
364  //
365  // @return True if image could be read at given path.
366  bool ExtractColorsForImage(const image_t image_id, const std::string& path);
367 
368  // Extract colors for all 3D points by computing the mean color of all
369  // images.
370  //
371  // @param path Absolute or relative path to root folder of image.
372  // The image path is determined by concatenating the
373  // root path and the name of the image.
374  void ExtractColorsForAllImages(const std::string& path);
375 
376  // Create all image sub-directories in the given path.
377  void CreateImageDirs(const std::string& path) const;
378 
379  // Access the correspondence graph.
380  inline const CorrespondenceGraph* GetCorrespondenceGraph() const;
381  inline bool HasCorrespondenceGraph() const;
382 
383 private:
384  size_t FilterPoints3DWithSmallTriangulationAngle(
385  const double min_tri_angle,
386  const std::unordered_set<point3D_t>& point3D_ids);
387  size_t FilterPoints3DWithLargeReprojectionError(
388  const double max_reproj_error,
389  const std::unordered_set<point3D_t>& point3D_ids);
390 
391  std::tuple<Eigen::Vector3d, Eigen::Vector3d, Eigen::Vector3d>
392  ComputeBoundsAndCentroid(const double p0,
393  const double p1,
394  const bool use_images) const;
395 
396  void ReadCamerasText(const std::string& path);
397  void ReadImagesText(const std::string& path);
398  void ReadPoints3DText(const std::string& path);
399  void ReadCamerasBinary(const std::string& path);
400  void ReadImagesBinary(const std::string& path);
401  void ReadPoints3DBinary(const std::string& path);
402 
403  void WriteCamerasText(const std::string& path) const;
404  void WriteImagesText(const std::string& path) const;
405  void WritePoints3DText(const std::string& path) const;
406  void WriteCamerasBinary(const std::string& path) const;
407  void WriteImagesBinary(const std::string& path) const;
408  void WritePoints3DBinary(const std::string& path) const;
409 
410  void SetObservationAsTriangulated(const image_t image_id,
411  const point2D_t point2D_idx,
412  const bool is_continued_point3D);
413  void ResetTriObservations(const image_t image_id,
414  const point2D_t point2D_idx,
415  const bool is_deleted_point3D);
416 
417  const CorrespondenceGraph* correspondence_graph_;
418 
419  std::unordered_map<camera_t, class Camera> cameras_;
420  std::unordered_map<image_t, class Image> images_;
421  std::unordered_map<point3D_t, class Point3D> points3D_;
422 
423  std::unordered_map<image_pair_t, ImagePairStat> image_pair_stats_;
424 
425  // { image_id, ... } where `images_.at(image_id).registered == true`.
426  std::vector<image_t> reg_image_ids_;
427 
428  // Total number of added 3D points, used to generate unique identifiers.
429  point3D_t num_added_points3D_;
430 };
431 
433 // Implementation
435 
436 size_t Reconstruction::NumCameras() const { return cameras_.size(); }
437 
438 size_t Reconstruction::NumImages() const { return images_.size(); }
439 
440 size_t Reconstruction::NumRegImages() const { return reg_image_ids_.size(); }
441 
442 size_t Reconstruction::NumPoints3D() const { return points3D_.size(); }
443 
445  return image_pair_stats_.size();
446 }
447 
448 size_t Reconstruction::NumAddedPoints3D() const { return num_added_points3D_; }
449 
450 const class Camera& Reconstruction::Camera(const camera_t camera_id) const {
451  return cameras_.at(camera_id);
452 }
453 
454 const class Image& Reconstruction::Image(const image_t image_id) const {
455  return images_.at(image_id);
456 }
457 
458 const class Point3D& Reconstruction::Point3D(const point3D_t point3D_id) const {
459  return points3D_.at(point3D_id);
460 }
461 
463  const image_pair_t pair_id) const {
464  return image_pair_stats_.at(pair_id);
465 }
466 
468  const image_t image_id1, const image_t image_id2) const {
469  const auto pair_id = Database::ImagePairToPairId(image_id1, image_id2);
470  return image_pair_stats_.at(pair_id);
471 }
472 
473 class Camera& Reconstruction::Camera(const camera_t camera_id) {
474  return cameras_.at(camera_id);
475 }
476 
477 class Image& Reconstruction::Image(const image_t image_id) {
478  return images_.at(image_id);
479 }
480 
481 class Point3D& Reconstruction::Point3D(const point3D_t point3D_id) {
482  return points3D_.at(point3D_id);
483 }
484 
486  const image_pair_t pair_id) {
487  return image_pair_stats_.at(pair_id);
488 }
489 
491  const image_t image_id1, const image_t image_id2) {
492  const auto pair_id = Database::ImagePairToPairId(image_id1, image_id2);
493  return image_pair_stats_.at(pair_id);
494 }
495 
496 const std::unordered_map<camera_t, Camera>& Reconstruction::Cameras() const {
497  return cameras_;
498 }
499 
500 const std::unordered_map<image_t, class Image>& Reconstruction::Images() const {
501  return images_;
502 }
503 
504 const std::vector<image_t>& Reconstruction::RegImageIds() const {
505  return reg_image_ids_;
506 }
507 
508 const std::unordered_map<point3D_t, Point3D>& Reconstruction::Points3D() const {
509  return points3D_;
510 }
511 
512 const std::unordered_map<image_pair_t, Reconstruction::ImagePairStat>&
514  return image_pair_stats_;
515 }
516 
517 bool Reconstruction::ExistsCamera(const camera_t camera_id) const {
518  return cameras_.find(camera_id) != cameras_.end();
519 }
520 
521 bool Reconstruction::ExistsImage(const image_t image_id) const {
522  return images_.find(image_id) != images_.end();
523 }
524 
525 bool Reconstruction::ExistsPoint3D(const point3D_t point3D_id) const {
526  return points3D_.find(point3D_id) != points3D_.end();
527 }
528 
530  return image_pair_stats_.find(pair_id) != image_pair_stats_.end();
531 }
532 
533 bool Reconstruction::IsImageRegistered(const image_t image_id) const {
534  return Image(image_id).IsRegistered();
535 }
536 
538  return correspondence_graph_;
539 }
540 
542  return correspondence_graph_ != nullptr;
543 }
544 
545 template <bool kEstimateScale>
546 bool Reconstruction::Align(const std::vector<std::string>& image_names,
547  const std::vector<Eigen::Vector3d>& locations,
548  const int min_common_images,
549  SimilarityTransform3* tform) {
550  CHECK_GE(min_common_images, 3);
551  CHECK_EQ(image_names.size(), locations.size());
552 
553  // Find out which images are contained in the reconstruction and get the
554  // positions of their camera centers.
555  std::unordered_set<image_t> common_image_ids;
556  std::vector<Eigen::Vector3d> src;
557  std::vector<Eigen::Vector3d> dst;
558  for (size_t i = 0; i < image_names.size(); ++i) {
559  const class Image* image = FindImageWithName(image_names[i]);
560  if (image == nullptr) {
561  continue;
562  }
563 
564  if (!IsImageRegistered(image->ImageId())) {
565  continue;
566  }
567 
568  // Ignore duplicate images.
569  if (common_image_ids.count(image->ImageId()) > 0) {
570  continue;
571  }
572 
573  common_image_ids.insert(image->ImageId());
574  src.push_back(image->ProjectionCenter());
575  dst.push_back(locations[i]);
576  }
577 
578  // Only compute the alignment if there are enough correspondences.
579  if (common_image_ids.size() < static_cast<size_t>(min_common_images)) {
580  return false;
581  }
582 
583  SimilarityTransform3 transform;
584  if (!transform.Estimate<kEstimateScale>(src, dst)) {
585  return false;
586  }
587 
588  Transform(transform);
589 
590  if (tform != nullptr) {
591  *tform = transform;
592  }
593 
594  return true;
595 }
596 
597 template <bool kEstimateScale>
598 bool Reconstruction::AlignRobust(const std::vector<std::string>& image_names,
599  const std::vector<Eigen::Vector3d>& locations,
600  const int min_common_images,
601  const RANSACOptions& ransac_options,
602  SimilarityTransform3* tform) {
603  CHECK_GE(min_common_images, 3);
604  CHECK_EQ(image_names.size(), locations.size());
605 
606  // Find out which images are contained in the reconstruction and get the
607  // positions of their camera centers.
608  std::unordered_set<image_t> common_image_ids;
609  std::vector<Eigen::Vector3d> src;
610  std::vector<Eigen::Vector3d> dst;
611  for (size_t i = 0; i < image_names.size(); ++i) {
612  const class Image* image = FindImageWithName(image_names[i]);
613  if (image == nullptr) {
614  continue;
615  }
616 
617  if (!IsImageRegistered(image->ImageId())) {
618  continue;
619  }
620 
621  // Ignore duplicate images.
622  if (common_image_ids.count(image->ImageId()) > 0) {
623  continue;
624  }
625 
626  common_image_ids.insert(image->ImageId());
627  src.push_back(image->ProjectionCenter());
628  dst.push_back(locations[i]);
629  }
630 
631  // Only compute the alignment if there are enough correspondences.
632  if (common_image_ids.size() < static_cast<size_t>(min_common_images)) {
633  return false;
634  }
635 
638  ransac(ransac_options);
639 
640  const auto report = ransac.Estimate(src, dst);
641 
642  if (report.support.num_inliers < static_cast<size_t>(min_common_images)) {
643  return false;
644  }
645 
646  SimilarityTransform3 transform = SimilarityTransform3(report.model);
647  Transform(transform);
648 
649  if (tform != nullptr) {
650  *tform = transform;
651  }
652 
653  return true;
654 }
655 
656 } // namespace colmap
std::shared_ptr< core::Tensor > image
std::string name
math::float4 color
static image_pair_t ImagePairToPairId(const image_t image_id1, const image_t image_id2)
Definition: database.h:339
bool IsRegistered() const
Definition: image.h:257
Report Estimate(const std::vector< typename Estimator::X_t > &X, const std::vector< typename Estimator::Y_t > &Y)
Definition: loransac.h:72
void ReadBinary(const std::string &path)
bool Align(const std::vector< std::string > &image_names, const std::vector< Eigen::Vector3d > &locations, const int min_common_images, SimilarityTransform3 *tform=nullptr)
size_t NumImages() const
void ExtractColorsForAllImages(const std::string &path)
bool ExportCam(const std::string &path, bool skip_distortion=false) const
size_t FilterAllPoints3D(const double max_reproj_error, const double min_tri_angle)
Reconstruction Crop(const std::pair< Eigen::Vector3d, Eigen::Vector3d > &bbox) const
double ComputeMeanTrackLength() const
point3D_t MergePoints3D(const point3D_t point3D_id1, const point3D_t point3D_id2)
size_t NumRegImages() const
Reconstruction & operator=(const Reconstruction &other)
void Transform(const SimilarityTransform3 &tform)
std::pair< Eigen::Vector3d, Eigen::Vector3d > ComputeBoundingBox(const double p0=0.0, const double p1=1.0) const
size_t FilterObservationsWithNegativeDepth()
void Write(const std::string &path) const
std::vector< image_t > FindCommonRegImageIds(const Reconstruction &reconstruction) const
void Normalize(const double extent=10.0, const double p0=0.1, const double p1=0.9, const bool use_images=true)
bool IsImageRegistered(const image_t image_id) const
bool ExportNVM(const std::string &path, bool skip_distortion=false) const
void AddImage(const class Image &image)
bool ExtractColorsForImage(const image_t image_id, const std::string &path)
const std::unordered_map< image_t, class Image > & Images() const
void AddCamera(const class Camera &camera)
std::vector< image_t > FilterImages(const double min_focal_length_ratio, const double max_focal_length_ratio, const double max_extra_param)
void DeleteObservation(const image_t image_id, const point2D_t point2D_idx)
size_t ComputeNumObservations() const
Eigen::Vector3d ComputeCentroid(const double p0=0.1, const double p1=0.9) const
const class Image & Image(const image_t image_id) const
bool ExportRecon3D(const std::string &path, bool skip_distortion=false) const
void ExportPLY(const std::string &path) const
std::unordered_set< point3D_t > Point3DIds() const
size_t NumPoints3D() const
const class Camera & Camera(const camera_t camera_id) const
void WriteBinary(const std::string &path) const
std::vector< PlyPoint > ConvertToPLY() const
bool Merge(const Reconstruction &reconstruction, const double max_reproj_error)
void ExportVRML(const std::string &images_path, const std::string &points3D_path, const double image_scale, const Eigen::Vector3d &image_rgb) const
bool ExportBundler(const std::string &path, const std::string &list_path, bool skip_distortion=false) const
void CreateImageDirs(const std::string &path) const
bool AlignRobust(const std::vector< std::string > &image_names, const std::vector< Eigen::Vector3d > &locations, const int min_common_images, const RANSACOptions &ransac_options, SimilarityTransform3 *tform=nullptr)
const std::unordered_map< camera_t, class Camera > & Cameras() const
void Load(const DatabaseCache &database_cache)
const std::unordered_map< point3D_t, class Point3D > & Points3D() const
bool ExistsCamera(const camera_t camera_id) const
void AddObservation(const point3D_t point3D_id, const TrackElement &track_el)
const class Image * FindImageWithName(const std::string &name) const
const std::unordered_map< image_pair_t, ImagePairStat > & ImagePairs() const
void DeRegisterImage(const image_t image_id)
void ReadText(const std::string &path)
const std::vector< image_t > & RegImageIds() const
size_t FilterPoints3D(const double max_reproj_error, const double min_tri_angle, const std::unordered_set< point3D_t > &point3D_ids)
size_t NumImagePairs() const
void DeletePoint3D(const point3D_t point3D_id)
double ComputeMeanReprojectionError() const
bool ExistsImage(const image_t image_id) const
double ComputeMeanObservationsPerRegImage() const
const ImagePairStat & ImagePair(const image_pair_t pair_id) const
void RegisterImage(const image_t image_id)
void WriteText(const std::string &path) const
size_t FilterPoints3DInImages(const double max_reproj_error, const double min_tri_angle, const std::unordered_set< image_t > &image_ids)
size_t NumCameras() const
void ImportPLY(const std::string &path)
void Read(const std::string &path)
const class Point3D & Point3D(const point3D_t point3D_id) const
point3D_t AddPoint3D(const Eigen::Vector3d &xyz, const Track &track, const Eigen::Vector3ub &color=Eigen::Vector3ub::Zero())
bool ExistsImagePair(const image_pair_t pair_id) const
void SetUp(const CorrespondenceGraph *correspondence_graph)
size_t NumAddedPoints3D() const
bool ExistsPoint3D(const point3D_t point3D_id) const
const CorrespondenceGraph * GetCorrespondenceGraph() const
bool HasCorrespondenceGraph() const
void TranscribeImageIdsToDatabase(const Database &database)
bool Estimate(const std::vector< Eigen::Vector3d > &src, const std::vector< Eigen::Vector3d > &dst)
Matrix< uint8_t, 3, 1 > Vector3ub
Definition: types.h:42
static const std::string path
Definition: PointCloud.cpp:59
uint64_t image_pair_t
Definition: types.h:64
uint64_t point3D_t
Definition: types.h:72
uint32_t point2D_t
Definition: types.h:67
uint32_t image_t
Definition: types.h:61
uint32_t camera_t
Definition: types.h:58