Python图像处理教程(Pillow)2计算机色彩空间

计算机色彩空间

2.1 可见光

可见光--我们的眼睛可以看到的光--是一种电磁辐射的形式。电磁辐射是指电磁场中的波,通过空间辐射,携带能量。

无线电波、微波、红外线、可见光、紫外线、X射线和伽马射线都是不同类型的电磁辐射。

尽管这些现象看起来非常不同,但事实上它们都是完全相同的东西--以光速穿越空间的电磁场的振荡。区别在于振荡频率。

例如,公共广播公司使用的模拟无线电波,其频率从中波AM的300kHz(每秒30万次振荡)到FM广播的300MHz(每秒3亿次振荡)。在模拟收音机上,你将调到特定的频率来收听特定的电台(例如95 FM意味着95 MHz)。

2.1.1 频率和波长

所有的电磁辐射,包括光,都以299 792 458米/秒的速度传播。这就是真空中的光速,通常称为c(如果光穿过空气、玻璃或水等材料,其速度会略微慢一些,但这一差别只是1%的微小部分)。

对于一个特定的频率f,电磁辐射有一个波长λ,由以下公式给出。

λ = c / f 其中c为光速
例如,一个100MHz的无线电信号的波长为3米。

可见光在光谱中占据一个很小的范围,介于红外线和紫外线之间,波长大约在400纳米和700纳米之间。

2.2 什么是颜色?

我们可以看到400纳米到700纳米范围内的电磁辐射。

2.2.1 非光谱色

我们看到的大部分光线并不只包含单一波长的光。这是因为大多数光源(如太阳光或许多形式的人造光)都含有许多不同波长的混合光。当这些光从一个表面上反弹时,该表面会以不同的程度吸收或反射不同的波长。

这意味着,进入我们眼睛的大部分光线都含有不同波长的混合物。但我们认为它是一种单一的颜色。

2.3 我们如何看待颜色

如果你想一想光谱中无限多的颜色,再想一想你可以把这些颜色的每一种组合以不同的数量混合在一起,在电脑屏幕上复制这些颜色似乎是一项不可能的任务。

幸运的是,我们感知颜色的方式比这要简单一些。

人眼包含三种类型的颜色检测细胞,称为锥体,它们测量不同的、广泛的光谱部分的光的强度。

  • L型锥体检测光谱中黄色/橙色/红色一端的光线。
  • M型锥体检测的是光谱中黄色/橙色/红色一端的光。
  • S型锥体检测光谱中蓝色/紫色一端的光。

每种类型的锥体都测量它能检测到的光谱部分的平均光量。这些探测波段是重叠的,通过测量每个波段的相对光量,我们的大脑可以重现我们看到的每种颜色。

这里的重要事实是,人类所感知到的颜色是一个三维量--三种锥体所检测到的光量。如果来自电脑显示器的光线以与真实物体的光线相同的方式刺激这些锥体,那么颜色就会显得非常相似。

这些锥体并不完全对应于红、绿和蓝,但如果我们混合不同数量的红、绿和蓝光,就可以模拟出我们看到的许多颜色。

眼睛还包含第二种类型的细胞,称为杆状细胞。杆状细胞能感知光线和黑暗,但它们看不到颜色。它们比锥体更敏感,所以它们提供了你在黑暗条件下的视觉能力(这就是为什么你在黑暗中看不到颜色)。眼睛中的棒状体比锥状体多,所以它们能比锥状体检测到更精细的细节。

2.4 RGB颜色模型

在计算机系统上表示颜色的最自然、最常见的方法是以我们看到的颜色为模型,也就是使用红、绿、蓝三种数值。红、绿、蓝的每个独特组合都会产生一种独特的颜色。我们把这称为RGB颜色模型。

我们说,红、绿、蓝是RGB模型的三个组成部分。另外,它们有时也被称为三个通道,意思是一样的。

2.4.1 显示颜色

在计算机屏幕上,每个像素有三个微小的元素。通常,这些是LCD单元,其透明度可由电信号控制。这些元件作为一个可变的红、绿、蓝光源。通过允许每个元件发出正确数量的光,我们可以将每个像素设置为任何颜色。

我们将每个像素的所需颜色作为一个数组存储在计算机的视频存储器中,每个像素由数组中的3个元素代表。视频硬件控制屏幕上每个像素的颜色。

2.4.2 将RGB颜色表示为百分比

有几种表示RGB颜色的方法,但它们都是一样的:颜色是由三个数字指定的,它们代表构成该颜色的红色、绿色和蓝色的数量。

