OpenCV立体声校准(示例代码问题)

时间:2013-05-09 18:09:12

标签: opencv camera-calibration calibration

目前我正在实施立体视觉的校准方法。我正在使用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] );

1 个答案:

答案 0 :(得分:3)

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

在您的示例中,它们是:

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

在这些矩阵的基础上,您可以 undistort 纠正您的图像,这样您就可以通过以下方式提取您在两个图像中看到的点的深度它们的差异(基本上是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-by-1矩阵) - 随意忽略它,无论如何都不会在OpenCV C ++ API中使用它。

基本上,cvStereoCalibrate将imagePoints与objectPoints相匹配,并返回1)失真系数,2)内在相机矩阵和3)两个相机的空间关系作为旋转矩阵R和平移向量T.第一个是用于 undistort 您的图像,第二个将像素坐标转换为真实世界坐标,第三个允许您纠正您的两个图像。

作为旁注:我记得立体声校准有问题,因为在左右相机图像中可以不同地检测棋盘方向。这不应该是一个问题,除非你的相机之间有一个很大的角度(这不是一个好主意)或你的棋盘很多(这是不必要的),但你仍然可以留意。 / p>