You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用colour-science包将多波长反射率数据转换为单个RGB值

如何使用colour-science包将多波长反射率数据转换为单个RGB值

嘿,我来帮你搞定这个问题!用colour-science处理光谱反射率转RGB的需求其实挺直接的,我给你一步步拆解,连代码示例都给你准备好了:

首先得明确核心逻辑:要从波长-反射率对得到RGB,我们需要先把光谱数据转换成CIE XYZ三刺激值(这是连接光谱和颜色感知的标准中间量),再把XYZ转成常用的sRGB格式。

步骤1:准备数据并创建光谱分布对象

colour-science里的SpectralDistribution类是处理光谱数据的核心对象,它需要把波长(单位:nm)和对应的反射率值配对起来。比如你的示例数据是190-200nm的反射率,直接把这两组数据传进去就行。

步骤2:计算CIE XYZ三刺激值

我们需要用标准光源(比如日常最常用的D65日光)和标准观察者(CIE 1931 2度观察者,这是默认的人眼颜色感知模型),把光谱数据转换成XYZ值。

步骤3:将XYZ转换为sRGB

最后把XYZ值转成sRGB,这里要注意处理可能超出sRGB色域的数值(有些光谱颜色是显示器无法显示的)。

完整代码示例

import colour
import numpy as np

# 替换成你自己的真实数据
wavelengths = np.arange(190, 201)  # 你的示例波长范围:190到200nm
rf_values = np.full(len(wavelengths), 0.3907051)  # 对应的反射率值

# 1. 创建光谱分布对象
spectral_data = colour.SpectralDistribution(rf_values, wavelengths)

# 2. 选择标准光源(D65是模拟日光的常用选项)
standard_illuminant = colour.ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D65']

# 3. 从光谱数据计算XYZ三刺激值
xyz_values = colour.spectral_to_XYZ(spectral_data, illuminant=standard_illuminant)

# 4. 将XYZ转换为sRGB,同时处理色域溢出
# 先得到线性sRGB,再应用伽马校正得到最终的sRGB值
linear_rgb = colour.XYZ_to_sRGB(xyz_values, apply_cctf_encoding=False)
# 把超出0-1范围的值裁剪掉,避免显示异常
clamped_linear_rgb = np.clip(linear_rgb, 0, 1)
final_rgb = colour.cctf_encoding(clamped_linear_rgb)

# 如果需要0-255范围的8位RGB值,直接转换即可
rgb_8bit = (final_rgb * 255).astype(np.uint8)

print("0-1范围的sRGB值:", final_rgb)
print("0-255范围的8位RGB值:", rgb_8bit)

几个重要的注意点

  • 关于波长范围:你的示例数据是190-200nm,这属于紫外光范围,人眼完全看不到,所以计算出来的RGB大概率是接近黑色的灰色。如果要得到有意义的颜色结果,你的数据集必须包含380-780nm的可见光谱范围的反射率数据哦。
  • 反射率数据要求:确保你的Rf值是线性的(没有经过伽马校正或者其他编码处理),colour-science的所有光谱计算都要求输入线性反射率。
  • 色域映射:如果你的光谱颜色超出了sRGB显示器的显示范围,上面代码里用np.clip是最简单的处理方式;如果你想要更自然的色域映射效果,可以试试colour-science里的colour.gamut_mapping函数,它能把超出色域的颜色智能压缩到可显示范围内。

备注:内容来源于stack exchange,提问作者Dheya El Hak Chiha

火山引擎 最新活动