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