Skip to content

Commit

Permalink
Refactor the option manager
Browse files Browse the repository at this point in the history
  • Loading branch information
ahojnnes committed Apr 21, 2017
1 parent 2789ca2 commit adc23ae
Show file tree
Hide file tree
Showing 76 changed files with 1,780 additions and 2,345 deletions.
88 changes: 45 additions & 43 deletions doc/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,42 @@ Then, an exemplary sequence of commands to reconstruct the scene would be::
PROJECT_PATH=/path/to/project

$ ./src/exe/feature_extractor \
--General.database_path $PROJECT_PATH/database.db \
--General.image_path $PROJECT_PATH/images
--database_path $PROJECT_PATH/database.db \
--image_path $PROJECT_PATH/images

$ ./src/exe/exhaustive_matcher \
--General.database_path $PROJECT_PATH/database.db
--database_path $PROJECT_PATH/database.db

$ mkdir $PROJECT_PATH/sparse

$ ./src/exe/mapper \
--General.database_path $PROJECT_PATH/database.db \
--General.image_path $PROJECT_PATH/images \
--database_path $PROJECT_PATH/database.db \
--image_path $PROJECT_PATH/images \
--export_path $PROJECT_PATH/sparse

$ mkdir $PROJECT_PATH/dense

$ ./src/exe/image_undistorter \
--General.image_path $PROJECT_PATH/images \
--image_path $PROJECT_PATH/images \
--input_path $PROJECT_PATH/sparse/0 \
--output_path $PROJECT_PATH/dense \
--output_type COLMAP \
--max_image_size 2000

$ ./src/exe/dense_mapper \
$ ./src/exe/dense_stereo \
--workspace_path $PROJECT_PATH/dense \
--workspace_format COLMAP \
--DenseMapperOptions.max_image_size 0 \
--DenseMapperOptions.patch_match_filter false \
--DenseMapperOptions.patch_match_geom_consistency false \
--DenseMapperOptions.patch_match_num_iterations 4
--DenseStereo.max_image_size 0 \
--DenseStereo.filter false \
--DenseStereo.geom_consistency false \
--DenseStereo.num_iterations 4

$ ./exe/dense_mapper \
$ ./exe/dense_stereo \
--workspace_path $PROJECT_PATH/dense \
--workspace_format COLMAP \
--DenseMapperOptions.max_image_size 0 \
--DenseMapperOptions.patch_match_filter true \
--DenseMapperOptions.patch_match_geom_consistency true
--DenseStereo.max_image_size 0 \
--DenseStereo.filter true \
--DenseStereo.geom_consistency true

$ ./exe/dense_fuser \
--workspace_path $PROJECT_PATH/dense \
Expand All @@ -74,9 +74,9 @@ Then, an exemplary sequence of commands to reconstruct the scene would be::

If you want to run COLMAP on a computer (e.g., cluster or cloud service) without
an attached display, you should run the ``feature_extractor`` and set the
``--ExtractionOptions.gpu_index 0`` explicitly if a CUDA device is available or
with the option ``--use_gpu false``. Then, you should run the ``*_matcher`` with
``--gpu_index 0`` if a CUDA device is available or with ``--use_gpu false`` for
``--SiftGPUExtraction.index 0`` explicitly if a CUDA device is available or with
the option ``--use_gpu false``. Then, you should run the ``*_matcher`` with
``--use_gpu true`` if a CUDA device is available or with ``--use_gpu false`` for
CPU-based feature matching.

Help
Expand All @@ -87,30 +87,32 @@ the available options, e.g.::

$ ./src/exe/feature_extractor -h

-h [ --help ] Configuration can either be specified
via command_line or by defining the
parameters in a .ini project_file (see
`--project_path`).
--project_path arg
--General.debug_log_to_stderr arg (=0)
--General.debug_log_level arg (=2)
--General.database_path arg
--General.image_path arg
--ExtractionOptions.camera_model arg (=SIMPLE_RADIAL)
--ExtractionOptions.single_camera arg (=0)
--ExtractionOptions.camera_params arg
--ExtractionOptions.default_focal_length_factor arg (=1.2)
--ExtractionOptions.sift_options_max_image_size arg (=3200)
--ExtractionOptions.sift_options_max_num_features arg (=8192)
--ExtractionOptions.sift_options_first_octave arg (=-1)
--ExtractionOptions.sift_options_octave_resolution arg (=3)
--ExtractionOptions.sift_options_peak_threshold arg (=0.0066666666666666671)
--ExtractionOptions.sift_options_edge_threshold arg (=10)
--ExtractionOptions.sift_options_max_num_orientations arg (=2)
--ExtractionOptions.sift_options_upright arg (=0)
--ExtractionOptions.cpu_options_batch_size_factor arg (=3)
--ExtractionOptions.cpu_options_num_threads arg (=-1)
--use_gpu arg (=1)
Options can either be specified via command-line or by defining
them in a .ini project file passed to `--project_path`.

