YUV to RGB conversion
YUV to RGB 변환 코드를 작성하시오.
step1)
#define CLIP(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
void Yuv2Rgb(int Y, int U, int V, int &R, int &G, int &B)
{
B = 1.164*(Y-16) + 2.018*(U-128) ;
G = 1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128) ;
R = 1.164*(Y-16) + 1.596*(V-128) ;
B = CLIP(B);
G = CLIP(G);
R = CLIP(R);
}
=> YUV, RGB 변환 공식은 아래와 같다.
B = 1.164*(Y-16) + 2.018*(U-128)
G = 1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128)
R = 1.164*(Y-16) + 1.596*(V-128)
(YUV 포멧 및 RGB 변환에 관해서는 http://www.fourcc.org/ 를 참조하라.)
위의 공식은 실제 몇몇 픽셀에서 overflow 가 발생할 것이다.
0~255의 범위를 벗어나는 값이 나온다. 이를 방지하기 위해, 0~ 255 값으로 clipping 이 필요하다.
step2)
#define CLIP(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
void Yuv2Rgb(int Y, int U, int V, int &R, int &G, int &B)
{
B = ( 76284*(Y-16) + 132252*(U-128) ) >> 16;
G = ( 76284*(Y-16) - 53281*(V-128) - 25625*(U-128) ) >> 16 ;
R = ( 76284*(Y-16) + 104595*(V-128) ) >> 16 ;
B = CLIP(B);
G = CLIP(G);
R = CLIP(R);
}
=> YUV, RGB 변환 공식을 약간 변형하면 아래와 같다.
B = 65536*(1.164*(Y-16) + 2.018*(U-128) ) / 65536
G = 65536*(1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128) ) / 65536
R = 65536*(1.164*(Y-16) + 1.596*(V-128) ) / 65536
B = ( 76284*(Y-16) + 132252*(U-128) ) >> 16
G = ( 76284*(Y-16) - 53281*(V-128) - 25625*(U-128) ) >> 16
R = ( 76284*(Y-16) + 104595*(V-128) ) >> 16
변형된 공식을 사용함으로서, floating point 연산을 없엘 수 있다.