| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "exe/mvs.h" |
| |
|
| | #include "base/reconstruction.h" |
| | #include "mvs/fusion.h" |
| | #include "mvs/meshing.h" |
| | #include "mvs/patch_match.h" |
| | #include "util/misc.h" |
| | #include "util/option_manager.h" |
| |
|
| | namespace colmap { |
| |
|
| | int RunDelaunayMesher(int argc, char** argv) { |
| | #ifndef CGAL_ENABLED |
| | std::cerr << "ERROR: Delaunay meshing requires CGAL, which is not " |
| | "available on your system." |
| | << std::endl; |
| | return EXIT_FAILURE; |
| | #else |
| | std::string input_path; |
| | std::string input_type = "dense"; |
| | std::string output_path; |
| |
|
| | OptionManager options; |
| | options.AddRequiredOption( |
| | "input_path", &input_path, |
| | "Path to either the dense workspace folder or the sparse reconstruction"); |
| | options.AddDefaultOption("input_type", &input_type, "{dense, sparse}"); |
| | options.AddRequiredOption("output_path", &output_path); |
| | options.AddDelaunayMeshingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | StringToLower(&input_type); |
| | if (input_type == "sparse") { |
| | mvs::SparseDelaunayMeshing(*options.delaunay_meshing, input_path, |
| | output_path); |
| | } else if (input_type == "dense") { |
| | mvs::DenseDelaunayMeshing(*options.delaunay_meshing, input_path, |
| | output_path); |
| | } else { |
| | std::cout << "ERROR: Invalid input type - " |
| | "supported values are 'sparse' and 'dense'." |
| | << std::endl; |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | #endif |
| | } |
| |
|
| | int RunPatchMatchStereo(int argc, char** argv) { |
| | #ifndef CUDA_ENABLED |
| | std::cerr << "ERROR: Dense stereo reconstruction requires CUDA, which is not " |
| | "available on your system." |
| | << std::endl; |
| | return EXIT_FAILURE; |
| | #else |
| | std::string workspace_path; |
| | std::string workspace_format = "COLMAP"; |
| | std::string pmvs_option_name = "option-all"; |
| | std::string config_path; |
| |
|
| | OptionManager options; |
| | options.AddRequiredOption( |
| | "workspace_path", &workspace_path, |
| | "Path to the folder containing the undistorted images"); |
| | options.AddDefaultOption("workspace_format", &workspace_format, |
| | "{COLMAP, PMVS}"); |
| | options.AddDefaultOption("pmvs_option_name", &pmvs_option_name); |
| | options.AddDefaultOption("config_path", &config_path); |
| | options.AddPatchMatchStereoOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | StringToLower(&workspace_format); |
| | if (workspace_format != "colmap" && workspace_format != "pmvs") { |
| | std::cout << "ERROR: Invalid `workspace_format` - supported values are " |
| | "'COLMAP' or 'PMVS'." |
| | << std::endl; |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | mvs::PatchMatchController controller(*options.patch_match_stereo, |
| | workspace_path, workspace_format, |
| | pmvs_option_name, config_path); |
| |
|
| | controller.Start(); |
| | controller.Wait(); |
| |
|
| | return EXIT_SUCCESS; |
| | #endif |
| | } |
| |
|
| | int RunPoissonMesher(int argc, char** argv) { |
| | std::string input_path; |
| | std::string output_path; |
| |
|
| | OptionManager options; |
| | options.AddRequiredOption("input_path", &input_path); |
| | options.AddRequiredOption("output_path", &output_path); |
| | options.AddPoissonMeshingOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | CHECK(mvs::PoissonMeshing(*options.poisson_meshing, input_path, output_path)); |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | int RunStereoFuser(int argc, char** argv) { |
| | std::string workspace_path; |
| | std::string input_type = "geometric"; |
| | std::string workspace_format = "COLMAP"; |
| | std::string pmvs_option_name = "option-all"; |
| | std::string output_type = "PLY"; |
| | std::string output_path; |
| | std::string bbox_path; |
| |
|
| | OptionManager options; |
| | options.AddRequiredOption("workspace_path", &workspace_path); |
| | options.AddDefaultOption("workspace_format", &workspace_format, |
| | "{COLMAP, PMVS}"); |
| | options.AddDefaultOption("pmvs_option_name", &pmvs_option_name); |
| | options.AddDefaultOption("input_type", &input_type, |
| | "{photometric, geometric}"); |
| | options.AddDefaultOption("output_type", &output_type, "{BIN, TXT, PLY}"); |
| | options.AddRequiredOption("output_path", &output_path); |
| | options.AddDefaultOption("bbox_path", &bbox_path); |
| | options.AddStereoFusionOptions(); |
| | options.Parse(argc, argv); |
| |
|
| | StringToLower(&workspace_format); |
| | if (workspace_format != "colmap" && workspace_format != "pmvs") { |
| | std::cout << "ERROR: Invalid `workspace_format` - supported values are " |
| | "'COLMAP' or 'PMVS'." |
| | << std::endl; |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | StringToLower(&input_type); |
| | if (input_type != "photometric" && input_type != "geometric") { |
| | std::cout << "ERROR: Invalid input type - supported values are " |
| | "'photometric' and 'geometric'." |
| | << std::endl; |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | if (!bbox_path.empty()) { |
| | std::ifstream file(bbox_path); |
| | if (file.is_open()) { |
| | auto& min_bound = options.stereo_fusion->bounding_box.first; |
| | auto& max_bound = options.stereo_fusion->bounding_box.second; |
| | file >> min_bound(0) >> min_bound(1) >> min_bound(2); |
| | file >> max_bound(0) >> max_bound(1) >> max_bound(2); |
| | } else { |
| | std::cout << "WARN: Invalid bounds path: \"" << bbox_path |
| | << "\" - continuing without bounds check" << std::endl; |
| | } |
| | } |
| |
|
| | mvs::StereoFusion fuser(*options.stereo_fusion, workspace_path, |
| | workspace_format, pmvs_option_name, input_type); |
| |
|
| | fuser.Start(); |
| | fuser.Wait(); |
| |
|
| | Reconstruction reconstruction; |
| |
|
| | |
| | if (workspace_format == "colmap") { |
| | reconstruction.Read(JoinPaths(workspace_path, "sparse")); |
| | } |
| |
|
| | |
| | reconstruction.ImportPLY(fuser.GetFusedPoints()); |
| |
|
| | std::cout << "Writing output: " << output_path << std::endl; |
| |
|
| | |
| | StringToLower(&output_type); |
| | if (output_type == "bin") { |
| | reconstruction.WriteBinary(output_path); |
| | } else if (output_type == "txt") { |
| | reconstruction.WriteText(output_path); |
| | } else if (output_type == "ply") { |
| | WriteBinaryPlyPoints(output_path, fuser.GetFusedPoints()); |
| | mvs::WritePointsVisibility(output_path + ".vis", |
| | fuser.GetFusedPointsVisibility()); |
| | } else { |
| | std::cerr << "ERROR: Invalid `output_type`" << std::endl; |
| | return EXIT_FAILURE; |
| | } |
| |
|
| | return EXIT_SUCCESS; |
| | } |
| |
|
| | } |
| |
|