使用openCV和openGL从Webcam显示图像

时间:2015-01-18 15:56:18

标签: opencv opengl

我正在使用openCV从网络摄像头拍摄照片。然后应该将帧转换为openGL纹理并显示在屏幕上。我得到了以下代码,但窗口仍为黑色。我对openGL很新,并且没有更多的想法,为什么它不起作用。

int main ()
{
    int w = 800,h=600;

    glfwInit();

    //configure glfw 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);


    GLFWwindow* window = glfwCreateWindow(w, h, "OpenGL", NULL, nullptr); // windowed
    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    glewInit();

    initializeCapturing();

    //init GL
    glViewport(0, 0, w, h); // use a screen size of WIDTH x HEIGHT
    glEnable(GL_TEXTURE_2D);     // Enable 2D texturing

    glMatrixMode(GL_PROJECTION);     // Make a simple 2D projection on the entire window
    glLoadIdentity();
    glOrtho(0.0, w, h, 0.0, 0.0, 100.0);

    glMatrixMode(GL_MODELVIEW);    // Set the matrix mode to object modeling

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClearDepth(0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the window

    cv::Mat frame;
    captureFromWebcam(frame,capture0);


    /* OpenGL texture binding of the image loaded by DevIL  */
    GLuint texid;
    glGenTextures(1, &texid); /* Texture name generation */
    glBindTexture(GL_TEXTURE_2D, texid); /* Binding of texture name */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */
    glTexImage2D(GL_TEXTURE_2D, 0,3, frame.size().width, frame.size().height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); /* Texture specification */


    while(!glfwWindowShouldClose(window))
    {
        glfwPollEvents();

        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, GL_TRUE);

        // Clear color and depth buffers
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       glBindTexture(GL_TEXTURE_2D,texid);
       glMatrixMode(GL_MODELVIEW);     // Operate on model-view matrix

        /* Draw a quad */
       glBegin(GL_QUADS);
           glTexCoord2i(0, 0); glVertex2i(0,   0);
           glTexCoord2i(0, 1); glVertex2i(0,   h);
           glTexCoord2i(1, 1); glVertex2i(w, h);
           glTexCoord2i(1, 0); glVertex2i(w, 0);
       glEnd();
       glFlush();
       glfwSwapBuffers(window);
    }


    releaseCapturing();
    glfwTerminate();

    return 1;
}

和其他程序

cv::VideoCapture capture0;
cv::VideoCapture capture1;

void captureFromWebcam(cv::Mat &frame, cv::VideoCapture &capture)
{
    capture.read(frame);
}

bool initializeCapturing()
{
    capture0.open(0);
    capture1.open(1);

    if(!capture0.isOpened() | !capture1.isOpened())
    {
        std::cout << "Ein oder mehrere VideoCaptures konnten nicht geöffnet werden" << std::endl;

        if(!capture0.isOpened())
            capture0.release(); 
        if(!capture1.isOpened())
            capture1.release();
        return false;
    }

    return true;
}

void releaseCapturing()
{
    capture0.release();
    capture1.release();
}

2 个答案:

答案 0 :(得分:3)

看起来你混合了几个在不同地方找到的代码片段。您正在寻找一个OpenGL 3.2 核心配置文件。但是您使用的绘图代码是具有固定功能管道的立即模式,在核心配置文件中不可用。您基本上要求现代GL上下文,但绘图代码已完全过时,并且您选择的GL版本不再支持它。

作为快速解决方法,您只需删除以下行:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

这样做应该为您提供一些遗留GL上下文或某些现代上下文的兼容性配置文件,具体取决于您使用的GL实现的操作系统。但是,您可以从中获得至少以这种方式获得OpenGL 2.1(除非在很旧的硬件上根本不支持GL2,但即使这样对您的代码也是如此)。其余的代码应该在这样的上下文中工作。

我仍然建议你学习现代GL,而不是你在这里使用旧的,已弃用的遗留物。

答案 1 :(得分:0)

您没有从框架中设置指针。

glTexImage2D(GL_TEXTURE_2D, 0,3, frame.size().width, frame.size().height, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)frame.data()); /* Texture specification */

使用此代码,您只能获得第一帧。

put&#34; captureFromWebcam&#34;并在里面加载纹理。

(对不起我的英文)