相关文章推荐
暴躁的香烟  ·  opencv yuv转rgb - CSDN文库·  昨天    · 
逆袭的鸵鸟  ·  python opencv yuv 转 ...·  昨天    · 
任性的紫菜  ·  File path formats on ...·  1 月前    · 
耍酷的菠菜  ·  LNK1000 Internal ...·  3 月前    · 
低调的登山鞋  ·  c# comboBox控件 ...·  1 年前    · 

色彩的二次抽样

在RGB颜色模式下,每个像素点由Red、Green、Blue三种颜色组合而成,YUV使用色彩通道UV和亮度通道Y,这种格式更适合图像处理领域,图片的所有细节保存在亮度通道中,如果没有亮度,图片就是一张灰度图片,人的眼睛对亮度的敏感度要高于颜色,所以可以通过减少每个像素点的颜色值,达到效果比较好的压缩,这个减少颜色数据的过程就是色彩的二次抽样

YUV转RGB绘制纹理

纹理映射只能在RGBA方式下执行,摄像头采集YUV,需要把YUV转换成RGBA

  • 获取到视频帧的YUV数据
  • CoreVideo进行分离Y分量和UV分量
  • Fragment Shader对Y分量和UV分量进行采样
  • Fragment Shader转换YUV到RGB
  • 进行渲染

看一下BT.601的RGB到YUV的转换算法

R' = 1.164*(Y’-16) + 1.596*(Cr'-128)
G' = 1.164*(Y’-16) - 0.392*(Cb'-128) - 0.813*(Cr'-128) 
B' = 1.164*(Y’-16) + 2.017*(Cb'-128)
// 其中括号里面的是做伽马矫正用的

所以我们的转换矩阵可以这样写

  mat3( 1.164,     1.164,     1.164,
          0.0,    -0.392,     2.017,
        1.596,    -0.813,       0.0,)

Fragment Shader中的转换下面这样写

