ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
fusion.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 <Eigen/Core>
11 #include <cfloat>
12 #include <unordered_set>
13 #include <vector>
14 
15 #include "mvs/depth_map.h"
16 #include "mvs/image.h"
17 #include "mvs/mat.h"
18 #include "mvs/model.h"
19 #include "mvs/normal_map.h"
20 #include "mvs/workspace.h"
21 #include "util/alignment.h"
22 #include "util/cache.h"
23 #include "util/math.h"
24 #include "util/ply.h"
25 #include "util/threading.h"
26 
27 namespace colmap {
28 namespace mvs {
29 
31  // Path for PNG masks. Same format expected as ImageReaderOptions.
32  std::string mask_path = "";
33 
34  // The number of threads to use during fusion.
35  int num_threads = -1;
36 
37  // Maximum image size in either dimension.
38  int max_image_size = -1;
39 
40  // Minimum number of fused pixels to produce a point.
41  int min_num_pixels = 5;
42 
43  // Maximum number of pixels to fuse into a single point.
44  int max_num_pixels = 10000;
45 
46  // Maximum depth in consistency graph traversal.
48 
49  // Maximum relative difference between measured and projected pixel.
50  double max_reproj_error = 2.0f;
51 
52  // Maximum relative difference between measured and projected depth.
53  double max_depth_error = 0.01f;
54 
55  // Maximum angular difference in degrees of normals of pixels to be fused.
56  double max_normal_error = 10.0f;
57 
58  // Number of overlapping images to transitively check for fusing points.
59  int check_num_images = 50;
60 
61  // Flag indicating whether to use LRU cache or pre-load all data
62  bool use_cache = false;
63 
64  // Cache size in gigabytes for fusion. The fusion keeps the bitmaps, depth
65  // maps, normal maps, and consistency graphs of this number of images in
66  // memory. A higher value leads to less disk access and faster fusion, while
67  // a lower value leads to reduced memory usage. Note that a single image can
68  // consume a lot of memory, if the consistency graph is dense.
69  double cache_size = 32.0;
70 
71  std::pair<Eigen::Vector3f, Eigen::Vector3f> bounding_box =
72  std::make_pair(Eigen::Vector3f(-FLT_MAX, -FLT_MAX, -FLT_MAX),
73  Eigen::Vector3f(FLT_MAX, FLT_MAX, FLT_MAX));
74 
75  // Check the options for validity.
76  bool Check() const;
77 
78  // Print the options to stdout.
79  void Print() const;
80 };
81 
82 class StereoFusion : public Thread {
83 public:
84  StereoFusion(const StereoFusionOptions& options,
85  const std::string& workspace_path,
86  const std::string& workspace_format,
87  const std::string& pmvs_option_name,
88  const std::string& input_type);
89 
90  const std::vector<PlyPoint>& GetFusedPoints() const;
91  const std::vector<std::vector<int>>& GetFusedPointsVisibility() const;
92 
93 private:
94  void Run();
95  void InitFusedPixelMask(int image_idx, size_t width, size_t height);
96  void Fuse(const int thread_id,
97  const int image_idx,
98  const int row,
99  const int col);
100 
101  const StereoFusionOptions options_;
102  const std::string workspace_path_;
103  const std::string workspace_format_;
104  const std::string pmvs_option_name_;
105  const std::string input_type_;
106  const float max_squared_reproj_error_;
107  const float min_cos_normal_error_;
108 
109  std::unique_ptr<Workspace> workspace_;
110  std::vector<char> used_images_;
111  std::vector<char> fused_images_;
112  std::vector<std::vector<int>> overlapping_images_;
113  // Contains image masks of pre-masked and already fused pixels.
114  // Initialized from image masks if provided in StereoFusionOptions.
115  std::vector<Mat<char>> fused_pixel_masks_;
116  std::vector<std::pair<int, int>> depth_map_sizes_;
117  std::vector<std::pair<float, float>> bitmap_scales_;
118  std::vector<Eigen::Matrix<float, 3, 4, Eigen::RowMajor>> P_;
119  std::vector<Eigen::Matrix<float, 3, 4, Eigen::RowMajor>> inv_P_;
120  std::vector<Eigen::Matrix<float, 3, 3, Eigen::RowMajor>> inv_R_;
121 
122  struct FusionData {
123  int image_idx = kInvalidImageId;
124  int row = 0;
125  int col = 0;
126  int traversal_depth = -1;
127  FusionData(int image_idx, int row, int col, int traversal_depth)
128  : image_idx(image_idx),
129  row(row),
130  col(col),
131  traversal_depth(traversal_depth) {}
132  bool operator()(const FusionData& data1, const FusionData& data2) {
133  return data1.image_idx > data2.image_idx;
134  }
135  };
136 
137  // Already fused points.
138  std::vector<PlyPoint> fused_points_;
139  std::vector<std::vector<int>> fused_points_visibility_;
140 
141  std::vector<std::vector<PlyPoint>> task_fused_points_;
142  std::vector<std::vector<std::vector<int>>> task_fused_points_visibility_;
143 };
144 
145 // Write the visiblity information into a binary file of the following format:
146 //
147 // <num_points : uint64_t>
148 // <num_visible_images_for_point1 : uint32_t>
149 // <point1_image_idx1 : uint32_t><point1_image_idx2 : uint32_t> ...
150 // <num_visible_images_for_point2 : uint32_t>
151 // <point2_image_idx2 : uint32_t><point2_image_idx2 : uint32_t> ...
152 // ...
153 //
154 // Note that an image_idx in the case of the mvs::StereoFuser does not
155 // correspond to the image_id of a Reconstruction, but the index of the image in
156 // the mvs::Model, which is the location of the image in the images.bin/.txt.
158  const std::string& path,
159  const std::vector<std::vector<int>>& points_visibility);
160 
161 } // namespace mvs
162 } // namespace colmap
int width
int height
const std::vector< std::vector< int > > & GetFusedPointsVisibility() const
Definition: fusion.cc:142
const std::vector< PlyPoint > & GetFusedPoints() const
Definition: fusion.cc:138
StereoFusion(const StereoFusionOptions &options, const std::string &workspace_path, const std::string &workspace_format, const std::string &pmvs_option_name, const std::string &input_type)
Definition: fusion.cc:122
CLOUDVIEWER_HOST_DEVICE Pair< First, Second > make_pair(const First &_first, const Second &_second)
Definition: SlabTraits.h:49
static const std::string path
Definition: PointCloud.cpp:59
void WritePointsVisibility(const std::string &path, const std::vector< std::vector< int >> &points_visibility)
Definition: fusion.cc:635
const image_t kInvalidImageId
Definition: types.h:76
std::pair< Eigen::Vector3f, Eigen::Vector3f > bounding_box
Definition: fusion.h:71