雷神系列文章
RGB、YUV像素数据处理
YUV格式
YUV图解 (YUV444, YUV422, YUV420, YV12, NV12, NV21)
YUV、YCbCr、YPbPr
Y : 表示明亮度(Luminance或Luma),也就是灰度值;
U V: 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩,饱和度,用于指定像素的颜色。
YUV存储格式 planar、Packet
对于planar的YUV格式,即平面模式 先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。形如 YYYY UUUU VVVV 4个像素的YUV444P
对于packed的YUV格式,即数据包模式, 每个像素点的Y,U,V是连续交叉存储的。 形如 YUV YUV YUV YUV 四个像素。
YUV444,YUV422,YUV420,NV12,NV21
YUV444
YUV444,这种格式占用空间最大,每个像素点有一个Y分量+一个U分量+一个V分量所以和rgb一样每个像素点占用3个字节!
但是根据UV存储顺序不一样,又有两种不同的格式。
形如:
YYYY UUUU VVVV
YYYY VVVV UUUU
YUV422
YUV422 每两个Y分量公用一个UV分量,所以一个像素占用两个字节,根据存储顺序不同又分为四种不同的格式。
还有一种变态的V210格式,好像是苹果搞出来的。
YUV420
YUV420 每四个y分量公用一个UV分量,所以每个像素点占用1.5个字节空间,根据存储顺序不一样又分为四个不同的类型。
形如:
I420: YYYYYYYY UU VV =>YUV420P
YV12: YYYYYYYY VV UU =>YUV420P
NV12: YYYYYYYY UVUV =>YUV420SP
NV21: YYYYYYYY VUVU =>YUV420SP
YUV数据常见处理
(1) 分离YUV420P像素数据中的Y、U、V分量
主要思路
就是读取平面格式的yuv数据,
前widthheight 为Y分量数据;
从widthheight,到widthheight5/4,是U分量数据;
从widthheight1/4,到widthheight3/2,是V分量数据;
分别存为三个文件output_420_y,output_420_u,output_420_v文件。
具体实现
int simplest_yuv420_split(char *url, int w, int h,int num){ FILE *fp=fopen(url,"rb+"); FILE *fp1=fopen("output_420_y.y","wb+"); FILE *fp2=fopen("output_420_u.y","wb+"); FILE *fp3=fopen("output_420_v.y","wb+"); unsigned char *pic=(unsigned char *)malloc(w*h*3/2); for(int i=0;i<num;i++){ fread(pic,1,w*h*3/2,fp); //Y fwrite(pic,1,w*h,fp1); //U fwrite(pic+w*h,1,w*h/4,fp2); //V fwrite(pic+w*h*5/4,1,w*h/4,fp3); } free(pic); fclose(fp); fclose(fp1); fclose(fp2); fclose(fp3); return 0; }
(2)分离YUV444P像素数据中的Y、U、V分量
主要思路
同理,yuv444p就是比例是1:1:1;
文件y,u,v区间分别是[0,widhei],[widhei,widhei2],[widhei2,widhei3].
(3) 将YUV420P像素数据去掉颜色(变成灰度图)
主要思路
去掉颜色uv,
如果想把YUV格式像素数据变成灰度图像,只需要将U、V分量设置成128。
(4) 将YUV420P像素数据的亮度减半
主要思路
可以通过将YUV数据中的亮度分量Y的数值减半的方法,降低图像的亮度。
如果打算将图像的亮度减半,只要将图像的每个像素的Y值取出来分别进行除以2的工作就可以了。图像的每个Y值占用1 Byte,取值范围是0至255,对应C语言中的unsigned char数据类型。
(5)将YUV420P像素数据的周围加上边框
主要思路
边框区域 设置为255, w在[0,border] && [w-border,w],h在[0,border]&&[h-border,h]区域为边框区域
(6) 生成YUV420P格式的灰阶测试图
主要思路
根据y的范围,和色带的数量,确定每个色带的亮度值,y = ymin+n*(ymax-ymin)/num
然后重新设置yuv图片值,uv=128,y根据色带设置y值。
(7)计算两个YUV420P像素数据的PSNR
PSNR通常用于质量评价,就是计算受损图像与原始图像之间的差别,以此来评价受损图像的质量。
主要思路
先算出mse sum+= pow(pic1[j]-pic2[j],2), mse = sum/M*N;
对于8bit量化的像素数据来说,PSNR的计算公式如下所示。
上述公式中mse的计算公式如下所示。
PSNR取值通常情况下都在20-50的范围内,取值越高,代表两张图像越接近,反映出受损图像质量越好。