gpt4 book ai didi

opencv - 使用OpenCV从屏幕坐标计算世界坐标

转载 作者:太空宇宙 更新时间:2023-11-03 20:42:33 25 4
gpt4 key购买 nike

我已经使用OpenCV计算了相机的内部和外部参数。
现在,我想根据屏幕坐标(u,v)计算世界坐标(x,y,z)。

我该怎么做?

N.B.当我使用kinect时,我已经知道z坐标。

任何帮助深表感谢。谢谢!

最佳答案

首先,要了解如何计算它,如果您阅读有关针孔相机模型和简单透视投影的一些知识,将对您有所帮助。快速浏览,请检查this。我会尝试更新更多。

因此,让我们从描述相机工作原理的反面开始:将世界坐标系中的3d点投影到图像中的2d点。根据相机型号:

P_screen =我* P_world

或(使用齐次坐标)

| x_screen | = I * | x_world |
| y_screen | | y_world |
| 1 | | z_world |
| 1 |

在哪里
I = | f_x    0    c_x    0 | 
| 0 f_y c_y 0 |
| 0 0 1 0 |

是3x4内在矩阵,f是焦点,c是投影的中心。

如果您解决上述系统,则会得到:
x_screen = (x_world/z_world)*f_x + c_x
y_screen = (y_world/z_world)*f_y + c_y

但是,您想做相反的事情,因此您的答案是:
x_world = (x_screen - c_x) * z_world / f_x
y_world = (y_screen - c_y) * z_world / f_y

z_world是Kinect返回给您的深度,并且您可以从内在校正中知道f和c,因此对于每个像素,您都可以应用上述值获得实际的世界坐标。

编辑1(为什么上面的值与世界坐标相对应,并且在校准过程中我们得到的外在性质是什么):

首先,检查 this one,它很好地解释了各种坐标系。

您的3d坐标系是:对象--->世界--->相机。有一种转换将您从对象坐标系转换为世界,而另一转换将您从世界坐标系统转换为摄影机(您所指的外部要素)。通常,您假定:
  • Object系统与World系统相对应
  • 或者,“摄影机”系统与“世界”系统
  • 相对应

    1.在使用Kinect 捕获对象时

    当您使用Kinect捕获对象时,从传感器返回的就是与相机的距离。这意味着z坐标已经在相机坐标中。通过使用上面的公式转换x和y,您可以得到 相机坐标中的点。

    现在,世界坐标系由您定义。一种常见的方法是假定照相机位于世界坐标系的(0,0,0)。因此,在这种情况下,外部矩阵实际上对应于单位矩阵,并且您找到的摄像机坐标对应于 世界坐标

    旁注:由于Kinect会以相机坐标返回z,因此也不需要从对象坐标系到世界坐标系的转换。例如,假设您有一个捕获面部的不同相机,并且它针对每个点返回了到 Nose 的距离(您将其视为对象坐标系的中心)。在那种情况下,由于返回的值将在对象坐标系中,因此我们确实需要一个旋转和平移矩阵才能将它们带到相机坐标系中。

    2.校准相机时

    我想您正在使用带有各种姿势的校准板使用OpenCV校准相机。通常的方法是假设电路板实际上是稳定的,并且摄像机在移动而不是相反(在两种情况下,变换都是相同的)。 这意味着现在世界坐标系对应于对象坐标系。 这样,对于每一帧,我们都会找到棋盘格边角并为其分配3d坐标,方法如下:
    std::vector<cv::Point3f> objectCorners;

    for (int i=0; i<noOfCornersInHeight; i++)
    {
    for (int j=0; j<noOfCornersInWidth; j++)
    {
    objectCorners.push_back(cv::Point3f(float(i*squareSize),float(j*squareSize), 0.0f));
    }
    }

    其中 noOfCornersInWidthnoOfCornersInHeightsquareSize取决于您的校准板。例如,如果noOfCornersInWidth = 4,noOfCornersInHeight = 3,squareSize = 100,我们将获得3d点
    (0  ,0,0)  (0  ,100,0)  (0  ,200,0)    (0  ,300,0)
    (100,0,0) (100,100,0) (100,200,0) (100,300,0)
    (200,0,0) (200,100,0) (200,200,0) (200,300,0)

    因此,这里的坐标实际上位于 对象坐标系中。 (我们任意假设板的左上角为(0,0,0),其余角的坐标均以此为准)。因此,在这里,我们确实需要旋转和变换矩阵才能将我们从物体(世界)带到相机系统。这些是OpenCV为每一帧返回的外部特性。

    总结 Kinect 情况:
  • 相机和世界同类系统被认为是相同的,因此那里不需要外部。
  • 因为Kinect返回值已经在Camera系统中,所以不需要Object to World(Camera)转换。

  • 编辑2(在使用的坐标系上):

    这是一个约定,我认为这还取决于您使用的驱动程序以及返回的数据类型。检查例如 thatthatthat one

    旁注:如果您可视化点云并对其进行一点操作,它将对您有很大帮助。您可以将点保存为3d对象格式(例如 plyobj),然后将其导入到 Meshlab这样的程序中(非常易于使用)。

    关于opencv - 使用OpenCV从屏幕坐标计算世界坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12007775/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com