Tistory View

Android Develop/GLES2.0

YUV shader

God Dangchy What should I do? 2017. 10. 30. 18:42

동영상이나 디지털인식장치(카메라 등등)을 사용할 때, 이미지의 정보가 RGB보다는 YUV색을 쓰는 경우가 많다.


이 YUV로 표현된 형태를 Texture등으로 만들어야 할 경우 RGB 색공간으로 변환하는 작업을 해야 하는 데, 이미지라는 상당히 큰 데이터를 다루는 문제라 실제 변환작업은 영상의 frame-rate를 떨어뜨릴 정도로 부하가 걸린다.

이 변환작업만으로 완성된 결과가 나오면, 상관없을 정도지만, 이 것뿐만아니라 다른 작업또한 부하가 걸리니, 이 작업의 부하를 좀 줄일 필요가 있다.


실제 카메라등에서 넘어오는 데이터는 그 들만의 형태를 가지게 되는 데, 이 것을 변환하는 작업은 2부분으로 주로 나뉜다.

1 ) 처음에는 color pixel의 배치가 순서대로 되어 있지 않으므로(보통 Y-U-V가 따로 떨어져있다.), 이를 packed(+1)시켜야 한다.

2 ) 두번째는 이 Packing을 하는 과정 중에 각 Pixel의 YUV색을 RGB로 변환을 해야 한다.


1번작업도 부하가 들지만 2번 작업에서 더 많은 부하가 발생한다. 단순한 연산이지만 픽셀마다 그 것도 RGB 세번 연산해야한다.


2번의 작업을 CPU를 통하지 말고 shader에서 처리한다면 부하가 GPU로 분산되어 부하가 느껴지지 않을 정도로 성능이 향상된다. 실제 GPU는 이런 연산하라고 있는 거라, 이 작업을 수행하기에는 적절한 위치다.


RGB색을 YUV색으로 변환하는 shader코드는 다음과 같다. 색을 다루는 부분이니 fragment-shader 코드내에 위치하게 될 것이다.

vec4 yuv2rgb( float y, float u, float v, float a ) {

float r = clamp( y + 1.403 * (v-0.5), 0.0, 1.0 );

float g = clamp( y - 0.714 * (v-0.5) - 0.344 * (u-0.5), 0.0, 1.0 );

float b = clamp( y + 1.770 * (u-0.5), 0.0, 1.0 );

return vec4( r, g, b, a );

}


vec4 yuv2rgb( vec4 v ) {

return yuv2rgb( v.r, v.g, v.b, v.a );

}


정말 성능향상과는 반대되는 코드지만 테스트 목적으로 만든 RGB이미지를 YUV이미지로 변환하는 코드이다.


// 여기서 sw와 sh는 원본이미지의 width, height값이며, RGBRGBRGB식으로 저장된이미지이고 stride는 sw와 같다(padding이 없다)고 가정한다.


// rgba값을 YUVA값으로 변환하는 함수 // Little Endian이라고 가정한다.

uint32_t rgba2yuva( uint8_t r, uint8_t g, uint8_t b, uint8_t a ) {

uint8_t y, u, v;

y = 0.299*r + 0.587*g + 0.114*b

u = ( b - y ) * 0.565;

v = ( r - y ) * 0.713;

return ( a << 24 ) | ( v << 16 ) | ( u << 8 ) | y;

}

uint8_t* srcImage; // 원본이미지

/*

dstImage : YUV색공간을 가진 이미지, packed, 1픽셀은 YUVA순서로 4bytes로 구성된다.

*/


uint32_t* dstImage = new uint32_t[sw*sh];

uint8_t* src = srcImage;

uint32_t* dst = dstImage;

for( int y = 0 ; y < sh ; y++ ) {

for( int x = 0 ; x < sw ; x++ ) {

uint8_t r = *src++;

uint8_t g = *src++;

uint8_t b = *src++;

*dst++ = rgba2yuva( r, g, b, 255 ); // 원본에 alpha값이 없으므로 255로 alpha지정

}

}


// 이 곳에 Texture를 만드는 코드가 들어간다.


delete []dstImage;




'Android Develop > GLES2.0' 카테고리의 다른 글

기본 사용법 : GLSurfaceView  (2) 2020.07.19
YUV shader  (0) 2017.10.30
Replies
Reply Write