% By Philip Torr 2002 % copyright Microsoft Corp. %this function allows for self calibration, it implements the Sturm method given in CVPR 2001 %following the steps of Sturm, first provide an f and CC %CC is an estimate of the self calibration parameters other than the focal length % % CC = [aspect_ratio * est_foc, 0 , pp_x; % 0, est_foc , pp_y; % 0, 0, 1/f_est] % % where est_foc is the estimate of the focal length % % G ~ C' F C %to get to the focal length we solve % G ~ diag (1,1,f) E diag (1,1,f) %how far is the focal length from our initial estimate : 1/CC(3,3) ? % well note the focal length we have calculated here is relative to our initial guess %therefore the true focal length is 1/CC(3,3) * focal_length % is we are a factor 5 out then we should start to worry function [focal_length, E, CC_out] = torr_self_calib_f(F,CC) temp_foc = CC(3,3); CC(3,3) = 1; if nargin < 2 G = F / norm(F); CC = diag(ones(3,1),0); else %step 3 G = CC' * F * CC; G = G / norm(G); end [U,S,V] = svd(G); if abs(S(3,3)) > 0.001 error('F must be rank 2 to self calibrate'); end %next construct the quadratic equation of Sturm % c1 f^4 + c2 f^2 + c3 = 0 a = S(1,1)^2; b = S(2,2)^2; c1 = a * (1 - U(3,1)^2) * (1 - V(3,1)^2) - b * (1 - U(3,2)^2) * (1 - V(3,2)^2); c2 = a *( U(3,1)^2 + V(3,1)^2 - 2 * U(3,1)^2 * V(3,1)^2) - b * (U(3,2)^2 + V(3,2)^2 - 2 * U(3,2)^2 * V(3,2)^2); c3 = a * U(3,1)^2 * V(3,1)^2 - b * U(3,2)^2 * V(3,2)^2; temp = sqrt(c2^2 - 4 * c1 * c3); %first need to check, have the equations degenerated to a linear, i.e is c1 small if (c1^2/(c2^2 + c3^2)) < 0.001 %then linear foc1 = -(U(3,2) * V(3,1) * (S(1,1) * U(3,1) * V(3,1) + S(2,2) * U(3,2) * V(3,2))) ... /(S(1,1) * U(3,1) * U(3,2) * (1 - V(3,1)^2) + (S(2,2) * V(3,1) * V(3,2) * (1 - U(3,2)^2) )); foc2 = -(V(3,2) * U(3,1) * (S(1,1) * U(3,1) * V(3,1) + S(2,2) * U(3,2) * V(3,2)) ) ... /(S(1,1) * V(3,1) * V(3,2) * (1 - U(3,1)^2) + (S(2,2) * U(3,1) * U(3,2) * (1 - V(3,2)^2) )); else foc1 = sqrt((-c2 + temp)/(2 * c1)); foc2 = sqrt((-c2 - temp)/(2 * c1)); end %we now have two solutions we need to eliminate one. To do this we resort to the linear equations, %simply multiply the two linear equations together and take the minimum absolute value. alg1 = abs( ... foc1^2 * (S(1,1) * U(3,1) * U(3,2) * (1 - V(3,1)^2) + (S(2,2) * V(3,1) * V(3,2) * (1 - U(3,2)^2) ))... + U(3,2) * V(3,1) * (S(1,1) * U(3,1) * V(3,1) + S(2,2) * U(3,2) * V(3,2)) ); alg2 = abs( ... foc1^2 * (S(1,1) * V(3,1) * V(3,2) * (1 - U(3,1)^2) + (S(2,2) * U(3,1) * U(3,2) * (1 - V(3,2)^2) ))... + V(3,2) * U(3,1) * (S(1,1) * U(3,1) * V(3,1) + S(2,2) * U(3,2) * V(3,2)) ); alg_foc1 = alg1 * alg2; alg1 = abs( ... foc1^2 * (S(1,1) * U(3,1) * U(3,2) * (1 - V(3,1)^2) + (S(2,2) * V(3,1) * V(3,2) * (1 - U(3,2)^2) ))... + U(3,2) * V(3,1) * (S(1,1) * U(3,1) * V(3,1) + S(2,2) * U(3,2) * V(3,2)) ); alg2 = abs( ... foc2^2 * (S(1,1) * V(3,1) * V(3,2) * (1 - U(3,1)^2) + (S(2,2) * U(3,1) * U(3,2) * (1 - V(3,2)^2) ))... + V(3,2) * U(3,1) * (S(1,1) * U(3,1) * V(3,1) + S(2,2) * U(3,2) * V(3,2)) ); alg_foc2 = alg1 * alg2; if ~isreal(foc1) focal_length = foc2; else if ~isreal(foc2) focal_length = foc1; end end if isreal(foc1) & isreal(foc2) if (alg_foc1 < alg_foc2) focal_length = foc1; else focal_length = foc2; end end %how far is the focal length from our initial estimate : 1/CC(3,3) ? % well note the focal length we have calculated here is relative to our initial guess %therefore the true focal length is 1/CC(3,3) * focal_length % is we are a factor of 5 out then we should start to worry if (~isreal(foc1) & ~isreal(foc2)) | (abs(focal_length ) > 5)| (abs(focal_length) < 0.2) focal_length focal_length = 1; disp('either bad F or needs a stronger calibration method'); disp('ooo vicar big fat focal length setting it to original guess'); end Cf = [1 0 0; 0 1 0; 0 0 1/focal_length]; CC = (Cf * CC); %now we need to get to the essential matrix which is C^t F C = E E = CC' * F * CC; %now remove estimate of the focal length effect focal_length = 1/CC(3,3); focal_length CC_out = CC; [U,S,V] = svd(E); %note that there is a one p[arameter family of SVD's for E if abs(S(3,3)) > 0.00001 error('E must be rank 2 to self calibrate'); end % if abs(S(1,1) - S(2,2)) > 0.00001 % S % % error('E must have two equal singular values'); % end %this a problem not pointed out in the Sturm paper, the essential matrix produced might have funny singular values %fix the bugga to have equal singular values: S(3,3) = 0; S(1,1) = S(2,2); E = U*S*V';