Skip to content

Commit 313df93

Browse files
Merge branch 'devel'
Pre-release 0.9
2 parents d5f005e + fd37eee commit 313df93

File tree

3 files changed

+166
-94
lines changed

3 files changed

+166
-94
lines changed

examples/ex_01_minimal.m

-21
This file was deleted.

examples/ex_02_minimal.m

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
% FIVE_POINT_ALGORITHM -
2+
% Example 2: minimal example
3+
%
4+
% Work in Progress - may have bugs
5+
%
6+
% Given point matches extracted from two pictures and taken with the
7+
% same camere with known intrinsic parameters, exemplify the use of
8+
% five_point_algorithm
9+
%
10+
% Author: Sergio Agostinho - sergio(dot)r(dot)agostinho(at)gmail(dot)com
11+
% Date: Feb 2015
12+
% Last modified: Mar 2015
13+
% Version: 0.9
14+
% Repo: https://github.com/SergioRAgostinho/five_point_algorithm
15+
% Feel free to provide feedback or contribute.
16+
17+
[path, ~, ~] = fileparts(which('ex_02_minimal'));
18+
addpath([path '/..']);
19+
addpath([path '/../aux']);
20+
clear path
21+
22+
pts1 = [288.8398 12.1534 317.5059 74.5754 44.1327;
23+
77.2382 163.7803 82.8476 220.5643 192.9634];
24+
25+
pts2 = [286.1892 6.9846 312.5673 70.0283 40.2131;
26+
76.7289 164.3921 81.3119 220.4840 194.1166];
27+
28+
K = [602.5277 0 177.3328;
29+
0 562.9129 102.8893;
30+
0 0 1.0000];
31+
32+
33+
[E, R, t, Eo] = five_point_algorithm(pts1, pts2, K, K);
34+
35+
pts3Dhomo = triangulate(pts1, pts2, K, K, E{1}, R{1}, t{1});
36+
pts3D = pts3Dhomo(1:3,:)./(ones(3,1)*pts3Dhomo(4,:));
37+

five_point_algorithm.m

+129-73
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,45 @@
1-
function [E, Eo] = five_point_algorithm( pts1, pts2, K1, K2 )
1+
function [E_all, R_all, t_all, Eo_all] = five_point_algorithm( pts1, pts2, K1, K2 )
22
%FIVE_POINT_ALGORITHM Given five points matches between two images, and the
33
% intrinsic parameters of each camera. Estimate the essential matrix E, the
44
% rotation matrix R and translation vector t, between both images. This
55
% algorithm is based on the method described by David Nister in "An
66
% Efficient Solution to the Five-Point Relative Pose Problem"
77
% DOI: http://dx.doi.org/10.1109/TPAMI.2004.17
88
%
9-
% E = FIVE_POINT_ALGORITHM(pts1, pts2, K1, K2) returns the Essential matrix
10-
% enforcing the restriction U*diag([1 1 0])*V'
9+
% E = FIVE_POINT_ALGORITHM(pts1, pts2, K1, K2) returns in E all the valid
10+
% Essential matrix solutions for the five point correspondence. If you
11+
% don't need the R and t, use this version as it avoids computing
12+
% unnecessary results.
13+
%
14+
% [E_all, R_all, t_all, Eo_all] = FIVE_POINT_ALGORITHM(pts1, pts2, K1, K2)
15+
% also returns in R_all and t_all all the rotation matrices and translation
16+
% vectors of camera 2 for the different essential matrices, such that a 3D
17+
% point in camera 1 reference frame can be transformed into the camera 2
18+
% reference frame through p_2 = R{n}*p_1 + t{n}. Eo_all is the essential
19+
% matrix before the imposing the structure U*diag([1 1 0])*V'. It should
20+
% help get a better feeling on the accuracy of the solution. All these
21+
% return values a nx1 cell arrays.
1122
%
12-
% [E, Eo] = FIVE_POINT_ALGORITHM(pts1, pts2, K1, K2) returns the Essential
13-
% matrix enforcing the restriction U*diag([1 1 0])*V', and original matrix
14-
% computed by the method in Eo.
1523
%
1624
% Arguments:
1725
% pts1, pts2 - assumed to have dimension 2x5 and of equal size.
1826
% K1, K2 - 3x3 intrinsic parameters of cameras 1 and 2 respectively
19-
%
20-
% Returns:
21-
% E - U*diag([1 1 0])*V'
22-
% Eo - E as it is estimated originally
2327
%
24-
% Known Issues:
25-
% The algorithm is still incomplete. I'm releasing it at this early stage
26-
% because it already provides proper estimates of the essential matrix.
27-
% Although there is more than one solution, I'm currently only returning
28-
% the first. I still need to figure out how to select the "best" if such
29-
% exists.
28+
% Know Issues:
29+
% - R and t computation is done assuming perfect point correspondence.
3030
%
3131
% TODO:
32-
% - Extract R and t from E
33-
% - Provide example cases.
32+
% - Extract R and t without perfect point correspondence
33+
% - Augment example cases.
3434
% - Implement the variant with 5 points over 3 images
3535
% - Handle more than 5 points
3636
%
3737
% Author: Sergio Agostinho - sergio(dot)r(dot)agostinho(at)gmail(dot)com
3838
% Date: Feb 2015
39-
% Version: 0.8
39+
% Last modified: Mar 2015
40+
% Version: 0.9
4041
% Repo: https://github.com/SergioRAgostinho/five_point_algorithm
41-
% Feel free to provide feedback or aid in the development.
42+
% Feel free to provide feedback or contribute.
4243

