2017-11-19 23 views
0

Y 쉐이더를 사용하여 GiGE Vision 카메라에서 YUV411 패키지 이미지를 변환 해 봅니다. YUV411packed 픽셀 버퍼는 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, 높이)로 수정되었습니다. 뷰포트는 RGB에

#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 지금은 잘 작동하지만, 첫 번째 방법이 작동하지 않는 이유를 모르겠어요 (폭 *의 hieght)

버텍스 쉐이더

#version 130 

uniform vec2 texSize; 
in vec4 position; 
in vec2 texCoord; 
out vec2 vTexCoord; 

void main() 
{ 
    vTexCoord = texCoord * texSize; 
    gl_Position = position; 
} 

조각 쉐이더입니다.