视差图的 OpenCv 深度估计

Posted

技术标签:

【中文标题】视差图的 OpenCv 深度估计【英文标题】:OpenCv depth estimation from Disparity map 【发布时间】:2013-10-13 05:17:57 【问题描述】:

我正在尝试使用 OpenCV 从立体对图像中估计深度。我有视差图和深度估计可以得到:

             (Baseline*focal)
depth  =     ------------------
           (disparity*SensorSize)

我使用块匹配技术在两个校正后的图像中找到相同的点。 OpenCV 允许设置一些块匹配参数,例如BMState->numberOfDisparities

块匹配过程后:

cvFindStereoCorrespondenceBM( frame1r, frame2r, disp, BMState);
cvConvertScale( disp, disp, 16, 0 );
cvNormalize( disp, vdisp, 0, 255, CV_MINMAX );

我发现深度值为:

if(cvGet2D(vdisp,y,x).val[0]>0)
   
   depth =((baseline*focal)/(((cvGet2D(vdisp,y,x).val[0])*SENSOR_ELEMENT_SIZE)));
   

但是由于BMState->numberOfDisparities的值改变了结果值,所以得到的深度值与上式得到的值不同。

如何设置此参数?这个参数怎么改?

谢谢

【问题讨论】:

【参考方案1】:

当且仅当从左相机到右相机的运动是纯平移(特别是平行于水平图像轴)时,简单的公式才有效。

在实践中,几乎从来没有这种情况。例如,通常在rectifying 图像之后执行匹配,即在使用已知的基本矩阵对它们进行扭曲之后,以便将相应的像素限制为属于同一行。一旦你有比赛 校正后的图像,您可以使用校正扭曲的倒数将它们重新映射到原始图像上,然后三角剖分到 3D 空间以重建场景。 OpenCV 有一个例程可以做到这一点:reprojectImageTo3d

【讨论】:

谢谢你的回答,我在块匹配过程中给出了两个校正后的图像,所以这个公式应该有效吗?现在我将尝试使用 reprojectImageTo3D 函数。意大利语版本:Dal nome credo che tu sia italiano, quindi per una maggiore chiarezza (per me); se utilizzo già le immagini rettificate la formula prente dovrebbe andare bene giusto? Se invece utilizzo ReprojectImageTo3D dovrei estrapolare soltanto il valore Z? Grazie per la risposta。 定义“应该工作”?平行相机公式为您提供给定像素相对于观察校正图像的理想相机的深度。它的重建将是投影的,但不是度量的,准确的。 [是的,我会说意大利语,但这是一个仅限英语的论坛]【参考方案2】:

您上面提到的公式不适用于相机平面和图像平面不同,即相机将位于某个高度,而它捕获的平面将在地面上。所以,你必须对这个公式做一点修改。 您可以通过曲线拟合多项式上拟合这些视差值和已知距离。从中您将获得可用于其他未知距离的系数。 第二种方法是使用环绕矩阵和 reprojectimageTo3d (Opencv API) 创建 3d 点云。

【讨论】:

以上是关于视差图的 OpenCv 深度估计的主要内容,如果未能解决你的问题,请参考以下文章

opencv三维重建深度怎么不随视场变化

Playing with OpenCV

Playing with OpenCV

Emgu (OpenCV for C#) - 使用 cvStereoRectify 构建视差图

opencv估计两图的三维坐标变换矩阵

深度图 - 带有 OpenCV 的 Android 中的立体图像