| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "exe/feature.h" |
| |
|
| | #include "base/camera_models.h" |
| | #include "base/image_reader.h" |
| | #include "exe/gui.h" |
| | #include "feature/extraction.h" |
| | #include "feature/matching.h" |
| | #include "util/misc.h" |
| | #include "util/opengl_utils.h" |
| | #include "util/option_manager.h" |
| |
|
| | namespace colmap { |
| | namespace { |
| |
|
| | bool VerifyCameraParams(const std::string& camera_model, |
| | const std::string& params) { |
| | if (!ExistsCameraModelWithName(camera_model)) { |
| | std::cerr << "ERROR: Camera model does not exist" << std::endl; |
| | return false; |
| | } |
| |
|
| | const std::vector<double> camera_params = CSVToVector<double>(params); |
| | const int camera_model_id = CameraModelNameToId(camera_model); |
| |
|
| | if (camera_params.size() > 0 && |
| | !CameraModelVerifyParams(camera_model_id, camera_params)) { |
| | std::cerr << "ERROR: Invalid camera parameters" << std::endl; |
| | return false; |
| | } |
| | return true; |
| | } |
| |
|
| | bool VerifySiftGPUParams(const bool use_gpu) { |
| | #if !defined(CUDA_ENABLED) && !defined(OPENGL_ENABLED) |
| | if (use_gpu) { |
| | std::cerr << "ERROR: Cannot use Sift GPU without CUDA or OpenGL support; " |
| | "set SiftExtraction.use_gpu or SiftMatching.use_gpu to false." |
| | << std::endl; |
| | return false; |
| | } |
| | #endif |
| | return true; |
| | } |
| |
|
| | } |
| |
|
| | void UpdateImageReaderOptionsFromCameraMode(ImageReaderOptions& options, |
| | CameraMode mode) { |
| | switch (mode) { |
| | case CameraMode::AUTO: |
| | options.single_camera = false; |
| | options.single_camera_per_folder = false; |
| | options.single_camera_per_image = false; |
| | break; |
| | case CameraMode::SINGLE: |
| | options.single_camera = true; |
| | options.single_camera_per_folder = false; |
| | options.single_camera_per_image = false; |
| | break; |
| | case CameraMode::PER_FOLDER: |
| | options.single_camera = false; |
| | options.single_camera_per_folder = true; |
| | options.single_camera_per_image = false; |
| | break; |
| | case CameraMode::PER_IMAGE: |
| | options.single_camera = false; |
| | options.single_camera_per_folder = false; |
| | options.single_camera_per_image = true; |
| | break; |
| | } |
| | } |
| |
|
| | int RunFeatureExtractor(int argc, char** argv) { |
| | std::string image_list_path; |
| | int camera_mode = -1; |
| | std::string descriptor_normalization = "l1_root"; |
| |
|
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddImageOptions(); |
| | options.AddDefaultOption("camera_mode", &camera_mode); |
| | options.AddDefaultOption("image_list_path", &image_list_path); |
| | options.AddDefaultOption("descriptor_normalization", &descriptor_normalization, |
| | "{'l1_root', 'l2'}"); |
| | options.AddExtractionOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | ImageReaderOptions reader_options = *options.image_reader; |
| | reader_options.database_path = *options.database_path; |
| | reader_options.image_path = *options.image_path; |
| |
|
| | if (camera_mode >= 0) { |
| | UpdateImageReaderOptionsFromCameraMode(reader_options, |
| | (CameraMode)camera_mode); |
| | } |
| |
|
| | StringToLower(&descriptor_normalization); |
| | if (descriptor_normalization == "l1_root") { |
| | options.sift_extraction->normalization = |
| | SiftExtractionOptions::Normalization::L1_ROOT; |
| | } else if (descriptor_normalization == "l2") { |
| | options.sift_extraction->normalization = |
| | SiftExtractionOptions::Normalization::L2; |
| | } else { |
| | std::cerr << "ERROR: Invalid `descriptor_normalization`" |
| | << std::endl; |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | if (!image_list_path.empty()) { |
| | reader_options.image_list = ReadTextFileLines(image_list_path); |
| | if (reader_options.image_list.empty()) { |
| | return EXIT_SUCCESS; |
| | } |
| | } |
| |
|
| | if (!ExistsCameraModelWithName(reader_options.camera_model)) { |
| | std::cerr << "ERROR: Camera model does not exist" << std::endl; |
| | } |
| |
|
| | if (!VerifyCameraParams(reader_options.camera_model, |
| | reader_options.camera_params)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | if (!VerifySiftGPUParams(options.sift_extraction->use_gpu)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | std::unique_ptr<QApplication> app; |
| | if (options.sift_extraction->use_gpu && kUseOpenGL) { |
| | app.reset(new QApplication(argc, argv)); |
| | } |
| |
|
| | SiftFeatureExtractor feature_extractor(reader_options, |
| | *options.sift_extraction); |
| |
|
| | if (options.sift_extraction->use_gpu && kUseOpenGL) { |
| | RunThreadWithOpenGLContext(&feature_extractor); |
| | } else { |
| | feature_extractor.Start(); |
| | feature_extractor.Wait(); |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunFeatureImporter(int argc, char** argv) { |
| | std::string import_path; |
| | std::string image_list_path; |
| | int camera_mode = -1; |
| |
|
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddImageOptions(); |
| | options.AddDefaultOption("camera_mode", &camera_mode); |
| | options.AddRequiredOption("import_path", &import_path); |
| | options.AddDefaultOption("image_list_path", &image_list_path); |
| | options.AddExtractionOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | ImageReaderOptions reader_options = *options.image_reader; |
| | reader_options.database_path = *options.database_path; |
| | reader_options.image_path = *options.image_path; |
| |
|
| | if (camera_mode >= 0) { |
| | UpdateImageReaderOptionsFromCameraMode(reader_options, |
| | (CameraMode)camera_mode); |
| | } |
| |
|
| | if (!image_list_path.empty()) { |
| | reader_options.image_list = ReadTextFileLines(image_list_path); |
| | if (reader_options.image_list.empty()) { |
| | return EXIT_SUCCESS; |
| | } |
| | } |
| |
|
| | if (!VerifyCameraParams(reader_options.camera_model, |
| | reader_options.camera_params)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | FeatureImporter feature_importer(reader_options, import_path); |
| | feature_importer.Start(); |
| | feature_importer.Wait(); |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunExhaustiveMatcher(int argc, char** argv) { |
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddExhaustiveMatchingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | if (!VerifySiftGPUParams(options.sift_matching->use_gpu)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | std::unique_ptr<QApplication> app; |
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | app.reset(new QApplication(argc, argv)); |
| | } |
| |
|
| | ExhaustiveFeatureMatcher feature_matcher(*options.exhaustive_matching, |
| | *options.sift_matching, |
| | *options.database_path); |
| |
|
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | RunThreadWithOpenGLContext(&feature_matcher); |
| | } else { |
| | feature_matcher.Start(); |
| | feature_matcher.Wait(); |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunMatchesImporter(int argc, char** argv) { |
| | std::string match_list_path; |
| | std::string match_type = "pairs"; |
| |
|
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddRequiredOption("match_list_path", &match_list_path); |
| | options.AddDefaultOption("match_type", &match_type, |
| | "{'pairs', 'raw', 'inliers'}"); |
| | options.AddMatchingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | if (!VerifySiftGPUParams(options.sift_matching->use_gpu)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | std::unique_ptr<QApplication> app; |
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | app.reset(new QApplication(argc, argv)); |
| | } |
| |
|
| | std::unique_ptr<Thread> feature_matcher; |
| | if (match_type == "pairs") { |
| | ImagePairsMatchingOptions matcher_options; |
| | matcher_options.match_list_path = match_list_path; |
| | feature_matcher.reset(new ImagePairsFeatureMatcher( |
| | matcher_options, *options.sift_matching, *options.database_path)); |
| | } else if (match_type == "raw" || match_type == "inliers") { |
| | FeaturePairsMatchingOptions matcher_options; |
| | matcher_options.match_list_path = match_list_path; |
| | matcher_options.verify_matches = match_type == "raw"; |
| | feature_matcher.reset(new FeaturePairsFeatureMatcher( |
| | matcher_options, *options.sift_matching, *options.database_path)); |
| | } else { |
| | std::cerr << "ERROR: Invalid `match_type`"; |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | RunThreadWithOpenGLContext(feature_matcher.get()); |
| | } else { |
| | feature_matcher->Start(); |
| | feature_matcher->Wait(); |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunSequentialMatcher(int argc, char** argv) { |
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddSequentialMatchingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | if (!VerifySiftGPUParams(options.sift_matching->use_gpu)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | std::unique_ptr<QApplication> app; |
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | app.reset(new QApplication(argc, argv)); |
| | } |
| |
|
| | SequentialFeatureMatcher feature_matcher(*options.sequential_matching, |
| | *options.sift_matching, |
| | *options.database_path); |
| |
|
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | RunThreadWithOpenGLContext(&feature_matcher); |
| | } else { |
| | feature_matcher.Start(); |
| | feature_matcher.Wait(); |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunSpatialMatcher(int argc, char** argv) { |
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddSpatialMatchingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | if (!VerifySiftGPUParams(options.sift_matching->use_gpu)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | std::unique_ptr<QApplication> app; |
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | app.reset(new QApplication(argc, argv)); |
| | } |
| |
|
| | SpatialFeatureMatcher feature_matcher(*options.spatial_matching, |
| | *options.sift_matching, |
| | *options.database_path); |
| |
|
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | RunThreadWithOpenGLContext(&feature_matcher); |
| | } else { |
| | feature_matcher.Start(); |
| | feature_matcher.Wait(); |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunTransitiveMatcher(int argc, char** argv) { |
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddTransitiveMatchingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | if (!VerifySiftGPUParams(options.sift_matching->use_gpu)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | std::unique_ptr<QApplication> app; |
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | app.reset(new QApplication(argc, argv)); |
| | } |
| |
|
| | TransitiveFeatureMatcher feature_matcher(*options.transitive_matching, |
| | *options.sift_matching, |
| | *options.database_path); |
| |
|
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | RunThreadWithOpenGLContext(&feature_matcher); |
| | } else { |
| | feature_matcher.Start(); |
| | feature_matcher.Wait(); |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunVocabTreeMatcher(int argc, char** argv) { |
| | OptionManager options; |
| | options.AddDatabaseOptions(); |
| | options.AddVocabTreeMatchingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | if (!VerifySiftGPUParams(options.sift_matching->use_gpu)) { |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | std::unique_ptr<QApplication> app; |
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | app.reset(new QApplication(argc, argv)); |
| | } |
| |
|
| | VocabTreeFeatureMatcher feature_matcher(*options.vocab_tree_matching, |
| | *options.sift_matching, |
| | *options.database_path); |
| |
|
| | if (options.sift_matching->use_gpu && kUseOpenGL) { |
| | RunThreadWithOpenGLContext(&feature_matcher); |
| | } else { |
| | feature_matcher.Start(); |
| | feature_matcher.Wait(); |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | } |
| |
|