别再死记硬背了!用Python+Matplotlib亲手画一遍CIE 1931色度图,理解色彩空间的底层逻辑

别再只调RGB了!用Python+Matplotlib亲手画一遍CIE1931色度图,理解色彩空间的本质 本文通过Python和Matplotlib详细演示了如何绘制CIE1931色度图,帮助读者深入理解色彩空间的科学原理。从基础概念到代码实现,涵盖了光谱轨迹、黑体轨迹的绘制方法,以及色域映射等高级应用,为设计师和开发者提供了实用的色彩科学实践指南。 阅读详情

用Python绘制CIE 1931色度图:从三刺激值到可视化理解的完整实践

当设计师在Pantone色卡前犹豫不决时,当摄影师在Lightroom中调整白平衡时,背后起作用的正是那个神秘的马蹄形图表——CIE 1931色度图。这个看似简单的二维平面,实则是人类视觉感知的数学映射,它定义了"物理光信号"如何转化为"心理颜色感知"的桥梁。本文将带您用Python代码亲手构建这个色彩科学的基石,在数据计算与图形绘制中理解色彩空间的本质。

1. 色彩科学基础与实验数据准备

CIE 1931系统的核心在于将无限可能的可见光谱压缩为三个数值——X、Y、Z三刺激值。这源于1920年代Wright和Guild的突破性发现:人类视网膜上的三种视锥细胞对光的响应曲线,可以通过特定比例的红、绿、蓝光刺激来模拟。

获取标准观察者数据 是第一步。国际照明委员会(CIE)提供的标准数据包含两个关键部分:

import numpy as np
# CIE 1931 2°标准观察者数据 (波长间隔5nm)
wavelengths = np.arange(380, 781, 5)  # 380-780nm可见光谱
cmf_1931 = np.array([
    [0.0014, 0.0000, 0.0065],  # 380nm
    [0.0022, 0.0001, 0.0105],  # 385nm
    ...  # 完整数据应包含81组值
    [0.0003, 0.0000, 0.0001]   # 780nm
])

注意:实际应用中建议使用CIE发布的完整数据文件,上述仅为示例格式。X、Y、Z分量分别对应人眼对长波、中波、短波的敏感度曲线。

理解这些数据的物理意义至关重要:

  • X分量 :模拟L型视锥细胞对红光的响应
  • Y分量 :同时代表M型视锥细胞响应和亮度感知
  • Z分量 :对应S型视锥细胞的蓝光敏感度

2. 从光谱到色度坐标的计算路径

色度坐标的计算本质上是将三维XYZ空间投影到二维平面。这个降维过程通过归一化实现:

def xyz_to_xy(X, Y, Z):
    """将XYZ三刺激值转换为xy色度坐标"""
    sum_xyz = X + Y + Z
    return X/sum_xyz, Y/sum_xyz

# 示例:计算D65标准光源的色度坐标
D65_XYZ = [95.047, 100.00, 108.883]  # 标准D65光源
x_D65, y_D65 = xyz_to_xy(*D65_XYZ)
print(f"D65色度坐标: x={x_D65:.4f}, y={y_D65:.4f}")

这个转换带来两个重要特性:

  1. 亮度分离 :Y值单独表示亮度信息
  2. 色度纯化 :xy坐标仅反映颜色的"色调"和"饱和度"

光谱轨迹计算 是绘制色度图的关键步骤。我们需要对可见光谱的每个波长点进行计算:

spectral_xy = []
for i in range(len(wavelengths)):
    X, Y, Z = cmf_1931[i]
    x, y = xyz_to_xy(X, Y, Z)
    spectral_xy.append((x, y))

3. 构建色度图的几何要素

完整的CIE 1931色度图由三个核心几何要素构成:

  1. 光谱轨迹 :单色光在xy平面的投影形成的马蹄形曲线
  2. 紫红线 :连接380nm和780nm的直线,代表非光谱色
  3. 白点 :参考光源(如D65)的位置

Matplotlib绘制实现 :

import matplotlib.pyplot as plt
from matplotlib.patches import Polygon

fig, ax = plt.subplots(figsize=(10, 8))

# 绘制光谱轨迹
spectral_x, spectral_y = zip(*spectral_xy)
ax.plot(spectral_x, spectral_y, color='black', linewidth=2)

