% % %designed for the good of the world by Philip Torr based on ideas contained in % copyright Philip Torr and Microsoft Corp 2002 % % /* % ***************************************** % */This gives a new method for estimating F that I developed (see citations below) from 7 points: % % thus we can get a one parameter family of solutions (modulo scale) F = F1 + a F2 % exploiting det | F | = 0 % this gives us 1,2 or 3 distinct solutions for a %MORE DETAILS IN: % @phdthesis{Torr:thesis, % author="Torr, P. H. S.", % title="Outlier Detection and Motion Segmentation", % school=" Dept. of Engineering Science, University of Oxford", % year=1995} % % % @article{Torr97c, % author="Torr, P. H. S. and Murray, D. W. ", % title="The Development and Comparison of Robust Methods for Estimating the Fundamental Matrix", % journal="IJCV", % volume = 24, % number = 3, % pages = {271--300}, % year=1997 % } %A is a 7 x 9 design matrix; %big_result is a 3x9 matrix of putative F's % returns 0,1,2 or 3 the number of fits gained. % function [no_F, big_result] = torr_F_constrained_fit(x1,y1,x2,y2,m3) A(:,1) = x1(:).* x2(:); A(:,2) = y1(:).* x2(:); A(:,3) = m3* x2(:); A(:,4) = x1(:).* y2(:); A(:,5) = y1(:).* y2(:); A(:,6) = m3* y2(:); A(:,7) = x1(:).* m3; A(:,8) = y1(:).* m3; A(:,9) = m3* m3; no_F = 0; sizeA = size(A); if ((sizeA(1) ~= 7) | (sizeA(2) ~= 9)) error('A is wrong shape'); return; end % A % disp(sprintf('Rank of A = %d',rank(A))); % disp('Null space of A'); % null(A) [U,S,V] = svd(A); %the two solutions r1 = V(:,length(V)); r2 = V(:,length(V)-1); % disp('Torr') % r1 % r2 p = torr_calc_cubic_coefs(r1, r2); a_roots = roots(p); %disp('Roots') %a_roots % % we now want to chose a solution so that the constrtaint % % | aF_1 + (1-a)F_2 | = 0 is satisfies --- this gives us a cubic in a % % %coefficients of c_1 a^3 + c_2 a^2 + c_3 a + c_4 % cubic = zeros(4,1); % % cubic = torr_accumulate_coeff(cubic, r1, r2,1,5,9, 1); % cubic = torr_accumulate_coeff(cubic, r1, r2,1,6,8, 0); % cubic = torr_accumulate_coeff(cubic, r1, r2,2,4,9, 0); % cubic = torr_accumulate_coeff(cubic, r1, r2,2,6,7, 1); % cubic = torr_accumulate_coeff(cubic, r1, r2,3,4,8, 1); % cubic = torr_accumulate_coeff(cubic, r1, r2,3,5,7, 0); % % % /* cubic(0) x^3 + cubic(1) x^2 + cubic(2) x + cubic(3) etc */ % a_roots = roots(cubic); for i_root = 1:3 if isreal(a_roots(i_root)) % disp(sprintf('Real root #%d = %0.8g',i_root,a_roots(i_root))) no_F = no_F + 1; big_result(no_F,:) = r1(:)' * a_roots(i_root) + r2(:)' * (1 - a_roots(i_root)); % test that it is the correct solution. % simply det(big_result) = 0 % disp(sprintf('det(aF1 + (1-a)F2) = %0.8g',det(reshape(big_result(no_F,:),3,3)'))) end end %accumulates the coefficients for the % function cubic_out = torr_accumulate_coeff(cubic,f1, f2, a, b, c, plus) % temp(1) = f1(a) * f1(b) * f1(c); % temp(2) = f1(a) * f1(b) * f2(c); % temp(3) = f1(a) * f2(b) * f1(c); % temp(4) = f1(a) * f2(b) * f2(c); % temp(5) = f2(a) * f1(b) * f1(c); % temp(6) = f2(a) * f1(b) * f2(c); % temp(7) = f2(a) * f2(b) * f1(c); % temp(8) = f2(a) * f2(b) * f2(c); % % if plus % cubic_out(1) = cubic(1) + temp(1) - temp(2) - temp(3) + temp(4) - temp(5) + temp(6) + temp(7) - temp(8); % cubic_out(2) = cubic(2) + temp(2) + temp(3) - 2*temp(4) + temp(5) - 2*temp(6) - 2*temp(7)+ 3*temp(8); % cubic_out(3) = cubic(3) +temp(4) + temp(6) + temp(7) - 3 * temp(8); % cubic_out(4) = cubic(4) +temp(8); % else % cubic_out(1) = cubic(1) -temp(1) - temp(2) - temp(3) + temp(4) - temp(5) + temp(6) + temp(7) - temp(8); % cubic_out(2) = cubic(2) -temp(2) + temp(3) - 2*temp(4) + temp(5) - 2*temp(6) - 2*temp(7)+ 3*temp(8); % cubic_out(3) = cubic(3) -temp(4) + temp(6) + temp(7) - 3 * temp(8); % cubic_out(4) = cubic(4) -temp(8); % end