Възможно най-бързият OpenCV 2 OpenGL контекст

Търсих в мрежата от няколко дни в търсене на възможно най-бързия начин да заснема 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 контекст. Ще тествам всичко, което видя и ще публикувам резултати.


person aquawicket    schedule 25.04.2012    source източник
comment
glDrawPixels() определено не е чудесен начин да го направите. Нещо като това може да е по-добро.   -  person Flexo    schedule 26.04.2012
comment
Днес опитах 4 различни начина. Текстурите не работят добре, защото имате нужда от съотношение мощност 2 и подтекстурите го забавят. Използването на glu към mipmap или друг вид mipmap го забавя. Използването на glImage API е бавно, защото работи само mipmap. Досега най-бързият пример, който съм опитвал, е този по-горе.   -  person aquawicket    schedule 26.04.2012
comment
Какво ще кажете за качване на данните в NPOT текстура с glTexImage2D() и след това чертане през glBegin(GL_QUADS)?   -  person karlphillip    schedule 10.05.2012


Отговори (1)


Сигурни ли сте, че вашата реализация на openGL се нуждае от ^2 текстури? Дори много лоши PC реализации (да Intel) вече могат да управляват произволни размери.

Тогава най-бързият вероятно е да използвате openGL Pixel буфер Съжаляваме, кодът е от Qt, така че имената на функциите са малко по-различни, но последователността е същата

Разпределете opengl Texture

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

След това да го начертаете - това трябва да е по същество мигновено, защото данните бяха копирани в графичния процесор в картографираните повиквания по-горе

glBindTexture(GL_TEXTURE_2D,texture);                       
glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, width, height, glFormatExt, glType, 0);                                                                                  
glbuffer.release();

Като използвате различни типове за glFormat и glFormatExt, можете да накарате графичната карта автоматично да преобразува между opencVs BGR и типичните RGBA формати на дисплея за вас в хардуера.

person Martin Beckett    schedule 10.05.2012
comment
Бихте ли разяснили повече за това? Не разбирам какъв буфер обвързвате в glbuffer.bind(). Имате предвид FBO? Не мога да използвам никакъв метод bind() във FBO... Много се интересувам от вашия отговор, попитах нещо подобно тук gamedev.stackexchange.com/questions/30606/ - person Dan; 14.06.2012
comment
Това е QGLBuffer qt-project.org/doc/qt-4.8/qglbuffer.html обвивка около PBO или VBO. Така че glbuffer.bind е еквивалентен само на glBindBufferARB, вижте songho.ca/opengl/gl_pbo.html - person Martin Beckett; 14.06.2012