Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 如何将视频(帧)输入GLSL着色器_Opencv_Opengl_Glsl_Video Processing - Fatal编程技术网

Opencv 如何将视频(帧)输入GLSL着色器

Opencv 如何将视频(帧)输入GLSL着色器,opencv,opengl,glsl,video-processing,Opencv,Opengl,Glsl,Video Processing,我正在尝试使用GLSL进行视频处理。我使用OpenCV打开一个视频文件,并将每个帧作为单个图像,然后我想在GLSL着色器中使用每个帧 使用GLSL视频的最佳/理想/智能解决方案是什么 从视频中阅读 图像到纹理 我的渲染while循环中需要什么? 是否每次都需要重新编译/重新连接/重新链接着色器?或者,一旦我的着色器被创建和编译并且我使用了glUseProgram(shaderProgram)我可以继续发送新的纹理吗 我用来在屏幕上渲染纹理的当前循环如下所示。我怎样才能使其适应视频工作?我需要在哪

我正在尝试使用GLSL进行视频处理。我使用OpenCV打开一个视频文件,并将每个帧作为单个图像,然后我想在GLSL着色器中使用每个帧

使用GLSL视频的最佳/理想/智能解决方案是什么

从视频中阅读 图像到纹理 我的渲染while循环中需要什么? 是否每次都需要重新编译/重新连接/重新链接着色器?或者,一旦我的着色器被创建和编译并且我使用了
glUseProgram(shaderProgram)
我可以继续发送新的纹理吗

我用来在屏幕上渲染纹理的当前循环如下所示。我怎样才能使其适应视频工作?我需要在哪里调用以更新着色器中使用的纹理

while(!glfwWindowShouldClose(window))
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glViewport(0,0,512,512);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBlitFramebuffer(0, 0, image.cols, image.rows, 0, 0, image.cols, image.rows, GL_COLOR_BUFFER_BIT, GL_LINEAR);


    glfwSwapBuffers(window);
    glfwPollEvents();
}

不需要使用帧缓冲区将纹理发送到着色器。一旦将纹理0选择为活动纹理,并将0设置为着色器中统一采样器2D的值,每次调用
glBindTexture()
,它都会将采样器2D设置为在函数参数中指定的任何纹理。因此,不需要每次更改纹理时都重新链接或重新编译着色器。

让我们澄清一些在循环之前需要发生的事情:

  • 使用
    glPixelStorei()
    设置像素存储模式
  • 使用
    glGenTextures()
    只生成一个纹理,因为在循环的每次迭代中,其内容都将被新数据替换
  • 使用
    glCompileShader()
    编译着色器,使用
    glCreateShader()
    创建着色器对象,调用
    glCreateProgram()
    创建程序,调用
    glAttachShader()
    将着色器对象附加到新程序,最后调用
    glLinkProgram()
    准备就绪
也就是说,循环的每个迭代必须:

  • 清除颜色和深度缓冲区
  • 使用标识矩阵加载modelview矩阵
  • 指定要绘制图形的位置
    glTranslatef()
  • 从视频中检索新帧
  • 启用相应的纹理目标,绑定它,然后使用
    glTexImage2D()
    将帧传输到GPU
  • 调用
    glUseProgram()
    以激活GLSL着色器
  • 使用
    GL_四边形
    或其他工具绘制二维面
  • 使用
    glUseProgram(0)
    禁用程序
  • 使用
    glDisable(GL_texture\u YOUR_texture\u target)
    禁用纹理目标
这或多或少是我们需要做的

顺便说一句:从相机检索帧并在窗口中显示。不过,没有着色器


祝你好运

IplImages是过去的爆炸。使用cv::Mat和cv::VideoCaptureOk,我将其更新为使用cv::Mat.downvote。请对捕获执行相同的操作。你的帖子将永远保留SO@karlphillip我刚刚开始了这个网页,这是一个正在进行的工作,但是感谢您的输入:)哦,这就是我在示例代码中使用帧缓冲区对象的原因。因为我实际上是同时处理两个视频流。我需要从着色器中取出两帧。因此,我使用了
COLOR\u ATTACHMENT0
COLOR\u ATTACHMENT1
您始终可以同时绑定两个纹理,一个使用纹理槽0,一个使用纹理槽1,然后在着色器中有两个
sampler2D
s。感谢您概述了非常容易遵循的步骤
 GLuint tex;
 glGenTextures(1, tex);
 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D, tex);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.cols, image.rows, 0,
                GL_BGR, GL_UNSIGNED_BYTE, image.data);

 glUniform1i(glGetUniformLocation(shaderProgram, "Texture"), 0);
while(!glfwWindowShouldClose(window))
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glViewport(0,0,512,512);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBlitFramebuffer(0, 0, image.cols, image.rows, 0, 0, image.cols, image.rows, GL_COLOR_BUFFER_BIT, GL_LINEAR);


    glfwSwapBuffers(window);
    glfwPollEvents();
}