@@ -252,6 +252,7 @@ bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale,
252252bool filterObservations (SfMData& sfmData, int maxNbObservationsPerLandmark, int nbNeighbors, double neighborsInfluence,
253253 int nbIterations)
254254{
255+ // store in vector for faster access
255256 std::vector<Landmark*> landmarksData (sfmData.getLandmarks ().size ());
256257 {
257258 size_t i = 0 ;
@@ -261,6 +262,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
261262 }
262263 }
263264
265+ // contains the observing view ids for each landmark with their corresponding scores
264266 std::vector<std::pair<std::vector<IndexT>, std::vector<double >>> viewScoresData (landmarksData.size ());
265267
266268 ALICEVISION_LOG_INFO (" Computing initial observation scores based on distance to observing view: started" );
@@ -270,11 +272,11 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
270272 const sfmData::Landmark& landmark = *landmarksData[i];
271273
272274 // compute observation scores
273-
274275 const auto & nbObservations = landmark.observations .size ();
275276 auto & [viewIds, viewScores] = viewScoresData[i];
276277 viewIds.reserve (nbObservations);
277278 viewScores.reserve (nbObservations);
279+ // accumulator for normalizing the scores
278280 double total = 0 .;
279281 for (const auto & observationPair : landmark.observations )
280282 {
@@ -283,6 +285,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
283285 const geometry::Pose3 pose = sfmData.getPose (view).getTransform ();
284286
285287 viewIds.push_back (viewId);
288+ // score is the inverse of distance to observations
286289 const auto & v = 1 . / (pose.center () - landmark.X ).squaredNorm ();
287290 total += v;
288291 viewScores.push_back (v);
@@ -296,9 +299,12 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
296299
297300 // sort by ascending view id order
298301 // for consequent faster access
302+
303+ // indices that sort the view ids
299304 std::vector<size_t > idx (nbObservations);
300305 std::iota (idx.begin (), idx.end (), 0 );
301306 std::stable_sort (idx.begin (), idx.end (), [&v = viewIds](size_t i1, size_t i2) { return v[i1] < v[i2]; });
307+ // apply sorting to both view ids and view scores for correspondance
302308 auto ids_temp = viewIds;
303309 auto scores_temp = viewScores;
304310 for (auto j = 0 ; j < nbObservations; j++)
@@ -317,6 +323,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
317323 ALICEVISION_LOG_INFO (" KdTree created for " << landmarksData.size () << " points." );
318324 // note that the landmark is a neighbor to itself with zero distance, hence the +/- 1
319325 int nbNeighbors_ = std::min (nbNeighbors, static_cast <int >(landmarksData.size () - 1 )) + 1 ;
326+ // contains the neighbor landmarks ids with their corresponding weights
320327 std::vector<std::pair<std::vector<size_t >, std::vector<double >>> neighborsData (landmarksData.size ());
321328#pragma omp parallel for
322329 for (auto i = 0 ; i < landmarksData.size (); i++)
@@ -329,12 +336,15 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
329336 // a landmark is a neighbor to itself with zero distance, remove it
330337 indices_.erase (indices_.begin ());
331338 weights_.erase (weights_.begin ());
339+ // accumulator used for normalisation
332340 double total = 0 .;
333341 for (auto & w : weights_)
334342 {
343+ // weight is the inverse of distance between a landmark and its neighbor
335344 w = 1 . / std::sqrt (w);
336345 total += w;
337346 }
347+ // normalize weights
338348 for (auto & w : weights_)
339349 {
340350 w /= total;
@@ -343,6 +353,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
343353 ALICEVISION_LOG_INFO (" Computing landmark neighbors and distance-based weights: done" );
344354
345355 ALICEVISION_LOG_INFO (" Propagating neighbors observation scores: started" );
356+ // new view scores at iteration t
346357 std::vector<std::vector<double >> viewScoresData_t (landmarksData.size ());
347358 for (auto i = 0 ; i < nbIterations; i++)
348359 {
@@ -352,14 +363,17 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
352363 {
353364 const auto & [viewIds, viewScores] = viewScoresData[id];
354365 auto & viewScores_acc = viewScoresData_t[id];
366+ // initialize to zero, will first contain the weighted average scores of neighbors
355367 viewScores_acc.assign (viewScores.size (), 0 .);
368+ // accumulator for normalisation
356369 double viewScores_total = 0 .;
357370 auto & [indices_, weights_] = neighborsData[id];
358371 for (auto j = 0 ; j < nbNeighbors; j++)
359372 {
360373 const auto & neighborId = indices_[j];
361374 const auto & neighborWeight = weights_[j];
362375 const auto & [viewIds_neighbor, viewScores_neighbor] = viewScoresData[neighborId];
376+ // loop over common views
363377 auto viewIds_it = viewIds.begin ();
364378 auto viewIds_neighbor_it = viewIds_neighbor.begin ();
365379 auto viewScores_neighbor_it = viewScores_neighbor.begin ();
@@ -373,6 +387,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
373387 }
374388 else
375389 {
390+ // if same view, accumulate weighted scores
376391 if (!(*viewIds_neighbor_it < *viewIds_it))
377392 {
378393 const auto & v = *viewScores_neighbor_it * neighborWeight;
@@ -388,10 +403,13 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
388403 }
389404 for (auto j = 0 ; j < viewScores_acc.size (); j++)
390405 {
406+ // normalize score and apply influence factor
391407 viewScores_acc[j] *= neighborsInfluence / viewScores_total;
408+ // combine weghted neighbor scores and the landmark's own scores
392409 viewScores_acc[j] += (1 - neighborsInfluence) * viewScores[j];
393410 }
394411 }
412+ // update scores at end of iteration
395413#pragma omp parallel for
396414 for (auto id = 0 ; id < landmarksData.size (); id++)
397415 {
@@ -417,7 +435,7 @@ bool filterObservations(SfMData& sfmData, int maxNbObservationsPerLandmark, int
417435 std::iota (idx.begin (), idx.end (), 0 );
418436 std::stable_sort (idx.begin (), idx.end (), [&v = viewScores](size_t i1, size_t i2) { return v[i1] > v[i2]; });
419437
420- // replace the observations
438+ // keep only observations with best scores
421439 Observations filteredObservations;
422440 for (auto j = 0 ; j < maxNbObservationsPerLandmark; j++)
423441 {
0 commit comments