RGB与YUV转换


const double RtoY[3][3] = {   0.299,    0.587,     0.114,
                            -0.1687,  -0.3313,       0.5, 
                                0.5,  -0.4187,   -0.0813 };

const double YtoR[3][3] = {     1.0,      0.0,     1.402,
                                1.0, -0.34414,  -0.71414,
                                1.0,    1.772,       0.0 };
typedef struct FrameStruct {
  uint8_t *Y, *Cr, *Cb;
  uint8_t *datas;
  uint32_t channelLength;
  uint32_t width, height;
  FrameStruct() {
    width = height = channelLength = 0;
    Y = Cr = Cb = NULL;
    datas = NULL;
  }
  ~FrameStruct() {
    if (datas != NULL) {
      delete[] datas;
    }
  }
} FrameS;

typedef struct ImageStruct {
  uint8_t *datas;
  uint32_t width, height;
 
  ImageStruct() { 
    datas = NULL;
    width = height = 0;
  }
  ~ImageStruct() {
    if (datas != NULL) {
      delete[] datas;
    }
  }
} ImageS;

RGB to YUV:

void ConvertRGBToYUV( ImageS *rgb , FrameS *yuv ) {
  int offset, dat;
  int cnt = 0;
  double signal;

  yuv->width = rgb->width;
  yuv->height = rgb->height;
  yuv->channelLength = rgb->width * yuv->height;

  for(uint32_t y = 0 ; y < rgb->height ; ++y) {
    ///   width * 3:  one pixel is 24 bit( 3 byte ) /
    for(uint32_t x = 0 ; x < rgb->width * 3 ; x += 3) {

      for(int i = 0 ; i < 3 ; ++i ) {

        offset = yuv->channelLength * i;
        dat = 0;
        int step = x;
        for(int j = 0 ; j < 3 ; ++j , ++step) {
          signal = (double)rgb->datas[y * rgb->width * 3 + step];
          dat += (int)( signal * RtoY[i][j] );
        }

        yuv->datas[cnt + offset] = (int8_t)(dat + ( i <= 0 ? 0.0 : 128.0 ));
      }
      cnt++;
    }
  }
  yuv->Y = yuv->datas;
  yuv->Cb = &yuv->datas[yuv->channelLength];
  yuv->Cr = &yuv->datas[yuv->channelLength * 2];
}

YUV to RGB:

void ConvertYUVToRGB( FrameS *yuv , ImageS *rgb ){
  int offset, dat, cnt;
  cnt = 0;

  rgb->width = yuv->width; rgb->height = yuv->height;
  
  for(uint32_t y = 0; y < yuv->height; ++y) {
    for(uint32_t x = 0; x < yuv->width; ++x) {
      for(int i = 0; i < 3; ++i) {

        dat = 0;
        for(int j = 0 ; j < 3 ; ++j) {
          offset = yuv->channelLength * j;
          dat += (int)((double)(yuv->datas[y * yuv->width + x + offset] - 
            (j > 0 ? 128.0 : 0.0)) * YtoR[i][j]);
        }

        if( dat > 255 ) { dat = 255; }
        if( dat < 0 )   { dat = 0; }
        rgb->datas[cnt++] = (uint8_t)dat;
      }
    }
  }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值