使用 openCV 和 openGL 显示来自网络摄像头的图像

Display a image from the Webcam using openCV and openGL

我正在使用 openCV 从网络摄像头捕捉照片。然后帧应该被转换成 openGL 纹理并显示在屏幕上。我得到以下代码,但 window 仍然是黑色。我是 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();
}

您似乎混合了在不同地方找到的多个代码片段。您正在请求 OpenGL 3.2 core 配置文件。但是您使用的绘图代码是具有固定功能管道的即时模式,在核心配置文件中不可用。您基本上请求了一个现代 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,而不是您在这里使用的旧的、已弃用的旧东西。

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

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

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

放入 "captureFromWebcam" 并在 while 内加载纹理。

(对不起我的英语)