-h [ --help ]
--project_path arg
--log_to_stderr arg (=0)
--log_level arg (=2)
--database_path arg
--image_path arg
--use_gpu arg (=1)
--image_list_path arg
--ImageReader.camera_model arg (=SIMPLE_RADIAL)
--ImageReader.single_camera arg (=0)
--ImageReader.camera_params arg
--ImageReader.default_focal_length_factor arg (=1.2)
--SiftExtraction.max_image_size arg (=3200)
--SiftExtraction.max_num_features arg (=8192)
--SiftExtraction.first_octave arg (=-1)
--SiftExtraction.octave_resolution arg (=3)
--SiftExtraction.peak_threshold arg (=0.0066666666666666671)
--SiftExtraction.edge_threshold arg (=10)
--SiftExtraction.max_num_orientations arg (=2)
--SiftExtraction.upright arg (=0)
--SiftCPUExtraction.batch_size_factor arg (=3)
--SiftCPUExtraction.num_threads arg (=-1)
--SiftGPUExtraction.index arg (=-1)


The available options can either be provided directly from the command-line or
Expand Down Expand Up @@ -139,7 +141,7 @@ Executables
- ``image_rectifier``: Stereo rectify cameras and undistort images for stereo
disparity estimation.

- ``dense_mapper``: Dense 3D reconstruction / mapping using MVS after running
- ``dense_stereo``: Dense 3D reconstruction / mapping using MVS after running
the ``image_undistorter`` to initialize the workspace.

- ``dense_fuser``: Fusion of MVS depth and normal maps to a colored point cloud.
Expand Down
35 changes: 17 additions & 18 deletions doc/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,18 @@ If you have an existing reconstruction of images and want to register/localize
new images within this reconstruction, you can follow these steps::

./src/exe/feature_extractor \
--General.database_path $PROJECT_PATH/database.db \
--General.image_path $PROJECT_PATH/images \
--database_path $PROJECT_PATH/database.db \
--image_path $PROJECT_PATH/images \
--image_list_path /path/to/image-list.txt

./src/exe/vocab_tree_matcher \
--General.database_path $PROJECT_PATH/database.db \
--VocabTreeMatchOptions.vocab_tree_path /path/to/vocab-tree.bin \
--VocabTreeMatchOptions.match_list_path /path/to/image-list.txt
--database_path $PROJECT_PATH/database.db \
--VocabTreeMatching.vocab_tree_path /path/to/vocab-tree.bin \
--VocabTreeMatching.match_list_path /path/to/image-list.txt

./src/exe/image_registrator \
--General.database_path $PROJECT_PATH/database.db \
--General.image_path $PROJECT_PATH/images \
--database_path $PROJECT_PATH/database.db \
--image_path $PROJECT_PATH/images \
--import_path /path/to/existing-model \
--export_path /path/to/model-with-new-images

Expand All @@ -145,7 +145,7 @@ Multi-GPU support in feature matching
-------------------------------------

You can run feature matching on multiple GPUs by specifying multiple indices for
CUDA-enabled GPUs, e.g., ``--MatchOptions.gpu_index=0,1,2,3`` runs the feature
CUDA-enabled GPUs, e.g., ``--SiftMatching.gpu_index=0,1,2,3`` runs the feature
matching on 4 GPUs in parallel. By default, COLMAP runs feature matching on all
CUDA-enabled GPUs.

Expand All @@ -158,7 +158,7 @@ If you encounter the following error message::
MultiplyDescriptor: an illegal memory access was encountered

during feature matching, your GPU runs out of memory. Try decreasing the option
``--MatchOptions.max_num_matches`` until the error disappears. Note that this
``--SiftMatching.max_num_matches`` until the error disappears. Note that this
might lead to inferior feature matching results, since the lower-scale input
features will be clamped in order to fit them into GPU memory. Alternatively,
you could change to CPU-based feature matching, but this can become very slow,
Expand All @@ -169,13 +169,13 @@ Trading off completeness and accuracy in dense reconstruction
-------------------------------------------------------------

If the dense point cloud contains too many outliers and too much noise, try to
increase the value of option ``--DenseMapperOptions.fusion_min_num_pixels``.
increase the value of option ``--DenseFusion.min_num_pixels``.

