AttributeError: 'numpy.ndarray' object has no attribute 'wavelengths'这是报错信息
import numpy as np
import pandas as pd
from scipy.optimize import minimize
import colour
from colour import SDS_ILLUMINANTS, MSDS_CMFS, sd_blackbody, sd_CIE_illuminant_D_series
from colour.quality import colour_fidelity_index_CIE2017
from colour.colorimetry import SpectralDistribution
from colour.temperature import CCT_to_uv_Ohno2013, uv_to_CCT_Ohno2013
import matplotlib.pyplot as plt
# 1. 读取LED光谱数据 (修改为处理附录格式)
def load_led_spectra(df):
"""从DataFrame加载LED光谱数据"""
# 提取波长列并处理单位
wavelengths = df['波长'].str.extract(r'(\d+)')[0].astype(int).values
# 提取各通道光谱数据
spectra = {
'Blue': df['Blue'].values,
'Green': df['Green'].values,
'Red': df['Red'].values,
'Warm White': df['Warm White'].values,
'Cold White': df['Cold White'].values
}
return wavelengths, spectra
# 2. 光谱计算函数 (保持不变)
def compute_synthetic_spd(weights, spectra):
"""计算合成光谱"""
channels = ['Blue', 'Green', 'Red', 'Warm White', 'Cold White']
spd = np.zeros_like(spectra['Blue'])
for i, channel in enumerate(channels):
spd += weights[i] * spectra[channel]
return spd
def compute_cct_duv(spd, wavelengths):
"""计算CCT和Duv"""
# 创建光谱分布对象
sd = SpectralDistribution(spd, wavelengths, name='Synthetic')
# 计算XYZ三刺激值
cmfs = MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
XYZ = colour.sd_to_XYZ(sd, cmfs)
# 计算uv色度坐标
uv = colour.UCS_to_uv(colour.XYZ_to_UCS(XYZ))
# 计算CCT和Duv
cct, duv = uv_to_CCT_Ohno2013(uv)
return cct, duv
def compute_rf_rg(spd, wavelengths, cct):
"""计算Rf和Rg指数"""
sd_test = SpectralDistribution(spd, wavelengths, name='Test')
# 生成参考光源(CCT>5000K用日光模型,否则用黑体辐射)
if cct > 5000:
sd_ref = sd_CIE_illuminant_D_series(cct)
else:
sd_ref = sd_blackbody(cct, wavelengths)
# 对齐光谱
sd_ref = sd_ref.align(wavelengths)
# 计算色域指数Rf和Rg
try:
results = colour_fidelity_index_CIE2017(sd_test, sd_ref, additional_data=True)
Rf = results[0]
Rg = results[1]
return Rf, Rg
except:
return 0, 0 # 计算失败时返回默认值
def compute_mel_der(spd, wavelengths):
"""计算褪黑素抑制指数(mel-DER)"""
# 褪黑素作用光谱(高斯模型)
sigma = 33.19
lambda0 = 477
v_spectrum = np.exp(-(wavelengths - lambda0)**2 / (2 * sigma**2))
# 获取D65标准光源
sd_D65 = SDS_ILLUMINANTS['D65'].copy()
sd_D65 = sd_D65.align(wavelengths)
d65_values = sd_D65.values
# 计算分子(合成光谱作用量)
numerator = np.sum(spd * v_spectrum)
# 计算分母(D65作用量)
denominator = np.sum(d65_values * v_spectrum)
return numerator / denominator
# 3. 优化模型 (修改约束条件为字典形式)
def daytime_objective(weights, spectra, wavelengths):
"""日间模式目标函数:最小化平均色差(最大化Rf)"""
spd = compute_synthetic_spd(weights, spectra)
cct, duv = compute_cct_duv(spd, wavelengths)
Rf, Rg = compute_rf_rg(spd, wavelengths, cct)
# 目标函数:最小化ΔE00(等价于最大化Rf)
return 100 - Rf if Rf > 0 else 100 # 确保有意义的返回值
def daytime_constraints(weights, spectra, wavelengths):
"""日间模式约束条件 - 返回字典形式"""
spd = compute_synthetic_spd(weights, spectra)
cct, duv = compute_cct_duv(spd, wavelengths)
Rf, Rg = compute_rf_rg(spd, wavelengths, cct)
return [
{'type': 'ineq', 'fun': lambda w: cct - 5500}, # CCT >= 5500
{'type': 'ineq', 'fun': lambda w: 6500 - cct}, # CCT <= 6500
{'type': 'ineq', 'fun': lambda w: Rg - 95}, # Rg >= 95
{'type': 'ineq', 'fun': lambda w: 105 - Rg}, # Rg <= 105
{'type': 'ineq', 'fun': lambda w: Rf - 88}, # Rf >= 88
{'type': 'ineq', 'fun': lambda w: duv + 0.002}, # Duv >= -0.002
{'type': 'ineq', 'fun': lambda w: 0.002 - duv}, # Duv <= 0.002
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1} # 权重和=1
]
def nighttime_objective(weights, spectra, wavelengths):
"""夜间模式目标函数:最小化mel-DER"""
spd = compute_synthetic_spd(weights, spectra)
return compute_mel_der(spd, wavelengths)
def nighttime_constraints(weights, spectra, wavelengths):
"""夜间模式约束条件 - 返回字典形式"""
spd = compute_synthetic_spd(weights, spectra)
cct, duv = compute_cct_duv(spd, wavelengths)
Rf, Rg = compute_rf_rg(spd, wavelengths, cct)
return [
{'type': 'ineq', 'fun': lambda w: cct - 2500}, # CCT >= 2500
{'type': 'ineq', 'fun': lambda w: 3500 - cct}, # CCT <= 3500
{'type': 'ineq', 'fun': lambda w: Rf - 80}, # Rf >= 80
{'type': 'ineq', 'fun': lambda w: duv + 0.003}, # Duv >= -0.003
{'type': 'ineq', 'fun': lambda w: 0.003 - duv}, # Duv <= 0.003
{'type': 'eq', 'fun': lambda w: np.sum(w) - 1} # 权重和=1
]
# 4. SQP优化算法 (修改为处理新的约束格式)
def optimize_weights(mode, spectra, wavelengths):
"""使用SQP算法优化LED权重"""
# 初始权重和边界
x0 = [0.2, 0.2, 0.2, 0.2, 0.2]
bounds = [(0, 1) for _ in range(5)]
# 根据模式选择目标函数和约束
if mode == 'daytime':
objective = lambda w: daytime_objective(w, spectra, wavelengths)
constraints = daytime_constraints(x0, spectra, wavelengths) # 初始约束
else: # nighttime
objective = lambda w: nighttime_objective(w, spectra, wavelengths)
constraints = nighttime_constraints(x0, spectra, wavelengths) # 初始约束
# SQP优化
options = {
'maxiter': 200,
'ftol': 1e-3,
'disp': True
}
result = minimize(
objective,
x0,
method='SLSQP',
bounds=bounds,
constraints=constraints,
options=options
)
return result
# 5. 结果分析和可视化 (保持不变)
def analyze_results(weights, spectra, wavelengths, mode):
"""分析并展示优化结果"""
spd = compute_synthetic_spd(weights, spectra)
cct, duv = compute_cct_duv(spd, wavelengths)
Rf, Rg = compute_rf_rg(spd, wavelengths, cct)
mel_der = compute_mel_der(spd, wavelengths) if mode == 'nighttime' else None
print(f"\n{'='*50}")
print(f"{'日间照明模式' if mode=='daytime' else '夜间助眠模式'}优化结果")
print('='*50)
print(f"权重分配: 蓝光={weights[0]:.4f}, 绿光={weights[1]:.4f}, 红光={weights[2]:.4f}")
print(f" 暖白={weights[3]:.4f}, 冷白={weights[4]:.4f}")
print(f"CCT = {cct:.1f}K, Duv = {duv:.6f}")
print(f"Rf = {Rf:.2f}, Rg = {Rg:.2f}")
if mode == 'nighttime':
print(f"mel-DER = {mel_der:.4f}")
# 绘制光谱图
plt.figure(figsize=(12, 6))
for i, (name, values) in enumerate(spectra.items()):
plt.plot(wavelengths, weights[i] * values, label=f"{name} ({weights[i]:.2f})")
plt.plot(wavelengths, spd, 'k-', linewidth=2, label='合成光谱')
plt.title(f"{'日间照明模式' if mode=='daytime' else '夜间助眠模式'} - 合成光谱")
plt.xlabel('波长 (nm)')
plt.ylabel('相对光谱功率')
plt.legend()
plt.grid(True)
plt.show()
return {
'weights': weights,
'cct': cct,
'duv': duv,
'Rf': Rf,
'Rg': Rg,
'mel_der': mel_der
}
# 主程序 (修改为处理附录数据)
def main():
# 加载Excel文件
file_path = '附录.xlsx'
# 读取Problem 2_LED_SPD工作表
df_led = pd.read_excel(file_path, sheet_name='Problem 2_LED_SPD')
# 处理LED光谱数据
wavelengths, spectra = load_led_spectra(df_led)
# 日间照明模式优化
print("开始优化日间照明模式...")
result_day = optimize_weights('daytime', spectra, wavelengths)
weights_day = result_day.x / np.sum(result_day.x) # 重新归一化
day_results = analyze_results(weights_day, spectra, wavelengths, 'daytime')
# 夜间助眠模式优化
print("\n开始优化夜间助眠模式...")
result_night = optimize_weights('nighttime', spectra, wavelengths)
weights_night = result_night.x / np.sum(result_night.x) # 重新归一化
night_results = analyze_results(weights_night, spectra, wavelengths, 'nighttime')
# 输出最终结果
print("\n最终优化结果:")
print(f"日间模式权重: {weights_day}")
print(f"夜间模式权重: {weights_night}")
return day_results, night_results
if __name__ == "__main__":
day_results, night_results = main()这是代码,我要修改代码