void FourPointSolver::Solve(const Mat &x, const Mat &y, vector<Mat3> *Hs) {
  assert(2 == x.rows());
  assert(4 <= x.cols());
  assert(x.rows() == y.rows());
  assert(x.cols() == y.cols());

  Mat::Index n = x.cols();

  Vec9 h;
  if (n == 4)  {
    // In the case of minimal configuration we use fixed sized matrix to let
    //  Eigen and the compiler doing the maximum of optimization.
    typedef Eigen::Matrix<double, 16, 9> Mat16_9;
    Mat16_9 L = Mat::Zero(16, 9);
    BuildActionMatrix(L, x, y);
    Nullspace(&L, &h);
  }
  else {
    MatX9 L = Mat::Zero(n * 2, 9);
    BuildActionMatrix(L, x, y);
    Nullspace(&L, &h);
  }
  Mat3 H = Map<RMat3>(h.data()); // map the linear vector as the H matrix
  Hs->push_back(H);
}
			void PointWithNegativeDepth::Solve(const Mat &x1, const Mat &x2, vector<Mat3> *Es) {
				assert(2 == x1.rows());
				assert(8 <= x1.cols());
				assert(x1.rows() == x2.rows());
				assert(x1.cols() == x2.cols());

				MatX9 A(x1.cols(), 9);
				fundamental::EncodeEpipolarEquation(x1, x2, &A);

				Vec9 e;
				Nullspace(&A, &e);
				Mat3 E = Map<RMat3>(e.data());

				// Find the closest essential matrix to E in frobenius norm
				// E = UD'VT
				if (x1.cols() > 8) {
					Eigen::JacobiSVD<Mat3> USV(E, Eigen::ComputeFullU | Eigen::ComputeFullV);
					Vec3 d = USV.singularValues();
					double a = d[0];
					double b = d[1];
					d << (a + b) / 2., (a + b) / 2., 0.0;
					E = USV.matrixU() * d.asDiagonal() * USV.matrixV().transpose();
				}
				Es->push_back(E);
			}
Ejemplo n.º 3
0
  void TriangulateNViewAlgebraic(const Mat2X &x,
    const std::vector< Mat34 > &Ps,
    Vec4 *X) {
      const Mat2X::Index nviews = x.cols();
      assert(static_cast<size_t>(nviews) == Ps.size());

      Mat design(2*nviews, 4);
      for (int i = 0; i < nviews; i++) {
        design.block<2, 4>(2*i, 0) = SkewMatMinimal(x.col(i)) * Ps[i];
      }
      Nullspace(&design, X);
  }
Ejemplo n.º 4
0
  void TriangulateNView(const Mat2X &x,
    const std::vector< Mat34 > &Ps,
    Vec4 *X) {
      const Mat2X::Index nviews = x.cols();
      assert(static_cast<size_t>(nviews) == Ps.size());

      Mat design = Mat::Zero(3*nviews, 4 + nviews);
      for (int i = 0; i < nviews; i++) {
        design.block<3, 4>(3*i, 0) = -Ps[i];
        design(3*i + 0, 4 + i) = x(0, i);
        design(3*i + 1, 4 + i) = x(1, i);
        design(3*i + 2, 4 + i) = 1.0;
      }
      Vec X_and_alphas;
      Nullspace(&design, &X_and_alphas);
      *X = X_and_alphas.head(4);
  }
Ejemplo n.º 5
0
double Nullspace
(
  const Eigen::Ref<const Mat> & A,
  Eigen::Ref<Vec> nullspace
)
{
  if ( A.rows() >= A.cols() )
  {
    Eigen::JacobiSVD<Mat> svd( A, Eigen::ComputeFullV );
    nullspace = svd.matrixV().col( A.cols() - 1 );
    return svd.singularValues()( A.cols() - 1 );
  }
  // Extend A with rows of zeros to make it square. It's a hack, but it is
  // necessary until Eigen supports SVD with more columns than rows.
  Mat A_extended( A.cols(), A.cols() );
  A_extended.block( A.rows(), 0, A.cols() - A.rows(), A.cols() ).setZero();
  A_extended.block( 0, 0, A.rows(), A.cols() ) = A;
  return Nullspace( A_extended, nullspace );
}