C++ opencv'中的深度贴图值;s重新投影到3D()

C++ opencv'中的深度贴图值;s重新投影到3D(),c++,opencv,camera-calibration,stereo-3d,C++,Opencv,Camera Calibration,Stereo 3d,OpenCV的reprojectImageTo3D()输出“表示3D曲面的3通道图像”。 您可以通过以下方式访问此数据: Vec3f coordinates = _3dImage.at<Vec3f>(y,x); float depth = _3dImage.at<Vec3f>(y,x)[2]; Vec3f坐标=3dImage.at(y,x); 浮动深度=3dImage.at(y,x)[2]; witch返回一个向量[X,Y,Z] 在Gary Bradski和Adria

OpenCV的reprojectImageTo3D()输出“表示3D曲面的3通道图像”。 您可以通过以下方式访问此数据:

Vec3f coordinates = _3dImage.at<Vec3f>(y,x);
float depth = _3dImage.at<Vec3f>(y,x)[2];
Vec3f坐标=3dImage.at(y,x);
浮动深度=3dImage.at(y,x)[2];
witch返回一个向量[X,Y,Z]

在Gary Bradski和Adrian Kaehler的“学习OpenCV”中,解释了深度是通过

Z=ft/(x_左-x_右)

其中f=焦距,T=眼睛底部/摄像机之间的平移,(x_左-x_右)=视差

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

T以您的单位表示(例如mm),x_l-x_r以像素表示,[f]=?


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

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

Z=fB/d
,其中

  • f
    是焦距(以像素为单位),您称之为眼底/摄像机之间的平移
  • B
    是立体声基线(以米为单位)
  • d
    是测量对应点之间视网膜位置差异的视差(以像素为单位)
  • Z
    是沿摄影机Z轴的距离
图像点(例如,
(u,v)
(像素)的三维位置
(X,Y,Z)
)可以以米、厘米、毫米或您选择的任何单位给出,因为三维坐标
(X,Y,Z)
与棋盘的正方形大小采用相同的单位。例如,如果将正方形大小定义为1厘米,则三维坐标也将以厘米为单位

i、 e:

Size boardSize(4,5);//4x5棋盘
浮子平方尺寸=0.025F;//0.025米
对于(int i=0;i
p、 美国:
确定
Z
后,可以使用常用的投影相机方程计算
X
Y

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

基线(在你的帖子
B
,在我的问题
T
中)必须以米为单位。单位仅由校准模式的大小定义?因此,这些信息必须存储在内在矩阵的
c_x,c_y
值中。是的,它是由图案的大小定义的。因此,
Z
(即mm)的单位度量值代表为棋盘图案选择的任何度量单位。但是,该信息不应存储在本质矩阵中,因为本质不依赖于所查看的场景。这些信息存储在外部参数中,这些参数表示从3D世界坐标到3D相机坐标的坐标系转换。我没有对相机进行立体校准,我只校准了它们。因此,我只有相机的内部参数,并手动提供外部参数
T
B
。因此,这是绝对值,而不是
X*squareSize
,在这种情况下,单位度量将是手动提供的
T
B
的单位。
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));