Skip to content

Commit

Permalink
files were left out of the commit for release 0.9
Browse files Browse the repository at this point in the history
  • Loading branch information
SergioRAgostinho committed Mar 9, 2015
1 parent 24e94a7 commit 47a6669
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 0 deletions.
23 changes: 23 additions & 0 deletions aux/cross_vec3.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function out = cross_vec3(u, v)
%CROSS_VEC3 Function to compute the cross product of two 3D vectors. The
% function disregards if they're row or collumn vectors. The default
% MATLAB implementation is simply too slow.
%
% Author: Sergio Agostinho - sergio(dot)r(dot)agostinho(at)gmail(dot)com
% Date: Mar 2015
% Version: 0.9
% Repo: https://github.com/SergioRAgostinho/five_point_algorithm
% Feel free to provide feedback or contribute.

if numel(u) ~= 3
error('cross_vec3:wrong_dimensions','u must be either 1x3 ou 3x1');
end

if numel(v) ~= 3
error('cross_vec3:wrong_dimensions','v must be either 1x3 ou 3x1');
end

out = [ u(2)*v(3) - u(3)*v(2);
u(3)*v(1) - u(1)*v(3);
u(1)*v(2) - u(2)*v(1)];
end
28 changes: 28 additions & 0 deletions aux/cube_3D.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
function cube_pts = cube_3D(centre_3D, size)
%CUBE_3D Auxiliary function that given a cube centre coordinates and the
% edge size returns the 3D coordenates of all vertices in a 3x8 matrix.
%
% Author: Sergio Agostinho - sergio(dot)r(dot)agostinho(at)gmail(dot)com
% Date: Mar 2015
% Version: 0.9
% Repo: https://github.com/SergioRAgostinho/five_point_algorithm
% Feel free to provide feedback or contribute.

if numel(centre_3D) ~= 3
error('cube_3D:wrong_dimensions:centre_3D',['centre_3D needs to either be a 3x1 collum ' ...
'vector or a 1x3 row vector']);
end

if numel(size) ~= 1
error('cube_3D:wrong_dimensions:size', 'size is a scalar');
end

x = centre_3D(1);
y = centre_3D(2);
z = centre_3D(3);
hs = size/2;

cube_pts = [x + hs, x + hs, x - hs, x - hs, x + hs, x + hs, x - hs, x - hs; ...
y + hs, y - hs, y + hs, y - hs, y + hs, y - hs, y + hs, y - hs; ...
z + hs, z + hs, z + hs, z + hs, z - hs, z - hs, z - hs, z - hs];
end
37 changes: 37 additions & 0 deletions aux/frustrum.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function h_out = frustrum(R,t,h)
% Work in progress
%
% Author: Sergio Agostinho - sergio(dot)r(dot)agostinho(at)gmail(dot)com
% Date: Mar 2015
% Version: 0.9
% Repo: https://github.com/SergioRAgostinho/five_point_algorithm
% Feel free to provide feedback or contribute.

T = [R t; zeros(1,3) 1];
R_view = [0 0 1 0; -1 0 0 0 ; 0 -1 0 0; 0 0 0 1];
frame = [1 0 0 0;
0 1 0 0;
0 0 1 0;
1 1 1 1];


pts = R_view *(T \ frame);


if nargin > 2 && ishandle(h)
next_plot = get(h, 'NextPlot');
set(h, 'NextPlot', 'add');

h_p = plot3(h, [pts(1,4) pts(1,1)], [pts(2,4) pts(2,1)], [pts(3,4) pts(3,1)], 'r', ...
[pts(1,4) pts(1,2)], [pts(2,4) pts(2,2)], [pts(3,4) pts(3,2)], 'g', ...
[pts(1,4) pts(1,3)], [pts(2,4) pts(2,3)], [pts(3,4) pts(3,3)], 'b');
set(h, 'NextPlot', next_plot);
else
h_p = plot3([pts(1,4) pts(1,1)], [pts(2,4) pts(2,1)], [pts(3,4) pts(3,1)], 'r', ...
[pts(1,4) pts(1,2)], [pts(2,4) pts(2,2)], [pts(3,4) pts(3,2)], 'g', ...
[pts(1,4) pts(1,3)], [pts(2,4) pts(2,3)], [pts(3,4) pts(3,3)], 'b');
end

h_out = get(h_p(1), 'Parent');

