Y尝试使用着色器从GiGE Vision相机转换YUV411packed图像。 YUV411封装的像素缓冲区为U1Y1Y2V1Y3Y4,因此4个像素为6个字节。 我以GL_TEXTURE_RECTANGLE上传缓冲区,像素格式为GL_RG8。
顶点着色器非常简单:
#version 130
uniform vec2 texSize;
in vec4 position;
in vec2 texCoord;
out vec2 vTexCoord;
void main()
{
vTexCoord = texCoord * texSize;
gl_Position = position;
}
片段着色器
#version 130
uniform sampler2DRect tex;
uniform int stride;
in vec2 vTexCoord;
out vec4 rgb;
/*
R = 1.164(Y - 0.0625) + 1.596(V - 0.5) = (1.164 * Y) + (1.596 * V) - 0.8827
G = 1.164(Y - 0.0625) - 0.391(U - 0.5) - 0.813(V - 0.5) = (1.164 * Y) - (0.391 * U) - (0.813 * V) + 0.5173
B = 1.164(Y - 0.0625) + 2.018(U - 0.5) = (1.164 * Y) + (2.018 * U) - 1.0937
*/
const mat4 YUVtoRGB = mat4( 1.1640, 1.1640, 1.1640, 0.0,
0.0000, -0.3910, 2.0180, 0.0,
1.5960, -0.8130, 0.0000, 0.0,
-0.8827, 0.5173, -1.0937, 1.0);
vec2 fetch(vec2 coord)
{
return texture2DRect(tex, coord).rg;
}
void main()
{
int offsetX, quark;
ivec2 iCoord = ivec2(floor(vTexCoord));
offsetX = (iCoord.y * stride) + iCoord.x;
quark = 3 * (offsetX / 4);
int x = quark % stride;
int y = quark / stride;
vec2 srcTexCoord = vec2(x , y);
vec4 yuv = vec4(0.5, fetch(srcTexCoord).r, fetch(srcTexCoord + vec2(1.0, 0.0)).g, 1.0);
switch (offsetX % 4) {
case 0:
yuv.r = fetch(srcTexCoord).g;
break;
case 1:
yuv.r = fetch(srcTexCoord + vec2(1.0, 0.0)).r;
break;
case 2:
yuv.r = fetch(srcTexCoord + vec2(2.0, 0.0)).r;
break;
case 3:
yuv.r = fetch(srcTexCoord + vec2(2.0, 0.0)).g;
break;
}
rgb = clamp(YUVtoRGB * yuv, 0.0, 1.0);
}
结果Yuv411包装为RGB
正如你所看到的,我有一个坏像素周期。我无法找到我的错误。将不胜感激。
答案 0 :(得分:0)
为了解决我的问题,我使用了另一种方法。 纹理现在上传为GL_R8,但大小被修改为(宽* 1.5,高)。 视口是(宽*高)
顶点着色器
#version 130
uniform vec2 texSize;
in vec4 position;
in vec2 texCoord;
out vec2 vTexCoord;
void main()
{
vTexCoord = texCoord * texSize;
gl_Position = position;
}
片段着色器
#version 130
uniform sampler2DRect tex;
in vec2 vTexCoord;
out vec4 rgb;
/*
R = 1.164(Y - 0.0625) + 1.596(V - 0.5) = (1.164 * Y) + (1.596 * V) - 0.8827
G = 1.164(Y - 0.0625) - 0.391(U - 0.5) - 0.813(V - 0.5) = (1.164 * Y) - (0.391 * U) - (0.813 * V) + 0.5173
B = 1.164(Y - 0.0625) + 2.018(U - 0.5) = (1.164 * Y) + (2.018 * U) - 1.0937
*/
const mat4 YUVtoRGB = mat4( 1.1640, 1.1640, 1.1640, 0.0,
0.0000, -0.3910, 2.0180, 0.0,
1.5960, -0.8130, 0.0000, 0.0,
-0.8827, 0.5173, -1.0937, 1.0);
void main()
{
float xcoord = floor(vTexCoord.x);
float quarkIndex = mod(xcoord, 4.0);
vec2 coord = vec2(0.5 + (6.0 * floor(xcoord / 4.0)), vTexCoord.y);
vec4 yuv = (quarkIndex<1.0)?vec4(texture2DRect(tex, coord+vec2(1.0, 0.0)).r, texture2DRect(tex, coord).r, texture2DRect(tex, coord+vec2(3.0, 0.0)).r, 1.0)
:(quarkIndex<2.0)?vec4(texture2DRect(tex, coord+vec2(2.0, 0.0)).r, texture2DRect(tex, coord).r, texture2DRect(tex, coord+vec2(3.0, 0.0)).r, 1.0)
:(quarkIndex<3.0)?vec4(texture2DRect(tex, coord+vec2(4.0, 0.0)).r, texture2DRect(tex, coord).r, texture2DRect(tex, coord+vec2(3.0, 0.0)).r, 1.0)
:vec4(texture2DRect(tex, coord+vec2(5.0, 0.0)).r, texture2DRect(tex, coord).r, texture2DRect(tex, coord+vec2(3.0, 0.0)).r, 1.0);
rgb = clamp(YUVtoRGB * yuv, 0.0, 1.0);
}
YUV411到RGB现在工作正常,但我不知道为什么第一种方法不起作用。