Wednesday, July 30, 2008

Activity 11: Camera Calibration

In this activity, we are to obtain transformation of the camera coordinates with real world coordinates using a checkerboard pattern shown below as a calibration object
I assigned the bottom center of the image as my origin and the left part as the "x" axis and the right part as the "y" and the vertical direction as the "z". To calibrate the camera, first, we assigned 25 corner points chosen at random in the image (marked with yellow squares). The location of the points are obtained using the "locate" function of scilab.
To solve for the camera parameters, we use the following matrix:
Where xo, yo and zo correspond to real world coordinates and yi and zi correspond to image coordinates. aij correspond to the camera parameters.
The camera parameter matrix can be solved using:
Where Q is the matrix containing the real world coordinates and d is the matrix containing the image coordinates.
The camera parameters obtained are as follows:
-19.19404
9.7237133
-0.5773294
167.80985
-2.5034951
-3.831655
20.477795
32.311712
-0.0067168
-0.0120008
-0.0025509

To confirm if this camera parameters are correct, we use it to predict the locations of the selected points in the image from the real world coordinates. The following equation is applied:

Using the above equations I obtained the following results:
The 1st pair of data correspond to the actual image coordinates, 2nd pair correspond to the coordinates solved using the above equation and the 3rd pair corresponds to their difference.


Image Coordinates Solved Coordinates difference
yi zi yi zi yi zi
29.096045 259.60452 29.300782 259.52771 0.204737 0.07681
89.548023 262.42938 89.604812 261.94118 0.056789 0.4882
216.66667 261.86441 216.84828 262.18338 0.18161 0.31897
166.38418 243.22034 166.27818 243.29594 0.106 0.0756
50 214.97175 50.653965 215.20451 0.653965 0.23276
147.74011 220.62147 147.806 220.65636 0.06589 0.03489
217.23164 216.66667 216.9003 216.65975 0.33134 0.00692
91.242938 194.63277 90.702993 195.35542 0.539945 0.72265
229.66102 192.37288 230.33101 192.45105 0.66999 0.07817
31.920904 169.20904 31.45059 169.10213 0.470314 0.10691
147.74011 176.55367 148.21666 177.51489 0.47655 0.96122
191.24294 175.9887 191.22007 175.33202 0.02287 0.65668
129.66102 155.08475 129.68482 154.61499 0.0238 0.46976
73.163842 127.9661 72.303439 128.12011 0.860403 0.15401
167.51412 137.00565 167.05391 136.44094 0.46021 0.56471
204.80226 130.22599 204.04286 129.52077 0.7594 0.70522
258.47458 119.49153 257.94833 119.43573 0.52625 0.0558
33.050847 81.073446 33.55399 80.628618 0.503143 0.444828
129.66102 90.677966 130.44029 90.649574 0.77927 0.028392
191.24294 88.983051 191.58995 88.895726 0.34701 0.087325
92.937853 65.254237 92.847265 65.342247 0.090588 0.08801
217.23164 60.169492 217.07798 61.190191 0.15366 1.020699
34.745763 37.00565 34.588753 37.10424 0.15701 0.09859
149.43503 50.564972 149.42329 50.756407 0.01174 0.191435
243.22034 32.485876 243.74758 32.200294 0.52724 0.285582

The average value of the difference is 0.359 with standard deviation of 0.318. This translates to an error of roughly 1%.

The scilab code I used is given below:
---------------------------------------------------------------------------------
I = imread("C:\Users\RAFAEL JACULBIA\Documents\subjects\186\activity11\marked.bmp");
I = im2gray(I);
//imshow(I,[]);
//d = [];
//d = locate(25,flag=1);

image = [7 4 0 0 6 1 0 4 0 7 1 0 2 5 0 0 0 7 2 0 4 0 7 1 0;
0 0 4 0 0 0 4 0 5 0 0 2 0 0 0 3 7 0 0 2 0 4 0 0 6;
11 11 11 10 9 9 9 8 8 7 7 7 6 5 5 5 5 3 3 3 2 2 1 1 1];


//image = image*72;

Q = [];
yi = [];
zi = [];
for i = 1:25
x = image(1,i);
y = image(2,i);
z = image(3,i);
yi = d(1,i);
zi = d(2,i);
Qi = [x y z 1 0 0 0 0 -(yi*x) -(yi*y) -(yi*z); 0 0 0 0 x y z 1 -(zi*x) -(zi*y) -(zi*z)];
Q = cat(1, Q, Qi);
end
d2 = [];
d2 = matrix(d, 50,1);
a = inv(Q'*Q)*Q'*d2;

for j = 1:25
yi2(j) = ((a(1)*image(1,j))+(a(2)*image(2,j))+(a(3)*image(3,j))+a(4))/((a(9)*image(1,j))+(a(10)*image(2,j))+(a(11)*image(3,j))+1);
zi2(j) = ((a(5)*image(1,j))+(a(6)*image(2,j))+(a(7)*image(3,j))+a(8))/((a(9)*image(1,j))+(a(10)*image(2,j))+(a(11)*image(3,j))+1);
end

for k = 1:25
yi(k) = d(1,k);
zi(k) = d(2,k);
end

tryx = 0;
tryy = 6;
tryz = 1;

yiTry = ((a(1)*tryx)+(a(2)*tryy)+(a(3)*tryz)+a(4))/((a(9)*tryx)+(a(10)*tryy)+(a(11)*tryz)+1)
ziTry = ((a(5)*tryx)+(a(6)*tryy)+(a(7)*tryz)+a(8))/((a(9)*tryx)+(a(10)*tryy)+(a(11)*tryz)+1)
-------------------------------------------------------------------------------------------

For this activity I will give myself a grade of 10 because I was able to obtain quite accurate results.
Thanks to Eduardo David for teaching me how to resize a matrix in scilab

No comments: