联系人: 销售经理
手机: 150 0072 7503(微信同号)
邮箱: klaus@jnewtech.com
地址: 上海市杨浦区波阳路16号波阳创业园23幢A座207
光谱转换为颜色XYZ原理和代码
本文介绍了一个 Python 脚本,用于将波长光谱映射到一种颜色的表示。没有独特的方法可以做到这一点,但这里使用的公式基于CIE 颜色匹配函数XYZ。这些模型通过将波长的功率谱 P 映射到一组三刺激值$X$、$Y$ 和 $Z$ 来模拟“标准观察者”的色度响应,类似于实际人眼中三种视锥细胞的反应。
这样,只需要 $x$ 和 $y$ 两个参数来描述光的颜色(更准确地说是色度)。CIE标准色度图如下所示。
将 $(x, y)$ 进一步转换为显示设备输出的 RGB 值需要通过适当的色度矩阵进行转换。在几何上,这将上述颜色“舌头”中的点映射到 RGB“色域”内的点子集,即指示的三角形区域。甲颜色系统可通过的三点基色的色度(三角形的顶点)和一个矩阵来定义的白点的一组限定用于某种目的的“颜色”白色chromaticiy坐标:
$(x,y,z)$ 值的向量乘以该矩阵的倒数,因此给出了描述所使用系统内相应颜色的RGB 值。
并非所有 $(x, y)$ 对都映射到 RGB 色域内的点(它们会为一个或多个组件提供负值):解决此问题的一种方法是通过相等地提高所有组件的值来“降低饱和度”,直到它们都是非负的。
下面的代码定义了一个类,ColourSystem用于表示和使用颜色系统,并实例化了一些特定的例子。CIE 匹配函数从文件cie-cmf.txt读入。
# colour_system.pyimport numpy as npdef xyz_from_xy(x, y):
"""Return the vector (x, y, 1-x-y)."""
return np.array((x, y, 1-x-y))class ColourSystem:
"""A class representing a colour system. A colour system defined by the CIE x, y and z=1-x-y coordinates of its three primary illuminants and its "white point". TODO: Implement gamma correction """
# The CIE colour matching function for 380 - 780 nm in 5 nm intervals
cmf = np.loadtxt('cie-cmf.txt', usecols=(1,2,3))
def __init__(self, red, green, blue, white):
"""Initialise the ColourSystem object. Pass vectors (ie NumPy arrays of shape (3,)) for each of the red, green, blue chromaticities and the white illuminant defining the colour system. """
# Chromaticities
self.red, self.green, self.blue = red, green, blue
self.white = white
# The chromaticity matrix (rgb -> xyz) and its inverse
self.M = np.vstack((self.red, self.green, self.blue)).T
self.MI = np.linalg.inv(self.M)
# White scaling array
self.wscale = self.MI.dot(self.white)
# xyz -> rgb transformation matrix
self.T = self.MI / self.wscale[:, np.newaxis]
def xyz_to_rgb(self, xyz, out_fmt=None):
"""Transform from xyz to rgb representation of colour. The output rgb components are normalized on their maximum value. If xyz is out the rgb gamut, it is desaturated until it comes into gamut. By default, fractional rgb components are returned; if out_fmt='html', the HTML hex string '#rrggbb' is returned. """
rgb = self.T.dot(xyz)
if np.any(rgb < 0):
# We're not in the RGB gamut: approximate by desaturating
w = - np.min(rgb)
rgb += w
if not np.all(rgb==0):
# Normalize the rgb vector
rgb /= np.max(rgb)
if out_fmt == 'html':
return self.rgb_to_hex(rgb)
return rgb
def rgb_to_hex(self, rgb):
"""Convert from fractional rgb values to HTML-style hex string."""
hex_rgb = (255 * rgb).astype(int)
return '#{:02x}{:02x}{:02x}'.format(*hex_rgb)
def spec_to_xyz(self, spec):
"""Convert a spectrum to an xyz point. The spectrum must be on the same grid of points as the colour-matching function, self.cmf: 380-780 nm in 5 nm steps. """
XYZ = np.sum(spec[:, np.newaxis] * self.cmf, axis=0)
den = np.sum(XYZ)
if den == 0.:
return XYZ
return XYZ / den
def spec_to_rgb(self, spec, out_fmt=None):
"""Convert a spectrum to an rgb value."""
xyz = self.spec_to_xyz(spec)
return self.xyz_to_rgb(xyz, out_fmt)illuminant_D65 = xyz_from_xy(0.3127, 0.3291)cs_hdtv = ColourSystem(red=xyz_from_xy(0.67, 0.33),
green=xyz_from_xy(0.21, 0.71),
blue=xyz_from_xy(0.15, 0.06),
white=illuminant_D65)cs_smpte = ColourSystem(red=xyz_from_xy(0.63, 0.34),
green=xyz_from_xy(0.31, 0.595),
blue=xyz_from_xy(0.155, 0.070),
white=illuminant_D65)cs_srgb = ColourSystem(red=xyz_from_xy(0.64, 0.33),
green=xyz_from_xy(0.30, 0.60),
blue=xyz_from_xy(0.15, 0.06),
white=illuminant_D65)
- 上一篇: 紫外可见分光光谱仪原理
- 下一篇: CIE A光源和D65光源
-
2022-10-01紫外可见分光光谱仪原理
-
2022-10-01光谱转换为颜色XYZ原理和代码
-
2022-10-01光谱质量评价指标 峰值信噪比
-
2022-10-01LED灯具LED显示屏发光稳定性测量
-
2022-10-01汽车LED大灯检测方法
-
2022-10-01CIE A光源和D65光源

客服