OpenCV triangulatePoints不同的距离

时间:2015-10-15 17:09:25

标签: c++ opencv

我正在使用OpenCV的triangulatePoints功能来确定立体相机拍摄的点的3D坐标。

我正在经历这个功能根据相机与该点的角度给出了不同的距离。

这是一段视频: https://www.youtube.com/watch?v=FrYBhLJGiE4

在此视频中,我们正在跟踪“X'标记。在左上角显示有关正在跟踪的点的信息。 (Youtube降低了质量,视频通常更清晰。(2x1280)x 720)

在视频中,左侧相机是3D坐标系的原点,它以正Z方向看。左相机正在进行一些翻译,但不会像triangulatePoints函数那样相信。 (更多信息在视频说明中。)

公制单位 mm ,因此该点最初距离左相机约1.94米处进行三角测量。

我知道校准不够精确会导致这种行为。我使用棋盘图案运行了三次独立校准。由此产生的参数因我的口味而变化太大。 (焦距估计约为±10%)。

正如您所看到的,视频严重失真。直线在任何地方看起来都非常直。因此,最佳摄像机参数必须接近我已使用的参数。

我的问题是,还有什么可以导致这种情况吗?

两台立体相机之间的会聚角度能否产生这种效果?或错误的基线长度?

当然,特征检测总是存在错误。由于我正在使用光流来追踪' X'标记,我得到亚像素精度,可以被误解......我不知道...... + -0.2 px?

我使用的是Stereolabs ZED立体相机。我直接使用OpenCV访问视频帧。相反,我必须使用购买相机时获得的特殊SDK。我发现这个我使用 的SDK可能 做了一些不成比例的事情。

所以,现在我想知道......如果SDK使用不正确的失真系数对图像进行解析,那么可以创建一个既没有桶形失真也没有枕形失真但完全不同的图像? < / p>

2 个答案:

答案 0 :(得分:2)

随ZED相机提供的SDK执行图像的不失真和纠正。几何模型与openCV相同:

  • 左右相机的内在参数和失真参数。
  • 右和左之间旋转/平移的外在参数。

通过ZED(ZED设置应用程序)的一个工具,您可以为左/右和失真系数以及基线/收敛输入您自己的内在矩阵。

要获得精确的三维三角测量,您可能需要调整这些参数,因为它们会对您在转换为深度之前估计的差异产生很大影响。

OpenCV提供了一个很好的模块来校准3D相机。它确实: - 左和右的单声道校准(calibrateCamera),然后是立体声校准(cv :: StereoCalibrate())。如果R是3×1矩阵,它将输出固有参数(focale,光学中心(非常重要))和外在(Baseline = T [0],Convergence = R [1])。 RMS(stereoCalibrate()的返回值)是查看校准是否正确完成的好方法。

重要的是,您需要在原始图像上进行此校准,而不是使用ZED SDK提供的图像。由于ZED是标准的UVC相机,您可以使用opencv来获取并排的原始图像(带有正确设备编号的cv :: videoCapture)并提取Left和RIght原生图像。

然后,您可以在工具中输入这些校准参数。然后,ZED SDK将执行不失真/校正并提供校正后的图像。 getParameters()中提供了新的相机矩阵。你需要在三角测量时采用这些值,因为图像被校正,好像它们是从这个&#34;理想的&#34;相机。

希望这会有所帮助。 / OB /

答案 1 :(得分:1)

我能想到有3点可能对你有所帮助。

  1. 可能是最不重要的,但根据您的描述,您已经分别校准了相机,然后是立体声系统。运行整体优化应该可以提高重建精度,因为有些&#34;不太准确&#34;参数补偿其他&#34;不太准确&#34;参数。

  2. 如果重建的准确性对您很重要,您需要采用系统的方法来减少重建。由于数学模型,构建不确定性模型很简单,可以编写几行代码来为您构建。假设您想要查看3d点是否在距离相机系统特定角度2米处,并且您对3d点的2d投影具有特定的不确定性,则很容易将不确定性反投影到3d在您的3d点附近的空间。通过增加系统其他参数的不确定性,您可以看到哪些更重要,并且需要具有较低的不确定性。

  3. 这种不准确性是问题和您正在使用的方法所固有的。

    • 首先,如果您对不确定性进行建模,您将看到远离相机中心的重建3d点具有更高的不确定性。原因是角度<left-camera, 3d-point, right-camera>更窄。我记得MVG book对这个有一个很好的描述。
    • 其次,如果查看triangulatePoints的{​​{3}},您会看到使用SVD实现伪逆方法来构造3d点。这可能导致很多问题,你可能会从线性代数中记住这些问题。
  4. <强>更新

      

    但是我一直在靠近边缘的距离很长很多次   由角度引起的不确定性的大小。

    这是使用伪逆的结果,这是一种数值方法。您可以使用几何方法替换它。一种简单的方法是反投影2d投影以在3d空间中获得2条光线。然后你想找到相交的地方,由于不准确,它不会发生。相反,你想要找到2条光线距离最短的点。如果不考虑不确定性,您将始终倾向于从可行解决方案中获得一点。这就是为什么使用伪逆,你不会看到任何波动而是严重错误。

    关于一般优化,是的,您可以对所有参数运行迭代LM优化。这是SLAM等自动驾驶汽车应用中使用的方法,其精度非常重要。您可以通过Google搜索bundle adjustment slam找到一些论文。