计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算mel-DER时出错: 'numpy.ndarray' object has no attribute 'start'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算mel-DER时出错: 'numpy.ndarray' object has no attribute 'start'
计算mel-DER时出错: 'numpy.ndarray' object has no attribute 'start'
计算mel-DER时出错: 'numpy.ndarray' object has no attribute 'start'
计算mel-DER时出错: 'numpy.ndarray' object has no attribute 'start'
计算mel-DER时出错: 'numpy.ndarray' object has no attribute 'start'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算Rf/Rg时出错: 'numpy.ndarray' object has no attribute 'wavelengths'
计算Rf/Rg时出错: '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
import re
# 完全重构的数据加载函数 - 正确解析附录中的数据结构
def load_led_spectra(file_path):
"""从Excel文件加载LED光谱数据"""
try:
# 读取Problem 2_LED_SPD工作表
df = pd.read_excel(file_path, sheet_name='Problem 2_LED_SPD', header=None)
# 提取波长和光谱数据
wavelengths = []
spectra = {
'Blue': [],
'Green': [],
'Red': [],
'Warm White': [],
'Cold White': []
}
# 从第2行开始读取数据(跳过表头)
for i in range(2, len(df)):
row = df.iloc[i]
# 解析波长值
wavelength_val = row[0]
if isinstance(wavelength_val, str):
match = re.search(r'(\d+)\(mW/m2/nm\)', wavelength_val)
if match:
wavelengths.append(float(match.group(1)))
else:
continue
else:
wavelengths.append(float(wavelength_val))
# 解析各通道的光谱数据
for j, channel in enumerate(spectra.keys(), start=1):
val = row[j]
if isinstance(val, str):
# 处理科学计数法
if 'e' in val.lower():
val = float(val)
# 处理带括号的值
elif '(' in val:
val = float(val.split('(')[0])
else:
val = float(val)
spectra[channel].append(val)
# 转换为NumPy数组
wavelengths = np.array(wavelengths)
for channel in spectra:
spectra[channel] = np.array(spectra[channel])
print(f"加载成功! 波长范围: {wavelengths.min()}-{wavelengths.max()}nm")
print(f"数据点数: {len(wavelengths)}")
return wavelengths, spectra
except Exception as e:
print(f"加载数据时出错: {str(e)}")
# 创建默认数据以防失败
wavelengths = np.linspace(380, 780, 81)
spectra = {
'Blue': np.zeros(81),
'Green': np.zeros(81),
'Red': np.zeros(81),
'Warm White': np.zeros(81),
'Cold White': np.zeros(81)
}
return wavelengths, spectra
# 光谱计算函数
def compute_synthetic_spd(weights, spectra):
"""计算合成光谱"""
channels = ['Blue', 'Green', 'Red', 'Warm White', 'Cold White']
spd = np.zeros_like(spectra['Blue'], dtype=np.float64)
for i, channel in enumerate(channels):
spd += weights[i] * spectra[channel].astype(np.float64)
return spd
def compute_cct_duv(spd, wavelengths):
"""计算CCT和Duv"""
try:
# 创建光谱分布对象
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
except Exception as e:
print(f"计算CCT/Duv时出错: {str(e)}")
return 6500, 0.0 # 返回默认值
def compute_rf_rg(spd, wavelengths, cct):
"""计算Rf和Rg指数"""
try:
sd_test = SpectralDistribution(spd, wavelengths, name='Test')
# 生成参考光源
if cct > 5000:
sd_ref = sd_CIE_illuminant_D_series(cct)
else:
sd_ref = sd_blackbody(cct, wavelengths)
# 对齐光谱
sd_ref = sd_ref.align(wavelengths)
# 计算色域指数
results = colour_fidelity_index_CIE2017(sd_test, sd_ref, additional_data=True)
Rf = results[0]
Rg = results[1]
return Rf, Rg
except Exception as e:
print(f"计算Rf/Rg时出错: {str(e)}")
return 80, 100 # 返回默认值
def compute_mel_der(spd, wavelengths):
"""计算褪黑素抑制指数(mel-DER)"""
try:
# 褪黑素作用光谱(高斯模型)
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
except Exception as e:
print(f"计算mel-DER时出错: {str(e)}")
return 0.5 # 返回默认值
# 优化模型
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)
constraints = [
cct - 5500, # CCT >= 5500
6500 - cct, # CCT <= 6500
Rg - 95, # Rg >= 95
105 - Rg, # Rg <= 105
Rf - 88, # Rf >= 88
duv + 0.002, # Duv >= -0.002
0.002 - duv, # Duv <= 0.002
np.sum(weights) - 1 # 权重和=1
]
return np.array(constraints, dtype=np.float64)
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)
constraints = [
cct - 2500, # CCT >= 2500
3500 - cct, # CCT <= 3500
Rf - 80, # Rf >= 80
duv + 0.003, # Duv >= -0.003
0.003 - duv, # Duv <= 0.003
np.sum(weights) - 1 # 权重和=1
]
return np.array(constraints, dtype=np.float64)
# 增强的优化算法
def optimize_weights(mode, spectra, wavelengths):
"""使用SQP算法优化LED权重"""
# 初始权重和边界
x0 = np.array([0.2, 0.2, 0.2, 0.2, 0.2], dtype=np.float64)
bounds = [(0.0, 1.0) for _ in range(5)]
# 根据模式选择目标函数和约束
if mode == 'daytime':
objective = lambda w: daytime_objective(w, spectra, wavelengths)
constraints = {
'type': 'ineq',
'fun': lambda w: daytime_constraints(w, spectra, wavelengths)
}
else: # nighttime
objective = lambda w: nighttime_objective(w, spectra, wavelengths)
constraints = {
'type': 'ineq',
'fun': lambda w: nighttime_constraints(w, spectra, wavelengths)
}
# SQP优化参数
options = {
'maxiter': 1000, # 增加最大迭代次数
'ftol': 1e-6, # 提高精度
'disp': True,
'eps': 1e-4 # 有限差分步长
}
# 多次尝试优化
best_result = None
for attempt in range(5): # 最多尝试5次
try:
print(f"\n优化尝试 #{attempt+1}")
# 随机化初始值
if attempt > 0:
x0 = np.random.dirichlet(np.ones(5), size=1)[0].astype(np.float64)
result = minimize(
objective,
x0,
method='SLSQP',
bounds=bounds,
constraints=constraints,
options=options
)
if result.success:
print(f"优化成功! 目标函数值: {result.fun:.4f}")
return result
# 保存最佳尝试结果
if best_result is None or (result.fun < best_result.fun and result.fun is not None):
best_result = result
print(f"当前最佳目标值: {best_result.fun:.4f}")
except Exception as e:
print(f"优化过程中出错: {str(e)}")
if best_result is not None:
print("返回最佳尝试结果")
best_result.success = True # 标记为成功以便继续
return best_result
print("所有优化尝试均失败,返回默认权重")
result = type('', (), {'x': np.array([0.2, 0.2, 0.2, 0.2, 0.2]), 'success': False, 'message': 'All attempts failed'})
result.success = True # 强制标记为成功
return result
# 结果分析和可视化
def analyze_results(weights, spectra, wavelengths, mode):
"""分析并展示优化结果"""
# 确保权重和为1
weights = weights / np.sum(weights) if np.sum(weights) > 0 else weights
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.savefig(f'{mode}_spectrum.png') # 保存图像
plt.show()
return {
'weights': weights,
'cct': cct,
'duv': duv,
'Rf': Rf,
'Rg': Rg,
'mel_der': mel_der
}
# 主程序
def main():
# 加载光谱数据
file_path = r'D:\BaiduNetdiskDownload\MATLAB R2024a\bin\project\附录.xlsx'
print(f"加载数据文件: {file_path}")
wavelengths, spectra = load_led_spectra(file_path)
# 日间照明模式优化
print("\n开始优化日间照明模式...")
result_day = optimize_weights('daytime', spectra, wavelengths)
weights_day = result_day.x
analyze_results(weights_day, spectra, wavelengths, 'daytime')
# 夜间助眠模式优化
print("\n开始优化夜间助眠模式...")
result_night = optimize_weights('nighttime', spectra, wavelengths)
weights_night = result_night.x
analyze_results(weights_night, spectra, wavelengths, 'nighttime')
if __name__ == "__main__":
main()这是代码
我希望你是真的能修改好,让这个代码能不报错的运行