我想抓取一个OpenGL图像并将其输入OpenCV进行分析(作为OpenCV算法的模拟器),但我没有找到太多关于它的信息,我所能找到的只是相反的方法(将OpenCV图像放入OpenGL中)。有人能解释一下如何做到这一点吗?编辑:我将在机器人上模拟一个摄像头,因此我将实时渲染一个3D环境,并在Qt GUI中为用户显示。我将为用户提供使用真实摄像头馈送或模拟3D场景(随机器人移动而变化)的选项,两种输入的OpenCV算法将相同,因此用户可以测试他的代码,而不必一直使用真实机器人。
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?
d7v8vwbk2#
我在以前的一个研究项目中做过,这里没有太大的困难。你要做的基本上是:
cv::Mat
如另一个答案所示,阅读OpenGL纹理是调用glRead()函数的一件简单事情。您得到的通常是3或4个通道,每个数据8位(RGB / RGBA -每个通道8位),尽管这可能取决于您的实际OpenGL环境。如果颜色对您很重要,您可能需要(但不是必须)将RGB图像数据转换为BGR格式(蓝-绿色-红)。由于历史原因,这是OpenCV中的默认颜色通道顺序。例如,您可以通过调用cv::cvtColor(source, dest, cv::COLOR_RGB2BGR)来完成此操作。
glRead()
cv::cvtColor(source, dest, cv::COLOR_RGB2BGR)
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; }
希望有人觉得这个有用。
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的自述文件!
4条答案
按热度按时间iyfamqjs1#
你可能正在寻找glReadPixels函数。它会把OpenGL当前显示的任何内容下载到一个缓冲区。
对于OpenCV,您可能还需要翻转并转换为BGR。
编辑:由于只使用glReadPixels不是一种非常有效的方法,因此下面是一些使用Framebuffers和Pixel Buffer Objects进行高效传输的示例代码:How to render offscreen on OpenGL?
d7v8vwbk2#
我在以前的一个研究项目中做过,这里没有太大的困难。
你要做的基本上是:
cv::Mat
对象,然后直接处理它,或者将它复制到某个其他Matrix对象并进行处理。如另一个答案所示,阅读OpenGL纹理是调用
glRead()
函数的一件简单事情。您得到的通常是3或4个通道,每个数据8位(RGB / RGBA -每个通道8位),尽管这可能取决于您的实际OpenGL环境。如果颜色对您很重要,您可能需要(但不是必须)将RGB图像数据转换为BGR格式(蓝-绿色-红)。由于历史原因,这是OpenCV中的默认颜色通道顺序。例如,您可以通过调用
cv::cvtColor(source, dest, cv::COLOR_RGB2BGR)
来完成此操作。vsnjm48y3#
我的研究需要这个,我接受了littleimp的建议,但是修复颜色和翻转图像花了宝贵的时间来弄清楚。
这是我最后得到的结果。
希望有人觉得这个有用。
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的自述文件!