一帧YUV420P像素数据一共占用w*h*3/2 Byte的数据。其中前w*h Byte存储Y,接着的w*h*1/4 Byte存储U,最后w*h*1/4 Byte存储V
RGB到YUV的转换公式:
Y= 0.299*R+0.587*G+0.114*B
V= 0.615*R-0.515*G-0.100*B
在转换的过程中有以下几点需要注意:
1) RGB24存储方式是Packed,YUV420P存储方式是Packed。
2) U,V在水平和垂直方向的取样数是Y的一半
RGB24_TO_YUV420代码源自雷神博客。补充yuv420_to_rgb24.
资料博客:https://blog.csdn.net/leixiaohua1020/article/details/50534150
unsigned char clip_value(unsigned char x,unsigned char min_val,unsigned char max_val){
if(x>max_val){
return max_val;
}else if(x
bool RGB24_TO_YUV420(unsigned char *RgbBuf,int w,int h,unsigned char *yuvBuf)
{
unsigned char*ptrY, *ptrU, *ptrV, *ptrRGB;
memset(yuvBuf,0,w*h*3/2);
ptrY = yuvBuf;
ptrU = yuvBuf + w*h;
ptrV = ptrU + (w*h*1/4);
unsigned char y, u, v, r, g, b;
for (int j = 0; j> 8) + 16 ;
u = (unsigned char)( ( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128 ;
v = (unsigned char)( ( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128 ;
*(ptrY++) = clip_value(y,0,255);
if (j%2==0&&i%2 ==0){
*(ptrU++) =clip_value(u,0,255);
}
else{
if (i%2==0){
*(ptrV++) =clip_value(v,0,255);
}
}
}
}
return true;
}
与YUV420P三个分量分开存储不同,RGB24格式的每个像素的三个分量是连续存储的。一帧宽高分别为w、h的RGB24图像一共占用w*h*3 Byte的存储空间。RGB24格式规定首先存储第一个像素的R、G、B,然后存储第二个像素的R、G、B…以此类推。类似于YUV420P的存储方式称为Planar方式,而类似于RGB24的存储方式称为Packed方式。
R = Y + 1.4075 *(V-128)
G = Y – 0.3455 *(U –128) – 0.7169 *(V –128)
B = Y + 1.779 *(U – 128)
bool yuv420ToRgb(char *yuv,int w,int h,char *rgb)
{
unsigned char *pBufy = new unsigned char[w*h];
unsigned char *pBufu = new unsigned char[w*h/4];
unsigned char *pBufv = new unsigned char[w*h/4];
memcpy(pBufy,yuv,w*h);
memcpy(pBufu,yuv+w*h,w*h/4);
memcpy(pBufv,yuv+w*h*5/4,w*h/4);
for(int i = 0; i
亲测,两份代码可用。如有问题,欢迎指正。共同学习,共同进步。
资料源自网络。