end
57 changes: 57 additions & 0 deletions aux/triangulate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
function pts = triangulate(pts1, pts2, K1, K2, E, R, t)
%TRIANGULATE Given 2D point matches between two images and the
% transformatiom between them in terms of the rotation matrix R and the
% translation vector t, such a point in camera 1 reference frame, can be
% transformed to camera 2 reference frame through, P_2 = [R t; zeros(1,3) 1]
% This triangulation method assumes ideal point correspondence and it is
% presented in "An Efficient Solution to the Five-Point Relative Pose
% Problem" by David Nister.
% DOI: http://dx.doi.org/10.1109/TPAMI.2004.17
%
% Known Issues:
% - There's no need to request E and R|t
%
% TODO:
% - Fix the required arguments.
%
% Author: Sergio Agostinho - sergio(dot)r(dot)agostinho(at)gmail(dot)com
% Date: Mar 2015
% Version: 0.9
% Repo: https://github.com/SergioRAgostinho/five_point_algorithm
% Feel free to provide feedback or contribute.

if size(pts1,1) ~= 2 || size(pts2,1) ~= 2
error('triangulate:wrong_dimensions','pts1 and pts2 must be of size 2xn');
end

if size(pts1,2) ~= size(pts2,2)
error('triangulate:wrong_dimensions','pts1 and pts2 must have the same number of points');
end

if ~all(size(R) == [3, 3])
error('triangulate:wrong_dimensions','R must be of size 3x3');
end

if ~all(size(t) == [3, 1])
error('triangulate:wrong_dimensions','t must be of size 3x1');
end

n = size(pts1,2);
pts = zeros(4,n);
q_1 = K1 \ [pts1; ones(1,n)];
q_2 = K2 \ [pts2; ones(1,n)];

for m = 1:n
a = E'*q_2(:,m);
b = cross_vec3(q_1(:,m), [a(1:2); 0]);
c = cross_vec3(q_2(:,m), diag([1 1 0])*E*q_1(:,m));
d = cross_vec3(a, b);

P = [R t];
C = P'*c;
Q = [d*C(4); -d(1:3)'*C(1:3)];

pts(:,m) = Q;
end

end
54 changes: 54 additions & 0 deletions examples/ex_01_full_synthetic.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
% FIVE_POINT_ALGORITHM -
% Example 1: Full synthetic
%
% Draw a fictional cube whose vertices are seen by two camera. Project
% these points into the camera image plain, run the five_point_method on
% top of them and verify the final result.
%
% Author: Sergio Agostinho - sergio(dot)r(dot)agostinho(at)gmail(dot)com
% Date: Mar 2015
% Version: 0.9
% Repo: https://github.com/SergioRAgostinho/five_point_algorithm
% Feel free to provide feedback or contribute.

[path, ~, ~] = fileparts(which('ex_01_full_synthetic'));
addpath([path '/..']);
addpath([path '/../aux']);
clear path

cube_pts = cube_3D([0 0 10]', 0.2);
cube_pts_homo = [cube_pts; ones(1,size(cube_pts,2))];

K1 = [602.5277 0 177.3328;
0 562.9129 102.8893;
0 0 1.0000];

K2 = [562.9129 0 102.8893;
0 602.5277 177.3328;
0 0 1.0000];

%The first camera will be placed at the origin
P_1 = [eye(3), zeros(3,1)];
cam1_pts = K1*P_1*cube_pts_homo;
pts1 = cam1_pts(1:2,:)./(ones(2,1)*cam1_pts(3,:));

%The second camera will be displaced 1 unit (to match our algorithm
%assumption) in the +x direction of the first camera reference frame and
%rotated -10 degrees in y.
t_o = [1; 0; 0];
R_o = [ cosd(-10) 0 sind(-10);
0 1 0;
-sind(-10) 0 cosd(-10)];
P_2 = [R_o', -R_o'*t_o];
cam2_pts = K2*P_2*cube_pts_homo;
pts2 = cam2_pts(1:2,:)./(ones(2,1)*cam2_pts(3,:));

[E, R, t, Eo] = five_point_algorithm(pts1(:,1:5), pts2(:,1:5), K1, K2);

%In this case the first solution is the correct one.
pts3Dhomo = triangulate(pts1, pts2, K1, K2, E{1}, R{1}, t{1});
pts3D = pts3Dhomo(1:3,:)./(ones(3,1)*pts3Dhomo(4,:));

%Display results
cube_pts
pts3D

0 comments on commit 47a6669

Please sign in to comment.