# 绘制紫红线
ax.plot([spectral_x[0], spectral_x[-1]], 
        [spectral_y[0], spectral_y[-1]], 
        color='purple', linestyle='--')

# 标记白点
ax.scatter(x_D65, y_D65, color='white', edgecolor='black', s=100, label='D65')

# 填充色域
spectrum_polygon = Polygon(list(zip(spectral_x, spectral_y)) + 
                          [(spectral_x[-1], spectral_y[-1]), 
                           (spectral_x[0], spectral_y[0])], 
                          closed=True, alpha=0.3)
ax.add_patch(spectrum_polygon)

4. 色度图的高级可视化技巧

基础图形绘制完成后,我们可以通过以下增强手段提升信息传达效果:

色彩填充技术 :

from matplotlib.colors import LinearSegmentedColormap

# 创建色度图专用的非均匀色彩映射
cie_cmap = LinearSegmentedColormap.from_list('cie_map', 
    [(0, (1,0,0)), (0.3, (1,1,0)), (0.6, (0,1,0)), 
     (0.8, (0,1,1)), (1, (0,0,1))])

# 在色域多边形内创建网格点进行颜色插值
xx, yy = np.meshgrid(np.linspace(0, 0.8, 200), 
                     np.linspace(0, 0.9, 200))
inside = []
for x, y in zip(xx.flatten(), yy.flatten()):
    if spectrum_polygon.contains_point((x, y)):
        inside.append((x, y))

等色调线与等饱和度线 :

# 计算从白点到光谱轨迹的等色调线
for hue_angle in np.linspace(0, 360, 12):
    rad = np.deg2rad(hue_angle)
    end_x = x_D65 + 0.5 * np.cos(rad)
    end_y = y_D65 + 0.5 * np.sin(rad)
    ax.plot([x_D65, end_x], [y_D65, end_y], 
            color='gray', alpha=0.3, linestyle=':')

关键标注元素 :

# 标记主要波长点
key_wavelengths = [450, 500, 550, 580, 600, 650]
for wl in key_wavelengths:
    idx = np.where(wavelengths == wl)[0][0]
    ax.annotate(f'{wl}nm', (spectral_x[idx], spectral_y[idx]),
                textcoords="offset points", xytext=(5,5), 
                ha='left', fontsize=10)

5. 色度图的实际应用解析

理解色度图的最终目的是应用。以下是三个典型场景:

1. 色域比较 :

# 定义sRGB和Adobe RGB色域边界
srgb_vertices = [(0.64,0.33), (0.30,0.60), (0.15,0.06)]
adobe_rgb_vertices = [(0.64,0.33), (0.21,0.71), (0.15,0.06)]

# 绘制色域对比
ax.add_patch(Polygon(srgb_vertices, closed=True, 
                    fill=False, edgecolor='blue', linewidth=2))
ax.add_patch(Polygon(adobe_rgb_vertices, closed=True, 
                    fill=False, edgecolor='green', linewidth=2))

2. 颜色混合预测 :

def mix_colors(xy1, xy2, ratio):
    """预测两种颜色混合后的色度坐标"""
    mix_x = ratio*xy1[0] + (1-ratio)*xy2[0]
    mix_y = ratio*xy1[1] + (1-ratio)*xy2[1]
    return (mix_x, mix_y)

red = (0.64, 0.33)
green = (0.30, 0.60)
for ratio in np.linspace(0, 1, 10):
    mix = mix_colors(red, green, ratio)
    ax.scatter(*mix, color='black', s=20)

3. 色温轨迹可视化 :

# 普朗克轨迹数据 (黑体辐射色温线)
planckian_locus = [(0.4476,0.4074), (0.3484,0.3516), 
                   (0.3101,0.3162), (0.2856,0.2827)]

ax.plot(*zip(*planckian_locus), color='red', 
        linestyle='-.', label='Planckian Locus')

6. 工程实践中的注意事项

在实际项目中应用色度图时,有几个关键点需要特别注意:

色彩转换的精度问题 :

  • 8位RGB到XYZ的转换会引入量化误差
  • 不同白点假设会导致色度坐标偏移
  • 显示器色域限制可能使理论计算无法实现
def rgb_to_xyz(rgb, gamma=2.2):
    """考虑gamma校正的RGB转XYZ"""
    linear_rgb = np.where(rgb <= 0.04045, 
                         rgb/12.92, 
                         ((rgb+0.055)/1.055)**gamma)
    # 此处应有完整的转换矩阵计算
    return xyz

视觉均匀性问题 : CIE 1931的一个主要缺陷是色度图上的距离与视觉感知差异不一致。这导致了后续CIELUV等均匀色彩空间的开发:

def xy_to_Luv(x, y, Y=100):
    """将xyY转换到CIELUV空间"""
    u_prime = 4*x / (-2*x + 12*y + 3)
    v_prime = 9*y / (-2*x + 12*y + 3)
    # 完整计算还应考虑参考白点等参数
    return (116*(Y/100)**(1/3)-16, 13*L*(u_prime-u_ref), 13*L*(v_prime-v_ref))

现代色彩管理实践 :

  • 使用ICC配置文件确保跨设备一致性
  • 在图像处理管线中保持线性色彩空间计算
  • 对广色域内容进行适当的元数据标记
import PIL.ImageCms

# 创建从sRGB到Adobe RGB的色彩转换管道
srgb_profile = PIL.ImageCms.createProfile("sRGB")
adobe_rgb_profile = PIL.ImageCms.createProfile("Adobe RGB")
transform = PIL.ImageCms.buildTransform(
    srgb_profile, adobe_rgb_profile, "RGB", "RGB")
从Wright和Guild的实验到你的屏幕:手把手理解CIE 1931色度图(附计算示例) 本文通过Python代码重现CIE 1931色度图的科学之旅,解析Wright和Guild的颜色匹配实验如何奠定现代色彩科学基础。从三刺激值到色度坐标的数学转换,再到Display P3广色域的实际应用,帮助读者深入理解色彩管理的核心技术。 阅读详情

相关推荐

光谱数据计算CIE值(三刺激值、CIE1931、CIE1976、CCT)软件

软件界面如下,免安装,拷贝即可使用 导入光谱数据即可计算三刺激值、CIE1931、CIE1976、CCT CIE1931、CIE1976色坐标图形只管显示 导入的光谱数据格式如下,txt文本 波长380到780,间隔1nm 注意:缺省的数据默认写0即可 下面为一些CIE相关介绍: CIE(国际发光照明委员会):原文为Commission Internationale de L’Eclairage(法)或International Commission on Illumination(英)。这个委员会创

业余程序员小徐的博客 2万+

【Python】Python绘制CIE1931色度图并标点

Python绘制CIE1931色度图

Carifee的博客 7609

绘制CIE色度图的程序示例和解释

CIE色度图是一种用于可视化颜色和色彩空间的工具,它基于国际照明委员会(CIE)定义的色度图谱。通过绘制CIE色度图,我们可以更好地理解和比较不同颜色之间的差异和关系。CIE色度图是一种用于可视化颜色和色彩空间的工具,它基于国际照明委员会(CIE)定义的色度图谱。通过绘制CIE色度图,我们可以更好地理解和比较不同颜色之间的差异和关系。首先,我们定义了CIE 1931标准观察者曲线的x和y坐标。首先,我们定义了CIE 1931标准观察者曲线的x和y坐标。函数绘制了CIE色度图的边界。函数绘制了CIE色度图。

CodeNexus的博客 797

人生八大经典问题(转)

问题一, 如果你家附近有一家餐厅,东西又贵又难吃,桌上还爬着蟑螂,你会因为它很近很方便,就一而再、再而三地光临吗?回答:你一定会说,这是什么烂问题,谁那么笨,花钱买罪受?~可同样的情况换个场合,自己或许就做类似的蠢事。不少男女都曾经抱怨过他们的情人或配偶品性不端,三心二意,不负责任。明知在一起没 什么好的结果,怨恨已经比爱还多,但却“不知道为什么”还是要和他搅和下去,分不了手。说穿了,只是为了不甘

hebohexi的专栏 333

Color Gamut 色域matlab 编码

利用matlab,很好的画出了色域,个人自己写出的算法

Python-Colour一个Python颜色科学软件包实现了全面的颜色理论转换和算法

Colour 一个Python颜色科学软件包,实现了全面的颜色理论转换和算法

别再只盯着sRGB了!用Python和Matplotlib亲手绘制CIE 1931色度图,理解色彩空间的边界

本文详细介绍了如何使用Python和Matplotlib绘制CIE 1931色度图,帮助理解色彩空间的边界。通过代码实现光谱数据到色彩可视化的完整流程,包括获取标准观察者数据、计算色度坐标、绘制光谱轨迹以及添加常见色域和普朗克轨迹。适合设计师、摄影师和色彩科学爱好者深入理解色彩空间。

weixin_31986143的博客 219

CIE 1931 color space

色坐标的计算公式。The CIE xy chromaticity diagram and the CIE xyY color space

cie1931 python绘制_用cie1931颜色空间python2.7绘制色域

我想在这些坐标内创建一个ciexyY颜色的三角形图:(.119,.113),(.162,.723),(.695,.304),如图所示-亮度Y设置为30.0。在我创建了一个0-1之间xy值的三维数组。然后我创建了一个矩阵,三角形内有1,三角形外有0。我把三角形矩阵乘以xyNdarray。然后我循环使用xyY-ndarray并将xyY值转换为rgb,并显示它们。在结果有点接近,但不正确。我想错误是在最...

weixin_39598796的博客 768

CIE_1931_色度图

CIE_1931_色度图,广泛应用于信息技术应用和信息化建设。

plot-CIE-color-gamut.zip_CIE 色度图_CIE1976 BT.2020_色域图_色度_色度图 matl

CIE色度图绘制。 从CIE1931数据点开始,光刺激波长从360nm到830nm,间隔1nm,很准确的马蹄形图。色度图中贴入CIE1976均匀色空间彩色映射图。同时画出BT709和BT2020三角形色域,D65坐标。需要表示色域覆盖的文章,是绝好的插图。

别再死记硬背xyY了!用Python和Matplotlib亲手绘制你的第一张CIE 1931色度图

本文教你使用Python和Matplotlib从零开始绘制CIE 1931色度图,深入解析色彩科学中的XYZ色彩空间和色度坐标计算。通过代码实践,你将掌握光谱数据处理、色度转换及可视化技巧,应用于色彩管理、显示校准等实际场景。

weixin_30575517的博客 252

STM32踩坑--NoST-LINK detected

这里出现的NoST-LINK detected是没有扫描到端口 在我使用一段Fly-MCU后,有一天突然发现出现如上错误,再检查的过程中检查以下几点 1.STM32 魔术棒的设置 1.1Debug设置 1.2 utilities 设置没有问题,与原来一样又看了下端口——在设备管理器中;也没有问题 ...

qq_53002477的博客 2万+

cie1931 python绘制_在cie1931颜色空间python 2.7中绘制色域

我想在这些坐标内创建一个ciexyy颜色的三角图:(.119,.113),(.162,.723),(.695,.304),如图中所示-亮度y设置为30.0。我已经创建了一个XY值介于0-1之间的三维数组。然后我创建了一个矩阵,其中1在三角形内,0在三角形外。我把三角形矩阵乘以xyy-ndarray。然后我循环遍历xyy ndarray并将xyy值转换为rgb,并显示它们。结果有点接近,但不正确。我...

weixin_33279969的博客 1799

VTK vtkLookupTable vtkScalarBarActor 颜色条

有时需要给数据做一个 vtkScalarBarActor, 我们把显示的数据的一个 坐标系 来显示 颜色条1.以 Z 显示颜色 效果如下。

q610098308的专栏 4033

华为交换机与思科/华三设备LACP对接实战:手把手教你配置链路聚合

本文详细解析了华为交换机与思科、华三设备间的LACP链路聚合配置实战,涵盖核心原理、配置步骤及排错技巧。通过对比不同厂商的实现差异,提供可落地的跨厂商对接方案,助力企业网络工程师高效部署高可靠性链路聚合。

weixin_30836759的博客 422

cie1931 python绘制_科学网-gnuplot与CIE1931 XYZ三刺激值曲线-范学良的博文

1、直接生成PNG文件gunplot script:gnuplot> set term pngcairoTerminal type set to 'pngcairo'Options are ' background "#ffffff" fontscale 1.0 size 640, 480 linewidth 2'gnuplot> set output 'XYZ1931.png'gn...

weixin_36272079的博客 419

STM32学习笔记(江协科技)-----OLED显示屏

