2008. 9. 29. 18:26

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 연산을 없엘 수 있다.