You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python绘制可交互CIElab色彩空间并实现色差分析与可视化

Python实现交互式CIElab色彩空间可视化及色差分析

依赖库安装

打开终端执行以下命令安装所需工具库:

pip install plotly colormath numpy

完整代码实现

import numpy as np
import plotly.graph_objects as go
from colormath.color_objects import LabColor
from colormath.color_diff import delta_e_cie76
from colormath.color_conversions import convert_color

# ---------------------- 1. 色彩参数转换工具 ----------------------
def lab_to_ch(lab):
    """将L*a*b*转换为彩度C*和色相角h"""
    l, a, b = lab
    c = np.sqrt(a**2 + b**2)
    if a == 0 and b == 0:
        h = 0
    else:
        h = np.degrees(np.arctan2(b, a))
        h = h if h >= 0 else h + 360
    return c, h

def ch_to_lab(l, c, h):
    """将L*、C*、h转换为L*a*b*"""
    h_rad = np.radians(h)
    a = c * np.cos(h_rad)
    b = c * np.sin(h_rad)
    return (l, a, b)

# ---------------------- 2. 色差计算 ----------------------
def calculate_color_diff(ref_lab, test_lab):
    """计算参考样与待测样的ΔE*ab色差(CIE76标准)"""
    ref_color = LabColor(*ref_lab)
    test_color = LabColor(*test_lab)
    return delta_e_cie76(ref_color, test_color)

# ---------------------- 3. 交互式CIElab空间绘制 ----------------------
def plot_interactive_lab_space(ref_sample, test_samples):
    # 定义坐标轴范围
    l_range = [0, 100]
    a_range = [-128, 127]
    b_range = [-128, 127]

    # 创建3D画布
    fig = go.Figure()

    # 添加CIElab坐标轴参考线
    # L*轴(a=0, b=0,从黑到白)
    fig.add_trace(go.Scatter3d(
        x=[0]*100, y=[0]*100, z=np.linspace(l_range[0], l_range[1], 100),
        mode='lines', line=dict(color='gray', width=2), name='L*轴'
    ))
    # a*轴(L=50, b=0,从绿到红)
    fig.add_trace(go.Scatter3d(
        x=np.linspace(a_range[0], a_range[1], 100), y=[0]*100, z=[50]*100,
        mode='lines', line=dict(color='red', width=2), name='a*轴(绿→红)'
    ))
    # b*轴(L=50, a=0,从蓝到黄)
    fig.add_trace(go.Scatter3d(
        x=[0]*100, y=np.linspace(b_range[0], b_range[1], 100), z=[50]*100,
        mode='lines', line=dict(color='yellow', width=2), name='b*轴(蓝→黄)'
    ))

    # 添加参考样品数据点
    ref_l, ref_a, ref_b = ref_sample
    ref_c, ref_h = lab_to_ch(ref_sample)
    # 将Lab转换为RGB用于点的颜色显示
    ref_rgb = convert_color(LabColor(ref_l, ref_a, ref_b), LabColor).get_rgb()
    ref_rgb = tuple(np.clip(np.array(ref_rgb)*255, 0, 255).astype(int))
    fig.add_trace(go.Scatter3d(
        x=[ref_a], y=[ref_b], z=[ref_l],
        mode='markers+text', marker=dict(size=12, color=f'rgb{ref_rgb}'),
        text=f"参考样<br>L={ref_l:.1f}<br>a={ref_a:.1f}<br>b={ref_b:.1f}<br>C={ref_c:.1f}<br>h={ref_h:.0f}°",
        textposition='top center', name='参考样品'
    ))

    # 添加待测样品及色移连线
    for idx, test_lab in enumerate(test_samples):
        test_l, test_a, test_b = test_lab
        test_c, test_h = lab_to_ch(test_lab)
        test_rgb = convert_color(LabColor(test_l, test_a, test_b), LabColor).get_rgb()
        test_rgb = tuple(np.clip(np.array(test_rgb)*255, 0, 255).astype(int))
        # 计算色差
        delta_e = calculate_color_diff(ref_sample, test_lab)
        # 添加待测样点
        fig.add_trace(go.Scatter3d(
            x=[test_a], y=[test_b], z=[test_l],
            mode='markers+text', marker=dict(size=10, color=f'rgb{test_rgb}'),
            text=f"待测样{idx+1}<br>L={test_l:.1f}<br>a={test_a:.1f}<br>b={test_b:.1f}<br>C={test_c:.1f}<br>h={test_h:.0f}°<br>ΔE={delta_e:.2f}",
            textposition='top center', name=f'待测样品{idx+1}'
        ))
        # 添加色移连线(参考样→待测样)
        fig.add_trace(go.Scatter3d(
            x=[ref_a, test_a], y=[ref_b, test_b], z=[ref_l, test_l],
            mode='lines', line=dict(color='black', dash='dash', width=2),
            name=f'色移{idx+1} (ΔE={delta_e:.2f})'
        ))

    # 配置图表布局
    fig.update_layout(
        scene=dict(
            xaxis_title='a*(绿→红)',
            yaxis_title='b*(蓝→黄)',
            zaxis_title='L*(黑→白)',
            xaxis_range=a_range,
            yaxis_range=b_range,
            zaxis_range=l_range,
            camera=dict(eye=dict(x=1.5, y=1.5, z=0.8))
        ),
        title='交互式CIElab色彩空间及色差分析',
        showlegend=True
    )

    # 显示交互式图表
    fig.show()

# ---------------------- 示例使用 ----------------------
if __name__ == '__main__':
    # 参考样品L*a*b*参数
    reference_sample = (50, 20, 30)
    # 待测样品列表(可添加更多)
    test_samples = [
        (55, 25, 35),
        (45, 15, 25),
        (50, 10, 40)
    ]
    # 生成交互式图表
    plot_interactive_lab_space(reference_sample, test_samples)

代码说明

  1. 色彩参数转换:实现Lab与C(彩度)、h(色相角)的双向转换,适配不同参数输入场景。
  2. 色差计算:采用行业通用的CIE76标准计算ΔE*ab,数值越大代表色彩差异越显著。
  3. 交互式可视化:基于Plotly生成3D交互图表,支持旋转、缩放、悬停查看参数;每个数据点的颜色与对应Lab色彩一致,直观呈现色彩属性。
  4. 色移展示:用虚线连接参考样与待测样,标注ΔE值,清晰展示色彩偏移的方向和程度。

使用注意事项

  • 若需添加更多待测样品,直接在test_samples列表中补充Lab*参数组即可。
  • 若使用C*、h参数输入,可通过ch_to_lab函数转换为Lab*格式后传入。
  • 支持将图表导出为HTML、PNG等格式,方便保存和分享。

内容的提问来源于stack exchange,提问作者Abhishek Kashyap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 10:13:15