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

优化LED 8bit信号驱动下CIE XYZ色彩的指数曲线拟合

LED色度拟合优化问题

背景与现有方案

我记录了LED色彩随8bit驱动信号(范围0-255)变化的数据,采用指数曲线拟合能较好表征LED特性,使用公式:

x * signal ** ex 
y * signal ** ey 
z * signal ** ez 

在Python中通过scipy实现拟合:

from scipy.optimize import curve_fit

def fit_func_xae(x, a, e):
    # Curve fitting function
    return a * x**e

# X, Y, Z为物理仪器测得的真实色度值
(aX, eX), cov = curve_fit(fit_func_xae, signal, X)
(aY, eY), cov = curve_fit(fit_func_xae, signal, Y)
(aZ, eZ), cov = curve_fit(fit_func_xae, signal, Z)

注:色度学中采用CIE XYZ色彩空间表示LED颜色,该空间为线性空间,与线性RGB空间类似,可近似将XYZ视为线性RGB的同义词,颜色由三元组线性值X、Y、Z表示。

原始测量数据

每个8bit驱动信号对应3组测量值:

Signal 
[  3.   3.   3.   5.   5.   5.   7.   7.   7.  10.  10.  10.  15.  15.
  15.  20.  20.  20.  30.  30.  30.  40.  40.  40.  80.  80.  80. 160.
 160. 160. 240. 240. 240. 255. 255. 255.]

X, Y, Z
[[9.93295448e-05 8.88955748e-04 6.34978556e-04]
 [9.66399391e-05 8.86031926e-04 6.24680520e-04]
 [1.06108685e-04 8.99010175e-04 6.41577838e-04]
 [1.96407653e-04 1.70210146e-03 1.27178991e-03]
 [1.84965943e-04 1.67927596e-03 1.24985475e-03]
 [1.83770476e-04 1.67905297e-03 1.24855580e-03]
 [3.28537613e-04 2.75382195e-03 2.14639821e-03]
 [3.17804246e-04 2.74152647e-03 2.11730825e-03]
 [3.19167905e-04 2.74977632e-03 2.11142769e-03]
 [5.43770342e-04 4.09314433e-03 3.33793380e-03]
 [5.02493149e-04 4.04392581e-03 3.24784452e-03]
 [5.00712102e-04 4.03456071e-03 3.26803716e-03]
 [1.48001671e-03 1.09367632e-02 9.59283037e-03]
 [1.52082180e-03 1.09920985e-02 9.63624777e-03]
 [1.50153844e-03 1.09623592e-02 9.61724422e-03]
 [3.66206564e-03 2.74730946e-02 2.51982924e-02]
 [3.64074861e-03 2.74283157e-02 2.52187294e-02]
 [3.68719991e-03 2.75033778e-02 2.51691331e-02]
 [1.50905917e-02 1.06056566e-01 1.06534373e-01]
 [1.51370269e-02 1.06091182e-01 1.06790424e-01]
 [1.51654172e-02 1.06109863e-01 1.06943957e-01]
 [3.42912601e-02 2.30854413e-01 2.43427207e-01]
 [3.42217124e-02 2.30565972e-01 2.43529454e-01]
 [3.41486993e-02 2.30807320e-01 2.43591644e-01]
 [1.95905112e-01 1.27409867e+00 1.37490536e+00]
 [1.94923951e-01 1.26934278e+00 1.37751808e+00]
 [1.95242984e-01 1.26805844e+00 1.37565458e+00]
 [1.07931878e+00 6.97822521e+00 7.49602715e+00]
 [1.08944832e+00 7.03128378e+00 7.54296884e+00]
 [1.07994964e+00 6.96864302e+00 7.44011991e+00]
 [2.95296087e+00 1.90746191e+01 1.99164655e+01]
 [2.94254973e+00 1.89524517e+01 1.98158118e+01]
 [2.95753358e+00 1.90200667e+01 1.98885050e+01]
 [3.44049055e+00 2.21221159e+01 2.29667049e+01]
 [3.43817829e+00 2.21225393e+01 2.29363833e+01]
 [3.43077583e+00 2.21158929e+01 2.29399652e+01]]

问题描述

上述指数曲线拟合整体效果较好,但放大后发现低信号区间精度不足:高信号时Z分量(蓝色点)高于Y分量(绿色点),低信号时Y分量高于Z分量,说明LED色彩随PWM变化(或因功率提升致温度上升),现有模型无法表征该特性。

我尝试用双指数项公式优化:

x1 * signal ** ex + x2 * signal ** fx

替代原公式:

x * signal ** ex

但导致scipy溢出。需要简洁优雅的方案,满足:

  1. 信号为0时输出为0
  2. 低信号区间增长快于单一指数
  3. 保留高信号拟合精度

优化思路

1. 修正双指数模型的数值稳定性

双指数溢出的核心原因是signal ** fx在fx为极端值时,数值会趋近于0或无穷大。可以通过以下方式解决:

  • 参数约束:给curve_fit添加bounds参数,限制指数范围(比如0.5到3之间),避免极端值导致溢出。
  • 对数转换计算:先计算log(signal),再乘以指数后取指数,避免直接计算大幂次:
    import numpy as np
    def fit_func_double_exp(x, a1, e1, a2, e2):
        log_x = np.log(x + 1e-8)  # 加极小值避免log(0)报错
        term1 = a1 * np.exp(e1 * log_x)
        term2 = a2 * np.exp(e2 * log_x)
        return term1 + term2
    
  • 初始化合理参数:用单指数拟合的结果作为初始值(比如p0=[aX, eX, 0.1*aX, eX+0.5]),让拟合从合理起点开始,减少溢出概率。

2. 采用带偏移的指数模型

使用a * (signal + b) ** e - a * b ** e,这个模型满足signal=0时输出为0,通过调整b的值可以改变低信号区间的增长速率:当b>0时,低信号部分的增长会比单一指数更快;高信号时signal + b近似等于signal,不会影响高区间的拟合精度。

def fit_func_offset_exp(x, a, b, e):
    return a * (x + b)**e - a * (b)**e

拟合时给b设置下界(比如b>0),避免出现不合理的负值。

3. 分段拟合+平滑过渡

将数据分为低信号(比如signal<50)和高信号(signal>=50)两段,分别用不同的指数模型拟合,再用Sigmoid函数实现平滑过渡:

  • 低信号段:用a1 * signal ** e1,保证低区间增长速率
  • 高信号段:用a2 * signal ** e2,保留高区间精度
  • 过渡权重:weight = 1 / (1 + np.exp(-k*(signal - threshold))),最终输出为(1-weight)*low_fit + weight*high_fit

这种方法逻辑清晰,能针对性优化低信号区间,同时不影响高信号拟合效果,也不会出现数值溢出问题。

4. 引入温度相关修正项

如果色彩变化确实由温度导致,可以用PWM信号间接表征温度(比如temp = c * signal + d),给每个分量的指数添加温度依赖:

def fit_func_temp_exp(x, a, e0, k, c, d):
    temp = c * x + d
    e = e0 + k * temp
    return a * x**e

这个模型能直接表征温度对LED发光特性的影响,更贴合物理本质,但需要确保温度与PWM的相关性合理。


内容的提问来源于stack exchange,提问作者adrienlucca.net

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 15:15:37