【问题标题】:OpenGL ES - get 2D pixel coordinate from camera positionOpenGL ES - 从相机位置获取 2D 像素坐标
【发布时间】:2016-12-08 19:29:37
【问题描述】:

我正在使用 OpenGL ES (IOS) 和 OpenCV。我想知道是否有办法从 GLKMatrix4 相机位置获取 2D 像素坐标?

确实,我有一个使用 OpenGL 显示的特定 3D 对象,它只有它的大小和相机姿势,我想将它转换为 OpenCV 参考坐标,即 2D 像素。

更准确地说,我有一个 IOS 应用程序,我可以流式传输相机颜色。这个流在我的 Ipad 上用 OpenGL 显示。在这个显示器上,我有一个特定的叠加层,它是一个 3D 对象。同时,我用 OpenCV 做了一些检测。现在,我想将我的检测结果与我的框架中的 OpenCV(这是一个矩形绘制)关联起来,但是对于这个,我只有它的相机位置和它的大小。

我知道 4x4 相机姿势的内容,但没有找到任何关于如何将其(如果可能)转换为 2D 坐标的信息。

简单地说: 输入:一个 2D 矩形(仅获取 2D 坐标)和一个 3D 对象(仅获取其相机位置)

有办法吗?你能帮帮我吗?

谢谢

【问题讨论】:

  • 您是要获得由矩阵表示的像素还是由向量乘以矩阵表示的像素?解释你的意见究竟是什么。
  • 我刚刚编辑了我的帖子。实际上是的,我想从我的 3D 对象的相机姿势(矩阵 4x4)中获得 2D 坐标(像素)。感谢 Matic。
  • 最初发布于Robotics,但在此处重复发布后迁移。

标签: c++ ios objective-c opencv opengl-es


【解决方案1】:

要获得矢量的屏幕投影,您只需将其乘以您在 openGL 中使用的矩阵。第三个坐标被简单地丢弃,仅用于深度缓冲区(也是插值,但在这里并不重要)。

在 openGL 中,通过将其与矩阵相乘得到的绘制像素的坐标将被归一化为所有轴上范围 [-1,1] 的坐标系。这意味着位于屏幕/视图最左上角的像素将具有坐标(-1,1)、右上角(1,1)、中心(0,0)...现在对应于缓冲区像素,此值必须非规范化:

您需要有缓冲区widthheight,因此像素位置为bufferX = ((x+1)/2.0) * widthbufferY = ((y+1)/2.0) * height。结果是浮点值,因此您需要将它们四舍五入为整数或对它们进行类型转换。我不知道 openGL 是做什么的。

【讨论】:

  • 不要忘记检查坐标是否真的在缓冲区内...
  • 感谢您的回复,但我只有对象的相机位置,仅此而已。那么我需要分解这个相机位置吗?
  • 如果我理解正确,您只需将零向量与矩阵相乘即可​​。或者您可能只取矩阵的变换向量(第 4 行)并将其用作结果。
  • 是的,好吧,假设我拿第四行来获取我的位置 float posX =cubePose.m30;float posY = cubePose.m31;posZ =_slamState.cubePose.m32;我的坐标似乎介于 - 1 和 1(OpenGL 坐标)之间,那么我该如何恢复屏幕坐标(例如 640x420)?谢谢
  • 你确定 m30, 31.. 是正确的吗?不是m40、41..吗?无论如何,您只需要如上所述应用变换的 2 个坐标。您需要首先使用 (x+1)/2 将它们标准化为 [0,1],然后将它们缩放到缓冲区大小,即 (x+1)/2*bufferWidth。如果您还没有缓冲区的大小,应该可以通过 openGL API 访问它们。
【解决方案2】:

由于您已经在使用 GLKit 类型和数学,请尝试使用函数 GLKMathProject 将 3D 模型空间转换为视口(窗口/像素 2D)空间,如果您还需要其他方法,请尝试使用 GLKMathUnproject。您将需要(可能)传递给着色器以绘制场景的(相同)模型视图和投影矩阵。

【讨论】:

    猜你喜欢
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多