std::unordered_set BAHelpers::DirectShotNeighbors()

in opensfm/src/sfm/src/ba_helpers.cc [69:113]


std::unordered_set<map::Shot*> BAHelpers::DirectShotNeighbors(
    map::Map& map, const std::unordered_set<map::Shot*>& shot_ids,
    const size_t min_common_points, const size_t max_neighbors) {
  std::unordered_set<map::Landmark*> points;
  for (auto* shot : shot_ids) {
    for (const auto& lm_obs : shot->GetLandmarkObservations()) {
      points.insert(lm_obs.first);
    }
  }

  std::unordered_map<map::Shot*, size_t> common_points;
  for (auto* pt : points) {
    for (const auto& neighbor_p : pt->GetObservations()) {
      auto* shot = neighbor_p.first;
      if (shot_ids.find(shot) == shot_ids.end()) {
        ++common_points[shot];
      }
    }
  }

  std::vector<std::pair<map::Shot*, size_t>> pairs(common_points.begin(),
                                                   common_points.end());
  std::sort(pairs.begin(), pairs.end(),
            [](const std::pair<map::Shot*, size_t>& val1,
               const std::pair<map::Shot*, size_t>& val2) {
              return val1.second > val2.second;
            });

  const size_t max_n = std::min(max_neighbors, pairs.size());
  std::unordered_set<map::Shot*> neighbors;
  size_t idx = 0;
  for (auto& p : pairs) {
    if (p.second >= min_common_points && idx < max_n) {
      const auto instance_shots =
          map.GetRigInstance(p.first->GetRigInstanceId()).GetShotIDs();
      for (const auto& s : instance_shots) {
        neighbors.insert(&map.GetShot(s));
      }
    } else {
      break;
    }
    ++idx;
  }
  return neighbors;
}