摘要:这里记录一下关于“颜色”这一话题的个人认识,因是个人认识,所以不建立在科学基础上。建议先去看看关于颜色的一点认识(一)

光的定义

关于颜色的一点认识(二)1.png

科学牛顿把一束日光穿过三棱镜,结果白光会分散成许多不同颜色的光。这些光每个波长具有不同的颜色。500 – 530nm 波长的光人看上去是绿色,460 – 480nm 波长的光人看上去是红色。科学家把只有单一波长的光叫做单色光。

这里补充一下:有个叫名词叫贝措德-布吕克效应(Bezold-Brücke effect),总结就是光的强度变化会影响到人类感知到的颜色

人的视觉对不同波长光的颜色辨认精度不同。除了黄(572nm)、绿(503nm)、蓝(478nm)外,其他波长的颜色随光的强度而变化。
关于颜色的一点认识(二)2.png
下面是一张入射光是氦氖激光器产生的632.8nm红光的图片,用彩色CCD去观察。可以看到中心是白色,然后渐变为黄色,边缘处是红色。
关于颜色的一点认识(二)3.png

人眼构造

人类是怎么看到颜色呢?人类眼里有两种感光细胞:视杆细胞(rod)视锥细胞(cone),其中视锥细胞由L、M、S三种细胞组成。

视杆细胞:主要分布在视网膜的外围,虽然不能感知颜色,但它有很高的光敏性,用来黑暗条件中分辨轮廓
视锥细胞:主要集中在视网膜或凹点中心,它可以感知颜色,但比视杆细胞的感光性要差,用来明亮条件下分辨颜色和细节

所以明亮条件下主要是视锥细胞感知光,人们可以分辨物体的细节和颜色,这种视觉模式被称为明视觉。黑暗条件下主要是视杆细胞感知光,人们只能分辨物体的大致轮廓,这种视觉模式被称为暗视觉

人眼中感光细胞中视杆细胞占了95%,而视锥细胞仅占5%。因此,人眼对亮度的敏感程度要高于对色度的敏感程度,人眼对于亮度的分辨要比对颜色的分辨精细一些。如果把图像的色度分量减少一些,人眼也丝毫感觉不到变化和差异。

随着科学进步,科学家发现每种不同的感光细胞感光的原因在于含有不同的感光色素。而用不同颜色的光照射这些色素会产生光致异构化(Photoisomerization)现象【简单理解为这些感光色素会产生响应即可】。所以科学家从人眼中切除约 150 个完整的视锥细胞,这些视锥细胞固定在一根小玻璃管中,并用一束细细的单色(单波长)光从侧面照射(a technique called microspectrophotometry 显微分光光度法),测量细胞中含有的感光色素对不同颜色光的敏感程度。最后得到了相对灵敏度曲线(relative sensitivity curve)

实验结果如下:

关于颜色的一点认识(二)4.png

5、39、45、58分别代表测试的不同种类的细胞的数量,总数量共计150个。横坐标代表光的波长。纵坐标代表感光色素对相应波长光的敏感程度,即产生反应的细胞占总体细胞的比例。紫色线代表是S视锥细胞中的感光色素、淡蓝色线是杆状细胞中的感光色素、绿色线是M视锥细胞中的感光色素、红色线是L视锥细胞中的感光色素。

测量后科学家发现一个bug:

如果每种类型的视锥细胞仅包含一种感光色素并且视锥细胞对光刺激的产生的强度与响应的感光色素的数量成正比,则相对灵敏度曲线应该能描述色觉。事实上,这些曲线并不对应于人类的颜色匹配实验,特别是对于L 视锥细胞。因此,我们必须将注意力转移到视锥细胞上,因为它们在完整(活的)视网膜中做出反应。

所以以单靠感光色素不能拿来完全衡量色觉。

后面又有两位科学家分别是 Andrew Stockman 和 Lindsay Sharpe (2000) 结合色彩匹配实验(color matching)得出了视锥细胞的灵敏度曲线(cone sensitivity curve)。如果想知道视锥细胞的灵敏度曲线怎么画出来的,自己去看论文去The spectral sensitivities of the middle- and long-wavelength-sensitive cones derived from measurements in observers of known genotype0

关于颜色的一点认识(二)5.png

视锥细胞的灵敏度曲线(cone sensitivity curve) 说明不同种类的视锥细胞对不同波长的光的敏感程度不同。

又有人根据视网膜解剖结构的比例:63% L视锥细胞31% M视锥细胞6% S视锥细胞,对上面那幅图进行加权,得到下面这幅图表群体加权线性锥敏感度函数(population weighted linear cone sensitivity functions)

关于颜色的一点认识(二)6.png

群体加权线性锥敏感度函数(population weighted linear cone sensitivity functions) 说明人眼总体对不同波长的光的敏感程度不同。

根据加权后的图表可以看出 我们的眼睛对光谱中间的“黄绿色”波长最敏感:黄色和绿色是棱镜光谱或彩虹中最明亮的颜色。事实上,我们的大部分光敏感度都在 500 nm 到 620 nm 之间——大致从“蓝绿色”到“猩红色” 。

后面又有人提出:

在色度测量中采用的一个合理假设是,每种类型的锥状细胞在感知纯白色或无色彩色时都有相等的贡献。这意味着锥状细胞基本上并不代表单个光感受器,而是作为一个组的锥状细胞类别或类型。在视觉系统中,每个类别都被赋予了相等的感知权重。在这种显示方式中,每个灵敏度曲线的峰值会被放大或缩小,以使每个曲线下的面积(相当于每种类型的锥状细胞的总响应灵敏度,汇总所有的锥状细胞)相同;这些曲线通常在线性垂直刻度上呈现。

