From 2eac9de615acdde8e3930c90913048cef9f66034 Mon Sep 17 00:00:00 2001 From: Fabien Servant Date: Tue, 21 Jan 2025 11:29:47 +0100 Subject: [PATCH] Enable merging of multiple sfms --- src/software/utils/main_sfmMerge.cpp | 86 ++++++++++++++++------------ 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/src/software/utils/main_sfmMerge.cpp b/src/software/utils/main_sfmMerge.cpp index 1303efd8c6..052c484bc8 100644 --- a/src/software/utils/main_sfmMerge.cpp +++ b/src/software/utils/main_sfmMerge.cpp @@ -21,7 +21,7 @@ // These constants define the current software version. // They must be updated when the command line is changed. -#define ALICEVISION_SOFTWARE_VERSION_MAJOR 2 +#define ALICEVISION_SOFTWARE_VERSION_MAJOR 3 #define ALICEVISION_SOFTWARE_VERSION_MINOR 0 using namespace aliceVision; @@ -355,7 +355,7 @@ bool fromLandmarksMerge(sfmData::SfMData & sfmData1, const sfmData::SfMData & sf int aliceVision_main(int argc, char** argv) { // command-line parameters - std::string sfmDataFilename1, sfmDataFilename2; + std::vector sfmDataFilenames; std::string outSfMDataFilename; EMergeMethod mergeMethod = EMergeMethod::SIMPLE_COPY; std::vector matchesFolders; @@ -364,10 +364,8 @@ int aliceVision_main(int argc, char** argv) // clang-format off po::options_description requiredParams("Required parameters"); requiredParams.add_options() - ("firstinput,i1", po::value(&sfmDataFilename1)->required(), - "First SfMData file to merge.") - ("secondinput,i2", po::value(&sfmDataFilename2)->required(), - "Second SfMData file to merge.") + ("inputs,i", po::value>(&sfmDataFilenames)->multitoken(), + "Path to sfmDatas to merge.") ("output,o", po::value(&outSfMDataFilename)->required(), "Output SfMData scene."); @@ -391,55 +389,69 @@ int aliceVision_main(int argc, char** argv) return EXIT_FAILURE; } - // Load input scene - sfmData::SfMData sfmData1; - if (!sfmDataIO::load(sfmData1, sfmDataFilename1, sfmDataIO::ESfMData::ALL)) + if (sfmDataFilenames.empty()) { - ALICEVISION_LOG_ERROR("The input SfMData file '" << sfmDataFilename1 << "' cannot be read"); + ALICEVISION_LOG_ERROR("At least one sfmData input should be given."); return EXIT_FAILURE; } - sfmData::SfMData sfmData2; - if (!sfmDataIO::load(sfmData2, sfmDataFilename2, sfmDataIO::ESfMData::ALL)) - { - ALICEVISION_LOG_ERROR("The input SfMData file '" << sfmDataFilename2 << "' cannot be read"); - return EXIT_FAILURE; - } + sfmData::SfMData outputSfmData; - if (mergeMethod == EMergeMethod::SIMPLE_COPY) + for (int id = 0; id < sfmDataFilenames.size(); id++) { - if (!simpleMerge(sfmData1, sfmData2)) + const std::string & filename = sfmDataFilenames[id]; + ALICEVISION_LOG_INFO("Processing " << filename); + + // Load input scene + sfmData::SfMData sfmData; + if (!sfmDataIO::load(sfmData, filename, sfmDataIO::ESfMData::ALL)) { + ALICEVISION_LOG_ERROR("The input SfMData file '" << filename << "' cannot be read"); return EXIT_FAILURE; } - } - else - { - // get imageDescriber type - const std::vector describerTypes = feature::EImageDescriberType_stringToEnums(describerTypesName); - // matches reading - matching::PairwiseMatches pairwiseMatches; - if (!matching::Load(pairwiseMatches, std::set(), matchesFolders, describerTypes, 0, 0)) + if (id == 0) { - std::stringstream ss("Unable to read the matches file(s) from:\n"); - for (const std::string& folder : matchesFolders) + outputSfmData = sfmData; + continue; + } + + if (mergeMethod == EMergeMethod::SIMPLE_COPY) + { + if (!simpleMerge(outputSfmData, sfmData)) { - ss << "\t- " << folder << "\n"; + return EXIT_FAILURE; } - - ALICEVISION_LOG_WARNING(ss.str()); - - return EXIT_FAILURE; } - - if (!fromLandmarksMerge(sfmData1, sfmData2, pairwiseMatches)) + else { - return EXIT_FAILURE; + // get imageDescriber type + const std::vector describerTypes = feature::EImageDescriberType_stringToEnums(describerTypesName); + + // matches reading + matching::PairwiseMatches pairwiseMatches; + if (!matching::Load(pairwiseMatches, std::set(), matchesFolders, describerTypes, 0, 0)) + { + std::stringstream ss("Unable to read the matches file(s) from:\n"); + for (const std::string& folder : matchesFolders) + { + ss << "\t- " << folder << "\n"; + } + + ALICEVISION_LOG_WARNING(ss.str()); + + return EXIT_FAILURE; + } + + if (!fromLandmarksMerge(outputSfmData, sfmData, pairwiseMatches)) + { + return EXIT_FAILURE; + } } } + - if (!sfmDataIO::save(sfmData1, outSfMDataFilename, sfmDataIO::ESfMData::ALL)) + if (!sfmDataIO::save(outputSfmData, outSfMDataFilename, sfmDataIO::ESfMData::ALL)) { ALICEVISION_LOG_ERROR("An error occurred while trying to save '" << outSfMDataFilename << "'"); return EXIT_FAILURE;