将灰度 OpenCV 图像传递给 OpenGL 纹理

Posted

技术标签:

【中文标题】将灰度 OpenCV 图像传递给 OpenGL 纹理【英文标题】:Passing grayscale OpenCV image to an OpenGL texture 【发布时间】:2015-06-08 09:13:24 【问题描述】:

我想在 GLSL 着色器中使用 OpenCV 生成的灰度图像。

基于OpenCV image loading for OpenGL Texture 上的问题,我设法想出了将RGB 图像传递给着色器的代码:

cv::Mat image; 
// ...acquire and process image somehow...

//create and bind a GL texture
glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D,     // Type of texture
    0,                 // Pyramid level (for mip-mapping) - 0 is the top level
    GL_RGB, // Internal colour format to convert to
    image.cols, image.rows, // texture size
    0,                 // Border width in pixels (can either be 1 or 0)
    GL_BGR, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
    GL_UNSIGNED_BYTE,  // Image data type
    image.ptr());        // The actual image data itself

glGenerateMipmap(GL_TEXTURE_2D);

然后在片段着色器中我只使用这个纹理:

#version 330
in vec2 tCoord;

uniform sampler2D texture;

out vec4 color;

void main() 
    color = texture2D(texture, tCoord);

这一切都很好。

但现在我想对该图像进行一些灰度处理,从 cv::cvtColor(image, image, CV_BGR2GRAY); 开始,对其进行更多 OpenCV 处理,然后将灰度传递给着色器。

我认为我应该使用 GL_LUMINOSITY 作为要转换的颜色格式,也可能作为输入图像格式 - 但我得到的只是黑屏。

有人可以帮我吗?

【问题讨论】:

***.com/questions/680125/… 【参考方案1】:

输入格式

我会使用 GL_RED,因为 GL_LUMINANCE 格式一直是 deprecated

内部格式

取决于你想在你的着色器中做什么,尽管你应该总是指定一个 sized 内部格式,例如GL_RGBA8 为每个通道提供 8 位。尽管使用 GL_RGBA8,绿色、蓝色和 alpha 通道无论如何都会为零,因为您的输入数据只有一个通道,因此您可能应该改用 GL_R8 格式。另外,你可以使用texture swizzling:

GLint swizzleMask[] = GL_RED, GL_RED, GL_RED, GL_RED;
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);

当您在着色器中访问纹理时,这将导致所有通道“镜像”红色通道。

【讨论】:

谢谢! GL_RED 和 RL_R8 的组合有效,尽管片段着色器中的采样器仍然返回 vec4(r,0,0,0),而不是我预期的单个值。

以上是关于将灰度 OpenCV 图像传递给 OpenGL 纹理的主要内容,如果未能解决你的问题,请参考以下文章

opencv如何将lena.jpg的灰度值读取出来并在计算机上保存下来

OpenCV + OpenGL - 获取 OpenGL 图像作为 OpenCV 相机

opencv 提取单通道 ,转化灰度图像。

Opencv之图像灰度化

OpenCV-巴特沃斯低通&高通滤波器(C++)

OpenCV大型阵列类型Mat类