C++ OpenCV-来自两个垂直2D图像的3D真实世界坐标

C++ OpenCV-来自两个垂直2D图像的3D真实世界坐标,c++,opencv,3d-reconstruction,C++,Opencv,3d Reconstruction,也许有答案,但我只是不明白我发现了什么。也许是语言障碍。所以我决定最后问一下。我需要的是从两台摄像机录制的两个视频中找到3D坐标。设置如下所示: 我似乎不知道怎么做。我所拥有的是 两张图片上的像素坐标(相对于图片上的0,0点) 焦距 两个摄影机与0,0,0真实世界点的距离(Ax和By) 像素的大小 我知道摄像机之间的角度是90度 现在怎么办?OpenCV文档包含以下公式: 我不知道‘s’是什么,也不知道[R | t]矩阵,也不知道外在参数。我不知道主要点在哪里以及如何找到它(cx,cy)

也许有答案,但我只是不明白我发现了什么。也许是语言障碍。所以我决定最后问一下。我需要的是从两台摄像机录制的两个视频中找到3D坐标。设置如下所示:

我似乎不知道怎么做。我所拥有的是

  • 两张图片上的像素坐标(相对于图片上的0,0点)
  • 焦距
  • 两个摄影机与0,0,0真实世界点的距离(Ax和By)
  • 像素的大小
  • 我知道摄像机之间的角度是90度
现在怎么办?OpenCV文档包含以下公式:

我不知道‘s’是什么,也不知道[R | t]矩阵,也不知道外在参数。我不知道主要点在哪里以及如何找到它(cx,cy),我只能假设将其设置为0不会是灾难性的。而且,它看起来只使用了一个2D图像,而不是两个

我知道
caliberecamera
solvePnP
。还有
stereoCalibrate
函数,但我不知道如何使用它们

我知道当你把相机当作两个“眼睛”时会有多复杂,我希望在相机拍摄垂直图像的情况下会更容易。我现在有了一个计算3D坐标的公式,但它并不精确。误差在1英寸以下,但1英寸太大

xa, ya, xb, yb - pixel coordinates from pictures
focalAB - focal length
W = -(Ax*xb*pixelSize - focalB*By)/(xa*pixelSize*xb*pixelSize - focalA*focalB)
X = Ax + W*xa*pixelSize
Y = W*focalA
Z = W*xa*pixelSize
错误:


这些是由制造商提供的焦距和像素大小。5400微米和1,75微米。然而,对于4620um和1,69um的值,误差最小,其中最大的是3#X轴,2,3cm,高度误差最快消失(最大0,2cm),其余为0,1cm或1-1,5cm

除了告诉你按照@YangKui的建议阅读立体视觉之外,我还可以回答你的一些小问题

您引用的公式是(单个摄影机)三维到二维投影公式。这是一个射影几何方程(因此1是最后一个坐标),所有东西都达到了一定的比例
s

  • s
    是这个比例因子
  • R
    是相机相对于世界/选定坐标系的3x3旋转
  • t
    是摄影机原点从世界/选定坐标系原点的平移
  • cx
    cy
    是图像中的主要点-以像素为单位的图像平面上Z轴相交的点。它通常被认为是图像的中心

我发现,如果不是高性能实现,一种方法可以提供直观性,那就是为两个摄像头构造摄像头矩阵,然后使用非线性优化来求解
M
以最小化“重投影错误”

所以拿出相机矩阵:A的相机矩阵将把A在世界坐标系中的相机中心映射到A的相机坐标系中的(0,0,0)。摄影机矩阵的旋转部分将世界坐标中的(0,1,0)映射到摄影机坐标中的(0,0,1)

现在您可以将世界坐标映射到A和B图像坐标,因此对于任何(x,y,z),您都有一个对应的4向量:(x_A,y_A,x_B,y_B)。如果你加入点(A_x,B_y,0),你会得到一个4向量。该4矢量与测量位置之间的差异就是重投影误差。把它扔到解算器上,它会很快收敛到一个答案上


你可以试试Hartley和Zisserman的《计算机视觉中的多视图几何》。

你应该先读一本关于立体视觉的书,学习基本概念。@YangKui我知道,可惜我时间紧迫。我可以算,我只需要解释一下这几点。主要是什么是外部参数以及如何找到主点。问题是我不知道我的语言中有任何关于这个主题的文献,而英文文本是很难阅读的。我甚至试着自己做数学计算,结果非常接近(误差小于2cm),除了Z轴,误差非常大,“我可以做数学计算”-好的,然后阅读这一部分,包括两个视图几何体。学生们意识到这并不那么容易,那么,读一读,然后重新开始;-)。顺便问一下,你的母语是什么?也许我们可以推荐一个合适的参考译文。为了获得主点和外部参数,您必须首先校准您的相机系统。这可以使用opencv函数stereoCalibrate完成,也可以使用著名的matlab校准工具箱。此外,cx cy绝对不是0。如果你的图像大小是[sx,sy],[cx,cy]将接近[sx/2,sy/2]。@YangKui我知道。1000x1000图片的cx,cy等于(或多或少)到(500500),而不是(0,0)。所以坐标通常是从左上角开始“计数”的,而不是从3D到2D的中心(这里我们有一个负的一半,0在中心,正的一半)。。。所以我基本上用了一个相反的等式来表示我想做什么?此外,如果相机是完全水平的,R基本上只包含0和1吗?摄像机原点的翻译到底是什么?这是否意味着距离原点的距离(在我的照片上x、y和z相交的地方)?(Ax,0,0)矩阵?是的。但你必须更深入地研究双摄像机重建。在这种情况下,通常在原点选择一个相机,并相对于第一个相机选择另一个相机。