主流图像存储格式
参考文章:
一文读懂 YUV 的采样与格式 - 知乎 (zhihu.com)
RGB颜色编码,每个像素点都有红,绿,蓝三个原色,其中每种原色都占用8bit,即1个字节,那么一个像素点也就占用24bit,也就是三个字节。那么一张1280x
720大小的图片就占用1280x720x3/1024/1024=2.63MB存储空间。
YUV颜色编码采用的是明亮度和色度来指定像素的颜色,Y表示明亮度,而U和V表示色度。而色度又定义了颜色的两个方面:色调和饱和度。和RGB表示图像类似,每个像素点都包含Y,U,V三个分量,根据不同的采样格式,可以每个Y分量都对应自己的U,V分量,也可以几个Y分量共用UV分量。
对于图像器显示器来说,它是通过RGB模型来显示图像的,但是传输图像数据的时候又是使用的YUV模型,这时因为YUV模型可以节省带宽。因此就需要采集图像时将RGB模型转换到YUV模型,显示时再将YUV模型转换为RGB模型。
颜色转换公式
RGB to YUV420(如果此公式不准确可以尝试BT601或BT709转换公式)
:
YUV420 to RGB
:
R = Y + 1.402* (V - 128); //R
G = Y - 0.34413 * (U - 128) - 0.71414 * (V - 128); //G
B = Y + 1.772 * (U - 128); //B
参考文章:图片格式之YUV420 转RGB格式(含代码)_yuv420转rgb_Huo的藏经阁的博客-CSDN博客
色彩空间标准
BT601和BT709是两种数字电视的色彩空间标准,它们规定了RGB颜色和YUV颜色之间的转换关系。BT601是标准清晰度电视(SDTV)的色彩空间标准,适用于480i或576i的分辨率。BT709是高清晰度电视(HDTV)的色彩空间标准,适用于720p或1080p的分辨率。BT601和BT709的主要区别是转换系数不同,导致同样的RGB颜色在不同的标准下转换成不同的YUV颜色。如果转换标准不匹配,就会出现色彩偏差或失真。它们两个的本质区别是数据转换系数不同。
BT601转换公式
Y’ = 0.257R’ + 0.504G’ + 0.098B’ + 16
Cb’ = -0.148R’ - 0.291G’ + 0.439B’ + 128
Cr’ = 0.439R’ - 0.368G’ - 0.071B’ + 128
R’ = 1.164(Y’ - 16) + 1.596*(Cr’ - 128)
G’ = 1.164*(Y’ - 16) - 0.813*(Cr’ - 128) - 0.392*(Cb’ - 128)
B’ = 1.164*(Y’ - 16) + 2.017*(Cb’ - 128)
BT709转换公式
Y’ = 0.183R’ + 0.614G’ + 0.062B’ + 16
Cb’ = -0.101R’ - 0.338G’ + 0.439B’ + 128
Cr’ = 0.439R’ - 0.399G’ - 0.040B’ + 128
R’ = 1.164(Y’ - 16) + 1.793*(Cr’ - 128)
G’ = 1.164*(Y’ - 16) - 0.534*(Cr’ - 128) - 0.213*(Cb’ - 128)
B’ = 1.164*(Y’ - 16) + 2.115*(Cb’ - 128)
参考文章:
YUV/RGB颜色空间转换公式_yuv转rgb公式_晓茗的博客-CSDN博客
YUV格式
YUV420
YUV420的存储格式通常有四种:I420、YV12、NV12、NV21
平面和交错
YUV420每采样8个Y分量,就由2个U分量和2个V分量。
一帧图像,先把所有Y分量按序存储,接着是所有的U,最后是所有的V,也即YYYYYYYYUUVV或YYYYYYYYVVUU,这就顺序形成三个平面。通常称这种能形成三个平面的存储格式为YUV420P。另一种交错存储的,在采样格式为YUV420时,通常只会U和V交错,即存储格式是YYYYYYYYUVUV或YYYYYYYYVUVU,这样Y分量形成一个平面,UV形成一个平面,总共两个平面,通常称为YUV420SP,这也是安卓和IOS使用的YUV存储格式。
I420、YV12、NV12、NV21的存储格式
I420:YYYYYYYYUUVV
YV12:YYYYYYYYVVUU
NV12:YYYYYYYYUVUV
NV21:YYYYYYYYVUVU
I420和YV12有三个平面,属于YUV420P的,而NV12和NV21有两个平面,属于YUV420SP。
一般在YUV资源网站上,下载得到YUV文件一般是I420的,也即先存Y、后存U、最后V。
I420存储示例
YUV444
YUV4:4:4采样意味着,Y、U、V三个分量的采样比例相同,因此在生成的图像中,每个像素的三个分量信息完整,都是8bit,也就是一个字节。
假如图像像素为:[Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]
那么采样的码流为:Y0 U0 V0 Y1 U1 V1 Y2 U2 V2 Y3 U3 V3
最后映射出的像素点依旧为 [Y0 U0 V0]、[Y1 U1 V1]、[Y2 U2 V2]、[Y3 U3 V3]
可以看到这种采样方式的图像和 RGB 颜色模型的图像大小是一样,并没有达到节省带宽的目的,当将 RGB 图像转换为 YUV 图像时,也是先转换为 YUV 4:4:4 采样的图像。
YUV422
YUV 4:2:2 采样,意味着 UV 分量是 Y 分量采样的一半,Y 分量和 UV 分量按照 2 : 1 的比例采样。如果水平方向有 10 个像素点,那么采样了 10 个 Y 分量,而只采样了 5 个 UV 分量。
RGB格式
RGB颜色空间以R、G、B三种基本色为基础,进行不同程度的叠加,产生丰富的颜色,叫做三基色模式。
RGB图像空间:
RGB555
每个像素用16位比特位表示,占2个字节,RGB分量都使用5位,最高位不用
// 获取高字节的5个bit
R = color & 0x7C00
// 获取中间的5个bit
G = color & 0x03E0
// 获取低字节5个bit
B = color & 0x001F
RGB1555
RGBA(ARGB)的一种,一位用于表示透明度,0表示透明,1完全不透明
RGB565
每个像素用16bit表示,占两个字节,RGB分量分别使用5位、6位、5位
// 获取高字节的5个bit
R = color & 0xF800;
// 获取中间6个bit
G = color & 0x07E0;
// 获取低字节5个bit
B = color & 0x001F;
RGB24格式
RGB24图像每个像素用24比特位表示,占3个字节,但是在内存中RGB各分量的排列顺序为:BGR BGR...
RGB32格式
RGB32图像每个像素用32bit表示,占4个字节,R,G,B分别用8个bit表示,存储顺序为B,G,R,最后8个字节保留。在内存中RGB各分量的排列顺序为:BGRA BGRA BGRA …。
R = color & 0x0000FF00;
G = color & 0x00FF0000;
B = color & 0xFF000000;
A = color & 0x000000FF;
RGB222
是一种8bit的RGB格式,各分量占用2bit位,剩下2bit位不用。这种格式一般用于灰度图。
单通道和双通道
单通道俗称灰度图,每个像素点只有一个值表示颜色,它的像素值在0到255之间,0是黑色,255是白色,中间值是一些不同等级的灰色,相当于黑与白之间的过渡色。
多通道也就是RGB三原色,每个像素点有三个字节来表示(RGB),分别最大取值范围是0-255,可以组合成千万种颜色。
单通道通常用于图像处理,因为单通道只有一个像素点(1个字节),相比多通道的3个字节,处理速度上要快很多。而且单通道能将图像以灰度形式显示出来,不会影响图像识别和特征提取。
多通道也可以组成灰度图,红+绿+蓝=白色,三色相等时才会组成白色。
HSV格式
参考文章:HSV和RGB通道颜色的区别和转换 - 知乎 (zhihu.com)
用角度度量,取值范围为0-360度,从红色开始按逆时针方向计算,红色为0度,绿色为120度,蓝色为240度。它们的补色:黄色为60度,青色为180度,紫色为300度
饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。
RGB和CMY颜色模型都是面向硬件的,而HSV(Hue Saturation Value)颜色模型是面向用户的。
HSV模型的三维表示从RGB立方体演化而来。设想从RGB沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。
RGB转HSV
HSV转RGB