Skip to content

Commit

Permalink
Merge pull request #1413 from alicevision/dev/sfmExposeParams
Browse files Browse the repository at this point in the history
SfM: Expose new parameters to the command line
  • Loading branch information
fabiencastan authored May 10, 2023
2 parents 807f696 + 3ef258c commit 315f36f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 20 deletions.
8 changes: 8 additions & 0 deletions src/aliceVision/sfm/pipeline/pairwiseMatchesIO.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,21 @@ inline bool loadPairwiseMatches(
{
std::vector<std::string> matchesFolders;

ALICEVISION_LOG_DEBUG("List of provided match folders:");
for (auto it = folders.begin(); it != folders.end(); ++it)
ALICEVISION_LOG_DEBUG("\t - " << *it);

if(!useOnlyMatchesFromFolder)
matchesFolders = sfmData.getMatchesFolders();
else
ALICEVISION_LOG_DEBUG("Load only matches from given folder.");

matchesFolders.insert(matchesFolders.end(), folders.begin(), folders.end());

ALICEVISION_LOG_DEBUG("List of match folders to load:");
for (auto it = matchesFolders.begin(); it != matchesFolders.end(); ++it)
ALICEVISION_LOG_DEBUG("\t - " << *it);

ALICEVISION_LOG_DEBUG("Loading matches");
if (!matching::Load(out_pairwiseMatches, sfmData.getViewsKeys(), matchesFolders, descTypes, maxNbMatches, minNbMatches))
{
Expand Down
10 changes: 9 additions & 1 deletion src/aliceVision/sfm/pipeline/regionsIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ std::unique_ptr<feature::Regions> loadFeatures(const std::vector<std::string>& f
if(featFilename.empty())
throw std::runtime_error("Can't find view " + basename + " features file");

ALICEVISION_LOG_TRACE("Features filename: " << featFilename);
ALICEVISION_LOG_DEBUG("Features filename: " << featFilename);

std::unique_ptr<feature::Regions> regionsPtr;
imageDescriber.allocate(regionsPtr);
Expand Down Expand Up @@ -241,6 +241,14 @@ bool loadFeaturesPerView(feature::FeaturesPerView& featuresPerView,
std::vector<std::string> featuresFolders = sfmData.getFeaturesFolders(); // add sfm features folders
featuresFolders.insert(featuresFolders.end(), folders.begin(), folders.end()); // add user features folders

ALICEVISION_LOG_DEBUG("List of provided feature folders:");
for (auto it = folders.begin(); it != folders.end(); ++it)
ALICEVISION_LOG_DEBUG("\t - " << *it);

ALICEVISION_LOG_DEBUG("List of feature folders to load:");
for (auto it = featuresFolders.begin(); it != featuresFolders.end(); ++it)
ALICEVISION_LOG_DEBUG("\t - " << *it);

auto progressDisplay = system::createConsoleProgressDisplay(sfmData.getViews().size(), std::cout,
"Loading features\n");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1089,33 +1089,24 @@ bool ReconstructionEngine_sequentialSfM::findNextBestViews(
}
}

// The beginning of the incremental SfM is a well known risky and
// unstable step which has a big impact on the final result.
// The Bundle Adjustment is an intensive computing step so we only use it
// every N cameras.
// We make an exception for the first 'nbFirstUnstableCameras' cameras
// and perform a BA for each camera because it makes the results
// more stable and it's quite cheap because we have few data.
static const std::size_t nbFirstUnstableCameras = 30;

if(_sfmData.getPoses().size() < nbFirstUnstableCameras &&
// If the number of cameras is less than nbFirstUnstableCameras, then the bundle adjustment should be performed
// every time a new camera is added: it is not expensive as there is very little data and it gives more stable results.
if(_sfmData.getPoses().size() < _params.nbFirstUnstableCameras &&
!out_selectedViewIds.empty())
{
// add images one by one to reconstruct the first cameras
ALICEVISION_LOG_DEBUG("findNextBestViews: beginning of the incremental SfM" << std::endl
<< "Only the first image of the resection group is used." << std::endl
<< "\t- image view id : " << out_selectedViewIds.front() << std::endl
<< "\t- # unstable poses : " << _sfmData.getPoses().size() << " / " << nbFirstUnstableCameras << std::endl);
<< "\t- # unstable poses : " << _sfmData.getPoses().size() << " / " << _params.nbFirstUnstableCameras << std::endl);

out_selectedViewIds.resize(1);
}

// Limit to a maximum number of cameras added to ensure that
// we don't add too much data in one step without bundle adjustment.
static const std::size_t maxImagesPerGroup = 30;

if(out_selectedViewIds.size() > maxImagesPerGroup)
out_selectedViewIds.resize(maxImagesPerGroup);
// No more than maxImagesPerGroup cameras should be added at once without performing the bundle adjustment (if set to
// 0, then there is no limit on the number of views that can be added at once)
if(_params.maxImagesPerGroup > 0 && out_selectedViewIds.size() > _params.maxImagesPerGroup)
out_selectedViewIds.resize(_params.maxImagesPerGroup);

ALICEVISION_LOG_DEBUG(
"Find next best views took: " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - chrono_start).count() << " msec\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,28 @@ class ReconstructionEngine_sequentialSfM : public ReconstructionEngine
bool filterTrackForks = true;
robustEstimation::ERobustEstimator localizerEstimator = robustEstimation::ERobustEstimator::ACRANSAC;
double localizerEstimatorError = std::numeric_limits<double>::infinity();
size_t localizerEstimatorMaxIterations = 4096;
std::size_t localizerEstimatorMaxIterations = 4096;

// Pyramid scoring

const int pyramidBase = 2;
const int pyramidDepth = 5;

// Bundle Adjustment triggering

/// The beginning of the incremental SfM is a well known risky and
/// unstable step which has a big impact on the final result.
/// The Bundle Adjustment is an intensive computing step so we only use it
/// every N cameras.
/// We make an exception for the first 'nbFirstUnstableCameras' cameras
/// and perform a BA for each camera because it makes the results
/// more stable and it's quite cheap because we have few data.
std::size_t nbFirstUnstableCameras = 30;

/// Limit to a maximum number of cameras added to ensure that
/// we don't add too much data in one step without bundle adjustment.
std::size_t maxImagesPerGroup = 30;

// Local Bundle Adjustment data

/// The minimum number of shared matches to create an edge between two views (nodes)
Expand Down
9 changes: 8 additions & 1 deletion src/software/pipeline/main_incrementalSfM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,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_MINOR 1
#define ALICEVISION_SOFTWARE_VERSION_MINOR 2

using namespace aliceVision;

Expand Down Expand Up @@ -153,6 +153,13 @@ int aliceVision_main(int argc, char **argv)
"It reduces the reconstruction time, especially for big datasets (500+ images).")
("localBAGraphDistance", po::value<int>(&sfmParams.localBundelAdjustementGraphDistanceLimit)->default_value(sfmParams.localBundelAdjustementGraphDistanceLimit),
"Graph-distance limit setting the Active region in the Local Bundle Adjustment strategy.")
("nbFirstUnstableCameras", po::value<std::size_t>(&sfmParams.nbFirstUnstableCameras)->default_value(sfmParams.nbFirstUnstableCameras),
"Number of cameras for which the bundle adjustment is performed every single time a camera is added, leading to more stable "
"results while the computations are not too expensive since there is not much data. Past this number, the bundle adjustment "
"will only be performed once for N added cameras.")
("maxImagesPerGroup", po::value<std::size_t>(&sfmParams.maxImagesPerGroup)->default_value(sfmParams.maxImagesPerGroup),
"Maximum number of cameras that can be added before the bundle adjustment is performed. This prevents adding too much data "
"at once without performing the bundle adjustment.")
("localizerEstimator", po::value<robustEstimation::ERobustEstimator>(&sfmParams.localizerEstimator)->default_value(sfmParams.localizerEstimator),
"Estimator type used to localize cameras (acransac (default), ransac, lsmeds, loransac, maxconsensus)")
("localizerEstimatorError", po::value<double>(&sfmParams.localizerEstimatorError)->default_value(0.0),
Expand Down

0 comments on commit 315f36f

Please sign in to comment.