@@ -544,56 +544,65 @@ bool filterObservations2D(SfMData& sfmData, int nbNeighbors2D, float percentile,
544544 const IndexT viewId = *itView;
545545
546546 auto & observationsIt = observationsPerView.find (viewId);
547- if (observationsIt != observationsPerView.end ())
548- {
549- auto & observations = observationsIt->second .first ;
550- auto & landmarks = observationsIt->second .second ;
547+ if (observationsIt == observationsPerView.end ())
548+ continue ;
551549
552- ALICEVISION_LOG_INFO (" Build nanoflann KdTree index for projected landmarks in 2D." );
553- ObservationsAdaptator data (observations);
554- KdTree2D tree (2 , data, nanoflann::KDTreeSingleIndexAdaptorParams (MAX_LEAF_ELEMENTS));
555- tree.buildIndex ();
556- ALICEVISION_LOG_INFO (" KdTree created for " << observations.size () << " points." );
557-
558- // note that the observation is a neighbor to itself with zero distance, hence the +/- 1
559- size_t nbNeighbors_ = std::min (static_cast <size_t >(nbNeighbors2D), observations.size () - 1 ) + 1 ;
560- std::vector<double > means (observations.size ());
561- const std::size_t cacheSize = 1000 ;
562- accumulator_set<double , stats<tag::tail_quantile<right>, tag::mean>> acc (tag::tail<right>::cache_size =
563- cacheSize);
564- for (auto j = 0 ; j < observations.size (); j++)
550+ auto & observations = observationsIt->second .first ;
551+ auto & landmarks = observationsIt->second .second ;
552+
553+ ALICEVISION_LOG_INFO (" Build nanoflann KdTree index for projected landmarks in 2D." );
554+ ObservationsAdaptator data (observations);
555+ KdTree2D tree (2 , data, nanoflann::KDTreeSingleIndexAdaptorParams (MAX_LEAF_ELEMENTS));
556+ tree.buildIndex ();
557+ ALICEVISION_LOG_INFO (" KdTree created for " << observations.size () << " points." );
558+
559+ // note that the observation is a neighbor to itself with zero distance, hence the +/- 1
560+ size_t nbNeighbors_ = std::min (static_cast <size_t >(nbNeighbors2D), observations.size () - 1 ) + 1 ;
561+ std::vector<double > means (observations.size ());
562+ const std::size_t cacheSize = 1000 ;
563+ accumulator_set<double , stats<tag::tail_quantile<right>, tag::mean>> acc (tag::tail<right>::cache_size =
564+ cacheSize);
565+ for (auto j = 0 ; j < observations.size (); j++)
566+ {
567+ const auto & obs = *observations[j];
568+ std::vector<size_t > indices_ (nbNeighbors_);
569+ std::vector<double > distances_ (nbNeighbors_);
570+ tree.knnSearch (obs.x .data (), nbNeighbors_, &indices_[0 ], &distances_[0 ]);
571+
572+ std::transform (distances_.begin (), distances_.end (), distances_.begin (),
573+ static_cast <double (*)(double )>(std::sqrt));
574+ const auto & mean = std::accumulate (distances_.begin (), distances_.end (), 0.0 ) / (nbNeighbors_ - 1 );
575+ means[j] = mean;
576+ acc (mean);
577+ }
578+ double mean_max = std::numeric_limits<double >::max ();
579+ if (percentile != 1 .f )
580+ mean_max = quantile (acc, quantile_probability = percentile);
581+
582+ double radius = mean (acc);
583+ // check if estimated radius is too large
584+ {
585+ const View& view = *(sfmData.getViews ().at (viewId));
586+ double radiusMax = 0.15 * 0.5 * (view.getImage ().getWidth () + view.getImage ().getHeight ());
587+ if (radius > radiusMax)
588+ radius = radiusMax;
589+ }
590+ estimatedRadii_[i] = radius;
591+
592+ std::vector<const Observation*> filteredObservations;
593+ std::vector<Landmark*> filteredLandmarks;
594+ filteredObservations.reserve (observations.size ());
595+ filteredLandmarks.reserve (landmarks.size ());
596+ for (auto j = 0 ; j < observations.size (); j++)
597+ if (means[j] < mean_max)
565598 {
566- const auto & obs = *observations[j];
567- std::vector<size_t > indices_ (nbNeighbors_);
568- std::vector<double > distances_ (nbNeighbors_);
569- tree.knnSearch (obs.x .data (), nbNeighbors_, &indices_[0 ], &distances_[0 ]);
570-
571- std::transform (distances_.begin (), distances_.end (), distances_.begin (),
572- static_cast <double (*)(double )>(std::sqrt));
573- const auto & mean = std::accumulate (distances_.begin (), distances_.end (), 0.0 ) / (nbNeighbors_ - 1 );
574- means[j] = mean;
575- acc (mean);
599+ filteredObservations.push_back (observations[j]);
600+ filteredLandmarks.push_back (landmarks[j]);
576601 }
577- double mean_max = std::numeric_limits<double >::max ();
578- if (percentile != 1 .f )
579- mean_max = quantile (acc, quantile_probability = percentile);
580- estimatedRadii_[i] = mean (acc);
581-
582- std::vector<const Observation*> filteredObservations;
583- std::vector<Landmark*> filteredLandmarks;
584- filteredObservations.reserve (observations.size ());
585- filteredLandmarks.reserve (landmarks.size ());
586- for (auto j = 0 ; j < observations.size (); j++)
587- if (means[j] < mean_max)
588- {
589- filteredObservations.push_back (observations[j]);
590- filteredLandmarks.push_back (landmarks[j]);
591- }
592- filteredObservations.shrink_to_fit ();
593- filteredLandmarks.shrink_to_fit ();
594- observations = std::move (filteredObservations);
595- landmarks = std::move (filteredLandmarks);
596- }
602+ filteredObservations.shrink_to_fit ();
603+ filteredLandmarks.shrink_to_fit ();
604+ observations = std::move (filteredObservations);
605+ landmarks = std::move (filteredLandmarks);
597606 }
598607
599608 for (auto & landmark : sfmData.getLandmarks ())
0 commit comments