打开CV和三维坐标中的立体校准

Stereo Calibration in Open CV and 3D Coordinates

本文关键字:CV 三维 坐标 打开      更新时间:2023-10-16

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

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

在执行立体校准时,我没有在哪里输入棋盘图案的确切正方形大小(25毫米乘25毫米(。我只输入了水平和垂直内角的数量以及板的数量。那么,当我重新投影到3D时,这会有效果吗?如果是,如何在StereoCalibrate函数中包含正方形大小。

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

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

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

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

我同意前两个问题的其他答案。但为了进一步澄清和详细说明,

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将以像素为单位。为了获得以毫米为单位的焦距,需要将其乘以比例因子。

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

我上面提到的比例因子是相机传感器每毫米的像素数。

3(

你得到的三维世界坐标正是你提到的坐标。从系统中的某个点引用。它们是对象点的xyz坐标。坐标没有单位!

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

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 e.height。在现代相机中通常cx==cy。您可以在相机手册中找到相机传感器的尺寸。