2025. 4. 29. 09:21ㆍProgramming
영상을 직접 처리하기 위해 카메라로부터 영상을 스트리밍하다보면, 색이 이상하게 표시되는 경우가 있습니다. 영상을 스트리밍할때는 효율적으로 데이터를 전송하기 위해서 YUV 색공간을 사용하는데, 일반적으로 모니터같은 디스플레이 장치는 RGB 색공간을 사용하기 때문이죠. 이번 글에서는 YUV와 RGB 색공간의 차이에 대해 살펴보고, 자주 사용되는 라이브러리에 대해 알아봅니다.
YUV 색공간이란?
YUV는 인간의 시각적 특성을 고려해 개발된 색상 인코딩 시스템입니다. 우리 눈은 색상보다 밝기 변화에 더 민감하다는 특성을 활용한 것이죠.
YUV 색공간은 세 가지 주요 구성 요소로 이루어집니다:
- Y (휘도): 이미지의 밝기 정보
- U, V (색차): 색상 정보를 나타내는 두 가지 요소
수학적으로 RGB에서 YUV로의 변환은 다음과 같이 이루어집니다:
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B (청색-휘도)
V = 0.615R - 0.515G - 0.100B (적색-휘도)
RGB 색공간과의 차이점
RGB(Red, Green, Blue) 색공간은 빛의 삼원색을 기반으로 하며, 모든 색상을 이 세 가지 색의 조합으로 표현합니다. 디스플레이 장치들은 대부분 이 RGB 모델을 기반으로 작동합니다.
주요 차이점:
- 표현 방식: RGB는 색상을 직접 표현하지만, YUV는 밝기와 색상 정보를 분리
- 목적: RGB는 디스플레이 출력용, YUV는 효율적인 신호 처리 및 전송용
- 데이터량: YUV는 인간이 덜 민감한 색상 정보(U,V)를 압축할 수 있어 효율적
왜 YUV 색공간을 사용할까?
YUV 색공간은 다음과 같은 이유로 널리 사용됩니다:
- 데이터 압축 효율성
- 인간의 눈이 색상보다 밝기에 더 민감하므로, U와 V 채널을 Y보다 낮은 해상도로 압축 가능
- 이를 통해 데이터 양을 크게 줄일 수 있음 (대역폭 절약)
- 역사적 호환성
- 흑백 TV와 컬러 TV의 호환성을 위해 개발됨
- Y 신호만으로도 흑백 이미지를 표현할 수 있어 하위 호환성 제공
- 비디오 코딩 표준
- JPEG, MPEG, H.264 등 대부분의 이미지/비디오 압축 표준에서 YUV 형식 사용
- 스트리밍 서비스, 디지털 방송 등에서 필수적인 요소
YUV를 그대로 디스플레이하면 왜 색상이 이상하게 보일까?
YUV 색공간의 영상을 RGB 변환 없이 그대로 디스플레이하면 색상이 왜곡되어 보입니다. 그 이유는:
- 디스플레이의 RGB 기반 하드웨어 구조
- 현대 디스플레이는 R, G, B 서브픽셀로 구성되어 RGB 신호만 직접 해석 가능
- 데이터 해석 오류
- YUV 데이터를 RGB로 변환하지 않고 그대로 RGB 채널에 입력하면, 의미가 다른 값들이 잘못 해석됨
- 예: Y값이 R로, U값이 G로, V값이 B로 직접 매핑되면 완전히 다른 색상으로 표현됨
- 데이터 범위 불일치
- U와 V는 일반적으로 -128에서 +127 범위의 값
- RGB는 0에서 255 범위로 표현
- 이 범위 차이로 인해 색상 왜곡 발생
예를 들어, YUV 값 (Y=235, U=128, V=90)을 적절한 변환 없이 RGB(235, 128, 90)으로 그대로 디스플레이하면 원래 의도했던 색상과 전혀 다른 색상이 표시됩니다.
YUV에서 RGB로의 변환
YUV 영상을 제대로 표시하기 위해서는 다음과 같은 공식으로 RGB로 변환해야 합니다:
R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U
이 변환 과정은 일반적으로 비디오 처리 파이프라인 내에서 자동으로 이루어지며, 하드웨어나 소프트웨어적으로 최적화되어 실행됩니다.
YUV 기반 디스플레이는 가능할까?
이론적으로 디스플레이 하드웨어가 직접 YUV를 이해하고 표시할 수 있다면 여러 이점이 있을 수 있습니다:
- 처리 효율성 향상
- 색공간 변환 단계 생략으로 지연시간 감소
- CPU/GPU 자원 절약
- 에너지 효율성
- 변환 과정에서 소모되는 계산 비용과 전력 절약
- 모바일 기기에서 배터리 수명 연장 가능성
그러나 현실적인 제약이 있습니다:
- 하드웨어 구조적 제약
- 현대 디스플레이의 물리적 구조는 RGB 서브픽셀 기반
- LCD, OLED 등 현존하는 디스플레이 기술은 근본적으로 RGB 광원 제어 방식
- 디지털 콘텐츠 생태계
- 컴퓨터 그래픽, 웹, 사진 등 대부분의 시각 콘텐츠가 RGB 기반으로 제작됨
- 모든 콘텐츠를 YUV로 처리하기 어려움
현재의 해결책
현재는 하드웨어 가속을 통해 YUV → RGB 변환 과정을 최적화하는 방향으로 발전하고 있습니다:
- GPU나 전용 영상 처리 칩을 통한 고속 색공간 변환
- 비디오 디코더에 변환 기능 내장으로 효율성 향상
- 최적화된 알고리즘으로 변환 과정에서의 품질 손실 최소화
실제 개발에 활용할 수 있는 YUV-RGB 변환 라이브러리
YUV와 RGB 간 변환이 필요한 개발자분들을 위해 플랫폼별로 유용한 오픈소스 라이브러리를 소개합니다:
안드로이드
- libyuv
- Google에서 만든 고성능 YUV 처리 라이브러리
- C++로 작성되었으며 JNI를 통해 안드로이드에서 사용 가능
- GitHub 저장소
- 다양한 YUV 포맷(I420, NV12, NV21 등) 지원
- android-gpuimage
- GPU 가속을 활용한 이미지 처리 라이브러리
- YUV-RGB 변환 필터 포함
- GitHub 저장소
플러터
- camera (공식 플러터 패키지)
- YUV 이미지 처리 기능 포함
- pub.dev 페이지
ImageFormatGroup.yuv420
형식으로 이미지 캡처 지원
웹/자바스크립트
- yuv-canvas
- 웹에서 YUV 프레임을 HTML5 캔버스에 렌더링
- GitHub 저장소
- yuv-buffer
- YUV 버퍼 조작을 위한 유틸리티
- GitHub 저장소
크로스 플랫폼
- FFmpeg
- 멀티미디어 처리를 위한 종합 라이브러리
- 다양한 색공간 변환 기능 내장
- 공식 웹사이트
- OpenCV
- 컴퓨터 비전 라이브러리로 색공간 변환 기능 제공
cv::cvtColor()
함수로 YUV-RGB 변환 가능- 공식 웹사이트
직접 구현하기
YUV-RGB 변환을 위한 간단한 코드 예시입니다:
// 안드로이드에서 NV21(YUV) -> RGB 변환 예시 코드
public static int[] nv21ToRgb(byte[] nv21, int width, int height) {
int[] rgb = new int[width * height];
int frameSize = width * height;
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width;
int u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = 0xff & nv21[yp];
if ((i & 1) == 0) {
v = 0xff & nv21[uvp++];
u = 0xff & nv21[uvp++];
}
int y1192 = 1192 * (y - 16);
int r = (y1192 + 1634 * (v - 128)) >> 10;
int g = (y1192 - 833 * (v - 128) - 400 * (u - 128)) >> 10;
int b = (y1192 + 2066 * (u - 128)) >> 10;
r = r < 0 ? 0 : (r > 255 ? 255 : r);
g = g < 0 ? 0 : (g > 255 ? 255 : g);
b = b < 0 ? 0 : (b > 255 ? 255 : b);
rgb[yp] = 0xff000000 | (r << 16) | (g << 8) | b;
}
}
return rgb;
}
직접 라이브러리를 만들고 싶다면, 다음 고려사항을 참고하세요:
- 다양한 YUV 포맷(YUV420, YUV422, YUV444, NV12, NV21 등) 지원
- 하드웨어 가속(SIMD, GPU) 활용으로 성능 최적화
- 다양한 플랫폼 지원을 위한 크로스 플랫폼 설계
- 메모리 효율적인 구현으로 모바일 환경 최적화
결론
YUV 색공간은 영상 압축과 전송에 매우 효율적인 방식이지만, 최종 사용자에게 표시될 때는 RGB로의 변환이 필수적입니다. 이 변환 과정은 비디오 처리 파이프라인의 중요한 부분이며, 현대 기술은 이 과정을 가능한 효율적으로 수행하기 위해 계속 발전하고 있습니다.