RGB 色彩空间更适合图像采集和显示, YUV 空间用于编码和存储则比较好。 无论是 RGB 还是 YUV ,他们都是 表达 色彩信息的一种方式。
(Human Visual System)人类视觉系统
色度感知 包含两个维度:色调(Hue)和 色饱和度(saturation)。色调是由光波的峰值定义的,描述的是光的颜色。色饱和度是由光波的谱宽定义的,描述的是光的纯度。
因此 HVS 对色彩的感知主要有 3个属性:亮度(luminance),色调(Hue)和 色饱和度(saturation)。也就是 YUV 色彩空间,Y 代表 亮度,U代表色调,V代表色饱和度。 经过大量研究实验表明,视觉系统 对 色度 的敏感度 是远小于 亮度的。所以可以对 色度 采用更小的采样率来压缩数据,对亮度采用正常的采样率即可,这样压缩数据不会对视觉体验产生太大的影响。简单来说就是用更少的数据/信息来表达 色度(chroma),用更多的数据/信息来表达 亮度(luminance)。
首先 YUV 有 3 种采样模式:
1,4:4:4 ,一个像素 占 3 个字节。
2,4:2:2,平均一个像素占 2 个字节。
3,4:2:0,平均一个像素占 1.5 个字节。
这些 UV 值都是新值,是以前的 4 个像素的 U 值加起来 除以4 的平均值。
其实有好几种求 UV 值算法。
1,平均值,4 个像素的 U 值加起来 除以4。
2,加权,例如第一第二个像素的U权重大点,第三第四个像素的U权重小一点。
3,直接丢弃 第二,第三,第四个像素的 U值,取 第一个 像素的 U 值。V值同理。
我个人觉得求 平均比较靠谱,FFmpeg 的代码也有这个算法,具体是求平均还是 加权,我要看下源码,这里埋个坑,后面填。
由于大多数视频编码使用的是 YUV420,所以我们经常说的 视频分辨率,是指他的亮度分辨率,因为只有亮度才是铺满的,UV 不是。
YUV 格式有3大类 :
1,planner :平面格式, 先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
注意:这里的连续存储,不是一行像素里面连续存储,是整张图片的连续存储,例如 本文的 juren_yuv_444.yuv 图片是 6075kb 大小,那第 1~ 2025kb 都是 Y 的数据, 2026 ~ 4050kb 都是 像素点的 U 数据,以此类推。
2,semi-Planar:半平面的YUV格式,Y分量单独存储,但是UV分量交叉存储。
3,packed :每个像素点的Y,U,V是连续交错存储的。
上面 FFmpeg 命令把 jpeg 转 yuv 的时候,使用的格式是 yuvj444p,后面的 p 就代表 planner,所以 本文只关注 planner格式,其他格式不讲。
YUV 的三种分类:
1,YIQ 适用于NTSC彩色电视制式
2,YUV 适用于PAL和SECAM彩色电视制式
3,YCbCr 适用于计算机用的显示器
我们做互联网音视频开发, 一般说的 YUV 是 指 YCbCr ,U 就是 Cb,V 就是 Cr。
大家经常在一些音视频书籍看到 YCbCr ,把它当成是 YUV 就行。实际上 YCbCr 才是比较准确的术语,JPEG、MPEG 标准 用的也是 YCbCr 。YUV420 这些数据,进入 编码系统之后,从编码系统出了的数据会少很多,具体少多少,H264 的压缩比 可以是 102:1 ,也就是上面那个 253G 的YUV420电影,压缩之后只需 2.5G 存储空间。多么惊人的压缩比,这就是编码系统的魅力。