当前位置: 首页 > news >正文

别再死记硬背了!用Python Matplotlib手把手教你画出CIE1931色度图与黑体轨迹

用Python Matplotlib实战:从零绘制CIE1931色度图与黑体轨迹

色彩科学是数字图像处理、UI设计和影视制作的基石。对于开发者而言,理解CIE1931色度图不仅有助于精准控制色彩还原,还能优化跨设备色彩一致性。本文将带你用Python和Matplotlib,从原始数据开始,完整实现专业级色度图绘制,并标注黑体轨迹关键点。

1. 环境准备与数据解析

在开始绘制前,需要准备Python环境和原始色度数据。推荐使用Anaconda创建独立环境:

conda create -n color_science python=3.9 conda activate color_science pip install numpy matplotlib

原始数据通常以JSON格式存储,包含光谱轨迹(Spectrum Locus)和黑体轨迹(Blackbody Locus)的xy坐标。我们可以直接使用提供的字典结构:

color_data = { "Spectrum_Locus": { "x": [0.174112234, 0.174007918, ...], "y": [0.004963726, 0.004980549, ...] }, "Blackbody_Locus": { "x": [0.652728231, 0.585713587, ...], "y": [0.344483581, 0.393126202, ...] } }

提示:实际工程中建议将数据保存为JSON文件,使用json.load()读取,避免硬编码

2. 基础色度图绘制

2.1 创建画布与坐标设置

Matplotlib的默认设置不适合色度图展示,需要特别调整:

import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(10, 8)) ax.set_xlim(0, 0.8) ax.set_ylim(0, 0.9) ax.set_aspect('equal') ax.grid(True, alpha=0.3) ax.set_title('CIE 1931 Chromaticity Diagram', pad=20) ax.set_xlabel('x coordinate') ax.set_ylabel('y coordinate')

2.2 绘制光谱轨迹

光谱轨迹需要特殊处理闭合区域和填充色:

from matplotlib.patches import Polygon # 绘制光谱轨迹线 ax.plot(color_data['Spectrum_Locus']['x'], color_data['Spectrum_Locus']['y'], color='black', linewidth=1.5) # 创建填充多边形 polygon = Polygon(list(zip(color_data['Spectrum_Locus']['x'], color_data['Spectrum_Locus']['y'])), closed=True, alpha=0.3) ax.add_patch(polygon)

3. 黑体轨迹实现

3.1 绘制基础轨迹线

黑体轨迹代表不同色温下理想黑体辐射的色彩变化:

bb_x = color_data['Blackbody_Locus']['x'] bb_y = color_data['Blackbody_Locus']['y'] ax.scatter(bb_x, bb_y, s=50, c='red', zorder=5) ax.plot(bb_x, bb_y, 'r--', linewidth=2)

3.2 标注关键色温点

常见色温点及其对应坐标:

色温(K)x坐标y坐标颜色描述
28560.43690.4041白炽灯
50000.34510.3516正午阳光
65000.31270.3290D65标准光源
100000.28070.2918阴天天空

标注代码实现:

temperatures = [2856, 5000, 6500, 10000] for temp, x, y in zip(temperatures, bb_x[:4], bb_y[:4]): ax.annotate(f'{temp}K', (x, y), xytext=(10, 10), textcoords='offset points', bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5))

4. 高级可视化技巧

4.1 色彩空间填充

使用imshow实现色域可视化:

import numpy as np # 生成网格坐标 x = np.linspace(0, 0.8, 500) y = np.linspace(0, 0.9, 500) X, Y = np.meshgrid(x, y) # 计算色度坐标到RGB的转换(简化版) Z = np.sqrt(X**2 + Y**2) img = np.dstack((X, Y, Z)) # 显示色域 ax.imshow(img, extent=[0, 0.8, 0, 0.9], origin='lower', alpha=0.4, aspect='auto', zorder=0)

4.2 交互式标注

添加鼠标悬停显示坐标功能:

def on_move(event): if event.inaxes == ax: print(f'x={event.xdata:.4f}, y={event.ydata:.4f}') fig.canvas.mpl_connect('motion_notify_event', on_move)

5. 工程实践应用

5.1 色域检测算法

判断任意xy坐标是否在可见光谱内:

