OpenCV + OpenGL -将OpenGL图像作为OpenCV摄像头获取

u59ebvdq  于 2022-11-04  发布在  其他
关注(0)|答案(4)|浏览(227)

我想抓取一个OpenGL图像并将其输入OpenCV进行分析(作为OpenCV算法的模拟器),但我没有找到太多关于它的信息,我所能找到的只是相反的方法(将OpenCV图像放入OpenGL中)。有人能解释一下如何做到这一点吗?
编辑:
我将在机器人上模拟一个摄像头,因此我将实时渲染一个3D环境,并在Qt GUI中为用户显示。我将为用户提供使用真实摄像头馈送或模拟3D场景(随机器人移动而变化)的选项,两种输入的OpenCV算法将相同,因此用户可以测试他的代码,而不必一直使用真实机器人。

iyfamqjs

iyfamqjs1#

你可能正在寻找glReadPixels函数。它会把OpenGL当前显示的任何内容下载到一个缓冲区。

unsigned char* buffer = new unsigned char[width*height*3];
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
cv::Mat image(height, width, CV_8UC3, buffer);
cv::imshow("Show Image", image);

对于OpenCV,您可能还需要翻转并转换为BGR。
编辑:由于只使用glReadPixels不是一种非常有效的方法,因此下面是一些使用Framebuffers和Pixel Buffer Objects进行高效传输的示例代码:How to render offscreen on OpenGL?

d7v8vwbk

d7v8vwbk2#

我在以前的一个研究项目中做过,这里没有太大的困难。
你要做的基本上是:

  • 从OpenGL向某个预分配存储器缓冲区进行纹理读取;
  • 应用一些几何变换(翻转X和/或Y坐标),以说明OpenGL和OpenCV之间可能存在的不同坐标框架。这是一个细节,但有助于可视化(提示:使用一个内部带有F字母的纹理来快速找到你需要翻转的坐标!);
  • 您可以直接在预分配内存缓冲区周围构建OpenCV cv::Mat对象,然后直接处理它,或者将它复制到某个其他Matrix对象并进行处理。

如另一个答案所示,阅读OpenGL纹理是调用glRead()函数的一件简单事情。您得到的通常是3或4个通道,每个数据8位(RGB / RGBA -每个通道8位),尽管这可能取决于您的实际OpenGL环境。
如果颜色对您很重要,您可能需要(但不是必须)将RGB图像数据转换为BGR格式(蓝-绿色-红)。由于历史原因,这是OpenCV中的默认颜色通道顺序。例如,您可以通过调用cv::cvtColor(source, dest, cv::COLOR_RGB2BGR)来完成此操作。

vsnjm48y

vsnjm48y3#

我的研究需要这个,我接受了littleimp的建议,但是修复颜色和翻转图像花了宝贵的时间来弄清楚。
这是我最后得到的结果。

typedef Mat Image ;

typedef struct {
  int width;
  int height;
  char* title;
  float field_of_view_angle;
  float z_near;
  float z_far;
} glutWindow;

glutWindow win;

Image glutTakeCVImage() {
  // take a picture within glut and return formatted
  // for use in openCV
  int width = win.width;
  int height = win.height;
  unsigned char* buffer = new unsigned char[width*height*3];
  glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
  Image img(height, width, CV_8UC3, buffer);
  Image flipped_img;
  flip(img,flipped_img,0);
  Image BGR_img;
  cvtColor(flipped_img,BGR_img, COLOR_RGB2BGR);
  return BGR_img;
}

希望有人觉得这个有用。

hzbexzde

hzbexzde4#

有一个OpenGL/OpenCV互操作API:https://docs.opencv.org/4.x/d2/d3c/group__core__opengl.html。这应该会使事情比你目前的方法更容易和更快。我写了一个演示,使用OpenCL/OpenGL/VAAPI互操作来解码视频,在顶部渲染,做一些opencl计算和编码视频-所有这些都在GPU上,而不需要在步骤之间复制回来。
https://github.com/kallaballa/GCV/blob/main/src/camera/camera-demo.cpp
请注意repo的自述文件!

相关问题