4344
if ~all(size(pts1) == [2,5]) || ~all(size(pts2) == [2,5])
4445
error('five_point_algorithm:wrong_dimensions','pts1 and pts2 must be of size 2x5');
@@ -216,69 +217,124 @@
216217
e_val = eig([-n_row_scaled(2:end);
217218
eye(9), zeros(9,1)]);
218219

219-
%Select the first real root
220-
%TODO: Find if there's a "best" solution
220+
221+
m = 0;
221222
for n = 1:10
222223
if ~isreal(e_val(n))
223224
continue
224225
end
225226

227+
m = m + 1;
228+
end
229+
230+
R_all = cell(m,1);
231+
t_all = cell(m,1);
232+
E_all = cell(m,1);
233+
Eo_all = cell(m,1);
234+
235+
m = 1;
236+
for n = 1:10
237+
if ~isreal(e_val(n))
238+
continue
239+
end
226240
z = e_val(n);
227-
break
241+
242+
%Backsubstition
243+
p_z6 = [z^6; z^5; z^4; z^3; z^2; z; 1];
244+
p_z7 = [z^7; p_z6];
245+
246+
x = (p_1*p_z7)/(p_3*p_z6);
247+
y = (p_2*p_z7)/(p_3*p_z6);
248+
249+
Eo = x*Xmat + y*Ymat + z*Zmat + Wmat;
250+
Eo_all{m} = Eo;
251+
[U,~,V] = svd(Eo);
252+
253+
254+
E = U*diag([1 1 0])*V';
255+
E_all{m} = E;
256+
257+
%stop here if nothing else is required to be computed
258+
if nargout < 2
259+
m = m + 1;
260+
continue
261+
end
262+
263+
%check determinan signs
264+
if(det(U) < 0)
265+
U(:,3) = -U(:,3);
266+
end
267+
268+
if (det(V) < 0)
269+
V(:,3) = -V(:,3);
270+
end
271+
272+
%Extracting R and t from E
273+
D = [0 1 0;
274+
-1 0 0;
275+
0 0 1];
276+
277+
q_1 = q1(:,1);
278+
q_2 = q2(:,1);
279+
280+
281+
for n = 1:4
282+
switch(n)
283+
case 1
284+
t = U(:,3);
285+
R = U*D*V';
286+
case 2
287+
t = -U(:,3);
288+
R = U*D*V';
289+
case 3
290+
t = U(:,3);
291+
R = U*D'*V';
292+
case 4
293+
t = -U(:,3);
294+
R = U*D'*V';
295+
end
296+
297+
%Cheirality (points in front of the camera) constraint assuming perfect
298+
%point correspondence
299+
a = E'*q_2;
300+
b = cross_vec3(q_1, [a(1:2); 0]);
301+
c = cross_vec3(q_2, diag([1 1 0])*E*q_1);
302+
d = cross_vec3(a, b);
303+
304+
P = [R t];
305+
C = P'*c;
306+
Q = [d*C(4); -d(1:3)'*C(1:3)];
307+
308+
%Cheirality test
309+
310+
%behind the 1st camera
311+
if (Q(3)*Q(4) < 0)
312+
continue
313+
end
314+
315+
%behind the 2nd camera
316+
c_2 = P*Q;
317+
if (c_2(3)*Q(4) < 0)
318+
continue
319+
end
320+
321+
R_all{m} = R;
322+
t_all{m} = t;
323+
break
324+
end
325+
m = m + 1;
228326
end
229327

230-
%Backsubstition
231-
p_z6 = [z^6; z^5; z^4; z^3; z^2; z; 1];
232-
p_z7 = [z^7; p_z6];
233-
234-
x = (p_1*p_z7)/(p_3*p_z6);
235-
y = (p_2*p_z7)/(p_3*p_z6);
236-
237-
Eo = x*Xmat + y*Ymat + z*Zmat + Wmat;
238-
[U,~,V] = svd(Eo);
239-
240-
241-
E = U*diag([1 1 0])*V';
242-
243-
% if nargout < 3
244-
% return
245-
% end
246-
247-
% %check determinan signs
248-
% if(det(U) < 0)
249-
% U(:,3) = -U(:,3);
250-
% end
251-
%
252-
% if (det(V) < 0)
253-
% V(:,3) = -V(:,3);
254-
% end
255-
%
256-
% %Extracting R and t from E
257-
% D = [0 1 0;
258-
% -1 0 0;
259-
% 0 0 1];
260-
%
261-
% for n = 1:4
262-
% switch(n)
263-
% case 1
264-
% t = U(:,3);
265-
% R = U*D*V';
266-
% case 2
267-
% t = -U(:,3);
268-
% R = U*D*V';
269-
% case 3
270-
% t = U(:,3);
271-
% R = U*D'*V';
272-
% case 4
273-
% t = -U(:,3);
274-
% R = U*D'*V';
275-
% end
276-
%
277-
%
278-
%
279-
% end
280328
end
281329

330+
function out = cross_vec3(u, v)
331+
%CROSS_VEC Function to compute the cross product of two 3D column vectors.
332+
%The default MATLAB implementation is simply too slow.
333+
334+
out = [ u(2)*v(3) - u(3)*v(2);
335+
u(3)*v(1) - u(1)*v(3);
336+
u(1)*v(2) - u(2)*v(1)];
337+
end
282338

283339
function po = pz6pz4(p1, p2)
284340
%PZ4PZ3 Function responsible for multiplying a 6th order z polynomial p1

0 commit comments

Comments
 (0)