c++ - OpenCV-OpenGL 互操作性

标签 c++ opencv opengl glut

我在 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();
    }
}

在网络摄像头流上使用 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;
}

注意:

  1. 建议使用 freeGLUT 而不是 GLUT,它们是两件事。 GLUT 已过时。但 freeGLUT 在扩展 GLUT 的同时继续支持最新的 OpenGL 版本。
  2. 您可能需要一个 GL loading library像GLEW一样获取GL函数指针
  3. 较新的 OpenGL (3.1+) 不再支持固定管线渲染,因此需要 VBO 和着色器。如果您的目标是较低版本的 GL,则需要指定上下文版本。这可以通过 glutInitContextVersion( int major, int minor ) 完成。网上有很多教程。

关于c++ - OpenCV-OpenGL 互操作性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15552179/

相关文章:

python - 为什么opencv视频读取fps与视频加密fps不同?

python - 如何使用cv2分割图像?

c - 理解这个 opengl 代码

java - JOGL/OPENGL 中的大型线带管理...?

C++11 (g++ thread sanitized) 用原子排序非原子操作(误报?)

c++ - AVX2是最有效的基于 mask 包装的方法吗?

C++/C 将第三方库导入到 CMake

基类未捕获 C++ 派生类异常

c++ - 没有 glVertexPointer,通用顶点属性缓冲区似乎不起作用

c++ - 使用 SOLVEPNP_EPNP 的相机姿态估计是否对异常值敏感,可以纠正吗?