diff --git a/src/aliceVision/sfm/pipeline/bootstrapping/Bootstrap.cpp b/src/aliceVision/sfm/pipeline/bootstrapping/Bootstrap.cpp index db246895cc..2e8287bbf0 100644 --- a/src/aliceVision/sfm/pipeline/bootstrapping/Bootstrap.cpp +++ b/src/aliceVision/sfm/pipeline/bootstrapping/Bootstrap.cpp @@ -104,10 +104,11 @@ bool bootstrapMesh(sfmData::SfMData & sfmData, std::mt19937 randomNumberGenerator; Eigen::Matrix4d pose; double threshold; + size_t countInliers; //Compute resection for selected view SfmResection resection(50000, std::numeric_limits::infinity()); - if (!resection.processView(sfmData, tracksMap, tracksPerView, randomNumberGenerator, viewId, pose, threshold)) + if (!resection.processView(sfmData, tracksMap, tracksPerView, randomNumberGenerator, viewId, pose, threshold, countInliers)) { return false; } diff --git a/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.cpp b/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.cpp index 4c4d7caed3..1282350032 100644 --- a/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.cpp +++ b/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.cpp @@ -15,6 +15,7 @@ namespace sfm { bool ExpansionChunk::process(sfmData::SfMData & sfmData, const track::TracksHandler & tracksHandler, const std::set & viewsChunk) { + _ignoredViews.clear(); ALICEVISION_LOG_INFO("ExpansionChunk::process start"); ALICEVISION_LOG_INFO("Chunk size : " << viewsChunk.size()); @@ -31,6 +32,17 @@ bool ExpansionChunk::process(sfmData::SfMData & sfmData, const track::TracksHand return false; } + + struct IntermediateResectionInfo + { + IndexT viewId; + Eigen::Matrix4d pose; + size_t inliersCount; + double threshold; + }; + + std::vector intermediateInfos; + ALICEVISION_LOG_INFO("Resection start"); #pragma omp parallel for for (int i = 0; i < viewsChunk.size(); i++) @@ -41,25 +53,52 @@ bool ExpansionChunk::process(sfmData::SfMData & sfmData, const track::TracksHand if (!sfmData.isPoseAndIntrinsicDefined(viewId)) { + IntermediateResectionInfo iri; + iri.viewId = viewId; + SfmResection resection(_resectionIterations, _resectionMaxError); - Eigen::Matrix4d pose; - double threshold = 0.0; std::mt19937 randomNumberGenerator; if (!resection.processView(sfmData, tracksHandler.getAllTracks(), tracksHandler.getTracksPerView(), randomNumberGenerator, viewId, - pose, threshold)) + iri.pose, iri.threshold, iri.inliersCount)) { continue; } #pragma omp critical { - - addPose(sfmData, viewId, pose); + intermediateInfos.push_back(iri); + } + } + } + + //Check that at least one view has rich info + const int poorInliersCount = 100; + int richViews = 0; + for (const auto & item : intermediateInfos) + { + if (item.inliersCount > poorInliersCount) + { + richViews++; + } + } + + + //Add pose only if it match conditions + for (const auto & item : intermediateInfos) + { + if (richViews > 0) + { + if (item.inliersCount < poorInliersCount) + { + _ignoredViews.insert(item.viewId); + continue; } } + + addPose(sfmData, item.viewId, item.pose); } // Get a list of valid views diff --git a/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.hpp b/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.hpp index 417fdfc284..29acca4129 100644 --- a/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.hpp +++ b/src/aliceVision/sfm/pipeline/expanding/ExpansionChunk.hpp @@ -98,6 +98,11 @@ class ExpansionChunk _minTriangulationAngleDegrees = angle; } + const std::set & getIgnoredViews() + { + return _ignoredViews; + } + private: /** @@ -128,6 +133,7 @@ class ExpansionChunk SfmBundle::uptr _bundleHandler; ExpansionHistory::sptr _historyHandler; PointFetcher::uptr _pointFetcherHandler; + std::set _ignoredViews; private: size_t _resectionIterations = 1024; diff --git a/src/aliceVision/sfm/pipeline/expanding/ExpansionIteration.cpp b/src/aliceVision/sfm/pipeline/expanding/ExpansionIteration.cpp index e2988a8e20..954defcea1 100644 --- a/src/aliceVision/sfm/pipeline/expanding/ExpansionIteration.cpp +++ b/src/aliceVision/sfm/pipeline/expanding/ExpansionIteration.cpp @@ -47,6 +47,10 @@ bool ExpansionIteration::process(sfmData::SfMData & sfmData, track::TracksHandle continue; } + //Rollback any views which were ignored (not with errors) + _policy->rollback(_chunkHandler->getIgnoredViews()); + + //Save this epoch to history _historyHandler->endEpoch(sfmData, _policy->getNextViews()); } diff --git a/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicy.hpp b/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicy.hpp index 27f68bec08..fff36ebd7c 100644 --- a/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicy.hpp +++ b/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicy.hpp @@ -33,6 +33,12 @@ class ExpansionPolicy * @return true if the policy succeeded */ virtual bool process(const sfmData::SfMData & sfmData, const track::TracksHandler & tracksHandler) = 0; + + /** + * @brief rollback some processed views inside the available views + * @param viewsSet the set of views that we want to be able to select again. + */ + virtual void rollback(const std::set & viewsSet) = 0; /** * @brief Retrieve the selected next views diff --git a/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.cpp b/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.cpp index b30fd7a9c0..dcbeaa033b 100644 --- a/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.cpp +++ b/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.cpp @@ -200,5 +200,14 @@ double ExpansionPolicyLegacy::computeScore(const track::TracksMap & tracksMap, return sum; } +void ExpansionPolicyLegacy::rollback(const std::set & viewsSet) +{ + for (const auto & item : viewsSet) + { + ALICEVISION_LOG_INFO("rollback view : " << item); + _availableViewsIds.insert(item); + } +} + } } \ No newline at end of file diff --git a/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.hpp b/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.hpp index 25361f2f8d..34afa986eb 100644 --- a/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.hpp +++ b/src/aliceVision/sfm/pipeline/expanding/ExpansionPolicyLegacy.hpp @@ -73,6 +73,12 @@ class ExpansionPolicyLegacy : public ExpansionPolicy _maxViewsPerGroup = count; } + /** + * @brief rollback some processed views inside the available views + * @param viewsSet the set of views that we want to be able to select again. + */ + virtual void rollback(const std::set & viewsSet); + private: // vector of selected views for this iteration diff --git a/src/aliceVision/sfm/pipeline/expanding/SfmResection.cpp b/src/aliceVision/sfm/pipeline/expanding/SfmResection.cpp index 246aa93e57..d529fe33df 100644 --- a/src/aliceVision/sfm/pipeline/expanding/SfmResection.cpp +++ b/src/aliceVision/sfm/pipeline/expanding/SfmResection.cpp @@ -26,7 +26,8 @@ bool SfmResection::processView( std::mt19937 &randomNumberGenerator, const IndexT viewId, Eigen::Matrix4d & updatedPose, - double & updatedThreshold + double & updatedThreshold, + size_t & inliersCount ) { ALICEVISION_LOG_INFO("SfmResection::processView start " << viewId); @@ -90,6 +91,9 @@ bool SfmResection::processView( return false; } + inliersCount = inliers.size(); + ALICEVISION_LOG_INFO("Resection for view " << viewId << " had " << inliersCount << " inliers."); + //Refine the pose if (!internalRefinement(structure, observations, inliers, pose, intrinsic, errorMax)) { diff --git a/src/aliceVision/sfm/pipeline/expanding/SfmResection.hpp b/src/aliceVision/sfm/pipeline/expanding/SfmResection.hpp index 20cb59a292..1de7874d61 100644 --- a/src/aliceVision/sfm/pipeline/expanding/SfmResection.hpp +++ b/src/aliceVision/sfm/pipeline/expanding/SfmResection.hpp @@ -32,6 +32,7 @@ class SfmResection * @param viewId the view id to process * @param updatedPose output estimated pose * @param updatedThreshold estimated threshold + * @param inliersCount number of inliers for this resection * @return false if a critical error occured */ bool processView( @@ -41,7 +42,8 @@ class SfmResection std::mt19937 &randomNumberGenerator, const IndexT viewId, Eigen::Matrix4d & updatedPose, - double & updatedThreshold + double & updatedThreshold, + size_t & inliersCount ); private: