颜色空间模型(HSV\LAB\RGB\CMYK)
通过Photoshop的拾色器,我们知道表征颜色的模型的不止一种,本文将系统并且详细讨论这四种模型(HSV、LAB、RGB和CMYK)之间的联系以及应用。
本文部分章节整合了多位优秀博主的博客(链接见本文末尾),并对其表示感谢。文章中模型转换使用的是C式伪代码而不是数学公式,这样更便于编程人士理解。
图1.Photoshop cc的拾色器
数字图像处理中,最常用的使用也是最容易理解的是RGB模型,常用于颜色显示和图像处理,是三维坐标的模型形式。
下面先介绍RGB模型(图1),该模型可以使用vec3(r, g, b)表示,相当于三维直角坐标系,x、y、z轴相当于红、绿、蓝三通道,原点vec3(0.0, 0.0, 0.0)代表黑色,顶点vec3(1.0, 1.0, 1.0)代表白色,原点到顶点的中轴线x = y = z代表灰度线。
图2.RGB模型
图3.RGB模型解析
用RGB模型表征色彩、深浅、明暗变化的方法是:
色彩变化:三个轴RGB的最大分量顶点与黄紫青(YMC)色顶点的连线;
深浅变化:RGB顶点与CMY顶点到中轴线(原点和顶点的连线)的距离;
明暗变化:中轴线上的点的位置。离远点近偏暗,反之偏亮。
自然界中7色光都是单色光,都有自己独特的光谱特征。之所以使用RGB能混合成其他颜色的光,是因为人类的感官系统导致的,与人类的生理系统有关。可以说:将RGB以不同的比例混合后,人的眼睛可以形成与其他各种频率的可见光等效的色觉,所以才采用RGB作为三原色。
通过对RGB模型的讲解,我们了解到虽然RGB用来表示颜色方便,但相近的两个颜色其值相差可能较大。可以说RGB模型适用于计算机表示,而接下来讲解的HSV模型(Hue色相、Saturation饱和度、Value/Brightness亮度,也叫HSB)模型更适合人类习惯。
HSV模型可以使用倒锥形模型表示(图2)。模型中H表示色彩信息,即光谱颜色所在的位置,该参数用角度来表示,红、绿、蓝分别相隔120°,互补色(CMY)分别相差180°。纯度S是一个比例值,范围[0, 1],表示所选颜色的纯度和该颜色最大的纯度之间的比率,当S = 0时,代表灰度。V表示色彩的明亮程度,范围[0, 1],与光强度无直接关系。
图4.HSV模型
图5.HSV模型解析
HSV对人类来说是一种最直观的颜色模型,我们指定彩色角H,并使V = S = 1.0,然后通过添加黑色或者白色得到目标颜色。增加黑色可以减小V而S不变,这样减小了该颜色亮度;同样增加白色可以减小S而V不变,这样增加了颜色亮度。例如深蓝色(240°, 1.0, 0.4),浅蓝色(240°, 0.4, 1.0)[百度百科]。
一般的,人的眼睛最大能区分128种色彩,130种饱和度和23种明暗度。若仅使用16bits表示HSV值的话,可用7位存放H,4位存放S,5位存放V,即H7S4V5或者H6S5V5就能满足需求。
HSV可用于颜色分割:用H和S表示颜色距离。Androutsos等人同过实验,对HSV颜色空间模型进行大致划分,V > 75% && S > 20%为亮彩色区域,V < 25%为黑色区域,V > 75% && S < 20%为白色区域,其他为彩色区域。对于不同的彩色区域,混合H与S变量,根据划定的阈值就可以进行简单的颜色分割。
《Improving shadow suppression in moving object detection with HSV color information》(基于HSV的去阴影算法)
HSV模型不适合在使用光照的模型中,大部分光线混合运算、光强度运算都无法直接使用HSV模型来实现。
RGB与HSV模型互转(伪代码表示)
取值范围:
R, G, B: [0.0, 1.0] // RGB 0 - 255
H: [0, 2π] // H: [0, 360]
S, V: [0.0, 1.0] // S、V: [0, 100]%
1.RGB to HSV:
float maxValue = max(R, G, B);
float minValue = min(R, G, B);
V = maxValue;
S = (V != 0) ? 1.0 - minValue / maxValue : 0.0;
if (maxValue == minValue)
// undefined, throw error or return valid value.
if (R == maxValue && G >= B)
H = π/3 * (G - B) / (maxValue - minValue) + 0; // H = 60 * (G - B) / (maxValue - minValue) + 0;
if (R == maxValue && G < B)
H = π/3 * (G - B) / (maxValue - minValue) + 2π; // H = 60 * (G - B) / (maxValue - minValue) + 360;
if (G == maxValue)
H = π/3 * (B - R) / (maxValue - minValue) + 2π/3; // H = 60 * (G - B) / (maxValue - minValue) + 120;
if (B == maxValue)
H = π/3 * (R - G) / (maxValue - minValue) + 4π/3; // H = 60 * (G - B) / (maxValue - minValue) + 240;
2. HSV to RGB
hi = mod(floor(H / (π/3)), 6); // hi = floor( H / 60° ) mod 6
f = H / (π/3) - hi; // H = 60 * (G - B) / (maxValue - minValue) + 0;
p = V * (1 - S);
q = V * (1 - f * S);
t = V * (1 - (1 - f) * S);
switch (hi)
case 0: R = V; G = t; B = p; break; // (R, G, B) = (V, t, p)
case 1: R = q; G = V; B = p; break; // (R, G, B) = (q, V, p)
case 2: R = p; G = V; B = t; break; // (R, G, B) = (p, V, t)
case 3: R = p; G = q; B = V; break; // (R, G, B) = (p, q, V)
case 4: R = t; G = p; B = V; break; // (R, G, B) = (t, p, V)
case 5: R = V; G = p; B = q; break; // (R, G, B) = (V, p, q)
第三个我们要介绍的是Lab模型,该模型是基于人对颜色的感觉,描述的是颜色的显示方式,而非显示设备生成颜色所需要的特定色料的数量,故Lab也被视为设备无关的颜色模型。
Lab色彩模型是由亮度(L,Luminosity)和有关色彩的a、b三个要素组成。a表示从洋红色到绿色的范围,b表示由黄色到蓝色的范围。L取值[0, 100],当L = 50时,相当于50%的黑。a、b的值域都是[-128, 127]。当x = -128时,a是绿色,b是蓝色;当x渐渐过渡到127时,a渐渐变成了洋红色,b渐渐变成了黄色。所有的颜色可以由这3个值交互变化组成。例如,当Lab取值为(100, 30, 0)时,色彩表现为粉红色。
Lab模式中,a轴和b轴与RGB模型相比,洋红色更加偏红,绿色更加偏青,黄色略带红色,蓝色略偏青色。
图6.Lab颜色模型
Lab模型具有不依赖设备的优点,除此之外,它还具有宽阔的色域优势。色域范围内不仅包含了RGB、CMYK的所有色域,还能表示他们不能表现的色彩。人类能感知的色彩,都能通过Lab模型表现出来。另外,Lab色彩模型弥补了RGB色彩模型中分布不均匀的不足,在RGB模型中蓝色到绿色之间过度的色彩多,而绿色到红色之间缺少黄色和其他色彩。所以,如果想在数字图像处理中保留宽阔的色域和丰富的色彩,最好选择Lab模型。
1.RGB模型到Lab色彩空间的转换
RGB无法直接转成Lab,需要先转换成XYZ再转成Lab,因此转换需要两个步骤:
R、G、B: [0.0, 1.0] // 0 - 255
L: [0, 100]
a、b: [-128, 127]
(1)RGB转成XYZ
R = gamma(R);
G = gamma(G);
B = gamma(B);
float gamma(float x)
{
if (x > 0.04045) {
return pow((x + 0.055) / 1.055, 2.4);
} else {
return x / 12.92;
}
}
mat3x1(X, Y, Z) = mat3(M) * mat3x1(R, G, B);
其中 0.436052025 0.385081593 0.143087414
[M] = [ 0.222491598 0.716886060 0.060621486 ]
0.013929122 0.097097002 0.714185470
gamma函数是用来对图像进行非线性色调调整的,目的是提高图像的对比度。该函数并不唯一,本文给出的值被广泛应用于大多数。
(2)XYZ转Lab
L = 116 * f(Y / Yn) - 16;
a = 500 * (f(X/ Xn) - f(Y / Yn));
b = 200 * (f(Y / Yn) - f(Z / Zn));
float f(float t)
{
if (t > pow(6.0 / 29.0, 3)) {
return pow(t, 1.0 / 3.0);
} else {
return 1.0 / 3.0 * pow(29.0 / 6.0, 2.0) * t + 4.0 / 29.0;
}
}
其中Xn、Yn、Zn一般默认为1。
最后,本文介绍CMYK色彩模式,该模式是以打印油墨在纸张上的光线吸收特性为基础,图像中每个像素都是由靛青(C)、品红(M)、黄(Y)和黑(K)按照不同比例组成。每个像素的每种印刷油墨会被分配一个百分比例,最亮的颜色分配较低的印刷油墨颜色百分比,较暗的颜色分配较高的百分比。例如,明亮的红色可能会是(0.02, 0.93, 0.9, 0)。(0, 0, 0, 0)会产生纯白色。
R、G、B: [0.0, 1.0] // 0 - 255
C、M、Y、K: [0.0, 1.0] // 0% - 100%
由CMYK转换成RGB的公式:
R = (1.0 - C) * (1.0 - K)
G = (1.0 - M) * (1.0 - K)
B = (1.0 - Y) * (1.0 - K)
参考链接:
http://baike.baidu.com/view/1139658.htm (颜色模式)
http://baike.baidu.com/view/974298.htm (色彩空间)
http://zhuanlan.zhihu.com/lianghai/19652492
http://blog.csdn.net/viewcode/article/details/8203728