www.gusucode.com > 基于matlab的三维重建代码,提取两幅图片的匹配点源码程序 > 基于matlab的三维重建代码,提取两幅图片的匹配点源码程序/code/code/dessential.m
% [T,R] = dessential(x,xp) % % The basic 8-point algorithm of Longuet Higgins % for reconstruction from two uncalibrated views % as described in Chapter 5, "An introduction to 3-D Vision" % by Y. Ma, S. Soatto, J. Kosecka, S. Sastry (MASKS) % % Code distributed free for non-commercial use % Copyright (c) MASKS, 2003 % % Last modified 5/5/2003 % % function [T0,R0] = dessential(p,q) n = size(p); NPOINTS = n(2); %set up matrix A such that A*[v1,v2,v3,s1,s2,s3,s4,s5,s6]' = 0 A = zeros(NPOINTS, 9); if NPOINTS < 9 error('Too few mesurements') return; end for i = 1:NPOINTS A(i,:) = kron(q(:,i),p(:,i))'; end r = rank(A); if r < 8 error('Measurement matrix rank defficient') end; [U,S,V] = svd(A); % pick the eigenvector corresponding to the smallest eigenvalue eigs98 = [S(9,9), S(8,8)]; e = V(:,9); e = (round(1.0e+10*e))*(1.0e-10); E = reshape(e, 3, 3)'; % essential matrix % then four possibilities are Rzp = [0 -1 0 ; 1 0 0 ; 0 0 1 ]; % rotation by pi/2 Rzn = [0 1 0 ; -1 0 0 ; 0 0 1 ]; % rotation by -pi/2 [U,S,V] = svd(E); S = diag([1,1,0]); detu = det(U); detv = det(V); if detu < 0 & detv < 0 U = -U; V = -V; % break elseif detu < 0 & detv > 0 S1 = Rzp*S; U = -U*rot_matrix([S1(3,2), S1(1,3) S1(2,1)],pi)*Rzp; V = V*Rzp; % break elseif detu > 0 & detv < 0 S1 = Rzp*S; U = U*rot_matrix([S1(3,2), S1(1,3) S1(2,1)],pi)*Rzp; V = -V*Rzp; % break end R(:,:,1) = (U*Rzp'*V'); Th(:,:,1) = (U*Rzp*S*U'); t(:,1) = [-Th(2,3,1), Th(1,3,1), -Th(1,2,1)]'; [omega(:,1),theta(1)] = exp_rotation(R(:,:,1)); R(:,:,2) = (U*Rzn'*V'); Th(:,:,2) = (U*Rzn*S*U'); t(:,2) = [-Th(2,3,2), Th(1,3,2), -Th(1,2,2)]'; [omega(:,2),theta(2)] = exp_rotation(R(:,:,2)); [U,S,V] = svd(-E); S = diag([1,1,0]); detu = det(U); detv = det(V); if detu < 0 & detv < 0 U = -U; V = -V; % break elseif detu < 0 & detv > 0 S1 = Rzp*S; U = -U*rot_matrix([S1(3,2), S1(1,3) S1(2,1)],pi)*Rzp; V = V*Rzp; % break elseif detu > 0 & detv < 0 S1 = Rzp*S; U = U*rot_matrix([S1(3,2), S1(1,3) S1(2,1)],pi)*Rzp; V = -V*Rzp; end R(:,:,3) = (U*Rzp'*V'); Th(:,:,3) = U*Rzp*S*U'; t(:,3) = [-Th(2,3,3), Th(1,3,3), -Th(1,2,3)]'; [omega(:,3),theta(3)] = exp_rotation(R(:,:,3)); R(:,:,4) = (U*Rzn'*V'); Th(:,:,4) = U*Rzn*S*U'; t(:,4) = [-Th(2,3,4), Th(1,3,4), -Th(1,2,4)]'; [omega(:,4),theta(4)] = exp_rotation(R(:,:,4)); index = 0; posdepth = zeros(1,4); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % pick the correct solution based on positive depth constraint % there are two ways (below 2. is used): % 1. Compute both scales and pick the solution where the majority is % positive in both frames % 2. Compute volume, which has to be positive if the two scales have % the same sign and then check whether one of the scale is positive % (similar solution suggested by Kanatani, 1993 book). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for i = 1:4 for j = 1:NPOINTS % c (a x b) (That*q)'*That*R*p > 0 % if the depths have the same sign the triple product has to % be greater then 0 volume(j) = triple_product(t(:,i), R(:,:,i)*p(:,j), Th(:,:,i)*q(:,j)); alpha1(j) = -(skew(q(:,j))*t(:,i))'*... (skew(q(:,j))*R(:,:,i)*p(:,j)) ... /(norm(skew(q(:,j))*t(:,i)))^2; alpha2(j) = (skew(R(:,:,i)*p(:,j))*q(:,j))'*... (skew(R(:,:,i)*p(:,j))*t(:,i)) ... /norm(skew(R(:,:,i)*p(:,j))*q(:,j))^2; end vol = sum(sign(volume)); depth = sum(sign(alpha1)); depth2 = sum(sign(alpha2)); posdepth(i) = vol + depth; end % end for all motions [val, index] = max(posdepth); index_final = index; T0 = t(:,index); R0 = R(:,:,index);