2012-04-25 17 views
2

我一直在網上搜索幾天,尋找以OpenCV攝像頭捕獲並在OpenGL上下文中顯示它的最快方法。到目前爲止,這似乎工作正常,直到我需要放大。儘可能最快的OpenCV 2 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上下文中。我會測試我看到的所有內容併發布結果。

+2

'glDrawPixels()'絕對不是一個很好的方法來做到這一點。類似[this](http://www.songho.ca/opengl/gl_pbo.html#unpack)可能會更好。 – Flexo 2012-04-25 21:56:14

+0

我今天試過4種不同的方式。紋理效果不佳,因爲您需要2倍的比例,而子紋理會減慢比例。使用glu到mipmap或任何有點mipmap減緩它。使用glImage API速度很慢,因爲只有mipmap有效。到目前爲止,我嘗試過的最快的例子就是上面的例子。 – aquawicket 2012-04-26 10:58:08

+0

如何使用'glTexImage2D()'將數據上傳到NPOT紋理,然後[通過'glBegin(GL_QUADS)繪圖'](http://stackoverflow.com/a/4854802/176769)? – karlphillip 2012-05-10 18:38:08

回答

3

你確定你的openGL實現需要^ 2紋理嗎?即使非常差的PC實現(是英特爾)現在可以管理任意大小。

然後最快的可能是使用openGL的像素緩衝區 對不起的代碼是從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);  

現在得到一個指向紋理使用memeory

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 

然後把它畫 - 這應該是基本上是時刻b ecause數據被複制到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顯示格式之間轉換爲您服務。

+0

請您詳細說明一下嗎?我不明白你在「glbuffer.bind()」中綁定了什麼緩衝區。你是指FBO嗎?我不能在FBO中使用任何bind()方法......我對你的回答非常感興趣,我在這裏提出了類似的問題http://gamedev.stackexchange.com/questions/30606/opengl-fbo-to-opencv-圖片 – Dan 2012-06-14 15:34:12

+1

這是QGLBuffer http://qt-project.org/doc/qt-4.8/qglbuffer.html圍繞PBO或VBO的封裝。所以glbuffer.bind相當於一個glBindBufferARB,請參閱http://www.songho.ca/opengl/gl_pbo.html – 2012-06-14 15:37:14