If the reconstructed dense surface mesh model contains no surface or there are
too many outlier surfaces, you should reduce the value of option
``--DenseMapperOptions.poisson_trim`` to decrease the surface are and vice versa
to increase it. Also consider to try the reduce the outliers or increase the
completeness in the fusion stage, as described above.
``--DenseMeshing.trim`` to decrease the surface are and vice versa to increase
it. Also consider to try the reduce the outliers or increase the completeness in
the fusion stage, as described above.


.. _faq-dense-memory:
Expand All @@ -190,8 +190,8 @@ the number of source images in the ``stereo/patch- match.cfg`` file from e.g.
``geom_consistency`` option increases the required GPU memory.

If you run out of CPU memory during stereo fusion, you can reduce the
``--DenseMapperOptions.fusion_cache_size``. Note that a too low value might lead
to very slow fusion and heavy load on the hard disk.
``--DenseFusion.cache_size``. Note that a too low value might lead to very slow
fusion and heavy load on the hard disk.

For large-scale reconstructions of several thousands of images, you should
consider splitting your sparse reconstruction into more manageable clusters of
Expand Down Expand Up @@ -228,8 +228,7 @@ Multi-GPU support in dense reconstruction
-----------------------------------------

You can run dense reconstruction on multiple GPUs by specifying multiple indices
for CUDA-enabled GPUs, e.g.,
``--DenseMapperOptions.patch_match_gpu_index=0,1,2,3`` runs the dense
for CUDA-enabled GPUs, e.g., ``--DenseStereo.gpu_index=0,1,2,3`` runs the dense
reconstruction on 4 GPUs in parallel. By default, COLMAP runs dense
reconstruction on all CUDA-enabled GPUs.

Expand Down Expand Up @@ -263,7 +262,7 @@ command-line. Under Ubuntu, you could first stop X using::

And then run the dense reconstruction code from the command-line::

./src/exe/dense_mapper ...
./src/exe/dense_stereo ...

