OpenCV与OpenGL的互操作性

OpenCV与OpenGL的互操作性,opengl,opencv,Opengl,Opencv,我在Linux下,使用OpenGL支持编译OpenCV 2.4.4,但我不知道如何使用OpenGL_interop.hpp函数(其中一些函数甚至没有文档记录,至少在我的文档版本上是这样)。查看启用OpenGL部分中的window.cpp,我发现了一些关于函数setOpenGLContext、setOpenGLDrawCallback和updateView使用的提示,但即使是这段非常简单的代码,我也无法使用: #include <opencv2/opencv.hpp> #include

我在Linux下,使用OpenGL支持编译OpenCV 2.4.4,但我不知道如何使用OpenGL_interop.hpp函数(其中一些函数甚至没有文档记录,至少在我的文档版本上是这样)。查看启用OpenGL部分中的window.cpp,我发现了一些关于函数setOpenGLContext、setOpenGLDrawCallback和updateView使用的提示,但即使是这段非常简单的代码,我也无法使用:

#include <opencv2/opencv.hpp>
#include <GL/gl.h>
#include <GL/glut.h>
#include <opencv2/core/opengl_interop.hpp>

using namespace cv;

void on_opengl(void* userdata);

int main(void)
{
    VideoCapture webcam(CV_CAP_ANY);
    Mat frame;
    namedWindow("window", CV_WINDOW_OPENGL);
    setOpenGlContext("window");
    while(waitKey(30) < 0)
    {
        webcam >> frame;
        setOpenGlDrawCallback("window", on_opengl);
        imshow("window", frame);
        updateWindow("window");
    }

    return 0;
}

void on_opengl(void* userdata)
{
    glLoadIdentity();

    glTranslated(0.0, 0.0, 1.0);

    glRotatef( 55, 1, 0, 0 );
    glRotatef( 45, 0, 1, 0 );
    glRotatef( 0, 0, 0, 1 );

    static const int coords[6][4][3] = {
        { { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } },
        { { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } },
        { { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } },
        { { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } },
        { { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } },
        { { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } }
    };

    for (int i = 0; i < 6; ++i) {
                glColor3ub( i*20, 100+i*10, i*42 );
                glBegin(GL_QUADS);
                for (int j = 0; j < 4; ++j) {
                        glVertex3d(0.2*coords[i][j][0], 0.2 * coords[i][j][1], 0.2*coords[i][j][2]);
                }
                glEnd();
    }
}
#包括
#包括
#包括
#包括
使用名称空间cv;
opengl上的void(void*userdata);
内部主(空)
{
视频捕获网络摄像头(CV_CAP_ANY);
垫架;
namedWindow(“窗口”,CV\u window\u OPENGL);
setOpenGlContext(“窗口”);
while(等待键(30)<0)
{
网络摄像头>>框架;
setOpenGlDrawCallback(“窗口”,在opengl上);
imshow(“窗口”,框架);
更新窗口(“窗口”);
}
返回0;
}
opengl上的void(void*userdata)
{
glLoadIdentity();
(0.0,0.0,1.0);
glRotatef(55,1,0,0);
glRotatef(45,0,1,0);
glRotatef(0,0,0,1);
静态常数int坐标[6][4][3]={
{ { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } },
{ { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } },
{ { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } },
{ { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } },
{ { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } },
{ { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } }
};
对于(int i=0;i<6;++i){
glColor3ub(i*20、100+i*10、i*42);
glBegin(GL_QUADS);
对于(int j=0;j<4;++j){
glVertex3d(0.2*coords[i][j][0]、0.2*coords[i][j][1]、0.2*coords[i][j][2];
}
格伦德();
}
}

在网络摄像头流上使用opengl的正确方法是什么?再见

为我的英语不好道歉,因为它不是我的母语

OpenGL是为绘制图形而设计的,OpenCV是为计算机视觉而设计的。因此,我建议您在基于GL的应用程序中使用CV,而不是使用CV API进行渲染、回调等

如果您只需要一个简单的演示,那么您可以使用freeGLUT编写一个非常简单的程序,其中包含一些回调,freeGLUT将处理窗口回调和GL上下文创建。(GLFW或Qt也可以)在程序中,使用
cv::ogl::Texture2D
类处理纹理对象。使用
Texture2D::copyFrom(…)
Texture2D::copyTo(…)
处理设备/主机内存传输。在渲染回调内部,使用标准GL例程绘制全屏矩形。尽管这种方法效率不高,但它是有效的

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <opencv2/opencv.hpp>
#include <opencv2/core/opengl_interop.hpp>

using namespace cv;

//Global vars
Texture2D g_img;
void timer_cb( int )
{
    //...Update the content of g_img
}

void resize_cb( int w, int h ) { /*...*/ }
void render_cb() {
    /* ...render g_img here */
    g_img.bind();
#ifdef USE_FIXED_PIPELINE
//use fixed pipeline for old-school GL rendering
    glMatrixMode( GL_MODELVIEW );
    //Do some transformation
    glBegin(GL_QUADS);
        glTexCoord(...);
        glVertex**(...);
        ...
    glEnd();
#else
//use shaders and VBOs for 3.1+ GL
    glBindProgram( ... );
    glBindBuffer( ... );
    glVertexAttribPointer( ... );
    glDrawArrays( ... );
#endif
}
int main( int argc, char** argv )
{
    //...init GLUT, GLEW and other stuff
    glutMainLoop();
    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间cv;
//全局变量
纹理2d g_img;
无效计时器\u cb(内部)
{
//…更新g_img的内容
}
void resize_cb(int w,int h){/*…*/}
void render_cb(){
/*…在这里渲染g_img*/
g_img.bind();
#ifdef使用固定管道
//使用固定管道进行旧式GL渲染
glMatrixMode(GLU模型视图);
//做一些改变
glBegin(GL_QUADS);
glTexCoord(…);
glVertex**(…);
...
格伦德();
#否则
//对3.1+GL使用着色器和VBO
glBindProgram(…);
glBindBuffer(…);
glvertexattributepointer(…);
GLD阵列(…);
#恩迪夫
}
int main(int argc,字符**argv)
{
//…包括超负荷、GLEW和其他东西
glutMainLoop();
返回0;
}
注:

a。推荐自由过剩而不是过剩,这是两件事。GLUT已经过时了,但freeGLUT在扩展GLUT的同时仍然支持最新的OpenGL版本

b。您可能需要一个类似的GLEW来获取GL函数指针

c。较新的OpenGL(3.1+)不再支持固定管道渲染,因此需要VBOs和着色器。如果目标是较低版本的总账,则需要指定上下文版本。这可以通过
glutInitContextVersion(int-major,int-minor)
实现。网上有很多教程