我已经在网上搜索了几天,寻找最快的方式来获取OpenCV网络摄像头捕获并在OpenGL上下文中显示它。到目前为止,这似乎工作正常,直到我需要缩放。
void Camera::DrawIplImage1(IplImage *image, int x, int y, GLfloat xZoom, GLfloat yZoom)
{
GLenum format;
switch(image->nChannels) {
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_BGR;
break;
default:
return;
}
yZoom =- yZoom;
glRasterPos2i(x, y);
glPixelZoom(xZoom, yZoom); //Slow when not (1.0f, 1.0f);
glDrawPixels(image->width, image->height, format, GL_UNSIGNED_BYTE, image->imageData);
}
我听说过采取FBO方法可能会更快。有关将OpenCV网络摄像头捕获到OpenGL上下文的最快方法的任何想法。我将测试我看到的所有内容并发布结果。
答案 0 :(得分:3)
你确定你的openGL实现需要^ 2纹理吗?即使非常糟糕的PC实现(是英特尔)也可以管理任意大小。
然后最快的可能是使用openGL Pixel缓冲区 对不起,代码来自Qt,因此函数名称略有不同,但序列相同
分配opengl纹理
glEnable(GL_TEXTURE_2D);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, width, height, 0, glFormatExt, glType, NULL );
glDisable(GL_TEXTURE_2D);
现在获取一个指向纹理的指针以使用记忆
glbuffer.bind();
unsigned char *dest = (unsigned char*)glbuffer.map(QGLBuffer::ReadWrite);
// creates an openCV image but the pixel data is stored in an opengl buffer
cv::Mat opencvImage(rows,cols,CV_TYPE,dest);
.... do stuff ....
glbuffer.unmap(); // pointer is no longer valid - so neither is openCV image
然后绘制它 - 这应该是基本上即时的,因为数据在上面的映射调用中被复制到GPU
glBindTexture(GL_TEXTURE_2D,texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, width, height, glFormatExt, glType, 0);
glbuffer.release();
通过为glFormat和glFormatExt使用不同的类型,您可以让显卡在硬件中自动在opencVs BGR和典型的RGBA显示格式之间进行转换。