2017-11-19 9 views
0

Y YUV411packedイメージをシェイダーでGiGE Visionカメラから変換しようとしました。 YUV411パックピクセルバッファはU1Y1Y2V1Y3Y4であるため、4ピクセルは6バイトです。 バッファをGL_TEXTURE_RECTANGLEのピクセル形式GL_RG8にアップロードします。OpenGL Yuv411をrgbシェーダにパックして、不良ピクセルを循環させた

頂点シェーダは非常に簡単です:

#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); 
} 

結果はご覧のように、私はサイクルを持つRGB

Yuv411packed to RGB

をYuv411packed不良ピクセルの私はどこにエラーがあるのか​​分からない。ヘルプは高く評価されます。

+0

あなたが描画しているジオメトリはどのように正確に見えますか、頂点とテクスチャは何ですか? – derhass

+0

イメージとビューポートは400x400です。頂点およびテクスコードはQVector 座標内にある{ -1.0f、-1.0f、0.0f、0.0f、 1.0f、-1.0f、1.0f、0.0f、 1.0f、1.0f、1.0f、1.0 f、 -1.0f、1.0f、0.0f、1.0f }; –

答えて

0

私の問題を解決するために、別のアプローチを使用しました。 テクスチャはGL_R8としてアップロードされますが、サイズは(幅* 1.5、高さ)に変更されます。 ビューポートは、(幅* hieght)RGBへ

頂点シェーダ

#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は今も元気に動作しますが、最初のアプローチが動作しない理由を私は知らないです。

関連する問題