关于颜色的一点认识(二)7.png

如果想看比较权威的资料,请去以下网站看 light and the eye

颜色定义

有人研究说色彩可以用 明度(lightness)色调、色相(hue)饱和度(saturation)。用我的话说又是一堆白痴样的玩意

明度

表示物体明亮程度的一种属性。
彩色光的亮度越高,人眼就越感觉 明亮。在物理上表现为物体表面的光反射率越高,明度就越高。

关于颜色的一点认识(二)8.png

色相

色相是彩色彼此相互区分的特性。
在物理学中表现为可见光的光谱波长不同。在视觉上表现为红、橙、黄、绿、蓝、紫等各种色调。

关于颜色的一点认识(二)9.png

饱和度

饱和度是指彩色的纯度(纯洁度)。
可见光中的单色光是最饱和的彩色,饱和度为1。
单色光中掺入白光成分越多,饱和度就越低。

关于颜色的一点认识(二)10.png

上面关于颜色属性的定义由于各种奇奇怪怪的原因,在各种工具中一个名字不同叫法,再加上三者之间不是严格的并列关系,所以慢慢的问题很大。这也是我说他是一堆白痴玩意的原因。后面会举个例子说明。

颜色的科学定义

上面虽然从物理上解读了人眼对光的敏感程度,但是依然无法解读:我要定义制作一个红色的染料,怎么衡量有多红?因为这不是最精确的“物理科学”级别的描述。我们需要一种完全客观的方式来描述色彩。

于是Commission Internationale de l’Eclairage (CIE)在1931年建立了一套色彩系统,希望能够完全客观的量化色彩。

CIE 1931 RGB Color Specification System 【1931】

此RGB 非彼RGB

很多人一看到RGB 就觉得这就是现在常说的那个RGB 色彩模型,一个立方体的盒子。

不不不!要说到你理解的那个RGB 还有好多年要走…… 这两个RGB 八杆子打不着。

CIE1931—RGB标准色度观察者光谱三刺激值曲线图

不幸的是,在色彩科学中不存在“完全的客观”。因为最后总是需要人来看颜色,人就是主观的。
于是就需要想办法尽可能的弱化这部分主观可能导致的误差。CIE 的科学家想出了一个实验 颜色匹配实验(color match function)

关于颜色的一点认识(二)11.png

关于颜色的一点认识(二)12.png

  1. 观察者通过一个挡板上面的洞看到后面的两个白板;
  2. 右边的白板被某个测试光源照亮,左边是被RGB 三个基色混合照亮。
  3. 要求观察者,通过调整RGB 三个光源的强度,使得左右两边的颜色看起来一样。
  4. 然后,记录下此时RGB 三基色分别的强度数值。如果用公式来表示:

    【测试光源】 = R * [R] + G * [G] + B * [B]

    [R]、[G]、[B] 表示三个基色,r、g、b 分别对应三种基色的强度,也称为三刺激值

    [R] = 光通量为 1 lm的700.0 nm的红光。
    [G] = 光通量为 4.5907 lm的546.1 nm的绿光。
    [B] = 光通量为 0.0601 lm的435.8 nm的蓝光。
    

    这个公式表示的就是色彩的加色混合原理。

CIE 很有耐心的把从380 nm ~ 780 nm波长中所有的光线都作为测试光,一个一个的重复上面的实验。
就得到了类似如下的数据:

380 nm = 0 * [R] + 0 * [G] + 0.01 * [B]
381 nm = 0 * [R] + 0 * [G] + 0.02 * [B]
……
780 nm = 0.01 * [R] + 0 * [G] + 0 * [B]

然后,我们把所有的数值都画在一张图表上面。就得到了三条曲线,其中R、G、B分别对应R(λ)、G(λ)、B(λ)。称为CIE1931—RGB标准色度观察者光谱三刺激值曲线图

关于颜色的一点认识(二)13.png

如果你很细心的观察,你会发现有从435.8 nm ~ 546.1 nm 这段波长中,红色基色的强度竟然是负值?!

难道还能出现吸收光亮的光线么?!

当然是不可能的,造成这个的原因是在这个波段中,测试者不论怎么努力的调整三基色的强度都无法让混合后的颜色与测试光源的颜色相同;最后只要在测试光源的那一侧混入一定量的红色才使得左右两边看起来颜色相同。

这个通过公式来说就是:

【测试光源】+ R * [R] = G * [G] + B * [B]
(等式两遍同时减去 R * [R])
【测试光源】 = -R * [R] + G * [G] + B * [B]

这就是为什么出现了红色基色的强度出现了负值。

CIE1931—RGB标准色度观察者光谱三刺激值色度图

上面的色彩匹配方程其实已经完全足够了,但是科学家有个癖好,总是希望参数都是-1~1 之间的。这一步操作就叫做归一化
归一化的计算也是异常的简单,原理就是算出每种基色强度在当前混色强度中所占的比例:

r = R / (R+G+B)
g = G / (R+G+B)
b = B / (R+G+B)

经过这样的计算之后,r、g、b 就都是在-1 ~ 1 之间了。而且很明显,我们发现 r + g + b = 1。

这么说的话,我们只需要知道r、g、b 三个参数中的任意两个,剩下的一个总是可以通过 1 - r - g 来得到。

也就是说,我们没有必要使用三个参数啦!只需要两个就够了!这也是归一化的另外一个优点。

