Tistory View
동영상이나 디지털인식장치(카메라 등등)을 사용할 때, 이미지의 정보가 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 > OpenGLES' 카테고리의 다른 글
OpenGL ES : (Texture or FBO) to (Texture or FBO) 복사 정리 (0) | 2021.06.21 |
---|---|
Android OpenGL ES : 올바른 Framebuffer 사용법 (2) | 2021.06.21 |
Android OpenGLES FenceSync 이해하기 (1) | 2021.03.16 |
안드로이드 NDK OpenGLES 초기화 및 Shared Context (1) | 2021.03.15 |
기본 사용법 : GLSurfaceView (2) | 2020.07.19 |
- Total
- Today
- Yesterday
- OpenGLes
- 컴퓨트셰이더
- 아끼는 법
- 애드센스
- choreographer
- 티스토리
- 전기요금
- 에어콘
- 경제보복
- ComputeShader
- 재태크
- texture
- 사용료
- 전기료
- 금리
- 텍스처
- 컴퓨트쉐이더
- 예금
- 적금
- 전기세
- 공유 컨텍스트
- Android
- 애드핏
- TTS
- 안드로이드
- gpgpu
- 재테크
- 에어컨
- OpenGL ES
- 블로그
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |