【问题标题】:OpenCV Stereo Calibration (example code questions)OpenCV 立体校准(示例代码问题)
【发布时间】:2013-05-04 07:26:36
【问题描述】:

目前我正在实施立体视觉的校准方法。我正在使用 OpenCV 库。

示例文件夹中有一个示例,但我对实现有一些疑问:

这些数组的用途是什么?这些 CvMat 变量是什么?

// ARRAY AND VECTOR STORAGE:
double M1[3][3], M2[3][3], D1[5], D2[5];
double R[3][3], T[3], E[3][3], F[3][3];
CvMat _M1 = cvMat(3, 3, CV_64F, M1 );
CvMat _M2 = cvMat(3, 3, CV_64F, M2 );
CvMat _D1 = cvMat(1, 5, CV_64F, D1 );
CvMat _D2 = cvMat(1, 5, CV_64F, D2 );
CvMat _R = cvMat(3, 3, CV_64F, R );
CvMat _T = cvMat(3, 1, CV_64F, T );
CvMat _E = cvMat(3, 3, CV_64F, E );
CvMat _F = cvMat(3, 3, CV_64F, F );

在其他示例中,我看到以下代码:

//--------Find and Draw chessboard--------------------------------------------------    

    if((frame++ % 20) == 0)
    {
        //----------------CAM1-------------------------------------------------------------------------------------------------------
        result1 = cvFindChessboardCorners( frame1, board_sz,&temp1[0], &count1,CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_FILTER_QUADS);
        cvCvtColor( frame1, gray_fr1, CV_BGR2GRAY );

if 语句究竟做了什么?为什么是 %20?

提前谢谢你!


更新:

我有两个关于一些实现代码的问题:link

-1:在第 18 行声明并在第 25 行的 board_sz 变量中使用的那些 nx 和 ny 变量。这些 nx 和 ny 是棋盘模式中的行和列还是角? (我认为这些是行和列,因为 cvSize 有宽度和高度的参数)。

-2:这些 CvMat 变量用于什么(第 143 - 146 行)?

CvMat _objectPoints = cvMat(1, N, CV_32FC3, &objectPoints[0] );
CvMat _imagePoints1 = cvMat(1, N, CV_32FC2, &points[0][0] );
CvMat _imagePoints2 = cvMat(1, N, CV_32FC2, &points[1][0] );
CvMat _npoints = cvMat(1, npoints.size(), CV_32S, &npoints[0] );

【问题讨论】:

  • 不可能从这段代码中找出这些变量的用途。这就像在int x = 0; 中询问x 是什么,而 %20 是为了每 20 帧运行一次下面的代码。
  • 你可以在这个网站上找到例子:link 我还是不知道那些 CvMat 变量是干什么用的?

标签: opencv camera-calibration calibration


【解决方案1】:

每个矩阵在epipolar geometry 中都有一个含义。它们描述了 3D 空间中两台相机之间的关系以及它们记录的图像之间的关系。

在您的示例中,它们是:

  • M1 - 左相机的相机内在矩阵
  • M2 - 右侧相机的相机内在矩阵
  • D1 - 左摄像头的畸变系数
  • D2 - 右侧摄像头的失真系数
  • R - 从右到左相机的旋转矩阵
  • T - 从右到左相机的平移向量
  • E - 立体声设置的基本矩阵
  • F - 立体声设置的基本矩阵

在这些矩阵的基础上,您可以undistortrectify您的图像,这允许您通过以下方式提取您在两个图像中看到的点的深度它们的差异(基本上是 x 的差异)。在两个图像中找到一个点称为匹配,通常是校正后的最后一步。

对极线几何和立体视觉的任何好的介绍都可能比我在这里输入的任何内容都要好。我推荐 Learning OpenCV 这本书,从中获取您的示例代码,其中非常详细地解释了基础知识。

您的问题的第二部分已在评论中得到回答: (frame++ % 20) 从您的网络摄像头记录的每 20 帧为 0,因此 if 子句中的代码每 20 帧执行一次。


回复您的更新:

nx 和 ny 是校准图像中棋盘图案中的角数。 na "正常" 8x8 棋盘,nx = ny = 7。你可以看到,在第 138-139 行中,一个理想棋盘的点是通过将 nx*ny 个点与 squareSize 的距离偏移来创建的,即你的一个正方形的大小棋盘。

CvMat 变量“objectPoints”、“imagePoints”和“npoints”被传递到 cvStereoCalibrate 函数中。

  • objectPoints 包含校准对象(棋盘)的点
  • imagePoints1/2 包含您的每个相机看到的这些点
  • npoints 仅包含每个图像中的点数(作为 M×1 矩阵) - 随意忽略它,无论如何它不再用于 OpenCV C++ API。

基本上,cvStereoCalibrate 将 imagePoints 拟合到 objectPoints,并返回 1)失真系数,2)固有相机矩阵和 3)两个相机的空间关系作为旋转矩阵 R 和平移向量 T。第一个是用于不失真您的图像,第二个将您的像素坐标传递到真实世界坐标,第三个允许您校正您的两个图像。

附带说明:我记得在立体校准时遇到了问题,因为在左右摄像头图像中检测到的棋盘方向可能不同。这应该不是问题,除非您的相机之间的角度很大(这不是一个好主意)或者您的棋盘倾斜很多(这不是必需的),但您仍然可以留意。

【讨论】:

  • 非常感谢!现在我变得更清楚了! :) 我对一些实现代码link 有另一个问题:在校准区域/区域中有 3 个 for 循环。在这些循环中,ny 和 nx 是行和列。所以我认为你正在循环一个二维数组?第三个 for 循环是在带有 j 变量的 for 循环内还是在那个循环之外? for 循环的含义是什么?你能(再次)向我解释一下这些 CvMat 变量的用途吗?提前谢谢!
  • 第 138-140 行合成了棋盘图案的“理想”点,这些点与校准图像中的点进行比较。 nx 和 ny 不是行和列,而是您正在使用的棋盘图案中的角数。第 140 行不在 for 循环内 - for 循环关注其后的单个命令或由花括号分组的一组命令。您在谈论哪些 CvMat 变量?在第 163-172 行声明的那些?在这种情况下编辑您的问题,我无法在评论中回答。
  • 见第一篇文章中的“更新”。
  • 请参阅此答案中的“更新”@Odrai
  • 好的,我实现了一些方法来校准两个凸轮。校准过程并不总是很好地执行,并且还会生成错误/不正确的视差文件夹。如果我将项目上传到例如Dropbox,可以看看代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
  • 2014-07-30
  • 1970-01-01
  • 2015-01-07
相关资源
最近更新 更多