这一步需要你稍微有点空间想象能力啦!

因为我们已经对数值进行归一化,因此只需要两个变量就足够表示所有的信息.

这里我们选择 r、g 这两个参数,那么b = 1 - r - g 是可以随时计算出来的。

所以我们画个图表,横坐标是r,纵坐标是g ,然后把所有的数值都画在这个图表上,就得到了CIE1931—RGB标准色度观察者光谱三刺激值色度图

关于颜色的一点认识(二)14.png

这里注意一下国际上一般以R、G、B大写表示三刺激值(three tristimulus value),r、g、b小写表示色度图。下面的CIE 1931 XYZ Color Specification System【1931】也是一样

CIE 1931 XYZ Color Specification System【1931】

为了消除CIE1931—RGB标准色度观察者光谱三刺激值色度图上面的负值,科学家又进行了一堆数学变幻,将CIE1931—RGB转换为了CIE1931-XYZ

关于转换步骤可以参考:

CIE RGB 转 XYZ
颜色的计量系统
How the CIE 1931 Color-MatchingFunctions Were Derived fromWright–Guild Data

在CIE RGB 转 XYZ中涉及到下图中YZ线的选取,可以参考 How the CIE 1931 Color-MatchingFunctions Were Derived fromWright–Guild Data

关于颜色的一点认识(二)15.png

CIE1931—XYZ光谱三刺激值色度图

关于颜色的一点认识(二)16.png

CIE1931—XYZ光谱三刺激值曲线图

关于颜色的一点认识(二)17.png

关于CIE1931—RGB和CIE1931—XYZ的补充说明

逻辑上是由CIE1931—RGB标准色度观察者光谱三刺激值色度图推导出CIE1931—XYZ光谱三刺激值色度图,然后再由CIE1931—XYZ光谱三刺激值色度图推导出CIE1931—XYZ光谱三刺激值曲线图

CIE1931—RGB颜色空间是一个三维空间,把CIE1931—RGB标准色度观察者光谱三刺激值曲线图中的点画到三维立体空间中即可得到。
CIE1931—XYZ颜色空间也是一个三维空间,把CIE1931—XYZ光谱三刺激值曲线图中的点画到三维立体空间中即可得到。

CIE1931—XYZ颜色空间三维空间示意图:

关于颜色的一点认识(二)18_GamutXYZ_WF.gif

CIE1931—xyY颜色空间三维空间示意图:

关于颜色的一点认识(二)19_GamutxyY_WF.gif

CIE1931—XYZ中光谱三刺激值 与 CIE1931—RGB中光谱三刺激值 中坐标转换关系:

X = 2.7689*R  +1.7518*G + 1.1302*B
X = 1.0000*R  +4.5907*G + 0.0601*B
Y = 0.0000*R  +0.0565*G + 5.5942*B

CIE1931—XYZ光谱三刺激值色度图 与 CCIE1931—RGB标准色度观察者光谱三刺激值色度图 中坐标转换关系:

