@@ -400,7 +400,6 @@ void filterLandmarks_step2(SfMData& sfmData,
400400 ALICEVISION_LOG_INFO (" KdTree created for " << landmarksData.size () << " points." );
401401
402402 ALICEVISION_LOG_INFO (" Computing landmarks neighbors: started." );
403- // note that the landmark is a neighbor to itself with zero distance, hence the +/- 1
404403 int nbNeighbors_ = params.nbNeighbors3D ;
405404 // contains the observing view ids and neighbors for each landmark
406405 std::vector<std::pair<std::vector<IndexT>, std::vector<size_t >>> viewData (landmarksData.size ());
@@ -687,6 +686,60 @@ void computeNeighborsInfo(std::vector<Landmark*>& landmarksData, const FilterPar
687686 ALICEVISION_LOG_INFO (" Computing landmark neighbors and distance-based weights: done" );
688687}
689688
689+ void augmentInitialObservations (std::vector<std::pair<std::vector<IndexT>, std::vector<double >>>& viewScoresData,
690+ std::vector<std::pair<std::vector<size_t >, std::vector<double >>>& neighborsData)
691+ {
692+ ALICEVISION_LOG_INFO (" Augment initial observations based on neighbors observations: started" );
693+ std::vector<std::vector<IndexT>> viewScoresData_t (viewScoresData.size ());
694+ // for each landmark, identify the new observations coming from its neighborhood
695+ #pragma omp parallel for
696+ for (int id = 0 ; id < viewScoresData.size (); id++)
697+ {
698+ const auto & viewIds = viewScoresData[id].first ;
699+ auto & viewIds_t = viewScoresData_t[id];
700+ const auto & neighborIds = neighborsData[id].first ;
701+
702+ for (const auto & neighborId : neighborIds)
703+ {
704+ const auto & viewIds_neighbor = viewScoresData[neighborId].first ;
705+ std::vector<IndexT> viewIds_union;
706+ std::set_union (viewIds_neighbor.begin (), viewIds_neighbor.end (), viewIds_t.begin (), viewIds_t.end (),
707+ std::back_inserter (viewIds_union));
708+ viewIds_t = std::move (viewIds_union);
709+ }
710+ std::vector<IndexT> viewIds_toAdd;
711+ std::set_difference (viewIds_t.begin (), viewIds_t.end (), viewIds.begin (), viewIds.end (),
712+ std::back_inserter (viewIds_toAdd));
713+ viewIds_t = std::move (viewIds_toAdd);
714+ }
715+ // for each landmark, add the previously identified observations
716+ #pragma omp parallel for
717+ for (int id = 0 ; id < viewScoresData.size (); id++)
718+ {
719+ auto & [viewIds, viewScores] = viewScoresData[id];
720+ const auto & viewIds_toAdd = viewScoresData_t[id];
721+ viewIds.insert (viewIds.end (), viewIds_toAdd.begin (), viewIds_toAdd.end ());
722+ viewScores.insert (viewScores.end (), viewIds_toAdd.size (), 0 .);
723+
724+ // sort by ascending view id order
725+ // for consequent faster access
726+
727+ // indices that sort the view ids
728+ std::vector<size_t > idx (viewIds.size ());
729+ std::iota (idx.begin (), idx.end (), 0 );
730+ std::stable_sort (idx.begin (), idx.end (), [&v = viewIds](size_t i1, size_t i2) { return v[i1] < v[i2]; });
731+ // apply sorting to both view ids and view scores for correspondance
732+ auto ids_temp = viewIds;
733+ auto scores_temp = viewScores;
734+ for (auto j = 0 ; j < viewIds.size (); j++)
735+ {
736+ viewIds[j] = ids_temp[idx[j]];
737+ viewScores[j] = scores_temp[idx[j]];
738+ }
739+ }
740+ ALICEVISION_LOG_INFO (" Augment initial observations based on neighbors observations: done" );
741+ }
742+
690743void computeNewScores (const std::vector<Landmark*>& landmarksData,
691744 const FilterParams::FilterObservations3DParams& params,
692745 const std::vector<std::pair<std::vector<size_t >, std::vector<double >>>& neighborsData,
@@ -808,6 +861,25 @@ void propagateNeighborsInfo(std::vector<Landmark*>& landmarksData,
808861 ALICEVISION_LOG_INFO (" Propagating neighbors observation scores: done" );
809862}
810863
864+ void removeNonObservedLandmarks (SfMData& sfmData)
865+ {
866+ // remove landmarks with no remaining observations
867+ ALICEVISION_LOG_INFO (" Remove non-observed landmarks: started" );
868+ const auto & initialNbLandmarks = sfmData.getLandmarks ().size ();
869+ for (auto it = sfmData.getLandmarks ().begin (); it != sfmData.getLandmarks ().end ();)
870+ {
871+ if (it->second .observations .size () == 0 )
872+ it = sfmData.getLandmarks ().erase (it);
873+ else
874+ ++it;
875+ }
876+ const auto & modifiedNbLandmarks = sfmData.getLandmarks ().size ();
877+ ALICEVISION_LOG_INFO (
878+ " Removed " << (initialNbLandmarks - modifiedNbLandmarks) << " landmarks out of " << initialNbLandmarks
879+ << " , i.e. " << ((initialNbLandmarks - modifiedNbLandmarks) * 100 .f / initialNbLandmarks) << " % " );
880+ ALICEVISION_LOG_INFO (" Remove non-observed landmarks: done" );
881+ }
882+
811883bool filterObservations3D (SfMData& sfmData, const FilterParams::FilterObservations3DParams& params)
812884{
813885 // store in vector for faster access
@@ -829,6 +901,7 @@ bool filterObservations3D(SfMData& sfmData, const FilterParams::FilterObservatio
829901 // contains the neighbor landmarks ids with their corresponding weights
830902 std::vector<std::pair<std::vector<size_t >, std::vector<double >>> neighborsData (landmarksData.size ());
831903 computeNeighborsInfo (landmarksData, params, neighborsData);
904+ augmentInitialObservations (viewScoresData, neighborsData);
832905 propagateNeighborsInfo (landmarksData, params, neighborsData, viewScoresData);
833906 }
834907
@@ -837,12 +910,12 @@ bool filterObservations3D(SfMData& sfmData, const FilterParams::FilterObservatio
837910 for (auto i = 0 ; i < landmarksData.size (); i++)
838911 {
839912 sfmData::Landmark& landmark = *landmarksData[i];
840- const auto & nbObservations = landmark.observations .size ();
841913 auto & [viewIds, viewScores] = viewScoresData[i];
914+ const auto & nbObservations = viewIds.size ();
842915
843- // check number of observations
844- if (landmark.observations .size () <= params.maxNbObservationsPerLandmark )
845- continue ;
916+ // // check number of observations
917+ // if(landmark.observations.size() <= params.maxNbObservationsPerLandmark)
918+ // continue;
846919
847920 // sort by descending view score order
848921 std::vector<size_t > idx (nbObservations);
@@ -854,16 +927,22 @@ bool filterObservations3D(SfMData& sfmData, const FilterParams::FilterObservatio
854927 // double threshold = 0.1 / params.maxNbObservationsPerLandmark;
855928 for (auto j = 0 ; j < params.maxNbObservationsPerLandmark ; j++)
856929 {
857- const auto & viewScore = viewScores[idx[j]];
930+ // const auto& viewScore = viewScores[idx[j]];
858931 /* if(viewScore < threshold)
859932 break;*/
933+
934+ // add observation only if it's an original observation and not augmented
860935 const auto & viewId = viewIds[idx[j]];
861- filteredObservations[viewId] = landmark.observations [viewId];
936+ const auto & obsIt = landmark.observations .find (viewId);
937+ if (obsIt != landmark.observations .end ())
938+ filteredObservations[viewId] = landmark.observations [viewId];
862939 }
863940 landmark.observations = std::move (filteredObservations);
864941 }
865942 ALICEVISION_LOG_INFO (" Selecting observations with best scores: done" );
866943
944+ removeNonObservedLandmarks (sfmData);
945+
867946 return true ;
868947}
869948
@@ -875,7 +954,6 @@ double filter2DView(SfMData& sfmData, const FilterParams::FilterObservations2DPa
875954 KdTree2D tree (2 , data, nanoflann::KDTreeSingleIndexAdaptorParams (MAX_LEAF_ELEMENTS));
876955 tree.buildIndex ();
877956
878- // note that the observation is a neighbor to itself with zero distance, hence the +/- 1
879957 size_t nbNeighbors_ = params.nbNeighbors2D ;
880958 // average neighbors distance for each observation
881959 std::vector<double > means (observations.size (), std::numeric_limits<double >::max ());
@@ -988,21 +1066,14 @@ bool filterObservations2D(SfMData& sfmData, const FilterParams::FilterObservatio
9881066 }
9891067 }
9901068 }
991- // remove landmarks with no remaining observations
992- for (auto it = sfmData.getLandmarks ().begin (); it != sfmData.getLandmarks ().end ();)
993- {
994- if (it->second .observations .size () == 0 )
995- it = sfmData.getLandmarks ().erase (it);
996- else
997- ++it;
998- }
1069+
1070+ removeNonObservedLandmarks (sfmData);
9991071
10001072 return true ;
10011073}
10021074
10031075int aliceVision_main (int argc, char *argv[])
10041076{
1005- std::cout << " hello" << std::endl;
10061077 // command-line parameters
10071078
10081079 std::string inputSfmFilename;
0 commit comments