summaryrefslogtreecommitdiffstats
path: root/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib
diff options
context:
space:
mode:
authorLeo Chan <leochanj@live.unc.edu>2020-10-22 01:53:21 -0400
committerJoshua Bakita <jbakita@cs.unc.edu>2020-10-22 01:56:35 -0400
commitd17b33131c14864bd1eae275f49a3f148e21cf29 (patch)
tree0d8f77922e8d193cb0f6edab83018f057aad64a0 /SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib
parent601ed25a4c5b66cb75315832c15613a727db2c26 (diff)
Squashed commit of the sb-vbs branch.
Includes the SD-VBS benchmarks modified to: - Use libextra to loop as realtime jobs - Preallocate memory before starting their main computation - Accept input via stdin instead of via argc Does not include the SD-VBS matlab code. Fixes libextra execution in LITMUS^RT.
Diffstat (limited to 'SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib')
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Distor2Calib.m391
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m19
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m54
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m98
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m141
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m137
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m117
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m19
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m48
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m97
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m37
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m4
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m10
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m193
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m230
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m482
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m38
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m71
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m47
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m46
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m66
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m123
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m151
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m113
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m163
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m215
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m74
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m92
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m182
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m99
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m152
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m234
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m46
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m36
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m185
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m19
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m18
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m216
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m139
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m394
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m158
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m158
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m19
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m10
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m52
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m89
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m109
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m7
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m92
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m43
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m26
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m53
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m276
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m312
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m24
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m258
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m87
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m119
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m127
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m121
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m66
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m217
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m23
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m65
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m46
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m22
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m45
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m95
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m39
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m9
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m193
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m89
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m59
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m105
74 files changed, 8209 insertions, 0 deletions
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Distor2Calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Distor2Calib.m
new file mode 100755
index 0000000..a82f583
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Distor2Calib.m
@@ -0,0 +1,391 @@
1function [fc_2,Rc_2,Tc_2,H_2,distance,V_vert,V_hori,x_all_c,V_hori_pix,V_vert_pix,V_diag1_pix,V_diag2_pix]=Distor2Calib(k_dist,grid_pts_centered,n_sq_x,n_sq_y,Np,W,L,Xgrid_2,f_ini,N_iter,two_focal);
2
3% Computes the calibration parameters knowing the
4% distortion factor k_dist
5
6% grid_pts_centered are the grid point coordinates after substraction of
7% the optical center.
8
9% can give an optional guess for the focal length f_ini (can set to [])
10% can provide the number of iterations for the Iterative Vanishing Point Algorithm
11
12% if the focal length is known perfectly, then, there is no need to iterate,
13% and therefore, one can fix: N_iter = 0;
14
15% California Institute of Technology
16% (c) Jean-Yves Bouguet - October 7th, 1997
17
18
19
20%keyboard;
21
22if exist('two_focal'),
23 if isempty(two_focal),
24 two_focal=0;
25 end;
26else
27 two_focal = 0;
28end;
29
30
31if exist('N_iter'),
32 if ~isempty(N_iter),
33 disp('Use number of iterations provided');
34 else
35 N_iter = 10;
36 end;
37else
38 N_iter = 10;
39end;
40
41if exist('f_ini'),
42 if ~isempty(f_ini),
43 disp('Use focal provided');
44 if length(f_ini)<2, f_ini=[f_ini;f_ini]; end;
45 fc_2 = f_ini;
46 x_all_c = [grid_pts_centered(1,:)/fc_2(1);grid_pts_centered(2,:)/fc_2(2)];
47 x_all_c = comp_distortion(x_all_c,k_dist); % we can this time!!!
48 else
49 fc_2 = [1;1];
50 x_all_c = grid_pts_centered;
51 end;
52else
53 fc_2 = [1;1];
54 x_all_c = grid_pts_centered;
55end;
56
57
58dX = W/n_sq_x;
59dY = L/n_sq_y;
60
61
62N_x = n_sq_x+1;
63N_y = n_sq_y+1;
64
65
66x_grid = zeros(N_x,N_y);
67y_grid = zeros(N_x,N_y);
68
69
70
71
72
73%%% Computation of the four vanishing points in pixels
74
75
76 x_grid(:) = grid_pts_centered(1,:);
77 y_grid(:) = grid_pts_centered(2,:);
78
79 for k=1:n_sq_x+1,
80 [U,S,V] = svd([x_grid(k,:);y_grid(k,:);ones(1,n_sq_y+1)]);
81 vert(:,k) = U(:,3);
82 end;
83
84 for k=1:n_sq_y+1,
85 [U,S,V] = svd([x_grid(:,k)';y_grid(:,k)';ones(1,n_sq_x+1)]);
86 hori(:,k) = U(:,3);
87 end;
88
89 % 2 principle Vanishing points:
90 [U,S,V] = svd(vert);
91 V_vert = U(:,3);
92 [U,S,V] = svd(hori);
93 V_hori = U(:,3);
94
95
96
97 % Square warping:
98
99
100 vert_first = vert(:,1) - dot(V_vert,vert(:,1))/dot(V_vert,V_vert) * V_vert;
101 vert_last = vert(:,n_sq_x+1) - dot(V_vert,vert(:,n_sq_x+1))/dot(V_vert,V_vert) * V_vert;
102
103 hori_first = hori(:,1) - dot(V_hori,hori(:,1))/dot(V_hori,V_hori) * V_hori;
104 hori_last = hori(:,n_sq_y+1) - dot(V_hori,hori(:,n_sq_y+1))/dot(V_hori,V_hori) * V_hori;
105
106
107 x1 = cross(hori_first,vert_first);
108 x2 = cross(hori_first,vert_last);
109 x3 = cross(hori_last,vert_last);
110 x4 = cross(hori_last,vert_first);
111
112 x1 = x1/x1(3);
113 x2 = x2/x2(3);
114 x3 = x3/x3(3);
115 x4 = x4/x4(3);
116
117
118
119 [square] = Rectangle2Square([x1 x2 x3 x4],W,L);
120
121 y1 = square(:,1);
122 y2 = square(:,2);
123 y3 = square(:,3);
124 y4 = square(:,4);
125
126 H2 = cross(V_vert,V_hori);
127
128 V_diag1 = cross(cross(y1,y3),H2);
129 V_diag2 = cross(cross(y2,y4),H2);
130
131 V_diag1 = V_diag1 / norm(V_diag1);
132 V_diag2 = V_diag2 / norm(V_diag2);
133
134 V_hori_pix = V_hori;
135 V_vert_pix = V_vert;
136 V_diag1_pix = V_diag1;
137 V_diag2_pix = V_diag2;
138
139
140% end of computation of the vanishing points in pixels.
141
142
143
144
145
146
147
148
149if two_focal, % only if we attempt to estimate two focals...
150 % Use diagonal lines also to add two extra vanishing points (?)
151 N_min = min(N_x,N_y);
152
153 if N_min < 2,
154 use_diag = 0;
155 two_focal = 0;
156 disp('Cannot estimate two focals (no existing diagonals)');
157 else
158 use_diag = 1;
159 Delta_N = abs(N_x-N_y);
160 N_extra = round((N_min - Delta_N - 1)/2);
161 diag_list = -N_extra:Delta_N+N_extra;
162 N_diag = length(diag_list);
163 diag_1 = zeros(3,N_diag);
164 diag_2 = zeros(3,N_diag);
165 end;
166else
167 % Give up the use of the diagonals (so far)
168 % it seems that the error is increased
169 use_diag = 0;
170end;
171
172
173
174% The vertical lines: vert, Horizontal lines: hori
175vert = zeros(3,n_sq_x+1);
176hori = zeros(3,n_sq_y+1);
177
178for counter_k = 1:N_iter, % the Iterative Vanishing Points Algorithm to
179 % estimate the focal length accurately
180
181 x_grid(:) = x_all_c(1,:);
182 y_grid(:) = x_all_c(2,:);
183
184 for k=1:n_sq_x+1,
185 [U,S,V] = svd([x_grid(k,:);y_grid(k,:);ones(1,n_sq_y+1)]);
186 vert(:,k) = U(:,3);
187 end;
188
189 for k=1:n_sq_y+1,
190 [U,S,V] = svd([x_grid(:,k)';y_grid(:,k)';ones(1,n_sq_x+1)]);
191 hori(:,k) = U(:,3);
192 end;
193
194 % 2 principle Vanishing points:
195 [U,S,V] = svd(vert);
196 V_vert = U(:,3);
197 [U,S,V] = svd(hori);
198 V_hori = U(:,3);
199
200
201
202 % Square warping:
203
204
205 vert_first = vert(:,1) - dot(V_vert,vert(:,1))/dot(V_vert,V_vert) * V_vert;
206 vert_last = vert(:,n_sq_x+1) - dot(V_vert,vert(:,n_sq_x+1))/dot(V_vert,V_vert) * V_vert;
207
208 hori_first = hori(:,1) - dot(V_hori,hori(:,1))/dot(V_hori,V_hori) * V_hori;
209 hori_last = hori(:,n_sq_y+1) - dot(V_hori,hori(:,n_sq_y+1))/dot(V_hori,V_hori) * V_hori;
210
211
212 x1 = cross(hori_first,vert_first);
213 x2 = cross(hori_first,vert_last);
214 x3 = cross(hori_last,vert_last);
215 x4 = cross(hori_last,vert_first);
216
217 x1 = x1/x1(3);
218 x2 = x2/x2(3);
219 x3 = x3/x3(3);
220 x4 = x4/x4(3);
221
222
223
224 [square] = Rectangle2Square([x1 x2 x3 x4],W,L);
225
226 y1 = square(:,1);
227 y2 = square(:,2);
228 y3 = square(:,3);
229 y4 = square(:,4);
230
231 H2 = cross(V_vert,V_hori);
232
233 V_diag1 = cross(cross(y1,y3),H2);
234 V_diag2 = cross(cross(y2,y4),H2);
235
236 V_diag1 = V_diag1 / norm(V_diag1);
237 V_diag2 = V_diag2 / norm(V_diag2);
238
239
240
241
242 % Estimation of the focal length, and normalization:
243
244 % Compute the ellipsis of (1/f^2) positions:
245 % a * (1/fx)^2 + b * (1/fx)^2 = -c
246
247
248 a1 = V_hori(1);
249 b1 = V_hori(2);
250 c1 = V_hori(3);
251
252 a2 = V_vert(1);
253 b2 = V_vert(2);
254 c2 = V_vert(3);
255
256 a3 = V_diag1(1);
257 b3 = V_diag1(2);
258 c3 = V_diag1(3);
259
260 a4 = V_diag2(1);
261 b4 = V_diag2(2);
262 c4 = V_diag2(3);
263
264
265 if two_focal,
266
267
268 A = [a1*a2 b1*b2;a3*a4 b3*b4];
269 b = -[c1*c2;c3*c4];
270
271 f = sqrt(abs(1./(inv(A)*b)));
272
273 else
274
275 f = sqrt(abs(-(c1*c2*(a1*a2 + b1*b2) + c3*c4*(a3*a4 + b3*b4))/(c1^2*c2^2 + c3^2*c4^2)));
276
277 f = [f;f];
278
279 end;
280
281
282
283 % REMARK:
284 % if both a and b are small, the calibration is impossible.
285 % if one of them is small, only the other focal length is observable
286 % if none is small, both focals are observable
287
288
289 fc_2 = fc_2 .* f;
290
291
292 % DEBUG PART: fix focal to 500...
293 %fc_2= [500;500]; disp('Line 293 to be earased in Distor2Calib.m');
294
295
296 % end of focal compensation
297
298 % normalize by the current focal:
299
300 x_all = [grid_pts_centered(1,:)/fc_2(1);grid_pts_centered(2,:)/fc_2(2)];
301
302 % Compensate by the distortion factor:
303
304 x_all_c = comp_distortion(x_all,k_dist);
305
306end;
307
308% At that point, we hope that the distortion is gone...
309
310x_grid(:) = x_all_c(1,:);
311y_grid(:) = x_all_c(2,:);
312
313for k=1:n_sq_x+1,
314 [U,S,V] = svd([x_grid(k,:);y_grid(k,:);ones(1,n_sq_y+1)]);
315 vert(:,k) = U(:,3);
316end;
317
318for k=1:n_sq_y+1,
319 [U,S,V] = svd([x_grid(:,k)';y_grid(:,k)';ones(1,n_sq_x+1)]);
320 hori(:,k) = U(:,3);
321end;
322
323% Vanishing points:
324[U,S,V] = svd(vert);
325V_vert = U(:,3);
326[U,S,V] = svd(hori);
327V_hori = U(:,3);
328
329% Horizon:
330
331H_2 = cross(V_vert,V_hori);
332
333% H_2 = cross(V_vert,V_hori);
334
335% pick a plane in front of the camera (positive depth)
336if H_2(3) < 0, H_2 = -H_2; end;
337
338
339% Rotation matrix:
340
341if V_hori(1) < 0, V_hori = -V_hori; end;
342
343V_hori = V_hori/norm(V_hori);
344H_2 = H_2/norm(H_2);
345
346V_hori = V_hori - dot(V_hori,H_2)*H_2;
347
348Rc_2 = [V_hori cross(H_2,V_hori) H_2];
349
350Rc_2 = Rc_2 / det(Rc_2);
351
352%omc_2 = rodrigues(Rc_2);
353
354%Rc_2 = rodrigues(omc_2);
355
356% Find the distance of the plane for translation vector:
357
358xc_2 = [x_all_c;ones(1,Np)];
359
360Zc_2 = 1./sum(xc_2 .* (Rc_2(:,3)*ones(1,Np)));
361
362Xo_2 = [sum(xc_2 .* (Rc_2(:,1)*ones(1,Np))).*Zc_2 ; sum(xc_2 .* (Rc_2(:,2)*ones(1,Np))).*Zc_2];
363
364XXo_2 = Xo_2 - mean(Xo_2')'*ones(1,Np);
365
366distance_x = norm(Xgrid_2(1,:))/norm(XXo_2(1,:));
367distance_y = norm(Xgrid_2(2,:))/norm(XXo_2(2,:));
368
369
370distance = sum(sum(XXo_2(1:2,:).*Xgrid_2(1:2,:)))/sum(sum(XXo_2(1:2,:).^2));
371
372alpha = abs(distance_x - distance_y)/distance;
373
374if (alpha>0.1)&~two_focal,
375 disp('Should use two focals in x and y...');
376end;
377
378% Deduce the translation vector:
379
380Tc_2 = distance * H_2;
381
382
383
384
385
386return;
387
388 V_hori_pix/V_hori_pix(3)
389 V_vert_pix/V_vert_pix(3)
390 V_diag1_pix/V_diag1_pix(3)
391 V_diag2_pix/V_diag2_pix(3)
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m
new file mode 100755
index 0000000..a6bbbe5
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/Rectangle2Square.m
@@ -0,0 +1,19 @@
1function [square] = Rectangle2Square(rectangle,L,W);
2
3% Generate the square from a rectangle of known segment lengths
4% from pt1 to pt2 : L
5% from pt2 to pt3 : W
6
7[u_hori,u_vert] = UnWarpPlane(rectangle);
8
9coeff_x = sqrt(W/L);
10coeff_y = 1/coeff_x;
11
12x_coord = [ 0 coeff_x coeff_x 0];
13y_coord = [ 0 0 coeff_y coeff_y];
14
15
16square = rectangle(:,1) * ones(1,4) + u_hori*x_coord + u_vert*y_coord;
17square = square ./ (ones(3,1)*square(3,:));
18
19
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m
new file mode 100755
index 0000000..8addf52
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/UnWarpPlane.m
@@ -0,0 +1,54 @@
1function [u_hori,u_vert] = UnWarpPlane(x1,x2,x3,x4);
2
3% Recovers the two 3D directions of the rectangular patch x1x2x3x4
4% x1 is the origin point, ie any point of planar coordinate (x,y) on the
5% rectangular patch will be projected on the image plane at:
6% x1 + x * u_hori + y * u_vert
7%
8% Note: u_hori and u_vert are also the two vanishing points.
9
10
11if nargin < 4,
12
13 x4 = x1(:,4);
14 x3 = x1(:,3);
15 x2 = x1(:,2);
16 x1 = x1(:,1);
17
18end;
19
20
21% Image Projection:
22L1 = cross(x1,x2);
23L2 = cross(x4,x3);
24L3 = cross(x2,x3);
25L4 = cross(x1,x4);
26
27% Vanishing point:
28V1 = cross(L1,L2);
29V2 = cross(L3,L4);
30
31% Horizon line:
32H = cross(V1,V2);
33
34if H(3) < 0, H = -H; end;
35
36
37H = H / norm(H);
38
39
40X1 = x1 / dot(H,x1);
41X2 = x2 / dot(H,x2);
42X3 = x3 / dot(H,x3);
43X4 = x4 / dot(H,x4);
44
45scale = X1(3);
46
47X1 = X1/scale;
48X2 = X2/scale;
49X3 = X3/scale;
50X4 = X4/scale;
51
52
53u_hori = X2 - X1;
54u_vert = X4 - X1;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m
new file mode 100755
index 0000000..a8a32c0
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/add_suppress.m
@@ -0,0 +1,98 @@
1
2if ~exist('n_ima'),
3 fprintf(1,'No data to process.\n');
4 return;
5end;
6
7
8check_active_images;
9
10
11fprintf(1,'\nThis function is useful to select a subset of images to calibrate\n');
12
13 fprintf(1,'\nThere are currently %d active images selected for calibration (out of %d):\n',length(ind_active),n_ima);
14
15 if ~isempty(ind_active),
16
17 for ii = 1:length(ind_active)-2,
18
19 fprintf(1,'%d, ',ind_active(ii));
20
21 end;
22
23 fprintf(1,'%d and %d.',ind_active(end-1),ind_active(end));
24
25 end;
26
27 fprintf(1,'\n');
28
29
30fprintf(1,'\nDo you want to suppress or add images from that list?\n');
31
32choice = 2;
33
34while (choice~=0)&(choice~=1),
35 choice = input('For suppressing images enter 0, for adding images enter 1 ([]=no change): ');
36 if isempty(choice),
37 fprintf(1,'No change applied to the list of active images.\n');
38 return;
39 end;
40 if (choice~=0)&(choice~=1),
41 disp('Bad entry. Try again.');
42 end;
43end;
44
45
46if choice,
47
48 ima_numbers = input('Number(s) of image(s) to add ([] = all images) = ');
49
50if isempty(ima_numbers),
51 fprintf(1,'All %d images are now active\n',n_ima);
52 ima_proc = 1:n_ima;
53 else
54 ima_proc = ima_numbers;
55 end;
56
57else
58
59
60 ima_numbers = input('Number(s) of image(s) to suppress ([] = no image) = ');
61
62 if isempty(ima_numbers),
63 fprintf(1,'No image has been suppressed. No modication of the list of active images.\n',n_ima);
64 ima_proc = [];
65 else
66 ima_proc = ima_numbers;
67 end;
68
69end;
70
71if ~isempty(ima_proc),
72
73 active_images(ima_proc) = choice * ones(1,length(ima_proc));
74
75end;
76
77
78 check_active_images;
79
80
81 fprintf(1,'\nThere is now a total of %d active images for calibration:\n',length(ind_active));
82
83 if ~isempty(ind_active),
84
85 for ii = 1:length(ind_active)-2,
86
87 fprintf(1,'%d, ',ind_active(ii));
88
89 end;
90
91 fprintf(1,'%d and %d.',ind_active(end-1),ind_active(end));
92
93 end;
94
95 fprintf(1,'\n\nYou may now run ''Calibration'' to recalibrate based on this new set of images.\n');
96
97
98 \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m
new file mode 100755
index 0000000..7a9cf0f
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/analyse_error.m
@@ -0,0 +1,141 @@
1% Color code for each image:
2
3if ~exist('n_ima')|~exist('fc'),
4 fprintf(1,'No calibration data available.\n');
5 return;
6end;
7
8check_active_images;
9
10if ~exist(['ex_' num2str(ind_active(1)) ]),
11 fprintf(1,'Need to calibrate before analysing reprojection error. Maybe need to load Calib_Results.mat file.\n');
12 return;
13end;
14
15
16%if ~exist('no_grid'),
17 no_grid = 0;
18%end;
19
20colors = 'brgkcm';
21
22
23figure(5);
24
25for kk = 1:n_ima,
26 if exist(['y_' num2str(kk)]),
27 if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']),
28
29 if ~no_grid,
30 eval(['XX_kk = X_' num2str(kk) ';']);
31 N_kk = size(XX_kk,2);
32
33 if ~exist(['n_sq_x_' num2str(kk)]),
34 no_grid = 1;
35 end;
36
37 if ~no_grid,
38 eval(['n_sq_x = n_sq_x_' num2str(kk) ';']);
39 eval(['n_sq_y = n_sq_y_' num2str(kk) ';']);
40 if (N_kk ~= ((n_sq_x+1)*(n_sq_y+1))),
41 no_grid = 1;
42 end;
43 end;
44 end;
45
46 eval(['plot(ex_' num2str(kk) '(1,:),ex_' num2str(kk) '(2,:),''' colors(rem(kk-1,6)+1) '+'');']);
47
48 hold on;
49 end;
50 end;
51end;
52
53hold off;
54axis('equal');
55if 1, %~no_grid,
56 title('Reprojection error (in pixel) - To exit: right button');
57else
58 title('Reprojection error (in pixel)');
59end;
60xlabel('x');
61ylabel('y');
62
63set(5,'Name','error','NumberTitle','off');
64
65
66
67err_std = std(ex')';
68
69fprintf(1,'Pixel error: err = [ %3.5f %3.5f] (all active images)\n\n',err_std);
70
71
72b = 1;
73
74while b==1,
75
76[xp,yp,b] = ginput3(1);
77
78if b==1,
79ddd = (ex(1,:)-xp).^2 + (ex(2,:)-yp).^2;
80
81[mind,indmin] = min(ddd);
82
83
84done = 0;
85kk_ima = 1;
86while (~done)&(kk_ima<=n_ima),
87 %fprintf(1,'%d...',kk_ima);
88 eval(['ex_kk = ex_' num2str(kk_ima) ';']);
89 sol_kk = find((ex_kk(1,:) == ex(1,indmin))&(ex_kk(2,:) == ex(2,indmin)));
90 if isempty(sol_kk),
91 kk_ima = kk_ima + 1;
92 else
93 done = 1;
94 end;
95end;
96
97if ~no_grid,
98
99eval(['n_sq_x = n_sq_x_' num2str(kk_ima) ';']);
100eval(['n_sq_y = n_sq_y_' num2str(kk_ima) ';']);
101
102Nx = n_sq_x+1;
103Ny = n_sq_y+1;
104
105y1 = floor((sol_kk-1)./Nx);
106x1 = sol_kk - 1 - Nx*y1; %rem(sol_kk-1,Nx);
107
108y1 = (n_sq_y+1) - y1;
109x1 = x1 + 1;
110
111fprintf(1,'\nSelected image: %d\nSelected point: (col,row)=(%d,%d)\nNcol=%d, Nrow=%d\n',[kk_ima x1 y1 Nx Ny]);
112fprintf(1,'Pixel error = (%3.5f,%3.5f)\n',[ex(1,indmin) ex(2,indmin)]);
113
114else
115
116 eval(['x_kk = x_' num2str(kk_ima) ';']);
117
118 xpt = x_kk(:,sol_kk);
119
120fprintf(1,'\nSelected image: %d\nImage coordinates (in pixel): (%3.2f,%3.2f)\n',[kk_ima xpt']);
121fprintf(1,'Pixel error = (%3.5f,%3.5f)\n',[ex(1,indmin) ex(2,indmin)]);
122
123
124end;
125
126
127if exist(['wintx_' num2str(kk_ima)]),
128
129 eval(['wintx = wintx_' num2str(kk_ima) ';']);
130 eval(['winty = winty_' num2str(kk_ima) ';']);
131
132 fprintf(1,'Window size: wintx = %d, winty = %d\n',[wintx winty]);
133end;
134
135
136end;
137
138end;
139
140disp('done');
141
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m
new file mode 100755
index 0000000..f5c5b48
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/apply_distortion.m
@@ -0,0 +1,137 @@
1function [xd,dxddk] = apply_distortion(x,k)
2
3
4[m,n] = size(x);
5
6% Add distortion:
7
8r2 = x(1,:).^2 + x(2,:).^2;
9
10r4 = r2.^2;
11
12% Radial distortion:
13
14cdist = 1 + k(1) * r2 + k(2) * r4;
15
16if nargout > 1,
17 dcdistdk = [ r2' r4' zeros(n,2)];
18end;
19
20
21xd1 = x .* (ones(2,1)*cdist);
22
23coeff = (reshape([cdist;cdist],2*n,1)*ones(1,3));
24
25if nargout > 1,
26 dxd1dk = zeros(2*n,4);
27 dxd1dk(1:2:end,:) = (x(1,:)'*ones(1,4)) .* dcdistdk;
28 dxd1dk(2:2:end,:) = (x(2,:)'*ones(1,4)) .* dcdistdk;
29end;
30
31
32% tangential distortion:
33
34a1 = 2.*x(1,:).*x(2,:);
35a2 = r2 + 2*x(1,:).^2;
36a3 = r2 + 2*x(2,:).^2;
37
38delta_x = [k(3)*a1 + k(4)*a2 ;
39 k(3) * a3 + k(4)*a1];
40
41aa = (2*k(3)*x(2,:)+6*k(4)*x(1,:))'*ones(1,3);
42bb = (2*k(3)*x(1,:)+2*k(4)*x(2,:))'*ones(1,3);
43cc = (6*k(3)*x(2,:)+2*k(4)*x(1,:))'*ones(1,3);
44
45if nargout > 1,
46 ddelta_xdk = zeros(2*n,4);
47 ddelta_xdk(1:2:end,3) = a1';
48 ddelta_xdk(1:2:end,4) = a2';
49 ddelta_xdk(2:2:end,3) = a3';
50 ddelta_xdk(2:2:end,4) = a1';
51end;
52
53xd = xd1 + delta_x;
54
55if nargout > 1,
56 dxddk = dxd1dk + ddelta_xdk ;
57end;
58
59
60return;
61
62% Test of the Jacobians:
63
64n = 10;
65
66X = 10*randn(3,n);
67om = randn(3,1);
68T = [10*randn(2,1);40];
69f = 1000*rand(2,1);
70c = 1000*randn(2,1);
71k = 0.5*randn(4,1);
72
73
74[x,dxdom,dxdT,dxdf,dxdc,dxdk] = project_points(X,om,T,f,c,k);
75
76
77% Test on om: NOT OK
78
79dom = 0.000000001 * norm(om)*randn(3,1);
80om2 = om + dom;
81
82[x2] = project_points(X,om2,T,f,c,k);
83
84x_pred = x + reshape(dxdom * dom,2,n);
85
86
87norm(x2-x)/norm(x2 - x_pred)
88
89
90% Test on T: OK!!
91
92dT = 0.0001 * norm(T)*randn(3,1);
93T2 = T + dT;
94
95[x2] = project_points(X,om,T2,f,c,k);
96
97x_pred = x + reshape(dxdT * dT,2,n);
98
99
100norm(x2-x)/norm(x2 - x_pred)
101
102
103
104% Test on f: OK!!
105
106df = 0.001 * norm(f)*randn(2,1);
107f2 = f + df;
108
109[x2] = project_points(X,om,T,f2,c,k);
110
111x_pred = x + reshape(dxdf * df,2,n);
112
113
114norm(x2-x)/norm(x2 - x_pred)
115
116
117% Test on c: OK!!
118
119dc = 0.01 * norm(c)*randn(2,1);
120c2 = c + dc;
121
122[x2] = project_points(X,om,T,f,c2,k);
123
124x_pred = x + reshape(dxdc * dc,2,n);
125
126norm(x2-x)/norm(x2 - x_pred)
127
128% Test on k: OK!!
129
130dk = 0.001 * norm(4)*randn(4,1);
131k2 = k + dk;
132
133[x2] = project_points(X,om,T,f,c,k2);
134
135x_pred = x + reshape(dxdk * dk,2,n);
136
137norm(x2-x)/norm(x2 - x_pred)
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m
new file mode 100755
index 0000000..d591d03
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/calib_gui.m
@@ -0,0 +1,117 @@
1fig_number = 1;
2
3n_row = 4;
4n_col = 4;
5
6string_list = cell(n_row,n_col);
7callback_list = cell(n_row,n_col);
8
9x_size = 85;
10y_size = 14;
11gap_x = 0;
12font_name = 'clean';
13font_size = 8;
14
15title_figure = 'Camera Calibration Toolbox';
16
17string_list{1,1} = 'Image names';
18string_list{1,2} = 'Read images';
19string_list{1,3} = 'Extract grid corners';
20string_list{1,4} = 'Calibration';
21string_list{2,1} = 'Show Extrinsic';
22string_list{2,2} = 'Reproject on images';
23string_list{2,3} = 'Analyse error';
24string_list{2,4} = 'Recomp. corners';
25string_list{3,1} = 'Add/Suppress images';
26string_list{3,2} = 'Save';
27string_list{3,3} = 'Load';
28string_list{3,4} = 'Exit';
29
30string_list{4,1} = 'Comp. Extrinsic';
31string_list{4,2} = 'Undistort image';
32string_list{4,3} = 'Export calib data';
33
34
35callback_list{1,1} = 'data_calib;';
36callback_list{1,2} = 'ima_read_calib;';
37callback_list{1,3} = 'click_calib;';
38callback_list{1,4} = 'go_calib_optim;';
39callback_list{2,1} = 'ext_calib;';
40callback_list{2,2} = 'reproject_calib;';
41callback_list{2,3} = 'analyse_error;';
42callback_list{2,4} = 'recomp_corner_calib;';
43callback_list{3,1} = 'add_suppress;';
44callback_list{3,2} = 'saving_calib;';
45callback_list{3,3} = 'loading_calib;';
46callback_list{3,4} = ['disp(''Bye. To run again, type calib_gui.''); close(' num2str(fig_number) ');'];
47
48callback_list{4,1} = 'extrinsic_computation;';
49callback_list{4,2} = 'undistort_image;';
50callback_list{4,3} = 'export_calib_data;';
51
52
53%------- BEGIN PROECTED REGION -----------%
54%------- DO NOT EDIT IN THIS REGION -----------%
55
56figure(fig_number); clf;
57pos = get(fig_number,'Position');
58
59fig_size_x = x_size*n_col+(n_col+1)*gap_x;
60fig_size_y = y_size*n_row+(n_row+1)*gap_x;
61
62set(fig_number,'Units','points', ...
63 'BackingStore','off', ...
64 'Color',[0.8 0.8 0.8], ...
65 'MenuBar','none', ...
66 'Resize','off', ...
67 'Name',title_figure, ...
68'Position',[pos(1) pos(2) fig_size_x fig_size_y], ...
69'NumberTitle','off'); %,'WindowButtonMotionFcn',['figure(' num2str(fig_number) ');']);
70
71h_mat = zeros(n_row,n_col);
72
73posx = zeros(n_row,n_col);
74posy = zeros(n_row,n_col);
75
76for i=n_row:-1:1,
77 for j = n_col:-1:1,
78 posx(i,j) = gap_x+(j-1)*(x_size+gap_x);
79 posy(i,j) = fig_size_y - i*(gap_x+y_size);
80 end;
81end;
82
83for i=n_row:-1:1,
84 for j = n_col:-1:1,
85 if ~isempty(string_list{i,j}) & ~isempty(callback_list{i,j}),
86 h_mat(i,j) = uicontrol('Parent',fig_number, ...
87 'Units','points', ...
88 'Callback',callback_list{i,j}, ...
89 'ListboxTop',0, ...
90 'Position',[posx(i,j) posy(i,j) x_size y_size], ...
91 'String',string_list{i,j}, ...
92 'fontsize',font_size,...
93 'fontname',font_name,...
94 'Tag','Pushbutton1');
95 end;
96 end;
97end;
98
99%------ END PROTECTED REGION ----------------%
100
101if 0,
102%-- VERSION:
103
104uicontrol('Parent',fig_number, ...
105 'Units','points', ...
106 'ListboxTop',0, ...
107 'Position',[(fig_size_x-x_size/2)-2 -5 x_size/2 y_size], ...
108 'String','ver. 1.0', ...
109 'fontsize',8,...
110 'BackgroundColor',[0.8 0.8 0.8], ...
111 'fontname','clean',...
112 'HorizontalAlignment','right', ...
113 'Style','text');
114end;
115
116
117%clear callback_list string_list fig_number fig_size_x fig_size_y i j n_col n_row pos string_list title_figure x_size y_size font_name font_size gap_x h_mat posx posy
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m
new file mode 100755
index 0000000..fc365a5
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_active_images.m
@@ -0,0 +1,19 @@
1
2if ~exist('active_images'),
3 active_images = ones(1,n_ima);
4end;
5n_act = length(active_images);
6if n_act < n_ima,
7 active_images = [active_images ones(1,n_ima-n_act)];
8else
9 if n_act > n_ima,
10 active_images = active_images(1:n_ima);
11 end;
12end;
13
14ind_active = find(active_images);
15
16if prod(active_images == 0),
17 disp('Error: There is no active image');
18 break
19end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m
new file mode 100755
index 0000000..c4b13fd
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_convergence.m
@@ -0,0 +1,48 @@
1%%% Replay the set of solution vectors:
2
3
4if ~exist('param_list'),
5 if ~exist('solution');
6 fprintf(1,'Error: Need to calibrate first\n');
7 return;
8 else
9 param_list = solution;
10 end;
11end;
12
13N_iter = size(param_list,2);
14
15if N_iter == 1,
16 fprintf(1,'Warning: There is a unique state in the list of parameters.\n');
17end;
18
19
20
21%M = moviein(N_iter);
22
23for nn = 1:N_iter,
24
25 solution = param_list(:,nn);
26
27 extract_parameters;
28 comp_error_calib;
29
30 ext_calib;
31
32 drawnow;
33
34% Mnn = getframe(gcf);
35
36% M(:,nn) = Mnn;
37
38end;
39
40%fig = gcf;
41
42
43%figure(fig+1);
44%close;
45%figure(fig+1);
46
47%clf;
48%movie(M,20);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m
new file mode 100755
index 0000000..dc23149
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_directory.m
@@ -0,0 +1,97 @@
1% This small script looks in the direcory and checks if the images are there.
2%
3% This works only on Matlab 5.x (otherwise, the dir commands works differently)
4
5% (c) Jean-Yves Bouguet - Dec. 27th, 1999
6
7l = dir([calib_name '*']);
8
9Nl = size(l,1);
10Nima_valid = 0;
11ind_valid = [];
12loc_extension = [];
13length_name = size(calib_name,2);
14
15if Nl > 0,
16
17 for pp = 1:Nl,
18 filenamepp = l(pp).name;
19 iii = findstr(filenamepp,calib_name);
20
21 loc_ext = findstr(filenamepp,format_image);
22 string_num = filenamepp(length_name+1:loc_ext - 2);
23
24 if isempty(str2num(string_num)),
25 iii = [];
26 end;
27
28
29 if ~isempty(iii),
30 if (iii(1) ~= 1),
31 iii = [];
32 end;
33 end;
34
35
36
37 if ~isempty(iii) & ~isempty(loc_ext),
38
39 Nima_valid = Nima_valid + 1;
40 ind_valid = [ind_valid pp];
41 loc_extension = [loc_extension loc_ext(1)];
42
43 end;
44
45 end;
46
47 if (Nima_valid==0),
48
49 fprintf(1,'No image found. File format may be wrong.\n');
50
51 else
52
53 % Get all the string numbers:
54
55 string_length = zeros(1,Nima_valid);
56 indices = zeros(1,Nima_valid);
57
58
59 for ppp = 1:Nima_valid,
60
61 name = l(ind_valid(ppp)).name;
62 string_num = name(length_name+1:loc_extension(ppp) - 2);
63 string_length(ppp) = size(string_num,2);
64 indices(ppp) = str2num(string_num);
65
66 end;
67
68 % Number of images...
69 first_num = min(indices);
70 n_ima = max(indices) - first_num + 1;
71
72 if min(string_length) == max(string_length),
73
74 N_slots = min(string_length);
75 type_numbering = 1;
76
77 else
78
79 N_slots = 1;
80 type_numbering = 0;
81
82 end;
83
84 image_numbers = first_num:n_ima-1+first_num;
85
86 %%% By default, all the images are active for calibration:
87
88 active_images = ones(1,n_ima);
89
90 end;
91
92else
93
94 fprintf(1,'No image found. Basename may be wrong.\n');
95
96end;
97
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m
new file mode 100755
index 0000000..fa7df87
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/check_extracted_images.m
@@ -0,0 +1,37 @@
1check_active_images;
2
3for kk = ind_active,
4
5 if ~exist(['x_' num2str(kk)]),
6
7 fprintf(1,'WARNING: Need to extract grid corners on image %d\n',kk);
8
9 active_images(kk) = 0;
10
11 eval(['dX_' num2str(kk) ' = NaN;']);
12 eval(['dY_' num2str(kk) ' = NaN;']);
13
14 eval(['wintx_' num2str(kk) ' = NaN;']);
15 eval(['winty_' num2str(kk) ' = NaN;']);
16
17 eval(['x_' num2str(kk) ' = NaN*ones(2,1);']);
18 eval(['X_' num2str(kk) ' = NaN*ones(3,1);']);
19
20 eval(['n_sq_x_' num2str(kk) ' = NaN;']);
21 eval(['n_sq_y_' num2str(kk) ' = NaN;']);
22
23 else
24
25 eval(['xkk = x_' num2str(kk) ';']);
26
27 if isnan(xkk(1)),
28
29 fprintf(1,'WARNING: Need to extract grid corners on image %d - This image is now set inactive\n',kk);
30
31 active_images(kk) = 0;
32
33 end;
34
35 end;
36
37end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m
new file mode 100755
index 0000000..1eccbd3
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clear_windows.m
@@ -0,0 +1,4 @@
1for kk = 1:n_ima,
2 eval(['clear wintx_' num2str(kk)]);
3 eval(['clear winty_' num2str(kk)]);
4end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m
new file mode 100755
index 0000000..a04be67
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/clearwin.m
@@ -0,0 +1,10 @@
1% Function that clears all the wintx_i and winty_i
2% In normal operation of the toolbox, this function should not be
3% useful.
4% only in cases where you want to re-extract corners using the Extract grid corners another time... not common. You might as well use the Recomp. corners.
5
6for kk = 1:n_ima,
7
8 eval(['clear wintx_' num2str(kk) ' winty_' num2str(kk)]);
9
10end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m
new file mode 100755
index 0000000..1a6d2d7
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_calib.m
@@ -0,0 +1,193 @@
1%if exist('images_read');
2% active_images = active_images & images_read;
3%end;
4
5var2fix = 'dX_default';
6
7fixvariable;
8
9var2fix = 'dY_default';
10
11fixvariable;
12
13var2fix = 'map';
14
15fixvariable;
16
17
18if ~exist('n_ima'),
19 data_calib;
20end;
21
22check_active_images;
23
24if ~exist(['I_' num2str(ind_active(1))]),
25 ima_read_calib;
26 if isempty(ind_read),
27 disp('Cannot extract corners without images');
28 return;
29 end;
30end;
31
32
33%wintx = 10; % neigborhood of integration for
34%winty = 10; % the corner finder
35
36fprintf(1,'\nExtraction of the grid corners on the images\n');
37
38
39if ~exist('map'), map = gray(256); end;
40
41
42disp('WARNING!!! Do not forget to change dX_default and dY_default in click_calib.m!!!')
43
44if ~exist('dX_default');
45
46% Default size of the pattern squares;
47
48% Setup of JY (old at Caltech)
49%dX_default = 21.9250/11;
50%dY_default = 18.1250/9;
51
52% Setup of JY (new at Intel)
53%dX_default = 1.9750;
54%dY_default = 1.9865;
55
56
57% Setup of Luis and Enrico
58%dX_default = 67.7/16;
59%dY_default = 50.65/12;
60
61
62% Setup of German
63%dX_default = 10.16;
64%dY_default = 10.16;
65
66% Setup of JY (new at Intel)
67%dX_default = 1.9750*2.54;
68%dY_default = 1.9865*2.54;
69
70% Setup of JY - 3D calibration rig at Intel (new at Intel)
71%dX_default = 3;
72%dY_default = 3;
73
74% Setup of JY - 3D calibration rig at Intel (new at Intel) - use units in mm to match Zhang
75dX_default = 30;
76dY_default = 30;
77
78end;
79
80
81if ~exist('dont_ask'),
82 dont_ask = 0;
83end;
84
85
86if ~dont_ask,
87 ima_numbers = input('Number(s) of image(s) to process ([] = all images) = ');
88else
89 ima_numbers = [];
90end;
91
92if isempty(ima_numbers),
93 ima_proc = 1:n_ima;
94else
95 ima_proc = ima_numbers;
96end;
97
98
99% Useful option to add images:
100kk_first = ima_proc(1); %input('Start image number ([]=1=first): ');
101
102%if isempty(kk_first), kk_first = 1; end;
103
104
105if exist(['wintx_' num2str(kk_first)]),
106
107 eval(['wintxkk = wintx_' num2str(kk_first) ';']);
108
109 if isempty(wintxkk) | isnan(wintxkk),
110
111 disp('Window size for corner finder (wintx and winty):');
112 wintx = input('wintx ([] = 5) = ');
113 if isempty(wintx), wintx = 5; end;
114 wintx = round(wintx);
115 winty = input('winty ([] = 5) = ');
116 if isempty(winty), winty = 5; end;
117 winty = round(winty);
118
119 fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1);
120
121 end;
122
123else
124
125 disp('Window size for corner finder (wintx and winty):');
126 wintx = input('wintx ([] = 5) = ');
127 if isempty(wintx), wintx = 5; end;
128 wintx = round(wintx);
129 winty = input('winty ([] = 5) = ');
130 if isempty(winty), winty = 5; end;
131 winty = round(winty);
132
133 fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1);
134
135end;
136
137
138for kk = ima_proc,
139 if exist(['I_' num2str(kk)]),
140 click_ima_calib;
141 active_images(kk) = 1;
142 else
143 eval(['dX_' num2str(kk) ' = NaN;']);
144 eval(['dY_' num2str(kk) ' = NaN;']);
145
146 eval(['wintx_' num2str(kk) ' = NaN;']);
147 eval(['winty_' num2str(kk) ' = NaN;']);
148
149 eval(['x_' num2str(kk) ' = NaN*ones(2,1);']);
150 eval(['X_' num2str(kk) ' = NaN*ones(3,1);']);
151
152 eval(['n_sq_x_' num2str(kk) ' = NaN;']);
153 eval(['n_sq_y_' num2str(kk) ' = NaN;']);
154 end;
155end;
156
157
158check_active_images;
159
160
161% Fix potential non-existing variables:
162
163for kk = 1:n_ima,
164 if ~exist(['x_' num2str(kk)]),
165 eval(['dX_' num2str(kk) ' = NaN;']);
166 eval(['dY_' num2str(kk) ' = NaN;']);
167
168 eval(['wintx_' num2str(kk) ' = NaN;']);
169 eval(['winty_' num2str(kk) ' = NaN;']);
170
171 eval(['x_' num2str(kk) ' = NaN*ones(2,1);']);
172 eval(['X_' num2str(kk) ' = NaN*ones(3,1);']);
173
174 eval(['n_sq_x_' num2str(kk) ' = NaN;']);
175 eval(['n_sq_y_' num2str(kk) ' = NaN;']);
176 end;
177end;
178
179
180string_save = 'save calib_data active_images ind_active wintx winty n_ima type_numbering N_slots first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default dX dY';
181
182for kk = 1:n_ima,
183 string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)];
184end;
185
186eval(string_save);
187
188disp('done');
189
190return;
191
192go_calib_optim;
193
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m
new file mode 100755
index 0000000..f0fd4ca
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib.m
@@ -0,0 +1,230 @@
1 % Cleaned-up version of init_calib.m
2
3 fprintf(1,'\nProcessing image %d...\n',kk);
4
5 eval(['I = I_' num2str(kk) ';']);
6
7 if exist(['wintx_' num2str(kk)]),
8
9 eval(['wintxkk = wintx_' num2str(kk) ';']);
10
11 if ~isempty(wintxkk) & ~isnan(wintxkk),
12
13 eval(['wintx = wintx_' num2str(kk) ';']);
14 eval(['winty = winty_' num2str(kk) ';']);
15
16 end;
17 end;
18
19
20 fprintf(1,'Using (wintx,winty)=(%d,%d) - Window size = %dx%d\n',wintx,winty,2*wintx+1,2*winty+1);
21
22
23 figure(2);
24 image(I);
25 colormap(map);
26
27 title(['Click on the four extreme corners of the rectangular pattern... Image ' num2str(kk)]);
28
29 disp('Click on the four extreme corners of the rectangular complete pattern...');
30
31 [x,y] = ginput3(4);
32
33 [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners
34
35 x = Xc(1,:)';
36 y = Xc(2,:)';
37
38 [y,indy] = sort(y);
39 x = x(indy);
40
41 if (x(2) > x(1)),
42 x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2);
43 else
44 x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1);
45 end;
46 if (x(3) > x(4)),
47 x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4);
48 else
49 x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3);
50 end;
51
52 x = [x1;x2;x3;x4];
53 y = [y1;y2;y3;y4];
54
55
56 figure(2); hold on;
57 plot([x;x(1)],[y;y(1)],'g-');
58 plot(x,y,'og');
59 hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X');
60 set(hx,'color','g','Fontsize',14);
61 hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y');
62 set(hy,'color','g','Fontsize',14);
63 hold off;
64
65
66 % Try to automatically count the number of squares in the grid
67
68 n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx);
69 n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx);
70 n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx);
71 n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx);
72
73
74
75 % If could not count the number of squares, enter manually
76
77 if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2),
78
79
80 disp('Could not count the number of squares in the grid. Enter manually.');
81 n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6
82 if isempty(n_sq_x), n_sq_x = 10; end;
83 n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6
84 if isempty(n_sq_y), n_sq_y = 10; end;
85
86 else
87
88 n_sq_x = n_sq_x1;
89 n_sq_y = n_sq_y1;
90
91 end;
92
93
94 % Enter the size of each square
95
96 dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'mm) = ']);
97 dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'mm) = ']);
98 if isempty(dX), dX = dX_default; else dX_default = dX; end;
99 if isempty(dY), dY = dY_default; else dY_default = dY; end;
100
101 % Compute the inside points through computation of the planar homography (collineation)
102
103 a00 = [x(1);y(1);1];
104 a10 = [x(2);y(2);1];
105 a11 = [x(3);y(3);1];
106 a01 = [x(4);y(4);1];
107
108
109 % Compute the planar collineation: (return the normalization matrix as well)
110
111 [Homo,Hnorm,inv_Hnorm] = compute_homography ([a00 a10 a11 a01],[0 1 1 0;0 0 1 1;1 1 1 1]);
112
113
114 % Build the grid using the planar collineation:
115
116 x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x;
117 y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y;
118 pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]';
119
120 XX = Homo*pts;
121 XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:));
122
123
124 % Complete size of the rectangle
125
126 W = n_sq_x*dX;
127 L = n_sq_y*dY;
128
129
130
131
132 %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
133 figure(2);
134 hold on;
135 plot(XX(1,:),XX(2,:),'r+');
136 title('The red crosses should be close to the image corners');
137 hold off;
138
139 disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,');
140 disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)');
141 quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) ');
142
143 quest_distort = ~isempty(quest_distort);
144
145 if quest_distort,
146 % Estimation of focal length:
147 c_g = [size(I,2);size(I,1)]/2 + .5;
148 f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1);
149 f_g = mean(f_g);
150 script_fit_distortion;
151 end;
152 %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
153
154
155
156
157
158 Np = (n_sq_x+1)*(n_sq_y+1);
159
160 disp('Corner extraction...');
161
162 grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points!
163
164
165
166 %save all_corners x y grid_pts
167
168 grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C)
169
170
171
172 ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners
173 ind_orig = (n_sq_x+1)*n_sq_y + 1;
174 xorig = grid_pts(1,ind_orig);
175 yorig = grid_pts(2,ind_orig);
176 dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]');
177 dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]');
178
179
180 x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)];
181 y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)];
182
183
184 figure(3);
185 image(I); colormap(map); hold on;
186 plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+');
187 plot(x_box_kk+1,y_box_kk+1,'-b');
188 plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo');
189 plot(xorig+1,yorig+1,'*m');
190 h = text(xorig-15,yorig-15,'O');
191 set(h,'Color','m','FontSize',14);
192 h2 = text(dxpos(1)-10,dxpos(2)-10,'dX');
193 set(h2,'Color','g','FontSize',14);
194 h3 = text(dypos(1)-25,dypos(2)-3,'dY');
195 set(h3,'Color','g','FontSize',14);
196 xlabel('Xc (in camera frame)');
197 ylabel('Yc (in camera frame)');
198 title('Extracted corners');
199 zoom on;
200 drawnow;
201 hold off;
202
203
204 Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)';
205 Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)';
206 Zi = zeros(1,Np);
207
208 Xgrid = [Xi;Yi;Zi];
209
210
211 % All the point coordinates (on the image, and in 3D) - for global optimization:
212
213 x = grid_pts;
214 X = Xgrid;
215
216
217 % Saves all the data into variables:
218
219 eval(['dX_' num2str(kk) ' = dX;']);
220 eval(['dY_' num2str(kk) ' = dY;']);
221
222 eval(['wintx_' num2str(kk) ' = wintx;']);
223 eval(['winty_' num2str(kk) ' = winty;']);
224
225 eval(['x_' num2str(kk) ' = x;']);
226 eval(['X_' num2str(kk) ' = X;']);
227
228 eval(['n_sq_x_' num2str(kk) ' = n_sq_x;']);
229 eval(['n_sq_y_' num2str(kk) ' = n_sq_y;']);
230 \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m
new file mode 100755
index 0000000..7718268
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/click_ima_calib3D.m
@@ -0,0 +1,482 @@
1 % Cleaned-up version of init_calib.m
2
3 eval(['I = I_' num2str(kk) ';']);
4
5 figure(2);
6 image(I);
7 colormap(map);
8
9
10
11
12
13 %%%%%%%%%%%%%%%%%%%%%%%%% LEFT PATTERN ACQUISITION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14
15
16
17 title(['Click on the four extreme corners of the left rectangular pattern... Image ' num2str(kk)]);
18
19 disp('Click on the four extreme corners of the left rectangular pattern...');
20
21 [x,y] = ginput3(4);
22
23 [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners
24
25 x = Xc(1,:)';
26 y = Xc(2,:)';
27
28 [y,indy] = sort(y);
29 x = x(indy);
30
31 if (x(2) > x(1)),
32 x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2);
33 else
34 x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1);
35 end;
36 if (x(3) > x(4)),
37 x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4);
38 else
39 x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3);
40 end;
41
42 x = [x1;x2;x3;x4];
43 y = [y1;y2;y3;y4];
44
45
46 figure(2); hold on;
47 plot([x;x(1)],[y;y(1)],'g-');
48 plot(x,y,'og');
49 hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X');
50 set(hx,'color','g','Fontsize',14);
51 hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y');
52 set(hy,'color','g','Fontsize',14);
53 hold off;
54
55 drawnow;
56
57
58 % Try to automatically count the number of squares in the grid
59
60 n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx);
61 n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx);
62 n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx);
63 n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx);
64
65
66
67 % If could not count the number of squares, enter manually
68
69 if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2),
70
71
72 disp('Could not count the number of squares in the grid. Enter manually.');
73 n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6
74 if isempty(n_sq_x), n_sq_x = 10; end;
75 n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6
76 if isempty(n_sq_y), n_sq_y = 10; end;
77
78 else
79
80 n_sq_x = n_sq_x1;
81 n_sq_y = n_sq_y1;
82
83 end;
84
85
86 if 1,
87 % Enter the size of each square
88
89 dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'cm) = ']);
90 dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'cm) = ']);
91 if isempty(dX), dX = dX_default; else dX_default = dX; end;
92 if isempty(dY), dY = dY_default; else dY_default = dY; end;
93
94 else
95
96 dX = 3;
97 dY = 3;
98
99 end;
100
101
102 % Compute the inside points through computation of the planar homography (collineation)
103
104 a00 = [x(1);y(1);1];
105 a10 = [x(2);y(2);1];
106 a11 = [x(3);y(3);1];
107 a01 = [x(4);y(4);1];
108
109
110 % Compute the planart collineation: (return the normalization matrice as well)
111
112 [Homo,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01);
113
114
115 % Build the grid using the planar collineation:
116
117 x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x;
118 y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y;
119 pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]';
120
121 XX = Homo*pts;
122 XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:));
123
124
125 % Complete size of the rectangle
126
127 W = n_sq_x*dX;
128 L = n_sq_y*dY;
129
130
131
132 if 1,
133 %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
134 figure(2);
135 hold on;
136 plot(XX(1,:),XX(2,:),'r+');
137 title('The red crosses should be close to the image corners');
138 hold off;
139
140 disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,');
141 disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)');
142 quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) ');
143
144 quest_distort = ~isempty(quest_distort);
145
146 if quest_distort,
147 % Estimation of focal length:
148 c_g = [size(I,2);size(I,1)]/2 + .5;
149 f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1);
150 f_g = mean(f_g);
151 script_fit_distortion;
152 end;
153 %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
154 end;
155
156
157 Np = (n_sq_x+1)*(n_sq_y+1);
158
159 disp('Corner extraction...');
160
161 grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points!
162
163 %save all_corners x y grid_pts
164
165 grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C)
166
167
168 % Global Homography from plane to pixel coordinates:
169
170 H_total = [1 0 -1 ; 0 1 -1 ; 0 0 1]*Homo*[1 0 0;0 -1 1;0 0 1]*[1/W 0 0 ; 0 1/L 0; 0 0 1];
171 % WARNING!!! the first matrix (on the left side) takes care of the transformation of the pixel cooredinates by -1 (previous line)
172 % If it is not done, then this matrix should not appear (in C)
173 H_total = H_total / H_total(3,3);
174
175
176 ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners
177 ind_orig = (n_sq_x+1)*n_sq_y + 1;
178 xorig = grid_pts(1,ind_orig);
179 yorig = grid_pts(2,ind_orig);
180 dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]');
181 dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]');
182
183
184 x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)];
185 y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)];
186
187
188 figure(3);
189 image(I); colormap(map); hold on;
190 plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+');
191 plot(x_box_kk+1,y_box_kk+1,'-b');
192 plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo');
193 plot(xorig+1,yorig+1,'*m');
194 h = text(xorig-15,yorig-15,'O');
195 set(h,'Color','m','FontSize',14);
196 h2 = text(dxpos(1)-10,dxpos(2)-10,'dX');
197 set(h2,'Color','g','FontSize',14);
198 h3 = text(dypos(1)-25,dypos(2)-3,'dY');
199 set(h3,'Color','g','FontSize',14);
200 xlabel('Xc (in camera frame)');
201 ylabel('Yc (in camera frame)');
202 title('Extracted corners');
203 zoom on;
204 drawnow;
205 hold off;
206
207
208 Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)';
209 Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)';
210 Zi = zeros(1,Np);
211
212 Xgrid = [Xi;Yi;Zi];
213
214
215 % All the point coordinates (on the image, and in 3D) - for global optimization:
216
217 x = grid_pts;
218 X = Xgrid;
219
220
221 % The left pannel info:
222
223 xl = x;
224 Xl = X;
225 nl_sq_x = n_sq_x;
226 nl_sq_y = n_sq_y;
227 Hl = H_total;
228
229
230
231
232
233
234 %%%%%%%%%%%%%%%%%%%%%%%%% RIGHT PATTERN ACQUISITION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235
236
237 x1 = a10(1)/a10(3);
238 x4 = a11(1)/a11(3);
239
240 y1 = a10(2)/a10(3);
241 y4 = a11(2)/a11(3);
242
243
244 figure(2);
245 hold on;
246 plot([x1 x4],[y1 y4],'c-');
247 plot([x1 x4],[y1 y4],'co');
248 hold off;
249
250 title(['Click on the two remaining extreme corners of the right rectangular pattern... Image ' num2str(kk)]);
251
252 disp('Click on the two remaining extreme corners of the right rectangular pattern...');
253
254 [x,y] = ginput3(2);
255
256 [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners
257
258 x = Xc(1,:)';
259 y = Xc(2,:)';
260
261 [y,indy] = sort(y);
262 x = x(indy);
263
264 x2 = x(2);
265 x3 = x(1);
266
267 y2 = y(2);
268 y3 = y(1);
269
270
271 x = [x1;x2;x3;x4];
272 y = [y1;y2;y3;y4];
273
274 figure(2); hold on;
275 plot([x;x(1)],[y;y(1)],'c-');
276 plot(x,y,'oc');
277 hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X');
278 set(hx,'color','c','Fontsize',14);
279 hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y');
280 set(hy,'color','c','Fontsize',14);
281 hold off;
282 drawnow;
283
284
285 % Try to automatically count the number of squares in the grid
286
287 n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx);
288 n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx);
289 n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx);
290 n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx);
291
292
293
294 % If could not count the number of squares, enter manually
295
296 if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2),
297
298
299 disp('Could not count the number of squares in the grid. Enter manually.');
300 n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6
301 if isempty(n_sq_x), n_sq_x = 10; end;
302 n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6
303 if isempty(n_sq_y), n_sq_y = 10; end;
304
305 else
306
307 n_sq_x = n_sq_x1;
308 n_sq_y = n_sq_y1;
309
310 end;
311
312
313 if 1,
314 % Enter the size of each square
315
316 dX = input(['Size dX of each square along the X direction ([]=' num2str(dX_default) 'cm) = ']);
317 dY = input(['Size dY of each square along the Y direction ([]=' num2str(dY_default) 'cm) = ']);
318 if isempty(dX), dX = dX_default; else dX_default = dX; end;
319 if isempty(dY), dY = dY_default; else dY_default = dY; end;
320
321 else
322
323 dX = 3;
324 dY = 3;
325
326 end;
327
328
329 % Compute the inside points through computation of the planar homography (collineation)
330
331 a00 = [x(1);y(1);1];
332 a10 = [x(2);y(2);1];
333 a11 = [x(3);y(3);1];
334 a01 = [x(4);y(4);1];
335
336
337 % Compute the planart collineation: (return the normalization matrice as well)
338
339 [Homo,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01);
340
341
342 % Build the grid using the planar collineation:
343
344 x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x;
345 y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y;
346 pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]';
347
348 XX = Homo*pts;
349 XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:));
350
351
352 % Complete size of the rectangle
353
354 W = n_sq_x*dX;
355 L = n_sq_y*dY;
356
357
358
359 if 1,
360 %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
361 figure(2);
362 hold on;
363 plot(XX(1,:),XX(2,:),'r+');
364 title('The red crosses should be close to the image corners');
365 hold off;
366
367 disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,');
368 disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)');
369 quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) ');
370
371 quest_distort = ~isempty(quest_distort);
372
373 if quest_distort,
374 % Estimation of focal length:
375 c_g = [size(I,2);size(I,1)]/2 + .5;
376 f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1);
377 f_g = mean(f_g);
378 script_fit_distortion;
379 end;
380 %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
381 end;
382
383
384 Np = (n_sq_x+1)*(n_sq_y+1);
385
386 disp('Corner extraction...');
387
388 grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points!
389
390 %save all_corners x y grid_pts
391
392 grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C)
393
394
395 % Global Homography from plane to pixel coordinates:
396
397 H_total = [1 0 -1 ; 0 1 -1 ; 0 0 1]*Homo*[1 0 0;0 -1 1;0 0 1]*[1/W 0 0 ; 0 1/L 0; 0 0 1];
398 % WARNING!!! the first matrix (on the left side) takes care of the transformation of the pixel cooredinates by -1 (previous line)
399 % If it is not done, then this matrix should not appear (in C)
400 H_total = H_total / H_total(3,3);
401
402
403 ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners
404 ind_orig = (n_sq_x+1)*n_sq_y + 1;
405 xorig = grid_pts(1,ind_orig);
406 yorig = grid_pts(2,ind_orig);
407 dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]');
408 dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]');
409
410
411 x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)];
412 y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)];
413
414
415 figure(3);
416 hold on;
417 plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+');
418 plot(x_box_kk+1,y_box_kk+1,'-b');
419 plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo');
420 plot(xorig+1,yorig+1,'*m');
421 h = text(xorig-15,yorig-15,'O');
422 set(h,'Color','m','FontSize',14);
423 h2 = text(dxpos(1)-10,dxpos(2)-10,'dX');
424 set(h2,'Color','g','FontSize',14);
425 h3 = text(dypos(1)-25,dypos(2)-3,'dY');
426 set(h3,'Color','g','FontSize',14);
427 xlabel('Xc (in camera frame)');
428 ylabel('Yc (in camera frame)');
429 title('Extracted corners');
430 zoom on;
431 drawnow;
432 hold off;
433
434
435 Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)';
436 Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)';
437 Zi = zeros(1,Np);
438
439 Xgrid = [Xi;Yi;Zi];
440
441
442 % All the point coordinates (on the image, and in 3D) - for global optimization:
443
444 x = grid_pts;
445 X = Xgrid;
446
447
448 % The right pannel info:
449
450 xr = x;
451 Xr = X;
452 nr_sq_x = n_sq_x;
453 nr_sq_y = n_sq_y;
454 Hr = H_total;
455
456
457
458%%%%%%%% REGROUP THE LEFT AND RIHT PATTERNS %%%%%%%%%%%%%
459
460
461Xr2 = [0 0 1;0 1 0;-1 0 0]*Xr + [dX*nl_sq_x;0;0]*ones(1,length(Xr));
462
463
464x = [xl xr];
465
466X = [Xl Xr2];
467
468
469
470 eval(['x_' num2str(kk) ' = x;']);
471 eval(['X_' num2str(kk) ' = X;']);
472
473 eval(['nl_sq_x_' num2str(kk) ' = nl_sq_x;']);
474 eval(['nl_sq_y_' num2str(kk) ' = nl_sq_y;']);
475
476 eval(['nr_sq_x_' num2str(kk) ' = nr_sq_x;']);
477 eval(['nr_sq_y_' num2str(kk) ' = nr_sq_y;']);
478
479 % Save the global planar homography:
480
481 eval(['Hl_' num2str(kk) ' = Hl;']);
482 eval(['Hr_' num2str(kk) ' = Hr;']); \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m
new file mode 100755
index 0000000..a0f03de
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion.m
@@ -0,0 +1,38 @@
1function [x_comp] = comp_distortion(x_dist,k2);
2
3% [x_comp] = comp_distortion(x_dist,k2);
4%
5% compensates the radial distortion of the camera
6% on the image plane.
7%
8% x_dist : the image points got without considering the
9% radial distortion.
10% x : The image plane points after correction for the distortion
11%
12% x and x_dist are 2xN arrays
13%
14% NOTE : This compensation has to be done after the substraction
15% of the center of projection, and division by the focal
16% length.
17%
18% (do it up to a second order approximation)
19
20[two,N] = size(x_dist);
21
22if (two ~= 2 ),
23 error('ERROR : The dimension of the points should be 2xN');
24end;
25
26if length(k2) > 2,
27 [x_comp] = comp_distortion_oulu(x_dist,k2);
28else
29
30radius_2= x_dist(1,:).^2 + x_dist(2,:).^2;
31radial_distortion = 1 + ones(2,1)*(k2 * radius_2);
32radius_2_comp = (x_dist(1,:).^2 + x_dist(2,:).^2) ./ radial_distortion(1,:);
33radial_distortion = 1 + ones(2,1)*(k2 * radius_2_comp);
34x_comp = x_dist ./ radial_distortion;
35
36end;
37
38%% Function completely checked : It works fine !!! \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m
new file mode 100755
index 0000000..532ee9a
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion2.m
@@ -0,0 +1,71 @@
1function [x_comp] = comp_distortion(x_dist,k2);
2
3% [x_comp] = comp_distortion(x_dist,k2);
4%
5% compensates the radial distortion of the camera
6% on the image plane.
7%
8% x_dist : the image points got without considering the
9% radial distortion.
10% k2: Radial distortion factor
11%
12% x : The image plane points after correction for the distortion
13%
14% x and x_dist are 2xN arrays
15%
16% NOTE : This compensation has to be done after the substraction
17% of the center of projection, and division by the focal
18% length.
19%
20% Solve for cubic roots using method from Numerical Recipes in C 2nd Ed.
21% pages 184-185.
22
23
24% California Institute of Technology
25% (c) Jean-Yves Bouguet - April 27th, 1998
26
27% fully checked! JYB, april 27th, 1998 - 2am
28
29if k2 ~= 0,
30
31[two,N] = size(x_dist);
32
33if (two ~= 2 ),
34 error('ERROR : The dimension of the points should be 2xN');
35end;
36
37
38ph = atan2(x_dist(2,:),x_dist(1,:));
39
40Q = -1/(3*k2);
41R = -x_dist(1,:)./(2*k2*cos(ph));
42
43R2 = R.^2;
44Q3 = Q^3;
45
46
47if k2 < 0,
48
49 % this works in all practical situations (it starts failing for very large
50 % values of k2)
51
52 th = acos(R./sqrt(Q3));
53 r = -2*sqrt(Q)*cos((th-2*pi)/3);
54
55else
56
57 % note: this always works, even for ridiculous values of k2
58
59 A = (sqrt(R2-Q3)-R).^(1/3);
60 B = Q*(1./A);
61 r = (A+B);
62
63end;
64
65x_comp = [r.*cos(ph); r.*sin(ph)];
66
67else
68
69 x_comp = x_dist;
70
71end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m
new file mode 100755
index 0000000..67d02d5
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_distortion_oulu.m
@@ -0,0 +1,47 @@
1function [x] = comp_distortion_oulu(xd,k);
2
3%comp_distortion_oulu.m
4%
5%[x] = comp_distortion_oulu(xd,k)
6%
7%Compensates for radial and tangential distortion. Model From Oulu university.
8%For more informatino about the distortion model, check the forward projection mapping function:
9%project_points.m
10%
11%INPUT: xd: distorted (normalized) point coordinates in the image plane (2xN matrix)
12% k: Distortion coefficients (radial and tangential) (4x1 vector)
13%
14%OUTPUT: x: undistorted (normalized) point coordinates in the image plane (2xN matrix)
15%
16%Method: Iterative method for compensation.
17%
18%NOTE: This compensation has to be done after the subtraction
19% of the principal point, and division by the focal length.
20
21
22if length(k) < 4,
23
24 [x] = comp_distortion(xd,k);
25
26else
27
28
29 k1 = k(1);
30 k2 = k(2);
31 p1 = k(3);
32 p2 = k(4);
33
34 x = xd; % initial guess
35
36 for kk=1:5;
37
38 r_2 = sum(x.^2);
39 k_radial = 1 + k1 * r_2 + k2 * r_2.^2;
40 delta_x = [2*p1*x(1,:).*x(2,:) + p2*(r_2 + 2*x(1,:).^2) ;
41 p1 * (r_2 + 2*x(2,:).^2)+2*p2*x(1,:).*x(2,:)];
42 x = (xd - delta_x)./(ones(2,1)*k_radial);
43
44 end;
45
46end;
47
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m
new file mode 100755
index 0000000..c7bf662
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/comp_error_calib.m
@@ -0,0 +1,46 @@
1%%%%%%%%%%%%%%%%%%%% RECOMPUTES THE REPROJECTION ERROR %%%%%%%%%%%%%%%%%%%%%%%%
2
3check_active_images;
4
5% Reproject the patterns on the images, and compute the pixel errors:
6
7ex = []; % Global error vector
8x = []; % Detected corners on the image plane
9y = []; % Reprojected points
10
11if ~exist('alpha_c'),
12 alpha_c = 0;
13end;
14
15for kk = 1:n_ima,
16
17 eval(['omckk = omc_' num2str(kk) ';']);
18 eval(['Tckk = Tc_' num2str(kk) ';']);
19
20 if active_images(kk) & (~isnan(omckk(1,1))),
21
22 %Rkk = rodrigues(omckk);
23
24 eval(['y_' num2str(kk) ' = project_points2(X_' num2str(kk) ',omckk,Tckk,fc,cc,kc,alpha_c);']);
25
26 eval(['ex_' num2str(kk) ' = x_' num2str(kk) ' -y_' num2str(kk) ';']);
27
28 eval(['x_kk = x_' num2str(kk) ';']);
29
30 eval(['ex = [ex ex_' num2str(kk) '];']);
31 eval(['x = [x x_' num2str(kk) '];']);
32 eval(['y = [y y_' num2str(kk) '];']);
33
34 else
35
36 % eval(['y_' num2str(kk) ' = NaN*ones(2,1);']);
37
38
39 % If inactivated image, the error does not make sense:
40 eval(['ex_' num2str(kk) ' = NaN*ones(2,1);']);
41
42 end;
43
44end;
45
46err_std = std(ex')';
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m
new file mode 100755
index 0000000..809c309
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_collineation.m
@@ -0,0 +1,66 @@
1function [H,Hnorm,inv_Hnorm] = compute_collineation (a00, a10, a11, a01);
2
3% new formalism using homographies
4
5a00 = a00 / a00(3);
6a10 = a10 / a10(3);
7a11 = a11 / a11(3);
8a01 = a01 / a01(3);
9
10
11% Prenormalization of point coordinates (very important):
12% (Affine normalization)
13
14ax = [a00(1);a10(1);a11(1);a01(1)];
15ay = [a00(2);a10(2);a11(2);a01(2)];
16
17mxx = mean(ax);
18myy = mean(ay);
19ax = ax - mxx;
20ay = ay - myy;
21
22scxx = mean(abs(ax));
23scyy = mean(abs(ay));
24
25
26Hnorm = [1/scxx 0 -mxx/scxx;0 1/scyy -myy/scyy;0 0 1];
27inv_Hnorm = [scxx 0 mxx ; 0 scyy myy; 0 0 1];
28
29
30a00n = Hnorm*a00;
31a10n = Hnorm*a10;
32a11n = Hnorm*a11;
33a01n = Hnorm*a01;
34
35
36% Computation of the vanishing points:
37
38V1n = cross(cross(a00n,a10n),cross(a01n,a11n));
39V2n = cross(cross(a00n,a01n),cross(a10n,a11n));
40
41V1 = inv_Hnorm*V1n;
42V2 = inv_Hnorm*V2n;
43
44
45% Normalizaion of the vanishing points:
46
47V1n = V1n/norm(V1n);
48V2n = V2n/norm(V2n);
49
50
51% Closed-form solution of the coefficients:
52
53alpha_x = (a10n(2)*a00n(1) - a10n(1)*a00n(2))/(V1n(2)*a10n(1)-V1n(1)*a10n(2));
54
55alpha_y = (a01n(2)*a00n(1) - a01n(1)*a00n(2))/(V2n(2)*a01n(1)-V2n(1)*a01n(2));
56
57
58% Remaining Homography
59
60Hrem = [alpha_x*V1n alpha_y*V2n a00n];
61
62
63% Final homography:
64
65H = inv_Hnorm*Hrem;
66
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m
new file mode 100755
index 0000000..5217351
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic.m
@@ -0,0 +1,123 @@
1function [omckk,Tckk,Rckk,H,x,ex,JJ] = compute_extrinsic(x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter,thresh_cond),
2
3%compute_extrinsic
4%
5%[omckk,Tckk,Rckk,H,x,ex] = compute_extrinsic(x_kk,X_kk,fc,cc,kc,alpha_c)
6%
7%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection
8%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc.
9%Works with planar and non-planar structures.
10%
11%INPUT: x_kk: Feature locations on the images
12% X_kk: Corresponding grid coordinates
13% fc: Camera focal length
14% cc: Principal point coordinates
15% kc: Distortion coefficients
16% alpha_c: Skew coefficient
17%
18%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space
19% Tckk: 3D translation vector attached to the grid positions in space
20% Rckk: 3D rotation matrices corresponding to the omc vectors
21% H: Homography between points on the grid and points on the image plane (in pixel)
22% This makes sense only if the planar that is used in planar.
23% x: Reprojections of the points on the image plane
24% ex: Reprojection error: ex = x_kk - x;
25%
26%Method: Computes the normalized point coordinates, then computes the 3D pose
27%
28%Important functions called within that program:
29%
30%normalize: Computes the normalize image point coordinates.
31%
32%pose3D: Computes the 3D pose of the structure given the normalized image projection.
33%
34%project_points.m: Computes the 2D image projections of a set of 3D points
35
36
37
38if nargin < 8,
39 thresh_cond = inf;
40end;
41
42
43if nargin < 7,
44 MaxIter = 20;
45end;
46
47
48if nargin < 6,
49 alpha_c = 0;
50 if nargin < 5,
51 kc = zeros(4,1);
52 if nargin < 4,
53 cc = zeros(2,1);
54 if nargin < 3,
55 fc = ones(2,1);
56 if nargin < 2,
57 error('Need 2D projections and 3D points (in compute_extrinsic.m)');
58 return;
59 end;
60 end;
61 end;
62 end;
63end;
64
65% Initialization:
66
67[omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c);
68
69% Refinement:
70
71[omckk,Tckk,Rckk,JJ] = compute_extrinsic_refine(omckk,Tckk,x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter,thresh_cond);
72
73
74% computation of the homography (not useful in the end)
75
76H = [Rckk(:,1:2) Tckk];
77
78% Computes the reprojection error in pixels:
79
80x = project_points2(X_kk,omckk,Tckk,fc,cc,kc,alpha_c);
81
82ex = x_kk - x;
83
84
85% Converts the homography in pixel units:
86
87KK = [fc(1) alpha_c*fc(1) cc(1);0 fc(2) cc(2); 0 0 1];
88
89H = KK*H;
90
91
92
93
94return;
95
96
97% Test of compte extrinsic:
98
99Np = 4;
100sx = 10;
101sy = 10;
102sz = 5;
103
104om = randn(3,1);
105T = [0;0;100];
106
107noise = 2/1000;
108
109XX = [sx*randn(1,Np);sy*randn(1,Np);sz*randn(1,Np)];
110xx = project_points(XX,om,T);
111
112xxn = xx + noise * randn(2,Np);
113
114[omckk,Tckk] = compute_extrinsic(xxn,XX);
115
116[om omckk om-omckk]
117[T Tckk T-Tckk]
118
119figure(3);
120plot(xx(1,:),xx(2,:),'r+');
121hold on;
122plot(xxn(1,:),xxn(2,:),'g+');
123hold off;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m
new file mode 100755
index 0000000..2e6d821
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_init.m
@@ -0,0 +1,151 @@
1function [omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c),
2
3%compute_extrinsic
4%
5%[omckk,Tckk,Rckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c)
6%
7%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection
8%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc.
9%Works with planar and non-planar structures.
10%
11%INPUT: x_kk: Feature locations on the images
12% X_kk: Corresponding grid coordinates
13% fc: Camera focal length
14% cc: Principal point coordinates
15% kc: Distortion coefficients
16% alpha_c: Skew coefficient
17%
18%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space
19% Tckk: 3D translation vector attached to the grid positions in space
20% Rckk: 3D rotation matrices corresponding to the omc vectors
21%
22%Method: Computes the normalized point coordinates, then computes the 3D pose
23%
24%Important functions called within that program:
25%
26%normalize: Computes the normalize image point coordinates.
27%
28%pose3D: Computes the 3D pose of the structure given the normalized image projection.
29%
30%project_points.m: Computes the 2D image projections of a set of 3D points
31
32
33
34if nargin < 6,
35 alpha_c = 0;
36 if nargin < 5,
37 kc = zeros(4,1);
38 if nargin < 4,
39 cc = zeros(2,1);
40 if nargin < 3,
41 fc = ones(2,1);
42 if nargin < 2,
43 error('Need 2D projections and 3D points (in compute_extrinsic.m)');
44 return;
45 end;
46 end;
47 end;
48 end;
49end;
50
51
52% Compute the normalized coordinates:
53
54xn = normalize(x_kk,fc,cc,kc,alpha_c);
55
56
57
58Np = size(xn,2);
59
60%% Check for planarity of the structure:
61
62X_mean = mean(X_kk')';
63
64Y = X_kk - (X_mean*ones(1,Np));
65
66YY = Y*Y';
67
68[U,S,V] = svd(YY);
69
70r = S(3,3)/S(2,2);
71
72if (r < 1e-3)|(Np < 6), %1e-3, %1e-4, %norm(X_kk(3,:)) < eps, % Test of planarity
73
74 %fprintf(1,'Planar structure detected: r=%f\n',r);
75
76 % Transform the plane to bring it in the Z=0 plane:
77
78 R_transform = V';
79
80 if det(R_transform) < 0, R_transform = -R_transform; end;
81
82 T_transform = -(R_transform)*X_mean;
83
84 X_new = R_transform*X_kk + T_transform*ones(1,Np);
85
86
87 % Compute the planar homography:
88
89 H = compute_homography (xn,X_new(1:2,:));
90
91 % De-embed the motion parameters from the homography:
92
93 sc = mean([norm(H(:,1));norm(H(:,2))]);
94
95 H = H/sc;
96
97 omckk = rodrigues([H(:,1:2) cross(H(:,1),H(:,2))]);
98 Rckk = rodrigues(omckk);
99 Tckk = H(:,3);
100
101 %If Xc = Rckk * X_new + Tckk, then Xc = Rckk * R_transform * X_kk + Tckk + T_transform
102
103 Tckk = Tckk + Rckk* T_transform;
104 Rckk = Rckk * R_transform;
105
106 omckk = rodrigues(Rckk);
107 Rckk = rodrigues(omckk);
108
109
110else
111
112 %fprintf(1,'Non planar structure detected: r=%f\n',r);
113
114 % Computes an initial guess for extrinsic parameters (works for general 3d structure, not planar!!!):
115 % The DLT method is applied here!!
116
117 J = zeros(2*Np,12);
118
119 xX = (ones(3,1)*xn(1,:)).*X_kk;
120 yX = (ones(3,1)*xn(2,:)).*X_kk;
121
122 J(1:2:end,[1 4 7]) = -X_kk';
123 J(2:2:end,[2 5 8]) = X_kk';
124 J(1:2:end,[3 6 9]) = xX';
125 J(2:2:end,[3 6 9]) = -yX';
126 J(1:2:end,12) = xn(1,:)';
127 J(2:2:end,12) = -xn(2,:)';
128 J(1:2:end,10) = -ones(Np,1);
129 J(2:2:end,11) = ones(Np,1);
130
131 JJ = J'*J;
132 [U,S,V] = svd(JJ);
133
134 RR = reshape(V(1:9,12),3,3);
135
136 if det(RR) < 0,
137 V(:,12) = -V(:,12);
138 RR = -RR;
139 end;
140
141 [Ur,Sr,Vr] = svd(RR);
142
143 Rckk = Ur*Vr';
144
145 sc = norm(V(1:9,12)) / norm(Rckk(:));
146 Tckk = V(10:12,12)/sc;
147
148 omckk = rodrigues(Rckk);
149 Rckk = rodrigues(omckk);
150
151end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m
new file mode 100755
index 0000000..a4d066c
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_extrinsic_refine.m
@@ -0,0 +1,113 @@
1function [omckk,Tckk,Rckk,JJ] = compute_extrinsic_refine(omc_init,Tc_init,x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter,thresh_cond),
2
3%compute_extrinsic
4%
5%[omckk,Tckk,Rckk] = compute_extrinsic_refine(x_kk,X_kk,fc,cc,kc,alpha_c,MaxIter)
6%
7%Computes the extrinsic parameters attached to a 3D structure X_kk given its projection
8%on the image plane x_kk and the intrinsic camera parameters fc, cc and kc.
9%Works with planar and non-planar structures.
10%
11%INPUT: x_kk: Feature locations on the images
12% X_kk: Corresponding grid coordinates
13% fc: Camera focal length
14% cc: Principal point coordinates
15% kc: Distortion coefficients
16% alpha_c: Skew coefficient
17% MaxIter: Maximum number of iterations
18%
19%OUTPUT: omckk: 3D rotation vector attached to the grid positions in space
20% Tckk: 3D translation vector attached to the grid positions in space
21% Rckk: 3D rotation matrices corresponding to the omc vectors
22
23%
24%Method: Computes the normalized point coordinates, then computes the 3D pose
25%
26%Important functions called within that program:
27%
28%normalize: Computes the normalize image point coordinates.
29%
30%pose3D: Computes the 3D pose of the structure given the normalized image projection.
31%
32%project_points.m: Computes the 2D image projections of a set of 3D points
33
34
35if nargin < 10,
36 thresh_cond = inf;
37end;
38
39
40if nargin < 9,
41 MaxIter = 20;
42end;
43
44if nargin < 8,
45 alpha_c = 0;
46 if nargin < 7,
47 kc = zeros(4,1);
48 if nargin < 6,
49 cc = zeros(2,1);
50 if nargin < 5,
51 fc = ones(2,1);
52 if nargin < 4,
53 error('Need 2D projections and 3D points (in compute_extrinsic_refine.m)');
54 return;
55 end;
56 end;
57 end;
58 end;
59end;
60
61
62% Initialization:
63
64omckk = omc_init;
65Tckk = Tc_init;
66
67
68% Final optimization (minimize the reprojection error in pixel):
69% through Gradient Descent:
70
71param = [omckk;Tckk];
72
73change = 1;
74
75iter = 0;
76
77%keyboard;
78
79%fprintf(1,'Gradient descent iterations: ');
80
81while (change > 1e-10)&(iter < MaxIter),
82
83 %fprintf(1,'%d...',iter+1);
84
85 [x,dxdom,dxdT] = project_points2(X_kk,omckk,Tckk,fc,cc,kc,alpha_c);
86
87 ex = x_kk - x;
88
89 %keyboard;
90
91 JJ = [dxdom dxdT];
92
93 if cond(JJ) > thresh_cond,
94 change = 0;
95 else
96
97 JJ2 = JJ'*JJ;
98
99 param_innov = inv(JJ2)*(JJ')*ex(:);
100 param_up = param + param_innov;
101 change = norm(param_innov)/norm(param_up);
102 param = param_up;
103 iter = iter + 1;
104
105 omckk = param(1:3);
106 Tckk = param(4:6);
107 end;
108
109end;
110
111%fprintf(1,'\n');
112
113Rckk = rodrigues(omckk);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m
new file mode 100755
index 0000000..fcc9003
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/compute_homography.m
@@ -0,0 +1,163 @@
1function [H,Hnorm,inv_Hnorm] = compute_homography (m,M);
2
3%compute_homography
4%
5%[H,Hnorm,inv_Hnorm] = compute_homography (m,M)
6%
7%Computes the planar homography between the point coordinates on the plane (M) and the image
8%point coordinates (m).
9%
10%INPUT: m: homogeneous coordinates in the image plane (3xN matrix)
11% M: homogeneous coordinates in the plane in 3D (3xN matrix)
12%
13%OUTPUT: H: Homography matrix (3x3 homogeneous matrix)
14% Hnorm: Normlization matrix used on the points before homography computation
15% (useful for numerical stability is points in pixel coordinates)
16% inv_Hnorm: The inverse of Hnorm
17%
18%Definition: m ~ H*M where "~" means equal up to a non zero scalar factor.
19%
20%Method: First computes an initial guess for the homography through quasi-linear method.
21% Then, if the total number of points is larger than 4, optimize the solution by minimizing
22% the reprojection error (in the least squares sense).
23%
24%
25%Important functions called within that program:
26%
27%comp_distortion_oulu: Undistorts pixel coordinates.
28%
29%compute_homography.m: Computes the planar homography between points on the grid in 3D, and the image plane.
30%
31%project_points.m: Computes the 2D image projections of a set of 3D points, and also returns te Jacobian
32% matrix (derivative with respect to the intrinsic and extrinsic parameters).
33% This function is called within the minimization loop.
34
35
36
37
38Np = size(m,2);
39
40if size(m,1)<3,
41 m = [m;ones(1,Np)];
42end;
43
44if size(M,1)<3,
45 M = [M;ones(1,Np)];
46end;
47
48
49m = m ./ (ones(3,1)*m(3,:));
50M = M ./ (ones(3,1)*M(3,:));
51
52% Prenormalization of point coordinates (very important):
53% (Affine normalization)
54
55ax = m(1,:);
56ay = m(2,:);
57
58mxx = mean(ax);
59myy = mean(ay);
60ax = ax - mxx;
61ay = ay - myy;
62
63scxx = mean(abs(ax));
64scyy = mean(abs(ay));
65
66
67Hnorm = [1/scxx 0 -mxx/scxx;0 1/scyy -myy/scyy;0 0 1];
68inv_Hnorm = [scxx 0 mxx ; 0 scyy myy; 0 0 1];
69
70mn = Hnorm*m;
71
72% Compute the homography between m and mn:
73
74% Build the matrix:
75
76L = zeros(2*Np,9);
77
78L(1:2:2*Np,1:3) = M';
79L(2:2:2*Np,4:6) = M';
80L(1:2:2*Np,7:9) = -((ones(3,1)*mn(1,:)).* M)';
81L(2:2:2*Np,7:9) = -((ones(3,1)*mn(2,:)).* M)';
82
83if Np > 4,
84 L = L'*L;
85end;
86
87[U,S,V] = svd(L);
88
89hh = V(:,9);
90hh = hh/hh(9);
91
92Hrem = reshape(hh,3,3)';
93%Hrem = Hrem / Hrem(3,3);
94
95% Final homography:
96
97H = inv_Hnorm*Hrem;
98
99
100%%% Homography refinement if there are more than 4 points:
101
102if Np > 4,
103
104 % Final refinement:
105
106 hhv = reshape(H',9,1);
107 hhv = hhv(1:8);
108
109 for iter=1:10,
110
111 mrep = H * M;
112
113 J = zeros(2*Np,8);
114
115 MMM = (M ./ (ones(3,1)*mrep(3,:)));
116
117 J(1:2:2*Np,1:3) = -MMM';
118 J(2:2:2*Np,4:6) = -MMM';
119
120 mrep = mrep ./ (ones(3,1)*mrep(3,:));
121
122 m_err = m(1:2,:) - mrep(1:2,:);
123 m_err = m_err(:);
124
125 MMM2 = (ones(3,1)*mrep(1,:)) .* MMM;
126 MMM3 = (ones(3,1)*mrep(2,:)) .* MMM;
127
128 J(1:2:2*Np,7:8) = MMM2(1:2,:)';
129 J(2:2:2*Np,7:8) = MMM3(1:2,:)';
130
131 MMM = (M ./ (ones(3,1)*mrep(3,:)))';
132
133 hh_innov = inv(J'*J)*J'*m_err;
134
135 hhv_up = hhv - hh_innov;
136
137 H_up = reshape([hhv_up;1],3,3)';
138
139 %norm(m_err)
140 %norm(hh_innov)
141
142 hhv = hhv_up;
143 H = H_up;
144
145 end;
146
147end;
148
149
150
151
152
153return;
154
155%test of Jacobian
156
157mrep = H*M;
158mrep = mrep ./ (ones(3,1)*mrep(3,:));
159
160m_err = mrep(1:2,:) - m(1:2,:);
161figure(8);
162plot(m_err(1,:),m_err(2,:),'r+');
163std(m_err')
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m
new file mode 100755
index 0000000..9bfa51f
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/cornerfinder.m
@@ -0,0 +1,215 @@
1function [xc,good,bad,type] = cornerfinder(xt,I,wintx,winty,wx2,wy2);
2
3%[xc] = cornerfinder(xt,I);
4%
5%Finds the sub-pixel corners on the image I with initial guess xt
6%xt and xc are 2xN matrices. The first component is the x coordinate
7%(horizontal) and the second component is the y coordinate (vertical)
8%
9%Based on Harris corner finder method
10%
11%Finds corners to a precision below .1 pixel!
12%Oct. 14th, 1997 - UPDATED to work with vertical and horizontal edges as well!!!
13%Sept 1998 - UPDATED to handle diverged points: we keep the original points
14%good is a binary vector indicating wether a feature point has been properly
15%found.
16%
17%Add a zero zone of size wx2,wy2
18%July 15th, 1999 - Bug on the mask building... fixed + change to Gaussian mask with higher
19%resolution and larger number of iterations.
20
21
22% California Institute of Technology
23% (c) Jean-Yves Bouguet -- Oct. 14th, 1997
24
25
26
27line_feat = 1; % set to 1 to allow for extraction of line features.
28
29xt = xt';
30xt = fliplr(xt);
31
32
33if nargin < 4,
34 winty = 5;
35 if nargin < 3,
36 wintx = 5;
37 end;
38end;
39
40
41if nargin < 6,
42 wx2 = -1;
43 wy2 = -1;
44end;
45
46
47%mask = ones(2*wintx+1,2*winty+1);
48mask = exp(-((-wintx:wintx)'/(wintx)).^2) * exp(-((-winty:winty)/(winty)).^2);
49
50
51if (wx2>0) & (wy2>0),
52 if ((wintx - wx2)>=2)&((winty - wy2)>=2),
53 mask(wintx+1-wx2:wintx+1+wx2,winty+1-wy2:winty+1+wy2)= zeros(2*wx2+1,2*wy2+1);
54 end;
55end;
56
57offx = [-wintx:wintx]'*ones(1,2*winty+1);
58offy = ones(2*wintx+1,1)*[-winty:winty];
59
60resolution = 0.005;
61
62MaxIter = 10;
63
64[nx,ny] = size(I);
65N = size(xt,1);
66
67xc = xt; % first guess... they don't move !!!
68
69type = zeros(1,N);
70
71
72for i=1:N,
73
74 v_extra = resolution + 1; % just larger than resolution
75
76 compt = 0; % no iteration yet
77
78 while (norm(v_extra) > resolution) & (compt<MaxIter),
79
80 cIx = xc(i,1); %
81 cIy = xc(i,2); % Coords. of the point
82 crIx = round(cIx); % on the initial image
83 crIy = round(cIy); %
84 itIx = cIx - crIx; % Coefficients
85 itIy = cIy - crIy; % to compute
86 if itIx > 0, % the sub pixel
87 vIx = [itIx 1-itIx 0]'; % accuracy.
88 else
89 vIx = [0 1+itIx -itIx]';
90 end;
91 if itIy > 0,
92 vIy = [itIy 1-itIy 0];
93 else
94 vIy = [0 1+itIy -itIy];
95 end;
96
97
98 % What if the sub image is not in?
99
100 if (crIx-wintx-2 < 1), xmin=1; xmax = 2*wintx+5;
101 elseif (crIx+wintx+2 > nx), xmax = nx; xmin = nx-2*wintx-4;
102 else
103 xmin = crIx-wintx-2; xmax = crIx+wintx+2;
104 end;
105
106 if (crIy-winty-2 < 1), ymin=1; ymax = 2*winty+5;
107 elseif (crIy+winty+2 > ny), ymax = ny; ymin = ny-2*winty-4;
108 else
109 ymin = crIy-winty-2; ymax = crIy+winty+2;
110 end;
111
112
113 SI = I(xmin:xmax,ymin:ymax); % The necessary neighborhood
114 SI = conv2(conv2(SI,vIx,'same'),vIy,'same');
115 SI = SI(2:2*wintx+4,2:2*winty+4); % The subpixel interpolated neighborhood
116 [gy,gx] = gradient(SI); % The gradient image
117 gx = gx(2:2*wintx+2,2:2*winty+2); % extraction of the useful parts only
118 gy = gy(2:2*wintx+2,2:2*winty+2); % of the gradients
119
120 px = cIx + offx;
121 py = cIy + offy;
122
123 gxx = gx .* gx .* mask;
124 gyy = gy .* gy .* mask;
125 gxy = gx .* gy .* mask;
126
127
128 bb = [sum(sum(gxx .* px + gxy .* py)); sum(sum(gxy .* px + gyy .* py))];
129
130 a = sum(sum(gxx));
131 b = sum(sum(gxy));
132 c = sum(sum(gyy));
133
134 dt = a*c - b^2;
135
136 xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt;
137
138
139 %keyboard;
140
141 if line_feat,
142
143 G = [a b;b c];
144 [U,S,V] = svd(G);
145
146 %keyboard;
147
148 % If non-invertible, then project the point onto the edge orthogonal:
149
150 if (S(1,1)/S(2,2) > 50),
151 % projection operation:
152 xc2 = xc2 + sum((xc(i,:)-xc2).*(V(:,2)'))*V(:,2)';
153 type(i) = 1;
154 end;
155
156 end;
157
158
159 %keyboard;
160
161% G = [a b;b c];
162% [U,S,V] = svd(G);
163
164
165% if S(1,1)/S(2,2) > 150,
166% bb2 = U'*bb;
167% xc2 = (V*[bb2(1)/S(1,1) ;0])';
168% else
169% xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt;
170% end;
171
172
173 %if (abs(a)> 50*abs(c)),
174% xc2 = [(c*bb(1)-b*bb(2))/dt xc(i,2)];
175% elseif (abs(c)> 50*abs(a))
176% xc2 = [xc(i,1) (a*bb(2)-b*bb(1))/dt];
177% else
178% xc2 = [c*bb(1)-b*bb(2) a*bb(2)-b*bb(1)]/dt;
179% end;
180
181 %keyboard;
182
183 v_extra = xc(i,:) - xc2;
184
185 xc(i,:) = xc2;
186
187% keyboard;
188
189 compt = compt + 1;
190
191 end
192end;
193
194
195% check for points that diverge:
196
197delta_x = xc(:,1) - xt(:,1);
198delta_y = xc(:,2) - xt(:,2);
199
200%keyboard;
201
202
203bad = (abs(delta_x) > wintx) | (abs(delta_y) > winty);
204good = ~bad;
205in_bad = find(bad);
206
207% For the diverged points, keep the original guesses:
208
209xc(in_bad,:) = xt(in_bad,:);
210
211xc = fliplr(xc);
212xc = xc';
213
214bad = bad';
215good = good';
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m
new file mode 100755
index 0000000..0e226c0
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/count_squares.m
@@ -0,0 +1,74 @@
1function ns = count_squares(I,x1,y1,x2,y2,win);
2
3%keyboard;
4
5[ny,nx] = size(I);
6
7lambda = [y1 - y2;x2 - x1;x1*y2 - x2*y1];
8
9lambda = 1/sqrt(lambda(1)^2 + lambda(2)^2) * lambda;
10
11l1 = lambda + [0;0;win];
12l2 = lambda - [0;0;win];
13
14
15dx = x2-x1;
16dy = y2 - y1;
17
18
19if abs(dx) > abs(dy),
20
21 if x2 > x1,
22 xs = x1:x2;
23 else
24 xs = x1:-1:x2;
25 end;
26
27 ys = -(lambda(3) + lambda(1)*xs)/lambda(2);
28
29else
30
31 if y2 > y1,
32 ys = y1:y2;
33 else
34 ys = y1:-1:y2;
35 end;
36 xs = -(lambda(3) + lambda(2)*ys)/lambda(1);
37
38end;
39
40
41
42 Np = length(xs);
43
44 xs_mat = ones(2*win + 1,1)*xs;
45 ys_mat = ones(2*win + 1,1)*ys;
46
47 win_mat = (-win:win)'*ones(1,Np);
48
49
50 xs_mat2 = round(xs_mat - win_mat * lambda(1));
51 ys_mat2 = round(ys_mat - win_mat * lambda(2));
52
53 ind_mat = (xs_mat2 - 1) * ny + ys_mat2;
54
55 ima_patch = zeros(2*win + 1,Np);
56
57 ima_patch(:) = I(ind_mat(:));
58
59 %ima2 = ima_patch(:,win+1:end-win);
60
61 filtk = [ones(win,Np);zeros(1,Np);-ones(win,Np)];
62
63 out_f = sum(filtk.*ima_patch);
64
65 out_f_f = conv2(out_f,[1/4 1/2 1/4],'same');
66
67 out_f_f = out_f_f(win+1:end-win);
68
69 ns = length(find(((out_f_f(2:end)>=0)&(out_f_f(1:end-1)<0)) | ((out_f_f(2:end)<=0)&(out_f_f(1:end-1)>0))))+1;
70
71
72
73
74return;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m
new file mode 100755
index 0000000..422769b
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/data_calib.m
@@ -0,0 +1,92 @@
1%%% This script alets the user enter the name of the images (base name, numbering scheme,...
2
3
4% Checks that there are some images in the directory:
5
6l_ras = dir('*ras');
7s_ras = size(l_ras,1);
8l_bmp = dir('*bmp');
9s_bmp = size(l_bmp,1);
10l_tif = dir('*tif');
11s_tif = size(l_tif,1);
12l_pgm = dir('*pgm');
13s_pgm = size(l_pgm,1);
14l_jpg = dir('*jpg');
15s_jpg = size(l_jpg,1);
16
17s_tot = s_ras + s_bmp + s_tif + s_pgm + s_jpg;
18
19if s_tot < 1,
20 fprintf(1,'No image in this directory in either ras, bmp, tif, pgm or jpg format. Change directory and try again.\n');
21 break;
22end;
23
24
25% IF yes, display the directory content:
26
27dir;
28
29Nima_valid = 0;
30
31while (Nima_valid==0),
32
33 fprintf(1,'\n');
34 calib_name = input('Basename camera calibration images (without number nor suffix): ','s');
35
36 format_image = '0';
37
38 while format_image == '0',
39
40 format_image = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'', ''m''=''ppm'') ','s');
41
42 if isempty(format_image),
43 format_image = 'ras';
44 end;
45
46 if lower(format_image(1)) == 'm',
47 format_image = 'ppm';
48 else
49 if lower(format_image(1)) == 'b',
50 format_image = 'bmp';
51 else
52 if lower(format_image(1)) == 't',
53 format_image = 'tif';
54 else
55 if lower(format_image(1)) == 'p',
56 format_image = 'pgm';
57 else
58 if lower(format_image(1)) == 'j',
59 format_image = 'jpg';
60 else
61 if lower(format_image(1)) == 'r',
62 format_image = 'ras';
63 else
64 disp('Invalid image format');
65 format_image = '0'; % Ask for format once again
66 end;
67 end;
68 end;
69 end;
70 end;
71 end;
72 end;
73
74
75 check_directory;
76
77end;
78
79
80
81%string_save = 'save calib_data n_ima type_numbering N_slots image_numbers format_image calib_name first_num';
82
83%eval(string_save);
84
85
86
87if (Nima_valid~=0),
88 % Reading images:
89
90 ima_read_calib; % may be launched from the toolbox itself
91end;
92
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m
new file mode 100755
index 0000000..85feac5
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/error_analysis.m
@@ -0,0 +1,182 @@
1%%% ERROR_ANALYSIS
2%%% This simulation helps coputing the acturacies of calibration
3%%% Run it after the main calibration
4
5
6
7N_runs = 200;
8
9%N_ima_active = 4;
10
11saving = 1;
12
13if 1, %~exist('fc_list'), % initialization
14
15 % Initialization:
16
17 load Calib_Results;
18 check_active_images;
19
20 fc_list = [];
21 cc_list = [];
22 kc_list = [];
23 active_images_list = [];
24
25
26 for kk=1:n_ima,
27
28 eval(['omc_list_' num2str(kk) ' = [];']);
29 eval(['Tc_list_' num2str(kk) ' = [];']);
30
31 end;
32
33 %sx = median(abs(ex(1,:)))*1.4836;
34 %sy = median(abs(ex(2,:)))*1.4836;
35
36 sx = std(ex(1,:));
37 sy = std(ex(2,:));
38
39 % Saving the feature locations:
40
41 for kk = 1:n_ima,
42
43 eval(['x_save_' num2str(kk) ' = x_' num2str(kk) ';']);
44 eval(['y_save_' num2str(kk) ' = y_' num2str(kk) ';']);
45
46 end;
47
48 active_images_save = active_images;
49 ind_active_save = ind_active;
50
51 fc_save = fc;
52 cc_save = cc;
53 kc_save = kc;
54 KK_save = KK;
55
56
57end;
58
59
60
61
62%%% The main loop:
63
64
65for ntrial = 1:N_runs,
66
67 fprintf(1,'\nRun number: %d\n',ntrial);
68 fprintf(1, '----------\n');
69
70 for kk = 1:n_ima,
71
72 eval(['y_kk = y_save_' num2str(kk) ';'])
73
74 if active_images(kk) & ~isnan(y_kk(1,1)),
75
76 Nkk = size(y_kk,2);
77
78 x_kk_new = y_kk + [sx * randn(1,Nkk);sy*randn(1,Nkk)];
79
80 eval(['x_' num2str(kk) ' = x_kk_new;']);
81
82 end;
83
84 end;
85
86 N_active = length(ind_active_save);
87 junk = randn(1,N_active);
88 [junk,junk2] = sort(junk);
89
90 active_images = zeros(1,n_ima);
91 active_images(ind_active_save(junk2(1:N_ima_active))) = ones(1,N_ima_active);
92
93 fc = fc_save;
94 cc = cc_save;
95 kc = kc_save;
96 KK = KK_save;
97
98 go_calib_optim;
99
100 fc_list = [fc_list fc];
101 cc_list = [cc_list cc];
102 kc_list = [kc_list kc];
103 active_images_list = [active_images_list active_images'];
104
105 for kk=1:n_ima,
106
107 eval(['omc_list_' num2str(kk) ' = [ omc_list_' num2str(kk) ' omc_' num2str(kk) ' ];']);
108 eval(['Tc_list_' num2str(kk) ' = [ Tc_list_' num2str(kk) ' Tc_' num2str(kk) ' ];']);
109
110 end;
111
112end;
113
114
115
116
117if 0,
118
119% Restoring the feature locations:
120
121for kk = 1:n_ima,
122
123 eval(['x_' num2str(kk) ' = x_save_' num2str(kk) ';']);
124
125end;
126
127fprintf(1,'\nFinal run (with the real data)\n');
128fprintf(1, '------------------------------\n');
129
130active_images = active_images_save;
131ind_active = ind_active_save;
132
133go_calib_optim;
134
135fc_list = [fc_list fc];
136cc_list = [cc_list cc];
137kc_list = [kc_list kc];
138active_images_list = [active_images_list active_images'];
139
140for kk=1:n_ima,
141
142 eval(['omc_list_' num2str(kk) ' = [ omc_list_' num2str(kk) ' omc_' num2str(kk) ' ];']);
143 eval(['Tc_list_' num2str(kk) ' = [ Tc_list_' num2str(kk) ' Tc_' num2str(kk) ' ];']);
144
145end;
146
147end;
148
149
150
151
152
153if saving,
154
155disp(['Save Calibration accuracy results under Calib_Accuracies_' num2str(N_ima_active) '.mat']);
156
157string_save = ['save Calib_Accuracies_' num2str(N_ima_active) ' active_images n_ima N_ima_active N_runs active_images_list fc cc kc fc_list cc_list kc_list'];
158
159for kk = 1:n_ima,
160 string_save = [string_save ' Tc_list_' num2str(kk) ' omc_list_' num2str(kk) ' Tc_' num2str(kk) ' omc_' num2str(kk) ];
161end;
162
163eval(string_save);
164
165end;
166
167
168return;
169
170std(fc_list')
171
172std(cc_list')
173
174std(kc_list')
175
176for kk = 1:n_ima,
177
178 eval(['std(Tc_list_' num2str(kk) ''')'])
179
180end;
181
182
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m
new file mode 100755
index 0000000..39506a8
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/export_calib_data.m
@@ -0,0 +1,99 @@
1%% Export calibration data (corners + 3D coordinates) to
2%% text files (in Willson-Heikkila's format or Zhang's format)
3
4%% Thanks to Michael Goesele (from the Max-Planck-Institut) for the original suggestion
5%% of adding thsi export function to the toolbox.
6
7
8if ~exist('n_ima'),
9 fprintf(1,'ERROR: No calibration data to export\n');
10
11else
12
13 check_active_images;
14
15 check_extracted_images;
16
17 check_active_images;
18
19 fprintf(1,'Tool that exports calibration data to Willson-Heikkila or Zhang formats\n');
20
21 qformat = -1;
22
23 while (qformat ~=0)&(qformat ~=1),
24
25 fprintf(1,'Two possible formats of export: 0=Willson and Heikkila, 1=Zhang\n')
26 qformat = input('Format of export (enter 0 or 1): ');
27
28 if isempty(qformat)
29 qformat = -1;
30 end;
31
32 if (qformat ~=0)&(qformat ~=1),
33
34 fprintf(1,'Invalid entry. Try again.\n')
35
36 end;
37
38 end;
39
40 if qformat == 0,
41
42 fprintf(1,'\nExport of calibration data to text files (Willson and Heikkila''s format)\n');
43 outputfile = input('File basename: ','s');
44
45 for kk = ind_active,
46
47 eval(['X_kk = X_' num2str(kk) ';']);
48 eval(['x_kk = x_' num2str(kk) ';']);
49
50 Xx = [X_kk ; x_kk]';
51
52 file_name = [outputfile num2str(kk)];
53
54 disp(['Exporting calibration data (3D world + 2D image coordinates) of image ' num2str(kk) ' to file ' file_name '...']);
55
56 eval(['save ' file_name ' Xx -ASCII']);
57
58 end;
59
60 else
61
62 fprintf(1,'\nExport of calibration data to text files (Zhang''s format)\n');
63 modelfile = input('File basename for the 3D world coordinates: ','s');
64 datafile = input('File basename for the 2D image coordinates: ','s');
65
66 for kk = ind_active,
67
68 eval(['X_kk = X_' num2str(kk) ';']);
69 eval(['x_kk = x_' num2str(kk) ';']);
70
71 if ~exist(['n_sq_x_' num2str(kk)]),
72 n_sq_x = 1;
73 n_sq_y = size(X_kk,2);
74 else
75 eval(['n_sq_x = n_sq_x_' num2str(kk) ';']);
76 eval(['n_sq_y = n_sq_y_' num2str(kk) ';']);
77 end;
78
79 X = reshape(X_kk(1,:)',n_sq_x+1,n_sq_y+1)';
80 Y = reshape(X_kk(2,:)',n_sq_x+1,n_sq_y+1)';
81 XY = reshape([X;Y],n_sq_y+1,2*(n_sq_x+1));
82
83 x = reshape(x_kk(1,:)',n_sq_x+1,n_sq_y+1)';
84 y = reshape(x_kk(2,:)',n_sq_x+1,n_sq_y+1)';
85 xy = reshape([x;y],n_sq_y+1,2*(n_sq_x+1));
86
87 disp(['Exporting calibration data of image ' num2str(kk) ' to files ' modelfile num2str(kk) '.txt and ' datafile num2str(kk) '.txt...']);
88
89 eval(['save ' modelfile num2str(kk) '.txt XY -ASCII']);
90 eval(['save ' datafile num2str(kk) '.txt xy -ASCII']);
91
92 end;
93
94
95end;
96
97fprintf(1,'done\n');
98
99end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m
new file mode 100755
index 0000000..04d6319
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ext_calib.m
@@ -0,0 +1,152 @@
1
2%%%%%%%%%%%%%%%%%%%% SHOW EXTRINSIC RESULTS %%%%%%%%%%%%%%%%%%%%%%%%
3
4if ~exist('n_ima')|~exist('fc'),
5 fprintf(1,'No calibration data available.\n');
6 return;
7end;
8
9check_active_images;
10
11if ~exist(['omc_' num2str(ind_active(1))]),
12 fprintf(1,'No calibration data available.\n');
13 return;
14end;
15
16%if ~exist('no_grid'),
17 no_grid = 0;
18%end;
19
20if ~exist(['n_sq_x_' num2str(ind_active(1))]),
21 no_grid = 1;
22end;
23
24
25if 0,
26
27err_std = std(ex');
28
29fprintf(1,'\n\nCalibration results without principal point estimation:\n\n');
30fprintf(1,'Focal Length: fc = [ %3.5f %3.5f]\n',fc);
31fprintf(1,'Principal point: cc = [ %3.5f %3.5f]\n',cc);
32fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f]\n',kc);
33fprintf(1,'Pixel error: err = [ %3.5f %3.5f]\n\n',err_std);
34
35end;
36
37
38% Color code for each image:
39
40colors = 'brgkcm';
41
42
43%%% Show the extrinsic parameters
44
45if ~exist('dX'),
46 eval(['dX = norm(Tc_' num2str(ind_active(1)) ')/10;']);
47 dY = dX;
48end;
49
50IP = 5*dX*([0 nx-1 nx-1 0 0 ; 0 0 ny-1 ny-1 0;1 1 1 1 1] - [cc;0]*ones(1,5)) ./ ([fc;1]*ones(1,5));
51BASE = 5*dX*([0 1 0 0 0 0;0 0 0 1 0 0;0 0 0 0 0 1]);
52IP = reshape([IP;BASE(:,1)*ones(1,5);IP],3,15);
53
54figure(4);
55[a,b] = view;
56
57figure(4);
58plot3(BASE(1,:),BASE(3,:),-BASE(2,:),'b-','linewidth',2');
59hold on;
60plot3(IP(1,:),IP(3,:),-IP(2,:),'r-','linewidth',2);
61text(6*dX,0,0,'X_c');
62text(-dX,5*dX,0,'Z_c');
63text(0,0,-6*dX,'Y_c');
64text(-dX,-dX,dX,'O_c');
65
66
67for kk = 1:n_ima,
68
69 if active_images(kk);
70
71 if exist(['X_' num2str(kk)]) & exist(['omc_' num2str(kk)]),
72
73 eval(['XX_kk = X_' num2str(kk) ';']);
74
75 if ~isnan(XX_kk(1,1))
76
77 eval(['omc_kk = omc_' num2str(kk) ';']);
78 eval(['Tc_kk = Tc_' num2str(kk) ';']);
79 N_kk = size(XX_kk,2);
80
81 if ~exist(['n_sq_x_' num2str(kk)]),
82 no_grid = 1;
83 else
84 eval(['n_sq_x = n_sq_x_' num2str(kk) ';']);
85 if isnan(n_sq_x(1)),
86 no_grid = 1;
87 end;
88 end;
89
90
91 if ~no_grid,
92 eval(['n_sq_x = n_sq_x_' num2str(kk) ';']);
93 eval(['n_sq_y = n_sq_y_' num2str(kk) ';']);
94 if (N_kk ~= ((n_sq_x+1)*(n_sq_y+1))),
95 no_grid = 1;
96 end;
97 end;
98
99 if ~isnan(omc_kk(1,1)),
100
101 R_kk = rodrigues(omc_kk);
102
103 YY_kk = R_kk * XX_kk + Tc_kk * ones(1,length(XX_kk));
104
105 uu = [-dX;-dY;0]/2;
106 uu = R_kk * uu + Tc_kk;
107
108 if ~no_grid,
109 YYx = zeros(n_sq_x+1,n_sq_y+1);
110 YYy = zeros(n_sq_x+1,n_sq_y+1);
111 YYz = zeros(n_sq_x+1,n_sq_y+1);
112
113 YYx(:) = YY_kk(1,:);
114 YYy(:) = YY_kk(2,:);
115 YYz(:) = YY_kk(3,:);
116
117 %keyboard;
118
119 figure(4);
120 hhh= mesh(YYx,YYz,-YYy);
121 set(hhh,'edgecolor',colors(rem(kk-1,6)+1),'linewidth',1); %,'facecolor','none');
122 %plot3(YY_kk(1,:),YY_kk(3,:),-YY_kk(2,:),['o' colors(rem(kk-1,6)+1)]);
123 text(uu(1),uu(3),-uu(2),num2str(kk),'fontsize',14,'color',colors(rem(kk-1,6)+1));
124 else
125
126 figure(4);
127 plot3(YY_kk(1,:),YY_kk(3,:),-YY_kk(2,:),['.' colors(rem(kk-1,6)+1)]);
128 text(uu(1),uu(3),-uu(2),num2str(kk),'fontsize',14,'color',colors(rem(kk-1,6)+1));
129
130 end;
131
132 end;
133
134 end;
135
136 end;
137
138 end;
139
140end;
141
142figure(4);rotate3d on;
143axis('equal');
144title('Extrinsic parameters');
145%view(60,30);
146view(a,b);
147hold off;
148
149set(4,'Name','3D','NumberTitle','off');
150
151%fprintf(1,'To generate the complete movie associated to the optimization loop, try: check_convergence;\n');
152
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m
new file mode 100755
index 0000000..0cf9abe
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_grid.m
@@ -0,0 +1,234 @@
1function [x,X,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(I,wintx,winty,fc,cc,kc,dX,dY);
2
3map = gray(256);
4
5minI = min(I(:));
6maxI = max(I(:));
7
8Id = 255*(I - minI)/(maxI - minI);
9
10 figure(2);
11 image(Id);
12 colormap(map);
13
14
15 if nargin < 2,
16
17 disp('Window size for corner finder (wintx and winty):');
18 wintx = input('wintx ([] = 5) = ');
19 if isempty(wintx), wintx = 5; end;
20 wintx = round(wintx);
21 winty = input('winty ([] = 5) = ');
22 if isempty(winty), winty = 5; end;
23 winty = round(winty);
24
25 fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1);
26
27 end;
28
29
30
31 title('Click on the four extreme corners of the rectangular pattern...');
32
33 disp('Click on the four extreme corners of the rectangular complete pattern...');
34
35 [x,y] = ginput3(4);
36
37 [Xc,good,bad,type] = cornerfinder([x';y'],I,winty,wintx); % the four corners
38
39 x = Xc(1,:)';
40 y = Xc(2,:)';
41
42 [y,indy] = sort(y);
43 x = x(indy);
44
45 if (x(2) > x(1)),
46 x4 = x(1);y4 = y(1); x3 = x(2); y3 = y(2);
47 else
48 x4 = x(2);y4 = y(2); x3 = x(1); y3 = y(1);
49 end;
50 if (x(3) > x(4)),
51 x2 = x(3);y2 = y(3); x1 = x(4); y1 = y(4);
52 else
53 x2 = x(4);y2 = y(4); x1 = x(3); y1 = y(3);
54 end;
55
56 x = [x1;x2;x3;x4];
57 y = [y1;y2;y3;y4];
58
59
60 figure(2); hold on;
61 plot([x;x(1)],[y;y(1)],'g-');
62 plot(x,y,'og');
63 hx=text((x(4)+x(3))/2,(y(4)+y(3))/2 - 20,'X');
64 set(hx,'color','g','Fontsize',14);
65 hy=text((x(4)+x(1))/2-20,(y(4)+y(1))/2,'Y');
66 set(hy,'color','g','Fontsize',14);
67 hold off;
68
69
70 % Try to automatically count the number of squares in the grid
71
72 n_sq_x1 = count_squares(I,x1,y1,x2,y2,wintx);
73 n_sq_x2 = count_squares(I,x3,y3,x4,y4,wintx);
74 n_sq_y1 = count_squares(I,x2,y2,x3,y3,wintx);
75 n_sq_y2 = count_squares(I,x4,y4,x1,y1,wintx);
76
77
78
79 % If could not count the number of squares, enter manually
80
81 if (n_sq_x1~=n_sq_x2)|(n_sq_y1~=n_sq_y2),
82
83
84 disp('Could not count the number of squares in the grid. Enter manually.');
85 n_sq_x = input('Number of squares along the X direction ([]=10) = '); %6
86 if isempty(n_sq_x), n_sq_x = 10; end;
87 n_sq_y = input('Number of squares along the Y direction ([]=10) = '); %6
88 if isempty(n_sq_y), n_sq_y = 10; end;
89
90 else
91
92 n_sq_x = n_sq_x1;
93 n_sq_y = n_sq_y1;
94
95 end;
96
97 if ~exist('dX')|~exist('dY'),
98
99 % Enter the size of each square
100
101 dX = input(['Size dX of each square along the X direction ([]=30mm) = ']);
102 dY = input(['Size dY of each square along the Y direction ([]=30mm) = ']);
103 if isempty(dX), dX = 30; end;
104 if isempty(dY), dY = 30; end;
105
106 end;
107
108
109 % Compute the inside points through computation of the planar homography (collineation)
110
111 a00 = [x(1);y(1);1];
112 a10 = [x(2);y(2);1];
113 a11 = [x(3);y(3);1];
114 a01 = [x(4);y(4);1];
115
116
117 % Compute the planart collineation: (return the normalization matrice as well)
118
119 [Homo,Hnorm,inv_Hnorm] = compute_homography ([a00 a10 a11 a01],[0 1 1 0;0 0 1 1;1 1 1 1]);
120
121
122 % Build the grid using the planar collineation:
123
124 x_l = ((0:n_sq_x)'*ones(1,n_sq_y+1))/n_sq_x;
125 y_l = (ones(n_sq_x+1,1)*(0:n_sq_y))/n_sq_y;
126 pts = [x_l(:) y_l(:) ones((n_sq_x+1)*(n_sq_y+1),1)]';
127
128 XX = Homo*pts;
129 XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:));
130
131
132 % Complete size of the rectangle
133
134 W = n_sq_x*dX;
135 L = n_sq_y*dY;
136
137
138
139 if nargin < 6,
140
141 %%%%%%%%%%%%%%%%%%%%%%%% ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
142 figure(2);
143 hold on;
144 plot(XX(1,:),XX(2,:),'r+');
145 title('The red crosses should be close to the image corners');
146 hold off;
147
148 disp('If the guessed grid corners (red crosses on the image) are not close to the actual corners,');
149 disp('it is necessary to enter an initial guess for the radial distortion factor kc (useful for subpixel detection)');
150 quest_distort = input('Need of an initial guess for distortion? ([]=no, other=yes) ');
151
152 quest_distort = ~isempty(quest_distort);
153
154 if quest_distort,
155 % Estimation of focal length:
156 c_g = [size(I,2);size(I,1)]/2 + .5;
157 f_g = Distor2Calib(0,[[x(1) x(2) x(4) x(3)] - c_g(1);[y(1) y(2) y(4) y(3)] - c_g(2)],1,1,4,W,L,[-W/2 W/2 W/2 -W/2;L/2 L/2 -L/2 -L/2; 0 0 0 0],100,1,1);
158 f_g = mean(f_g);
159 script_fit_distortion;
160 end;
161 %%%%%%%%%%%%%%%%%%%%% END ADDITIONAL STUFF IN THE CASE OF HIGHLY DISTORTED IMAGES %%%%%%%%%%%%%
162
163 else
164
165 xy_corners_undist = comp_distortion_oulu([(x' - cc(1))/fc(1);(y'-cc(2))/fc(1)],kc);
166
167 xu = xy_corners_undist(1,:)';
168 yu = xy_corners_undist(2,:)';
169
170 [XXu] = projectedGrid ( [xu(1);yu(1)], [xu(2);yu(2)],[xu(3);yu(3)], [xu(4);yu(4)],n_sq_x+1,n_sq_y+1); % The full grid
171
172 r2 = sum(XXu.^2);
173 XX = (ones(2,1)*(1 + kc(1) * r2 + kc(2) * (r2.^2))) .* XXu;
174 XX(1,:) = fc(1)*XX(1,:)+cc(1);
175 XX(2,:) = fc(2)*XX(2,:)+cc(2);
176
177 end;
178
179
180 Np = (n_sq_x+1)*(n_sq_y+1);
181
182 disp('Corner extraction...');
183
184 grid_pts = cornerfinder(XX,I,winty,wintx); %%% Finds the exact corners at every points!
185
186 grid_pts = grid_pts - 1; % subtract 1 to bring the origin to (0,0) instead of (1,1) in matlab (not necessary in C)
187
188 ind_corners = [1 n_sq_x+1 (n_sq_x+1)*n_sq_y+1 (n_sq_x+1)*(n_sq_y+1)]; % index of the 4 corners
189 ind_orig = (n_sq_x+1)*n_sq_y + 1;
190 xorig = grid_pts(1,ind_orig);
191 yorig = grid_pts(2,ind_orig);
192 dxpos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig+1)]');
193 dypos = mean([grid_pts(:,ind_orig) grid_pts(:,ind_orig-n_sq_x-1)]');
194
195
196 ind_x = (n_sq_x+1)*(n_sq_y + 1);
197 ind_y = 1;
198
199 x_box_kk = [grid_pts(1,:)-(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)+(wintx+.5);grid_pts(1,:)-(wintx+.5);grid_pts(1,:)-(wintx+.5)];
200 y_box_kk = [grid_pts(2,:)-(winty+.5);grid_pts(2,:)-(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)+(winty+.5);grid_pts(2,:)-(winty+.5)];
201
202
203 figure(3);
204 image(Id); colormap(map); hold on;
205 plot(grid_pts(1,:)+1,grid_pts(2,:)+1,'r+');
206 plot(x_box_kk+1,y_box_kk+1,'-b');
207 plot(grid_pts(1,ind_corners)+1,grid_pts(2,ind_corners)+1,'mo');
208 plot(xorig+1,yorig+1,'*m');
209 h = text(xorig-15,yorig-15,'O');
210 set(h,'Color','m','FontSize',14);
211 h2 = text(dxpos(1)-10,dxpos(2)-10,'dX');
212 set(h2,'Color','g','FontSize',14);
213 h3 = text(dypos(1)-25,dypos(2)-3,'dY');
214 set(h3,'Color','g','FontSize',14);
215 xlabel('Xc (in camera frame)');
216 ylabel('Yc (in camera frame)');
217 title('Extracted corners');
218 zoom on;
219 drawnow;
220 hold off;
221
222
223 Xi = reshape(([0:n_sq_x]*dX)'*ones(1,n_sq_y+1),Np,1)';
224 Yi = reshape(ones(n_sq_x+1,1)*[n_sq_y:-1:0]*dY,Np,1)';
225 Zi = zeros(1,Np);
226
227 Xgrid = [Xi;Yi;Zi];
228
229
230 % All the point coordinates (on the image, and in 3D) - for global optimization:
231
232 x = grid_pts;
233 X = Xgrid;
234
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m
new file mode 100755
index 0000000..035b97d
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters.m
@@ -0,0 +1,46 @@
1
2%%% Extraction of the final intrinsic and extrinsic paramaters:
3
4check_active_images;
5
6fc = solution(1:2);%***
7cc = solution(3:4);%***
8alpha_c = solution(5);%***
9kc = solution(6:9);%***
10
11
12% Calibration matrix:
13
14KK = [fc(1) fc(1)*alpha_c cc(1);0 fc(2) cc(2); 0 0 1];
15inv_KK = inv(KK);
16
17% Extract the extrinsic paramters, and recomputer the collineations
18
19for kk = 1:n_ima,
20
21 if active_images(kk),
22
23 omckk = solution(15+6*(kk-1) + 1:15+6*(kk-1) + 3);%***
24 Tckk = solution(15+6*(kk-1) + 4:15+6*(kk-1) + 6);%***
25
26 Rckk = rodrigues(omckk);
27
28 Hkk = KK * [Rckk(:,1) Rckk(:,2) Tckk];
29
30 Hkk = Hkk / Hkk(3,3);
31
32 else
33
34 omckk = NaN*ones(3,1);
35 Tckk = NaN*ones(3,1);
36 Rckk = NaN*ones(3,3);
37 Hkk = NaN*ones(3,3);
38
39 end;
40
41 eval(['omc_' num2str(kk) ' = omckk;']);
42 eval(['Rc_' num2str(kk) ' = Rckk;']);
43 eval(['Tc_' num2str(kk) ' = Tckk;']);
44 eval(['H_' num2str(kk) '= Hkk;']);
45
46end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m
new file mode 100755
index 0000000..841c6ab
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extract_parameters3D.m
@@ -0,0 +1,36 @@
1
2%%% Extraction of the final intrinsic and extrinsic paramaters:
3
4
5fc = solution(1:2);
6kc = solution(3:6);
7cc = solution(6*n_ima + 4 +3:6*n_ima + 5 +3);
8
9% Calibration matrix:
10
11KK = [fc(1) 0 cc(1);0 fc(2) cc(2); 0 0 1];
12inv_KK = inv(KK);
13
14% Extract the extrinsic paramters, and recomputer the collineations
15
16for kk = 1:n_ima,
17
18 omckk = solution(4+6*(kk-1) + 3:6*kk + 3);
19
20 Tckk = solution(6*kk+1 + 3:6*kk+3 + 3);
21
22 Rckk = rodrigues(omckk);
23
24 Hlkk = KK * [Rckk(:,1) Rckk(:,2) Tckk];
25
26 Hlkk = Hlkk / Hlkk(3,3);
27
28 eval(['omc_' num2str(kk) ' = omckk;']);
29 eval(['Rc_' num2str(kk) ' = Rckk;']);
30 eval(['Tc_' num2str(kk) ' = Tckk;']);
31
32 eval(['Hl_' num2str(kk) '=Hlkk;']);
33
34end;
35
36
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m
new file mode 100755
index 0000000..fbba78e
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/extrinsic_computation.m
@@ -0,0 +1,185 @@
1%%% INPUT THE IMAGE FILE NAME:
2
3if ~exist('fc')|~exist('cc')|~exist('kc')|~exist('alpha_c'),
4 fprintf(1,'No intrinsic camera parameters available.\n');
5 return;
6end;
7
8dir;
9
10fprintf(1,'\n');
11disp('Computation of the extrinsic parameters from an image of a pattern');
12disp('The intrinsic camera parameters are assumed to be known (previously computed)');
13
14fprintf(1,'\n');
15image_name = input('Image name (full name without extension): ','s');
16
17format_image2 = '0';
18
19while format_image2 == '0',
20
21 format_image2 = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'', ''m''=''ppm'') ','s');
22
23 if isempty(format_image2),
24 format_image2 = 'ras';
25 end;
26
27 if lower(format_image2(1)) == 'm',
28 format_image2 = 'ppm';
29 else
30 if lower(format_image2(1)) == 'b',
31 format_image2 = 'bmp';
32 else
33 if lower(format_image2(1)) == 't',
34 format_image2 = 'tif';
35 else
36 if lower(format_image2(1)) == 'p',
37 format_image2 = 'pgm';
38 else
39 if lower(format_image2(1)) == 'j',
40 format_image2 = 'jpg';
41 else
42 if lower(format_image2(1)) == 'r',
43 format_image2 = 'ras';
44 else
45 disp('Invalid image format');
46 format_image2 = '0'; % Ask for format once again
47 end;
48 end;
49 end;
50 end;
51 end;
52 end;
53end;
54
55ima_name = [image_name '.' format_image2];
56
57
58%%% READ IN IMAGE:
59
60if format_image2(1) == 'p',
61 if format_image2(2) == 'p',
62 I = double(loadppm(ima_name));
63 else
64 I = double(loadpgm(ima_name));
65 end;
66else
67 if format_image2(1) == 'r',
68 I = readras(ima_name);
69 else
70 I = double(imread(ima_name));
71 end;
72end;
73
74if size(I,3)>1,
75 I = I(:,:,2);
76end;
77
78
79%%% EXTRACT GRID CORNERS:
80
81fprintf(1,'\nExtraction of the grid corners on the image\n');
82
83disp('Window size for corner finder (wintx and winty):');
84wintx = input('wintx ([] = 5) = ');
85if isempty(wintx), wintx = 5; end;
86wintx = round(wintx);
87winty = input('winty ([] = 5) = ');
88if isempty(winty), winty = 5; end;
89winty = round(winty);
90
91fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1);
92
93[x_ext,X_ext,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(I,wintx,winty,fc,cc,kc);
94
95
96
97%%% Computation of the Extrinsic Parameters attached to the grid:
98
99[omc_ext,Tc_ext,Rc_ext,H_ext] = compute_extrinsic(x_ext,X_ext,fc,cc,kc,alpha_c);
100
101
102%%% Reproject the points on the image:
103
104[x_reproj] = project_points2(X_ext,omc_ext,Tc_ext,fc,cc,kc,alpha_c);
105
106err_reproj = x_ext - x_reproj;
107
108err_std2 = std(err_reproj')';
109
110
111Basis = [X_ext(:,[ind_orig ind_x ind_orig ind_y ind_orig ])];
112
113VX = Basis(:,2) - Basis(:,1);
114VY = Basis(:,4) - Basis(:,1);
115
116nX = norm(VX);
117nY = norm(VY);
118
119VZ = min(nX,nY) * cross(VX/nX,VY/nY);
120
121Basis = [Basis VZ];
122
123[x_basis] = project_points2(Basis,omc_ext,Tc_ext,fc,cc,kc,alpha_c);
124
125dxpos = (x_basis(:,2) + x_basis(:,1))/2;
126dypos = (x_basis(:,4) + x_basis(:,3))/2;
127dzpos = (x_basis(:,6) + x_basis(:,5))/2;
128
129
130
131figure(2);
132image(I);
133colormap(gray(256));
134hold on;
135plot(x_ext(1,:)+1,x_ext(2,:)+1,'r+');
136plot(x_reproj(1,:)+1,x_reproj(2,:)+1,'yo');
137h = text(x_ext(1,ind_orig)-25,x_ext(2,ind_orig)-25,'O');
138set(h,'Color','g','FontSize',14);
139h2 = text(dxpos(1)+1,dxpos(2)-30,'X');
140set(h2,'Color','g','FontSize',14);
141h3 = text(dypos(1)-30,dypos(2)+1,'Y');
142set(h3,'Color','g','FontSize',14);
143h4 = text(dzpos(1)-10,dzpos(2)-20,'Z');
144set(h4,'Color','g','FontSize',14);
145plot(x_basis(1,:)+1,x_basis(2,:)+1,'g-','linewidth',2);
146title('Image points (+) and reprojected grid points (o)');
147hold off;
148
149
150fprintf(1,'\n\nExtrinsic parameters:\n\n');
151fprintf(1,'Translation vector: Tc_ext = [ %3.6f \t %3.6f \t %3.6f ]\n',Tc_ext);
152fprintf(1,'Rotation vector: omc_ext = [ %3.6f \t %3.6f \t %3.6f ]\n',omc_ext);
153fprintf(1,'Rotation matrix: Rc_ext = [ %3.6f \t %3.6f \t %3.6f\n',Rc_ext(1,:)');
154fprintf(1,' %3.6f \t %3.6f \t %3.6f\n',Rc_ext(2,:)');
155fprintf(1,' %3.6f \t %3.6f \t %3.6f ]\n',Rc_ext(3,:)');
156fprintf(1,'Pixel error: err = [ %3.5f \t %3.5f ]\n\n',err_std2);
157
158
159
160
161
162return;
163
164
165% Stores the results:
166
167kk = 1;
168
169% Stores location of grid wrt camera:
170
171eval(['omc_' num2str(kk) ' = omc_ext;']);
172eval(['Tc_' num2str(kk) ' = Tc_ext;']);
173
174% Stores the projected points:
175
176eval(['y_' num2str(kk) ' = x_reproj;']);
177eval(['X_' num2str(kk) ' = X_ext;']);
178eval(['x_' num2str(kk) ' = x_ext;']);
179
180
181% Organize the points in a grid:
182
183eval(['n_sq_x_' num2str(kk) ' = n_sq_x;']);
184eval(['n_sq_y_' num2str(kk) ' = n_sq_y;']);
185 \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m
new file mode 100755
index 0000000..b5808f3
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixallvariables.m
@@ -0,0 +1,19 @@
1% Code that clears all empty or NaN variables
2
3varlist = whos;
4
5if ~isempty(varlist),
6
7 Nvar = size(varlist,1);
8
9 for c_var = 1:Nvar,
10
11 var2fix = varlist(c_var).name;
12
13 fixvariable;
14
15 end;
16
17end;
18
19clear varlist var2fix Nvar c_var \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m
new file mode 100755
index 0000000..2213431
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/fixvariable.m
@@ -0,0 +1,18 @@
1% Code that clears an empty variable, or a NaN vsriable.
2% Does not clear structures, or cells.
3
4if exist('var2fix'),
5 if eval(['exist(''' var2fix ''') == 1']),
6 if eval(['isempty(' var2fix ')']),
7 eval(['clear ' var2fix ]);
8 else
9 if eval(['~isstruct(' var2fix ')']),
10 if eval(['~iscell(' var2fix ')']),
11 if eval(['isnan(' var2fix '(1))']),
12 eval(['clear ' var2fix ]);
13 end;
14 end;
15 end;
16 end;
17 end;
18end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m
new file mode 100755
index 0000000..56fe496
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ginput3.m
@@ -0,0 +1,216 @@
1function [out1,out2,out3] = ginput2(arg1)
2%GINPUT Graphical input from mouse.
3% [X,Y] = GINPUT(N) gets N points from the current axes and returns
4% the X- and Y-coordinates in length N vectors X and Y. The cursor
5% can be positioned using a mouse (or by using the Arrow Keys on some
6% systems). Data points are entered by pressing a mouse button
7% or any key on the keyboard except carriage return, which terminates
8% the input before N points are entered.
9%
10% [X,Y] = GINPUT gathers an unlimited number of points until the
11% return key is pressed.
12%
13% [X,Y,BUTTON] = GINPUT(N) returns a third result, BUTTON, that
14% contains a vector of integers specifying which mouse button was
15% used (1,2,3 from left) or ASCII numbers if a key on the keyboard
16% was used.
17
18% Copyright (c) 1984-96 by The MathWorks, Inc.
19% $Revision: 5.18 $ $Date: 1996/11/10 17:48:08 $
20
21% Fixed version by Jean-Yves Bouguet to have a cross instead of 2 lines
22% More visible for images
23
24P = NaN*ones(16,16);
25P(1:15,1:15) = 2*ones(15,15);
26P(2:14,2:14) = ones(13,13);
27P(3:13,3:13) = NaN*ones(11,11);
28P(6:10,6:10) = 2*ones(5,5);
29P(7:9,7:9) = 1*ones(3,3);
30
31out1 = []; out2 = []; out3 = []; y = [];
32c = computer;
33if ~strcmp(c(1:2),'PC') & ~strcmp(c(1:2),'MA')
34 tp = get(0,'TerminalProtocol');
35else
36 tp = 'micro';
37end
38
39if ~strcmp(tp,'none') & ~strcmp(tp,'x') & ~strcmp(tp,'micro'),
40 if nargout == 1,
41 if nargin == 1,
42 eval('out1 = trmginput(arg1);');
43 else
44 eval('out1 = trmginput;');
45 end
46 elseif nargout == 2 | nargout == 0,
47 if nargin == 1,
48 eval('[out1,out2] = trmginput(arg1);');
49 else
50 eval('[out1,out2] = trmginput;');
51 end
52 if nargout == 0
53 out1 = [ out1 out2 ];
54 end
55 elseif nargout == 3,
56 if nargin == 1,
57 eval('[out1,out2,out3] = trmginput(arg1);');
58 else
59 eval('[out1,out2,out3] = trmginput;');
60 end
61 end
62else
63
64 fig = gcf;
65 figure(gcf);
66
67 if nargin == 0
68 how_many = -1;
69 b = [];
70 else
71 how_many = arg1;
72 b = [];
73 if isstr(how_many) ...
74 | size(how_many,1) ~= 1 | size(how_many,2) ~= 1 ...
75 | ~(fix(how_many) == how_many) ...
76 | how_many < 0
77 error('Requires a positive integer.')
78 end
79 if how_many == 0
80 ptr_fig = 0;
81 while(ptr_fig ~= fig)
82 ptr_fig = get(0,'PointerWindow');
83 end
84 scrn_pt = get(0,'PointerLocation');
85 loc = get(fig,'Position');
86 pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)];
87 out1 = pt(1); y = pt(2);
88 elseif how_many < 0
89 error('Argument must be a positive integer.')
90 end
91 end
92
93pointer = get(gcf,'pointer');
94
95set(gcf,'Pointer','custom','PointerShapeCData',P,'PointerShapeHotSpot',[8,8]);
96%set(gcf,'pointer','crosshair');
97 fig_units = get(fig,'units');
98 char = 0;
99
100 while how_many ~= 0
101 % Use no-side effect WAITFORBUTTONPRESS
102 waserr = 0;
103 eval('keydown = wfbp;', 'waserr = 1;');
104 if(waserr == 1)
105 if(ishandle(fig))
106 set(fig,'pointer',pointer,'units',fig_units);
107 error('Interrupted');
108 else
109 error('Interrupted by figure deletion');
110 end
111 end
112
113 ptr_fig = get(0,'CurrentFigure');
114 if(ptr_fig == fig)
115 if keydown
116 char = get(fig, 'CurrentCharacter');
117 button = abs(get(fig, 'CurrentCharacter'));
118 scrn_pt = get(0, 'PointerLocation');
119 set(fig,'units','pixels')
120 loc = get(fig, 'Position');
121 pt = [scrn_pt(1) - loc(1), scrn_pt(2) - loc(2)];
122 set(fig,'CurrentPoint',pt);
123 else
124 button = get(fig, 'SelectionType');
125 if strcmp(button,'open')
126 button = b(length(b));
127 elseif strcmp(button,'normal')
128 button = 1;
129 elseif strcmp(button,'extend')
130 button = 2;
131 elseif strcmp(button,'alt')
132 button = 3;
133 else
134 error('Invalid mouse selection.')
135 end
136 end
137 pt = get(gca, 'CurrentPoint');
138
139 how_many = how_many - 1;
140
141 if(char == 13) % & how_many ~= 0)
142 % if the return key was pressed, char will == 13,
143 % and that's our signal to break out of here whether
144 % or not we have collected all the requested data
145 % points.
146 % If this was an early breakout, don't include
147 % the <Return> key info in the return arrays.
148 % We will no longer count it if it's the last input.
149 break;
150 end
151
152 out1 = [out1;pt(1,1)];
153 y = [y;pt(1,2)];
154 b = [b;button];
155 end
156 end
157
158 set(fig,'pointer',pointer,'units',fig_units);
159
160 if nargout > 1
161 out2 = y;
162 if nargout > 2
163 out3 = b;
164 end
165 else
166 out1 = [out1 y];
167 end
168
169end
170
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172function key = wfbp
173%WFBP Replacement for WAITFORBUTTONPRESS that has no side effects.
174
175% Remove figure button functions
176fprops = {'windowbuttonupfcn','buttondownfcn', ...
177 'windowbuttondownfcn','windowbuttonmotionfcn'};
178fig = gcf;
179fvals = get(fig,fprops);
180set(fig,fprops,{'','','',''})
181
182% Remove all other buttondown functions
183ax = findobj(fig,'type','axes');
184if isempty(ax)
185 ch = {};
186else
187 ch = get(ax,{'Children'});
188end
189for i=1:length(ch),
190 ch{i} = ch{i}(:)';
191end
192h = [ax(:)',ch{:}];
193vals = get(h,{'buttondownfcn'});
194mt = repmat({''},size(vals));
195set(h,{'buttondownfcn'},mt);
196
197% Now wait for that buttonpress, and check for error conditions
198waserr = 0;
199eval(['if nargout==0,', ...
200 ' waitforbuttonpress,', ...
201 'else,', ...
202 ' keydown = waitforbuttonpress;',...
203 'end' ], 'waserr = 1;');
204
205% Put everything back
206if(ishandle(fig))
207 set(fig,fprops,fvals)
208 set(h,{'buttondownfcn'},vals)
209end
210
211if(waserr == 1)
212 error('Interrupted');
213end
214
215if nargout>0, key = keydown; end
216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m
new file mode 100755
index 0000000..ad19f64
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim.m
@@ -0,0 +1,139 @@
1%go_calib_optim
2%
3%Main calibration function. Computes the intrinsic andextrinsic parameters.
4%Runs as a script.
5%
6%INPUT: x_1,x_2,x_3,...: Feature locations on the images
7% X_1,X_2,X_3,...: Corresponding grid coordinates
8%
9%OUTPUT: fc: Camera focal length
10% cc: Principal point coordinates
11% kc: Distortion coefficients
12% KK: The camera matrix (containing fc and cc)
13% omc_1,omc_2,omc_3,...: 3D rotation vectors attached to the grid positions in space
14% Tc_1,Tc_2,Tc_3,...: 3D translation vectors attached to the grid positions in space
15% Rc_1,Rc_2,Rc_3,...: 3D rotation matrices corresponding to the omc vectors
16%
17%Method: Minimizes the pixel reprojection error in the least squares sense over the intrinsic
18% camera parameters, and the extrinsic parameters (3D locations of the grids in space)
19%
20%Note: If the intrinsic camera parameters (fc, cc, kc) do not exist before, they are initialized through
21% the function init_intrinsic_param.m. Otherwise, the variables in memory are used as initial guesses.
22%
23%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the
24% corresponding entry in the active_images vector to zero.
25%
26%VERY IMPORTANT: This function works for 2D and 3D calibration rigs, except for init_intrinsic_param.m
27%that is so far implemented to work only with 2D rigs.
28%In the future, a more general function will be there.
29%For now, if using a 3D calibration rig, set quick_init to 1 for an easy initialization of the focal length
30
31
32if ~exist('n_ima'),
33 data_calib; % Load the images
34 click_calib; % Extract the corners
35end;
36
37
38check_active_images;
39
40check_extracted_images;
41
42check_active_images;
43
44
45desactivated_images = [];
46
47
48if ~exist('center_optim'),
49 center_optim = 1; %%% Set this variable to 0 if your do not want to estimate the principal point
50 %%% Required when using one image, and VERY RECOMMENDED WHEN USING LESS THAN 4 images
51end;
52
53% Check 3D-ness of the calibration rig:
54rig3D = 0;
55for kk = ind_active,
56 eval(['X_kk = X_' num2str(kk) ';']);
57 if is3D(X_kk),
58 rig3D = 1;
59 end;
60end;
61
62
63if center_optim & (length(ind_active) < 2) & ~rig3D,
64 fprintf(1,'\nPrincipal point rejected from the optimization when using one image and planar rig (center_optim = 1).\n');
65 center_optim = 0; %%% when using a single image, please, no principal point estimation!!!
66 est_alpha = 0;
67end;
68
69if ~exist('dont_ask'),
70 dont_ask = 0;
71end;
72
73if center_optim & (length(ind_active) < 5),
74 fprintf(1,'\nThe principal point estimation may be unreliable (using less than 5 images for calibration).\n');
75 if ~dont_ask,
76 quest = input('Are you sure you want to keep the principal point in the optimization process? ([]=yes, other=no) ');
77 center_optim = isempty(quest);
78 end;
79end;
80
81if center_optim,
82 fprintf(1,'\nINFO: To reject the principal point from the optimization, set center_optim = 0 in go_calib_optim.m\n');
83end;
84
85if ~exist('est_alpha'),
86 est_alpha = 0; % by default, do not estimate skew
87end;
88
89if ~center_optim & (est_alpha),
90 fprintf(1,'WARNING: Since there is no principal point estimation, no skew estimation (est_alpha = 0)\n');
91 est_alpha = 0;
92else
93 if ~est_alpha,
94 fprintf(1,'WARNING: Skew not optimized. Check variable est_alpha.\n');
95 alpha_c = 0;
96 else
97 fprintf(1,'WARNING: Skew is optimized. To disable skew estimation, set est_alpha=0.\n');
98 end;
99end;
100
101
102if ~exist('est_dist');
103 est_dist = [1;1;1;1];
104end;
105if ~prod(est_dist),
106 fprintf(1,'\nWARNING: Distortion not fully estimated. Check variable est_dist.\n');
107end;
108
109
110
111
112%%% MAIN OPTIMIZATION CALL!!!!! (look into this function for the details of implementation)
113go_calib_optim_iter;
114
115
116
117if ~isempty(desactivated_images),
118
119 param_list_save = param_list;
120
121 fprintf(1,'\nNew optimization including the images that have been deactivated during the previous optimization.\n');
122 active_images(desactivated_images) = ones(1,length(desactivated_images));
123 desactivated_images = [];
124
125 go_calib_optim_iter;
126
127 if ~isempty(desactivated_images),
128 fprintf(1,['List of images left desactivated: ' num2str(desactivated_images) '\n' ] );
129 end;
130
131 param_list = [param_list_save(:,1:end-1) param_list];
132
133end;
134
135
136%%%%%%%%%%%%%%%%%%%% GRAPHICAL OUTPUT %%%%%%%%%%%%%%%%%%%%%%%%
137
138%graphout_calib;
139
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m
new file mode 100755
index 0000000..e3d22f6
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/go_calib_optim_iter.m
@@ -0,0 +1,394 @@
1%go_calib_optim_iter
2%
3%Main calibration function. Computes the intrinsic andextrinsic parameters.
4%Runs as a script.
5%
6%INPUT: x_1,x_2,x_3,...: Feature locations on the images
7% X_1,X_2,X_3,...: Corresponding grid coordinates
8%
9%OUTPUT: fc: Camera focal length
10% cc: Principal point coordinates
11% kc: Distortion coefficients
12% KK: The camera matrix (containing fc and cc)
13% omc_1,omc_2,omc_3,...: 3D rotation vectors attached to the grid positions in space
14% Tc_1,Tc_2,Tc_3,...: 3D translation vectors attached to the grid positions in space
15% Rc_1,Rc_2,Rc_3,...: 3D rotation matrices corresponding to the omc vectors
16%
17%Method: Minimizes the pixel reprojection error in the least squares sense over the intrinsic
18% camera parameters, and the extrinsic parameters (3D locations of the grids in space)
19%
20%Note: If the intrinsic camera parameters (fc, cc, kc) do not exist before, they are initialized through
21% the function init_intrinsic_param.m. Otherwise, the variables in memory are used as initial guesses.
22%
23%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the
24% corresponding entry in the active_images vector to zero.
25%
26%VERY IMPORTANT: This function works for 2D and 3D calibration rigs, except for init_intrinsic_param.m
27%that is so far implemented to work only with 2D rigs.
28%In the future, a more general function will be there.
29%For now, if using a 3D calibration rig, quick_init is set to 1 for an easy initialization of the focal length
30
31
32if ~exist('center_optim'),
33 center_optim = 1; %%% Set this variable to 0 if your do not want to estimate the principal point
34end;
35
36if ~exist('est_dist'),
37 est_dist = [1;1;1;1];
38end;
39
40if ~exist('est_alpha'),
41 est_alpha = 0; % by default, do not estimate skew
42end;
43
44
45% Little fix in case of stupid values in the binary variables:
46center_optim = ~~center_optim;
47est_alpha = ~~est_alpha;
48est_dist = ~~est_dist;
49
50
51if ~exist('nx')&~exist('ny'),
52 fprintf(1,'WARNING: No image size (nx,ny) available. Setting nx=640 and ny=480\n');
53 nx = 640;
54 ny = 480;
55end;
56
57
58check_active_images;
59
60
61quick_init = 0; % Set to 1 for using a quick init (necessary when using 3D rigs)
62
63
64if ~center_optim, % In the case where the principal point is not estimated, keep it at the center of the image
65 fprintf(1,'Principal point not optimized (center_optim=0). It is kept at the center of the image.\n');
66 cc = [(nx-1)/2;(ny-1)/2];
67end;
68
69
70if ~prod(est_dist),
71 fprintf(1,'\nDistortion not fully estimated. Check variable est_dist.\n');
72end;
73
74if ~est_alpha,
75 fprintf(1,'Skew not optimized (est_alpha=0).\n');
76 alpha_c = 0;
77end;
78
79
80% Check 3D-ness of the calibration rig:
81rig3D = 0;
82for kk = ind_active,
83 eval(['X_kk = X_' num2str(kk) ';']);
84 if is3D(X_kk),
85 rig3D = 1;
86 end;
87end;
88
89% If the rig is 3D, then no choice: the only valid initialization is manual!
90if rig3D,
91 quick_init = 1;
92end;
93
94
95
96alpha_smooth = 1; % set alpha_smooth = 1; for steepest gradient descent
97
98
99% Conditioning threshold for view rejection
100thresh_cond = 1e6;
101
102
103
104%% Initialization of the intrinsic parameters (if necessary)
105
106if ~exist('cc'),
107 fprintf(1,'Initialization of the principal point at the center of the image.\n');
108 cc = [(nx-1)/2;(ny-1)/2];
109 alpha_smooth = 0.4; % slow convergence
110end;
111
112
113if ~exist('kc'),
114 fprintf(1,'Initialization of the image distortion to zero.\n');
115 kc = zeros(4,1);
116 alpha_smooth = 0.4; % slow convergence
117end;
118
119if ~exist('alpha_c'),
120 fprintf(1,'Initialization of the image skew to zero.\n');
121 alpha_c = 0;
122 alpha_smooth = 0.4; % slow convergence
123end;
124
125if ~exist('fc')& quick_init,
126 FOV_angle = 35; % Initial camera field of view in degrees
127 fprintf(1,['Initialization of the focal length to a FOV of ' num2str(FOV_angle) ' degrees.\n']);
128 fc = (nx/2)/tan(pi*FOV_angle/360) * ones(2,1);
129 alpha_smooth = 0.4; % slow
130end;
131
132
133if ~exist('fc'),
134 % Initialization of the intrinsic parameters:
135 fprintf(1,'Initialization of the intrinsic parameters using the vanishing points of planar patterns.\n')
136 init_intrinsic_param; % The right way to go (if quick_init is not active)!
137 alpha_smooth = 0.4; % slow convergence
138end;
139
140
141if ~prod(est_dist),
142 % If no distortion estimated, set to zero the variables that are not estimated
143 kc = kc .* est_dist;
144end;
145
146
147
148
149
150%% Initialization of the extrinsic parameters for global minimization:
151
152
153init_param = [fc;cc;alpha_c;kc;zeros(6,1)];
154
155
156
157for kk = 1:n_ima,
158
159 if exist(['x_' num2str(kk)]),
160
161 eval(['x_kk = x_' num2str(kk) ';']);
162 eval(['X_kk = X_' num2str(kk) ';']);
163
164 if (isnan(x_kk(1,1))),
165 if active_images(kk),
166 fprintf(1,'Warning: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk)
167 fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk)
168 end;
169 active_images(kk) = 0;
170 end;
171 if active_images(kk),
172 [omckk,Tckk] = compute_extrinsic_init(x_kk,X_kk,fc,cc,kc,alpha_c);
173 [omckk,Tckk,Rckk,JJ_kk] = compute_extrinsic_refine(omckk,Tckk,x_kk,X_kk,fc,cc,kc,alpha_c,20,thresh_cond);
174 if cond(JJ_kk)> thresh_cond,
175 active_images(kk) = 0;
176 omckk = NaN*ones(3,1);
177 Tckk = NaN*ones(3,1);
178 fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk)
179 desactivated_images = [desactivated_images kk];
180 end;
181 if isnan(omckk(1,1)),
182 %fprintf(1,'\nWarning: Desactivating image %d. Re-activate it later by typing:\nactive_images(%d)=1;\nand re-run optimization\n',[kk kk])
183 active_images(kk) = 0;
184 end;
185 else
186 omckk = NaN*ones(3,1);
187 Tckk = NaN*ones(3,1);
188 end;
189
190 else
191
192 omckk = NaN*ones(3,1);
193 Tckk = NaN*ones(3,1);
194
195 if active_images(kk),
196 fprintf(1,'Warning: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk)
197 fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk)
198 end;
199
200 active_images(kk) = 0;
201
202 end;
203
204 eval(['omc_' num2str(kk) ' = omckk;']);
205 eval(['Tc_' num2str(kk) ' = Tckk;']);
206
207 init_param = [init_param; omckk ; Tckk];
208
209end;
210
211
212check_active_images;
213
214
215
216%-------------------- Main Optimization:
217
218fprintf(1,'\nMain calibration optimization procedure - Number of images: %d\n',length(ind_active));
219
220
221param = init_param;
222change = 1;
223
224iter = 0;
225
226fprintf(1,'Gradient descent iterations: ');
227
228param_list = param;
229
230MaxIter = 30;
231
232
233while (change > 1e-6)&(iter < MaxIter),
234
235 fprintf(1,'%d...',iter+1);
236
237
238 %% The first step consists of updating the whole vector of knowns (intrinsic + extrinsic of active
239 %% images) through a one step steepest gradient descent.
240
241 JJ = [];
242 ex = [];
243
244 f = param(1:2);
245 c = param(3:4);
246 alpha = param(5);
247 k = param(6:9);
248
249
250 for kk = 1:n_ima,
251
252 if active_images(kk),
253
254 %omckk = param(4+6*(kk-1) + 3:6*kk + 3);
255
256 %Tckk = param(6*kk+1 + 3:6*kk+3 + 3);
257
258 omckk = param(15+6*(kk-1) + 1:15+6*(kk-1) + 3);
259
260 Tckk = param(15+6*(kk-1) + 4:15+6*(kk-1) + 6);
261
262 if isnan(omckk(1)),
263 fprintf(1,'Intrinsic parameters at frame %d do not exist\n',kk);
264 return;
265 end;
266
267 eval(['X_kk = X_' num2str(kk) ';']);
268 eval(['x_kk = x_' num2str(kk) ';']);
269
270 Np = size(X_kk,2);
271
272 JJkk = zeros(2*Np,n_ima * 6 + 15);
273
274 [x,dxdom,dxdT,dxdf,dxdc,dxdk,dxdalpha] = project_points2(X_kk,omckk,Tckk,f,c,k,alpha);
275
276 exkk = x_kk - x;
277
278 ex = [ex;exkk(:)];
279
280 JJkk(:,1:2) = dxdf;
281 JJkk(:,3:4) = dxdc;
282 JJkk(:,5) = dxdalpha;
283 JJkk(:,6:9) = dxdk;
284 JJkk(:,15+6*(kk-1) + 1:15+6*(kk-1) + 3) = dxdom;
285 JJkk(:,15+6*(kk-1) + 4:15+6*(kk-1) + 6) = dxdT;
286
287
288
289 JJ = [JJ;JJkk];
290
291
292 % Check if this view is ill-conditioned:
293 JJ_kk = [dxdom dxdT];
294 if cond(JJ_kk)> thresh_cond,
295 active_images(kk) = 0;
296 fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk)
297 desactivated_images = [desactivated_images kk];
298 param(15+6*(kk-1) + 1:15+6*(kk-1) + 6) = NaN*ones(6,1);
299 end;
300
301
302 end;
303
304 end;
305
306
307 % List of active images (necessary if changed):
308 check_active_images;
309
310
311 % The following vector helps to select the variables to update (for only active images):
312
313 ind_Jac = find([ones(2,1);center_optim*ones(2,1);est_alpha;est_dist;zeros(6,1);reshape(ones(6,1)*active_images,6*n_ima,1)])';
314
315
316 JJ = JJ(:,ind_Jac);
317
318 JJ2 = JJ'*JJ;
319
320
321 % Smoothing coefficient:
322
323 alpha_smooth2 = 1-(1-alpha_smooth)^(iter+1); %set to 1 to undo any smoothing!
324
325
326 param_innov = alpha_smooth2*inv(JJ2)*(JJ')*ex;
327 param_up = param(ind_Jac) + param_innov;
328 param(ind_Jac) = param_up;
329
330
331 % New intrinsic parameters:
332
333 fc_current = param(1:2);
334 cc_current = param(3:4);
335 alpha_current = param(5);
336 kc_current = param(6:9);
337
338
339 % Change on the intrinsic parameters:
340 change = norm([fc_current;cc_current] - [f;c])/norm([fc_current;cc_current]);
341
342
343 %% Second step: (optional) - It makes convergence faster, and the region of convergence LARGER!!!
344 %% Recompute the extrinsic parameters only using compute_extrinsic.m (this may be useful sometimes)
345 %% The complete gradient descent method is useful to precisely update the intrinsic parameters.
346
347 MaxIter2 = 20;
348
349
350 for kk = 1:n_ima,
351 if active_images(kk),
352 omc_current = param(15+6*(kk-1) + 1:15+6*(kk-1) + 3);
353 Tc_current = param(15+6*(kk-1) + 4:15+6*(kk-1) + 6);
354 eval(['X_kk = X_' num2str(kk) ';']);
355 eval(['x_kk = x_' num2str(kk) ';']);
356 [omc_current,Tc_current] = compute_extrinsic_init(x_kk,X_kk,fc_current,cc_current,kc_current,alpha_current);
357 [omckk,Tckk,Rckk,JJ_kk] = compute_extrinsic_refine(omc_current,Tc_current,x_kk,X_kk,fc_current,cc_current,kc_current,alpha_current,MaxIter2,thresh_cond);
358 if cond(JJ_kk)> thresh_cond,
359 active_images(kk) = 0;
360 fprintf(1,'\nWarning: View #%d ill-conditioned. This image is now set inactive.\n',kk)
361 desactivated_images = [desactivated_images kk];
362 omckk = NaN*ones(3,1);
363 Tckk = NaN*ones(3,1);
364 end;
365 param(15+6*(kk-1) + 1:15+6*(kk-1) + 3) = omckk;
366 param(15+6*(kk-1) + 4:15+6*(kk-1) + 6) = Tckk;
367 end;
368 end;
369
370 param_list = [param_list param];
371
372 iter = iter + 1;
373
374end;
375
376fprintf(1,'\n');
377
378
379solution = param;
380
381
382%%% Extraction of the final intrinsic and extrinsic paramaters:
383
384extract_parameters;
385
386comp_error_calib;
387
388fprintf(1,'\n\nCalibration results after optimization:\n\n');
389fprintf(1,'Focal Length: fc = [ %3.5f %3.5f ]\n',fc);
390fprintf(1,'Principal point: cc = [ %3.5f %3.5f ]\n',cc);
391fprintf(1,'Skew: alpha_c = [ %3.5f ] => angle of pixel = %3.5f degrees\n',alpha_c,90 - atan(alpha_c)*180/pi);
392fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f ]\n',kc);
393fprintf(1,'Pixel error: err = [ %3.5f %3.5f ]\n\n',err_std);
394
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m
new file mode 100755
index 0000000..dbbc4e0
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/ima_read_calib.m
@@ -0,0 +1,158 @@
1
2if ~exist('calib_name')|~exist('format_image'),
3 data_calib;
4 return;
5end;
6
7check_directory;
8
9if ~exist('n_ima'),
10 data_calib;
11 return;
12end;
13
14check_active_images;
15
16
17images_read = active_images;
18
19
20if exist('image_numbers'),
21 first_num = image_numbers(1);
22end;
23
24
25% Just to fix a minor bug:
26if ~exist('first_num'),
27 first_num = image_numbers(1);
28end;
29
30
31image_numbers = first_num:n_ima-1+first_num;
32
33no_image_file = 0;
34
35i = 1;
36
37while (i <= n_ima), % & (~no_image_file),
38
39 if active_images(i),
40
41 %fprintf(1,'Loading image %d...\n',i);
42
43 if ~type_numbering,
44 number_ext = num2str(image_numbers(i));
45 else
46 number_ext = sprintf(['%.' num2str(N_slots) 'd'],image_numbers(i));
47 end;
48
49 ima_name = [calib_name number_ext '.' format_image];
50
51 if i == ind_active(1),
52 fprintf(1,'Loading image ');
53 end;
54
55 if exist(ima_name),
56
57 fprintf(1,'%d...',i);
58
59 if format_image(1) == 'p',
60 if format_image(2) == 'p',
61 Ii = double(loadppm(ima_name));
62 else
63 Ii = double(loadpgm(ima_name));
64 end;
65 else
66 if format_image(1) == 'r',
67 Ii = readras(ima_name);
68 else
69 Ii = double(imread(ima_name));
70 end;
71 end;
72
73
74 if size(Ii,3)>1,
75 Ii = Ii(:,:,2);
76 end;
77
78 eval(['I_' num2str(i) ' = Ii;']);
79
80 else
81
82 fprintf(1,'%d...no image...',i);
83
84 images_read(i) = 0;
85
86 %no_image_file = 1;
87
88 end;
89
90 end;
91
92 i = i+1;
93
94end;
95
96
97ind_read = find(images_read);
98
99
100
101
102if isempty(ind_read),
103
104 fprintf(1,'\nWARNING! No image were read\n');
105
106 no_image_file = 1;
107
108
109else
110
111
112 %fprintf(1,'\nWARNING! Every exsisting image in the directory is set active.\n');
113
114
115 if no_image_file,
116
117 %fprintf(1,'WARNING! Some images were not read properly\n');
118
119 end;
120
121
122 fprintf(1,'\n');
123
124 if size(I_1,1)~=480,
125 small_calib_image = 1;
126 else
127 small_calib_image = 0;
128 end;
129
130 [Hcal,Wcal] = size(I_1); % size of the calibration image
131
132 [ny,nx] = size(I_1);
133
134 clickname = [];
135
136 map = gray(256);
137
138 %string_save = 'save calib_data n_ima type_numbering N_slots image_numbers format_image calib_name Hcal Wcal nx ny map small_calib_image';
139
140 %eval(string_save);
141
142 disp('done');
143 %click_calib;
144
145end;
146
147if ~exist('map'), map = gray(256); end;
148
149active_images = images_read;
150
151% Show all the calibration images:
152
153
154if ~isempty(ind_read),
155
156 mosaic;
157
158end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m
new file mode 100755
index 0000000..94a5240
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/init_intrinsic_param.m
@@ -0,0 +1,158 @@
1%init_intrinsic_param
2%
3%Initialization of the intrinsic parameters.
4%Runs as a script.
5%
6%INPUT: x_1,x_2,x_3,...: Feature locations on the images
7% X_1,X_2,X_3,...: Corresponding grid coordinates
8%
9%OUTPUT: fc: Camera focal length
10% cc: Principal point coordinates
11% kc: Distortion coefficients
12% alpha_c: skew coefficient
13% KK: The camera matrix (containing fc, cc and alpha_c)
14%
15%Method: Computes the planar homographies H_1, H_2, H_3, ... and computes
16% the focal length fc from orthogonal vanishing points constraint.
17% The principal point cc is assumed at the center of the image.
18% Assumes no image distortion (kc = [0;0;0;0])
19%
20%Note: The row vector active_images consists of zeros and ones. To deactivate an image, set the
21% corresponding entry in the active_images vector to zero.
22%
23%
24%Important function called within that program:
25%
26%compute_homography.m: Computes the planar homography between points on the grid in 3D, and the image plane.
27%
28%
29%VERY IMPORTANT: This function works only with 2D rigs.
30%In the future, a more general function will be there (working with 3D rigs as well).
31
32
33
34check_active_images;
35
36if ~exist(['x_' num2str(ind_active(1)) ]),
37 click_calib;
38end;
39
40
41fprintf(1,'\nInitialization of the intrinsic parameters - Number of images: %d\n',length(ind_active));
42
43
44% Initialize the homographies:
45
46for kk = 1:n_ima,
47 eval(['x_kk = x_' num2str(kk) ';']);
48 eval(['X_kk = X_' num2str(kk) ';']);
49 if (isnan(x_kk(1,1))),
50 if active_images(kk),
51 fprintf(1,'WARNING: Cannot calibrate with image %d. Need to extract grid corners first.\n',kk)
52 fprintf(1,' Set active_images(%d)=1; and run Extract grid corners.\n',kk)
53 end;
54 active_images(kk) = 0;
55 end;
56 if active_images(kk),
57 eval(['H_' num2str(kk) ' = compute_homography(x_kk,X_kk(1:2,:));']);
58 else
59 eval(['H_' num2str(kk) ' = NaN*ones(3,3);']);
60 end;
61end;
62
63check_active_images;
64
65% initial guess for principal point and distortion:
66
67if ~exist('nx'), [ny,nx] = size(I); end;
68
69c_init = [nx;ny]/2 - 0.5; % initialize at the center of the image
70k_init = [0;0;0;0]; % initialize to zero (no distortion)
71
72
73
74% Compute explicitely the focal length using all the (mutually orthogonal) vanishing points
75% note: The vanihing points are hidden in the planar collineations H_kk
76
77A = [];
78b = [];
79
80% matrix that subtract the principal point:
81Sub_cc = [1 0 -c_init(1);0 1 -c_init(2);0 0 1];
82
83for kk=1:n_ima,
84
85 if active_images(kk),
86
87 eval(['Hkk = H_' num2str(kk) ';']);
88
89 Hkk = Sub_cc * Hkk;
90
91 % Extract vanishing points (direct and diagonals):
92
93 V_hori_pix = Hkk(:,1);
94 V_vert_pix = Hkk(:,2);
95 V_diag1_pix = (Hkk(:,1)+Hkk(:,2))/2;
96 V_diag2_pix = (Hkk(:,1)-Hkk(:,2))/2;
97
98 V_hori_pix = V_hori_pix/norm(V_hori_pix);
99 V_vert_pix = V_vert_pix/norm(V_vert_pix);
100 V_diag1_pix = V_diag1_pix/norm(V_diag1_pix);
101 V_diag2_pix = V_diag2_pix/norm(V_diag2_pix);
102
103 a1 = V_hori_pix(1);
104 b1 = V_hori_pix(2);
105 c1 = V_hori_pix(3);
106
107 a2 = V_vert_pix(1);
108 b2 = V_vert_pix(2);
109 c2 = V_vert_pix(3);
110
111 a3 = V_diag1_pix(1);
112 b3 = V_diag1_pix(2);
113 c3 = V_diag1_pix(3);
114
115 a4 = V_diag2_pix(1);
116 b4 = V_diag2_pix(2);
117 c4 = V_diag2_pix(3);
118
119 A_kk = [a1*a2 b1*b2;
120 a3*a4 b3*b4];
121
122 b_kk = -[c1*c2;c3*c4];
123
124
125 A = [A;A_kk];
126 b = [b;b_kk];
127
128 end;
129
130end;
131
132
133% use all the vanishing points to estimate focal length:
134
135f_init = sqrt(abs(1./(inv(A'*A)*A'*b))); % if using a two-focal model for initial guess
136
137alpha_init = 0;
138
139%f_init = sqrt(b'*(sum(A')') / (b'*b)) * ones(2,1); % if single focal length model is used
140
141
142% Global calibration matrix (initial guess):
143
144KK = [f_init(1) alpha_init*f_init(1) c_init(1);0 f_init(2) c_init(2); 0 0 1];
145inv_KK = inv(KK);
146
147
148cc = c_init;
149fc = f_init;
150kc = k_init;
151alpha_c = alpha_init;
152
153
154fprintf(1,'\n\nCalibration parameters after initialization:\n\n');
155fprintf(1,'Focal Length: fc = [ %3.5f %3.5f ]\n',fc);
156fprintf(1,'Principal point: cc = [ %3.5f %3.5f ]\n',cc);
157fprintf(1,'Skew: alpha_c = [ %3.5f ] => angle of pixel = %3.5f degrees\n',alpha_c,90 - atan(alpha_c)*180/pi);
158fprintf(1,'Distortion: kc = [ %3.5f %3.5f %3.5f %3.5f ]\n',kc);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m
new file mode 100755
index 0000000..ab00b3d
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/is3D.m
@@ -0,0 +1,19 @@
1function test = is3D(X),
2
3
4Np = size(X,2);
5
6%% Check for planarity of the structure:
7
8X_mean = mean(X')';
9
10Y = X - (X_mean*ones(1,Np));
11
12YY = Y*Y';
13
14[U,S,V] = svd(YY);
15
16r = S(3,3)/S(2,2);
17
18test = (r > 1e-3);
19
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m
new file mode 100755
index 0000000..a0f50d2
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loading_calib.m
@@ -0,0 +1,10 @@
1if ~exist('Calib_Results.mat'),
2 fprintf(1,'\nCalibration file Calib_Results.mat not found!\n');
3 return;
4end;
5
6fprintf(1,'\nLoading calibration results from Calib_Results.mat\n');
7
8load Calib_Results
9
10fprintf(1,'done\n');
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m
new file mode 100755
index 0000000..91b6f89
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadinr.m
@@ -0,0 +1,52 @@
1%LOADINR Load an INRIMAGE format file
2%
3% LOADINR(filename, im)
4%
5% Load an INRIA image format file and return it as a matrix
6%
7% SEE ALSO: saveinr
8%
9% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab
10
11
12% Peter Corke 1996
13
14function im = loadinr(fname, im)
15
16 fid = fopen(fname, 'r');
17
18 s = fgets(fid);
19 if strcmp(s(1:12), '#INRIMAGE-4#') == 0,
20 error('not INRIMAGE format');
21 end
22
23 % not very complete, only looks for the X/YDIM keys
24 while 1,
25 s = fgets(fid);
26 n = length(s) - 1;
27 if s(1) == '#',
28 break
29 end
30 if strcmp(s(1:5), 'XDIM='),
31 cols = str2num(s(6:n));
32 end
33 if strcmp(s(1:5), 'YDIM='),
34 rows = str2num(s(6:n));
35 end
36 if strcmp(s(1:4), 'CPU='),
37 if strcmp(s(5:n), 'sun') == 0,
38 error('not sun data ordering');
39 end
40 end
41
42 end
43 disp(['INRIMAGE format file ' num2str(rows) ' x ' num2str(cols)])
44
45 % now the binary data
46 fseek(fid, 256, 'bof');
47 [im count] = fread(fid, [cols rows], 'float32');
48 im = im';
49 if count ~= (rows*cols),
50 error('file too short');
51 end
52 fclose(fid);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m
new file mode 100755
index 0000000..dfa8b61
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadpgm.m
@@ -0,0 +1,89 @@
1%LOADPGM Load a PGM image
2%
3% I = loadpgm(filename)
4%
5% Returns a matrix containing the image loaded from the PGM format
6% file filename. Handles ASCII (P2) and binary (P5) PGM file formats.
7%
8% If the filename has no extension, and open fails, a '.pgm' will
9% be appended.
10%
11%
12% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab
13
14
15% Peter Corke 1994
16
17function I = loadpgm(file)
18 white = [' ' 9 10 13]; % space, tab, lf, cr
19 white = setstr(white);
20
21 fid = fopen(file, 'r');
22 if fid < 0,
23 fid = fopen([file '.pgm'], 'r');
24 end
25 if fid < 0,
26 error('Couldn''t open file');
27 end
28
29 magic = fread(fid, 2, 'char');
30 while 1
31 c = fread(fid,1,'char');
32 if c == '#',
33 fgetl(fid);
34 elseif ~any(c == white)
35 fseek(fid, -1, 'cof'); % unputc()
36 break;
37 end
38 end
39 cols = fscanf(fid, '%d', 1);
40 while 1
41 c = fread(fid,1,'char');
42 if c == '#',
43 fgetl(fid);
44 elseif ~any(c == white)
45 fseek(fid, -1, 'cof'); % unputc()
46 break;
47 end
48 end
49 rows = fscanf(fid, '%d', 1);
50 while 1
51 c = fread(fid,1,'char');
52 if c == '#',
53 fgetl(fid);
54 elseif ~any(c == white)
55 fseek(fid, -1, 'cof'); % unputc()
56 break;
57 end
58 end
59 maxval = fscanf(fid, '%d', 1);
60 while 1
61 c = fread(fid,1,'char');
62 if c == '#',
63 fgetl(fid);
64 elseif ~any(c == white)
65 fseek(fid, -1, 'cof'); % unputc()
66 break;
67 end
68 end
69 if magic(1) == 'P',
70 if magic(2) == '2',
71 %disp(['ASCII PGM file ' num2str(rows) ' x ' num2str(cols)])
72 I = fscanf(fid, '%d', [cols rows])';
73 elseif magic(2) == '5',
74 %disp(['Binary PGM file ' num2str(rows) ' x ' num2str(cols)])
75 if maxval == 1,
76 fmt = 'unint1';
77 elseif maxval == 15,
78 fmt = 'uint4';
79 elseif maxval == 255,
80 fmt = 'uint8';
81 elseif maxval == 2^32-1,
82 fmt = 'uint32';
83 end
84 I = fread(fid, [cols rows], fmt)';
85 else
86 disp('Not a PGM file');
87 end
88 end
89 fclose(fid);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m
new file mode 100755
index 0000000..0c004fc
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/loadppm.m
@@ -0,0 +1,109 @@
1%LOADPPM Load a PPM image
2%
3% I = loadppm(filename)
4%
5% Returns a matrix containing the image loaded from the PPM format
6% file filename. Handles ASCII (P3) and binary (P6) PPM file formats.
7%
8% If the filename has no extension, and open fails, a '.ppm' and
9% '.pnm' extension will be tried.
10%
11% SEE ALSO: saveppm loadpgm
12%
13% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab
14
15
16% Peter Corke 1994
17
18function I = loadppm(file)
19 white = [' ' 9 10 13]; % space, tab, lf, cr
20 white = setstr(white);
21
22 fid = fopen(file, 'r');
23 if fid < 0,
24 fid = fopen([file '.ppm'], 'r');
25 end
26 if fid < 0,
27 fid = fopen([file '.pnm'], 'r');
28 end
29 if fid < 0,
30 error('Couldn''t open file');
31 end
32
33 magic = fread(fid, 2, 'char');
34 while 1
35 c = fread(fid,1,'char');
36 if c == '#',
37 fgetl(fid);
38 elseif ~any(c == white)
39 fseek(fid, -1, 'cof'); % unputc()
40 break;
41 end
42 end
43 cols = fscanf(fid, '%d', 1);
44 while 1
45 c = fread(fid,1,'char');
46 if c == '#',
47 fgetl(fid);
48 elseif ~any(c == white)
49 fseek(fid, -1, 'cof'); % unputc()
50 break;
51 end
52 end
53 rows = fscanf(fid, '%d', 1);
54 while 1
55 c = fread(fid,1,'char');
56 if c == '#',
57 fgetl(fid);
58 elseif ~any(c == white)
59 fseek(fid, -1, 'cof'); % unputc()
60 break;
61 end
62 end
63 maxval = fscanf(fid, '%d', 1);
64 while 1
65 c = fread(fid,1,'char');
66 if c == '#',
67 fgetl(fid);
68 elseif ~any(c == white)
69 fseek(fid, -1, 'cof'); % unputc()
70 break;
71 end
72 end
73 if magic(1) == 'P',
74 if magic(2) == '3',
75 %disp(['ASCII PPM file ' num2str(rows) ' x ' num2str(cols)])
76 I = fscanf(fid, '%d', [cols*3 rows]);
77 elseif magic(2) == '6',
78 %disp(['Binary PPM file ' num2str(rows) ' x ' num2str(cols)])
79 if maxval == 1,
80 fmt = 'unint1';
81 elseif maxval == 15,
82 fmt = 'uint4';
83 elseif maxval == 255,
84 fmt = 'uint8';
85 elseif maxval == 2^32-1,
86 fmt = 'uint32';
87 end
88 I = fread(fid, [cols*3 rows], fmt);
89 else
90 disp('Not a PPM file');
91 end
92 end
93 %
94 % now the matrix has interleaved columns of R, G, B
95 %
96 I = I';
97 size(I);
98 R = I(:,1:3:(cols*3));
99 G = I(:,2:3:(cols*3));
100 B = I(:,3:3:(cols*3));
101 fclose(fid);
102
103
104 I = zeros(rows,cols,3);
105 I(:,:,1) = R;
106 I(:,:,2) = G;
107 I(:,:,3) = B;
108 I = uint8(I);
109 \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m
new file mode 100755
index 0000000..0d18a62
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mean_std_robust.m
@@ -0,0 +1,7 @@
1function [m,s] = mean_std_robust(x);
2
3x = x(:);
4
5m = median(x);
6
7s = median(abs(x - m))*1.4836;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m
new file mode 100755
index 0000000..b056661
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/mosaic.m
@@ -0,0 +1,92 @@
1
2if ~exist('I_1'),
3 active_images_save = active_images;
4 ima_read_calib;
5 active_images = active_images_save;
6 check_active_images;
7end;
8
9check_active_images;
10
11if isempty(ind_read),
12 return;
13end;
14
15
16n_col = floor(sqrt(n_ima*nx/ny));
17
18n_row = ceil(n_ima / n_col);
19
20
21ker2 = 1;
22for ii = 1:n_col,
23 ker2 = conv(ker2,[1/4 1/2 1/4]);
24end;
25
26
27II = I_1(1:n_col:end,1:n_col:end);
28
29[ny2,nx2] = size(II);
30
31
32
33kk_c = 1;
34
35II_mosaic = [];
36
37for jj = 1:n_row,
38
39
40 II_row = [];
41
42 for ii = 1:n_col,
43
44 if (exist(['I_' num2str(kk_c)])) & (kk_c <= n_ima),
45
46 if active_images(kk_c),
47 eval(['I = I_' num2str(kk_c) ';']);
48 %I = conv2(conv2(I,ker2,'same'),ker2','same'); % anti-aliasing
49 I = I(1:n_col:end,1:n_col:end);
50 else
51 I = zeros(ny2,nx2);
52 end;
53
54 else
55
56 I = zeros(ny2,nx2);
57
58 end;
59
60
61
62 II_row = [II_row I];
63
64 if ii ~= n_col,
65
66 II_row = [II_row zeros(ny2,3)];
67
68 end;
69
70
71 kk_c = kk_c + 1;
72
73 end;
74
75 nn2 = size(II_row,2);
76
77 if jj ~= n_row,
78 II_row = [II_row; zeros(3,nn2)];
79 end;
80
81 II_mosaic = [II_mosaic ; II_row];
82
83end;
84
85figure(2);
86image(II_mosaic);
87colormap(gray(256));
88title('Calibration images');
89set(gca,'Xtick',[])
90set(gca,'Ytick',[])
91axis('image');
92
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m
new file mode 100755
index 0000000..6dc7149
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/normalize.m
@@ -0,0 +1,43 @@
1function [xn] = normalize(x_kk,fc,cc,kc,alpha_c),
2
3%normalize
4%
5%[xn] = normalize(x_kk,fc,cc,kc,alpha_c)
6%
7%Computes the normalized coordinates xn given the pixel coordinates x_kk
8%and the intrinsic camera parameters fc, cc and kc.
9%
10%INPUT: x_kk: Feature locations on the images
11% fc: Camera focal length
12% cc: Principal point coordinates
13% kc: Distortion coefficients
14% alpha_c: Skew coefficient
15%
16%OUTPUT: xn: Normalized feature locations on the image plane (a 2XN matrix)
17%
18%Important functions called within that program:
19%
20%comp_distortion_oulu: undistort pixel coordinates.
21
22if nargin < 5,
23 alpha_c = 0;
24 if nargin < 4;
25 kc = [0;0;0;0];
26 if nargin < 3;
27 cc = [0;0];
28 if nargin < 2,
29 fc = [1;1];
30 end;
31 end;
32 end;
33end;
34
35
36% First subtract principal point, and divide by the focal length:
37temp = (x_kk(2,:) - cc(2))/fc(2);
38x_distort = [(x_kk(1,:) - cc(1))/fc(1) - alpha_c*temp;temp];
39
40
41%Compensate for lens distortion:
42
43xn = comp_distortion_oulu(x_distort,kc);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m
new file mode 100755
index 0000000..c96ccb7
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/pgmread.m
@@ -0,0 +1,26 @@
1function img = pgmread(filename)
2% function img = pgmread(filename)
3% this is my version of pgmread for the pgm file created by XV.
4%
5% this program also corrects for the shifts in the image from pm file.
6
7fid = fopen(filename,'r');
8fscanf(fid, 'P5\n');
9cmt = '#';
10while findstr(cmt, '#'),
11 cmt = fgets(fid);
12 if length(findstr(cmt, '#')) ~= 1,
13 YX = sscanf(cmt, '%d %d');
14 y = YX(1); x = YX(2);
15 end
16end
17
18%fgets(fid);
19
20%img = fscanf(fid,'%d',size);
21%img = img';
22
23img = fread(fid,[y,x],'uint8');
24img = img';
25fclose(fid);
26
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m
new file mode 100755
index 0000000..c5c4a34
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project2_oulu.m
@@ -0,0 +1,53 @@
1function [x] = project2_oulu(X,R,T,f,t,k)
2%PROJECT Subsidiary to calib
3
4% (c) Pietro Perona -- March 24, 1994
5% California Institute of Technology
6% Pasadena, CA
7%
8% Renamed because project exists in matlab 5.2!!!
9% Now uses the more elaborate intrinsic model from Oulu
10
11
12
13[m,n] = size(X);
14
15Y = R*X + T*ones(1,n);
16Z = Y(3,:);
17
18f = f(:); %% make a column vector
19if length(f)==1,
20 f = [f f]';
21end;
22
23x = (Y(1:2,:) ./ (ones(2,1) * Z)) ;
24
25
26radius_2 = x(1,:).^2 + x(2,:).^2;
27
28if length(k) > 1,
29
30 radial_distortion = 1 + ones(2,1) * ((k(1) * radius_2) + (k(2) * radius_2.^2));
31
32 if length(k) < 4,
33
34 delta_x = zeros(2,n);
35
36 else
37
38 delta_x = [2*k(3)*x(1,:).*x(2,:) + k(4)*(radius_2 + 2*x(1,:).^2) ;
39 k(3) * (radius_2 + 2*x(2,:).^2)+2*k(4)*x(1,:).*x(2,:)];
40
41 end;
42
43
44else
45
46 radial_distortion = 1 + ones(2,1) * ((k(1) * radius_2));
47
48 delta_x = zeros(2,n);
49
50end;
51
52
53x = (x .* radial_distortion + delta_x).* (f * ones(1,n)) + t*ones(1,n);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m
new file mode 100755
index 0000000..1823490
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points.m
@@ -0,0 +1,276 @@
1function [xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points(X,om,T,f,c,k)
2
3%project_points.m
4%
5%[xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points(X,om,T,f,c,k)
6%
7%Projects a 3D structure onto the image plane.
8%
9%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points)
10% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame
11% om: rotation vector (3x1 vector); T: translation vector (3x1 vector)
12% f: camera focal length in units of horizontal and vertical pixel units (2x1 vector)
13% c: principal point location in pixel units (2x1 vector)
14% k: Distortion coefficients (radial and tangential) (4x1 vector)
15%
16%OUTPUT: xp: Projected pixel coordinates (2xN matrix for N points)
17% dxpdom: Derivative of xp with respect to om ((2N)x3 matrix)
18% dxpdT: Derivative of xp with respect to T ((2N)x3 matrix)
19% dxpdf: Derivative of xp with respect to f ((2N)x2 matrix)
20% dxpdc: Derivative of xp with respect to c ((2N)x2 matrix)
21% dxpdk: Derivative of xp with respect to k ((2N)x4 matrix)
22%
23%Definitions:
24%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X)
25%The coordinate vector of P in the camera reference frame is: Xc = R*X + T
26%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om);
27%call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3);
28%The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z.
29%call r^2 = a^2 + b^2.
30%The distorted point coordinates are: xd = [xx;yy] where:
31%
32%xx = a * (1 + kc(1)*r^2 + kc(2)*r^4) + 2*kc(3)*a*b + kc(4)*(r^2 + 2*a^2);
33%yy = b * (1 + kc(1)*r^2 + kc(2)*r^4) + kc(3)*(r^2 + 2*b^2) + 2*kc(4)*a*b;
34%
35%The left terms correspond to radial distortion, the right terms correspond to tangential distortion
36%
37%Fianlly, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where:
38%
39%xxp = f(1)*xx + c(1)
40%yyp = f(2)*yy + c(2)
41%
42%
43%NOTE: About 90 percent of the code takes care fo computing the Jacobian matrices
44%
45%
46%Important function called within that program:
47%
48%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector
49%
50%rigid_motion.m: Computes the rigid motion transformation of a given structure
51
52
53
54if nargin < 6,
55 k = zeros(4,1);
56 if nargin < 5,
57 c = zeros(2,1);
58 if nargin < 4,
59 f = ones(2,1);
60 if nargin < 3,
61 T = zeros(3,1);
62 if nargin < 2,
63 om = zeros(3,1);
64 if nargin < 1,
65 error('Need at least a 3D structure to project (in project_points.m)');
66 return;
67 end;
68 end;
69 end;
70 end;
71 end;
72end;
73
74
75[m,n] = size(X);
76
77[Y,dYdom,dYdT] = rigid_motion(X,om,T);
78
79
80inv_Z = 1./Y(3,:);
81
82x = (Y(1:2,:) .* (ones(2,1) * inv_Z)) ;
83
84
85bb = (-x(1,:) .* inv_Z)'*ones(1,3);
86cc = (-x(2,:) .* inv_Z)'*ones(1,3);
87
88
89dxdom = zeros(2*n,3);
90dxdom(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(1:3:end,:) + bb .* dYdom(3:3:end,:);
91dxdom(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(2:3:end,:) + cc .* dYdom(3:3:end,:);
92
93dxdT = zeros(2*n,3);
94dxdT(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(1:3:end,:) + bb .* dYdT(3:3:end,:);
95dxdT(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(2:3:end,:) + cc .* dYdT(3:3:end,:);
96
97
98% Add distortion:
99
100r2 = x(1,:).^2 + x(2,:).^2;
101
102
103
104dr2dom = 2*((x(1,:)')*ones(1,3)) .* dxdom(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdom(2:2:end,:);
105dr2dT = 2*((x(1,:)')*ones(1,3)) .* dxdT(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdT(2:2:end,:);
106
107
108r4 = r2.^2;
109
110dr4dom = 2*((r2')*ones(1,3)) .* dr2dom;
111dr4dT = 2*((r2')*ones(1,3)) .* dr2dT;
112
113
114% Radial distortion:
115
116cdist = 1 + k(1) * r2 + k(2) * r4;
117
118dcdistdom = k(1) * dr2dom + k(2) * dr4dom;
119dcdistdT = k(1) * dr2dT+ k(2) * dr4dT;
120dcdistdk = [ r2' r4' zeros(n,2)];
121
122
123xd1 = x .* (ones(2,1)*cdist);
124
125dxd1dom = zeros(2*n,3);
126dxd1dom(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdom;
127dxd1dom(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdom;
128coeff = (reshape([cdist;cdist],2*n,1)*ones(1,3));
129dxd1dom = dxd1dom + coeff.* dxdom;
130
131dxd1dT = zeros(2*n,3);
132dxd1dT(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdT;
133dxd1dT(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdT;
134dxd1dT = dxd1dT + coeff.* dxdT;
135
136dxd1dk = zeros(2*n,4);
137dxd1dk(1:2:end,:) = (x(1,:)'*ones(1,4)) .* dcdistdk;
138dxd1dk(2:2:end,:) = (x(2,:)'*ones(1,4)) .* dcdistdk;
139
140
141
142% tangential distortion:
143
144a1 = 2.*x(1,:).*x(2,:);
145a2 = r2 + 2*x(1,:).^2;
146a3 = r2 + 2*x(2,:).^2;
147
148delta_x = [k(3)*a1 + k(4)*a2 ;
149 k(3) * a3 + k(4)*a1];
150
151
152ddelta_xdx = zeros(2*n,2*n);
153aa = (2*k(3)*x(2,:)+6*k(4)*x(1,:))'*ones(1,3);
154bb = (2*k(3)*x(1,:)+2*k(4)*x(2,:))'*ones(1,3);
155cc = (6*k(3)*x(2,:)+2*k(4)*x(1,:))'*ones(1,3);
156
157ddelta_xdom = zeros(2*n,3);
158ddelta_xdom(1:2:end,:) = aa .* dxdom(1:2:end,:) + bb .* dxdom(2:2:end,:);
159ddelta_xdom(2:2:end,:) = bb .* dxdom(1:2:end,:) + cc .* dxdom(2:2:end,:);
160
161ddelta_xdT = zeros(2*n,3);
162ddelta_xdT(1:2:end,:) = aa .* dxdT(1:2:end,:) + bb .* dxdT(2:2:end,:);
163ddelta_xdT(2:2:end,:) = bb .* dxdT(1:2:end,:) + cc .* dxdT(2:2:end,:);
164
165ddelta_xdk = zeros(2*n,4);
166ddelta_xdk(1:2:end,3) = a1';
167ddelta_xdk(1:2:end,4) = a2';
168ddelta_xdk(2:2:end,3) = a3';
169ddelta_xdk(2:2:end,4) = a1';
170
171
172
173xd2 = xd1 + delta_x;
174
175dxd2dom = dxd1dom + ddelta_xdom ;
176dxd2dT = dxd1dT + ddelta_xdT;
177dxd2dk = dxd1dk + ddelta_xdk ;
178
179
180% Pixel coordinates:
181
182xp = xd2 .* (f * ones(1,n)) + c*ones(1,n);
183
184coeff = reshape(f*ones(1,n),2*n,1);
185
186dxpdom = (coeff*ones(1,3)) .* dxd2dom;
187dxpdT = (coeff*ones(1,3)) .* dxd2dT;
188dxpdk = (coeff*ones(1,4)) .* dxd2dk;
189
190dxpdf = zeros(2*n,2);
191dxpdf(1:2:end,1) = xd2(1,:)';
192dxpdf(2:2:end,2) = xd2(2,:)';
193
194dxpdc = zeros(2*n,2);
195dxpdc(1:2:end,1) = ones(n,1);
196dxpdc(2:2:end,2) = ones(n,1);
197
198
199return;
200
201% Test of the Jacobians:
202
203n = 10;
204
205X = 10*randn(3,n);
206om = randn(3,1);
207T = [10*randn(2,1);40];
208f = 1000*rand(2,1);
209c = 1000*randn(2,1);
210k = 0.5*randn(4,1);
211
212
213[x,dxdom,dxdT,dxdf,dxdc,dxdk] = project_points(X,om,T,f,c,k);
214
215
216% Test on om: NOT OK
217
218dom = 0.000000001 * norm(om)*randn(3,1);
219om2 = om + dom;
220
221[x2] = project_points(X,om2,T,f,c,k);
222
223x_pred = x + reshape(dxdom * dom,2,n);
224
225
226norm(x2-x)/norm(x2 - x_pred)
227
228
229% Test on T: OK!!
230
231dT = 0.0001 * norm(T)*randn(3,1);
232T2 = T + dT;
233
234[x2] = project_points(X,om,T2,f,c,k);
235
236x_pred = x + reshape(dxdT * dT,2,n);
237
238
239norm(x2-x)/norm(x2 - x_pred)
240
241
242
243% Test on f: OK!!
244
245df = 0.001 * norm(f)*randn(2,1);
246f2 = f + df;
247
248[x2] = project_points(X,om,T,f2,c,k);
249
250x_pred = x + reshape(dxdf * df,2,n);
251
252
253norm(x2-x)/norm(x2 - x_pred)
254
255
256% Test on c: OK!!
257
258dc = 0.01 * norm(c)*randn(2,1);
259c2 = c + dc;
260
261[x2] = project_points(X,om,T,f,c2,k);
262
263x_pred = x + reshape(dxdc * dc,2,n);
264
265norm(x2-x)/norm(x2 - x_pred)
266
267% Test on k: OK!!
268
269dk = 0.001 * norm(4)*randn(4,1);
270k2 = k + dk;
271
272[x2] = project_points(X,om,T,f,c,k2);
273
274x_pred = x + reshape(dxdk * dk,2,n);
275
276norm(x2-x)/norm(x2 - x_pred)
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m
new file mode 100755
index 0000000..5bb1b91
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/project_points2.m
@@ -0,0 +1,312 @@
1function [xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk,dxpdalpha] = project_points2(X,om,T,f,c,k,alpha)
2
3%project_points.m
4%
5%[xp,dxpdom,dxpdT,dxpdf,dxpdc,dxpdk] = project_points2(X,om,T,f,c,k,alpha)
6%
7%Projects a 3D structure onto the image plane.
8%
9%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points)
10% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame
11% om: rotation vector (3x1 vector); T: translation vector (3x1 vector)
12% f: camera focal length in units of horizontal and vertical pixel units (2x1 vector)
13% c: principal point location in pixel units (2x1 vector)
14% k: Distortion coefficients (radial and tangential) (4x1 vector)
15% alpha: Skew coefficient between x and y pixel (alpha = 0 <=> square pixels)
16%
17%OUTPUT: xp: Projected pixel coordinates (2xN matrix for N points)
18% dxpdom: Derivative of xp with respect to om ((2N)x3 matrix)
19% dxpdT: Derivative of xp with respect to T ((2N)x3 matrix)
20% dxpdf: Derivative of xp with respect to f ((2N)x2 matrix)
21% dxpdc: Derivative of xp with respect to c ((2N)x2 matrix)
22% dxpdk: Derivative of xp with respect to k ((2N)x4 matrix)
23%
24%Definitions:
25%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X)
26%The coordinate vector of P in the camera reference frame is: Xc = R*X + T
27%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om);
28%call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3);
29%The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z.
30%call r^2 = a^2 + b^2.
31%The distorted point coordinates are: xd = [xx;yy] where:
32%
33%xx = a * (1 + kc(1)*r^2 + kc(2)*r^4) + 2*kc(3)*a*b + kc(4)*(r^2 + 2*a^2);
34%yy = b * (1 + kc(1)*r^2 + kc(2)*r^4) + kc(3)*(r^2 + 2*b^2) + 2*kc(4)*a*b;
35%
36%The left terms correspond to radial distortion, the right terms correspond to tangential distortion
37%
38%Finally, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where:
39%
40%xxp = f(1)*(xx + alpha*yy) + c(1)
41%yyp = f(2)*yy + c(2)
42%
43%
44%NOTE: About 90 percent of the code takes care fo computing the Jacobian matrices
45%
46%
47%Important function called within that program:
48%
49%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector
50%
51%rigid_motion.m: Computes the rigid motion transformation of a given structure
52
53
54if nargin < 7,
55 alpha = 0;
56 if nargin < 6,
57 k = zeros(4,1);
58 if nargin < 5,
59 c = zeros(2,1);
60 if nargin < 4,
61 f = ones(2,1);
62 if nargin < 3,
63 T = zeros(3,1);
64 if nargin < 2,
65 om = zeros(3,1);
66 if nargin < 1,
67 error('Need at least a 3D structure to project (in project_points.m)');
68 return;
69 end;
70 end;
71 end;
72 end;
73 end;
74 end;
75end;
76
77
78[m,n] = size(X);
79
80[Y,dYdom,dYdT] = rigid_motion(X,om,T);
81
82
83inv_Z = 1./Y(3,:);
84
85x = (Y(1:2,:) .* (ones(2,1) * inv_Z)) ;
86
87
88bb = (-x(1,:) .* inv_Z)'*ones(1,3);
89cc = (-x(2,:) .* inv_Z)'*ones(1,3);
90
91
92dxdom = zeros(2*n,3);
93dxdom(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(1:3:end,:) + bb .* dYdom(3:3:end,:);
94dxdom(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdom(2:3:end,:) + cc .* dYdom(3:3:end,:);
95
96dxdT = zeros(2*n,3);
97dxdT(1:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(1:3:end,:) + bb .* dYdT(3:3:end,:);
98dxdT(2:2:end,:) = ((inv_Z')*ones(1,3)) .* dYdT(2:3:end,:) + cc .* dYdT(3:3:end,:);
99
100
101% Add distortion:
102
103r2 = x(1,:).^2 + x(2,:).^2;
104
105
106
107dr2dom = 2*((x(1,:)')*ones(1,3)) .* dxdom(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdom(2:2:end,:);
108dr2dT = 2*((x(1,:)')*ones(1,3)) .* dxdT(1:2:end,:) + 2*((x(2,:)')*ones(1,3)) .* dxdT(2:2:end,:);
109
110
111r4 = r2.^2;
112
113dr4dom = 2*((r2')*ones(1,3)) .* dr2dom;
114dr4dT = 2*((r2')*ones(1,3)) .* dr2dT;
115
116
117% Radial distortion:
118
119cdist = 1 + k(1) * r2 + k(2) * r4;
120
121dcdistdom = k(1) * dr2dom + k(2) * dr4dom;
122dcdistdT = k(1) * dr2dT+ k(2) * dr4dT;
123dcdistdk = [ r2' r4' zeros(n,2)];
124
125
126xd1 = x .* (ones(2,1)*cdist);
127
128dxd1dom = zeros(2*n,3);
129dxd1dom(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdom;
130dxd1dom(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdom;
131coeff = (reshape([cdist;cdist],2*n,1)*ones(1,3));
132dxd1dom = dxd1dom + coeff.* dxdom;
133
134dxd1dT = zeros(2*n,3);
135dxd1dT(1:2:end,:) = (x(1,:)'*ones(1,3)) .* dcdistdT;
136dxd1dT(2:2:end,:) = (x(2,:)'*ones(1,3)) .* dcdistdT;
137dxd1dT = dxd1dT + coeff.* dxdT;
138
139dxd1dk = zeros(2*n,4);
140dxd1dk(1:2:end,:) = (x(1,:)'*ones(1,4)) .* dcdistdk;
141dxd1dk(2:2:end,:) = (x(2,:)'*ones(1,4)) .* dcdistdk;
142
143
144
145% tangential distortion:
146
147a1 = 2.*x(1,:).*x(2,:);
148a2 = r2 + 2*x(1,:).^2;
149a3 = r2 + 2*x(2,:).^2;
150
151delta_x = [k(3)*a1 + k(4)*a2 ;
152 k(3) * a3 + k(4)*a1];
153
154
155ddelta_xdx = zeros(2*n,2*n);
156aa = (2*k(3)*x(2,:)+6*k(4)*x(1,:))'*ones(1,3);
157bb = (2*k(3)*x(1,:)+2*k(4)*x(2,:))'*ones(1,3);
158cc = (6*k(3)*x(2,:)+2*k(4)*x(1,:))'*ones(1,3);
159
160ddelta_xdom = zeros(2*n,3);
161ddelta_xdom(1:2:end,:) = aa .* dxdom(1:2:end,:) + bb .* dxdom(2:2:end,:);
162ddelta_xdom(2:2:end,:) = bb .* dxdom(1:2:end,:) + cc .* dxdom(2:2:end,:);
163
164ddelta_xdT = zeros(2*n,3);
165ddelta_xdT(1:2:end,:) = aa .* dxdT(1:2:end,:) + bb .* dxdT(2:2:end,:);
166ddelta_xdT(2:2:end,:) = bb .* dxdT(1:2:end,:) + cc .* dxdT(2:2:end,:);
167
168ddelta_xdk = zeros(2*n,4);
169ddelta_xdk(1:2:end,3) = a1';
170ddelta_xdk(1:2:end,4) = a2';
171ddelta_xdk(2:2:end,3) = a3';
172ddelta_xdk(2:2:end,4) = a1';
173
174
175
176xd2 = xd1 + delta_x;
177
178dxd2dom = dxd1dom + ddelta_xdom ;
179dxd2dT = dxd1dT + ddelta_xdT;
180dxd2dk = dxd1dk + ddelta_xdk ;
181
182
183% Add Skew:
184
185xd3 = [xd2(1,:) + alpha*xd2(2,:);xd2(2,:)];
186
187% Compute: dxd3dom, dxd3dT, dxd3dk, dxd3dalpha
188
189dxd3dom = zeros(2*n,3);
190dxd3dom(1:2:2*n,:) = dxd2dom(1:2:2*n,:) + alpha*dxd2dom(2:2:2*n,:);
191dxd3dom(2:2:2*n,:) = dxd2dom(2:2:2*n,:);
192dxd3dT = zeros(2*n,3);
193dxd3dT(1:2:2*n,:) = dxd2dT(1:2:2*n,:) + alpha*dxd2dT(2:2:2*n,:);
194dxd3dT(2:2:2*n,:) = dxd2dT(2:2:2*n,:);
195dxd3dk = zeros(2*n,4);
196dxd3dk(1:2:2*n,:) = dxd2dk(1:2:2*n,:) + alpha*dxd2dk(2:2:2*n,:);
197dxd3dk(2:2:2*n,:) = dxd2dk(2:2:2*n,:);
198dxd3dalpha = zeros(2*n,1);
199dxd3dalpha(1:2:2*n,:) = xd2(2,:)';
200
201
202
203% Pixel coordinates:
204
205xp = xd3 .* (f * ones(1,n)) + c*ones(1,n);
206
207coeff = reshape(f*ones(1,n),2*n,1);
208
209dxpdom = (coeff*ones(1,3)) .* dxd3dom;
210dxpdT = (coeff*ones(1,3)) .* dxd3dT;
211dxpdk = (coeff*ones(1,4)) .* dxd3dk;
212dxpdalpha = (coeff) .* dxd3dalpha;
213
214dxpdf = zeros(2*n,2);
215dxpdf(1:2:end,1) = xd2(1,:)';
216dxpdf(2:2:end,2) = xd2(2,:)';
217
218dxpdc = zeros(2*n,2);
219dxpdc(1:2:end,1) = ones(n,1);
220dxpdc(2:2:end,2) = ones(n,1);
221
222
223return;
224
225% Test of the Jacobians:
226
227n = 10;
228
229X = 10*randn(3,n);
230om = randn(3,1);
231T = [10*randn(2,1);40];
232f = 1000*rand(2,1);
233c = 1000*randn(2,1);
234k = 0.5*randn(4,1);
235alpha = 0.01*randn(1,1);
236
237[x,dxdom,dxdT,dxdf,dxdc,dxdk,dxdalpha] = project_points2(X,om,T,f,c,k,alpha);
238
239
240% Test on om: NOT OK
241
242dom = 0.000000001 * norm(om)*randn(3,1);
243om2 = om + dom;
244
245[x2] = project_points2(X,om2,T,f,c,k,alpha);
246
247x_pred = x + reshape(dxdom * dom,2,n);
248
249
250norm(x2-x)/norm(x2 - x_pred)
251
252
253% Test on T: OK!!
254
255dT = 0.0001 * norm(T)*randn(3,1);
256T2 = T + dT;
257
258[x2] = project_points2(X,om,T2,f,c,k,alpha);
259
260x_pred = x + reshape(dxdT * dT,2,n);
261
262
263norm(x2-x)/norm(x2 - x_pred)
264
265
266
267% Test on f: OK!!
268
269df = 0.001 * norm(f)*randn(2,1);
270f2 = f + df;
271
272[x2] = project_points2(X,om,T,f2,c,k,alpha);
273
274x_pred = x + reshape(dxdf * df,2,n);
275
276
277norm(x2-x)/norm(x2 - x_pred)
278
279
280% Test on c: OK!!
281
282dc = 0.01 * norm(c)*randn(2,1);
283c2 = c + dc;
284
285[x2] = project_points2(X,om,T,f,c2,k,alpha);
286
287x_pred = x + reshape(dxdc * dc,2,n);
288
289norm(x2-x)/norm(x2 - x_pred)
290
291% Test on k: OK!!
292
293dk = 0.001 * norm(k)*randn(4,1);
294k2 = k + dk;
295
296[x2] = project_points2(X,om,T,f,c,k2,alpha);
297
298x_pred = x + reshape(dxdk * dk,2,n);
299
300norm(x2-x)/norm(x2 - x_pred)
301
302
303% Test on alpha: OK!!
304
305dalpha = 0.001 * norm(k)*randn(1,1);
306alpha2 = alpha + dalpha;
307
308[x2] = project_points2(X,om,T,f,c,k,alpha2);
309
310x_pred = x + reshape(dxdalpha * dalpha,2,n);
311
312norm(x2-x)/norm(x2 - x_pred)
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m
new file mode 100755
index 0000000..561a7d0
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projectedGrid.m
@@ -0,0 +1,24 @@
1function [XX,H] = projectedGrid ( P1, P2, P3, P4 , nx, ny);
2
3% new formalism using homographies
4
5a00 = [P1;1];
6a10 = [P2;1];
7a11 = [P3;1];
8a01 = [P4;1];
9
10% Compute the planart collineation:
11
12[H] = compute_collineation (a00, a10, a11, a01);
13
14
15% Build the grid using the planar collineation:
16
17x_l = ((0:(nx-1))'*ones(1,ny))/(nx-1);
18y_l = (ones(nx,1)*(0:(ny-1)))/(ny-1);
19
20pts = [x_l(:) y_l(:) ones(nx*ny,1)]';
21
22XX = H*pts;
23
24XX = XX(1:2,:) ./ (ones(2,1)*XX(3,:));
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m
new file mode 100755
index 0000000..bb4ef86
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/projector_calib.m
@@ -0,0 +1,258 @@
1%%% This code is an additional code that helps doing projector calibration in 3D scanning setup.
2%%% This is not a useful code for anyone else but me.
3%%% I included it in the toolbox for illustration only.
4
5
6load camera_results;
7
8
9proj_name = input('Basename projector calibration images (without number nor suffix): ','s');
10
11
12i = 1;
13
14while (i <= n_ima), % & (~no_image_file),
15
16 if active_images(i),
17
18 %fprintf(1,'Loading image %d...\n',i);
19
20 if ~type_numbering,
21 number_ext = num2str(image_numbers(i));
22 else
23 number_ext = sprintf(['%.' num2str(N_slots) 'd'],image_numbers(i));
24 end;
25
26 ima_namep = [proj_name number_ext 'p.' format_image];
27 ima_namen = [proj_name number_ext 'n.' format_image];
28
29 if i == ind_active(1),
30 fprintf(1,'Loading image ');
31 end;
32
33 fprintf(1,'%d...',i);
34
35 if format_image(1) == 'p',
36 if format_image(2) == 'p',
37 Ip = double(loadppm(ima_namep));
38 In = double(loadppm(ima_namen));
39 else
40 Ip = double(loadpgm(ima_namep));
41 In = double(loadpgm(ima_namen));
42 end;
43 else
44 if format_image(1) == 'r',
45 Ip = readras(ima_namep);
46 In = readras(ima_namen);
47 else
48 Ip = double(imread(ima_namep));
49 In = double(imread(ima_namen));
50 end;
51 end;
52
53
54 if size(Ip,3)>1,
55 Ip = Ip(:,:,2);
56 In = In(:,:,2);
57 end;
58
59 eval(['Ip_' num2str(i) ' = Ip;']);
60 eval(['In_' num2str(i) ' = In;']);
61
62 end;
63
64 i = i+1;
65
66end;
67
68
69fprintf(1,'\nExtraction of the grid corners on the image\n');
70
71disp('Window size for corner finder (wintx and winty):');
72wintx = input('wintx ([] = 5) = ');
73if isempty(wintx), wintx = 5; end;
74wintx = round(wintx);
75winty = input('winty ([] = 5) = ');
76if isempty(winty), winty = 5; end;
77winty = round(winty);
78fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1);
79
80
81disp('The projector you are using is the DLP or Intel');
82nx = 800;
83ny = 600;
84
85dX = input('Size dX in x of the squares (in pixels) [50] = ');
86dY = input('Size dY in y of the squares (in pixels) [50] = ');
87
88if isempty(dX), dX=50; end;
89if isempty(dY), dY=50; end;
90
91dXoff = input('Position in x of your reference (in pixels) [399.5] = ');
92dYoff = input('Position in y of your reference (in pixels) [299.5] = ');
93
94if isempty(dXoff), dXoff=399.5; end;
95if isempty(dYoff), dYoff=299.5; end;
96
97end;
98
99
100
101for kk = ind_active,
102
103 eval(['Ip = Ip_' num2str(kk) ';']);
104 eval(['In = In_' num2str(kk) ';']);
105
106 [x,X,n_sq_x,n_sq_y,ind_orig,ind_x,ind_y] = extract_grid(In,wintx,winty,fc,cc,kc,dX,dY);
107 xproj = x;
108
109 Np_proj = size(x,2);
110
111 figure(2);
112 image(Ip);
113 hold on;
114 plot(xproj(1,:)+1,xproj(2,:)+1,'r+');
115 title('Click on your reference point');
116 xlabel('Xc (in camera frame)');
117 ylabel('Yc (in camera frame)');
118 hold off;
119
120 disp('Click on your reference point...');
121
122 [xr,yr] = ginput2(1);
123
124 err = sqrt(sum((xproj - [xr;yr]*ones(1,Np_proj)).^2));
125 ind_ref = find(err == min(err));
126
127 ref_pt = xproj(:,ind_ref);
128
129
130 figure(2);
131 hold on;
132 plot(ref_pt(1)+1,ref_pt(2)+1,'go'); hold off;
133
134
135 nn = floor(ind_ref/(n_sq_x+1));
136 off_x = ind_ref - nn*(n_sq_x+1) - 1;
137 off_y = n_sq_y - nn;
138
139
140 xprojn = xproj - cc * ones(1,Np_proj);
141 xprojn = xprojn ./ (fc * ones(1,Np_proj));
142 xprojn = comp_distortion(xprojn,kc);
143
144 eval(['Rc = Rc_' num2str(kk) ';']);
145 eval(['Tc = Tc_' num2str(kk) ';']);
146
147 Zc = ((Rc(:,3)'*Tc) * (1./(Rc(:,3)' * [xprojn; ones(1,Np_proj)])));
148 Xcp = (ones(3,1)*Zc) .* [xprojn; ones(1,Np_proj)]; % % in the camera frame
149 %Xproj = Rc'* Xcp - (Rc'*Tc)*ones(1,Np); % in the object frame !!! it works!
150 %Xproj(3,:) = zeros(1,Np);
151
152 eval(['X_proj_' num2str(kk) ' = Xcp;']); % coordinates of the points in the
153
154 x_proj = X(1:2,:) + ([dXoff - dX * off_x ; dYoff - dY * off_y]*ones(1,Np_proj));
155
156 eval(['x_proj_' num2str(kk) ' = x_proj;']); % coordinates of the points in the
157
158end;
159
160
161
162X_proj = [];
163x_proj = [];
164
165for kk = ind_active,
166 eval(['X_proj = [X_proj X_proj_' num2str(kk) '];']);
167 eval(['x_proj = [x_proj x_proj_' num2str(kk) '];']);
168end;
169
170
171%Save camera parameters:
172fc_save = fc;
173cc_save = cc;
174kc_save = kc;
175
176omc_1_save = omc_1;
177Rc_1_save = Rc_1;
178Tc_1_save = Tc_1;
179
180
181% Get started to calibrate projector:
182clear fc cc kc
183
184n_ima = 1;
185X_1 = X_proj;
186x_1 = x_proj;
187
188
189% Image size: (may or may not be available)
190
191nx = 800;
192ny = 600;
193
194% No calibration image is available (only the corner coordinates)
195
196no_image = 1;
197
198% Set the toolbox not to prompt the user (choose default values)
199
200dont_ask = 1;
201
202% Do not estimate distortion:
203
204est_dist = [0;0;0;0];
205est_dist = ones(4,1);
206
207center_optim = 1;
208
209% Run the main calibration routine:
210
211go_calib_optim_iter;
212
213% Shows the extrinsic parameters:
214
215dX = 3;
216dY = 3;
217
218ext_calib;
219
220% Reprojection on the original images:
221
222reproject_calib;
223
224
225
226
227%----------------------- Retrieve results:
228
229% Intrinsic:
230
231% Projector:
232fp = fc;
233cp = cc;
234kp = kc;
235
236% Camera:
237fc = fc_save;
238cc = cc_save;
239kc = kc_save;
240
241% Extrinsic:
242
243% Relative position of projector and camera:
244T = Tc_1;
245om = omc_1;
246R = rodrigues(om);
247
248% Relative prosition of camera wrt world:
249omc = omc_1_save;
250Rc = Rc_1_save;
251Tc = Tc_1_save;
252
253% relative position of projector wrt world:
254Rp = R*Rc;
255omp = rodrigues(Rp);
256Tp = T + R*Tc;
257
258eval(['save calib_cam_proj R om T fc fp cc cp kc kp Rc Rp Tc Tp']);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m
new file mode 100755
index 0000000..fc1820b
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/readras.m
@@ -0,0 +1,87 @@
1function [X, map] = readras(filename, ys, ye, xs, xe);
2%READRAS Read an image file in sun raster format.
3% READRAS('imagefile.ras') reads a "sun.raster" image file.
4% [X, map] = READRAS('imagefile.ras') returns both the image and a
5% color map, so that
6% [X, map] = readras('imagefile.ras');
7% image(X)
8% colormap(map)
9% axis('equal')
10% will display the result with the proper colors.
11% NOTE: readras cannot deal with complicated color maps.
12% In fact, Matlab doesn't quite allow to work with colormaps
13% with more than 64 entries.
14%
15
16%%
17%% (C) Thomas K. Leung 3/30/93.
18%% California Institute of Technology.
19%% Modified by Andrea Mennucci to deal with color images
20%%
21
22% PC and UNIX version of readras - Jean-Yves Bouguet - Dec. 1998
23
24dot = max(find(filename == '.'));
25suffix = filename(dot+1:dot+3);
26
27if(strcmp(suffix, 'ras')) % raster file format %
28 fp = fopen(filename, 'rb');
29 if(fp<0) error(['Cannot open ' filename '.']), end
30
31 %Read and crack the 32-byte header
32 fseek(fp, 4, -1);
33
34 width = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar');
35
36 height = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar');
37
38 depth = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar');
39
40 length = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar');
41
42 type = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar');
43
44 maptype = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar');
45
46 maplen = 2^24 * fread(fp, 1, 'uchar') + 2^16 * fread(fp, 1, 'uchar') + 2^8 * fread(fp, 1, 'uchar') + fread(fp, 1, 'uchar');
47
48 maplen = maplen / 3;
49
50 if maptype == 2 % RMT_RAW
51 map = fread(fp, [maplen, 3], 'uchar')/255;
52% if maplen<64, map=[map',zeros(3,64-maplen)]';maplen=64; end;
53 elseif maptype == 1 % RMT_EQUAL_RGB
54 map(:,1) = fread(fp, [maplen], 'uchar');
55 map(:,2) = fread(fp, [maplen], 'uchar');
56 map(:,3) = fread(fp, [maplen], 'uchar');
57 %maxmap = max(max(map));
58 map = map/255;
59 if maplen<64, map=[map',zeros(3,64-maplen)]'; maplen=64; end;
60 else % RMT_NONE
61 map = [];
62 end
63% if maplen>64,
64% map=[map',zeros(3,256-maplen)]';
65% end;
66
67 % Read the image
68
69 if rem(width,2) == 1
70 Xt = fread(fp, [width+1, height], 'uchar');
71 X = Xt(1:width, :)';
72 else
73 Xt = fread(fp, [width, height], 'uchar');
74 X = Xt';
75 end
76 X = X + 1;
77 fclose(fp);
78else
79 error('Image file name must end in either ''ras'' or ''rast''.');
80end
81
82
83if nargin == 5
84
85 X = X(ys:ye, xs:xe);
86
87end \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m
new file mode 100755
index 0000000..0909c69
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/recomp_corner_calib.m
@@ -0,0 +1,119 @@
1% Re-select te corners after calibration
2
3if ~exist('n_ima')|~exist('fc'),
4 fprintf(1,'No calibration data available.\n');
5 return;
6end;
7
8check_active_images;
9
10flag = 0;
11for kk = ind_active,
12 if ~exist(['y_' num2str(kk)]),
13 flag = 1;
14 else
15 eval(['ykk = y_' num2str(kk) ';']);
16 if isnan(ykk(1,1)),
17 flag = 1;
18 end;
19 end;
20end;
21
22if flag,
23 fprintf(1,'Need to calibrate once before before recomputing image corners. Maybe need to load Calib_Results.mat file.\n');
24 return;
25end;
26
27
28if ~exist(['I_' num2str(ind_active(1))]),
29 n_ima_save = n_ima;
30 active_images_save = active_images;
31 ima_read_calib;
32 n_ima = n_ima_save;
33 active_images = active_images_save;
34 check_active_images;
35 if no_image_file,
36 disp('Cannot extract corners without images');
37 return;
38 end;
39end;
40
41fprintf(1,'\nRe-extraction of the grid corners on the images (after first calibration)\n');
42
43disp('Window size for corner finder (wintx and winty):');
44wintx = input('wintx ([] = 5) = ');
45if isempty(wintx), wintx = 5; end;
46wintx = round(wintx);
47winty = input('winty ([] = 5) = ');
48if isempty(winty), winty = 5; end;
49winty = round(winty);
50
51fprintf(1,'Window size = %dx%d\n',2*wintx+1,2*winty+1);
52
53ima_numbers = input('Number(s) of image(s) to process ([] = all images) = ');
54
55if isempty(ima_numbers),
56 ima_proc = 1:n_ima;
57else
58 ima_proc = ima_numbers;
59end;
60
61q_auto = input('Use the projection of 3D grid or manual click ([]=auto, other=manual): ');
62
63fprintf(1,'Processing image ');
64
65for kk = ima_proc;
66
67 if active_images(kk),
68
69 fprintf(1,'%d...',kk);
70
71 if isempty(q_auto),
72
73 eval(['I = I_' num2str(kk) ';']);
74
75 eval(['y = y_' num2str(kk) ';']);
76
77 xc = cornerfinder(y+1,I,winty,wintx); % the four corners
78
79 eval(['wintx_' num2str(kk) ' = wintx;']);
80 eval(['winty_' num2str(kk) ' = winty;']);
81
82 eval(['x_' num2str(kk) '= xc - 1;']);
83
84 else
85
86 fprintf(1,'\n');
87
88 click_ima_calib;
89
90 end;
91
92 else
93
94 if ~exist(['omc_' num2str(kk)]),
95
96 eval(['dX_' num2str(kk) ' = NaN;']);
97 eval(['dY_' num2str(kk) ' = NaN;']);
98
99 eval(['wintx_' num2str(kk) ' = NaN;']);
100 eval(['winty_' num2str(kk) ' = NaN;']);
101
102 eval(['x_' num2str(kk) ' = NaN*ones(2,1);']);
103 eval(['X_' num2str(kk) ' = NaN*ones(3,1);']);
104
105 eval(['n_sq_x_' num2str(kk) ' = NaN;']);
106 eval(['n_sq_y_' num2str(kk) ' = NaN;']);
107
108 end;
109
110 end;
111
112
113end;
114
115% Recompute the error:
116
117comp_error_calib;
118
119fprintf(1,'\ndone\n'); \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m
new file mode 100755
index 0000000..ccac7a5
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rect.m
@@ -0,0 +1,127 @@
1function [Irec] = rect(I,R,f,c,k,alpha,KK_new);
2
3
4if nargin < 5,
5 k = 0;
6 if nargin < 4,
7 c = [0;0];
8 if nargin < 3,
9 f = [1;1];
10 if nargin < 2,
11 R = eye(3);
12 if nargin < 1,
13 error('ERROR: Need an image to rectify');
14 break;
15 end;
16 end;
17 end;
18 end;
19end;
20
21
22if nargin < 7,
23 if nargin < 6,
24 KK_new = [f(1) 0 c(1);0 f(2) c(2);0 0 1];
25 else
26 KK_new = alpha; % the 6th argument is actually KK_new
27 end;
28 alpha = 0;
29end;
30
31
32
33% Note: R is the motion of the points in space
34% So: X2 = R*X where X: coord in the old reference frame, X2: coord in the new ref frame.
35
36
37if ~exist('KK_new'),
38 KK_new = [f(1) alpha_c*fc(1) c(1);0 f(2) c(2);0 0 1];
39end;
40
41
42[nr,nc] = size(I);
43
44Irec = 255*ones(nr,nc);
45
46[mx,my] = meshgrid(1:nc, 1:nr);
47px = reshape(mx',nc*nr,1);
48py = reshape(my',nc*nr,1);
49
50rays = inv(KK_new)*[(px - 1)';(py - 1)';ones(1,length(px))];
51
52
53% Rotation: (or affine transformation):
54
55rays2 = R'*rays;
56
57x = [rays2(1,:)./rays2(3,:);rays2(2,:)./rays2(3,:)];
58
59
60% Add distortion:
61
62k1 = k(1);
63k2 = k(2);
64
65p1 = k(3);
66p2 = k(4);
67
68r_2 = sum(x.^2);
69
70delta_x = [2*p1*x(1,:).*x(2,:) + p2*(r_2 + 2*x(1,:).^2) ;
71 p1 * (r_2 + 2*x(2,:).^2)+2*p2*x(1,:).*x(2,:)];
72
73xd = (ones(2,1)*( 1 + k1 * r_2 + k2 * r_2.^2)) .* x + delta_x;
74
75
76% Reconvert in pixels:
77
78px2 = f(1)*(xd(1,:)+alpha_c*xd(2,:))+c(1);
79py2 = f(2)*xd(2,:)+c(2);
80
81
82% Interpolate between the closest pixels:
83
84px_0 = floor(px2);
85px_1 = px_0 + 1;
86alpha_x = px2 - px_0;
87
88py_0 = floor(py2);
89py_1 = py_0 + 1;
90alpha_y = py2 - py_0;
91
92good_points = find((px_0 >= 0) & (px_1 <= (nc-1)) & (py_0 >= 0) & (py_1 <= (nr-1)));
93
94I_lu = I(px_0(good_points) * nr + py_0(good_points) + 1);
95I_ru = I(px_1(good_points) * nr + py_0(good_points) + 1);
96I_ld = I(px_0(good_points) * nr + py_1(good_points) + 1);
97I_rd = I(px_1(good_points) * nr + py_1(good_points) + 1);
98
99
100I_interp = (1 - alpha_y(good_points)).*((1 - alpha_x(good_points)).* I_lu + alpha_x(good_points) .* I_ru) + alpha_y(good_points) .* ((1 - alpha_x(good_points)).* I_ld + alpha_x(good_points) .* I_rd);
101
102
103Irec((px(good_points)-1)*nr + py(good_points)) = I_interp;
104
105
106
107return;
108
109
110% Convert in indices:
111
112fact = 3;
113
114[XX,YY]= meshgrid(1:nc,1:nr);
115[XXi,YYi]= meshgrid(1:1/fact:nc,1:1/fact:nr);
116
117%tic;
118Iinterp = interp2(XX,YY,I,XXi,YYi);
119%toc
120
121[nri,nci] = size(Iinterp);
122
123
124ind_col = round(fact*(f(1)*xd(1,:)+c(1)))+1;
125ind_row = round(fact*(f(2)*xd(2,:)+c(2)))+1;
126
127good_points = find((ind_col >=1)&(ind_col<=nci)&(ind_row >=1)& (ind_row <=nri));
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m
new file mode 100755
index 0000000..d3ad3d2
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/reproject_calib.m
@@ -0,0 +1,121 @@
1%%%%%%%%%%%%%%%%%%%% REPROJECT ON THE IMAGES %%%%%%%%%%%%%%%%%%%%%%%%
2
3if ~exist('n_ima')|~exist('fc'),
4 fprintf(1,'No calibration data available.\n');
5 return;
6end;
7
8if ~exist('no_image'),
9 no_image = 0;
10end;
11
12if ~exist('nx')&~exist('ny'),
13 fprintf(1,'WARNING: No image size (nx,ny) available. Setting nx=640 and ny=480\n');
14 nx = 640;
15 ny = 480;
16end;
17
18
19check_active_images;
20
21
22% Color code for each image:
23
24colors = 'brgkcm';
25
26% Reproject the patterns on the images, and compute the pixel errors:
27
28% Reload the images if necessary
29
30if ~exist(['omc_' num2str(ind_active(1)) ]),
31 fprintf(1,'Need to calibrate before showing image reprojection. Maybe need to load Calib_Results.mat file.\n');
32 return;
33end;
34
35if ~no_image,
36 if ~exist(['I_' num2str(ind_active(1)) ]'),
37 n_ima_save = n_ima;
38 active_images_save = active_images;
39 ima_read_calib;
40 n_ima = n_ima_save;
41 active_images = active_images_save;
42 check_active_images;
43 if no_image_file,
44 fprintf(1,'WARNING: Do not show the original images\n'); %return;
45 end;
46 end;
47else
48 no_image_file = 1;
49end;
50
51
52if ~exist('dont_ask'),
53 dont_ask = 0;
54end;
55
56
57if ~dont_ask,
58 ima_numbers = input('Number(s) of image(s) to show ([] = all images) = ');
59else
60 ima_numbers = [];
61end;
62
63
64if isempty(ima_numbers),
65 ima_proc = 1:n_ima;
66else
67 ima_proc = ima_numbers;
68end;
69
70
71figure(5);
72for kk = ima_proc, %1:n_ima,
73 if exist(['y_' num2str(kk)]),
74 if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']),
75 eval(['plot(ex_' num2str(kk) '(1,:),ex_' num2str(kk) '(2,:),''' colors(rem(kk-1,6)+1) '+'');']);
76 hold on;
77 end;
78 end;
79end;
80hold off;
81axis('equal');
82title('Reprojection error (in pixel)');
83xlabel('x');
84ylabel('y');
85drawnow;
86
87set(5,'Name','error','NumberTitle','off');
88
89
90
91for kk = ima_proc,
92 if exist(['y_' num2str(kk)]),
93 if active_images(kk) & eval(['~isnan(y_' num2str(kk) '(1,1))']),
94
95 if exist(['I_' num2str(kk)]),
96 eval(['I = I_' num2str(kk) ';']);
97 else
98 I = 255*ones(ny,nx);
99 end;
100
101 figure(5+kk);
102 image(I); hold on;
103 colormap(gray(256));
104 title(['Image ' num2str(kk) ' - Image points (+) and reprojected grid points (o)']);
105 eval(['plot(x_' num2str(kk) '(1,:)+1,x_' num2str(kk) '(2,:)+1,''r+'');']);
106 eval(['plot(y_' num2str(kk) '(1,:)+1,y_' num2str(kk) '(2,:)+1,''' colors(rem(kk-1,6)+1) 'o'');']);
107 zoom on;
108 axis([1 nx 1 ny]);
109 hold off;
110 drawnow;
111
112 set(5+kk,'Name',num2str(kk),'NumberTitle','off');
113
114 end;
115 end;
116end;
117
118
119err_std = std(ex')';
120
121fprintf(1,'Pixel error: err = [%3.5f %3.5f] (all active images)\n\n',err_std);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m
new file mode 100755
index 0000000..473405c
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rigid_motion.m
@@ -0,0 +1,66 @@
1function [Y,dYdom,dYdT] = rigid_motion(X,om,T);
2
3%rigid_motion.m
4%
5%[Y,dYdom,dYdT] = rigid_motion(X,om,T)
6%
7%Computes the rigid motion transformation Y = R*X+T, where R = rodrigues(om).
8%
9%INPUT: X: 3D structure in the world coordinate frame (3xN matrix for N points)
10% (om,T): Rigid motion parameters between world coordinate frame and camera reference frame
11% om: rotation vector (3x1 vector); T: translation vector (3x1 vector)
12%
13%OUTPUT: Y: 3D coordinates of the structure points in the camera reference frame (3xN matrix for N points)
14% dYdom: Derivative of Y with respect to om ((3N)x3 matrix)
15% dYdT: Derivative of Y with respect to T ((3N)x3 matrix)
16%
17%Definitions:
18%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X)
19%The coordinate vector of P in the camera reference frame is: Y = R*X + T
20%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om);
21%
22%Important function called within that program:
23%
24%rodrigues.m: Computes the rotation matrix corresponding to a rotation vector
25
26
27
28if nargin < 3,
29 T = zeros(3,1);
30 if nargin < 2,
31 om = zeros(3,1);
32 if nargin < 1,
33 error('Need at least a 3D structure as input (in rigid_motion.m)');
34 return;
35 end;
36 end;
37end;
38
39
40[R,dRdom] = rodrigues(om);
41
42[m,n] = size(X);
43
44Y = R*X + T*ones(1,n);
45
46if nargout > 1,
47
48
49dYdR = zeros(3*n,9);
50dYdT = zeros(3*n,3);
51
52dYdR(1:3:end,1:3:end) = X';
53dYdR(2:3:end,2:3:end) = X';
54dYdR(3:3:end,3:3:end) = X';
55
56dYdT(1:3:end,1) = ones(n,1);
57dYdT(2:3:end,2) = ones(n,1);
58dYdT(3:3:end,3) = ones(n,1);
59
60dYdom = dYdR * dRdom;
61
62end;
63
64
65
66
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m
new file mode 100755
index 0000000..9d55337
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rodrigues.m
@@ -0,0 +1,217 @@
1function [out,dout]=rodrigues(in)
2
3% RODRIGUES Transform rotation matrix into rotation vector and viceversa.
4%
5% Sintax: [OUT]=RODRIGUES(IN)
6% If IN is a 3x3 rotation matrix then OUT is the
7% corresponding 3x1 rotation vector
8% if IN is a rotation 3-vector then OUT is the
9% corresponding 3x3 rotation matrix
10%
11
12%%
13%% Copyright (c) March 1993 -- Pietro Perona
14%% California Institute of Technology
15%%
16
17%% ALL CHECKED BY JEAN-YVES BOUGUET, October 1995.
18%% FOR ALL JACOBIAN MATRICES !!! LOOK AT THE TEST AT THE END !!
19
20%% BUG when norm(om)=pi fixed -- April 6th, 1997;
21%% Jean-Yves Bouguet
22
23
24[m,n] = size(in);
25%bigeps = 10e+4*eps;
26bigeps = 10e+20*eps;
27
28if ((m==1) & (n==3)) | ((m==3) & (n==1)) %% it is a rotation vector
29 theta = norm(in);
30 if theta < eps
31 R = eye(3);
32
33 %if nargout > 1,
34
35 dRdin = [0 0 0;
36 0 0 1;
37 0 -1 0;
38 0 0 -1;
39 0 0 0;
40 1 0 0;
41 0 1 0;
42 -1 0 0;
43 0 0 0];
44
45 %end;
46
47 else
48 if n==length(in) in=in'; end; %% make it a column vec. if necess.
49
50 %m3 = [in,theta]
51
52 dm3din = [eye(3);in'/theta];
53
54 omega = in/theta;
55
56 %m2 = [omega;theta]
57
58 dm2dm3 = [eye(3)/theta -in/theta^2; zeros(1,3) 1];
59
60 alpha = cos(theta);
61 beta = sin(theta);
62 gamma = 1-cos(theta);
63 omegav=[[0 -omega(3) omega(2)];[omega(3) 0 -omega(1)];[-omega(2) omega(1) 0 ]];
64 A = omega*omega';
65
66 %m1 = [alpha;beta;gamma;omegav;A];
67
68 dm1dm2 = zeros(21,4);
69 dm1dm2(1,4) = -sin(theta);
70 dm1dm2(2,4) = cos(theta);
71 dm1dm2(3,4) = sin(theta);
72 dm1dm2(4:12,1:3) = [0 0 0 0 0 1 0 -1 0;
73 0 0 -1 0 0 0 1 0 0;
74 0 1 0 -1 0 0 0 0 0]';
75
76 w1 = omega(1);
77 w2 = omega(2);
78 w3 = omega(3);
79
80 dm1dm2(13:21,1) = [2*w1;w2;w3;w2;0;0;w3;0;0];
81 dm1dm2(13: 21,2) = [0;w1;0;w1;2*w2;w3;0;w3;0];
82 dm1dm2(13:21,3) = [0;0;w1;0;0;w2;w1;w2;2*w3];
83
84 R = eye(3)*alpha + omegav*beta + A*gamma;
85
86 dRdm1 = zeros(9,21);
87
88 dRdm1([1 5 9],1) = ones(3,1);
89 dRdm1(:,2) = omegav(:);
90 dRdm1(:,4:12) = beta*eye(9);
91 dRdm1(:,3) = A(:);
92 dRdm1(:,13:21) = gamma*eye(9);
93
94 dRdin = dRdm1 * dm1dm2 * dm2dm3 * dm3din;
95
96
97 end;
98 out = R;
99 dout = dRdin;
100
101 %% it is prob. a rot matr.
102 elseif ((m==n) & (m==3) & (norm(in' * in - eye(3)) < bigeps)...
103 & (abs(det(in)-1) < bigeps))
104 R = in;
105
106
107
108 tr = (trace(R)-1)/2;
109 dtrdR = [1 0 0 0 1 0 0 0 1]/2;
110 theta = real(acos(tr));
111
112
113 if sin(theta) >= 1e-5,
114
115 dthetadtr = -1/sqrt(1-tr^2);
116
117 dthetadR = dthetadtr * dtrdR;
118 % var1 = [vth;theta];
119 vth = 1/(2*sin(theta));
120 dvthdtheta = -vth*cos(theta)/sin(theta);
121 dvar1dtheta = [dvthdtheta;1];
122
123 dvar1dR = dvar1dtheta * dthetadR;
124
125
126 om1 = [R(3,2)-R(2,3), R(1,3)-R(3,1), R(2,1)-R(1,2)]';
127
128 dom1dR = [0 0 0 0 0 1 0 -1 0;
129 0 0 -1 0 0 0 1 0 0;
130 0 1 0 -1 0 0 0 0 0];
131
132 % var = [om1;vth;theta];
133 dvardR = [dom1dR;dvar1dR];
134
135 % var2 = [om;theta];
136 om = vth*om1;
137 domdvar = [vth*eye(3) om1 zeros(3,1)];
138 dthetadvar = [0 0 0 0 1];
139 dvar2dvar = [domdvar;dthetadvar];
140
141
142 out = om*theta;
143 domegadvar2 = [theta*eye(3) om];
144
145 dout = domegadvar2 * dvar2dvar * dvardR;
146
147
148 else
149 if tr > 0; % case norm(om)=0;
150
151 out = [0 0 0]';
152
153 dout = [0 0 0 0 0 1/2 0 -1/2 0;
154 0 0 -1/2 0 0 0 1/2 0 0;
155 0 1/2 0 -1/2 0 0 0 0 0];
156 else % case norm(om)=pi; %% fixed April 6th
157
158
159 out = theta * (sqrt((diag(R)+1)/2).*[1;2*(R(1,2:3)>=0)'-1]);
160 %keyboard;
161
162 if nargout > 1,
163 fprintf(1,'WARNING!!!! Jacobian domdR undefined!!!\n');
164 dout = NaN*ones(3,9);
165 end;
166 end;
167 end;
168
169 else
170 error('Neither a rotation matrix nor a rotation vector were provided');
171 end;
172
173return;
174
175%% test of the Jacobians:
176
177%%%% TEST OF dRdom:
178om = randn(3,1);
179dom = randn(3,1)/1000000;
180
181[R1,dR1] = rodrigues(om);
182R2 = rodrigues(om+dom);
183
184R2a = R1 + reshape(dR1 * dom,3,3);
185
186gain = norm(R2 - R1)/norm(R2 - R2a)
187
188%%% TEST OF dOmdR:
189om = randn(3,1);
190R = rodrigues(om);
191dom = randn(3,1)/10000;
192dR = rodrigues(om+dom) - R;
193
194[omc,domdR] = rodrigues(R);
195[om2] = rodrigues(R+dR);
196
197om_app = omc + domdR*dR(:);
198
199gain = norm(om2 - omc)/norm(om2 - om_app)
200
201
202%%% OTHER BUG: (FIXED NOW!!!)
203
204omu = randn(3,1);
205omu = omu/norm(omu)
206om = pi*omu;
207[R,dR]= rodrigues(om);
208[om2] = rodrigues(R);
209[om om2]
210
211%%% NORMAL OPERATION
212
213om = randn(3,1);
214[R,dR]= rodrigues(om);
215[om2] = rodrigues(R);
216[om om2]
217
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m
new file mode 100755
index 0000000..87ee2fe
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/rotation.m
@@ -0,0 +1,23 @@
1function [] = rotation(st);
2
3if nargin < 1,
4 st= 1;
5end;
6
7
8fig = gcf;
9
10ax = gca;
11
12vv = get(ax,'view');
13
14az = vv(1);
15el = vv(2);
16
17for azi = az:-abs(st):az-360,
18
19 set(ax,'view',[azi el]);
20 figure(fig);
21 drawnow;
22
23end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m
new file mode 100755
index 0000000..095e17e
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/run_error_analysis.m
@@ -0,0 +1,65 @@
1%%% Program that launchs the complete
2
3for N_ima_active = 1:30,
4
5 error_analysis;
6
7end;
8
9
10
11return;
12
13
14f = [];
15f_std = [];
16
17c = [];
18c_std = [];
19
20k = [];
21k_std = [];
22
23NN = 30;
24
25for rr = 1:NN,
26
27 load(['Calib_Accuracies_' num2str(rr)]);
28
29 [m1,s1] = mean_std_robust(fc_list(1,:));
30 [m2,s2] = mean_std_robust(fc_list(2,:));
31
32 f = [f [m1;m2]];
33 f_std = [f_std [s1;s2]];
34
35 [m1,s1] = mean_std_robust(cc_list(1,:));
36 [m2,s2] = mean_std_robust(cc_list(2,:));
37
38 c = [c [m1;m2]];
39 c_std = [c_std [s1;s2]];
40
41 [m1,s1] = mean_std_robust(kc_list(1,:));
42 [m2,s2] = mean_std_robust(kc_list(2,:));
43 [m3,s3] = mean_std_robust(kc_list(3,:));
44 [m4,s4] = mean_std_robust(kc_list(4,:));
45
46 k = [k [m1;m2;m3;m4]];
47 k_std = [k_std [s1;s2;s3;s4]];
48
49end;
50
51figure(1);
52errorbar([1:NN;1:NN]',f',f_std');
53figure(2);
54errorbar([1:NN;1:NN]',c',c_std');
55figure(3);
56errorbar([1:NN;1:NN;1:NN;1:NN]',k',k_std');
57
58figure(4);
59semilogy(f_std');
60
61figure(5);
62semilogy(c_std');
63
64figure(6);
65semilogy(k_std');
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m
new file mode 100755
index 0000000..a176e39
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveinr.m
@@ -0,0 +1,46 @@
1%SAVEINR Write an INRIMAGE format file
2%
3% SAVEINR(filename, im)
4%
5% Saves the specified image array in a INRIA image format file.
6%
7% SEE ALSO: loadinr
8%
9% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab
10
11% Peter Corke 1996
12
13function saveinr(fname, im)
14
15 fid = fopen(fname, 'w');
16 [r,c] = size(im');
17
18 % build the header
19 hdr = [];
20 s = sprintf('#INRIMAGE-4#{\n');
21 hdr = [hdr s];
22 s = sprintf('XDIM=%d\n',c);
23 hdr = [hdr s];
24 s = sprintf('YDIM=%d\n',r);
25 hdr = [hdr s];
26 s = sprintf('ZDIM=1\n');
27 hdr = [hdr s];
28 s = sprintf('VDIM=1\n');
29 hdr = [hdr s];
30 s = sprintf('TYPE=float\n');
31 hdr = [hdr s];
32 s = sprintf('PIXSIZE=32\n');
33 hdr = [hdr s];
34 s = sprintf('SCALE=2**0\n');
35 hdr = [hdr s];
36 s = sprintf('CPU=sun\n#');
37 hdr = [hdr s];
38
39 % make it 256 bytes long and write it
40 hdr256 = zeros(1,256);
41 hdr256(1:length(hdr)) = hdr;
42 fwrite(fid, hdr256, 'uchar');
43
44 % now the binary data
45 fwrite(fid, im', 'float32');
46 fclose(fid)
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m
new file mode 100755
index 0000000..0cee75d
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/savepgm.m
@@ -0,0 +1,22 @@
1%SAVEPGM Write a PGM format file
2%
3% SAVEPGM(filename, im)
4%
5% Saves the specified image array in a binary (P5) format PGM image file.
6%
7% SEE ALSO: loadpgm
8%
9% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab
10
11
12% Peter Corke 1994
13
14function savepgm(fname, im)
15
16 fid = fopen(fname, 'w');
17 [r,c] = size(im');
18 fprintf(fid, 'P5\n');
19 fprintf(fid, '%d %d\n', r, c);
20 fprintf(fid, '255\n');
21 fwrite(fid, im', 'uchar');
22 fclose(fid);
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m
new file mode 100755
index 0000000..ece092b
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saveppm.m
@@ -0,0 +1,45 @@
1%SAVEPPM Write a PPM format file
2%
3% SAVEPPM(filename, I)
4%
5% Saves the specified red, green and blue planes in a binary (P6)
6% format PPM image file.
7%
8% SEE ALSO: loadppm
9%
10% Copyright (c) Peter Corke, 1999 Machine Vision Toolbox for Matlab
11
12
13% Peter Corke 1994
14
15function saveppm(fname, I)
16
17I = double(I);
18
19if size(I,3) == 1,
20 R = I;
21 G = I;
22 B = I;
23else
24 R = I(:,:,1);
25 G = I(:,:,2);
26 B = I(:,:,3);
27end;
28
29%keyboard;
30
31 fid = fopen(fname, 'w');
32 [r,c] = size(R');
33 fprintf(fid, 'P6\n');
34 fprintf(fid, '%d %d\n', r, c);
35 fprintf(fid, '255\n');
36 R = R';
37 G = G';
38 B = B';
39 im = [R(:) G(:) B(:)];
40 %im = reshape(im,r,c*3);
41 im = im';
42 %im = im(:);
43 fwrite(fid, im, 'uchar');
44 fclose(fid);
45
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m
new file mode 100755
index 0000000..3f98a8b
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/saving_calib.m
@@ -0,0 +1,95 @@
1
2if ~exist('n_ima')|~exist('fc'),
3 fprintf(1,'No calibration data available.\n');
4 return;
5end;
6
7check_active_images;
8
9if ~exist('solution_init'), solution_init = []; end;
10
11for kk = 1:n_ima,
12 if ~exist(['dX_' num2str(kk)]), eval(['dX_' num2str(kk) '= dX;']); end;
13 if ~exist(['dY_' num2str(kk)]), eval(['dY_' num2str(kk) '= dY;']); end;
14end;
15
16if ~exist('param_list'),
17 param_list = solution;
18end;
19
20if ~exist('wintx'),
21 wintx = [];
22 winty = [];
23end;
24
25if ~exist('dX_default'),
26 dX_default = [];
27 dY_default = [];
28end;
29
30if ~exist('alpha_c'),
31 alpha_c = 0;
32end;
33
34for kk = 1:n_ima,
35 if ~exist(['y_' num2str(kk)]),
36 eval(['y_' num2str(kk) ' = NaN*ones(2,1);']);
37 end;
38 if ~exist(['n_sq_x_' num2str(kk)]),
39 eval(['n_sq_x_' num2str(kk) ' = NaN;']);
40 eval(['n_sq_y_' num2str(kk) ' = NaN;']);
41 end;
42 if ~exist(['wintx_' num2str(kk)]),
43 eval(['wintx_' num2str(kk) ' = NaN;']);
44 eval(['winty_' num2str(kk) ' = NaN;']);
45 end;
46end;
47
48save_name = 'Calib_Results';
49
50if exist([ save_name '.mat'])==2,
51 disp('WARNING: File Calib_Results.mat already exists');
52 pfn = -1;
53 cont = 1;
54 while cont,
55 pfn = pfn + 1;
56 postfix = ['_old'num2str(pfn)];
57 save_name = [ 'Calib_Results' postfix];
58 cont = (exist([ save_name '.mat'])==2);
59 end;
60 copyfile('Calib_Results.mat',[save_name '.mat']);
61 disp(['Copying the current Calib_Results.mat file to ' save_name '.mat']);
62end;
63
64
65save_name = 'Calib_Results';
66
67if exist('calib_name'),
68
69 fprintf(1,['\nSaving calibration results under ' save_name '.mat\n']);
70
71 string_save = ['save ' save_name ' center_optim param_list active_images ind_active center_optim est_alpha est_dist fc kc cc alpha_c ex x y solution solution_init wintx winty n_ima type_numbering N_slots small_calib_image first_num image_numbers format_image calib_name Hcal Wcal nx ny map dX_default dY_default KK inv_KK dX dY'];
72
73 for kk = 1:n_ima,
74 string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' y_' num2str(kk) ' ex_' num2str(kk) ' omc_' num2str(kk) ' Rc_' num2str(kk) ' Tc_' num2str(kk) ' H_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)];
75 end;
76
77else
78
79 fprintf(1,['\nSaving calibration results under ' save_name '.mat (no image version)\n']);
80
81 string_save = ['save ' save_name ' center_optim param_list active_images ind_active center_optim est_alpha est_dist fc kc cc alpha_c ex x y solution solution_init wintx winty n_ima nx ny dX_default dY_default KK inv_KK dX dY'];
82
83 for kk = 1:n_ima,
84 string_save = [string_save ' X_' num2str(kk) ' x_' num2str(kk) ' y_' num2str(kk) ' ex_' num2str(kk) ' omc_' num2str(kk) ' Rc_' num2str(kk) ' Tc_' num2str(kk) ' H_' num2str(kk) ' n_sq_x_' num2str(kk) ' n_sq_y_' num2str(kk) ' wintx_' num2str(kk) ' winty_' num2str(kk) ' dX_' num2str(kk) ' dY_' num2str(kk)];
85 end;
86
87end;
88
89
90
91%fprintf(1,'To load later click on Load\n');
92
93eval(string_save);
94
95fprintf(1,'done\n'); \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m
new file mode 100755
index 0000000..c5e5430
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/script_fit_distortion.m
@@ -0,0 +1,39 @@
1
2 satis_distort = 0;
3
4 disp(['Estimated focal: ' num2str(f_g) ' pixels']);
5
6 while ~satis_distort,
7
8 k_g = input('Guess for distortion factor kc ([]=0): ');
9
10 if isempty(k_g), k_g = 0; end;
11
12 xy_corners_undist = comp_distortion2([x' - c_g(1);y'-c_g(2)]/f_g,k_g);
13
14 xu = xy_corners_undist(1,:)';
15 yu = xy_corners_undist(2,:)';
16
17 [XXu] = projectedGrid ( [xu(1);yu(1)], [xu(2);yu(2)],[xu(3);yu(3)], [xu(4);yu(4)],n_sq_x+1,n_sq_y+1); % The full grid
18
19 XX = (ones(2,1)*(1 + k_g * sum(XXu.^2))) .* XXu;
20 XX(1,:) = f_g*XX(1,:)+c_g(1);
21 XX(2,:) = f_g*XX(2,:)+c_g(2);
22
23 figure(2);
24 image(I);
25 colormap(map);
26 zoom on;
27 hold on;
28 %plot(f_g*XXu(1,:)+c_g(1),f_g*XXu(2,:)+c_g(2),'ro');
29 plot(XX(1,:),XX(2,:),'r+');
30 title('The red crosses should be on the grid corners...');
31 hold off;
32
33 satis_distort = input('Satisfied with distortion? ([]=no, other=yes) ');
34
35 satis_distort = ~isempty(satis_distort);
36
37
38 end;
39 \ No newline at end of file
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m
new file mode 100755
index 0000000..aad0fa4
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/startup.m
@@ -0,0 +1,9 @@
1% Main camera calibration toolbox:
2
3calib_gui;
4
5%calib_gui;
6
7path(pwd,path);
8
9format compact
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m
new file mode 100755
index 0000000..d9a7574
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/undistort_image.m
@@ -0,0 +1,193 @@
1%%% INPUT THE IMAGE FILE NAME:
2
3if ~exist('fc')|~exist('cc')|~exist('kc')|~exist('alpha_c'),
4 fprintf(1,'No intrinsic camera parameters available.\n');
5 return;
6end;
7
8KK = [fc(1) alpha_c*fc(1) cc(1);0 fc(2) cc(2) ; 0 0 1];
9
10disp('Program that undistorts images');
11disp('The intrinsic camera parameters are assumed to be known (previously computed)');
12
13fprintf(1,'\n');
14
15quest = input('Do you want to undistort all the calibration images ([],0) or a new image (1)? ');
16
17if isempty(quest),
18 quest = 0;
19end;
20
21if ~quest,
22
23 if ~exist(['I_' num2str(ind_active(1))]),
24 ima_read_calib;
25 end;
26
27 check_active_images;
28
29 format_image2 = format_image;
30 if format_image2(1) == 'j',
31 format_image2 = 'bmp';
32 end;
33
34 for kk = 1:n_ima,
35
36 if exist(['I_' num2str(kk)]),
37
38 eval(['I = I_' num2str(kk) ';']);
39 [I2] = rect(I,eye(3),fc,cc,kc,KK);
40
41 if ~type_numbering,
42 number_ext = num2str(image_numbers(kk));
43 else
44 number_ext = sprintf(['%.' num2str(N_slots) 'd'],image_numbers(kk));
45 end;
46
47 ima_name2 = [calib_name '_rect' number_ext '.' format_image2];
48
49 fprintf(1,['Saving undistorted image under ' ima_name2 '...\n']);
50
51
52 if format_image2(1) == 'p',
53 if format_images2(2) == 'p',
54 saveppm(ima_name2,uint8(round(I2)));
55 else
56 savepgm(ima_name2,uint8(round(I2)));
57 end;
58 else
59 if format_image2(1) == 'r',
60 writeras(ima_name2,round(I2),gray(256));
61 else
62 imwrite(uint8(round(I2)),gray(256),ima_name2,format_image2);
63 end;
64 end;
65
66
67 end;
68
69 end;
70
71 fprintf(1,'done\n');
72
73else
74
75 dir;
76 fprintf(1,'\n');
77
78 image_name = input('Image name (full name without extension): ','s');
79
80 format_image2 = '0';
81
82while format_image2 == '0',
83
84 format_image2 = input('Image format: ([]=''r''=''ras'', ''b''=''bmp'', ''t''=''tif'', ''p''=''pgm'', ''j''=''jpg'', ''m''=''ppm'') ','s');
85
86 if isempty(format_image2),
87 format_image2 = 'ras';
88 end;
89
90 if lower(format_image2(1)) == 'm',
91 format_image2 = 'ppm';
92 else
93 if lower(format_image2(1)) == 'b',
94 format_image2 = 'bmp';
95 else
96 if lower(format_image2(1)) == 't',
97 format_image2 = 'tif';
98 else
99 if lower(format_image2(1)) == 'p',
100 format_image2 = 'pgm';
101 else
102 if lower(format_image2(1)) == 'j',
103 format_image2 = 'jpg';
104 else
105 if lower(format_image2(1)) == 'r',
106 format_image2 = 'ras';
107 else
108 disp('Invalid image format');
109 format_image2 = '0'; % Ask for format once again
110 end;
111 end;
112 end;
113 end;
114 end;
115 end;
116end;
117
118ima_name = [image_name '.' format_image2];
119
120
121%%% READ IN IMAGE:
122
123if format_image2(1) == 'p',
124 if format_image2(2) == 'p',
125 I = double(loadppm(ima_name));
126 else
127 I = double(loadpgm(ima_name));
128 end;
129else
130 if format_image2(1) == 'r',
131 I = readras(ima_name);
132 else
133 I = double(imread(ima_name));
134 end;
135end;
136
137if size(I,3)>1,
138 I = I(:,:,2);
139end;
140
141
142if (size(I,1)>ny)|(size(I,2)>nx),
143 I = I(1:ny,1:nx);
144end;
145
146
147 %% SHOW THE ORIGINAL IMAGE:
148
149 figure(2);
150 image(I);
151 colormap(gray(256));
152 title('Original image (with distortion) - Stored in array I');
153 drawnow;
154
155
156 %% UNDISTORT THE IMAGE:
157
158 fprintf(1,'Computing the undistorted image...')
159
160 [I2] = rect(I,eye(3),fc,cc,kc,alpha_c,KK);
161
162 fprintf(1,'done\n');
163
164 figure(3);
165 image(I2);
166 colormap(gray(256));
167 title('Undistorted image - Stored in array I2');
168 drawnow;
169
170
171 %% SAVE THE IMAGE IN FILE:
172
173 ima_name2 = [image_name '_rect.' format_image2];
174
175 fprintf(1,['Saving undistorted image under ' ima_name2 '...']);
176
177 if format_image2(1) == 'p',
178 if format_images2(2) == 'p',
179 saveppm(ima_name2,uint8(round(I2)));
180 else
181 savepgm(ima_name2,uint8(round(I2)));
182 end;
183 else
184 if format_image2(1) == 'r',
185 writeras(ima_name2,round(I2),gray(256));
186 else
187 imwrite(uint8(round(I2)),gray(256),ima_name2,format_image2);
188 end;
189 end;
190
191 fprintf(1,'done\n');
192
193end;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m
new file mode 100755
index 0000000..8946349
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_convert.m
@@ -0,0 +1,89 @@
1function [fc,cc,kc,Rc,Tc,omc,nx,ny] = willson_convert(Ncx,Nfx,dx,dy,dpx,dpy,Cx,Cy,sx,f,kappa1,Tx,Ty,Tz,Rx,Ry,Rz,p1,p2);
2
3%Conversion from Reg Willson's calibration format to my format
4
5% Conversion:
6
7% Focal length:
8fc = [sx/dpx ; 1/dpy]*f;
9
10% Principal point;
11cc = [Cx;Cy];
12
13% Extrinsic parameters:
14Rx = rodrigues([Rx;0;0]);
15Ry = rodrigues([0;Ry;0]);
16Rz = rodrigues([0;0;Rz]);
17
18Rc = Rz * Ry * Rx;
19
20omc = rodrigues(Rc);
21
22Tc = [Tx;Ty;Tz];
23
24
25% More tricky: Take care of the distorsion:
26
27Nfy = round(Nfx * 3/4);
28
29nx = Nfx;
30ny = Nfy;
31
32% Select a set of DISTORTED coordinates uniformely distributed across the image:
33
34[xp_dist,yp_dist] = meshgrid(0:Nfx-1,0:Nfy);
35
36xp_dist = xp_dist(:)';
37yp_dist = yp_dist(:)';
38
39
40% Apply UNDISTORTION according to Willson:
41
42xp_sensor_dist = dpx*(xp_dist - Cx)/sx;
43yp_sensor_dist = dpy*(yp_dist - Cy);
44
45dist_fact = 1 + kappa1*(xp_sensor_dist.^2 + yp_sensor_dist.^2);
46
47xp_sensor = xp_sensor_dist .* dist_fact;
48yp_sensor = yp_sensor_dist .* dist_fact;
49
50xp = xp_sensor * sx / dpx + Cx;
51yp = yp_sensor / dpy + Cy;
52
53ind= find((xp > 0) & (xp < Nfx-1) & (yp > 0) & (yp < Nfy-1));
54
55xp = xp(ind);
56yp = yp(ind);
57xp_dist = xp_dist(ind);
58yp_dist = yp_dist(ind);
59
60
61% Now, find my own set of parameters:
62
63x_dist = [(xp_dist - cc(1))/fc(1);(yp_dist - cc(2))/fc(2)];
64x = [(xp - cc(1))/fc(1);(yp - cc(2))/fc(2)];
65
66k = [0;0;0;0];
67
68for kk = 1:5,
69
70 [xd,dxddk] = apply_distortion(x,k);
71
72 err = x_dist - xd;
73
74 %norm(err)
75
76 k_step = inv(dxddk'*dxddk)*(dxddk')*err(:);
77
78 k = k + k_step; %inv(dxddk'*dxddk)*(dxddk')*err(:);
79
80 %norm(k_step)/norm(k)
81
82 if norm(k_step)/norm(k) < 10e-10,
83 break;
84 end;
85
86end;
87
88
89kc = k;
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m
new file mode 100755
index 0000000..bbde63c
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/willson_read.m
@@ -0,0 +1,59 @@
1% Read in Reg Willson's data file, and convert it into my data format:
2
3%dir;
4
5%calib_file = input('Reg Willson calibration file name: ','s');
6
7if exist(calib_file),
8
9
10 load(calib_file);
11
12 inddot = find(calib_file == '.');
13
14 if isempty(inddot),
15 varname = calib_file;
16 else
17 varname = calib_file(1:inddot(1)-1);
18 end;
19
20 eval(['calib_params = ' varname ';'])
21
22 Ncx = calib_params(1);
23 Nfx = calib_params(2);
24 dx = calib_params(3);
25 dy = calib_params(4);
26 dpx = calib_params(5);
27 dpy = calib_params(6);
28 Cx = calib_params(7);
29 Cy = calib_params(8);
30 sx = calib_params(9);
31 f = calib_params(10);
32 kappa1 = calib_params(11);
33 Tx = calib_params(12);
34 Ty = calib_params(13);
35 Tz = calib_params(14);
36 Rx = calib_params(15);
37 Ry = calib_params(16);
38 Rz = calib_params(17);
39 p1 = calib_params(18);
40 p2 = calib_params(19);
41
42 % Conversion:
43 [fc,cc,kc,Rc_1,Tc_1,omc_1,nx,ny] = willson_convert(Ncx,Nfx,dx,dy,dpx,dpy,Cx,Cy,sx,f,kappa1,Tx,Ty,Tz,Rx,Ry,Rz,p1,p2);
44
45 KK = [fc(1) 0 cc(1);0 fc(2) cc(2) ; 0 0 1];
46
47 n_ima = 1;
48
49 X_1 = [NaN;NaN;NaN];
50 x_1 = [NaN;NaN];
51
52 map = gray(256);
53
54else
55
56 disp(['WARNING: Calibration file ' calib_file ' not found']);
57
58end;
59
diff --git a/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m
new file mode 100755
index 0000000..c7eb7bc
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/TOOLBOX_calib/writeras.m
@@ -0,0 +1,105 @@
1function writeras(filename, image, map);
2%WRITERAS Write an image file in sun raster format.
3% WRITERAS('imagefile.ras', image_matrix, map) writes a
4% "sun.raster" image file.
5
6% Written by Thomas K. Leung 3/30/93.
7% @ California Institute of Technology.
8
9
10% PC and UNIX version of writeras - Jean-Yves Bouguet - Dec. 1998
11
12dot = max(find(filename == '.'));
13suffix = filename(dot+1:dot+3);
14
15if nargin < 3,
16 map = [];
17end;
18
19if(strcmp(suffix, 'ras'))
20 %Write header
21
22 fp = fopen(filename, 'wb');
23 if(fp < 0) error(['Cannot open ' filename '.']), end
24
25 [height, width] = size(image);
26 image = image - 1;
27 mapsize = size(map, 1)*size(map,2);
28 %fwrite(fp, ...
29 % [1504078485, width, height, 8, height*width, 1, 1, mapsize], ...
30 % 'long');
31
32
33 zero_str = '00000000';
34
35 % MAGIC NUMBER:
36
37
38 fwrite(fp,89,'uchar');
39 fwrite(fp,166,'uchar');
40 fwrite(fp,106,'uchar');
41 fwrite(fp,149,'uchar');
42
43 width_str = dec2hex(width);
44 width_str = [zero_str(1:8-length(width_str)) width_str];
45
46 for ii = 1:2:7,
47 fwrite(fp,hex2dec(width_str(ii:ii+1)),'uchar');
48 end;
49
50
51 height_str = dec2hex(height);
52 height_str = [zero_str(1:8-length(height_str)) height_str];
53
54 for ii = 1:2:7,
55 fwrite(fp,hex2dec(height_str(ii:ii+1)),'uchar');
56 end;
57
58 fwrite(fp,0,'uchar');
59 fwrite(fp,0,'uchar');
60 fwrite(fp,0,'uchar');
61 fwrite(fp,8,'uchar');
62
63 ll = height*width;
64 ll_str = dec2hex(ll);
65 ll_str = [zero_str(1:8-length(ll_str)) ll_str];
66
67 for ii = 1:2:7,
68 fwrite(fp,hex2dec(ll_str(ii:ii+1)),'uchar');
69 end;
70
71 fwrite(fp,0,'uchar');
72 fwrite(fp,0,'uchar');
73 fwrite(fp,0,'uchar');
74 fwrite(fp,1,'uchar');
75 fwrite(fp,0,'uchar');
76 fwrite(fp,0,'uchar');
77 fwrite(fp,0,'uchar');
78 fwrite(fp,~~mapsize,'uchar');
79
80 mapsize_str = dec2hex(mapsize);
81 mapsize_str = [zero_str(1:8-length(mapsize_str)) mapsize_str];
82
83 %keyboard;
84
85 for ii = 1:2:7,
86 fwrite(fp,hex2dec(mapsize_str(ii:ii+1)),'uchar');
87 end;
88
89
90 if mapsize ~= 0
91 map = min(255, fix(255*map));
92 fwrite(fp, map, 'uchar');
93 end
94 if rem(width,2) == 1
95 image = [image'; zeros(1, height)]';
96 top = 255 * ones(size(image));
97 fwrite(fp, min(top,image)', 'uchar');
98 else
99 top = 255 * ones(size(image));
100 fwrite(fp, min(top,image)', 'uchar');
101 end
102 fclose(fp);
103else
104 error('Image file name must end in either ''ras'' or ''rast''.');
105end