@@ -8,99 +8,63 @@ void focalsFromHomography(const Mat& H, double &f0, double &f1, bool &f0_ok, boo
88{
99 CV_Assert (H.type () == CV_64F && H.size () == Size (3 , 3 ));
1010
11- const double h[9 ] =
12- {
13- H.at <double >(0 , 0 ), H.at <double >(0 , 1 ), H.at <double >(0 , 2 ),
14- H.at <double >(1 , 0 ), H.at <double >(1 , 1 ), H.at <double >(1 , 2 ),
15- H.at <double >(2 , 0 ), H.at <double >(2 , 1 ), H.at <double >(2 , 2 )
16- };
11+ const double * h = reinterpret_cast <const double *>(H.data );
12+
13+ double d1, d2; // Denominators
14+ double v1, v2; // Focal squares value candidates
1715
1816 f1_ok = true ;
19- double denom1 = h[6 ] * h[7 ];
20- double denom2 = (h[7 ] - h[6 ]) * (h[7 ] + h[6 ]);
21- if (max (abs (denom1), abs (denom2)) < 1e-5 )
22- f1_ok = false ;
23- else
24- {
25- double val1 = -(h[0 ] * h[1 ] + h[3 ] * h[4 ]) / denom1;
26- double val2 = (h[0 ] * h[0 ] + h[3 ] * h[3 ] - h[1 ] * h[1 ] - h[4 ] * h[4 ]) / denom2;
27- if (val1 < val2)
28- swap (val1, val2);
29- if (val1 > 0 && val2 > 0 )
30- f1 = sqrt (abs (denom1) > abs (denom2) ? val1 : val2);
31- else if (val1 > 0 )
32- f1 = sqrt (val1);
33- else
34- f1_ok = false ;
35- }
17+ d1 = h[6 ] * h[7 ];
18+ d2 = (h[7 ] - h[6 ]) * (h[7 ] + h[6 ]);
19+ v1 = -(h[0 ] * h[1 ] + h[3 ] * h[4 ]) / d1;
20+ v2 = (h[0 ] * h[0 ] + h[3 ] * h[3 ] - h[1 ] * h[1 ] - h[4 ] * h[4 ]) / d2;
21+ if (v1 < v2) swap (v1, v2);
22+ if (v1 > 0 && v2 > 0 ) f1 = sqrt (abs (d1) > abs (d2) ? v1 : v2);
23+ else if (v1 > 0 ) f1 = sqrt (v1);
24+ else f1_ok = false ;
3625
3726 f0_ok = true ;
38- denom1 = h[0 ] * h[3 ] + h[1 ] * h[4 ];
39- denom2 = h[0 ] * h[0 ] + h[1 ] * h[1 ] - h[3 ] * h[3 ] - h[4 ] * h[4 ];
40- if (max (abs (denom1), abs (denom2)) < 1e-5 )
41- f0_ok = false ;
42- else
43- {
44- double val1 = -h[2 ] * h[5 ] / denom1;
45- double val2 = (h[5 ] * h[5 ] - h[2 ] * h[2 ]) / denom2;
46- if (val1 < val2)
47- swap (val1, val2);
48- if (val1 > 0 && val2 > 0 )
49- f0 = sqrt (abs (denom1) > abs (denom2) ? val1 : val2);
50- else if (val1 > 0 )
51- f0 = sqrt (val1);
52- else
53- f0_ok = false ;
54- }
27+ d1 = h[0 ] * h[3 ] + h[1 ] * h[4 ];
28+ d2 = h[0 ] * h[0 ] + h[1 ] * h[1 ] - h[3 ] * h[3 ] - h[4 ] * h[4 ];
29+ v1 = -h[2 ] * h[5 ] / d1;
30+ v2 = (h[5 ] * h[5 ] - h[2 ] * h[2 ]) / d2;
31+ if (v1 < v2) swap (v1, v2);
32+ if (v1 > 0 && v2 > 0 ) f0 = sqrt (abs (d1) > abs (d2) ? v1 : v2);
33+ else if (v1 > 0 ) f0 = sqrt (v1);
34+ else f0_ok = false ;
5535}
5636
5737
58- bool focalsFromFundamental (const Mat &F, double &f0, double &f1)
38+ double estimateFocal (const vector<Mat> &images, const vector<ImageFeatures> &/* features*/ ,
39+ const vector<MatchesInfo> &pairwise_matches)
5940{
60- CV_Assert (F.type () == CV_64F);
61- CV_Assert (F.size () == Size (3 , 3 ));
62-
63- Mat Ft = F.t ();
64- Mat k = Mat::zeros (3 , 1 , CV_64F);
65- k.at <double >(2 , 0 ) = 1 .f ;
41+ const int num_images = static_cast <int >(images.size ());
6642
67- // 1. Compute quantities
68- double a = normL2sq (F*Ft*k) / normL2sq (Ft*k);
69- double b = normL2sq (Ft*F*k) / normL2sq (F*k);
70- double c = sqr (k.dot (F*k)) / (normL2sq (Ft*k) * normL2sq (F*k));
71- double d = k.dot (F*Ft*F*k) / k.dot (F*k);
72- double A = 1 /c + a - 2 *d;
73- double B = 1 /c + b - 2 *d;
74- double P = 2 *(1 /c - 2 *d + 0.5 *normL2sq (F));
75- double Q = -(A + B)/c + 0.5 *(normL2sq (F*Ft) - 0.5 *sqr (normL2sq (F)));
76-
77- // 2. Solve quadratic equation Z*Z*a_ + Z*b_ + c_ = 0
78- double a_ = 1 + c*P;
79- double b_ = -(c*P*P + 2 *P + 4 *c*Q);
80- double c_ = P*P + 4 *c*P*Q + 12 *A*B;
81- double D = b_*b_ - 4 *a_*c_;
82- if (abs (D) < 1e-5 )
83- D = 0 ;
84- else if (D < 0 )
85- return false ;
86- double D_sqrt = sqrt (D);
87- double Z0 = (-b_ - D_sqrt) / (2 *a_);
88- double Z1 = (-b_ + D_sqrt) / (2 *a_);
89-
90- // 3. Choose solution
91- double w0 = abs (Z0*Z0*Z0 - 3 *P*Z0*Z0 + 2 *(P*P + 2 *Q)*Z0 - 4 *(P*Q + 4 *A*B/c));
92- double w1 = abs (Z1*Z1*Z1 - 3 *P*Z1*Z1 + 2 *(P*P + 2 *Q)*Z1 - 4 *(P*Q + 4 *A*B/c));
93- double Z = Z0;
94- if (w1 < w0)
95- Z = Z1;
43+ vector<double > focals;
44+ for (int src_idx = 0 ; src_idx < num_images; ++src_idx)
45+ {
46+ for (int dst_idx = 0 ; dst_idx < num_images; ++dst_idx)
47+ {
48+ const MatchesInfo &m = pairwise_matches[src_idx*num_images + dst_idx];
49+ if (m.H .empty ())
50+ continue ;
9651
97- // 4.
98- double X = -1 /c*(1 + 2 *B/(Z - P));
99- double Y = -1 /c*(1 + 2 *A/(Z - P));
52+ double f0, f1;
53+ bool f0ok, f1ok;
54+ focalsFromHomography (m.H , f0, f1, f0ok, f1ok);
55+ if (f0ok && f1ok) focals.push_back (sqrt (f0*f1));
56+ }
57+ }
10058
101- // 5. Compute focal lengths
102- f0 = 1 /sqrt (1 + X/normL2sq (Ft*k));
103- f1 = 1 /sqrt (1 + Y/normL2sq (F*k));
59+ if (focals.size () + 1 >= images.size ())
60+ {
61+ nth_element (focals.begin (), focals.end (), focals.begin () + focals.size ()/2 );
62+ return focals[focals.size ()/2 ];
63+ }
10464
105- return true ;
65+ LOGLN (" Can't estimate focal length, will use naive approach" );
66+ double focals_sum = 0 ;
67+ for (int i = 0 ; i < num_images; ++i)
68+ focals_sum += images[i].rows + images[i].cols ;
69+ return focals_sum / num_images;
10670}
0 commit comments