void removeOutliersFromCameras()

in source/calibration/GeometricCalibration.cpp [407:467]


void removeOutliersFromCameras(
    std::vector<Overlap>& overlaps,
    const FeatureMap& featureMap,
    const std::vector<Trace>& traces,
    const std::vector<Camera>& cameras,
    const Camera::Real outlierFactor) {
  // compute reprojection errors for each camera
  std::vector<std::vector<Camera::Real>> errors =
      reprojectionErrors(overlaps, featureMap, traces, cameras);

  // compute median for each camera
  std::vector<Camera::Real> medians(ssize(errors));
  for (ssize_t i = 0; i < ssize(errors); ++i) {
    medians[i] = calcPercentile(errors[i]);
  }

  std::unordered_map<ImageId, int> outliers;

  // remove matches that neither endpoint wants to keep around
  std::vector<ssize_t> errorIdxs(ssize(errors), 0);
  int total = 0;
  int inlierTotal = 0;
  for (Overlap& overlap : overlaps) {
    if (!overlap.isIntraFrame()) {
      continue;
    }
    const std::reference_wrapper<const ImageId> images[2] = {overlap.images[0], overlap.images[1]};
    const int idxs[2] = {getCameraIndex(images[0]), getCameraIndex(images[1])};

    // move the inliers to front of overlap.matches and resize to fit
    int inliers = 0;
    for (const auto& match : overlap.matches) {
      bool inlier = false;
      for (ssize_t i = 0; i < ssize(match); ++i) {
        int cameraIndex = idxs[i];
        if (errors[cameraIndex][errorIdxs[cameraIndex]++] < medians[cameraIndex] * outlierFactor) {
          inlier = true;
        }
      }
      if (inlier) {
        overlap.matches[inliers++] = match;
      }
    }
    outliers[overlap.images[0]] += ssize(overlap.matches) - inliers;
    outliers[overlap.images[1]] += ssize(overlap.matches) - inliers;
    total += ssize(overlap.matches);
    overlap.matches.resize(inliers);
    inlierTotal += inliers;
  }

  // sanity check that we consumed all the errors
  for (ssize_t i = 0; i < ssize(errors); ++i) {
    CHECK_EQ(errorIdxs[i], ssize(errors[i]));
  }
  if (FLAGS_log_verbose) {
    for (const auto& p : outliers) {
      LOG(INFO) << folly::sformat("Removed {} outliers from {}", p.second, p.first);
    }
  }
  LOG(INFO) << folly::sformat("{} of {} matches were inliers", inlierTotal, total);
}