Python光学仿真:波长与颜色的对应关系及CIE色度系统实现
本文解析Python实现波长与颜色对应关系的原理,涵盖人眼对光的明度、色调和饱和度感知机制。重点介绍CIE RGB与XYZ色度系统的转换逻辑,并提供Python代码实现色品图绘制、光谱颜色生成及光谱图展示,帮助开发者理解光学仿真中的色彩映射算法。
光的颜色
颜色并非光本身的固有属性,而是人眼在可见光频率范围内产生的生理感应,属于视觉系统的特性。人眼对光的感知主要包含三个维度:明度、色调和饱和度。
具体而言,
- 明度取决于光的强度,
- 色调反映光的频率信息,
- 饱和度则表征图像颜色与标准光谱色的接近程度。
若忽略色调与饱和度(设为0),仅保留明度,则色彩感知消失,呈现黑白或更严谨意义上的灰度图像。
色调与饱和度虽间接反映光的频率,但本质上是人眼对光的反馈特性,与光的物理频率不同。这种对应关系由人眼感光细胞决定。由于自然界缺乏严格单色光,人类的色觉实际上是两种感光细胞信号混合的结果。
这意味着,不同基准频率的光按特定饱和度混合,人眼会感知到颜色变化或新颜色的产生。实验证实,任意三种无法相互转换的颜色,通过混合即可一一对应光谱色。这三种光被称为三原色,通常选取红、绿、蓝(RGB)。

由于三原色已归一化,已知其中两个值即可确定色品。以r为横坐标、g为纵坐标,可绘制出所有可能的色品分布图。此类图表常见于手机发布会,此处我们绘制类似的色品图。

def CIE_RGB():
rgb = np.zeros([1000,1000,3])
r = np.arange(0,1,0.001)
r,g = np.meshgrid(r,r)
rgb[:,:,0] = r
rgb[:,:,1] = g
rgb[:,:,2] = 1-r-g
over = rgb[:,:,2]<0
rgb[over,:]=[1,1,1]
#将色品转化成RGB
maxVal = np.max(rgb,2)
for i in [0,1,2]:
rgb[:,:,i] /= maxVal
#rgb[rgb<0]=0
ax = plt.gca()
ax.imshow(rgb)
ax.invert_yaxis() #plt显示图片时y轴从上到下,所以反置
# 坐标映射
plt.xticks(range(0,1001,200),['0','0.2','0.4','0.6','0.8','1'])
plt.yticks(range(0,1001,200),['0','0.2','0.4','0.6','0.8','1'])
plt.show()
然而实验发现,RGB系统的刺激值存在负数,意味着前述色品图并未涵盖所有颜色。因此,CIE推荐了XYZ色度学系统,它是对RGB系统的线性变换,确保刺激值均为正数。其转换公式为:

Python实现代码如下:
#dWave为波长;maxPix为最大值;gamma为调教参数
def getRGB(dWave,maxPix=1,gamma=1):
waveArea = [380,440,490,510,580,645,780]
minusWave = [0,440,440,510,510,645,780]
deltWave = [1,60,50,20,70,65,35]
for p in range(len(waveArea)):
if dWave<waveArea[p]:
break
pVar = abs(minusWave[p]-dWave)/deltWave[p]
rgbs = [[0,0,0],[pVar,0,1],[0,pVar,1],[0,1,pVar],
[pVar,1,0],[1,pVar,0],[1,0,0],[0,0,0]]
#在光谱边缘处颜色变暗
if (dWave>=380) & (dWave<420):
alpha = 0.3+0.7*(dWave-380)/(420-380)
elif (dWave>=420) & (dWave<701):
alpha = 1.0
elif (dWave>=701) & (dWave<780):
alpha = 0.3+0.7*(780-dWave)/(780-700)
else:
alpha = 0 #非可见区
return [maxPix*(c*alpha)**gamma for c in rgbs[p]]
绘制光谱颜色分布
def drawSpec():
pic = np.zeros([100,360,3])
rgb = [getRGB(d) for d in range(400,760)]
pic = pic+rgb
plt.imshow(pic)
plt.yticks([]) #隐藏y坐标轴
plt.xticks(range(0,360,50),['400','450','500','550','600','650','700','750'])
plt.show()

以上为Python光学仿真中波长与颜色对应关系的详细解析,更多相关技术内容请关注本站其他文章。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