Finally, you can restart your desktop environment with the following command::

Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ set(COLMAP_LIBRARIES
mvs
sfm
base
ui
util
estimators
base
Expand Down
80 changes: 44 additions & 36 deletions src/base/feature_extraction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,30 @@ void ScaleBitmap(const int max_image_size, double* scale_x, double* scale_y,

} // namespace

void SiftOptions::Check() const {
CHECK_GT(max_image_size, 0);
CHECK_GT(max_num_features, 0);
CHECK_GT(octave_resolution, 0);
CHECK_GT(peak_threshold, 0.0);
CHECK_GT(edge_threshold, 0.0);
CHECK_GT(max_num_orientations, 0);
bool SiftExtractionOptions::Check() const {
CHECK_OPTION_GT(max_image_size, 0);
CHECK_OPTION_GT(max_num_features, 0);
CHECK_OPTION_GT(octave_resolution, 0);
CHECK_OPTION_GT(peak_threshold, 0.0);
CHECK_OPTION_GT(edge_threshold, 0.0);
CHECK_OPTION_GT(max_num_orientations, 0);
return true;
}

void ImageReader::Options::Check() const {
CHECK_GT(default_focal_length_factor, 0.0);
bool ImageReader::Options::Check() const {
CHECK_OPTION_GT(default_focal_length_factor, 0.0);
const int model_id = CameraModelNameToId(camera_model);
CHECK_NE(model_id, -1);
CHECK_OPTION_NE(model_id, -1);
if (!camera_params.empty()) {
CHECK(
CHECK_OPTION(
CameraModelVerifyParams(model_id, CSVToVector<double>(camera_params)));
}
return true;
}

ImageReader::ImageReader(const Options& options)
: options_(options), image_index_(0) {
options_.Check();
CHECK(options_.Check());

// Ensure trailing slash, so that we can build the correct image name.
options_.image_path =
Expand Down Expand Up @@ -262,17 +264,18 @@ size_t ImageReader::NextIndex() const { return image_index_; }
size_t ImageReader::NumImages() const { return options_.image_list.size(); }

SiftCPUFeatureExtractor::SiftCPUFeatureExtractor(
const ImageReader::Options& reader_options, const SiftOptions& sift_options,
const Options& cpu_options)
const ImageReader::Options& reader_options,
const SiftExtractionOptions& sift_options, const Options& cpu_options)
: reader_options_(reader_options),
sift_options_(sift_options),
cpu_options_(cpu_options) {
sift_options_.Check();
cpu_options_.Check();
CHECK(sift_options_.Check());
CHECK(cpu_options_.Check());
}

void SiftCPUFeatureExtractor::Options::Check() const {
CHECK_GT(batch_size_factor, 0);
bool SiftCPUFeatureExtractor::Options::Check() const {
CHECK_OPTION_GT(batch_size_factor, 0);
return true;
}

void SiftCPUFeatureExtractor::Run() {
Expand Down Expand Up @@ -364,16 +367,19 @@ void SiftCPUFeatureExtractor::Run() {
GetTimer().PrintMinutes();
}

void SiftGPUFeatureExtractor::Options::Check() const { CHECK_GE(index, -1); }
bool SiftGPUFeatureExtractor::Options::Check() const {
CHECK_OPTION_GE(index, -1);
return true;
}

SiftGPUFeatureExtractor::SiftGPUFeatureExtractor(
const ImageReader::Options& reader_options, const SiftOptions& sift_options,
const Options& gpu_options)
const ImageReader::Options& reader_options,
const SiftExtractionOptions& sift_options, const Options& gpu_options)
: reader_options_(reader_options),
sift_options_(sift_options),
gpu_options_(gpu_options) {
sift_options_.Check();
gpu_options_.Check();
CHECK(sift_options_.Check());
CHECK(gpu_options_.Check());

// Create an OpenGL context.
if (gpu_options_.index < 0) {
Expand Down Expand Up @@ -504,10 +510,10 @@ void FeatureImporter::Run() {
GetTimer().PrintMinutes();
}

bool ExtractSiftFeaturesCPU(const SiftOptions& options, const Bitmap& bitmap,
FeatureKeypoints* keypoints,
bool ExtractSiftFeaturesCPU(const SiftExtractionOptions& options,
const Bitmap& bitmap, FeatureKeypoints* keypoints,
FeatureDescriptors* descriptors) {
options.Check();
CHECK(options.Check());
CHECK(bitmap.IsGrey());
CHECK_NOTNULL(keypoints);
CHECK_NOTNULL(descriptors);
Expand Down Expand Up @@ -626,10 +632,10 @@ bool ExtractSiftFeaturesCPU(const SiftOptions& options, const Bitmap& bitmap,
Eigen::MatrixXf desc(1, 128);
vl_sift_calc_keypoint_descriptor(sift.get(), desc.data(),
&vl_keypoints[i], angles[o]);
if (options.normalization == SiftOptions::Normalization::L2) {
if (options.normalization == SiftExtractionOptions::Normalization::L2) {
desc = L2NormalizeFeatureDescriptors(desc);
} else if (options.normalization ==
SiftOptions::Normalization::L1_ROOT) {
SiftExtractionOptions::Normalization::L1_ROOT) {
desc = L1RootNormalizeFeatureDescriptors(desc);
}
level_descriptors.back().row(level_idx) =
Expand Down Expand Up @@ -672,9 +678,9 @@ bool ExtractSiftFeaturesCPU(const SiftOptions& options, const Bitmap& bitmap,
return true;
}

bool CreateSiftGPUExtractor(const SiftOptions& options, const int gpu_index,
SiftGPU* sift_gpu) {
options.Check();
bool CreateSiftGPUExtractor(const SiftExtractionOptions& options,
const int gpu_index, SiftGPU* sift_gpu) {
CHECK(options.Check());
CHECK_GE(gpu_index, -1);
CHECK_NOTNULL(sift_gpu);

Expand Down Expand Up @@ -749,10 +755,11 @@ bool CreateSiftGPUExtractor(const SiftOptions& options, const int gpu_index,
return sift_gpu->VerifyContextGL() == SiftGPU::SIFTGPU_FULL_SUPPORTED;
}

bool ExtractSiftFeaturesGPU(const SiftOptions& options, const Bitmap& bitmap,
SiftGPU* sift_gpu, FeatureKeypoints* keypoints,
bool ExtractSiftFeaturesGPU(const SiftExtractionOptions& options,
const Bitmap& bitmap, SiftGPU* sift_gpu,
FeatureKeypoints* keypoints,
FeatureDescriptors* descriptors) {
options.Check();
CHECK(options.Check());
CHECK(bitmap.IsGrey());
CHECK_NOTNULL(keypoints);
CHECK_NOTNULL(descriptors);
Expand Down Expand Up @@ -813,9 +820,10 @@ bool ExtractSiftFeaturesGPU(const SiftOptions& options, const Bitmap& bitmap,
}

// Save and normalize the descriptors.
if (options.normalization == SiftOptions::Normalization::L2) {
if (options.normalization == SiftExtractionOptions::Normalization::L2) {
descriptors_float = L2NormalizeFeatureDescriptors(descriptors_float);
} else if (options.normalization == SiftOptions::Normalization::L1_ROOT) {
} else if (options.normalization ==
SiftExtractionOptions::Normalization::L1_ROOT) {
descriptors_float = L1RootNormalizeFeatureDescriptors(descriptors_float);
}
*descriptors = FeatureDescriptorsToUnsignedByte(descriptors_float);
Expand Down
Loading

0 comments on commit adc23ae

Please sign in to comment.