def in_spectrum(x, y, tolerance=0.01): from scipy.spatial import ConvexHull points = np.column_stack([color_data['Spectrum_Locus']['x'], color_data['Spectrum_Locus']['y']]) hull = ConvexHull(points) new_point = np.array([[x, y]]) return all((np.dot(eq[:-1], new_point.T) + eq[-1] <= tolerance) for eq in hull.equations)

5.2 色温到xy坐标转换

实现黑体轨迹插值计算:

from scipy.interpolate import interp1d # 示例色温点(实际需要更完整的数据) temps = [1000, 2000, 2856, 5000, 6500, 10000] bb_interp_x = interp1d(temps, bb_x[:len(temps)], kind='cubic') bb_interp_y = interp1d(temps, bb_y[:len(temps)], kind='cubic') def temp_to_xy(temp): return float(bb_interp_x(temp)), float(bb_interp_y(temp))

在显示器校准项目中,这套代码帮助我快速验证了不同色温设置下的实际色彩表现。最实用的发现是in_spectrum()函数,它能自动过滤掉超出人类视觉范围的无效颜色值,避免了后续计算的资源浪费。

http://www.jsqmd.com/news/979718/

相关文章:

  • 光子关联函数与量子发射体系统的高效计算
  • 保姆级教程:用Gitolite+Repo在Ubuntu上为RK3588 Android12 SDK搭建私有代码仓库
  • [智能体-326]:messages: Annotated[list[str], operator.add], 这是什么语法
  • 清远闲置黄金变现攻略 六大回收门店横评 - 润富黄金回收
  • 旧电脑别扔!手把手教你用U盘给X86设备刷入原生Android TV 9(附ARM兼容开启教程)
  • 2026电子元器件派瑞林镀膜加工服务推荐榜:派瑞林镀膜工艺/派瑞林镀膜服务/派瑞林防水涂层/CVD设备/Parylene气相沉积设备/选择指南 - 优质品牌商家
  • Windows 10 + VS2019 保姆级教程:搞定OpenMVG 2.0编译与第一个3D重建
  • 2026年|应对AI检测算法:英文论文AI率居高不下?5个降AI方法实测盘点 - 降AI实验室
  • 别再死记硬背RC公式了!用Multisim仿真带你搞懂单片机复位电路里的电容怎么选
  • 从Parasolid实体到三角面片:深入解析PK_TOPOL_facet数据结构与内存管理实战
  • 深圳闲置黄金变现实测攻略:6家门店排名与安全变现指南 - 润富黄金回收
  • 文本嵌入与向量数据库:构建LLM知识问答系统的实战指南
  • 遥感图像分类新思路:我是如何用‘空间-光谱Transformer’在Kaggle比赛中提升5个点的
  • 告别配置地狱!手把手教你用VS2022和Intel oneAPI搞定OpenCL开发环境(附完整路径)
  • 清远黄金奢侈品回收实测盘点 - 润富黄金回收
  • 双曲空间多模态学习在恶意软件检测中的应用
  • 用grid_map玩转2.5D地图:在RViz中可视化你的机器人崎岖地形数据
  • 从网页监控到移动端查看:用Astra相机和ROS melodic搭建一个简易的远程3D点云监控系统
  • IDEA快捷键太多记不住?这20个高频组合键让你编码效率翻倍(附自定义技巧)
  • 别再让侧扫声呐图变马赛克!SonarWiz7导入Klein 4000数据的正确姿势(浮点型设置详解)
  • 2025-2026年久韵红家具电话查询:选购实木家具前需核实材质与合同条款 - 品牌推荐
  • 纯C语言三端教务系统源码:管理员/教师/学生各司其职,全靠文本文件存数据
  • 广东光伏哪家好:排名前五专业深度测评解析 - 服务品牌热点
  • 从硬件RSS到软件RPS:一张图看懂Linux网络收包优化全家桶(含XPS与Offload)
  • 别再手动算电压了!STM32CubeMX+DAC+DMA+TIM,10分钟搞定10KHz正弦波信号源
  • Transformer架构深度解析:从数学原理到工程落地
  • STM32F105+RT-Thread下OLED12864的硬件SPI+DMA驱动工程(KEIL完整项目)
  • 超越CBAM和SE:GAM注意力机制为何在ImageNet上更有效?深入解析其设计思想与消融实验
  • Navicat Premium 15连接MySQL 8.0报错10061?除了启动服务,这些隐藏配置项也得看一眼
  • 面试官最爱问的Transformer注意力:从PyTorch代码逐行拆解QKV计算(附避坑点)