📄 torr_self_calib_f.m
字号:
% 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';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -