Skip to content

Commit 190f42f

Browse files
committed
[WIP][filterSfM] add limit check on estimated 2D radius
1 parent c819386 commit 190f42f

File tree

1 file changed

+56
-47
lines changed

1 file changed

+56
-47
lines changed

src/software/pipeline/main_filterSfM.cpp

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)