ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
patch_match.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 <iostream>
11 #include <memory>
12 #include <vector>
13 
14 #include "mvs/depth_map.h"
15 #include "mvs/image.h"
16 #include "mvs/model.h"
17 #include "mvs/normal_map.h"
18 #ifndef __CUDACC__
19 #include "util/threading.h"
20 #endif
21 
22 namespace colmap {
23 namespace mvs {
24 
25 // Maximum possible window radius for the photometric consistency cost. This
26 // value is equal to THREADS_PER_BLOCK in patch_match_cuda.cu and the limit
27 // arises from the shared memory implementation.
28 const static size_t kMaxPatchMatchWindowRadius = 32;
29 
30 class ConsistencyGraph;
31 class PatchMatchCuda;
32 class Workspace;
33 
35  // Maximum image size in either dimension.
36  int max_image_size = -1;
37 
38  // Index of the GPU used for patch match. For multi-GPU usage,
39  // you should separate multiple GPU indices by comma, e.g., "0,1,2,3".
40  std::string gpu_index = "-1";
41 
42  // Depth range in which to randomly sample depth hypotheses.
43  double depth_min = -1.0f;
44  double depth_max = -1.0f;
45 
46  // Half window size to compute NCC photo-consistency cost.
47  int window_radius = 5;
48 
49  // Number of pixels to skip when computing NCC. For a value of 1, every
50  // pixel is used to compute the NCC. For larger values, only every n-th row
51  // and column is used and the computation speed thereby increases roughly by
52  // a factor of window_step^2. Note that not all combinations of window sizes
53  // and steps produce nice results, especially if the step is greather
54  // than 2.
55  int window_step = 1;
56 
57  // Parameters for bilaterally weighted NCC.
58  double sigma_spatial = -1;
59  double sigma_color = 0.2f;
60 
61  // Number of random samples to draw in Monte Carlo sampling.
62  int num_samples = 15;
63 
64  // Spread of the NCC likelihood function.
65  double ncc_sigma = 0.6f;
66 
67  // Minimum triangulation angle in degrees.
68  double min_triangulation_angle = 1.0f;
69 
70  // Spread of the incident angle likelihood function.
71  double incident_angle_sigma = 0.9f;
72 
73  // Number of coordinate descent iterations. Each iteration consists
74  // of four sweeps from left to right, top to bottom, and vice versa.
75  int num_iterations = 5;
76 
77  // Whether to add a regularized geometric consistency term to the cost
78  // function. If true, the `depth_maps` and `normal_maps` must not be null.
79  bool geom_consistency = true;
80 
81  // The relative weight of the geometric consistency term w.r.t. to
82  // the photo-consistency term.
84 
85  // Maximum geometric consistency cost in terms of the forward-backward
86  // reprojection error in pixels.
88 
89  // Whether to enable filtering.
90  bool filter = true;
91 
92  // Minimum NCC coefficient for pixel to be photo-consistent.
93  double filter_min_ncc = 0.1f;
94 
95  // Minimum triangulation angle to be stable.
97 
98  // Minimum number of source images have to be consistent
99  // for pixel not to be filtered.
101 
102  // Maximum forward-backward reprojection error for pixel
103  // to be geometrically consistent.
105 
106  // Cache size in gigabytes for patch match, which keeps the bitmaps, depth
107  // maps, and normal maps of this number of images in memory. A higher value
108  // leads to less disk access and faster computation, while a lower value
109  // leads to reduced memory usage. Note that a single image can consume a lot
110  // of memory, if the consistency graph is dense.
111  double cache_size = 32.0;
112 
113  // Whether to tolerate missing images/maps in the problem setup
114  bool allow_missing_files = false;
115 
116  // Whether to write the consistency graph.
118 
119  void Print() const;
120  bool Check() const {
121  if (depth_min != -1.0f || depth_max != -1.0f) {
123  CHECK_OPTION_GE(depth_min, 0.0f);
124  }
126  static_cast<int>(kMaxPatchMatchWindowRadius));
132  CHECK_OPTION_GT(ncc_sigma, 0.0f);
146  return true;
147  }
148 };
149 
150 // This is a wrapper class around the actual PatchMatchCuda implementation. This
151 // class is necessary to hide Cuda code from any boost or Eigen code, since
152 // NVCC/MSVC cannot compile complex C++ code.
153 class PatchMatch {
154 public:
155  struct Problem {
156  // Index of the reference image.
157  int ref_image_idx = -1;
158 
159  // Indices of the source images.
160  std::vector<int> src_image_idxs;
161 
162  // Input images for the photometric consistency term.
163  std::vector<Image>* images = nullptr;
164 
165  // Input depth maps for the geometric consistency term.
166  std::vector<DepthMap>* depth_maps = nullptr;
167 
168  // Input normal maps for the geometric consistency term.
169  std::vector<NormalMap>* normal_maps = nullptr;
170 
171  // Print the configuration to stdout.
172  void Print() const;
173  };
174 
175  PatchMatch(const PatchMatchOptions& options, const Problem& problem);
176  ~PatchMatch();
177 
178  // Check the options and the problem for validity.
179  void Check() const;
180 
181  // Run the patch match algorithm.
182  void Run();
183 
184  // Get the computed values after running the algorithm.
185  DepthMap GetDepthMap() const;
186  NormalMap GetNormalMap() const;
188  Mat<float> GetSelProbMap() const;
189 
190 private:
191  const PatchMatchOptions options_;
192  const Problem problem_;
193  std::unique_ptr<PatchMatchCuda> patch_match_cuda_;
194 };
195 
196 // This thread processes all problems in a workspace. A workspace has the
197 // following file structure, if the workspace format is "COLMAP":
198 //
199 // images/*
200 // sparse/{cameras.txt, images.txt, points3D.txt}
201 // stereo/
202 // depth_maps/*
203 // normal_maps/*
204 // consistency_graphs/*
205 // patch-match.cfg
206 //
207 // The `patch-match.cfg` file specifies the images to be processed as:
208 //
209 // image_name1.jpg
210 // __all__
211 // image_name2.jpg
212 // __auto__, 20
213 // image_name3.jpg
214 // image_name1.jpg, image_name2.jpg
215 //
216 // Two consecutive lines specify the images used to compute one patch match
217 // problem. The first line specifies the reference image and the second line the
218 // source images. Image names are relative to the `images` directory. In this
219 // example, the first reference image uses all other images as source images,
220 // the second reference image uses the 20 most connected images as source
221 // images, and the third reference image uses the first and second as source
222 // images. Note that all specified images must be reconstructed in the COLMAP
223 // reconstruction provided in the `sparse` folder.
224 
225 #ifndef __CUDACC__
226 
227 class PatchMatchController : public Thread {
228 public:
230  const std::string& workspace_path,
231  const std::string& workspace_format,
232  const std::string& pmvs_option_name,
233  const std::string& config_path = "");
234 
235 private:
236  void Run();
237  void ReadWorkspace();
238  void ReadProblems();
239  void ReadGpuIndices();
240  void ProcessProblem(const PatchMatchOptions& options,
241  const size_t problem_idx);
242 
243  const PatchMatchOptions options_;
244  const std::string workspace_path_;
245  const std::string workspace_format_;
246  const std::string pmvs_option_name_;
247  const std::string config_path_;
248 
249  std::unique_ptr<ThreadPool> thread_pool_;
250  std::mutex workspace_mutex_;
251  std::unique_ptr<Workspace> workspace_;
252  std::vector<PatchMatch::Problem> problems_;
253  std::vector<int> gpu_indices_;
254  std::vector<std::pair<float, float>> depth_ranges_;
255 };
256 
257 #endif
258 
259 } // namespace mvs
260 } // namespace colmap
PatchMatchController(const PatchMatchOptions &options, const std::string &workspace_path, const std::string &workspace_format, const std::string &pmvs_option_name, const std::string &config_path="")
Definition: patch_match.cc:184
Mat< float > GetSelProbMap() const
Definition: patch_match.cc:174
ConsistencyGraph GetConsistencyGraph() const
Definition: patch_match.cc:178
NormalMap GetNormalMap() const
Definition: patch_match.cc:170
PatchMatch(const PatchMatchOptions &options, const Problem &problem)
Definition: patch_match.cc:48
DepthMap GetDepthMap() const
Definition: patch_match.cc:166
#define CHECK_OPTION_LT(val1, val2)
Definition: logging.h:32
#define CHECK_OPTION_LE(val1, val2)
Definition: logging.h:31
#define CHECK_OPTION_GT(val1, val2)
Definition: logging.h:34
#define CHECK_OPTION_GE(val1, val2)
Definition: logging.h:33
static const size_t kMaxPatchMatchWindowRadius
Definition: patch_match.h:28
std::vector< Image > * images
Definition: patch_match.h:163
std::vector< NormalMap > * normal_maps
Definition: patch_match.h:169
std::vector< DepthMap > * depth_maps
Definition: patch_match.h:166
std::vector< int > src_image_idxs
Definition: patch_match.h:160