2 #ifndef vpgl_fm_compute_7_point_cxx_ 3 #define vpgl_fm_compute_7_point_cxx_ 14 # include <vcl_msvc_warnings.h> 25 if ( pr.size() < 7 || pl.size() < 7 ) {
26 std::cerr <<
"vpgl_fm_compute_7_point: Need at least 7 point pairs.\n" 27 <<
"Number in each set: " << pr.size() <<
", " << pl.size() << std::endl;
32 if ( pr.size() != pl.size() ) {
33 std::cerr <<
"vpgl_fm_compute_7_point: Need correspondence lists of same size.\n";
38 std::vector< vgl_homg_point_2d<double> > pr_norm, pl_norm;
43 for (
unsigned i = 0; i < pl.size(); i++ ) {
44 pr_norm.push_back( prnt*pr[i] );
45 pl_norm.push_back( plnt*pl[i] );
49 for (
unsigned i = 0; i < pl.size(); i++ ) {
50 pr_norm.push_back( pr[i] );
51 pl_norm.push_back( pl[i] );
57 for (
unsigned r = 0; r < pr_norm.size(); r++ ) {
58 design_matrix(r,0) = pr_norm[r].x()*pl_norm[r].x();
59 design_matrix(r,1) = pr_norm[r].y()*pl_norm[r].x();
60 design_matrix(r,2) = pr_norm[r].w()*pl_norm[r].x();
61 design_matrix(r,3) = pr_norm[r].x()*pl_norm[r].y();
62 design_matrix(r,4) = pr_norm[r].y()*pl_norm[r].y();
63 design_matrix(r,5) = pr_norm[r].w()*pl_norm[r].y();
64 design_matrix(r,6) = pr_norm[r].x()*pl_norm[r].w();
65 design_matrix(r,7) = pr_norm[r].y()*pl_norm[r].w();
66 design_matrix(r,8) = pr_norm[r].w()*pl_norm[r].w();
84 for (
unsigned int i = 0; i < roots.size(); i++) {
100 double a=F1(0,0), j=F2(0,0), aa=a-j,
101 b=F1(0,1), k=F2(0,1), bb=b-k,
102 c=F1(0,2),
l=F2(0,2), cc=c-
l,
103 d=F1(1,0),
m=F2(1,0), dd=d-
m,
104 e=F1(1,1), n=F2(1,1), ee=e-n,
105 f=F1(1,2), o=F2(1,2), ff=f-o,
106 g=F1(2,0), p=F2(2,0), gg=g-p,
107 h=F1(2,1), q=F2(2,1), hh=h-q,
108 i=F1(2,2), r=F2(2,2), ii=i-r;
110 double a1=ee*ii-ff*hh, b1=ee*r+ii*n-ff*q-hh*o, c1=r*n-o*q;
111 double d1=bb*ii-cc*hh, e1=bb*r+ii*k-cc*q-hh*
l, f1=r*k-
l*q;
112 double g1=bb*ff-cc*ee, h1=bb*o+ff*k-cc*n-ee*
l, i1=o*k-
l*n;
114 std::vector<double>
v;
115 v.push_back(aa*a1-dd*d1+gg*g1);
116 v.push_back(aa*b1+a1*j-dd*e1-d1*
m+gg*h1+g1*p);
117 v.push_back(aa*c1+b1*j-dd*f1-e1*
m+gg*i1+h1*p);
118 v.push_back(c1*j-f1*
m+i1*p);
128 double a =
v[1], b =
v[2], c =
v[3];
129 double s = (b > 0.0) ? 1.0 : -1.0;
130 double d = b * b - 4 * a * c;
133 if ( d > -1e-5 && d < 0)
137 return std::vector<double>();
139 double q = -0.5 * ( b + s * std::sqrt(d));
140 std::vector<double>
l;
l.push_back(q/a);
l.push_back(c/q);
149 double a =
v[0], b =
v[1], c =
v[2], d =
v[3];
152 double len = a*a + b*b + c*c + d*d;
153 if (std::abs(a*a/len) < 1e-6 )
156 b /= a; c /= a; d /= a; b /= 3;
158 double q = b*b - c/3;
159 double r = b*(b*b-c/2) + d/2;
163 std::vector<double> w;
164 double cbrt = (r<0) ? std::exp(std::log(-2*r)/3.0) : -std::exp(std::log(2*r)/3.0);
165 w.push_back(cbrt - b);
176 if ( -r + std::sqrt(d) >= 0 ) z = std::exp(std::log(-r + std::sqrt(d))/3.0);
177 else z = -std::exp(std::log(-r + std::sqrt(d))/3.0);
180 std::vector<double> w; w.push_back(z + q/z - b);
return w;
185 double theta = std::acos( r/q/c ) / 3;
186 std::vector<double>
l;
187 l.push_back(-2.0*c*std::cos(theta) - b);
188 l.push_back(-2.0*c*std::cos(theta + vnl_math::twopi/3) - b);
189 l.push_back(-2.0*c*std::cos(theta - vnl_math::twopi/3) - b);
194 #endif // vpgl_fm_compute_7_point_cxx_ vnl_matrix_fixed< T, 3, 3 > const & get_matrix() const
double const * data_block() const
static std::vector< double > get_coeffs(vnl_double_3x3 const &F1, vnl_double_3x3 const &F2)
The 7 point algorithm for computing a fundamental matrix from point correspondences.
vnl_matrix & normalize_rows()
static std::vector< double > solve_quadratic(std::vector< double > v)
vnl_matrix_fixed< T, num_cols, num_rows > transpose() const
vnl_vector< double > get_column(unsigned c) const
bool compute_from_points(std::vector< vgl_homg_point_2d< T > > const &points, bool isotropic=true)
static std::vector< double > solve_cubic(std::vector< double > v)
vnl_matrix< T > nullspace() const
bool compute(const std::vector< vgl_homg_point_2d< double > > &pr, const std::vector< vgl_homg_point_2d< double > > &pl, std::vector< vpgl_fundamental_matrix< double > * > &fm)
Compute from two sets of corresponding points.
const vnl_matrix_fixed< T, 3, 3 > & get_matrix() const
Get a copy of the FM in vnl form.
void set_matrix(const vpgl_proj_camera< T > &cr, const vpgl_proj_camera< T > &cl)