% By Philip Torr 2002 % copyright Microsoft Corp. %takes an essential matrix and a set of corrected matches, and outputs projection matrices, 3D points etc %all via linear estimation; need camera calibration matrix too function [P1,P2,R,t,rot_axis,rot_angle,g] = torr_linear_EtoPX(E,matches,C,m3) %stage 1 generate twisted pairs etc [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 error('E must have two equal singular values'); end %use Hartley matrices: W = [0 -1 0; 1 0 0; 0 0 1]; Z = [0 1 0; -1 0 0; 0 0 0]; Tx = U * Z * U'; R1 = U * W * V'; R2 = U * W' * V'; R1 = R1 * sign(det(R1)) * sign(det(C)); R2 = R2 * sign(det(R2)) * sign(det(C)); %the left epipole is, which gives the direction of translation u3 = U(:,3); %such that u3' * E = 0, %next establish the four possible camera matrix pairs as points out in Maybank, Hartley & zisserman etc %first camera is 3x4 at origin of the world system. P1 = [C'; 0,0,0]'; %given this there are four choices for the second, we normalize them so that the %determinant of the first 3x3 is greater than zero, this is useful for determining chierality later P21 = C * [ R1'; u3']'; P22 = C * [ R1'; -u3']'; P23 = C * [ R2'; u3']'; P24 = C * [ R2'; -u3']'; %next we take one point to determine the chierality of the camera X1 = torr_triangulate(matches, m3, P1, P21); X2 = torr_triangulate(matches, m3, P1, P22); X3 = torr_triangulate(matches, m3, P1, P23); X4 = torr_triangulate(matches, m3, P1, P24); %next reproject and compare with the images %the chieral constraint is sign(det M) * sign (third homog coord of reprojected image) * sign (fourth homog coord X) % to make sure we dont get any outliers we average the inequalities over all the points, ones with a bad sign % can later be removed as outleirs. %we want chieral for both cameras to be positive ax1 = P1 * X1; %ax1 = ax1 *m3/ax1(3) ax2 = P1 * X2; %ax2 = ax2 *m3/ax2(3) ax3 = P1 * X3; %ax3 = ax3 *m3/ax3(3) ax4 = P1 * X4; %ax4 = ax4 *m3/ax4(3); bx1 = P21 * X1; %bx1 = bx1 *m3/bx1(3) bx2 = P22 * X2; %bx2 = bx2 *m3/bx2(3) bx3 = P23 * X3; %bx3 = bx3 *m3/bx3(3) bx4 = P24 * X4; %bx4 = bx4 *m3/bx4(3); chieral1 = (sign(ax1(3,:) ) .* sign (X1(4,:))) + (sign(bx1(3,:) ) .* sign (X1(4,:))); chieral2 = (sign(ax2(3,:) ) .* sign (X1(4,:))) + (sign(bx2(3,:) ) .* sign (X2(4,:))); chieral3 = (sign(ax3(3,:) ) .* sign (X1(4,:))) + (sign(bx3(3,:) ) .* sign (X3(4,:))); chieral4 = (sign(ax4(3,:) ) .* sign (X1(4,:))) + (sign(bx4(3,:) ) .* sign (X4(4,:))); chieral_sum = [sum(chieral1) sum(chieral2) sum(chieral3) sum(chieral4)]; [max_ch correct_interpretation] = max(chieral_sum); switch correct_interpretation case 1 R = R1; t = u3; P2 = P21; case 2 R = R1; t = -u3; P2 = P22; case 3 R = R2; t = u3; P2 = P23; case 4 R = R2; t = -u3; P2 = P24; end %next recover the parameters of the rotation... % [VR,DR] = eig(R); % % dd = [DR(1,1), DR(2,2), DR(3,3)]; % [Y Index] = find(dd==1); % % %determine axis of rotation % axis = VR(:,Index(1)); rot_axis = [R(3,2)-R(2,3), R(1,3) - R(3,1), R(2,1) - R(1,2)]; rot_axis = rot_axis /norm(rot_axis); rot_angle = acos( (trace(R)-1)/2); [a b] = torr_unit2sphere(rot_axis); [ta tb] = torr_unit2sphere(t); %put together intrinisc and extrinsic parameters % % %here p is the set of paramets such that % g(1) = focal length % g(2-3) rotation axis % g(4) rotation angle % g(5-6) translation direction g(1) = 1/C(3,3); g(2) = a; g(3) = b; g(4) = rot_angle; g(5) = ta; g(6) = tb; % % CCC = C; % %convert intrinsic and extinsics to a F matrix % C(3,3) = 1/g(1); % rot_axis2 = torr_sphere2unit([g(2) g(3)]); % tt = torr_sphere2unit([g(5) g(6)]); % rot_angle2 = g(4); % % %Rogregues % II = [1 0 0; 0 1 0; 0 0 1]; % AX = torr_skew_sym(rot_axis2); % % %note -sin produce RR' % RR = (cos(rot_angle2) * II +sin(rot_angle2) * AX + (1 - cos(rot_angle2)) * rot_axis2 * rot_axis2'); % % TX = torr_skew_sym(tt); % nnE = TX * RR; % % %F = inv(C') * nnE * inv(C); % F = inv(C') * nnE * inv(C); % f = reshape(F,9,1);