Converting Between YUV and RGB

개발과 트러블슈팅 2011. 11. 14. 17:13 Posted by 양고
YUV422에서 RGB로 2:1 리샘플링한다.
이 때 괜히 위키피디아에 있는 YUV 문서 들어가면 주화입마에 빠질 수 있으며, 간단하게 변환하는 방법이 있어서 소개한다.
현재는 UYVY->BGR 리샘플링했을 때 8-core CPU임에도 점유율이 높은 것이 문제다.
디버그 모드: 약 10%,
릴리스 모드: 약 5~7% 정도.

// http://yango.tistory.com/185
byte clip(int i)
{
 if(i < 0)
  return 0;
 else if(i > 255)
  return 255;
 else
  return i;
}
void Resample(Mat& image, byte* src)
{
 for(int y = 0; y < 540; y++)
 for(int x = 0; x < 960; x++)
  image.data[x+y*960] = (src[2*y*1920*2 + 4*x+1]+src[2*y*1920*2 + 4*x+3])/2; // UYVY
}
// http://msdn.microsoft.com/en-us/library/ms893078.aspx
void Resample3(Mat& image, byte* src)
{
 int Y,U,V, C,D,E;
 for(int y = 0; y < 540; y++)
 for(int x = 0; x < 960; x++)
 {
  Y = (src[2*y*1920*2 + 4*x+1]+src[2*y*1920*2 + 4*x+3])/2;
  U = src[2*y*1920*2 + 4*x];
  V = src[2*y*1920*2 + 4*x+2];
  C = Y - 16;
  D = U - 128;
  E = V - 128;
  image.data[3*(x+y*960)]  = clip((298*C + 516*D + 128) >> 8);   // B
  image.data[3*(x+y*960)+1] = clip((298*C - 100*D - 208*E + 128) >> 8); // G
  image.data[3*(x+y*960)+2] = clip((298*C + 409*E + 128) >> 8);   // R
 }
}


클리핑 하기 전과 후 사진.


참고자료: http://msdn.microsoft.com/en-us/library/ms893078.aspx


Converting Between YUV and RGB

Windows CE .NET

It is frequently necessary to convert between YUV pixel formats (used by the JPEG and MPEG compression methods) and RGB format (used by many hardware manufacturers.) The following formulas show how to compute a pixel's value in one format from the pixel value in the other format.

YUV format allows for higher compression rates without a proportionately high loss of data, as the U and V portions can be highly compressed and computed from the non- or lowly-compressed Y portion.

Computer RGB888, or full-scale RGB, uses 8 bits each for the red, green, and blue channels. Black is represented by R = G = B = 0, and white is represented by R = G = B = 255. The 4:4:4 YUV format uses 8 bits each for the Y, U, and V channels.

Converting RGB888 to YUV

The following formulas define the conversion from RGB to YUV:

Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16
U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128
V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128

These formulas produce 8-bit results using coefficients that require no more than 8 bits of (unsigned) precision. Intermediate results require up to 16 bits of precision.

Converting 8-bit YUV to RGB888

The following coefficients are used in conversion process:

C = Y - 16
D = U - 128
E = V - 128

Using the previous coefficients and noting that clip() denotes clipping a value to the range of 0 to 255, the following formulas provide the conversion from YUV to RGB:

R = clip(( 298 * C           + 409 * E + 128) >> 8)
G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
B = clip(( 298 * C + 516 * D           + 128) >> 8)

These formulas use some coefficients that require more than 8 bits of precision to produce each 8-bit result, and intermediate results require more than 16 bits of precision.

Note   All units range from 0 (zero) to 1.0 (one). In DirectDraw, they range from 0 to 255. Overflow and underflow can (and does) occur, and the results must be saturated.

To convert 4:2:0 or 4:2:2 YUV to RGB, convert the YUV data to 4:4:4 YUV, and then convert from 4:4:4 YUV to RGB.


 Last updated on Thursday, April 08, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.