【问题标题】:Depth map values in opencv's reprojectImageTo3D()opencv 的 reprojectImageTo3D() 中的深度图值
【发布时间】:2015-10-26 10:31:10
【问题描述】:

OpenCV 的 reprojectImageTo3D() 输出 “表示 3D 表面的 3 通道图像”。 您可以通过

访问这些数据
Vec3f coordinates = _3dImage.at<Vec3f>(y,x);
float depth = _3dImage.at<Vec3f>(y,x)[2];

witch 返回一个向量 [X,Y,Z]。

在 Gary Bradski 和 Adrian Kaehler 的 “Learning OpenCV” 中,解释了深度是通过以下方式计算的

Z = f T / (x_left - x_right)

其中 f = 焦距,T = 眼距/相机之间的平移,(x_left - x_right) = 视差

这个精确的公式是在 OpenCV 中实现的(我检查了源代码 - 但是由于某种原因还有一个额外的负号)。问题是:X、Y、Z 值在哪个单位中指定?

T 是你的单位(例如 mm),x_l - x_r 是像素,[ f ] = ?

当您校准相机时,您以现实世界的单位(例如毫米)指定棋盘的大小。因此,内在矩阵是否具有真实世界的单位?还是以 px 指定?不幸的是,我在文档中找不到答案。

【问题讨论】:

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


    【解决方案1】:

    执行深度重建的基本方程是:

    Z = fB/d,在哪里

    • f 是焦距(以像素为单位),您将其称为眼距/相机之间的平移
    • B 是立体声基线(以米为单位)
    • d 是视差(以像素为单位),用于衡量对应点之间视网膜位置的差异
    • Z是沿相机Z轴的距离

    图像点的 3D 位置 (X,Y,Z)(例如 (u,v) 以像素为单位)可以以米、厘米、毫米或您选择的任何单位给出,因为 3D 坐标 (X,Y,Z) 与棋盘的单位相同正方形大小。例如,如果您将正方形大小定义为 1 厘米,则 3D 坐标也将以厘米为单位。

    即:

    Size boardSize(4, 5); // 4x5 chessboard
    float squareSize = 0.025F; // 0.025 meters
    for( int i = 0; i < boardSize.height; i++ )
        for( int j = 0; j < boardSize.width; j++ )
            corners.push_back(Point3f(float(j*squareSize), float(i*squareSize), 0.0F));
    

    附:
    确定Z后,就可以使用常用的投影相机方程计算出XY

    • X = uZ/f
    • Y = vZ/f

    【讨论】:

    • 基线(在你的帖子B,在我的问题T)总是必须以米为单位。单位仅由校准图案的大小定义?所以这个信息必须存储在固有矩阵的c_x, c_y 值中。
    • 是的,它是由图案的大小定义的。因此,Z 的单位度量(即毫米)代表人们为棋盘图案选择的任何度量单位。
    • 但是这些信息不应该存储在内部矩阵中,因为内部不依赖于所查看的场景。此信息存储在外部参数中,表示从 3D 世界坐标到 3D 相机坐标的坐标系转换。
    • 我没有对相机进行立体校准,我只是对其进行了校准。因此我只有相机的内在参数并手动提供外参数TB。因此这是绝对值而不是X * squareSize
    • 在这种情况下,统一度量将是您手动提供的TB 的单位。
    猜你喜欢
    • 2014-04-20
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多