为了计算世界坐标从屏幕坐标的OpenCV(To calculate world coordinate

2019-06-27 03:14发布

我计算了相机的OpenCV的内在和外在参数。 现在,我想从计算屏幕坐标的世界坐标(X,Y,Z)(U,V)。

我该怎么做呢?

NB,因为我使用Kinect的,我已经知道z坐标。

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

Answer 1:

首先要了解您如何计算它,它会帮助你,如果你看了关于针孔相机模型和简单的透视投影一些事情。 对于一个快速一瞥,检查此 。 我会尝试更多的更新。

所以,让我们通过描述一个相机的工作原理相反的开始:项目在世界上的三维点坐标系统中我们像一个2D点。 根据相机型号:

P_screen = I * 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 |

是3×4矩阵内部函数,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(为什么上面对应于世界坐标,什么是校准过程中,我们得到的外部参数):

首先,检查这一项 ,它解释了各种坐标系统非常好。

您的3D坐标系:对象--->世界--->相机。 还有,将您从对象坐标系世界,另一种是把你从世界到相机(与外部参数你参考)的转换。 通常你假设:

  • 无论是对象系统对应与世界体系,
  • 或者,相机系统对应与世界体系

1.在捕获对象与超高动力学

当您使用Kinect的拍摄对象,什么是从传感器返回给你的是从相机的距离。 这意味着,z坐标已经在相机坐标。 通过使用上面的公式转换x和y,你在相机的坐标点。

现在,世界坐标系是由你定义。 一种常见的方法是假设世界的相机位于(0,0,0)坐标系。 所以,在这种情况下,外部参数矩阵实际上对应于单位矩阵和摄像机坐标,你发现,对应于世界坐标

旁注:由于Kinect的返回相机坐标中的Z,也有来自转型坐标系到世界坐标系没有必要从对象。 比方说,比如你有一个不同的相机拍摄的脸,每个点是从鼻子返回的距离(你认为是对象的中心坐标系)。 在这种情况下,由于返回的值将是物体坐标系中,我们的确会需要一个旋转和平移矩阵,使他们的摄像机坐标系。

2.在校准照相机

我想你正在使用使用校准板用各种姿势OpenCV的校准镜头。 通常的方法是,假定板实际上是稳定的,并且摄像机移动的,而不是相反的(变换是在两种情况下是相同的)。 这意味着,现在的世界坐标系对应于对象的坐标系。 这样一来,对于每一帧,我们找到了棋盘的角落,并为其指定三维坐标,做这样的事情:

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的情况下总结:

  • 相机和世界coodinate系统被认为是相同的,所以不需要外部参数存在。
  • 无需对象世界(相机)改造,因为Kinect的返回值已经在摄像系统。

编辑2(在坐标系统中使用的):

这是一个惯例,我想这也取决于你使用的驱动程序和你回来的数据类型。 检查例如说 , 这和那一个 。

旁注:它会帮助你很多,如果你可视化点云,起到一点点吧。 您可以保存您点3D对象格式(如帘布或OBJ ),然后只将其导入到的程序等Meshlab (非常好用)。



Answer 2:

编辑2(在坐标系统中使用的):

这是一个惯例,我想这也取决于你使用的驱动程序和你回来的数据类型。 检查例子,这和那一个。

如果您例如使用微软的SDK:那么Z不是相机,而是相机的“平面”的距离的距离。 这可能会改变相应的公式。



文章来源: To calculate world coordinates from screen coordinates with OpenCV