和matlab的双目标定相对比,matlab首先通过calib界面对单个相机拍摄的图片进行标定,计算出单个相机的内参和外参(即成像变换矩阵)。然后运行stereo_gui进行双目标定,而这个双目标定的步骤是
(1)在load left and right calibration files的同时,计算两个相机的相对位置关系,即右边的相机相对于左边相机的平移和旋转关系,不过只是一个初值。
(2)执行双目标定。 函数go_calib_stereo.m是matlab 标定工具箱中双目标定的核心函数。在这个函数中,首先分别读取左右相机标定文件,然后按照本报告2.1部分图1中的公式,对每一组场景,计算R和T的估计值。将估计值代入project_points2函数反算标定板中各个角点在这一组R、T值下呈现在照片上的像素坐标,计算该坐标与真实像素坐标的偏差e。将这个偏差与一个稀疏矩阵J的逆矩阵相乘,作为参数向量的一个增量。以此迭代,直到旋转向量om,T连续两次的计算结果足够接近,或者迭代超出预定义的最大次数(即代码中的MaxIter=100)。
Matlab标定结果中各变量的分析
以下的表述中k代表一个数字,k介于1到图片最大张数之间
投影矩阵 H_k
Tc_ 平移向量
Tc_k 右平移向量
Tc_left_k 左平移向量
Rc:旋转矩形
Rc_k
Rc_left_k 左相机的第K幅图相应的旋转矩形(标定板坐标系相对于左相机坐标系)
Rc_right_k 右相机的第K幅图相应的旋转矩形(标定板坐标系相对于右相机坐标系)
照片的统一尺寸
nx ny
外参 ex_k
第k幅图的水平和竖直两方向的正方形数目
n_sq_x_k
n_sq_y_k
omc 旋转向量
omc_k 右图旋转向量
omc_error_k 右图误差估计
omc_left_k 左图旋转向量
omc_left_error_k 左误差估计
用来标记角点的小方格的尺寸
wintx_k
winty_k
在棋盘坐标系中间各个角点的三维坐标
X_left_k
X_right_k
x_left_k 待标定的左图中角点的像素坐标
x_right_k 待标定的右图中角点的像素坐标(用于单目标定)
x_k 只是中间结果
y_k 射影重建得到的像素坐标
om 右相机相对于左相机的旋转向量
T 右相机相对于左相机的平移向量
取左相机的坐标系为世界坐标系
左右相机坐标系的轴相对于世界坐标系的坐标(用于绘制坐标系)
BASE_left
BASE_right
评价方法(一):
按照标定的结果om,I反算标点角点在标定板坐标系中的坐标X_left_approx_1 。
[Xc_1_left,Xc_1_right] = stereo_triangulation(x_left_1,x_right_1,om,T,fc_left,cc_left,kc_left,alpha_c_left,fc_right,cc_right,kc_right,alpha_c_right);
X_left_approx_1 = Rc_left_1' * (Xc_1_left - repmat(Tc_left_1,[1 size(Xc_1_left,2)]));
%将X_left_approx_1 与标定板坐标系中的准确值进行对比显示。
figure; scatter3(X_left_approx_1(1,:),X_left_approx_1(2,:),X_left_approx_1(3,:),'b*')
hold on;scatter3(X_left_1(1,:),X_left_1(2,:),X_left_1(3,:),'ro')
评价方法(二):
把右图的相机坐标系中标定板各个角点的坐标转化为在左图相机坐标系中的坐标,并对比显示。
%执行本程序前 请确认已经把以下变量加入到工作空间
% omc_left_1 Tc_left_1 X_left_1
% omc_1 X_right_1 X_right_1
% om T
% 实际上,当运行完stereo_gui中的show entrinsics of stereo rig
% 命令以后,以下代码就具备了运行所需条件
left_1=rodrigues(omc_left_1) * X_left_1 +Tc_left_1 * ones(1,length( X_left_1));
right_1_i=rodrigues(omc_1) * X_right_1 +Tc_1 * ones(1,length( X_right_1));
R=rodrigues(om);
right_1 = R'*(right_1_i - repmat(T,[1 size(right_1_i,2)]));
figure;scatter3(left_1(1,:),left_1(2,:),left_1(3,:),'b')
hold on;
scatter3(right_1(1,:),right_1(2,:),right_1(3,:),'r+')
%蓝色圈和红色“*”分别表示左相机坐标系下标定角点的空间坐标
%和右相机坐标系下角点坐标反算到左相机坐标系的坐标
注意到,上面的代码中间,right_1_i是右相机坐标系下标定板各个角点的坐标,right_1则是再变换到左边相机坐标系的坐标。
(1)进行标定的时候,有时候会出现如下报错提示
Disabling view %d - Reason: the left and right images are found inconsistent
提示,按照matlab工具箱自带的说明,这表明所给的左右相机所拍图片并不匹配。追溯到go_calib_stereo.m文件中,就是标定点由棋盘的三维坐标反算到左相机照片的像素坐标以后和左相机照片的真实位置差值emax大于了系统指定的阈值。通过修改阈值可以强行让标定过程继续。
(2)有时候标定结果出现了NAN字样
Extrinsic parameters (position of right camera wrt left camera):
Rotation vector: om = [ NaN NaN NaN ] ?[ NaN NaN NaN ]
Translation vector: T = [ NaN NaN NaN ] ?[ NaN NaN NaN ]
经过观察,发现同时出现了警告
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 3.736396e-045.
而且每次迭代的投影偏差(即go_calib_stereo.m文件中的emax)是发散的,从200多增加到10的147次方量级。
按照提示追踪go_calib_stereo.m文件中相应代码,发现在244行附近有如下代码
J = J(:,ind_Jac);
J2 = J'*J;
J2_inv = inv(J2);
param_update = J2_inv*J'*e;
这里的矩阵求逆运算触发了警告,因为J2是一个条件数接近0的矩阵,不适合做求逆运算。
这也是造成结果出现NAN的原因。