我正在开发一个项目,该项目使用Kinect和OpenCV将fintertip坐标导出到Flash,以便在游戏和其他程序中使用。目前,我们的设置基于颜色,并以(x,y,z)格式将指尖输出到Flash,其中x和y以像素为单位,z以毫米为单位。
但是,我们希望将那些(x,y)坐标映射到“真实世界”值,例如毫米,使用Flash中的z深度值。
据我所知,Kinect 3D深度是通过沿着相机的水平方向投影X轴,沿着相机的垂直方向投影Y轴获得的,并且它的Z轴直接从相机的镜头向前移动。然后,深度值是从任何给定对象到XY平面绘制的垂线的长度。请参阅以下链接中的图片(从microsoft的网站获得)。
Microsoft Depth Coordinate System Example
另外,我们知道Kinect的水平视野以117度角投影。
使用这些信息,我想我可以将任何给定点的深度值投影到x = 0,y = 0线上,并在该点绘制一条平行于XY平面的水平线,与相机的视野相交。我最终得到一个三角形,分成两半,有一个物体深度的高度。然后我可以使用一点三角函数求解视场的宽度。我的等式是:
W = tan(theta / 2)* h * 2
其中:
(对不起,我不能发布图片,如果可以,我会发布)
现在,求解深度值为1000毫米(1米),值约为3264毫米。
然而,当实际看到产生的相机图像时,我得到了不同的值。也就是说,我在距离摄像机1米处放置了一根米棒,发现框架的宽度最多为1.6米,而不是估算的3.264米。
这里有什么我想念的吗?任何帮助将不胜感激。
答案 0 :(得分:4)
深度流是正确的。您确实应该获取深度值,然后从Kinect传感器中,您可以轻松找到相对于Kinect的真实世界中的点。这是通过简单的三角法完成的,但是你必须记住深度值是从Kinect“眼睛”到测量点的距离,所以它是一个长方体的对角线。
实际上,请点击此链接How to get real world coordinates (x, y, z) from a distinct object using a Kinect
重写是没有用的,你有正确的答案。
答案 1 :(得分:2)
一些事情:
A)我知道你从Kinect传感器的一个功能获得了117度FOV,但我仍然不相信这是正确的。那是一个巨大的FOV。当我在我的Kinect上运行该功能时,我实际上得到了相同的数字,但我仍然不相信它。虽然57(或某些来源的58.5)似乎很低,但它肯定更合理。尝试将Kinect放在平坦的表面上,并将物体放在其视野内并以此方式测量FOV。不精确,但我不认为你会发现它超过100度。
B)我看到一篇文章展示了实际距离与Kinect报告的深度;它不是线性的。这实际上不会影响你的1.6米触发问题,但这是你要记住的事情。
C)我强烈建议您更改代码以接受Kinect中的真实世界点。更好的是,如果可能的话,只发送更多数据。您可以继续提供当前数据,并将实际坐标数据添加到该数据上。
答案 2 :(得分:0)
矢量减法可以让你获得Kinect给出的任意两点之间的距离。您必须在特定环境中查找执行向量减法的最佳方法,但我希望无论如何这都有帮助。在我使用的Processing中,有一个PVector类,在哪里减去你只需PVector差值= PVector.sub(vector1,vector2),其中vector1和vector2是代表你的两个点的向量,差异是新的两点之间的向量。然后,您需要差异向量的大小。同样,在处理中,这只是通过magnitude = difference.mag()找到的。那个幅度应该是你想要的距离。
这里是处理中两个向量和一般向量的一个很好的概述:https://processing.org/tutorials/pvector/