SSD1306简介:•SSD1306是一款OLED/PLED点阵显示屏的控制器,可以嵌入在屏幕中,用于执行接收数据、显示存储、扫描刷新等任务••驱动接口:128个SEG引脚和64个COM引脚,对应128*64像素点阵显示屏••内置显示存储器(GDDRAM):128*64 bit128*8 ByteSRAM••供电:IC逻辑),VCC=7~15V(面板驱动)••通信接口:8位6800/8080并行接口,3/4线SPI。

lu322f的博客 1062

软件測试计划模板

第1章 引言 1.1目的 简述本计划的目的,旨在说明各种測试阶段任务、人员分配和时间安排、工作规范等。 測试计划在策略和方法的高度说明怎样计划、组织和管理測试项目。測试计划包括足够的信息使測试人员明确项目须要做什么是怎样运作的。另外,清晰的文档结构能使不论什么一个读者在浏览计划的前面几页后,就能对项目有一个大概的认识。測试计划仅仅是測试的一个框架,非常多细节须要跟开发者或其它人员沟通,因...

weixin_34402408的博客 167

STM32F103串口接收中断:USART_IT_IDLE和USART_IT_RXNE区别

2:如果是大于1个byte的数据,在不用DMA的情况下,同时使能USART_IT_RXNE,USART_IT_IDLE中断,每收到一个字节在中断中把数据存到缓存中,待收到USART_IT_IDLE中断时,收完整帧数据,然后再解析处理数据。比如:如上图在初始化时,同时开启了两个中断,如果传送8个字节的数据,就会产生8个USART_IT_RXNE,和1个USART_IT_IDLE中断。(如果接收到数据,在1个byte的时间内,没有收到新数据,就认为是数据传送完成,产生空闲USART_IT_IDLE中断)

weixin_66299220的博客 2398

基于传感器数据实现火灾报警预测分析

火警 系统当检测到烟雾、火灾、一氧化碳或其他与火灾有关或一般通知的紧急情况时,向人们发出警告

DT程序员的博客 722

ORA-01861: 文字与格式字符串不匹配

这个错误一般出现在日期时间字段上,即你插入的时间格式和数据库现有的时间格式不一致,解决的方法是格式化你 插入的时间: to_date('#','yyyy-mm-dd hh24:mi:ss')   注:yyyy-mm-dd hh24:mi:ss是因为oracle不区分MM和mm大小写,分钟写成mi否则会显示月份。 这样的插入的时候就不会报这个ORA-01861 当用pl/sql develo...

weixin_33796177的博客 929

PCB板Gerber文件的理解和制作

Gerber文件是PCB生产的关键文件,主要包括:1)走线层(GTL/GBL);2)阻焊层(GTS/GBS);3)丝印层(GTO/GBO);4)板框层(GMx/GKO);5)钢网层(Gtp/GBp);6)钻孔文件(NCdrillFiles)。其中1-10项和15项钻孔文件必须提供,建议包含11-14项辅助钻孔层。Gerber文件不含过孔属性,需提前在AD中设置过孔盖油。导出步骤包括:导出非机械层、机械层和钻孔层,新版AD可通过"文件->制造输出->GerberFiles"操作

qq_37999850的博客 852

Philips Hue Python RGB/CIE1931 "xy" 转换工具常见问题解决方案

Philips Hue Python RGB/CIE1931 "xy" 转换工具常见问题解决方案 1. 项目基础介绍和主要编程语言 该项目是一个开源的Python库,用于将RGB颜色值转换为Philips Hue灯泡使用的CIE1931 "xy" 颜色空间。它支持多种不同的色域,包括Gamut A、B和C,默认使用的是Gamut B。项目的主要编程语言是Py...

gitblog_00605的博客 444

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

cie1931 python绘制_科学网—gnuplot与CIE1931 XYZ三刺激值曲线 - 范学良的博文

1、直接生成PNG文件gunplot script:gnuplot> set term pngcairoTerminal type set to 'pngcairo'Options are ' background "#ffffff" fontscale 1.0 size 640, 480 linewidth 2'gnuplot> set output 'XYZ1931.png'gn...

weixin_39662432的博客 426

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

上一篇: 深入解析SCI串口通信:从寄存器机制到LIN总线实战应用
下一篇: 告别Arcgis的复杂网络!用Qgis的ORS插件5分钟搞定等时圈分析(附免费Key申请)
SleepInDelphi
博客等级 码龄19年 32粉丝 388原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值