三角测量 (MATLAB) 后的输出不准确
Output after Triangulation (MATLAB) isn't accurate
我正在使用 MATLAB-CVST 执行立体相机校准。从 28 张图像(6 X 7 个角)中,获得 stereoParams(stereoParams.MeanReprojectionError = 0.3168)。
接下来,我拿了一对棋盘立体声(CB_I1 & CB_I2)。
到CB_I1我应用了以下函数:
- undistortImage
- 检测棋盘点
- 生成棋盘点
- extrinsics:这给了我平移向量(T)和旋转矩阵(R)
接下来,对 CB_I1 和 CB_I2,我应用以下函数:
- 不失真图像
- 检测棋盘点数
- 三角测量:这给了我 worldPoints
- 逆平移和旋转变换
这是我的代码:
CB_I1_undist = undistortImage(CB_I1, stereoParams.CameraParameters1);
CB_I2_undist = undistortImage(CB_I2, stereoParams.CameraParameters2);
[imagePoints1, ~] = detectCheckerboardPoints(CB_I1_undist);
[imagePoints, ~] = detectCheckerboardPoints(CB_I2_undist);
worldPoints = triangulate(imagePoints1,imagePoints,stereoParams);
Translated_pnts = zeros(size(worldPoints));
Translated_pnts(:,1) = worldPoints(:,1) - T(1);
Translated_pnts(:,2) = worldPoints(:,2) - T(2);
Translated_pnts(:,3) = worldPoints(:,3) - T(3);
Rotated_pnts = Translated_pnts * (R');
Transformed_points = Rotated_pnts;
最终,Transformed_points 看起来像这样:
依此类推....获得 42 分。
我该如何解释?我希望 Transformed_points 是:
因为每个正方形的尺寸是 40mm。
- 首先,这是一个错误吗?
- 这是什么原因?是因为高重投影误差吗? (如果是,如何才能最小化?)
- 我怎样才能尽可能减少它?
- 我希望它尽可能接近理想值。我可以通过哪些不同的方式来提高算法的准确性?
如果您需要任何其他信息,请告诉我。
你说你的平均重投影误差为 0.3~。
如果我计算你的第一点和第二点之间的距离:
sqrt((-0.2006+0.1993)^2+(-1.2843-39.1922)^2+(3.0466-2.0656)^2)
ans >>
40.4884
嗯,这就是您所期望的,对吧?当然不是100%准确。
另外,再看看你的观点。它们正是您期望的位置。而不是 120 你有 120.06。而不是 160,你有 159.94。
你错过了大约 0.3 毫米的点。 0.3 毫米。
拿一把尺子,试着测量0.3毫米!!
- 那是人发的 4 倍!
- 差不多就是人眼能分辨的最小距离了!
- 纸的3倍!
- 细菌大小的 0.6 倍! (变形虫)
哇,我认为这是一个很好的错误,不是吗?
无论如何,您可以使用更多校准图像来减少该错误,但是,是的,我想说您已经做得很好了。
测量误差使其具有更多意义的一个好方法是计算像素误差,而不是真正的物理误差。如果将误差除以一个像素的长度,就可以知道有多少个像素的误差。您会发现,在您的情况下,您很可能具有亚像素精度(像素误差 < 1)。这非常好,因为这意味着您的误差小于您可以测量的误差,因此,在某种意义上(不是真的,但是是的)您违反了香农原则!干得好
对于 Ander 的回答,我想补充一点,您应该确保使用卡尺非常精确地测量正方形的尺寸。如果您可以获得亚毫米精度,那将对您的重建精度产生影响。另外,请确保不要对图像使用有损压缩,即。 e.没有 jpeg。 Jpeg 伪像也会降低您的准确性。
我正在使用 MATLAB-CVST 执行立体相机校准。从 28 张图像(6 X 7 个角)中,获得 stereoParams(stereoParams.MeanReprojectionError = 0.3168)。
接下来,我拿了一对棋盘立体声(CB_I1 & CB_I2)。
到CB_I1我应用了以下函数:
- undistortImage
- 检测棋盘点
- 生成棋盘点
- extrinsics:这给了我平移向量(T)和旋转矩阵(R)
接下来,对 CB_I1 和 CB_I2,我应用以下函数:
- 不失真图像
- 检测棋盘点数
- 三角测量:这给了我 worldPoints
- 逆平移和旋转变换
这是我的代码:
CB_I1_undist = undistortImage(CB_I1, stereoParams.CameraParameters1);
CB_I2_undist = undistortImage(CB_I2, stereoParams.CameraParameters2);
[imagePoints1, ~] = detectCheckerboardPoints(CB_I1_undist);
[imagePoints, ~] = detectCheckerboardPoints(CB_I2_undist);
worldPoints = triangulate(imagePoints1,imagePoints,stereoParams);
Translated_pnts = zeros(size(worldPoints));
Translated_pnts(:,1) = worldPoints(:,1) - T(1);
Translated_pnts(:,2) = worldPoints(:,2) - T(2);
Translated_pnts(:,3) = worldPoints(:,3) - T(3);
Rotated_pnts = Translated_pnts * (R');
Transformed_points = Rotated_pnts;
最终,Transformed_points 看起来像这样:
依此类推....获得 42 分。
我该如何解释?我希望 Transformed_points 是:
因为每个正方形的尺寸是 40mm。
- 首先,这是一个错误吗?
- 这是什么原因?是因为高重投影误差吗? (如果是,如何才能最小化?)
- 我怎样才能尽可能减少它?
- 我希望它尽可能接近理想值。我可以通过哪些不同的方式来提高算法的准确性?
如果您需要任何其他信息,请告诉我。
你说你的平均重投影误差为 0.3~。
如果我计算你的第一点和第二点之间的距离:
sqrt((-0.2006+0.1993)^2+(-1.2843-39.1922)^2+(3.0466-2.0656)^2)
ans >>
40.4884
嗯,这就是您所期望的,对吧?当然不是100%准确。
另外,再看看你的观点。它们正是您期望的位置。而不是 120 你有 120.06。而不是 160,你有 159.94。
你错过了大约 0.3 毫米的点。 0.3 毫米。 拿一把尺子,试着测量0.3毫米!!
- 那是人发的 4 倍!
- 差不多就是人眼能分辨的最小距离了!
- 纸的3倍!
- 细菌大小的 0.6 倍! (变形虫)
哇,我认为这是一个很好的错误,不是吗?
无论如何,您可以使用更多校准图像来减少该错误,但是,是的,我想说您已经做得很好了。
测量误差使其具有更多意义的一个好方法是计算像素误差,而不是真正的物理误差。如果将误差除以一个像素的长度,就可以知道有多少个像素的误差。您会发现,在您的情况下,您很可能具有亚像素精度(像素误差 < 1)。这非常好,因为这意味着您的误差小于您可以测量的误差,因此,在某种意义上(不是真的,但是是的)您违反了香农原则!干得好
对于 Ander 的回答,我想补充一点,您应该确保使用卡尺非常精确地测量正方形的尺寸。如果您可以获得亚毫米精度,那将对您的重建精度产生影响。另外,请确保不要对图像使用有损压缩,即。 e.没有 jpeg。 Jpeg 伪像也会降低您的准确性。