ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
option_manager.cc
Go to the documentation of this file.
1 // Copyright (c) 2018, ETH Zurich and UNC Chapel Hill.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 //
14 // * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
15 // its contributors may be used to endorse or promote products derived
16 // from this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Johannes L. Schoenberger (jsch-at-demuc-dot-de)
31 
32 #include "util/option_manager.h"
33 
34 #include <boost/filesystem/operations.hpp>
35 #include <boost/property_tree/ini_parser.hpp>
36 
37 #include "base/image_reader.h"
40 #include "feature/extraction.h"
41 #include "feature/matching.h"
42 #include "feature/sift.h"
43 #include "mvs/fusion.h"
44 #include "mvs/meshing.h"
45 #include "mvs/patch_match.h"
47 #include "ui/render_options.h"
48 #include "util/misc.h"
49 #include "util/random.h"
50 #include "util/version.h"
51 
52 namespace config = boost::program_options;
53 
54 namespace colmap {
55 
56 OptionManager::OptionManager(bool add_project_options) {
57  project_path.reset(new std::string());
58  database_path.reset(new std::string());
59  image_path.reset(new std::string());
60 
61  image_reader.reset(new ImageReaderOptions());
71  mapper.reset(new IncrementalMapperOptions());
76  texturing.reset(new TexturingOptions());
77  render.reset(new RenderOptions());
78 
79  Reset();
80 
81  desc_->add_options()("help,h", "");
82 
84  AddLogOptions();
85 
86  if (add_project_options) {
87  desc_->add_options()("project_path", config::value<std::string>());
88  }
89 }
90 
92  mapper->min_focal_length_ratio = 0.1;
93  mapper->max_focal_length_ratio = 10;
94  mapper->max_extra_param = std::numeric_limits<double>::max();
95 }
96 
98  const bool kResetPaths = false;
99  ResetOptions(kResetPaths);
100  mapper->mapper.init_min_tri_angle /= 2;
101  mapper->ba_global_images_ratio = 1.4;
102  mapper->ba_global_points_ratio = 1.4;
103  mapper->min_focal_length_ratio = 0.1;
104  mapper->max_focal_length_ratio = 10;
105  mapper->max_extra_param = std::numeric_limits<double>::max();
106  stereo_fusion->min_num_pixels = 15;
107 }
108 
110  stereo_fusion->min_num_pixels = 10;
111 }
112 
114  sift_extraction->max_image_size = 1000;
115  sift_extraction->max_num_features = 2048;
116  sequential_matching->loop_detection_num_images /= 2;
117  vocab_tree_matching->max_num_features = 256;
118  vocab_tree_matching->num_images /= 2;
119  mapper->ba_local_max_num_iterations /= 2;
120  mapper->ba_global_max_num_iterations /= 2;
121  mapper->ba_global_images_ratio *= 1.2;
122  mapper->ba_global_points_ratio *= 1.2;
123  mapper->ba_global_max_refinements = 2;
124  patch_match_stereo->max_image_size = 1000;
125  patch_match_stereo->window_radius = 4;
126  patch_match_stereo->window_step = 2;
127  patch_match_stereo->num_samples /= 2;
128  patch_match_stereo->num_iterations = 3;
129  patch_match_stereo->geom_consistency = false;
130  stereo_fusion->check_num_images /= 2;
131  stereo_fusion->max_image_size = 1000;
132 }
133 
135  sift_extraction->max_image_size = 1600;
136  sift_extraction->max_num_features = 4096;
137  sequential_matching->loop_detection_num_images /= 1.5;
138  vocab_tree_matching->max_num_features = 1024;
139  vocab_tree_matching->num_images /= 1.5;
140  mapper->ba_local_max_num_iterations /= 1.5;
141  mapper->ba_global_max_num_iterations /= 1.5;
142  mapper->ba_global_images_ratio *= 1.1;
143  mapper->ba_global_points_ratio *= 1.1;
144  mapper->ba_global_max_refinements = 2;
145  patch_match_stereo->max_image_size = 1600;
146  patch_match_stereo->window_radius = 4;
147  patch_match_stereo->window_step = 2;
148  patch_match_stereo->num_samples /= 1.5;
149  patch_match_stereo->num_iterations = 5;
150  patch_match_stereo->geom_consistency = false;
151  stereo_fusion->check_num_images /= 1.5;
152  stereo_fusion->max_image_size = 1600;
153 }
154 
156  sift_extraction->estimate_affine_shape = true;
157  sift_extraction->max_image_size = 2400;
158  sift_extraction->max_num_features = 8192;
159  sift_matching->guided_matching = true;
160  vocab_tree_matching->max_num_features = 4096;
161  mapper->ba_local_max_num_iterations = 30;
162  mapper->ba_local_max_refinements = 3;
163  mapper->ba_global_max_num_iterations = 75;
164  patch_match_stereo->max_image_size = 2400;
165  stereo_fusion->max_image_size = 2400;
166 }
167 
169  // Most of the options are set to extreme quality by default.
170  sift_extraction->estimate_affine_shape = true;
171  sift_extraction->domain_size_pooling = true;
172  sift_matching->guided_matching = true;
173  mapper->ba_local_max_num_iterations = 40;
174  mapper->ba_local_max_refinements = 3;
175  mapper->ba_global_max_num_iterations = 100;
176 }
177 
179  AddLogOptions();
182  AddImageOptions();
198 }
199 
201  if (added_log_options_) {
202  return;
203  }
204  added_log_options_ = true;
205 
206  AddAndRegisterDefaultOption("log_to_stderr", &FLAGS_logtostderr);
207  AddAndRegisterDefaultOption("log_level", &FLAGS_v);
208 }
209 
211  if (added_random_options_) {
212  return;
213  }
214  added_random_options_ = true;
215 
216  AddAndRegisterDefaultOption("random_seed", &kDefaultPRNGSeed);
217 }
218 
220  if (added_database_options_) {
221  return;
222  }
223  added_database_options_ = true;
224 
225  AddAndRegisterRequiredOption("database_path", database_path.get());
226 }
227 
229  if (added_image_options_) {
230  return;
231  }
232  added_image_options_ = true;
233 
234  AddAndRegisterRequiredOption("image_path", image_path.get());
235 }
236 
238  if (added_extraction_options_) {
239  return;
240  }
241  added_extraction_options_ = true;
242 
243  AddAndRegisterDefaultOption("ImageReader.mask_path",
244  &image_reader->mask_path);
245  AddAndRegisterDefaultOption("ImageReader.camera_model",
246  &image_reader->camera_model);
247  AddAndRegisterDefaultOption("ImageReader.single_camera",
248  &image_reader->single_camera);
249  AddAndRegisterDefaultOption("ImageReader.single_camera_per_folder",
250  &image_reader->single_camera_per_folder);
251  AddAndRegisterDefaultOption("ImageReader.single_camera_per_image",
252  &image_reader->single_camera_per_image);
253  AddAndRegisterDefaultOption("ImageReader.existing_camera_id",
254  &image_reader->existing_camera_id);
255  AddAndRegisterDefaultOption("ImageReader.camera_params",
256  &image_reader->camera_params);
257  AddAndRegisterDefaultOption("ImageReader.default_focal_length_factor",
258  &image_reader->default_focal_length_factor);
259  AddAndRegisterDefaultOption("ImageReader.camera_mask_path",
260  &image_reader->camera_mask_path);
261 
262  AddAndRegisterDefaultOption("SiftExtraction.num_threads",
263  &sift_extraction->num_threads);
264  AddAndRegisterDefaultOption("SiftExtraction.use_gpu",
265  &sift_extraction->use_gpu);
266  AddAndRegisterDefaultOption("SiftExtraction.gpu_index",
267  &sift_extraction->gpu_index);
268  AddAndRegisterDefaultOption("SiftExtraction.max_image_size",
269  &sift_extraction->max_image_size);
270  AddAndRegisterDefaultOption("SiftExtraction.max_num_features",
271  &sift_extraction->max_num_features);
272  AddAndRegisterDefaultOption("SiftExtraction.first_octave",
273  &sift_extraction->first_octave);
274  AddAndRegisterDefaultOption("SiftExtraction.num_octaves",
275  &sift_extraction->num_octaves);
276  AddAndRegisterDefaultOption("SiftExtraction.octave_resolution",
277  &sift_extraction->octave_resolution);
278  AddAndRegisterDefaultOption("SiftExtraction.peak_threshold",
279  &sift_extraction->peak_threshold);
280  AddAndRegisterDefaultOption("SiftExtraction.edge_threshold",
281  &sift_extraction->edge_threshold);
282  AddAndRegisterDefaultOption("SiftExtraction.estimate_affine_shape",
283  &sift_extraction->estimate_affine_shape);
284  AddAndRegisterDefaultOption("SiftExtraction.max_num_orientations",
285  &sift_extraction->max_num_orientations);
286  AddAndRegisterDefaultOption("SiftExtraction.upright",
287  &sift_extraction->upright);
288  AddAndRegisterDefaultOption("SiftExtraction.domain_size_pooling",
289  &sift_extraction->domain_size_pooling);
290  AddAndRegisterDefaultOption("SiftExtraction.dsp_min_scale",
291  &sift_extraction->dsp_min_scale);
292  AddAndRegisterDefaultOption("SiftExtraction.dsp_max_scale",
293  &sift_extraction->dsp_max_scale);
294  AddAndRegisterDefaultOption("SiftExtraction.dsp_num_scales",
295  &sift_extraction->dsp_num_scales);
296 }
297 
299  if (added_match_options_) {
300  return;
301  }
302  added_match_options_ = true;
303 
304  AddAndRegisterDefaultOption("SiftMatching.num_threads",
305  &sift_matching->num_threads);
306  AddAndRegisterDefaultOption("SiftMatching.use_gpu",
307  &sift_matching->use_gpu);
308  AddAndRegisterDefaultOption("SiftMatching.gpu_index",
309  &sift_matching->gpu_index);
310  AddAndRegisterDefaultOption("SiftMatching.max_ratio",
311  &sift_matching->max_ratio);
312  AddAndRegisterDefaultOption("SiftMatching.max_distance",
313  &sift_matching->max_distance);
314  AddAndRegisterDefaultOption("SiftMatching.cross_check",
315  &sift_matching->cross_check);
316  AddAndRegisterDefaultOption("SiftMatching.max_error",
317  &sift_matching->max_error);
318  AddAndRegisterDefaultOption("SiftMatching.max_num_matches",
319  &sift_matching->max_num_matches);
320  AddAndRegisterDefaultOption("SiftMatching.confidence",
321  &sift_matching->confidence);
322  AddAndRegisterDefaultOption("SiftMatching.max_num_trials",
323  &sift_matching->max_num_trials);
324  AddAndRegisterDefaultOption("SiftMatching.min_inlier_ratio",
325  &sift_matching->min_inlier_ratio);
326  AddAndRegisterDefaultOption("SiftMatching.min_num_inliers",
327  &sift_matching->min_num_inliers);
328  AddAndRegisterDefaultOption("SiftMatching.multiple_models",
329  &sift_matching->multiple_models);
330  AddAndRegisterDefaultOption("SiftMatching.guided_matching",
331  &sift_matching->guided_matching);
332 }
333 
335  if (added_exhaustive_match_options_) {
336  return;
337  }
338  added_exhaustive_match_options_ = true;
339 
341 
342  AddAndRegisterDefaultOption("ExhaustiveMatching.block_size",
343  &exhaustive_matching->block_size);
344 }
345 
347  if (added_sequential_match_options_) {
348  return;
349  }
350  added_sequential_match_options_ = true;
351 
353 
354  AddAndRegisterDefaultOption("SequentialMatching.overlap",
355  &sequential_matching->overlap);
356  AddAndRegisterDefaultOption("SequentialMatching.quadratic_overlap",
357  &sequential_matching->quadratic_overlap);
358  AddAndRegisterDefaultOption("SequentialMatching.loop_detection",
359  &sequential_matching->loop_detection);
360  AddAndRegisterDefaultOption("SequentialMatching.loop_detection_period",
361  &sequential_matching->loop_detection_period);
362  AddAndRegisterDefaultOption(
363  "SequentialMatching.loop_detection_num_images",
364  &sequential_matching->loop_detection_num_images);
365  AddAndRegisterDefaultOption(
366  "SequentialMatching.loop_detection_num_nearest_neighbors",
367  &sequential_matching->loop_detection_num_nearest_neighbors);
368  AddAndRegisterDefaultOption(
369  "SequentialMatching.loop_detection_num_checks",
370  &sequential_matching->loop_detection_num_checks);
371  AddAndRegisterDefaultOption(
372  "SequentialMatching.loop_detection_num_images_after_verification",
373  &sequential_matching->loop_detection_num_images_after_verification);
374  AddAndRegisterDefaultOption(
375  "SequentialMatching.loop_detection_max_num_features",
376  &sequential_matching->loop_detection_max_num_features);
377  AddAndRegisterDefaultOption("SequentialMatching.vocab_tree_path",
378  &sequential_matching->vocab_tree_path);
379 }
380 
382  if (added_vocab_tree_match_options_) {
383  return;
384  }
385  added_vocab_tree_match_options_ = true;
386 
388 
389  AddAndRegisterDefaultOption("VocabTreeMatching.num_images",
390  &vocab_tree_matching->num_images);
391  AddAndRegisterDefaultOption("VocabTreeMatching.num_nearest_neighbors",
392  &vocab_tree_matching->num_nearest_neighbors);
393  AddAndRegisterDefaultOption("VocabTreeMatching.num_checks",
394  &vocab_tree_matching->num_checks);
395  AddAndRegisterDefaultOption(
396  "VocabTreeMatching.num_images_after_verification",
397  &vocab_tree_matching->num_images_after_verification);
398  AddAndRegisterDefaultOption("VocabTreeMatching.max_num_features",
399  &vocab_tree_matching->max_num_features);
400  AddAndRegisterDefaultOption("VocabTreeMatching.vocab_tree_path",
401  &vocab_tree_matching->vocab_tree_path);
402  AddAndRegisterDefaultOption("VocabTreeMatching.match_list_path",
403  &vocab_tree_matching->match_list_path);
404 }
405 
407  if (added_spatial_match_options_) {
408  return;
409  }
410  added_spatial_match_options_ = true;
411 
413 
414  AddAndRegisterDefaultOption("SpatialMatching.is_gps",
415  &spatial_matching->is_gps);
416  AddAndRegisterDefaultOption("SpatialMatching.ignore_z",
417  &spatial_matching->ignore_z);
418  AddAndRegisterDefaultOption("SpatialMatching.max_num_neighbors",
419  &spatial_matching->max_num_neighbors);
420  AddAndRegisterDefaultOption("SpatialMatching.max_distance",
421  &spatial_matching->max_distance);
422 }
423 
425  if (added_transitive_match_options_) {
426  return;
427  }
428  added_transitive_match_options_ = true;
429 
431 
432  AddAndRegisterDefaultOption("TransitiveMatching.batch_size",
433  &transitive_matching->batch_size);
434  AddAndRegisterDefaultOption("TransitiveMatching.num_iterations",
435  &transitive_matching->num_iterations);
436 }
437 
439  if (added_image_pairs_match_options_) {
440  return;
441  }
442  added_image_pairs_match_options_ = true;
443 
445 
446  AddAndRegisterDefaultOption("ImagePairsMatching.block_size",
447  &image_pairs_matching->block_size);
448 }
449 
451  if (added_ba_options_) {
452  return;
453  }
454  added_ba_options_ = true;
455 
456  AddAndRegisterDefaultOption(
457  "BundleAdjustment.max_num_iterations",
458  &bundle_adjustment->solver_options.max_num_iterations);
459  AddAndRegisterDefaultOption(
460  "BundleAdjustment.max_linear_solver_iterations",
461  &bundle_adjustment->solver_options.max_linear_solver_iterations);
462  AddAndRegisterDefaultOption(
463  "BundleAdjustment.function_tolerance",
464  &bundle_adjustment->solver_options.function_tolerance);
465  AddAndRegisterDefaultOption(
466  "BundleAdjustment.gradient_tolerance",
467  &bundle_adjustment->solver_options.gradient_tolerance);
468  AddAndRegisterDefaultOption(
469  "BundleAdjustment.parameter_tolerance",
470  &bundle_adjustment->solver_options.parameter_tolerance);
471  AddAndRegisterDefaultOption("BundleAdjustment.refine_focal_length",
472  &bundle_adjustment->refine_focal_length);
473  AddAndRegisterDefaultOption("BundleAdjustment.refine_principal_point",
474  &bundle_adjustment->refine_principal_point);
475  AddAndRegisterDefaultOption("BundleAdjustment.refine_extra_params",
476  &bundle_adjustment->refine_extra_params);
477  AddAndRegisterDefaultOption("BundleAdjustment.refine_extrinsics",
478  &bundle_adjustment->refine_extrinsics);
479  AddAndRegisterDefaultOption("BundleAdjustment.use_gpu",
480  &bundle_adjustment->use_gpu);
481  AddAndRegisterDefaultOption("BundleAdjustment.gpu_index",
482  &bundle_adjustment->gpu_index);
483  AddAndRegisterDefaultOption("BundleAdjustment.min_num_images_gpu_solver",
484  &bundle_adjustment->min_num_images_gpu_solver);
485  AddAndRegisterDefaultOption(
486  "BundleAdjustment.min_num_residuals_for_cpu_multi_threading",
487  &bundle_adjustment->min_num_residuals_for_cpu_multi_threading);
488  AddAndRegisterDefaultOption(
489  "BundleAdjustment.max_num_images_direct_dense_cpu_solver",
490  &bundle_adjustment->max_num_images_direct_dense_cpu_solver);
491  AddAndRegisterDefaultOption(
492  "BundleAdjustment.max_num_images_direct_sparse_cpu_solver",
493  &bundle_adjustment->max_num_images_direct_sparse_cpu_solver);
494  AddAndRegisterDefaultOption(
495  "BundleAdjustment.max_num_images_direct_dense_gpu_solver",
496  &bundle_adjustment->max_num_images_direct_dense_gpu_solver);
497  AddAndRegisterDefaultOption(
498  "BundleAdjustment.max_num_images_direct_sparse_gpu_solver",
499  &bundle_adjustment->max_num_images_direct_sparse_gpu_solver);
500 }
501 
503  if (added_mapper_options_) {
504  return;
505  }
506  added_mapper_options_ = true;
507 
508  AddAndRegisterDefaultOption("Mapper.min_num_matches",
509  &mapper->min_num_matches);
510  AddAndRegisterDefaultOption("Mapper.ignore_watermarks",
511  &mapper->ignore_watermarks);
512  AddAndRegisterDefaultOption("Mapper.multiple_models",
513  &mapper->multiple_models);
514  AddAndRegisterDefaultOption("Mapper.max_num_models",
515  &mapper->max_num_models);
516  AddAndRegisterDefaultOption("Mapper.max_model_overlap",
517  &mapper->max_model_overlap);
518  AddAndRegisterDefaultOption("Mapper.min_model_size",
519  &mapper->min_model_size);
520  AddAndRegisterDefaultOption("Mapper.init_image_id1",
521  &mapper->init_image_id1);
522  AddAndRegisterDefaultOption("Mapper.init_image_id2",
523  &mapper->init_image_id2);
524  AddAndRegisterDefaultOption("Mapper.init_num_trials",
525  &mapper->init_num_trials);
526  AddAndRegisterDefaultOption("Mapper.extract_colors",
527  &mapper->extract_colors);
528  AddAndRegisterDefaultOption("Mapper.num_threads", &mapper->num_threads);
529  AddAndRegisterDefaultOption("Mapper.min_focal_length_ratio",
530  &mapper->min_focal_length_ratio);
531  AddAndRegisterDefaultOption("Mapper.max_focal_length_ratio",
532  &mapper->max_focal_length_ratio);
533  AddAndRegisterDefaultOption("Mapper.max_extra_param",
534  &mapper->max_extra_param);
535  AddAndRegisterDefaultOption("Mapper.ba_refine_focal_length",
536  &mapper->ba_refine_focal_length);
537  AddAndRegisterDefaultOption("Mapper.ba_refine_principal_point",
538  &mapper->ba_refine_principal_point);
539  AddAndRegisterDefaultOption("Mapper.ba_refine_extra_params",
540  &mapper->ba_refine_extra_params);
541  AddAndRegisterDefaultOption("Mapper.ba_local_num_images",
542  &mapper->ba_local_num_images);
543  AddAndRegisterDefaultOption("Mapper.ba_local_function_tolerance",
544  &mapper->ba_local_function_tolerance);
545  AddAndRegisterDefaultOption("Mapper.ba_local_max_num_iterations",
546  &mapper->ba_local_max_num_iterations);
547 #ifdef PBA_ENABLED
548  AddAndRegisterDefaultOption("Mapper.ba_global_use_pba",
549  &mapper->ba_global_use_pba);
550  AddAndRegisterDefaultOption("Mapper.ba_global_pba_gpu_index",
551  &mapper->ba_global_pba_gpu_index);
552 #endif
553  AddAndRegisterDefaultOption("Mapper.ba_global_images_ratio",
554  &mapper->ba_global_images_ratio);
555  AddAndRegisterDefaultOption("Mapper.ba_global_points_ratio",
556  &mapper->ba_global_points_ratio);
557  AddAndRegisterDefaultOption("Mapper.ba_global_images_freq",
558  &mapper->ba_global_images_freq);
559  AddAndRegisterDefaultOption("Mapper.ba_global_points_freq",
560  &mapper->ba_global_points_freq);
561  AddAndRegisterDefaultOption("Mapper.ba_global_function_tolerance",
562  &mapper->ba_global_function_tolerance);
563  AddAndRegisterDefaultOption("Mapper.ba_global_max_num_iterations",
564  &mapper->ba_global_max_num_iterations);
565  AddAndRegisterDefaultOption("Mapper.ba_global_max_refinements",
566  &mapper->ba_global_max_refinements);
567  AddAndRegisterDefaultOption("Mapper.ba_global_max_refinement_change",
568  &mapper->ba_global_max_refinement_change);
569  AddAndRegisterDefaultOption("Mapper.ba_local_max_refinements",
570  &mapper->ba_local_max_refinements);
571  AddAndRegisterDefaultOption("Mapper.ba_local_max_refinement_change",
572  &mapper->ba_local_max_refinement_change);
573  AddAndRegisterDefaultOption("Mapper.ba_use_gpu", &mapper->ba_use_gpu);
574  AddAndRegisterDefaultOption("Mapper.ba_gpu_index", &mapper->ba_gpu_index);
575  AddAndRegisterDefaultOption(
576  "Mapper.ba_min_num_residuals_for_cpu_multi_threading",
577  &mapper->ba_min_num_residuals_for_cpu_multi_threading);
578  AddAndRegisterDefaultOption("Mapper.snapshot_path", &mapper->snapshot_path);
579  AddAndRegisterDefaultOption("Mapper.snapshot_images_freq",
580  &mapper->snapshot_images_freq);
581  AddAndRegisterDefaultOption("Mapper.fix_existing_images",
582  &mapper->fix_existing_images);
583 
584  // IncrementalMapper.
585  AddAndRegisterDefaultOption("Mapper.init_min_num_inliers",
586  &mapper->mapper.init_min_num_inliers);
587  AddAndRegisterDefaultOption("Mapper.init_max_error",
588  &mapper->mapper.init_max_error);
589  AddAndRegisterDefaultOption("Mapper.init_max_forward_motion",
590  &mapper->mapper.init_max_forward_motion);
591  AddAndRegisterDefaultOption("Mapper.init_min_tri_angle",
592  &mapper->mapper.init_min_tri_angle);
593  AddAndRegisterDefaultOption("Mapper.init_max_reg_trials",
594  &mapper->mapper.init_max_reg_trials);
595  AddAndRegisterDefaultOption("Mapper.abs_pose_max_error",
596  &mapper->mapper.abs_pose_max_error);
597  AddAndRegisterDefaultOption("Mapper.abs_pose_min_num_inliers",
598  &mapper->mapper.abs_pose_min_num_inliers);
599  AddAndRegisterDefaultOption("Mapper.abs_pose_min_inlier_ratio",
600  &mapper->mapper.abs_pose_min_inlier_ratio);
601  AddAndRegisterDefaultOption("Mapper.filter_max_reproj_error",
602  &mapper->mapper.filter_max_reproj_error);
603  AddAndRegisterDefaultOption("Mapper.filter_min_tri_angle",
604  &mapper->mapper.filter_min_tri_angle);
605  AddAndRegisterDefaultOption("Mapper.max_reg_trials",
606  &mapper->mapper.max_reg_trials);
607  AddAndRegisterDefaultOption("Mapper.local_ba_min_tri_angle",
608  &mapper->mapper.local_ba_min_tri_angle);
609 
610  // IncrementalTriangulator.
611  AddAndRegisterDefaultOption("Mapper.tri_max_transitivity",
612  &mapper->triangulation.max_transitivity);
613  AddAndRegisterDefaultOption("Mapper.tri_create_max_angle_error",
614  &mapper->triangulation.create_max_angle_error);
615  AddAndRegisterDefaultOption(
616  "Mapper.tri_continue_max_angle_error",
617  &mapper->triangulation.continue_max_angle_error);
618  AddAndRegisterDefaultOption("Mapper.tri_merge_max_reproj_error",
619  &mapper->triangulation.merge_max_reproj_error);
620  AddAndRegisterDefaultOption(
621  "Mapper.tri_complete_max_reproj_error",
622  &mapper->triangulation.complete_max_reproj_error);
623  AddAndRegisterDefaultOption(
624  "Mapper.tri_complete_max_transitivity",
625  &mapper->triangulation.complete_max_transitivity);
626  AddAndRegisterDefaultOption("Mapper.tri_re_max_angle_error",
627  &mapper->triangulation.re_max_angle_error);
628  AddAndRegisterDefaultOption("Mapper.tri_re_min_ratio",
629  &mapper->triangulation.re_min_ratio);
630  AddAndRegisterDefaultOption("Mapper.tri_re_max_trials",
631  &mapper->triangulation.re_max_trials);
632  AddAndRegisterDefaultOption("Mapper.tri_min_angle",
633  &mapper->triangulation.min_angle);
634  AddAndRegisterDefaultOption("Mapper.tri_ignore_two_view_tracks",
635  &mapper->triangulation.ignore_two_view_tracks);
636 }
637 
639  if (added_patch_match_stereo_options_) {
640  return;
641  }
642  added_patch_match_stereo_options_ = true;
643 
644  AddAndRegisterDefaultOption("PatchMatchStereo.max_image_size",
645  &patch_match_stereo->max_image_size);
646  AddAndRegisterDefaultOption("PatchMatchStereo.gpu_index",
647  &patch_match_stereo->gpu_index);
648  AddAndRegisterDefaultOption("PatchMatchStereo.depth_min",
649  &patch_match_stereo->depth_min);
650  AddAndRegisterDefaultOption("PatchMatchStereo.depth_max",
651  &patch_match_stereo->depth_max);
652  AddAndRegisterDefaultOption("PatchMatchStereo.window_radius",
653  &patch_match_stereo->window_radius);
654  AddAndRegisterDefaultOption("PatchMatchStereo.window_step",
655  &patch_match_stereo->window_step);
656  AddAndRegisterDefaultOption("PatchMatchStereo.sigma_spatial",
657  &patch_match_stereo->sigma_spatial);
658  AddAndRegisterDefaultOption("PatchMatchStereo.sigma_color",
659  &patch_match_stereo->sigma_color);
660  AddAndRegisterDefaultOption("PatchMatchStereo.num_samples",
661  &patch_match_stereo->num_samples);
662  AddAndRegisterDefaultOption("PatchMatchStereo.ncc_sigma",
663  &patch_match_stereo->ncc_sigma);
664  AddAndRegisterDefaultOption("PatchMatchStereo.min_triangulation_angle",
665  &patch_match_stereo->min_triangulation_angle);
666  AddAndRegisterDefaultOption("PatchMatchStereo.incident_angle_sigma",
667  &patch_match_stereo->incident_angle_sigma);
668  AddAndRegisterDefaultOption("PatchMatchStereo.num_iterations",
669  &patch_match_stereo->num_iterations);
670  AddAndRegisterDefaultOption("PatchMatchStereo.geom_consistency",
671  &patch_match_stereo->geom_consistency);
672  AddAndRegisterDefaultOption(
673  "PatchMatchStereo.geom_consistency_regularizer",
674  &patch_match_stereo->geom_consistency_regularizer);
675  AddAndRegisterDefaultOption("PatchMatchStereo.geom_consistency_max_cost",
676  &patch_match_stereo->geom_consistency_max_cost);
677  AddAndRegisterDefaultOption("PatchMatchStereo.filter",
678  &patch_match_stereo->filter);
679  AddAndRegisterDefaultOption("PatchMatchStereo.filter_min_ncc",
680  &patch_match_stereo->filter_min_ncc);
681  AddAndRegisterDefaultOption(
682  "PatchMatchStereo.filter_min_triangulation_angle",
683  &patch_match_stereo->filter_min_triangulation_angle);
684  AddAndRegisterDefaultOption("PatchMatchStereo.filter_min_num_consistent",
685  &patch_match_stereo->filter_min_num_consistent);
686  AddAndRegisterDefaultOption(
687  "PatchMatchStereo.filter_geom_consistency_max_cost",
688  &patch_match_stereo->filter_geom_consistency_max_cost);
689  AddAndRegisterDefaultOption("PatchMatchStereo.cache_size",
690  &patch_match_stereo->cache_size);
691  AddAndRegisterDefaultOption("PatchMatchStereo.allow_missing_files",
692  &patch_match_stereo->allow_missing_files);
693  AddAndRegisterDefaultOption("PatchMatchStereo.write_consistency_graph",
694  &patch_match_stereo->write_consistency_graph);
695 }
696 
698  if (added_stereo_fusion_options_) {
699  return;
700  }
701  added_stereo_fusion_options_ = true;
702 
703  AddAndRegisterDefaultOption("StereoFusion.mask_path",
704  &stereo_fusion->mask_path);
705  AddAndRegisterDefaultOption("StereoFusion.num_threads",
706  &stereo_fusion->num_threads);
707  AddAndRegisterDefaultOption("StereoFusion.max_image_size",
708  &stereo_fusion->max_image_size);
709  AddAndRegisterDefaultOption("StereoFusion.min_num_pixels",
710  &stereo_fusion->min_num_pixels);
711  AddAndRegisterDefaultOption("StereoFusion.max_num_pixels",
712  &stereo_fusion->max_num_pixels);
713  AddAndRegisterDefaultOption("StereoFusion.max_traversal_depth",
714  &stereo_fusion->max_traversal_depth);
715  AddAndRegisterDefaultOption("StereoFusion.max_reproj_error",
716  &stereo_fusion->max_reproj_error);
717  AddAndRegisterDefaultOption("StereoFusion.max_depth_error",
718  &stereo_fusion->max_depth_error);
719  AddAndRegisterDefaultOption("StereoFusion.max_normal_error",
720  &stereo_fusion->max_normal_error);
721  AddAndRegisterDefaultOption("StereoFusion.check_num_images",
722  &stereo_fusion->check_num_images);
723  AddAndRegisterDefaultOption("StereoFusion.cache_size",
724  &stereo_fusion->cache_size);
725  AddAndRegisterDefaultOption("StereoFusion.use_cache",
726  &stereo_fusion->use_cache);
727 }
728 
730  if (added_poisson_meshing_options_) {
731  return;
732  }
733  added_poisson_meshing_options_ = true;
734 
735  AddAndRegisterDefaultOption("PoissonMeshing.point_weight",
736  &poisson_meshing->point_weight);
737  AddAndRegisterDefaultOption("PoissonMeshing.depth",
738  &poisson_meshing->depth);
739  AddAndRegisterDefaultOption("PoissonMeshing.color",
740  &poisson_meshing->color);
741  AddAndRegisterDefaultOption("PoissonMeshing.trim", &poisson_meshing->trim);
742  AddAndRegisterDefaultOption("PoissonMeshing.num_threads",
743  &poisson_meshing->num_threads);
744 }
745 
747  if (added_delaunay_meshing_options_) {
748  return;
749  }
750  added_delaunay_meshing_options_ = true;
751 
752  AddAndRegisterDefaultOption("DelaunayMeshing.max_proj_dist",
753  &delaunay_meshing->max_proj_dist);
754  AddAndRegisterDefaultOption("DelaunayMeshing.max_depth_dist",
755  &delaunay_meshing->max_depth_dist);
756  AddAndRegisterDefaultOption("DelaunayMeshing.visibility_sigma",
757  &delaunay_meshing->visibility_sigma);
758  AddAndRegisterDefaultOption("DelaunayMeshing.distance_sigma_factor",
759  &delaunay_meshing->distance_sigma_factor);
760  AddAndRegisterDefaultOption("DelaunayMeshing.quality_regularization",
761  &delaunay_meshing->quality_regularization);
762  AddAndRegisterDefaultOption("DelaunayMeshing.max_side_length_factor",
763  &delaunay_meshing->max_side_length_factor);
764  AddAndRegisterDefaultOption("DelaunayMeshing.max_side_length_percentile",
765  &delaunay_meshing->max_side_length_percentile);
766  AddAndRegisterDefaultOption("DelaunayMeshing.num_threads",
767  &delaunay_meshing->num_threads);
768 }
769 
771  if (added_render_options_) {
772  return;
773  }
774  added_render_options_ = true;
775 
776  AddAndRegisterDefaultOption("Render.min_track_len", &render->min_track_len);
777  AddAndRegisterDefaultOption("Render.max_error", &render->max_error);
778  AddAndRegisterDefaultOption("Render.refresh_rate", &render->refresh_rate);
779  AddAndRegisterDefaultOption("Render.adapt_refresh_rate",
780  &render->adapt_refresh_rate);
781  AddAndRegisterDefaultOption("Render.image_connections",
782  &render->image_connections);
783  AddAndRegisterDefaultOption("Render.projection_type",
784  &render->projection_type);
785 }
786 
788  FLAGS_logtostderr = false;
789  FLAGS_v = 2;
790 
791  const bool kResetPaths = true;
792  ResetOptions(kResetPaths);
793 
794  desc_.reset(new boost::program_options::options_description());
795 
796  options_bool_.clear();
797  options_int_.clear();
798  options_double_.clear();
799  options_string_.clear();
800 
801  added_log_options_ = false;
802  added_random_options_ = false;
803  added_database_options_ = false;
804  added_image_options_ = false;
805  added_extraction_options_ = false;
806  added_match_options_ = false;
807  added_exhaustive_match_options_ = false;
808  added_sequential_match_options_ = false;
809  added_vocab_tree_match_options_ = false;
810  added_spatial_match_options_ = false;
811  added_transitive_match_options_ = false;
812  added_image_pairs_match_options_ = false;
813  added_ba_options_ = false;
814  added_mapper_options_ = false;
815  added_patch_match_stereo_options_ = false;
816  added_stereo_fusion_options_ = false;
817  added_poisson_meshing_options_ = false;
818  added_delaunay_meshing_options_ = false;
819  added_texturing_options_ = false;
820  added_render_options_ = false;
821 }
822 
823 void OptionManager::ResetOptions(const bool reset_paths) {
824  if (reset_paths) {
825  *project_path = "";
826  *database_path = "";
827  *image_path = "";
828  }
845  *render = RenderOptions();
846 }
847 
849  bool success = true;
850 
851  if (added_database_options_) {
852  const auto database_parent_path = GetParentDir(*database_path);
853  success = success && CHECK_OPTION_IMPL(!ExistsDir(*database_path)) &&
854  CHECK_OPTION_IMPL(database_parent_path == "" ||
855  ExistsDir(database_parent_path));
856  }
857 
858  if (added_image_options_)
859  success = success && CHECK_OPTION_IMPL(ExistsDir(*image_path));
860 
861  if (image_reader) success = success && image_reader->Check();
862  if (sift_extraction) success = success && sift_extraction->Check();
863 
864  if (sift_matching) success = success && sift_matching->Check();
865  if (exhaustive_matching) success = success && exhaustive_matching->Check();
866  if (sequential_matching) success = success && sequential_matching->Check();
867  if (vocab_tree_matching) success = success && vocab_tree_matching->Check();
868  if (spatial_matching) success = success && spatial_matching->Check();
869  if (transitive_matching) success = success && transitive_matching->Check();
871  success = success && image_pairs_matching->Check();
872 
873  if (bundle_adjustment) success = success && bundle_adjustment->Check();
874  if (mapper) success = success && mapper->Check();
875 
876  if (patch_match_stereo) success = success && patch_match_stereo->Check();
877  if (stereo_fusion) success = success && stereo_fusion->Check();
878  if (poisson_meshing) success = success && poisson_meshing->Check();
879  if (delaunay_meshing) success = success && delaunay_meshing->Check();
880 
881 #ifdef GUI_ENABLED
882  if (render) success = success && render->Check();
883 #endif
884 
885  return success;
886 }
887 
888 void OptionManager::Parse(const int argc, char** argv) {
889  config::variables_map vmap;
890 
891  try {
892  config::store(config::parse_command_line(argc, argv, *desc_), vmap);
893 
894  if (vmap.count("help")) {
895  std::cout << StringPrintf("%s (%s)", GetVersionInfo().c_str(),
896  GetBuildInfo().c_str())
897  << std::endl
898  << std::endl;
899  std::cout
900  << "Options can either be specified via command-line or by "
901  "defining"
902  << std::endl
903  << "them in a .ini project file passed to `--project_path`."
904  << std::endl
905  << std::endl;
906  std::cout << *desc_ << std::endl;
907  exit(EXIT_SUCCESS);
908  }
909 
910  if (vmap.count("project_path")) {
911  *project_path = vmap["project_path"].as<std::string>();
912  if (!Read(*project_path)) {
913  exit(EXIT_FAILURE);
914  }
915  } else {
916  vmap.notify();
917  }
918  } catch (std::exception& exc) {
919  std::cerr << "ERROR: Failed to parse options - " << exc.what() << "."
920  << std::endl;
921  exit(EXIT_FAILURE);
922  } catch (...) {
923  std::cerr << "ERROR: Failed to parse options for unknown reason."
924  << std::endl;
925  exit(EXIT_FAILURE);
926  }
927 
928  if (!Check()) {
929  std::cerr << "ERROR: Invalid options provided." << std::endl;
930  exit(EXIT_FAILURE);
931  }
932 }
933 
934 bool OptionManager::Read(const std::string& path) {
935  config::variables_map vmap;
936 
937  if (!ExistsFile(path)) {
938  std::cout << "WARNING: Configuration file does not exist." << std::endl;
939  return false;
940  }
941 
942  try {
943  std::ifstream file(path);
944  CHECK(file.is_open()) << path;
945  config::store(config::parse_config_file(file, *desc_), vmap);
946  vmap.notify();
947  } catch (std::exception& e) {
948  std::cout << "WARNING: Failed to parse options " << e.what() << "."
949  << std::endl;
950  return false;
951  } catch (...) {
952  std::cout << "WARNING: Failed to parse options for unknown reason."
953  << std::endl;
954  return false;
955  }
956 
957  return Check();
958 }
959 
960 bool OptionManager::ReRead(const std::string& path) {
961  Reset();
962  AddAllOptions();
963  return Read(path);
964 }
965 
966 void OptionManager::Write(const std::string& path) const {
967  boost::property_tree::ptree pt;
968 
969  // First, put all options without a section and then those with a section.
970  // This is necessary as otherwise older Boost versions will write the
971  // options without a section in between other sections and therefore
972  // the errors will be assigned to the wrong section if read later.
973 
974  for (const auto& option : options_bool_) {
975  if (!StringContains(option.first, ".")) {
976  pt.put(option.first, *option.second);
977  }
978  }
979 
980  for (const auto& option : options_int_) {
981  if (!StringContains(option.first, ".")) {
982  pt.put(option.first, *option.second);
983  }
984  }
985 
986  for (const auto& option : options_double_) {
987  if (!StringContains(option.first, ".")) {
988  pt.put(option.first, *option.second);
989  }
990  }
991 
992  for (const auto& option : options_string_) {
993  if (!StringContains(option.first, ".")) {
994  pt.put(option.first, *option.second);
995  }
996  }
997 
998  for (const auto& option : options_bool_) {
999  if (StringContains(option.first, ".")) {
1000  pt.put(option.first, *option.second);
1001  }
1002  }
1003 
1004  for (const auto& option : options_int_) {
1005  if (StringContains(option.first, ".")) {
1006  pt.put(option.first, *option.second);
1007  }
1008  }
1009 
1010  for (const auto& option : options_double_) {
1011  if (StringContains(option.first, ".")) {
1012  pt.put(option.first, *option.second);
1013  }
1014  }
1015 
1016  for (const auto& option : options_string_) {
1017  if (StringContains(option.first, ".")) {
1018  pt.put(option.first, *option.second);
1019  }
1020  }
1021 
1022  boost::property_tree::write_ini(path, pt);
1023 }
1024 
1026  if (added_texturing_options_) {
1027  return;
1028  }
1029  added_texturing_options_ = true;
1030 
1031  AddAndRegisterDefaultOption("Texturing.verbose", &texturing->verbose);
1032  AddAndRegisterDefaultOption("Texturing.meshed_file_path",
1033  &texturing->meshed_file_path);
1034  AddAndRegisterDefaultOption("Texturing.textured_file_path",
1035  &texturing->textured_file_path);
1036  AddAndRegisterDefaultOption("Texturing.use_depth_normal_maps",
1037  &texturing->use_depth_normal_maps);
1038  AddAndRegisterDefaultOption("Texturing.depth_map_type",
1039  &texturing->depth_map_type);
1040  AddAndRegisterDefaultOption("Texturing.max_depth_error",
1041  &texturing->max_depth_error);
1042  AddAndRegisterDefaultOption("Texturing.min_normal_consistency",
1043  &texturing->min_normal_consistency);
1044  AddAndRegisterDefaultOption("Texturing.max_viewing_angle_deg",
1045  &texturing->max_viewing_angle_deg);
1046  AddAndRegisterDefaultOption("Texturing.use_gradient_magnitude",
1047  &texturing->use_gradient_magnitude);
1048  AddAndRegisterDefaultOption("Texturing.mesh_source",
1049  &texturing->mesh_source);
1050 }
1051 
1052 } // namespace colmap
std::shared_ptr< SequentialMatchingOptions > sequential_matching
std::shared_ptr< TransitiveMatchingOptions > transitive_matching
OptionManager(bool add_project_options=true)
std::shared_ptr< mvs::PoissonMeshingOptions > poisson_meshing
std::shared_ptr< mvs::DelaunayMeshingOptions > delaunay_meshing
std::shared_ptr< TexturingOptions > texturing
bool Read(const std::string &path)
bool ReRead(const std::string &path)
std::shared_ptr< mvs::PatchMatchOptions > patch_match_stereo
std::shared_ptr< RenderOptions > render
std::shared_ptr< std::string > database_path
std::shared_ptr< mvs::StereoFusionOptions > stereo_fusion
std::shared_ptr< SiftMatchingOptions > sift_matching
std::shared_ptr< BundleAdjustmentOptions > bundle_adjustment
std::shared_ptr< IncrementalMapperOptions > mapper
void ResetOptions(const bool reset_paths)
std::shared_ptr< std::string > project_path
void Write(const std::string &path) const
std::shared_ptr< SiftExtractionOptions > sift_extraction
std::shared_ptr< ImageReaderOptions > image_reader
std::shared_ptr< VocabTreeMatchingOptions > vocab_tree_matching
void Parse(const int argc, char **argv)
std::shared_ptr< ExhaustiveMatchingOptions > exhaustive_matching
std::shared_ptr< SpatialMatchingOptions > spatial_matching
std::shared_ptr< ImagePairsMatchingOptions > image_pairs_matching
std::shared_ptr< std::string > image_path
const double * e
#define CHECK_OPTION_IMPL(expr)
Definition: logging.h:18
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
static const std::string path
Definition: PointCloud.cpp:59
colmap::IncrementalMapperOptions IncrementalMapperOptions
colmap::RenderOptions RenderOptions
static int kDefaultPRNGSeed
Definition: random.h:21
std::string GetBuildInfo()
Definition: version.cc:40
std::string GetVersionInfo()
Definition: version.cc:36
bool ExistsDir(const std::string &path)
Definition: misc.cc:104
bool ExistsFile(const std::string &path)
Definition: misc.cc:100
std::string StringPrintf(const char *format,...)
Definition: string.cc:131
std::string GetParentDir(const std::string &path)
Definition: misc.cc:128
bool StringContains(const std::string &str, const std::string &sub_str)
Definition: string.cc:201