开放式CV和3D坐标中的立体声校准

时间:2014-03-21 16:59:18

标签: c++ opencv 3d stereo-3d

我是OpenCV的初学者,目前我正在开展一个项目,要求将像素精确映射到厘米/毫米/任何真实世界单位。

我在OpenCV进行立体声校准,然后进行立体声校正。因此,我已经获得了内在和外在的参数。

在进行立体声校准时,我没有输入棋盘图案的确切方形尺寸(25mm×25mm)。我只输入了水平和垂直内角的数量以及板的数量。当重新投影到3D时,这会产生影响吗?如果是这样,我如何在StereoCalibrate函数中包含方形大小。

其次,从相机矩阵获得的值fxfy均为513.86,而从EXIF数据得出的值为3.7mm。那么,两者之间的确切关系是什么?

第三,我使用reprojectImageTo3D并获得了3d世界坐标。现在这些坐标的确切单位是多少(厘米/毫米/英寸/等)?

基本上,我想获得从像素到真实世界单位的精确映射,经过大量的阅读和搜索后,我无法做到这一点。请帮我解决这个问题。

3 个答案:

答案 0 :(得分:1)

我同意前两个问题的其他答案。但只是为了进一步澄清并详细阐述,

1)

在下面的代码块中查看参数'squareSize'。

这是你给出正方形大小的地方。这样做,它计算棋盘中每个角落的位置,并将其推入一个点矢量,称为objectPoints。这是可能的,因为棋盘具有规则图案。

矢量objectPoints将成为StereoCalibrate函数的第一个参数。

另外,请记住,无论您为squareSize指定的单位,校准结果(当然除fx和fy外)都将采用相同的单位。

    for( j = 0; j < boardSize.height; j++ ){
        for( k = 0; k < boardSize.width; k++ ){
            objectPoints.push_back(Point3f(j*squareSize, k*squareSize, 0));
        }
    }

<强> 2)

你得到的fx和fy将以像素为单位。为了获得以mm为单位的焦距,您需要将其与缩放系数相乘。

fx,fy与实际焦距(mm)之间的关系由相机传感器的大小决定。您应该能够在相机规格中找到此参数。

我上面提到的缩放系数是相机传感器每毫米像素数。

第3)

您获得的3D世界坐标正是您提到的。的坐标即可。从您系统中的某些角度引用。它们是对象点的 x y z坐标。坐标没有单位!

答案 1 :(得分:0)

到目前为止,我可以回答两个第一个问题:

1: cv :: stereoCalibrate 中的第一个参数是对象点的向量,您可以使用以下函数填充它:

void CalcBoardCornerPositions(cv::Size boardSize, double squareSize, std::vector<cv::Point3f>& corners) {
    corners.clear();
    for( int i = 0; i < boardSize.height; ++i )
        for( int j = 0; j < boardSize.width; ++j )
            corners.push_back(cv::Point3f(float( j*squareSize ), float( i*squareSize ), 0)); 
}

然后使用它:

 std::vector<std::vector<cv::Point3f> > objectPoints(1);
 CalcBoardCornerPositions(boardSize, squareSize, objectPoints[0]);
 cv::stereoCalibrate(objectPoints, imagePointsA, imagePointsB, _cameraMatrixA, /// etc

2:相机矩阵fx和fy实际上是焦距乘以分别是方向x和y的像素密度。这意味着

fx = f * cx

fy = f * cy

其中cx = imageSize.width / sensorSize.width和cy = imageSize.height / sensorSize.height。 通常在现代相机中使用cx == cy。您可以在相机手册中找到相机传感器的尺寸。

答案 2 :(得分:0)

  1. 函数StereoCalibrate的第一个参数是您需要自己创建的校准模式的实际尺寸。例如,如果您有一个3x正方形的棋盘网格6x5,则需要创建一个矩阵,其中包含棋盘e.x上参考系统中表示的每个角的位置。 [(0,0,0)(0,3,0)(0,6,0)...]等等。
  2. 焦距以像素尺寸表示。你应该检查像素的实际尺寸(通常是微米级)并乘以fxfy
  3. 单位取决于您创建校准图案的方式(问题1)。在示例中,我制作的棋盘具有3毫米的正方形,因此网格中角落的位置以毫米表示。这是结果的单位。