int main(int argc, char **argv) { #ifdef TEST_CMD_LINE string in; // Create command line options. CmdLine cmdLine; cmdLine.add(make_switch('h', "help")); // Verbose option for debug. cmdLine.add(make_option('i', in, "input folder")); // Image file name. // Try to process try { if (argc == 1) throw std::string("Invalid command line parameter."); cmdLine.process(argc, argv); if (!cmdLine.used('i')) throw std::string("Invalid command line parameter."); if (cmdLine.used('h')) print_usage(argv); } catch(const std::string& s) { print_usage(argv); return false; } #endif // Get image filenames. vector<string> filenames; getImageFilePaths(filenames, srcPath("../../datasets/")); return 0; }
// Convert from a SfM_Data format to another int main(int argc, char **argv) { CmdLine cmd; std::string sSfM_Data_Filename_In, sSfM_Data_Filename_Out; cmd.add(make_option('i', sSfM_Data_Filename_In, "input_file")); cmd.add(make_switch('V', "VIEWS")); cmd.add(make_switch('I', "INTRINSICS")); cmd.add(make_switch('E', "EXTRINSICS")); cmd.add(make_switch('S', "STRUCTURE")); cmd.add(make_switch('C', "CONTROL_POINTS")); cmd.add(make_option('o', sSfM_Data_Filename_Out, "output_file")); try { if (argc == 1) throw std::string("Invalid command line parameter."); cmd.process(argc, argv); } catch(const std::string& s) { std::cerr << "Usage: " << argv[0] << '\n' << "[-i|--input_file] path to the input SfM_Data scene\n" << "[-o|--output_file] path to the output SfM_Data scene\n" << "\t .json, .bin, .xml, .ply, .baf\n" << "\n[Options to export partial data (by default all data are exported)]\n" << "\nUsable for json/bin/xml format" << "[-V|--VIEWS] export views\n" << "[-I|--INTRINSICS] export intrinsics (view orientations)\n" << "[-E|--EXTRINSICS] export extrinsics (view poses)\n" << "[-S|--STRUCTURE] export structure\n" << "[-C|--CONTROL_POINTS] export control points\n" << std::endl; std::cerr << s << std::endl; return EXIT_FAILURE; } if (sSfM_Data_Filename_In.empty() || sSfM_Data_Filename_Out.empty()) { std::cerr << "Invalid input or output filename." << std::endl; return EXIT_FAILURE; } // OptionSwitch is cloned in cmd.add(), // so we must use cmd.used() instead of testing OptionSwitch.used int flags = (cmd.used('V') ? VIEWS : 0) | (cmd.used('I') ? INTRINSICS : 0) | (cmd.used('E') ? EXTRINSICS : 0) | (cmd.used('S') ? STRUCTURE : 0); flags = (flags) ? flags : ALL; // Load input SfM_Data scene SfM_Data sfm_data; if (!Load(sfm_data, sSfM_Data_Filename_In, ESfM_Data(ALL))) { std::cerr << std::endl << "The input SfM_Data file \"" << sSfM_Data_Filename_In << "\" cannot be read." << std::endl; return EXIT_FAILURE; } // Export the SfM_Data scene in the expected format if (Save( sfm_data, sSfM_Data_Filename_Out.c_str(), ESfM_Data(flags))) { return EXIT_SUCCESS; } else { std::cerr << std::endl << "An error occured while trying to save \"" << sSfM_Data_Filename_Out << "\"." << std::endl; return EXIT_FAILURE; } }
int main(int argc, char **argv) { using namespace std; std::cout << "Sequential/Incremental reconstruction" << std::endl << " Perform incremental SfM (Initial Pair Essential + Resection)." << std::endl << std::endl; CmdLine cmd; std::string sSfM_Data_Filename; std::string sMatchesDir, sMatchFilename; std::string sOutDir = ""; std::pair<std::string,std::string> initialPairString("",""); std::string sIntrinsic_refinement_options = "ADJUST_ALL"; int i_User_camera_model = PINHOLE_CAMERA_RADIAL3; bool b_use_motion_priors = false; cmd.add( make_option('i', sSfM_Data_Filename, "input_file") ); cmd.add( make_option('m', sMatchesDir, "matchdir") ); cmd.add( make_option('M', sMatchFilename, "match_file") ); cmd.add( make_option('o', sOutDir, "outdir") ); cmd.add( make_option('a', initialPairString.first, "initialPairA") ); cmd.add( make_option('b', initialPairString.second, "initialPairB") ); cmd.add( make_option('c', i_User_camera_model, "camera_model") ); cmd.add( make_option('f', sIntrinsic_refinement_options, "refineIntrinsics") ); cmd.add( make_switch('P', "prior_usage") ); try { if (argc == 1) throw std::string("Invalid parameter."); cmd.process(argc, argv); } catch (const std::string& s) { std::cerr << "Usage: " << argv[0] << '\n' << "[-i|--input_file] path to a SfM_Data scene\n" << "[-m|--matchdir] path to the matches that corresponds to the provided SfM_Data scene\n" << "[-o|--outdir] path where the output data will be stored\n" << "\n[Optional]\n" << "[-a|--initialPairA] filename of the first image (without path)\n" << "[-b|--initialPairB] filename of the second image (without path)\n" << "[-c|--camera_model] Camera model type for view with unknown intrinsic:\n" << "\t 1: Pinhole \n" << "\t 2: Pinhole radial 1\n" << "\t 3: Pinhole radial 3 (default)\n" << "\t 4: Pinhole radial 3 + tangential 2\n" << "\t 5: Pinhole fisheye\n" << "[-f|--refineIntrinsics] Intrinsic parameters refinement option\n" << "\t ADJUST_ALL -> refine all existing parameters (default) \n" << "\t NONE -> intrinsic parameters are held as constant\n" << "\t ADJUST_FOCAL_LENGTH -> refine only the focal length\n" << "\t ADJUST_PRINCIPAL_POINT -> refine only the principal point position\n" << "\t ADJUST_DISTORTION -> refine only the distortion coefficient(s) (if any)\n" << "\t -> NOTE: options can be combined thanks to '|'\n" << "\t ADJUST_FOCAL_LENGTH|ADJUST_PRINCIPAL_POINT\n" << "\t\t-> refine the focal length & the principal point position\n" << "\t ADJUST_FOCAL_LENGTH|ADJUST_DISTORTION\n" << "\t\t-> refine the focal length & the distortion coefficient(s) (if any)\n" << "\t ADJUST_PRINCIPAL_POINT|ADJUST_DISTORTION\n" << "\t\t-> refine the principal point position & the distortion coefficient(s) (if any)\n" << "[-P|--prior_usage] Enable usage of motion priors (i.e GPS positions) (default: false)\n" << "[-M|--match_file] path to the match file to use.\n" << std::endl; std::cerr << s << std::endl; return EXIT_FAILURE; } if ( !isValid(openMVG::cameras::EINTRINSIC(i_User_camera_model)) ) { std::cerr << "\n Invalid camera type" << std::endl; return EXIT_FAILURE; } const cameras::Intrinsic_Parameter_Type intrinsic_refinement_options = cameras::StringTo_Intrinsic_Parameter_Type(sIntrinsic_refinement_options); if (intrinsic_refinement_options == static_cast<cameras::Intrinsic_Parameter_Type>(0) ) { std::cerr << "Invalid input for Bundle Adjusment Intrinsic parameter refinement option" << std::endl; return EXIT_FAILURE; } // Load input SfM_Data scene SfM_Data sfm_data; if (!Load(sfm_data, sSfM_Data_Filename, ESfM_Data(VIEWS|INTRINSICS))) { std::cerr << std::endl << "The input SfM_Data file \""<< sSfM_Data_Filename << "\" cannot be read." << std::endl; return EXIT_FAILURE; } // Init the regions_type from the image describer file (used for image regions extraction) using namespace openMVG::features; const std::string sImage_describer = stlplus::create_filespec(sMatchesDir, "image_describer", "json"); std::unique_ptr<Regions> regions_type = Init_region_type_from_file(sImage_describer); if (!regions_type) { std::cerr << "Invalid: " << sImage_describer << " regions type file." << std::endl; return EXIT_FAILURE; } // Features reading std::shared_ptr<Features_Provider> feats_provider = std::make_shared<Features_Provider>(); if (!feats_provider->load(sfm_data, sMatchesDir, regions_type)) { std::cerr << std::endl << "Invalid features." << std::endl; return EXIT_FAILURE; } // Matches reading std::shared_ptr<Matches_Provider> matches_provider = std::make_shared<Matches_Provider>(); if // Try to read the provided match filename or the default one (matches.f.txt/bin) ( !(matches_provider->load(sfm_data, sMatchFilename) || matches_provider->load(sfm_data, stlplus::create_filespec(sMatchesDir, "matches.f.txt")) || matches_provider->load(sfm_data, stlplus::create_filespec(sMatchesDir, "matches.f.bin"))) ) { std::cerr << std::endl << "Invalid matches file." << std::endl; return EXIT_FAILURE; } if (sOutDir.empty()) { std::cerr << "\nIt is an invalid output directory" << std::endl; return EXIT_FAILURE; } if (!stlplus::folder_exists(sOutDir)) { if (!stlplus::folder_create(sOutDir)) { std::cerr << "\nCannot create the output directory" << std::endl; } } //--------------------------------------- // Sequential reconstruction process //--------------------------------------- openMVG::system::Timer timer; SequentialSfMReconstructionEngine sfmEngine( sfm_data, sOutDir, stlplus::create_filespec(sOutDir, "Reconstruction_Report.html")); // Configure the features_provider & the matches_provider sfmEngine.SetFeaturesProvider(feats_provider.get()); sfmEngine.SetMatchesProvider(matches_provider.get()); // Configure reconstruction parameters sfmEngine.Set_Intrinsics_Refinement_Type(intrinsic_refinement_options); sfmEngine.SetUnknownCameraType(EINTRINSIC(i_User_camera_model)); b_use_motion_priors = cmd.used('P'); sfmEngine.Set_Use_Motion_Prior(b_use_motion_priors); // Handle Initial pair parameter if (!initialPairString.first.empty() && !initialPairString.second.empty()) { Pair initialPairIndex; if (!computeIndexFromImageNames(sfm_data, initialPairString, initialPairIndex)) { std::cerr << "Could not find the initial pairs <" << initialPairString.first << ", " << initialPairString.second << ">!\n"; return EXIT_FAILURE; } sfmEngine.setInitialPair(initialPairIndex); } if (sfmEngine.Process()) { std::cout << std::endl << " Total Ac-Sfm took (s): " << timer.elapsed() << std::endl; std::cout << "...Generating SfM_Report.html" << std::endl; Generate_SfM_Report(sfmEngine.Get_SfM_Data(), stlplus::create_filespec(sOutDir, "SfMReconstruction_Report.html")); //-- Export to disk computed scene (data & visualizable results) std::cout << "...Export SfM_Data to disk." << std::endl; Save(sfmEngine.Get_SfM_Data(), stlplus::create_filespec(sOutDir, "sfm_data", ".bin"), ESfM_Data(ALL)); Save(sfmEngine.Get_SfM_Data(), stlplus::create_filespec(sOutDir, "cloud_and_poses", ".ply"), ESfM_Data(ALL)); return EXIT_SUCCESS; } return EXIT_FAILURE; }
/// Main Program int main(int argc, char *argv[]) { CmdLine cmd; std::string combine; ParamDisparity p; // Parameters for adaptive weights cmd.add( make_option('R',p.radius) ); cmd.add( make_option(0,p.gammaCol,"gcol") ); cmd.add( make_option(0,p.gammaPos,"gpos") ); cmd.add( make_option('c', combine) ); try { cmd.process(argc, argv); } catch(std::string str) { std::cerr << "Error: " << str << std::endl<<std::endl; argc = 1; // To display usage } if(argc!=5 && argc!=7) { usage(argv[0]); return 1; } // Load images Image im1 = loadImage(argv[1]); Image im2; if(argc>5) im2 = loadImage(argv[5]); int x,y; if(! ((std::istringstream(argv[2])>>x).eof() && (std::istringstream(argv[3])>>y).eof())) { std::cerr << "Error reading x or y" << std::endl; return 1; } int disp=0; if(argc>6 && !((std::istringstream(argv[6])>>disp).eof()) ) { std::cerr << "Error reading disparity" << std::endl; return 1; } Comb* comb=0; if(cmd.used('c') && im2.channels()!=0) { if(combine == "left") comb = new Comb(left); else if(combine == "max") comb = new Comb(max); else if(combine == "min") comb = new Comb(min); else if(combine == "mult") comb = new Comb(mult); else if(combine == "plus") comb = new Comb(plus); else { std::cerr << "Unrecognized option for weights combination " << "(should be left,max,min,mult or plus)" << std::endl; return 1; } } Image w = show_weights(im1, im2, x, y, x+disp, comb, p.radius, p.gammaCol, p.gammaPos); rescale(w); if(io_png_write_f32(argv[4], &w(0,0), w.width(), w.height(), 1) != 0) { std::cerr << "Unable to write file " << argv[4] << std::endl; return 1; } return 0; }
/// Compute the structure of a scene according existing camera poses. int main(int argc, char **argv) { using namespace std; std::cout << "Compute Structure from the provided poses" << std::endl; CmdLine cmd; std::string sSfM_Data_Filename; std::string sMatchesDir; std::string sMatchFile; std::string sOutFile = ""; double dMax_reprojection_error = 4.0; cmd.add( make_option('i', sSfM_Data_Filename, "input_file") ); cmd.add( make_option('m', sMatchesDir, "match_dir") ); cmd.add( make_option('f', sMatchFile, "match_file") ); cmd.add( make_option('o', sOutFile, "output_file") ); cmd.add( make_switch('b', "bundle_adjustment")); cmd.add( make_option('r', dMax_reprojection_error, "residual_threshold")); try { if (argc == 1) throw std::string("Invalid command line parameter."); cmd.process(argc, argv); } catch(const std::string& s) { std::cerr << "Usage: " << argv[0] << '\n' << "[-i|--input_file] path to a SfM_Data scene\n" << "[-m|--match_dir] path to the features and descriptors that " << "corresponds to the provided SfM_Data scene\n" << "[-o|--output_file] file where the output data will be stored " << "(i.e. path/sfm_data_structure.bin)\n" << "\n[Optional]\n" << "[-f|--match_file] path to a matches file (loaded pair indexes will be used)\n" << "[-b|--bundle_adjustment] (switch) perform a bundle adjustment on the scene (OFF by default)\n" << "[-r|--residual_threshold] maximal pixels reprojection error that will be considered for triangulations (4.0 by default)\n" << std::endl; std::cerr << s << std::endl; return EXIT_FAILURE; } // Load input SfM_Data scene SfM_Data sfm_data; if (!Load(sfm_data, sSfM_Data_Filename, ESfM_Data(VIEWS|INTRINSICS|EXTRINSICS))) { std::cerr << std::endl << "The input SfM_Data file \""<< sSfM_Data_Filename << "\" cannot be read." << std::endl; return EXIT_FAILURE; } // Init the regions_type from the image describer file (used for image regions extraction) using namespace openMVG::features; const std::string sImage_describer = stlplus::create_filespec(sMatchesDir, "image_describer", "json"); std::unique_ptr<Regions> regions_type = Init_region_type_from_file(sImage_describer); if (!regions_type) { std::cerr << "Invalid: " << sImage_describer << " regions type file." << std::endl; return EXIT_FAILURE; } // Prepare the Regions provider std::shared_ptr<Regions_Provider> regions_provider = std::make_shared<Regions_Provider>(); if (!regions_provider->load(sfm_data, sMatchesDir, regions_type)) { std::cerr << std::endl << "Invalid regions." << std::endl; return EXIT_FAILURE; } std::cout << "Loaded a sfm_data scene with:\n" << " #views: " << sfm_data.GetViews().size() << "\n" << " #poses: " << sfm_data.GetPoses().size() << "\n" << " #intrinsics: " << sfm_data.GetIntrinsics().size() << "\n" << " #tracks: " << sfm_data.GetLandmarks().size() << std::endl; //-- //- Pair selection method: // - geometry guided -> camera frustum intersection, // - putative matches guided (photometric matches) // (keep pairs that have valid Intrinsic & Pose ids). //-- Pair_Set pairs; if (sMatchFile.empty()) { // no provided pair, use camera frustum intersection pairs = BuildPairsFromFrustumsIntersections(sfm_data); } else { PairWiseMatches matches; if (!matching::Load(matches, sMatchFile)) { std::cerr<< "Unable to read the matches file." << std::endl; return EXIT_FAILURE; } pairs = getPairs(matches); // Keep only Pairs that belong to valid view indexes. const std::set<IndexT> valid_viewIdx = Get_Valid_Views(sfm_data); pairs = Pair_filter(pairs, valid_viewIdx); } openMVG::system::Timer timer; //------------------------------------------ // Compute Structure from known camera poses //------------------------------------------ SfM_Data_Structure_Estimation_From_Known_Poses structure_estimator(dMax_reprojection_error); structure_estimator.run(sfm_data, pairs, regions_provider); regions_provider.reset(); // Regions are not longer needed. RemoveOutliers_AngleError(sfm_data, 2.0); std::cout << "\nStructure estimation took (s): " << timer.elapsed() << "." << std::endl << "#landmark found: " << sfm_data.GetLandmarks().size() << std::endl; std::cout << "...Generating SfM_Report.html" << std::endl; Generate_SfM_Report(sfm_data, stlplus::create_filespec(stlplus::folder_part(sOutFile), "SfMStructureFromKnownPoses_Report.html")); if (cmd.used('b')) { // Check that poses & intrinsic cover some measures (after outlier removal) const IndexT minPointPerPose = 12; // 6 min const IndexT minTrackLength = 3; // 2 min if (eraseUnstablePosesAndObservations(sfm_data, minPointPerPose, minTrackLength)) { KeepLargestViewCCTracks(sfm_data); eraseUnstablePosesAndObservations(sfm_data, minPointPerPose, minTrackLength); const size_t pointcount_cleaning = sfm_data.structure.size(); std::cout << "Point_cloud cleaning:\n" << "\t #3DPoints: " << pointcount_cleaning << "\n"; } std::cout << "Bundle adjustment..." << std::endl; Bundle_Adjustment_Ceres bundle_adjustment_obj; bundle_adjustment_obj.Adjust ( sfm_data, Optimize_Options( cameras::Intrinsic_Parameter_Type::ADJUST_ALL, Extrinsic_Parameter_Type::ADJUST_ALL, Structure_Parameter_Type::ADJUST_ALL) ); } std::cout << "Found a sfm_data scene with:\n" << " #views: " << sfm_data.GetViews().size() << "\n" << " #poses: " << sfm_data.GetPoses().size() << "\n" << " #intrinsics: " << sfm_data.GetIntrinsics().size() << "\n" << " #tracks: " << sfm_data.GetLandmarks().size() << std::endl; if (stlplus::extension_part(sOutFile) != "ply") { Save(sfm_data, stlplus::create_filespec( stlplus::folder_part(sOutFile), stlplus::basename_part(sOutFile), "ply"), ESfM_Data(ALL)); } if (Save(sfm_data, sOutFile, ESfM_Data(ALL))) return EXIT_SUCCESS; else return EXIT_FAILURE; }