颜色通常用三个分量描述,这三个分量分别作为三个维度,直观上会形成一个空间上的区域,这块立体的区域就是色彩空间(color space)。不同的色彩空间,是这个坐标系的三个轴的用来衡量颜色的标准不同所产生的。色彩空间的基本结构主要有两大类:基本颜色空间(RGB)以及色度、亮度分离颜色空间(YUV,HSV)。通常ISP芯片都带有CSC(color space conversion)功能,用来转换不同的颜色空间。
通常显示器使用RGB色彩空间,其中有Red,Green,Blue三种颜色分量。
RGB色彩空间中,一个图像的采样点由三个数字组成,代表三种颜色分量的值。上图为一个简单的示例图,其中的绿色小圆点各个分量的值对应RGB坐标系里的坐标点在各个轴的投影。
除了R、G、B外,实际应用中常见的还有一个A通道的值,A是alpha缩写,代表透明度(0为完全透明,最大值为不透明)。
常见RGB数据格式
格式 | 说明 |
RGB555 | 16bits,2 bytes。最高位不使用,剩下每5位表示一种颜色值 |
RGB1555 | 16bits,2 bytes。RGBA的一种,和RGB555类似,但多了一位alpha值,0代表透明,1代表不透明 |
RGB565 | 16bits,2 bytes。R,G,B分别使用5,6,5个bits |
RGB24 | 24bits,3 bytes。R,G,B分别使用8,8,8bits |
RGB32 | 32bits, 4 bytes。R,G,B,A分别使用8,8,8,8 bits |
当然还有很多RGB格式比如RGB555等,这里不再列举。
视频处理系统中常用的色彩空间,由一个亮度信号Y(Luminance/Luma)和两个色度信号U、V(Chrominance/Chroma)组成。它主要利用了人眼对亮度信号敏感而对色度信号不敏感的特点,对RGB转换为一个亮度信号Y和两个色差分量信号U(R-Y)、V(B-Y)。
YUV和RGB的转换公式为:
RGB --> YUV | YUV --> RGB |
Y = 0.299R + 0.587G + 0.114B U = -0.147R - 0.289G + 0.436B V = 0.615R - 0.515G - 0.100B |
R = Y + 1.14V G = Y - 0.39U - 0.58V B = Y + 2.03U |
YUV类型
YUV细分为Y'UV,YUV,YCbCr,YPbPr等类型。YCbCr是计算机系统中应用最多的类型,JPEG、MPEG,H264均采用此格式。后文所说的YUV都是指YCbCr。
YUV采样
YUV有很多种采样方式,这里对常见的三种进行说明:444,422,420
上图中,实心黑点表示Y,空心圆表示UV
YUV4:4:4 -- 每一个Y有一个UV,每个像素24bits
YUV4:2:2 -- 每两个Y共享一个UV,每个像素16bits
YUV4:2:0 -- 每四个Y共享一个UV,每个像素12bits
YUV存储格式
planar:先存所有像素点的Y,再存所有像素点的U,最后存所有像素点的V
下面以YUV422P为例,来理解planar的存储方式
Y1 | Y2 | Y3 | Y4 |
Y5 | Y6 | Y7 | Y8 |
Y9 | Y10 | Y11 | Y12 |
Y13 | Y14 | Y15 | Y16 |
U1 | U2 | U3 | U4 |
U5 | U6 | U7 | U8 |
V1 | V2 | V3 | V4 |
V5 | V6 | V7 | V8 |
packed:每个像素点的Y,U,V交错存储
下面以UYVY422为例,来理解packed的存储方式
U1 | Y1 | V1 | Y2 | U2 | Y3 | V2 | Y4 |
U3 | Y5 | V3 | Y6 | U4 | Y7 | V4 | Y8 |
U5 | Y9 | V5 | Y10 | U6 | Y11 | V6 | Y12 |
U7 | Y13 | V7 | Y14 | U8 | Y15 | V8 | Y16 |
其它类型比如VYUY422,YUYV422,YVYU422等,只是Y,U,V的列顺序不同而已
semi-planar: 先存所有像素点的Y,再交错存储每个像素点的UV
下面以YUV422SP为例,来理解semi-planar的存储方式
Y1 | Y2 | Y3 | Y4 |
Y5 | Y6 | Y7 | Y8 |
Y9 | Y10 | Y11 | Y12 |
Y13 | Y14 | Y15 | Y16 |
U1 | V1 | U2 | V2 |
U3 | V3 | U4 | V4 |
U5 | V5 | U6 | V6 |
U7 | V7 | U8 | V8 |
HSV色彩空间的三个分量是:
Hue(色调、色相)
Saturation(饱和度、色彩纯净度)
Value(明度)
Hue为固定值的时候,饱和度Saturation越小,表示对应颜色里的白色越多,光谱本身颜色越淡,饱和度为0时颜色呈现白色。明度Value越小,表示对应颜色里的黑色越多,光谱本身颜色就越看不出来,明度为0时颜色呈现黑色。饱和度和明度的值,可以理解为当前颜色占白色和黑色的比例。
注意一点, HSV 中的Hue里没有白色,白色需要由S和V共同决定(S=0, V=100)。
HSL色彩空间
HLS 的三个分量是hue(色相)、saturation(饱和度)、lightness(亮度)。和HSV类似,区别是亮度Lightness和明度Value。
HLS 中的亮度为100表示白色,亮度为0,表示黑色;
HSV 中的明度为100,表示光谱色,明度为0,表示黑色。
HLS 中白色仅由亮度一个分量决定,在图像处理中检测白色时使用 HSL 颜色空间更准确。
还有很多其他类型的色彩空间如HSB,Ycc,Lab,CMYK等,感兴趣的可以自行google。
CFA全称Color Filter Array,色彩滤波阵列(颜色过滤阵列)。在这个专栏第一篇文章里有提到过sensor单个像素上存在一个颜色过滤片。
Camera和Image sensor技术基础笔记(1) -- 光和CCD/CMOS sensor基础知识_亦枫L的博客-CSDN博客
需要注意的是这种方式实际Sensor的一个像素只能记录一种颜色,在CFA出现之前,单个像素上摆放的是R、G、B三个滤光片,单个像素实际上能得到的全部三通道的值。CFA出现之后,使用CFA的sensor,单个像素只能获得一种颜色值,然后再通过插值的方法恢复出其它两个分量的值。这样对于滤光片的制作的难度上要求就降低了,特别是当单个像素面积越变越小的时候。
对于Bayer阵列颜色的排布方式,一般按照相邻的四个(2x2)格子的颜色排布顺序来定义。常见的bayer阵列pattern有:
RGGB,例如从[R1,G2;G7,B8] 开始算起;
GBRG,例如从[G7, B8; R12, G13]开始算起;
GRBG, 例如从[G2,R3;B8,G8]开始算起;
BGGR, 例如从 [B8,G8;G13,R14]开始算起;
无论哪种形式,绿色格子总是会有两个,因为人眼对绿色更为敏感。下面的例子中sensor的byaer阵列采用了BGGR排布。
这种方式下,sensor输出的原始数据会按照bayer pattern的形式输出。由于每个像素只有一个颜色,需要通过插值来补全像素的其它颜色分量的值。这个过程叫做“去马赛克”(Demosaic)。插值的算法有很多种。但通常来讲,将原始图像转换为RGB图的插值算法需要临近的像素的值作为参考,像素用的多一些,算法恢复的值就准确一些,同时计算的开销也就变得更大。
常见的插值算法:双线性插值法、基于梯度方法、自适应方法等等。
在实际应用中存在很多种不同的插值算法,除了公开的一些算法,还有一些是厂家的“秘籍”不公开。实际工作中,要么是用OpenCV这类软件去做,要么是有专门的IP硬件去做,具体的插值算法细节在之后如果有涉及到再具体展开。