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:
Post a Comment