Пример #1
0
void Simulator::perturbProjections(Observations& obs, double sigma){

  for (Observations::iterator it = obs.begin(); it != obs.end(); ++it){

    double dx = Simulator::getGaussianSample(0,sigma);
    double dy = Simulator::getGaussianSample(0,sigma);

    ROS_WARN("observation moved by %f %f", dx,dy);

    CvPoint2D32f p = it->second;

    p.x += dx; // zero centered normal
    p.y += dy;

    obs[it->first] = p;

  }

}
  /// Robustly try to estimate the best 3D point using a ransac Scheme
  /// Return true for a successful triangulation
  bool robust_triangulation(
    const SfM_Data & sfm_data,
    const Observations & obs,
    Vec3 & X,
    const IndexT min_required_inliers = 3,
    const IndexT min_sample_index = 3) const
  {
    const double dThresholdPixel = 4.0; // TODO: make this parameter customizable

    const IndexT nbIter = obs.size(); // TODO: automatic computation of the number of iterations?

    // - Ransac variables
    Vec3 best_model;
    std::set<IndexT> best_inlier_set;
    double best_error = std::numeric_limits<double>::max();

    // - Ransac loop
    for (IndexT i = 0; i < nbIter; ++i)
    {
      std::vector<size_t> vec_samples;
      robust::UniformSample(min_sample_index, obs.size(), &vec_samples);
      const std::set<IndexT> samples(vec_samples.begin(), vec_samples.end());

      // Hypothesis generation.
      const Vec3 current_model = track_sample_triangulation(sfm_data, obs, samples);

      // Test validity of the hypothesis
      // - chierality (for the samples)
      // - residual error

      // Chierality (Check the point is in front of the sampled cameras)
      bool bChierality = true;
      for (auto& it : samples){
        Observations::const_iterator itObs = obs.begin();
        std::advance(itObs, it);
      	const View * view = sfm_data.views.at(itObs->first).get();
        const IntrinsicBase * cam = sfm_data.getIntrinsics().at(view->id_intrinsic).get();
        const Pose3 & pose = sfm_data.poses.at(view->id_pose);
        const double z = pose.depth(current_model); // TODO: cam->depth(pose(X));
        bChierality &= z > 0;
      }

      if (!bChierality)
        continue;

      std::set<IndexT> inlier_set;
      double current_error = 0.0;
      // Classification as inlier/outlier according pixel residual errors.
      for (Observations::const_iterator itObs = obs.begin();
          itObs != obs.end(); ++itObs)
      {
        const View * view = sfm_data.views.at(itObs->first).get();
        const IntrinsicBase * intrinsic = sfm_data.getIntrinsics().at(view->id_intrinsic).get();
        const Pose3 & pose = sfm_data.poses.at(view->id_pose);
        const Vec2 residual = intrinsic->residual(pose, current_model, itObs->second.x);
        const double residual_d = residual.norm();
        if (residual_d < dThresholdPixel)
        {
          inlier_set.insert(itObs->first);
          current_error += residual_d;
        }
        else
        {
          current_error += dThresholdPixel;
        }
      }
      // Does the hypothesis is the best one we have seen and have sufficient inliers.
      if (current_error < best_error && inlier_set.size() >= min_required_inliers)
      {
        X = best_model = current_model;
        best_inlier_set = inlier_set;
        best_error = current_error;
      }
    }
    return !best_inlier_set.empty();
  }