openMVG----multiview

这个模块包括:

  • 在多目视觉几何中,关于双目和多目几何约束的求解方案
  • 一般的框架“kernel”,可以包含求解方案,进行鲁棒估计

2-view solvers

提供以下几何约束估计的solver:

  • 仿射,
  • 单应,
  • 基本矩阵,
    • 7 点算法 ,
    • 8 点算法 (Direct Linear Transform) .
  • 本质矩阵,
    • 8 点算法 (Direct Linear Transform),
    • 5 点算法 + 已知内参.
//affine
  Mat x1(2, 4);
  x1 <<  0, 1, 2, 5,
         0, 1, 2, 3;

  double angle = 45.0;
  Mat3 rot;
  rot <<  cos(angle),  sin(angle), -2,
         -sin(angle),  cos(angle), 5,
          0,           0,          1;

  Mat x2 = x1;
  // Transform point from ground truth matrix
  for (int i = 0; i < x2.cols(); ++i)  {
    x2.block<2,1>(0,i) = rot.block<2,2>(0,0) *  x1.col(i);// rot
    x2.block<2,1>(0,i) += rot.block<2,1>(0,2); // translation
  }

  Mat3 affine_mat;
  Affine2DFromCorrespondencesLinear(x1, x2, &affine_mat);

//

N-View geometry estimation

  • 三角重构
    • 2 to n view (Direct Linear Transform),
    • 2 to n view (Iterated least square).
  • Rotation averaging(全局求解旋转)
    • L2 (sparse) ,
    • L1 (sparse) .
  • Translation averaging
    • L2 Chordal ,
    • SoftL1 ‘approximation of the LInf method of .
//triangulation
  const NViewDataSet d = NRealisticCamerasRing(2, 12); //2个相机,12个3D点
  for (int i = 0; i < d._X.cols(); ++i) {
    const Vec3 X_gt = d._X.col(i);
    Vec3 X_estimated;
    const Vec2 x1 = d._x[0].col(i);
    const Vec2 x2 = d._x[1].col(i);
    TriangulateDLT(d.P(0), x1.homogeneous(), d.P(1), x2.homogeneous(), &X_estimated);
  //多目三角重构
  const int nviews = 5;
  const int npoints = 6;
  const NViewDataSet d = NRealisticCamerasRing(nviews, npoints);

  // Collect P matrices together.
  std::vector<Mat34> Ps(nviews);
  for (int j = 0; j < nviews; ++j) {
    Ps[j] = d.P(j);
  }

  for (int i = 0; i < npoints; ++i) {
    // Collect the image of point i in each frame.
    Mat3X xs(3, nviews);
    for (int j = 0; j < nviews; ++j) {
      xs.col(j) = d._x[j].col(i).homogeneous();
    }
    Vec4 X;
    TriangulateNView(xs, Ps, &X);
  //TriangulateNViewAlgebraic(xs, Ps, &X)
    // Check reprojection error. Should be nearly zero.
    for (int j = 0; j < nviews; ++j) {
      const Vec3 x_reprojected = Ps[j]*X;
      const double error = (x_reprojected.hnormalized() - xs.col(j).hnormalized()).norm();
      EXPECT_NEAR(error, 0.0, 1e-9);
    }

//rotation averaging
  const Mat3 rotx = RotationAroundX(0.3);
  const Mat3 Approximative_rotx = rotation_averaging::l2::ClosestSVDRotationMatrix(rotx);

  const Mat3 R01 = RotationAroundZ(2.*M_PI/3.0); //120 degree
  const Mat3 R12 = RotationAroundZ(2.*M_PI/3.0); //120 degree
  const Mat3 R20 = RotationAroundZ(2.*M_PI/3.0); //120 degree

  std::vector<RelativeRotation > vec_relativeRotEstimate;
  vec_relativeRotEstimate.push_back( RelativeRotation(0,1, R01));
  vec_relativeRotEstimate.push_back( RelativeRotation(1,2, R12));
  vec_relativeRotEstimate.push_back( RelativeRotation(2,0, R20));
  //- Solve the global rotation estimation problem :
  std::vector<Mat3> vec_globalR;
  L2RotationAveraging(3, vec_relativeRotEstimate, vec_globalR);
  //l1:  GlobalRotationsRobust(vec_relativeRotEstimate, vec_globalR, nMainViewID, 0.0f, &vec_inliers)
  //可以判断出外点。需要注意R可能会相差一个‘-’号。这不影响最小化一致性
  Mat3 R;
  Vec3 t, t0 = Vec3::Zero(), t1 = Vec3::Zero();
  RelativeCameraMotion(vec_globalR[0], t0, vec_globalR[1], t1, &R, &t); //R==R01

//translation averaging

已知3D点,求P

  • 6pt Direct Linear Transform [HZ],
  • 3pt with intrinsic EPnP [Ke],
  • 3pt with intrinsic P3P [Kneip].

Kernel concept

利用了RANSAC(随机采样一致)的思想。kernel包括:

  • 数据
  • solver
  • 度量函数

c++技巧

//输出vector
std::copy(vec_inliers.begin(), vec_inliers.end(), std::ostream_iterator<bool>(std::cout, " "));
std::cout << std::endl;
//交换vector
vec_relativeRotEstimate.swap(vec_relativeRotEstimateTemp);

猜你喜欢

转载自blog.csdn.net/qq_28038207/article/details/84594790