RGB与YUV转换

来源:互联网 发布:wms仓储管理系统 php 编辑:程序博客网 时间:2024/04/25 18:49


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;      }    }  }}



原创粉丝点击