前言
在Android视频或者拍摄图片开发中,因为不了解yuv,所以在写视频demo时,手机预览的界面可能存在旋转 90/180/270 度的问题。大部分后置摄像头是旋转了90度,
前置摄像头旋转270了度。如果要看到正常角度的预览界面,我们则需要对摄像头进行旋转一定的角度,而且旋转的角度只能是 0/90/180/270。
关于摄像头的旋转和开发打算放在下一篇文章记录,而这一次有更加重要的内容要记录。即使我们设置了正确的预览界面,当按下快门或者拍摄视频的那一刻,
摄像头记录下的数据(默认为NV21数据格式,是YUV的一种数据格式),可能并不是我们真正想要的。记录的照片或者视频的角度可能会存在问题,可能是旋转了 90/180/270 度。而我们要想获取到正确的角度,那么需要用 YUV 对数据进行转换或者旋转,才能得到我们希望的角度。
一、YUV与RGB
YUV
是视频应用程序中使用的一类像素格式。
亮度信号通常被称作Y,色度信号通常是由两个相互独立的的信号组成,不同的颜色系统有不同的格式,两种不同的色度信号经常被称作U和V 或者 Cb和 Cr 或者 Pb和Pr。这是由于不同颜色系统的编码格式不一样所产生的,实际上是相同的概念。色度信号主要作用是描述影像色彩及饱和度,用于指定像素的颜色。
主要用于电视系统以及模拟视频领域,它将亮度(luma)信息(Y)与色彩(chroma)信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。
RGB
是用于表示图像和视频的颜色模型。RGB代表红色,绿色和蓝色分量。
YUV 的格式有两种,分别是 planar
和 packed
- planar (平面格式)先连续存储所以像素点的Y,紧接着存储所有像素点的U,最后是存储所有像素点的V。
- 属于planer 的有 NV12、NV21、YV12、I420 等等,列举的这几个主要是YUV4:2:0采样,当然也包含其他采样方式。
- packed (打包格式)是每个像素点的Y、U、V是连续交叉存储的。
- 属于packed的有 YUYV、UYVY、VYUY等,这几个主要是YUV4:2:2采样
在Android 平台下使用相机默认格式是NV21,属于YUV420sp
二、YUV的 4:4:4 、4:2:2、4:2:0采样模式
据研究表明人眼对亮度的分辨相对于色彩色度的分辨更加敏锐,容易察觉。那么在存储图像信息时,采用不同的采样方式可以有效的减少媒体信息的内存空间和降低带宽资源的占用。
通常地 YUV a:b:c
的意思是表示每4个像素采样点Y采样了a次,U采样了b次,V采样了c次。
如上图所示,每一个小格表示一个像素,那么在这4中不同的采样方式中像素点和对应的亮度、色度采集信息大概可以总结为如下:
YUV4:4:4
采样方式生成的图像中,每4个采样的像素点都会对应4点亮度Y、4点U(或者Cb)、4点V(或者Cr),即亮度分辨率和色度分辨率相等;一帧数据量为:width * height * 3byte
YUV4:2:2
采样方式,即每4个采样像素点对应有4点Y采样,2点U、2点V。即在色度采样上,个一个采样点才会有色度信息,会丢弃一半色度信息。亮度和色度在水平方向比值 2:1,在垂直方向1:1。一帧的数据量为:widht * heitht * 2byte
YUV4:2:0
采样,并不是只有Y、U或者V 采样,而是在行扫描线上,只有一种色度采样,其在存储中亮度和色度的采样比为2:1。也就是说,如果第一行YUV采样为4:2:0, 那么下一行是 4:0:2, 如此类推。从亮度、色度采样分布情况来看,每4个采样像素点在纵向和横向扫描线上都丢掉一半的色度采样信息。一帧的数据量为:width * height * 1.5byte
其中
YUV4:2:0
分为两种:YUV420P和YUV420SP
YUV420P
又叫plane平面模式
,Y、U、V 分别存储在不同的平面,也就有三个平面。它是标准格式YUV4:2:0
,又分为:YV12
和YU12
YUV420sp
是一种tow-plane模式
,即 Y与 UV分别存储在两个不同的平面,先是Y一个平面,然后UV(CbCr)在同一个平面里交替存储。子格式分为:NV12
和NV21
最后总结如下:
1
2
3YUV 4:4:4采样,每一个Y对应一组UV分量,一个YUV占8+8+8 = 24bits 3个字节。
YUV 4:2:2采样,每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits 2个字节。
YUV 4:2:0采样,每四个Y共用一组UV分量,一个YUV占8+2+2 = 12bits 1.5个字节。
三、YUV的存储格式
基于不同采样方式的码流存储方式如下:
- NV12、NV21格式:
NV12和NV21同属于YUV4:2:0 采样,是一种tow-plane模式,Y和UV分为两个Plane,UV交错存储。如图所示,其采样基本上遵循YUV4:2:0方式,即对于像素点Y00Y01Y10Y11,其对应色度值 UV(Cb,Cr) 为U00V00,二者的区别在于 NV12 是 UV(Cb,Cr) 交替存储,NV21是VU(Cb,Cr)交错存储。IOS应用的是NV12, 而Android应用的是NV21。
YV12、YU12格式:
YV12、YU12码流格式属于YUV4:2:0,是plane模式,其中Y、U、V分量分别打包,依次存储。同样也是每4个像素点共享一对UV,即如图所示:Y00Y01Y10Y11,其对应色度值 UV(Cb,Cr) 为U00V00
I420格式:
I420码流格式也是属于YUV4:2:0, Y、U、V采样数据分量分别打包,依次存储在不同的平面,对于Y00Y01Y10Y11 元素,共享的色度值元素为U00V00
YUYV格式:
YUYV是YUV4:2:2采样存储格式中的一种,是packed 打包格式,其中Y、U、V交替存储;相邻的两个Y 共享相邻的两个U、V色度采样,也即Y00Y01 共享 U00V00
UYVY、VYUY格式:
图示为UYVY格式,同样的,也是YUV4:2:2采样存储格式中的一种,与YUYV不同的是UV分别排列在Y的前方。
四、YUV和RGB转换
1 | YUV and RGB |
五、YUV旋转
参考
https://wiki.videolan.org/YUV/
https://wiki.videolan.org/RGB/
https://www.fourcc.org/yuv.php
https://www.cnblogs.com/sddai/p/10302979.html