38 #include <Eigen/Geometry>
48 std::vector<FundamentalMatrixSevenPointEstimator::M_t>
50 const std::vector<X_t>& points1,
const std::vector<Y_t>& points2) {
51 CHECK_EQ(points1.size(), 7);
52 CHECK_EQ(points2.size(), 7);
57 Eigen::Matrix<double, 7, 9> A;
58 for (
size_t i = 0; i < 7; ++i) {
59 const double x0 = points1[i](0);
60 const double y0 = points1[i](1);
61 const double x1 = points2[i](0);
62 const double y1 = points2[i](1);
75 Eigen::JacobiSVD<Eigen::Matrix<double, 7, 9>> svd(A, Eigen::ComputeFullV);
76 const Eigen::Matrix<double, 9, 9> f = svd.matrixV();
77 Eigen::Matrix<double, 1, 9> f1 = f.col(7);
78 Eigen::Matrix<double, 1, 9> f2 = f.col(8);
85 const double t0 = f1(4) * f1(8) - f1(5) * f1(7);
86 const double t1 = f1(3) * f1(8) - f1(5) * f1(6);
87 const double t2 = f1(3) * f1(7) - f1(4) * f1(6);
88 const double t3 = f2(4) * f2(8) - f2(5) * f2(7);
89 const double t4 = f2(3) * f2(8) - f2(5) * f2(6);
90 const double t5 = f2(3) * f2(7) - f2(4) * f2(6);
93 coeffs(0) = f1(0) * t0 - f1(1) * t1 + f1(2) * t2;
94 coeffs(1) = f2(0) * t0 - f2(1) * t1 + f2(2) * t2 -
95 f2(3) * (f1(1) * f1(8) - f1(2) * f1(7)) +
96 f2(4) * (f1(0) * f1(8) - f1(2) * f1(6)) -
97 f2(5) * (f1(0) * f1(7) - f1(1) * f1(6)) +
98 f2(6) * (f1(1) * f1(5) - f1(2) * f1(4)) -
99 f2(7) * (f1(0) * f1(5) - f1(2) * f1(3)) +
100 f2(8) * (f1(0) * f1(4) - f1(1) * f1(3));
101 coeffs(2) = f1(0) * t3 - f1(1) * t4 + f1(2) * t5 -
102 f1(3) * (f2(1) * f2(8) - f2(2) * f2(7)) +
103 f1(4) * (f2(0) * f2(8) - f2(2) * f2(6)) -
104 f1(5) * (f2(0) * f2(7) - f2(1) * f2(6)) +
105 f1(6) * (f2(1) * f2(5) - f2(2) * f2(4)) -
106 f1(7) * (f2(0) * f2(5) - f2(2) * f2(3)) +
107 f1(8) * (f2(0) * f2(4) - f2(1) * f2(3));
108 coeffs(3) = f2(0) * t3 - f2(1) * t4 + f2(2) * t5;
110 Eigen::VectorXd roots_real;
111 Eigen::VectorXd roots_imag;
116 std::vector<M_t> models;
117 models.reserve(roots_real.size());
120 const double kMaxRootImag = 1
e-10;
121 if (std::abs(roots_imag(i)) > kMaxRootImag) {
125 const double lambda = roots_real(i);
128 Eigen::MatrixXd F = lambda * f1 + mu * f2;
132 const double kEps = 1
e-10;
133 if (std::abs(F(2, 2)) < kEps) {
139 models.push_back(F.transpose());
146 const std::vector<X_t>& points1,
const std::vector<Y_t>& points2,
147 const M_t& F, std::vector<double>* residuals) {
151 std::vector<FundamentalMatrixEightPointEstimator::M_t>
153 const std::vector<X_t>& points1,
const std::vector<Y_t>& points2) {
154 CHECK_EQ(points1.size(), points2.size());
157 std::vector<X_t> normed_points1;
158 std::vector<Y_t> normed_points2;
159 Eigen::Matrix3d points1_norm_matrix;
160 Eigen::Matrix3d points2_norm_matrix;
165 Eigen::Matrix<double, Eigen::Dynamic, 9> cmatrix(points1.size(), 9);
166 for (
size_t i = 0; i < points1.size(); ++i) {
167 cmatrix.block<1, 3>(i, 0) = normed_points1[i].homogeneous();
168 cmatrix.block<1, 3>(i, 0) *= normed_points2[i].
x();
169 cmatrix.block<1, 3>(i, 3) = normed_points1[i].homogeneous();
170 cmatrix.block<1, 3>(i, 3) *= normed_points2[i].
y();
171 cmatrix.block<1, 3>(i, 6) = normed_points1[i].homogeneous();
175 Eigen::JacobiSVD<Eigen::Matrix<double, Eigen::Dynamic, 9>> cmatrix_svd(
176 cmatrix, Eigen::ComputeFullV);
177 const Eigen::VectorXd cmatrix_nullspace = cmatrix_svd.matrixV().col(8);
178 const Eigen::Map<const Eigen::Matrix3d> ematrix_t(cmatrix_nullspace.data());
182 Eigen::JacobiSVD<Eigen::Matrix3d> fmatrix_svd(
183 ematrix_t.transpose(), Eigen::ComputeFullU | Eigen::ComputeFullV);
184 Eigen::Vector3d singular_values = fmatrix_svd.singularValues();
185 singular_values(2) = 0.0;
186 const Eigen::Matrix3d F = fmatrix_svd.matrixU() *
187 singular_values.asDiagonal() *
188 fmatrix_svd.matrixV().transpose();
190 const std::vector<M_t> models = {points2_norm_matrix.transpose() * F *
191 points1_norm_matrix};
196 const std::vector<X_t>& points1,
const std::vector<Y_t>& points2,
197 const M_t& E, std::vector<double>* residuals) {
static void Residuals(const std::vector< X_t > &points1, const std::vector< Y_t > &points2, const M_t &F, std::vector< double > *residuals)
static std::vector< M_t > Estimate(const std::vector< X_t > &points1, const std::vector< Y_t > &points2)
static void Residuals(const std::vector< X_t > &points1, const std::vector< Y_t > &points2, const M_t &F, std::vector< double > *residuals)
static std::vector< M_t > Estimate(const std::vector< X_t > &points1, const std::vector< Y_t > &points2)
bool FindPolynomialRootsCompanionMatrix(const Eigen::VectorXd &coeffs_all, Eigen::VectorXd *real, Eigen::VectorXd *imag)
void CenterAndNormalizeImagePoints(const std::vector< Eigen::Vector2d > &points, std::vector< Eigen::Vector2d > *normed_points, Eigen::Matrix3d *matrix)
void ComputeSquaredSampsonError(const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, const Eigen::Matrix3d &E, std::vector< double > *residuals)
Eigen::MatrixXd::Index Index