Skip to content

Commit 57c4045

Browse files
committed
Adding matlab simulations
This is an experiment script for learning about camera calibration. The camera poses and intrinsic matrices are roughly reality. It would be nice to be able to somehow iteratively tweek these parameters using real data...
1 parent 568c334 commit 57c4045

File tree

2 files changed

+215
-0
lines changed

2 files changed

+215
-0
lines changed

matlab/CameraCalibrationExp.m

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
%Camera Calibration Experiments:
2+
% Jeremy Bredfeldt - Morgridge Institutes for Research
3+
% Sept 2013
4+
5+
%Trying to derive the camera calibration matrices from first principles
6+
%If we know the pose of the camera, then what are the camera matrices?
7+
%With this, we can ROM check the calibrations generated by the calibration routines
8+
9+
%Then can we use these matrices to triangulate points properly in 3D, based on 2 camera poses?
10+
11+
%Place the origin in the south, west, floor level corner of the atrium
12+
%Positive x = points east
13+
%Positive y = points north
14+
%Positive z = up
15+
%Rotations: Cameras start pointing in positive z direction, and rotated from there
16+
% Bottom of camera is pointing in neg y direction
17+
% Use right hand rule for direction of rotation
18+
19+
%Atrium dimensions
20+
%39624 mm in x direction
21+
ax = 39624;
22+
%10947 mm in y direction
23+
ay = 10947;
24+
%15240 mm in z direction
25+
az = 15240;
26+
27+
%Camera sensor and lens
28+
%Focal length = 4.2 mm
29+
fx = 4.2;
30+
fy = fx;
31+
%Sensor = 4.54 mm X 3.42 mm
32+
sx = 4.54/2;
33+
sy = 3.42/2;
34+
%Image size = 1280 X 720 pixels
35+
ix = 1280;
36+
iy = 720;
37+
38+
%These are in the world's reference frame, to actually get camera matrices, these must be inverted.
39+
%--Translation--
40+
%Camera 1 (west side)
41+
Cx1 = 0;
42+
Cy1 = ay/2; %centered in y dim
43+
Cz1 = az;
44+
C1 = [Cx1; Cy1; Cz1];
45+
46+
%Camera 2 (east side)
47+
Cx2 = ax;
48+
Cy2 = ay/2;
49+
Cz2 = az;
50+
C2 = [Cx2; Cy2; Cz2];
51+
52+
%--Rotation--
53+
%Camera 1
54+
thx1 = 0;
55+
thy1 = pi/1.5; %point 45 deg down
56+
thz1 = 0;
57+
Rcx1 = [1 0 0; 0 cos(thx1) -sin(thx1); 0 sin(thx1) cos(thx1)];
58+
Rcy1 = [cos(thy1) 0 sin(thy1); 0 1 0; -sin(thy1) 0 cos(thy1)];
59+
Rcz1 = [cos(thz1) -sin(thz1) 0; sin(thz1) cos(thz1) 0; 0 0 1];
60+
Rc1 = Rcx1*Rcy1*Rcz1;
61+
62+
%Camera 2
63+
thx2 = 0;
64+
thy2 = -pi/1.5; %point 45 deg down
65+
thz2 = pi;
66+
Rcx2 = [1 0 0; 0 cos(thx2) -sin(thx2); 0 sin(thx2) cos(thx2)];
67+
Rcy2 = [cos(thy2) 0 sin(thy2); 0 1 0; -sin(thy2) 0 cos(thy2)];
68+
Rcz2 = [cos(thz2) -sin(thz2) 0; sin(thz2) cos(thz2) 0; 0 0 1];
69+
Rc2 = Rcx2*Rcy2*Rcz2;
70+
71+
%Get the actual camera matrices (inverse of the previously written matrices):
72+
R1 = Rc1';
73+
R2 = Rc2';
74+
t1 = -R1*C1; %origin in cam 1 ref frame
75+
t2 = -R2*C2; %origin in cam 2 ref frame
76+
77+
%--Extrinsic--
78+
E1 = [R1 t1];
79+
E2 = [R2 t2];
80+
81+
%--Intrinsic--
82+
%Assume no skew or translation, and fx and fy are same
83+
%Assume both cameras are the same
84+
K = [fx 0 0; 0 fy 0; 0 0 1];
85+
86+
%--Final Matrices--
87+
P1 = K*E1;
88+
P2 = K*E2;
89+
90+
%--Tests--
91+
92+
%3D point, middle of the atrium floor:
93+
x1 = [ax/1.5; ay/3; 6000; 1];
94+
%x1 = [C2; 1];
95+
96+
%Project these points onto the camera image planes
97+
y11 = P1*x1;
98+
y12 = P2*x1;
99+
100+
c1x = y11(1)/y11(3)
101+
c1y = y11(2)/y11(3)
102+
c2x = y12(1)/y12(3)
103+
c2y = y12(2)/y12(3)
104+
105+
%Draw the spots on the images
106+
figure(2); clf;
107+
plot(c1x,c1y,'r*');
108+
axis equal;
109+
xlim([-sx sx]);
110+
ylim([-sy sy]);
111+
title('Camera 1');
112+
figure(3); clf;
113+
plot(c2x,c2y,'k*');
114+
axis equal;
115+
xlim([-sx sx]);
116+
ylim([-sy sy]);
117+
title('Camera 2');
118+
119+
%Create plots of the results
120+
figure(1);
121+
clf;
122+
%draw atrium floor
123+
plot3([0 ax ax 0 0],[0 0 ay ay 0],[0 0 0 0 0]);
124+
hold on;
125+
%draw camera centers
126+
%plot3(C1(1),C1(2),C1(3),'r*');
127+
%plot3(C2(1),C2(2),C2(3),'k*');
128+
%draw camera directions
129+
zd = 2000;
130+
d = [0; 0; zd; 1];
131+
D1 = [Rc1 C1]*d;
132+
D2 = [Rc2 C2]*d;
133+
plot3([C1(1) D1(1)],[C1(2) D1(2)],[C1(3) D1(3)],'r');
134+
plot3([C2(1) D2(1)],[C2(2) D2(2)],[C2(3) D2(3)],'k');
135+
136+
%draw camera frustrum
137+
%create rays in camera frame, then transform to world frame
138+
%4 rays
139+
f1 = [sx*zd/fx; sy*zd/fy; zd; 1];
140+
f2 = [-sx*zd/fx; sy*zd/fy; zd; 1];
141+
f3 = [-sx*zd/fx; -sy*zd/fy; zd; 1];
142+
f4 = [sx*zd/fx; -sy*zd/fy; zd; 1];
143+
%rays for first camera
144+
F11 = [Rc1 C1]*f1;
145+
F12 = [Rc1 C1]*f2;
146+
F13 = [Rc1 C1]*f3;
147+
F14 = [Rc1 C1]*f4;
148+
plot3([C1(1) F11(1)],[C1(2) F11(2)],[C1(3) F11(3)],'r');
149+
plot3([C1(1) F12(1)],[C1(2) F12(2)],[C1(3) F12(3)],'r');
150+
plot3([C1(1) F13(1)],[C1(2) F13(2)],[C1(3) F13(3)],'r');
151+
plot3([C1(1) F14(1)],[C1(2) F14(2)],[C1(3) F14(3)],'r');
152+
153+
%rays for second camera
154+
F21 = [Rc2 C2]*f1;
155+
F22 = [Rc2 C2]*f2;
156+
F23 = [Rc2 C2]*f3;
157+
F24 = [Rc2 C2]*f4;
158+
plot3([C2(1) F21(1)],[C2(2) F21(2)],[C2(3) F21(3)],'k');
159+
plot3([C2(1) F22(1)],[C2(2) F22(2)],[C2(3) F22(3)],'k');
160+
plot3([C2(1) F23(1)],[C2(2) F23(2)],[C2(3) F23(3)],'k');
161+
plot3([C2(1) F24(1)],[C2(2) F24(2)],[C2(3) F24(3)],'k');
162+
163+
%draw test point
164+
plot3(x1(1),x1(2),x1(3),'b*');
165+
%draw projection result
166+
167+
xlabel('South Wall (x, mm)');
168+
ylabel('West Wall (y, mm)');
169+
zlabel('(z, mm)');
170+
axis equal;
171+
172+
na = 0.01;
173+
%now triangulate to find the 3d location again, using the camera matrices
174+
M = triangulateJYB(P1,[c1x+na*randn c1y+na*randn],P2,[c2x+na*randn c2y+na*randn]);
175+
plot3(M(1),M(2),M(3),'ro');