varying highp vec2 texCoordVarying;
precision mediump float;
uniform sampler2D SamplerY;
uniform sampler2D SamplerUV;
uniform mat3 colorConversionMatrix;
void main() {
    mediump vec3 yuv;
    lowp vec3 rgb;
    yuv.x = (texture2D(SamplerY, texCoordVarying).r);// - (16.0/255.0));
    yuv.yz = (texture2D(SamplerUV, texCoordVarying).ra - vec2(0.5, 0.5));
    rgb = colorConversionMatrix * yuv;
    gl_FragColor = vec4(rgb, 1);
                    色彩的二次抽样在RGB颜色模式下,每个像素点由Red、Green、Blue三种颜色组合而成,YUV使用色彩通道UV和亮度通道Y,这种格式更适合图像处理领域,图片的所有细节保存在亮度通道中,如果没有亮度,图片就是一张灰度图片,人的眼睛对亮度的敏感度要高于颜色,所以可以通过减少每个像素点的颜色值,达到效果比较好的压缩,这个减少颜色数据的过程就是色彩的二次抽样YUV转RGB绘制纹理纹理映射只能在RGBA方式下执行,摄像头采集YUV,需要把YUV转换成RGBA获取到视频帧的YUV数据Core
 * Very simple example of how to perform YUV->RGB (YCrCb->RGB)
 * conversion with an OpenGL fragmen shader. The data (not included)
 * is presumed to be three files with Y, U and V samples for a 720x576
 * pixels large image.
 * Note! The examp
				
GPU 实现 RGB -- YUV RGB --> YUV 换的公式是现成的,直接在 CPU 端换的话,只需要遍历每个像素,得到新的 YUV 值,根据其内存分布规律,合理安排分布即可。然而在 CPU 端进行换,存在的问题运行效率太低,无法满足高效换的需求。我们将目光投向拥有流水线体系的支持高速浮点数计算的硬件——GPU. 换公式如下: GPU 上面的实现 考虑在 GP...
* Very simple example of how to perform YUV->RGB (YCrCb->RGB) * conversion with an OpenGL fragmen shader. The data (not included) * is presumed to be three files with Y, U and V samples for a 72 2. 将YUV数据绑定到一个纹理单元上。 3. 创建一个着色器程序,用于将YUV数据换为RGB格式。 4. 将纹理对象绑定到FBO(Frame Buffer Object),并将着色器程序与FBO绑定。 5. 渲染FBO以将YUV数据换为RGB格式。 下面是一个简单的代码示例: 1. 创建纹理对象 GLuint textureID; glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 2. 绑定YUV数据到纹理单元 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, yData); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width / 2, height / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, uvData); 3. 创建着色器程序 const char* vertexShader = "attribute vec4 position;\n" "attribute vec2 texCoord;\n" "varying vec2 v_texCoord;\n" "void main()\n" "{\n" " gl_Position = position;\n" " v_texCoord = texCoord;\n" "}\n"; const char* fragmentShader = "precision highp float;\n" "varying vec2 v_texCoord;\n" "uniform sampler2D yTexture;\n" "uniform sampler2D uvTexture;\n" "void main()\n" "{\n" " float y = texture2D(yTexture, v_texCoord).r;\n" " float u = texture2D(uvTexture, v_texCoord).r - 0.5;\n" " float v = texture2D(uvTexture, v_texCoord).a - 0.5;\n" " float r = y + 1.13983 * v;\n" " float g = y - 0.39465 * u - 0.58060 * v;\n" " float b = y + 2.03211 * u;\n" " gl_FragColor = vec4(r, g, b, 1.0);\n" "}\n"; GLuint programID = glCreateProgram(); GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShaderID, 1, &vertexShader, NULL); glCompileShader(vertexShaderID); glAttachShader(programID, vertexShaderID); GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShaderID, 1, &fragmentShader, NULL); glCompileShader(fragmentShaderID); glAttachShader(programID, fragmentShaderID); glLinkProgram(programID); glUseProgram(programID); 4. 绑定纹理对象到FBO,并将着色器程序与FBO绑定 GLuint fboID; glGenFramebuffers(1, &fboID); glBindFramebuffer(GL_FRAMEBUFFER, fboID); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0); glViewport(0, 0, width, height); glUseProgram(programID); glUniform1i(glGetUniformLocation(programID, "yTexture"), 0); glUniform1i(glGetUniformLocation(programID, "uvTexture"), 1); 5. 渲染FBO GLfloat vertices[] = { -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f GLubyte indices[] = {0, 1, 2, 3}; glVertexAttribPointer(glGetAttribLocation(programID, "position"), 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), vertices); glVertexAttribPointer(glGetAttribLocation(programID, "texCoord"), 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), vertices + 2); glEnableVertexAttribArray(glGetAttribLocation(programID, "position")); glEnableVertexAttribArray(glGetAttribLocation(programID, "texCoord")); glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices); glDisableVertexAttribArray(glGetAttribLocation(programID, "position")); glDisableVertexAttribArray(glGetAttribLocation(programID, "texCoord")); Unity 打包warning:Missing Project ID和Unable to access Unityservices.Please log in,or request ...... ଘ(੭ˊᵕˋ)੭* ੈkg: 没有organaization C++ 保存Excel文件(带密码保护) zyw169888: 已知密码,怎么在后台打开呢? Unity Shader之磨砂玻璃与水雾玻璃效果 seed_ling: 所以这个只支持2D的UI吗?就是canvas的render mode必须是Screen Space吗~? Unity 工具之 UniWebView 内嵌网页/浏览器到应用中,并且根据UGUI大小放置(简单适配UGUI) 一切皆会: 你这最后页面显示效果明显被放大了,而且没显示全,怎么做到网页在Ui中1:1大小显示呢? 直播换脸后,我们来搞搞微信QQ聊天换脸!| avatarify 2401_85850341: https://links.jianshu.com/go?to=https%3A%2F%2Fwww.tonyisstark.com%2F324.html