第一种方法是对每个成分使用一个百分比。因此,对于红色值来说。

  • 0%表示该颜色没有红色成分。例如,如果该颜色是纯蓝色,那么它就没有红色成分。
  • 100%意味着该成分存在的最大可能数量。例如,最亮的纯红色包含最大可能的红色量。
  • 50%意味着该颜色含有最大数量的红色的一半。

我们可以用百分比来指定任何RGB颜色,像这样。

RGB(100%, 50%, 0%)

这表示一种颜色包含最大数量的红色,最大数量的50%的绿色,没有蓝色。这将得到一个橙色。

2.4.3 浮点表示法

表示RGB颜色的另一种方法是使用0.0到1.0范围内的数字。这与百分比的工作方式相同,但使用分数而不是百分比。

  • 0.0的值对应于0%。
  • 1.0的值对应于100%。
  • 0.5的值对应于50%,以此类推。

Python的矢量图形库Pycairo就用这种方式表示颜色。数值处理库NumPy有时也使用这种方法来存储图像。

2.4.4 字节值表示

最后一种方法是将每个颜色通道表示为0到255之间的整数值。

  • 0的值对应于0%。
  • 255的值对应于100%。
  • 128的值对应于(大约)50%,以此类推。

我们选择0到255这个范围是有原因的。它是可以存储在一个无符号字节中的范围。这意味着一种颜色正好可以存储在3个字节的内存中,因此可以用每个像素的3个字节来存储一幅图像。

事实证明,每种颜色的256级足以能够精确地代表大多数用途的颜色--例如,对于照片和视频来说,这已经足够好了。

2.5 颜色分辨率

人眼可以看到许多不同的颜色,但我们的感知是有限度的。当两种颜色非常相似时,它们看起来是相同的--即使它们并排在一起,我们也看不出区别。下面是一个例子。

我们通常使用每个像素的每种颜色1个字节(8比特)来存储RGB图像。一个字节可以存储0到255的整数值,也就是256个不同的值。这意味着每个颜色通道的精度可以超过0.5%。由于我们看不到两个相差1%的颜色之间有什么区别,所以这个精度对于大多数用途来说是完全足够的。

2.6 灰度颜色模型

任何具有等量的红、绿、蓝的RGB颜色,都会显示为灰色的阴影,例如。

  • RGB(0%, 0%, 0%)是黑色。
  • RGB(30%, 30%, 30%)是深灰色。
  • rgb(100%, 100%, 100%)是白色。

在灰度色彩空间中,颜色是由一个单一的值指定的。颜色的显示就像红、绿、蓝三色值都相等一样。你可以把灰度看作是RGB的一个子集,只包括纯灰色。

  • 灰色值为0是黑色。
  • 灰色值30%为深灰色。
  • 灰色值100%为白色。

灰度对于不包括任何颜色的图像来说是很有用的,例如。

  • 只有文本的文件。
  • 不使用颜色的图表和图示。
  • 黑白摄影图像的扫描。

2.7 CMYK颜色模型

当我们打印图像时,我们通常在白纸上涂抹不同颜色的油墨,以产生我们所需要的颜色。

打印出来的页面与电脑屏幕的工作原理是完全不同的。屏幕启动时默认为暗色,然后添加红、绿、蓝光来创造颜色。我们把这称为加法模型。

印刷品不会产生光线,它只是反射光线。一张白纸开始是白色的(假设是在白光下看的白纸),页面上的墨水吸收了不同数量的红、绿、蓝光,留下所需的颜色。我们把这称为减法模式。

许多印刷过程是通过添加几层不同颜色的半透明油墨来实现的。这里有一个插图。

由于油墨是半透明的,光线穿过油墨,在下面的白纸上反射。墨水就像一个颜色过滤器,可以去除某些颜色。

图片的左边部分显示了当我们把青色放在白纸上时会发生什么。起初,这可能与直觉相悖,但青色墨水的作用是吸收红光。更准确地说,它吸收红光,但允许绿光和蓝光通过,所以产生的颜色是青色(绿加蓝)。

品红墨水过滤掉绿光,让红光和蓝光通过(品红是红加蓝)。黄色墨水过滤掉蓝光,让红光和绿光通过(黄色是红色和绿色的混合物)。

如果我们把一层墨水放在另一层上面,光线就会通过这两层墨水并反射到页面上。比如说。

在这个案例中,品红墨水被分层放在青色墨水上。青色墨水去掉了红光,品色墨水去掉了绿光,所以我们最终在页面上呈现出蓝色。事实上,通过在页面上分层使用不同数量的青色、品色和黄色墨水,可以从反射光中去除不同数量的红色、绿色和蓝色,这使你可以打印任何颜色。

2.7.1 K成分