x =(0.490r+0.310g+0.200b)/(0.667r+1.132g+1.200b)
y =(0.117r+0.812g+0.010b)/(0.667r+1.132g+1.200b) 
z =(0.000r+0.010g+0.990b)/(0.667r+1.132g+1.200b

上面提到过光的强度光的强度变化会影响到人类感知到的颜色,所在在颜色匹配实验的时候应该是对光的强度做了限制的。

参考颜色的计量系统中的这段话“分布色系数是指辐射功率为1瓦(注意,不是1光瓦)波长为l 的单色光所需要的三基色的单位数”。我猜测其中的分布色系数应该就是指颜色匹配实验(color match function)得到的三刺激值。所以颜色匹配实验(color match function)`应该限制了待测光的功率为1W。

色彩空间

对于色彩空间,还可以细分为绝对色彩空间非绝对色彩空间。上面讨论的CIE1931-RGB以及CIE1931-XYZ都是绝对色彩空间CIE L*a*b*白点固定的情况下,也是绝对色彩空间。其区别在于,绝对色彩空间对其空间内的某一色彩定位不依赖于外界,也就是说,它的任一坐标都明确指向了特定的人眼视觉所能感知的某种颜色

与之相对的,当然还有非绝对色彩空间。非绝对色彩空间可举例如我们常用的RGB色彩模型,同样的RGB数值在不同品牌的显示器上,将显示不同的颜色。但我们可以通过将非绝对色彩空间中的颜色与绝对空间色彩相映射,使这一颜色绝对化。

例如,我们在使用显示器时可以通过设置ICC颜色配置,来使不确定的RGB颜色被绝对化。我们可以说,测量和调整监视器颜色标准显示的目的就是要将显示设备所表现出的非绝对色彩空间集合转换成绝对色彩空间,使我们在不同显示设备中进行调色、监看、放映时,获得与统一标准的色彩表现

关于颜色的一点认识(二)20.png

常见色彩空间

以下列出常见的色彩模式以及其色彩空间。

  • RGB: 适用于数字显示屏设备。

    • CIERGB:也叫 CIE 1931 RGB 或 CIE RGB 色彩空间,RGB 色彩空间之一,以单色(单一波长)原色的特定集合著称。
    • CIEXYZ (CIE 1931 XYZ): 由国际照明委员会 (CIE) 制定的标准颜色空间。在颜色感知的研究中,CIEXYZ(也叫 CIE 1931 XYZ 或 CIE XYZ)色彩空间是其中一个最先采用数学方式来定义的色彩空间。它由国际照明委员会 (CIE) 于 1931 年创立。
    • CIEUVW (CIE 1964 UVW*): CIEXYZ。
    • CIELUV: CIEUVW 的变体
    • HSLuv: CIELUV 的变体
    • sRGB: 最常见的数字显示器的色彩空间。网站开发的默认色彩空间。即红[0, 255]、绿[0, 255]、蓝[0, 255],是一种面向硬件系统的加色模型。
    • Adobe RGB: Adobe RGB 比 sRGB 提供更宽的色域。
    • DCI-P3: 常见于电视、电影。
    • Display-P3: 苹果基于 DCI-P3 提出的演变版本。所有苹果产品的显示器都使用 Display-P3 色彩空间。DCI-P3 的色域比 sRGB 色域宽近四分之一。
    • NTSC: 美国电视标准委员会制定的标准。常见于专业级影片和照片编辑的显示器。
      EBU: 欧洲广播联盟制定的标准。
    • ICtCp
      ICtCp(ITP)是BT2100定义的一种像素格式, 主要用于HDR或者WCG(广色域)的图像或者视频。I代表亮度(luma),CtCp代表色度, 其中,Ct 代表 蓝-黄,Cp 表示红-绿。杜比视界 profile5 使用的是该像素格式
  • LAB

    • CIELAB(CIE Lab*):CIE Lab*色彩空间写为 CIE L*a*b*,是国际照明委员会 (CIE) 在 1976 年定义的色彩空间。它将颜色用三个值表达示:“L”代表感知的亮度、“a”和“b*”代表人类视觉的四种独特颜色:红色、绿色、蓝色和黄色。CIE Lab* 旨在作为一个感知上统一的空间,其中给定的数字变化对应于相似的感知颜色变化;虽然并不是真正的感知均匀,但在工业上仍可用于检测颜色的细微差异。CIE Lab*色彩空间与Hunter Lab都源自CIE XYZ色彩空间,为了有效区别,应避免将CIE Lab*写为不带星号的“Lab”。
    • CIELCh: CIELAB 的变体
    • Hunter LAB: 由理查·亨特 (Richard S. Hunter) 于 1948 年定义的 Hunter Lab 色彩空间是另一种名称有“Lab”的色彩空间。与 CIELAB 一样,它也可以通过 CIEXYZ 空间中的简单公式进行计算,但在感知上比 CIEXYZ 更为一致。亨特将他的色彩坐标命名为 L、a and b。 CIE 将 CIELAB 的坐标命名为 L*a*b*,以便于区别 Hunter 的坐标。
    • Munsell LAB: 根据 Munsell 颜色系统开发的 LAB色彩空间。
  • HSV

    • 即色调[0, 360]、饱和度[0, 100]、明度[0, 100],是一种符合人类视觉系统的倒锥体颜色模型。
  • HSL

    • 即色调[0, 360]、饱和度[0, 100]、亮度[0, 100],是一种符合人类视觉系统的双锥体颜色模型。
  • CMYK: 适用于喷墨和激光打印。

    • CMYK:刷四分色模式(CMYK)是彩色印刷时采用的一种套色模式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合叠加,形成所谓“全彩印刷”。四种标准颜色是:C:Cyan =青色,常被误称为“天蓝色”或“湛蓝”、M:Magenta =洋红色,又称为“品红色”、Y:Yellow =黄色、K:blacK=黑色,此处缩写使用最后一个字母K而非开头的B,是因为在整体色彩学中已经将B给了RGB的Blue蓝色。
    • SWOP(Specifications for Web Offset Publications,网路印刷出版规格):主要用于印刷杂志、目录和其他高质量印刷出版物。
    • Euroscale: 主要用于欧洲印刷,与 SWOP 相比,它的色域略有不同。
    • DIC (Dainippon Ink and Chemicals): 由日本一家油墨和化学公司开发的色彩空间。
    • FOGRA (Fogra Graphic Technology Research Association): 一种用于胶印的德国色彩空间。
    • TOYO: 一种由日本油墨制造商开发的色彩空间。
    • HKS: 图形行业中用于专色印刷的颜色空间。
    • ANPA (American Newspaper Publishers Association): 一种用于报纸印刷的颜色空间。
  • YUV

    • YUV
      “Y”表示明亮度(Luminance、Luma),“U”和“V”则是色度、浓度(Chrominance、Chroma)。YUV适用于PAL和SECAM彩色电视制式。YUV由来主要还是因为人眼对亮度更加敏感,颜色更迟钝,所以人们定义了一种色彩空间下,颜色的亮度信息被完全保存,色域信息将会进行下采样以压缩数据。YUV的发明处在彩色电视与黑白电视的过渡时期。YUV将亮度信息(Y)与色度信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的。这样的设计很好地解决了彩色电视与黑白电视的兼容性问题,使黑白电视也能够接收彩色电视信号,只不过它只显示了Y分量彩色电视有Y、U、V分量,如果去掉UV分量,剩下的Y分量和黑白电视相同。
    • YCbCr
      是YUV压缩和偏移的版本。YCbCr的Y与YUV中的Y含义一致,Cb和Cr与UV同样都指色彩,Cb指蓝色色度,Cr指红色色度。
    • Y’CbCr
      Y’的含义和YCbCr中的Y有所不一致,Cb分别指蓝色、红色色度。此外Y’CbCr 用于数字图像领域,YUV 用于模拟信号领域;MPEG、DVD、摄像机中常说的 YUV 其实是 Y'CbCr,二者转换为RGBA的转换矩阵是不同的。
    • YIQ
      YIQ是NTSC(美国国家电视标准委员会)在1953年定义的一种颜色空间,它由亮度(Y)和两个色差(I和Q)组成。YIQ颜色空间用于将RGB颜色信号转换为适用于电视传输的格式。在传输过程中,YIQ信号比RGB信号占用更少的带宽,因此可以更有效地传输。在接收端,YIQ信号被转换为RGB信号,以便在电视屏幕上显示。YIQ颜色空间与RGB颜色空间的不同之处在于,它将亮度和色度信息分开传输。这使得亮度信息可以与色度信息分开处理,从而提高图像质量。YIQ颜色空间在NTSC电视系统中被广泛使用,并且在其他电视系统中也有所应用。

如何定义一个颜色空间

CIE1931—XYZ光谱三刺激值色度图基本包含了我们能够感知到的最大色域,这也让它成为我们定义其他颜色空间所使用的标准空间。通常,我们会指定一个颜色空间,它定义了当前工作空间(workspace)下我们所关心的所有颜色值域范围,下面以sRGB颜色空间举例:

关于颜色的一点认识(二)21.png

图片来源:https://www.colour-science.org/posts/the-importance-of-terminology-and-srgb-uncertainty/

如上所示,RGB颜色空间本质是一个三维空间(左图),但为了方便可视化,我们通常会在CIE1931—XYZ光谱三刺激值色度图里来表示它的色度范围(右下图),上面的黑点表示右上图的所有像素在这个RGB颜色空间的位置。那么如何在数学上定义这样一个完整的RGB颜色空间呢?它需要包含以下三个组成部分:

  • 三原色(Primaries)
  • 白点(Whitepoint)
  • 传递函数(Transfer Function

三原色

为了定义一个RGB颜色空间的三原色,我们通常会在CIE 1931 xy色度图里中指定它的三原色的xy坐标,这些三原色定义了这个颜色空间的色域(gamut)。例如我们熟悉的sRGB颜色空间三原色的xy坐标如下:

关于颜色的一点认识(二)22.png

这些三原色就是色度图中三角形的三个顶点坐标,它们分别表示了这个sRGB颜色空间中Red (1, 0, 0)、Green (0, 1, 0)、Blue (0, 0, 1)在色度图中的位置:

The color primaries tells us what the primary colors Red (1,0,0), Green (0,1,0) and Blue(0,0,1) in our new color space map to in terms of real world chromaticities.
—— From HDR in Call of Duty

以下给出几种常见的颜色空间以及它们的三原色和白点(后面会详细讲白点)的位置(更多其他空间的三原色信息可以参见wiki):

色度图中的这些颜色空间三角形给了我们一个比较不同颜色空间范围的可视化方式,范围越大的颜色空间可以访问到更鲜亮的颜色,这在画面颜色体验上是非常不同的感受(符华的MMD可以下载HDR版本,在iPhone手机用nPlayer看HDR版本和在电脑上看普通版本是完全不一样的体验)。以下在色度图里比较各种颜色空间的色域范围:

关于颜色的一点认识(二)23.png

白点(White Point)

我们之前说过,CIE1931—XYZ光谱三刺激值色度图已经是经过降维后的二维空间了,这个空间只能表示色度信息而丢失了亮度信息,而我们实际需要使用的颜色空间仍然是三维空间。要想得到完整的颜色信息,我们需要定义一个白点(White Point)

The whitepoint defines the white color for a given RGB color space. Any set of colors lying on the neutral axis passing through the whitepoint, no matter their luminance, will be neutral to that RGB colorspace.
—— From this article

例如,我们之前提到的sRGB颜色空间的白点D65的位置如下(xy坐标为(0.31271, 0.32902)):

关于颜色的一点认识(二)24.png

白点的定义

简单来说,白点定义了这个sRGB颜色空间中纯白色 (1, 1, 1)在色度图上的位置。下面的可视化视频表示了这个定义过程:

关于颜色的一点认识(二)25_可视化视频.mp4

解释一下视频里的内容:利用三原色在色度图里的xy坐标可以它们在XYZ坐标空间中的向量方向,为了方便计算我们可以只考虑它们的单位向量方向记为(Rx, Ry, Rz)、(Gx, Gy, Gz)和(Bx, By, Bz)。通过缩放并叠加这三个单位向量方向我们可以得到这个颜色空间的任意一点的空间位置,即P = (Rx, Ry, Rz) * r + (Gx, Gy, Gz) * g + (Bx, By, Bz) * b,其中r、g、b分别表示三个向量的缩放大小。那么,我们可以找到一组(r, g, b)系数使得P = 白点位置。也就是说,通过这个白点我们可以定义三原色向量的相对长度关系(在之前的学习过程中,我总是搞不清楚色度图中的这个白点和RGB颜色空间里真正(1, 1, 1)纯白色的对应关系。用我自己的理解来说,色度图中的白点坐标是RGB三维颜色空间中纯白色(1, 1, 1)在二维xy空间中的投影,就如同三原色的xy坐标是RGB三维颜色空间中纯红色(1, 0, 0)、纯绿色(0, 1, 0)、纯蓝色(0, 0, 1)在二维xy空间中的投影一样,也就是说,色度图中的位置都是定义了真正RGB颜色空间各个点的投影位置)。那么有了相对长度关系,我们可以通过等比例缩放这组(r, g, b)系数来访问到原点到白点这条射线上的所有点的位置,其中有一个点是我们特别关心的——亮度值即纵坐标Y = 1的白点,这个特殊的三维空间白点位置定义了三原色的绝对长度值。通过这样的方式,最终我们可以在XYZ颜色空间里定义新的RGB颜色空间的三原色索引向量基Rxyz、Gxyz、Bxyz,其缩放范围均为0到1,并且当其三者的缩放值为(1, 1, 1)的时候我们可以到达亮度为1的白点Wxyz。这三个值域范围是0到1的向量基就定义了一个真正的三维RGB颜色空间范围。

还是有点绕,程序员信奉——Talk is cheap, show me the code! 下面我们以Rec. 709 / sRGB空间为例,推导下sRGB颜色空间中的坐标是如何转化到CIEXYZ颜色空间中的坐标。推导的伪代码参上:

//如果要求sRGB颜色空间中的任意一点S(SR,SG,SB)在CIEXYZ颜色空间中的对应坐标该怎么求呢?

// 已知sRGB颜色空间中的R、G、B三原色对应的CIEXYZ色度图中的三原色和白点坐标如下:

Rxyz = (0.64, 0.33, 0.03) 
Gxyz = (0.30, 0.60, 0.10)
Bxyz = (0.15, 0.06, 0.79)
Wxyz = (0.31271, 0.32902, 0.35827)

//已知sRGB颜色空间中的R、G、B三原色坐标如下:
R(RR,RG,RB) = (1, 0 ,0)
G(GR,GG,GB) = (0, 1, 0)
B(BR,BG,BB) = (0, 0, 1)


//第一步获得S(SR,SG,SB)对应的在CIEXYZ色度图中的色度坐标S(Sx,Sy,Sz):
//这个时候我们需要计算出一个公式的,从而使得
//R(RR,RG,RB) = (1, 0 ,0) 对应 Rxyz = (0.64, 0.33, 0.03)
//G(GR,GG,GB) = (0, 1, 0) 对应 Gxyz = (0.30, 0.60, 0.10)
//B(BR,BG,BB) = (0, 0, 1) 对应 Bxyz = (0.15, 0.06, 0.79)

//所以我们可以列出下列公式,得到S(Sx,Sy,Sz)。这个公式怎么来的?不要问我,只是刚好满足把R(RR,RG,RB)带入公式能够得到Rxyz。

关于颜色的一点认识(二)26.png

// 第二步:色度图中白点坐标对应CIEXYZ颜色空间中的坐标为:
WXYZ = (0.31271/0.32902, 1, 0.35827/0.32902) = (0.95043, 1, 1.08890)


// 第三步:因为色度图是由CIEXYZ颜色空间中的具体坐标归一化后得到的,无法映射为CIEXYZ颜色空间中的具体坐标,只能映射到某一个方向。所以白色点的意义在于校准三原色在向量空降中的长度,使得当 RGB = (1, 1, 1) 的时候正好对应的是白色。

假设Rxyz方向的向量长度为r、Gxyz方向的向量长度为g、Bxyz方向的向量长度为g
由定义r(Rxyz)+g(Gxyz)+b(Bxyz)=Wxyz可得下面方程式:

0.64r + 0.30g + 0.15b = 0.95043
0.33r + 0.60g + 0.06b = 1
0.03r + 0.10g + 0.79b = 1.08890

// 求解可得:
r = 0.644463125
g = 1.191920333
b = 1.202916667

//所以色度图中的三原色坐标对应CIEXYZ颜色空间中的坐标为:
RXYZ = (0.4124564, 0.2126729, 0.0193339)
GXYZ = (0.3575761, 0.7151522, 0.1191920)
BXYZ = (0.1804375, 0.0721750, 0.9503041)


//上面已经知道该点S的CIEXYZ色度图中色度坐标Sxyz为(Sx,Sy,Sz),同样假设r(Rxyz)+g(Gxyz)+b(Bxyz)=Sxyz

0.64r + 0.30g + 0.15b = Sx
0.33r + 0.60g + 0.06b = Sy
0.03r + 0.10g + 0.79b = Sz

求出r、g、b后,该点S在CIEXYZ颜色空间中的具体坐标为(r*0.4124564+g*0.3575761+b*0.1804375, r*0.2126729+g*0.7151522+b*0.0721750, r*0.0193339+g*0.1191920+b*0.9503041)

关于第二步中:为什么让Y=1?
因为CIEXYZ颜色空间中的坐标Y分量代表相对亮度,白点是最亮的点,所以Y=1。

Relative luminance Y values are normalized as 0.0 to 1.0 (or 1 to 100), with 1.0 (or 100).
——Relative_luminanceIlluminant_D65
The unit of the tristimulus values X, Y, and Z is often arbitrarily chosen so that Y = 1 or Y = 100 is the brightest white that a color display supports.
——CIE_1931_color_space

通过这样的方式,我们就可以靠色度图中的三原色和白点xy坐标还原sRGB颜色空间在XYZ空间中的三维体空间:

关于颜色的一点认识(二)27.png

色温(Color Temperature)

值得说明的是,我们可以根据上下文和使用环境给同一个RGB颜色空间定义不同的白点,例如:

  1. 如果要模拟标准观察条件下的光照环境,可以选择D50,它可以得到一个暖色温的颜色空间
  2. 如果要模拟正午条件下的光照环境,可以选择D65,它可以得到一个偏冷色温的颜色空间
  3. 如果想要模拟更冷色调的日光环境,可以选择D75,它可以得到一个更加偏冷色温的颜色空间

D50、D65、D75这些名字来源于基于色温表示的颜色信息。色温(Color Temperature)是基于黑体辐射(Black Body Radiation)物理理论基础的概念。在物理上,黑体是一种可以吸收掉所有光线的物质,而不同温度的黑体可以发射出该温度下特定光谱的光线。

温度高(比如1000K)的黑体会发出红光:

关于颜色的一点认识(二)28.png

随着温度增高光会变成黄色,比如温度为2000K:

关于颜色的一点认识(二)29.png

温度更高时会变成浅蓝色,比如温度为6500K:

关于颜色的一点认识(二)30.png

更高的温度会逐渐趋近于蓝色:

关于颜色的一点认识(二)31.png

这种温度和颜色之间的关系是非常固定的,因此我们可以使用一个温度值(以卡尔文K为单位)来指定一个特定的颜色:

关于颜色的一点认识(二)32.png

把上述特定温度下的颜色画到色度图上,我们可以得到一条曲线,这条曲线被称为普朗克轨迹(Planckian Locus,也被叫做黑体轨迹):

关于颜色的一点认识(二)33.png

我们经常会使用这条普朗克轨迹上的点来定义白点,例如之前提到的D65,字母D表示了它是在CIE Illuminant D系列下的标准照明,数字65表示了它是在6500K温度下的颜色值。D65大约表示了在西欧地区中午时间下的平均照明值:

关于颜色的一点认识(二)34.png

CIE负责颁布所有广为人知的标准照明(Standard Illuminant),这些标准包含了多个系列,其中CIE Illuminant D代表了自然天光环境下的标准照明。我们通常会在CIE 1960 UCS色度图里图示这些不同温度下的标准照明值:

关于颜色的一点认识(二)35.png

等能白光

在CIE1931—XYZ光谱三刺激值色度图有一个特殊的点叫做等能量点(equal energy point)或者等能白光(equal energy white light )

一句话放个结论:色度学中的等能量点(equal energy point)在CIE1931—XYZ光谱三刺激值色度图中的坐标为为(0.333, 0.333),CIE1931—XYZ光谱三刺激值颜色空间中的坐标为(1, 1, 1)。这个点的光谱相对辐射能通量功率分布曲线也叫做`等能量光谱(equal energy spectrum),是作为参考的白点(white point)。

但是,这个等能点定义的白色只是一个非常理想的状况,因为它是没有色温的。所以实际上也没有任何一个照明体可以达到这种白色。所以CIE又针对不同的应用场景,制订了一系列的有色温的标准照明,分别有对应的白点(white point)。例如户外阳光(D65)的白点,就是x=0.31271, y=0.32902的位置,色相上有点偏橙;纸张(D50)的白点颜色就更加橙黄色一些(x=0.34567, y=0.35850);
而电脑的白点则偏蓝一些,因为人眼对蓝色的宽容度较高。

以上的这些“白”,都实际上不是真正的纯白无色,而是在等能白点附近稍稍偏离一点的地方。但是它们在各自的系统中,都是作为“白色”的参考的。

伽马(Gamma)

现在,我们已知在新的sRGB颜色空间下的CIE1931—XYZ光谱三刺激值(tristimulus values),但我们需要在各种电子设备上显示它们。这种从线性三色值到非线性视频信号的转换关系就是由传递函数(Transfer Functions)来定义的。为什么我们非要这么麻烦地使用这一步非线性转换呢?就不能线性输入再线性输出直接完事呢?这主要是出于优化存储空间和带宽的目的(穷是原罪),Substance PBR手册里提到了这一点的动机(浪费可耻):

The Human Visual System (HVS) is more sensitive to relative differences in darker tones rather than brighter tones. Because of this, not using gamma correction is wasteful as too many bits will be allocated to tonal regions where the HVS cannot distinguish between tones.

简单来说,传递函数可以帮助我们更好的利用编码空间,以此来提升性能。传递函数可以分为以下两种:

  • OETF:光转电传递函数(opto-electronic transfer function),负责把场景线性光(relative scene linear light)转换到非线性视频信号值(non-linear signal value)。例如,当我们用摄像机拍摄时,现实场景的光会经过一次OETF转换成摄像机的视频信号
  • EOTF:电转光传递函数(electro-optical transfer function),负责把非线性视频信号值(non-linear signal value)转换成显示光亮度(display light)。例如,当我们把一个视频信号显示到屏幕上时,会经过一次EOTF

这些传递函数就是伽马矫正里使用的函数。伽马矫正(简称伽马)是指对线性三色值和非线性视频信号之间进行编码和解码的操作。在最简化版本的伽马矫正里,我们会使用一个γ < 1的值来作为编码伽马值(encoding gamma),使用这样一个伽马函数作为OETF(encoding function)来把线性颜色值转换成非线性信号值,这个过程被称为是伽马压缩(gamma compression);相反的,我们会使用一个γ > 1的值作为解码伽马值(decoding gamma),使用这样一个伽马函数作为EOTF(decoding function)来把非线性信号值转换回线性颜色值,这个过程被称为是伽马展开(gamma expansion)。

我们经常听到人们说,sRGB的解码伽马值是2.2,但实际上sRGB的伽马展开转换函数使用的指数值是2.4:

This is because the net effect of the piecewise decomposition is necessarily a changing instantaneous gamma at each point in the range: It goes from γ = 1 at zero to a gamma of 2.4 at maximum intensity with a median value being close to 2.2.
—— From wiki

在完整版本的伽马定义里,转换函数被定义成两段:靠近0的线性段部分(为了给一个C = 0处的有效定义),以及剩余的指数变化段部分。伽马曲线中各个参数的推导这里不再深入讨论,具体可以参见wiki。简单来说,我们可以使用以下公式来表示正向转换函数(这里指伽马压缩过程使用的转换函数,伽马展开过程使用的函数是下列函数的反函数):

关于颜色的一点认识(二)36.png

关于伽马校正:

假如灰度范围为0-1,平均分配给100个灯泡,1W的灯泡灰度是0.01,2W灯泡的灰度是0.02,依次类推直到100W的灰度是1 。把上面的灯泡依次拿给人辨认,让人分别哪个是中灰(灰度0.5)。理论上应该是50W的灯泡吧?但是22W的灯泡人眼就认为是中灰了。请注意整个色彩系统都是围绕人感受出发的,这一点从上面的色彩空间定义就可以看出——所有的颜色空间都要转化为绝对色彩空间。这个时候出现了伽马校正。(22/100^(1/2.2) = 0.5024597 ,经过伽马校正(其实就是数学开了次方),灰度就变成了人眼中的中灰(0.5024597)了。

那么为什么会更好的利用编码空间呢?还是拿刚才的例子举例:进行伽马变化前,1W到22W灯泡对应的灰阶数量为22。进行伽马变化后,1W到22W灯泡对应的灰阶数量为50。而人眼对暗部比较敏感,所以将用来描述1W到22W灯泡的灰阶数量变成50后(此时 我可以将1W灯泡定义为0.00003灰度、1.5W灯泡定义为0.00009灰度,相当于可以区分更多的光线比较暗的灯泡)会更能准确的描述物理暗部细节

要了解更多关于伽马校正(Gamma Correction)的知识参考:色彩空间与gamma校正

色彩空间转换

用下面这个图来表示从RGB到LCH的变换过程,从中可以看到,大体上分两类,一类是区分色域空间的,一类是不区分色域空间的。区分色域空间的,即使RGB的数值完全相等,只要对应的色域不一样,得到LCH也会不一样,这一类都是先将RGB转到和人眼比较相似的CIE1931 XYZ空间上,然后再选取某种颜色空间来衡量颜色,当然,不同的颜色空间,其得到的LCH也会不一样。总体来说,这一类是比较准确的,符合人眼特性的。而另一类,不区分色域的,哪怕是不同色域,RGB一样,得到的LCH就一样(实际人眼感知是不一样的),所以这一类是不准确的,不过这一类的计算相对要简单很多,经常一步或者两步就可以了。

关于颜色的一点认识(二)37.png

具体转换请参考 颜色空间转换-从RGB到LCH-亮度饱和度色度

icc配置文件

iCC Profile

ICC 色彩特性文件 (ICC Profile) 是一组用来描述色彩输入、输出设备或者某种色彩空间的特性的数据集合。因由国际色彩联盟 (ICC) 主持制定其规范而得名。

该类文件被广泛用于色彩管理,以实现让颜色在设备和文档之间保持一致。从而在目标设备上提供最佳的色彩表现、或者在其他设备上模拟文档在目标设备上的色彩表现。 此类文件的扩展名通常为 .icc 或 .icm。

现在 ICC Profile 有两个版本 ICC v2 和 ICC v4。软件和硬件设备基本都支持 v2,但 v4 就不一定了。

测试浏览器是否支持 ICC 色彩管理

各类文件如何存储色彩空间

图片编辑器或者摄像设备会把 ICC Profile 嵌入到图片文件里。 也存在不嵌入 ICC Profile 的图片,那么显示时就可能产生色差。

PDF 文件会存储 ICC Profile。所以去打印店完全可以给 PDF 文件,只要作图时的色彩模式设置是 CMYK 就没问题。

查看文件的 ICC Profile

用系统自带的文件管理器查看文件属性。

也可以使用 unix/linux/macos 系统自带的 file 命令查看图片文件的元信息,包括色彩空间(jpg 文件不会显示)。

也可以使用 magick identify 命令来查看,需要安装 magick。

回归颜色本质

之前说过色彩可以用 明度(value) 、色调或者色相(hue)、 饱和度或者纯度(saturation) 三个属性定义。

真的对吗?

下面给出两幅图:

关于颜色的一点认识(二)38.png

关于颜色的一点认识(二)39.png

我分别找人问过上面哪个颜色更亮:第一幅图中绿色更亮,第二幅图中黄色更亮。

但是图中四个颜色的HSV(HSV、HSB,即H色调[0, 360]、S饱和度[0, 100]、V明度[0, 100])中明度都是100%?这明显有问题。

上面说过CIELAB*(黑到白[0, 100]、红到绿[-128, 127]、黄到蓝[-128, 127]) 旨在作为一个感知上统一的空间,其中给定的数字变化对应于相似的感知颜色变化。所以判断颜色的亮度应该以CIELAB*为准。

这里建议参考: 明度饱和度的搞笑一生HSV色彩空间的“里技”别以为色彩的知识你全懂了

参考文档

light and the eye
一个颜色的光如果亮度足够大,那么人眼看起来会不会变成白色?
CIE_1931_color_space
总结 漫谈HDR和色彩管理(二)颜色空间
颜色的计量系统
how-the-cie-1931-color-matching-functions-were-derived-from-wright-guild-data
Introduction to Light, Color and Color Space
Color Spaces
cie-xyz-color-space

学习历程

如果想系统性学习关于图形学的话,可以看下面这些系列:

十分钟色彩科学
A free educational site that progressively introduces you to the world of computer graphics.
CS 178 - Digital Photography (Spring 2014)