当前位置:首页 > 技术分享 > 正文

双目立体视觉 I:标定和校正

导读双目立体校正和标定。大家好!今天我们将讨论什么是立体摄像机,以及我们如何将它用于计算机视觉。通过使用这里的代码:,我将解释我们如何为立体摄像机校准摄像机并计算视差图。我不会深入数学细节,你可以阅读一些OpenCV文档。简化的立体视觉。你可以看到物体P是如何被两个摄像机观察到的。物体的位置在两个图...

导读双目立体校正和标定。大家好!今天我们将讨论什么是立体摄像机,以及我们如何将它用于计算机视觉。通过使用这里的代码:,我将解释我们如何为立体摄像机校准摄像机并计算视差图。我不会深入数学细节,你可以阅读......

导读

双目立体校正和标定。

大家好!今天我们将讨论什么是立体摄像机,以及我们如何将它用于计算机视觉。通过使用这里的代码:,我将解释我们如何为立体摄像机校准摄像机并计算视差图。我不会深入数学细节,你可以阅读一些OpenCV文档。

简化的立体视觉。你可以看到物体P是如何被两个摄像机观察到的。物体的位置在两个图像中是不同的。

左上角图像和右下角图像分别是左/右相机图像,左下角是它们的组合来显示差异,右下角是深度图。

首先,将立体摄像机安装在一个固体物体上(尺子、木头或硬塑料材料等),使校准和校正参数能够正常工作。例如,如果你有IntelRealsense或zed相机,你可以跳过所有的部分,因为Realsense有自动校准功能,zed已经按出厂默认校准。下一步是分别校准两个相机。你可以按照这里:。立体摄像机首先需要单相机校准,因为校正需要这些参数。使用棋盘格图像进行校准,使用至少20张图像以进行良好的计算。

左图和右图的例子。注意拍照的时候要同步,在校正中,即使小的差别也会影响结果。

这些图像会给我们提供摄像机所需的信息。为了更好的校准,你不能移动并获取同步的图像。你可以使用grab和retrieve函数来获得更接近的时间戳。对于拍摄图像,你可以使用这个代码:,对于校准,你可以使用这个代码:。关于代码:

立体标定:立体摄像机的摄像机标定。

立体校正:通过旋转和平移使它们在y轴上对齐,使这些摄像机观察到的每个点都在每个摄像机图像的同一列中。

OpenCV立体标定函数:

ret,K1,D1,K2,D2,R,T,E,F=(objp,leftp,rightp,K1,D1,K2,D2,image_size,criteria,flag)

我们要注意函数中的flags:

CV_CALIB_FIX_INTRINSIC:K和D个矩阵是固定的。这是默认标志。如果你校准好你的相机,你可以修正它们,所以你只会得到校正矩阵。

CV_CALIB_USE_INTRINSIC_GUESS:K和D个矩阵将被优化。对于这个计算,你应该给出经过良好校准的矩阵,以便(可能)得到更好的结果。

CV_CALIB_FIX_PRINCIPAL_POINT:修复K矩阵中的参考点。

CV_CALIB_FIX_FOCAL_LENGTH:在K矩阵中固定焦距。

CV_CALIB_FIX_ASPECT_RATIO:固定长宽比。

CV_CALIB_SAME_FOCAL_LENGTH:校准焦距,并设置Fx和Fy相同的校准结果。我对这个不熟悉,但我肯定它是特定的立体设置所需要的。

CV_CALIB_ZERO_TANGENT_DIST:去掉畸变。

CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6:移除K1到K6的畸变。这对实验非常重要。我不熟悉这些背后的数学,但我做的实验帮助了我很多。

结果中的R,T,E,F系数给出了两个相机之间的关系,我们将使用它们进行校正:

R1,R2,P1,P2,Q,roi_left,roi_right=(K1,D1,K2,D2,image_size,R,T,flags=_ZERO_DISPARITY,alpha=0.9)

在这个函数中,我们只有一个标志CALIB_ZERO_DISPARITY,它用于匹配图像之间的y轴。alpha值用于转换后的黑色部分,因为图像会旋转,我们的大小不会改变,所以一些图像会是黑色的,我们的原始图像会小得多。我设置了相机的值。选项是:

alpha=-1-让OpenCV优化黑色部分。

alpha=0-旋转和切割图像,使没有黑色的部分。这个选项在大多数情况下会严重削减图像,你不会得到一个像样的高质量的图像,但值得一试。

alpha=1-进行变换,但不要切任何东西。

alpha=experimental-有时候什么都不管用。这意味着你应该试验这些值。在某个特定的alpha值,你可以有一些黑色的部分,但高质量的图像。我为我的相机找到了最好的0.9756,所以不要失去希望:)、S

R矩阵和P矩阵称为旋转矩阵和投影矩阵。R1和P1给出从第一个(左)到第二个(右)摄像机的旋转和位置。R2和P2是从二到一。从视差图中得到深度图需要Q矩阵。包括相机之间的距离,焦距等,用于深度地图的处理。当计算深度值时,不要忘记将在与校准工作相同的单位中获得坐标。有很多参数,所以最好仔细检查。

对于结果,应该去看我们的测试代码:。如果我们阅读主要部分,我们会看到我们使用了畸变校正:

leftMapX,leftMapY=(K1,D1,R1,P1,(width,height),_32FC1)left_rectified=(leftFrame,leftMapX,leftMapY,_LINEAR,_CONSTANT)rightMapX,rightMapY=(K2,D2,R2,P2,(width,height),_32FC1)right_rectified=(rightFrame,rightMapX,rightMapY,_LINEAR,_CONSTANT)

这意味着initUndistortRectifyMap函数可以同时实现图像的畸变校正和校准。对于左相机,我们使用K1(相机矩阵)和D1(失真矩阵)进行畸变校正,使用R1(从左到右旋转)和P1(从左到右投影矩阵)进行校正。在对remap进行变换后,我们将得到修正后的图像。对于右相机,我们会用相同的步骤做一遍,然后第一部分就完成了!总结一下过程:

这就是立体校准和标定。我们将在下一篇博客中讨论视差图的计算!

一些资源:

;source=lnmstbm=ischsa=Xved=0ahUKEwjlqIq1xsjeAhUkglwKHahhDVIQ_AUIDigBbiw=1536bih=732#imgrc=o7eiUTU5f3tKpM:

—END—

英文原文:

最新文章