matlab/triangulateJYB.m

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
function M = triangulateJYB(P1, m1, P2, m2)
2+
% TRIANGULATE computes the 3D point location using 2D camera views
3+
% P1: camera matrix of the first camera.
4+
% m1: pixel location (x1, y1) on the first view. Row vector.
5+
% P2: camera matrix of the second camera
6+
% m2: pixel location (x2, y2) on the second view. Row vector.
7+
% M: the (x, y, z) coordinate of the reconstructed 3D point. Row vector.
8+
% Camera one
9+
C1 = inv(P1(1:3, 1:3)) * (-P1(:,4));
10+
x0 = C1(1);
11+
y0 = C1(2);
12+
z0 = C1(3);
13+
m1 = [m1'; 1];
14+
M1 = pinv(P1) * m1;
15+
x = M1(1)/M1(4);
16+
y = M1(2)/M1(4);
17+
z = M1(3)/M1(4);
18+
a = x-x0;
19+
b = y-y0;
20+
c = z-z0;
21+
% Camera Two
22+
C2 = inv(P2(1:3, 1:3)) * (-P2(:,4));
23+
x1 = C2(1);
24+
y1 = C2(2);
25+
z1 = C2(3);
26+
m2 = [m2'; 1];
27+
M2 = pinv(P2) * m2;
28+
x = M2(1)/M2(4);
29+
y = M2(2)/M2(4);
30+
z = M2(3)/M2(4);
31+
d = x-x1;
32+
e = y-y1;
33+
f = z-z1;
34+
% Solve u and v
35+
A = [a^2 + b^2 + c^2, -(a*d + e*b + f*c);...
36+
-(a*d + e*b + f*c), d^2 + e^2 + f^2];
37+
v = [ (x1-x0)*a + (y1-y0)*b + (z1-z0)*c;...
38+
(x0-x1)*d + (y0-y1)*e + (z0-z1)*f];
39+
r = inv(A) * v;
40+
M = [x0+a*r(1) y0+b*r(1) z0+c*r(1)];

0 commit comments

Comments
 (0)