如果你拥有一台彩色喷墨打印机或类似的设备,你可能会知道它有4种颜色,青色、品色、黄色和黑色。CMYK的K部分代表Key,这是一个古老的印刷术语,指的是传统印刷机中的黑板。

从理论上讲,我们不应该需要单独的黑色墨水,因为将青色、品色和黄色墨水混合在一起应该能产生黑色。但在现实中,使用黑墨有几个好处。

  • 等量的青色、品色和黄色墨水并不能创造出完美的黑色。它们通常会产生一个非常深的棕色。
  • 要把这三种颜色放在页面上完全相同的位置是非常困难的。任何轻微的错位都会使黑色的形状略显模糊,这尤其会影响到黑色文本。
  • 黑墨水比彩色墨水便宜得多。
  • 使用的墨水总量较少,这可以帮助墨水更快地干燥,避免纸张拉伸,特别是在传统印刷机上。

几乎所有的彩色印刷过程--从家庭或办公室打印机,到报纸或杂志的印刷机--都使用单独的黑色通道,就是因为这些原因。在某些情况下,打印机也会在较深的彩色区域添加黑色墨水,以减少所需的彩色墨水量。

2.8 HSL/HSB色彩模型

HSL颜色空间将颜色存储为3个值。

  • 色相(H)表示基本颜色,基本上是颜色在色轮上的位置,从红色到绿色到蓝色,然后再回到红色。
  • 饱和度(S)控制颜色的饱和程度。100%的值表示纯色,50%表示相同的颜色但混有灰色,0%的值表示纯灰色。
  • 明度(L)控制颜色的明暗程度。50%的亮度表示基本颜色处于中等的亮度水平。如果L分量向100%增加,颜色就会越来越淡,直到最后变成白色。如果L分量向0%减少,颜色就会越来越暗,直到最终变成黑色。

这张图显示了色相值的色轮。色相可以表示为0到360度之间的角度,其中0是红色,120是绿色,240是蓝色。


下面是在0%和100%之间改变饱和度的效果(色相为绿色,明度为50%)。请注意,基本颜色保持不变。


最后,这是改变亮度在0%和100%之间的效果(色调为绿色,饱和度为50%)。同样,基本颜色保持不变。

HSL颜色在艺术和设计应用中非常有用,因为它可以非常容易地创建相关的颜色集。

2.9 HSL的变体

HSB(色调、饱和度、亮度)色彩空间使用与HSL相同的色调定义。饱和度和亮度的表现不同,但可以实现与HSL相同的颜色范围。

HSL模型与加法模型(如RGB所使用的)配合得很好。HSB是基于减法色彩模型的,但CMYK对减法色彩更有用。HSB往往不像HSL那样经常被使用,所以我们不会详细介绍它。

你可能还会看到HSV(色调、饱和度、数值)这个术语。这是HSB的一个替代名称。

2.10 感知性色彩模型

RGB是对眼睛如何感知颜色的一种粗略尝试,尽管它对许多日常使用非常有用。你可以在普通的电脑屏幕上看电影或看你的度假照片,而不一定觉得颜色有什么严重的问题。

但是对于要求更高的应用来说,RGB是不够好的。例如,假设你从事的是美术印刷品的业务。你需要扫描一幅原画,然后制作颜色完全相同的印刷品。因此,如果你把印刷品放在原作旁边,你希望它们看起来是一样的。

如果你使用一个普通的桌面扫描仪和一个普通的桌面打印机来做这件事,结果可能看起来非常漂亮,但它不会看起来像原作。如果你把它们并排放在一起,颜色会不一样。作为一张廉价的海报是可以的,但作为一张昂贵的印刷品就不行了,因为它要显示特纳海景的确切颜色。

基本的问题是,红色、绿色和蓝色没有被很好地定义。如果你在显示器上显示一个100%的纯红色圆圈,它肯定会看起来是红色的,但没有办法准确地知道它是什么红色。事实上,你可以通过调整你的显示器设置来改变颜色的外观。

同样,如果你打印这个红圈,确切的结果可能会有很大的不同--它将取决于打印机的类型、墨水的类型以及纸张的类型。它将取决于墨盒是满的还是快空的。同一类型的两台不同的打印机会略有不同,而同一台打印机在不同的日子也会略有不同。你怎么能希望与原始场景或绘画的颜色相匹配?

我们需要做的第一件事是建立一个标准的、确定的色彩空间,这样我们就可以准确地定义 "红色 "的含义。事实上,我们通常不使用RGB来做这个,因为RGB不是一个线性空间。例如,如果你看3个色块,红、绿、蓝各100%,绿色色块看起来会更亮。同样 "数量 "的绿色看起来更亮,因为我们的眼睛对绿色更敏感。

作为标准化色彩的第一步,我们通常采用一种感知色彩模型,分配给眼睛的色彩值看起来更加线性。

