【高光谱】如何科学地利用高光谱图像合成对应的RGB图像?
如何科学地利用高光谱图像合成对应的RGB图像?
1. 前言
参考链接:
23. 颜色知识1-人类的视觉系统与颜色 - 知乎 (zhihu.com)
CIE XYZ - freshair_cn - 博客园 (cnblogs.com)
CIE 1931 color space - Wikipedia
CIE 1931色彩空间 - 维基百科,自由的百科全书 (wikipedia.org)
RGB/XYZ Matrices (brucelindbloom.com)
调色名词浅析——Gamma(伽玛)校正 - 知乎 (zhihu.com)
前置条件:
- 必须有高光谱图像
- 必须有波段信息,(你需要知道高光谱图像每个通道对应的波长是多少)
对于波段信息,我的波段信息是从软件ENVI中获取的txt文件
本文以128波段的高光谱图像为例,txt文件详细内容在文末给出
先上流程图,随后再逐一解释:
2. 计算色匹配函数
色匹配函数其实就是如下三条曲线(使用python手动绘制):
CIE-XYZ色匹配函数曲线如下:
2.1 什么是色匹配函数
追根溯源的话,得从我们人类的视网膜说起。大部分人类的视网膜上有三种感知颜色的感光细胞,叫做视锥细胞,分别对不同波长的光线敏感,称为 L/M/S 型细胞。三种视锥细胞最敏感的波长分别是橙红色(长波,Long),绿色(中波,Medium),蓝色(短波,Short)。这三种视锥细胞的归一化感光曲线如下图所示
不仅如此,人类眼睛对不同颜色光线混合的反应还是 线性 的。根据 格拉斯曼定律(Grassmann’s Law)),两束不同颜色的光$C_1$和 $C_2$,假设某个视锥细胞对他们的反应分别是 $r_1$ 和 $r_2$,现在将他们按照一个比例混合,得到第三种颜色 $C_3=\alpha C_1 + \beta C_2$,那么视锥细胞对这个混合颜色的反应也将是前两个反应的线性叠加 $r_3=\alpha r_1 + \beta r_2$。
格拉斯曼定律是一个实验规律,并没有物理或者生物学上的依据。然而这个规律大大简化了我们对人类彩色视觉系统的建模,并且给我们使用线性代数理论分析人类彩色视觉系统提供了一个前提和基础。
前面已经提到,人类视网膜上有三种感知色彩的视锥细胞,所以理论上我们用三种颜色的光就可以混合出自然界中任何一种颜色来。在 20 世纪 20 年代,David Wright 和 John Guild 各自独立地领导了一些实验,通过三种颜色的光源进行匹配,得到了人眼对于不同颜色光的匹配函数。此后,多名科学家多次进行了类似的实验,加深了我们对人类彩色视觉的认识。
实验过程大致是这样的,把一个屏幕用不透光的挡板分割成两个区域,左边照射某个被测试的颜色的光线,这里记为$C$(以下用大写字母表明颜色,用小写字母表明分量大小),右边同时用三种颜色的光同时照射,这里记为$R$,$G$,$B$。然后,调节右边三种颜色光源的强度,直到左右两边的颜色看上去一样为止。假设这个时候三种颜色的光源强度分别为$r$,$g$,$b$,那么根据光色叠加的线性性质,我们可以写出
也就是说,只要按照 (r,g,b) 的分量来混合 (R,G,B) 三种颜色的光,就可以得到 C 这个颜色的光。于是在这一系列实验里,科学家们把左边的颜色按着光谱顺序,挨个测试了一遍,得到了纯光谱色的混合叠加的数据,这就是 色匹配函数(Color Matching Function) ,并且在这个基准下定义的色彩空间,就是 CIE RGB 色彩空间。下图是 CIE RGB 的色匹配函数曲线,(图片数据来自CVRL main (ucl.ac.uk))。浅色的细线代表实验中不同参与者个人的色匹配函数曲线,中间深色的粗线代表数据的平均值。
可以看到,曲线上出现了负数,这是怎么回事?回想一下前面描述的实验过程,左边是被测试的光色,右边是可调节的三色光的混合。如果碰到一种情况,右边三色光无论如何调节比例,都不能混合出左边的颜色,比如某种颜色的光强度已经减小为 0 了,然而看趋势还需要继续减小才能与左边的光色相匹配,怎么办?这时候需要往左边的光色中混入三色光中的一种或者几种,继续调节,直到两边的颜色匹配。在左边(被测试)的色光中添加,那就是相当于在右边的混合光中减去,这就导致了色匹配函数曲线上出现了负数。实际上,这相当于就是光线的「减法」了。
比如,对于 555nm 的黄色光,色匹配函数的值是 (1.30, 0.97, -0.01),意味着将 1.30 份的红光与 0.97 份的绿光混合放在右边,左边放上 1 份的 555nm 的黄光,以及 0.01 份的蓝光,这样左右两边的光色看上去就一样了。
因为有部分出现了负数,在使用和计算上都有不方便,因此就对这个匹配函数进行了一下线性变换,变换到一个所有分量都是正的空间中。变换后的色彩空间就是 CIE XYZ 色彩空间。 (图片数据来自CVRL main (ucl.ac.uk))
CIE RGB 色彩空间和 CIE XYZ 色彩空间是完全等价的,两者只是差了一个线性变换。由于允许「减法」的存在,因此 CIE RGB 空间是能够表示所有颜色的;同样的,CIE XYZ 空间也能。
在计算机问世之前,计算带有负值乘法的曲线是很麻烦的;XYZ就是为了把RGB空间转换成另一个没有负值的、方便计算的空间。很明显,XYZ的三色刺激值是想象出来的。
XYZ不用于描述颜色,而用于说明光波如何组合会产生什么样的颜色,因此XYZ是独立于设备的。
对于某些计算任务来说,查表可能变得不切实际。CIE XYZ颜色匹配函数可以通过高斯函数的和来近似。
设$g(x)$表示分段高斯函数,定义如下:
也就是说,$g(x)$类似于钟形曲线,其峰值在$x=μ$处,$σ1$的扩散/标准偏差在平均值的左侧,$σ2$的扩散在平均值右侧。使用以纳米为单位测量的波长$λ$,我们可以近似1931色匹配函数:
以上数据来自维基百科:CIE 1931 color space - Wikipedia
3. 根据光谱数据计算XYZ空间值
给定这些缩放了颜色匹配函数,带有频谱功率分布$I(\lambda)$的一个颜色的RGB 三色刺激值给出为:
实际上计算时多采用XYZ色彩空间,故对频谱分布函数积分时一般使用如下公式:
其中$\lambda$代表波长,$I(\lambda)$对应了该波段下的能量强度值(其实就是灰度值) 。
$\overline{x}(\lambda),\overline{y}(\lambda),\overline{z}(\lambda)$ 分别代表了刚才说的色匹配函数。
4. 将XYZ色彩空间变换到RGB色彩空间
由于 CIE RGB 和 CIE XYZ 两者其实是同一个线性空间的不同表达,因此两者的转换可以通过转换矩阵实现。
由于 CIE XYZ 空间是一个很方便的线性空间,与具体设备无关,因此常用来做各种颜色空间转换的中间媒介。设想某个颜色的光,经过色匹配函数的计算,得到了三个 XYZ 的值,如果直接将这三个值作为 RGB 颜色显示到屏幕上,显然是不对的。我们必须把 XYZ 的值转换到屏幕的 RGB 空间中的值。
由于不同的显示效果的需求,存在不同RGB色彩空间。不同的RGB色彩空间色域存在差异。
不同RGB色彩空间的转换矩阵在如下链接中可以找到:
RGB/XYZ Matrices (brucelindbloom.com)
因为白色参考点相关的内容确实还没有搞懂,但是对于本文要实现的目标不影响,所以挑选不同的转换矩阵尝试就好了,本文使用D50白色参考点,sRGB色域:
5. 伽马校正
在转换完之后,我们只是得到了一个线性的 RGB 值,要被显示器正确显示的话,还需要进行 gamma 校正。每个 RGB 空间对应的 gamma 校正公式不完全一致,大多数情况下都是 $C=C_{lin}^{1/\gamma}$,其中 $γ=2.2$,少数情况,比如 Apple RGB 采用的是 $γ=1.8 $的情况,再比如上面选择的 sRGB 空间,采用了一种分段的非线性函数进行校正:
在粗略的场景下,也可以直接使用 γ=2.2 的公式代替。
6. 代码实现
1 | # coding=utf-8 |
7. 附录
波段信息txt文件,一共128个波段:
1 | ENVI ASCII Plot File [*** *** 24 11:45:14 1919] |