@@ -215,7 +215,8 @@ ObservationsPerView getObservationsPerViews(SfMData& sfmData)
215
215
return observationsPerView;
216
216
}
217
217
218
- bool filterLandmarks (SfMData& sfmData, double radiusScale, bool useFeatureScale, int minNbObservationsPerLandmark)
218
+ bool filterLandmarks (SfMData& sfmData, double radiusScale, bool useFeatureScale, int minNbObservationsPerLandmark,
219
+ int nbNeighbors3D, int maxNbObservationsPerLandmark)
219
220
{
220
221
const auto initialNbLandmarks = sfmData.getLandmarks ().size ();
221
222
std::vector<Landmark> landmarksData (initialNbLandmarks);
@@ -255,11 +256,8 @@ bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale,
255
256
tree.buildIndex ();
256
257
ALICEVISION_LOG_INFO (" KdTree created for " << landmarksData.size () << " points." );
257
258
258
- // TODO as parameter
259
- int nbNeighbors3D = 10 ;
260
259
// note that the landmark is a neighbor to itself with zero distance, hence the +/- 1
261
260
int nbNeighbors_ = std::min (nbNeighbors3D, static_cast <int >(landmarksData.size () - 1 )) + 1 ;
262
-
263
261
// contains the observing view ids and neighbors for each landmark
264
262
std::vector<std::pair<std::vector<IndexT>, std::vector<size_t >>> viewData (landmarksData.size ());
265
263
@@ -287,8 +285,6 @@ bool filterLandmarks(SfMData& sfmData, double radiusScale, bool useFeatureScale,
287
285
288
286
std::vector<bool > toRemove (landmarksData.size (), false );
289
287
size_t nbToRemove = 0 ;
290
- // TODO as parameter
291
- int maxNbObservationsPerLandmark = 2 ;
292
288
const auto initialNbLandmarks = sfmData.getLandmarks ().size ();
293
289
#pragma omp parallel for reduction(+ : nbToRemove)
294
290
for (auto i = 0 ; i < landmarksData.size (); i++)
@@ -552,7 +548,6 @@ bool filterObservations3D(SfMData& sfmData, int maxNbObservationsPerLandmark, in
552
548
std::vector<std::vector<double >> viewScoresData_t (landmarksData.size ());
553
549
for (auto i = 0 ; i < nbIterations; i++)
554
550
{
555
- ALICEVISION_LOG_INFO (" Iteration " << i << " ..." );
556
551
#pragma omp parallel for
557
552
for (auto id = 0 ; id < landmarksData.size (); id++)
558
553
{
@@ -603,23 +598,44 @@ bool filterObservations3D(SfMData& sfmData, int maxNbObservationsPerLandmark, in
603
598
{
604
599
// normalize score and apply influence factor
605
600
viewScores_acc[j] *= neighborsInfluence / viewScores_total;
606
- // combine weghted neighbor scores and the landmark's own scores
601
+ // combine weighted neighbor scores and the landmark's own scores
607
602
viewScores_acc[j] += (1 - neighborsInfluence) * viewScores[j];
608
603
}
604
+ // dampen scores of non-chosen observations
605
+ if (viewScores_acc.size () <= maxNbObservationsPerLandmark)
606
+ continue ;
607
+ // sort by descending view score order
608
+ std::vector<size_t > idx (viewScores_acc.size ());
609
+ std::iota (idx.begin (), idx.end (), 0 );
610
+ std::stable_sort (idx.begin (), idx.end (),
611
+ [&v = viewScores_acc](size_t i1, size_t i2) { return v[i1] > v[i2]; });
612
+ viewScores_total = 1 .;
613
+ for (auto j = maxNbObservationsPerLandmark; j < viewScores_acc.size (); j++)
614
+ {
615
+ const double & v = 0.5 * viewScores_acc[j];
616
+ viewScores_acc[j] = v;
617
+ viewScores_total -= v;
618
+ }
619
+ // re-normalize
620
+ for (auto j = 0 ; j < viewScores_acc.size (); j++)
621
+ viewScores_acc[j] /= viewScores_total;
609
622
}
610
623
// update scores at end of iteration
611
624
double error = 0 .;
612
625
#pragma omp parallel for reduction(+:error)
613
626
for (auto id = 0 ; id < landmarksData.size (); id++)
614
627
{
615
- double error_j = 0 .;
616
- for (auto j = 0 ; j < viewScoresData_t[id].size (); j++)
628
+ // compute MSE
617
629
{
618
- const auto & v = viewScoresData_t[id][j] - viewScoresData[id].second [j];
619
- error_j += v * v;
630
+ double error_j = 0 .;
631
+ for (auto j = 0 ; j < viewScoresData_t[id].size (); j++)
632
+ {
633
+ const auto & v = viewScoresData_t[id][j] - viewScoresData[id].second [j];
634
+ error_j += v * v;
635
+ }
636
+ error_j /= viewScoresData_t[id].size ();
637
+ error += error_j;
620
638
}
621
- error_j /= viewScoresData_t[id].size ();
622
- error += error_j;
623
639
viewScoresData[id].second = std::move (viewScoresData_t[id]);
624
640
}
625
641
error /= landmarksData.size ();
@@ -850,7 +866,8 @@ int aliceVision_main(int argc, char *argv[])
850
866
if (radiusScale > 0 || minNbObservationsPerLandmark > 0 )
851
867
{
852
868
ALICEVISION_LOG_INFO (" Filtering landmarks: started." );
853
- filterLandmarks (sfmData, radiusScale, useFeatureScale, minNbObservationsPerLandmark);
869
+ filterLandmarks (sfmData, radiusScale, useFeatureScale, minNbObservationsPerLandmark, nbNeighbors3D,
870
+ maxNbObservationsPerLandmark);
854
871
ALICEVISION_LOG_INFO (" Filtering landmarks: done." );
855
872
}
856
873
0 commit comments