2.10.1 CIE空间

我们通常使用CIE色彩空间。这些都是基于国际照明委员会(CIE)的工作,该委员会在20世纪30年代做了许多实验来建立人类视觉的标准模型。

一个常用的标准空间是CIELAB。这个空间有三个组成部分。

  • L代表颜色的亮度(大致相当于HSL的L成分)。
  • A代表颜色在从红到绿的范围内的位置。
  • B代表颜色在从蓝色到黄色的刻度上的位置。

这不像RGB值那样容易想象,但它是代表我们所感知的更好的方式。如果我们用CIELAB来表达一种颜色,我们就有了对这种颜色的精确定义。

CIELAB并不是唯一的标准。CIEXYZ是另一个常用的感知色彩空间,其工作原理与此类似。

2.11 颜色管理

用标准的方式来表示颜色是解决了一半问题。我们仍然有一个问题,即我们的输入设备(照相机、扫描仪等)、计算机显示器和打印机都使用RGB,而每个设备对RGB的含义都有自己的想法。

色彩管理通过为每个设备使用配置文件来解决这个问题,它允许我们在设备的RGB值和标准CIELAB之间进行转换。

配置文件是通过测量设备来确定的。例如,为了给扫描仪建立档案,我们可能会扫描一个失去了不同颜色的页面,每个颜色都有一个已知的CIELAB颜色。我们可以查看扫描仪为每种不同的CIELAB颜色产生的RGB值,并得出RGB和CIELAB之间的转换。我们可以对显示器和打印机做同样的工作,通过打印不同的RGB颜色,用色度计测量结果。

大多数用户不会自己进行这些测量,他们只是安装由制造商提供的配置文件,根据扫描仪、打印机或显示器型号的典型特征转换颜色。

因此,原则上,我们可以扫描一幅图像,并将其从扫描仪的RGB转换为CIELAB。为了显示它,我们把CIELAB转换成显示器的RGB,为了打印它,我们把CIELAB转换成打印机的RGB。

在现实中,图像通常以RGB格式存储,但在图像上附有扫描仪的配置文件。当我们显示图像时,我们应用一个组合转换,从扫描仪RGB到CIELAB,然后再回到显示器RGB。这实现了同样的结果,但它的优点是存储在系统中的图像是RGB格式的。如果你想在没有色彩管理的情况下使用扫描的图像(例如,如果你想把图像放在网站上),你可以忽略附加的配置文件,把图像作为普通的RGB图像使用。

2.11.1 色域

在色彩管理中还有一个需要考虑的话题--色域。

如果你拍摄一张真实场景的照片,相机可能无法准确捕捉到所有的颜色。有些颜色可能太亮而无法正确记录。有些颜色可能过于鲜艳或强烈。我们把相机能够捕捉到的颜色集合称为色域。

如果我们在显示器上观看该图像,我们会发现色彩受到了更大的限制。监视器产生的白色不是很亮(你也不希望它很亮),黑色相当于监视器关闭时的颜色,不是很暗。不同颜色的强度也是有限的。一般来说,电脑屏幕的色域比输入设备的色域要小。

大多数打印机的色域甚至比屏幕还要小。将一张白纸(打印机能产生的最亮的颜色)与电脑显示器上的白色区域进行比较。纸张的亮度远不如屏幕。

这是没办法的事,你的屏幕或打印机上的图像永远不会有真实世界场景的对比度和鲜艳度。但是,在如何处理这一限制方面,是有选择的。你可以选择一种渲染意图。

  • 感知--这将调整颜色,使图像看起来很自然。它试图实现整体的自然外观,即使这意味着颜色并不完全准确。它适用于照片。
  • 相对色度--它试图保留图像中的正确颜色。这意味着在色域内的颜色将被正确显示,但在色域外的颜色将被转换为最接近的可用颜色。这使得图像尽可能的准确,但超出色域的区域可能会出现块状。在这种模式下,所有的颜色都会根据白点(基本上是显示器/打印机上最亮的白色)来进行缩放。
  • 饱和度 - 试图保留饱和的颜色,即使这意味着非饱和的颜色不太准确。这对于像商业文件这样的事情很有用,在这些文件中,黑色的文字和图形及图表中的亮色需要显示为完全饱和。
  • 绝对色度 - 与相对色度相似,但它不对白点进行调整。它试图使每个色域内的颜色在绝对条件下尽可能准确,但这可能会导致很多色域外的颜色看起来不正确和块状。

参考资料

  • 本文涉及的python测试开发库 谢谢点赞!
  • 本文相关海量书籍下载

你可能感兴趣的:(Python图像处理教程(Pillow)2计算机色彩空间)