黄鼠博客

理解颜色

2017-10-12

疑问

所有色光都可以由 绿 三原色合成吗?
为什么颜料的三原色是 而 色光三原色是 绿 呢?
计算机如何表示颜色,又如何存储呢?
本文将自底向上,为你解答颜色和光的秘密

光和颜色

在没有指定特定上下文的情况下,就等于可见光

我们能看到东西,本质上是我们看到了光。人眼就好像一根天线,接收感知电磁波,光就是电磁波中能被人眼感知到的部分。电磁波的波长范围从\(-\infty\) 到 $+$,而人类能感知到的大约是其中 \(400nm \sim 700nm\)的部分(具体感知范围存在个体差异),这部分电磁波谱叫做可见光谱
可见光谱在电磁波谱中的位置 上图彩色部分就是可见光谱。太阳光谱的范围是超过可见光谱的,所以你用三棱镜分解太阳光,就可以看到可见光谱所有色光(除非你买到了劣质的三棱镜🙃)

作为人类,我们先进的视觉系统不仅能感知到可见光谱的电磁波,还能区分可见光谱中不同波长的电磁波,于是我们就有了颜色的概念。我们能区分光的颜色,就像调频收音机,不仅能收到信号,还能区分不同频道。

然而,人类比收音机更强大的是,我们还能“收听”混合频道,并能获取信息。 可见光谱是你能看到的电磁波范围,但却不能涵盖你能感知到的全部颜色。别以为五光十色的彩虹就是你能看到的全部颜色,作为人类你不仅能感知可见光谱中这些单色光,还能感受它们的组合。举个例子,你能看见的白色就不在可见光谱中,当然,除了白色,还有大量的颜色不在可见光谱中

P.S.继续讲下去之前,我们先看个问题:

听说色光都可以用 红、绿、蓝 三原色合成?

单色光就是某个固定频率的电磁波。红、绿、蓝三种色光分别有自己的频率,可是两个频率不相同的波叠加是不能得到另外一个频率的波的。
\[X_1(t)=sin(2t)\] \[X_2(t)=sin(3t)\] \[X_3(t)=sin(2t) + sin(3t)\]

正如上图所示,两个频率不相同的波叠加是不能得到另外一个频率的波,那三原色的概念又从何谈起呢?难道三原色不能合成单色光?那为什么我们的显示器都只用三原色来显示呢?

欲知答案,我们先了解一下人的色彩视觉系统。

人的色彩视觉系统

人眼视网膜有总体有两种感光细胞,视杆细胞(cone)视锥细胞(rod)。光线昏暗时,视杆细胞起作用,无法分辨色彩。而光线充足时视锥细胞起作用,可以分辨色彩。

视锥细胞之所以能分辨色侧,原因是视锥细胞有三种类型:S,M,L 分别对短(蓝)、中(绿)、长(红)波敏感(上图横横坐标表示光波长(nm),纵坐标表示归一化敏感程度。图片来自wikipeida)

由此可以推断:不管我们看到了什么光,复色光也好,单色光也罢,最终大脑接收到的都是三种细胞的信号强度 (R,G,B) 既然如此,我们就可以仅用三种色光,合成(叠加)后表示其它色光。

所以物理上讲色光不能合成,一个频率的波加另一个频率的波不等于一个新的频率的波。但是人类感知的色光可以合成。人眼其实很容易欺骗,它不能准确感知光的频率,而是把所有看到的色光转化为(R,G,B)三个分量传递给大脑。

得益于人类这种视觉方式,我们可以简单地用三原色合成的方法制造彩色显示器。否则,倘若制造一种连续可变波长的发光机构,不知道多复杂。

然而事情并没有这么简单,我们就可以仅用三种色光,合成(叠加)后表示其它色光,但却无法表示其它所有色光。如前文所述,大脑接收到的是(R,G,B)三个信号,如果我们能准确地发送给大脑这个三元组就可以让大脑感知所有色光,但要做到这点,用光做不到,怕是只能用电极刺激大脑了(emmm)。为什么说用光所不到呢,且看上图,任何一个波长的光,都不只是单纯地引起一种细胞的反应,会同时对其它细胞产生反应。这样,你输入的是(200,0,0)的一个光,大脑接收到的却可能是(200,10,16)这样一种信号。所以,色光合成的规则是比较复杂的。

那么色光合成究竟满足怎样的规律呢,这个需要实验测定。(具体的实验细节和更深层次的问题笔者正在研究和思考,所以下面的内容可能有描述不准确的地方)
1931年,建立在William David Wright和John Guild的大量实验基础上,世界上第一个量化物理色光和人类感知色光的标准 CIE 1931 提出

标准中,有个非常有意思的图,它表示颜色之间的关系(上图)。图中马蹄形彩色区域为人类能看见的所有颜色,马蹄形上边缘的黑线表示单色光,对应的波长用蓝色字体标注。马蹄形内部颜色均为合成色光。马蹄形中(包括边缘)任意两点连线上的颜色,均可被这两端点颜色线性表示。所以,选择两个颜色就可以表示一条直线上的颜色;选择三个颜色,就可以表示它们构成的三角形内的颜色

这三个颜色点选择不同,就得到了不同的色域, 比如大家熟悉的sRGB, Adobe RGB等等色域。

p.s.有一个非常有意思的现象:马蹄形边缘右半段接近直线,这说明,这中间的单色光的颜色可由其它单色光合成。当然,这是指感官上的合成,不是物理上的合成。你可能看到过很多颜色相同的物体,但它们却可能发出的是不一样的光~

p.s.目前笔者还没看懂如何量化人类感知颜色这个存在巨大个体差异的问题的,如果你有什么见解,欢迎评论区留言

计算机表示颜色

上面讲到了色域,这些研究主要是要解决如何把一个颜色表示准确的问题。但从计算机抽象数据结构(ADT)的角度去看这个问题就很简单了,对于一个色光,我们只需要给定(r,g,b)三个分量即可。ADT不关心这个(r,g,b)坐标的究竟是上面讨论的哪三个颜色点,也就是ADT不关心红色有多红,绿色用多绿的问题
我们只关心R,G,B 三个分量就像坐标轴x,y,z一样张成了一个立方体。

关于打印颜色的表示

我们使用RGB模型的时候谈论的都是色光的叠加,我们很容易用显示器显示(r,g,b)这样的数据,因为屏幕一开始是黑色的,只需要控制发光的强度,我们是在黑色的基础上做加法。但是,我们在打印的时候使用的却是颜料,我们的纸张开始是白色的,而颜料是吸光的,多一点颜料就多吸收一点光,所以我们是在白色的基础上做减法。这时我们就需要一种减色模型,那很简单,取绿的补色:品红。 注意,通常说的颜料三原色 中的红不是RGB中的红,而是品红;蓝不是RGB中的蓝,而是青。说到这里大家应该明白了问什么色光三原色和颜料三原色不同的原因了。
(关于减色模型的数学原理,本文不再探讨)

更多颜色的表示

如果你有一定的计算机基础,你一定知道还有用色度,亮度,饱和度来表示颜色的方法。这种表示方法是为了适应人类的直观感受。人脑十分复杂,眼睛给它的信号是(r,g,b)三元组,但是我们意识里面却对这个三元组并不敏感,我们直观感受到的是色度,亮度,饱和度。这些颜色模型是为了适应人类的直观感受而提出的,至于它们提出的科学原理我们以后有机会再讲。

使用支付宝打赏
使用微信打赏

支持原创,用我们自己的力量