添加手动设置窗口亮度、曲线图生成

This commit is contained in:
xinzhu.yin
2026-06-08 11:39:54 +08:00
parent e4890d9d8d
commit 9ad9cf9aa0
3 changed files with 160 additions and 14 deletions

View File

@@ -8,6 +8,7 @@ import atexit
import csv
import datetime
import os
import re
import shutil
import sys
import threading
@@ -15,6 +16,7 @@ import time
import tkinter as tk
from tkinter import filedialog, messagebox
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
@@ -398,15 +400,42 @@ def send_ld_window(self: "PQAutomationApp", percentage):
messagebox.showwarning("警告", "请先连接 UCD323 设备")
return
self.log_gui.log(f"🔆 发送 {percentage}% 窗口...", level="info")
_set_current_ld_pattern(self, "峰值亮度", f"{percentage}%窗口", percentage)
try:
luminance_percent = float(
self.ld_window_luminance_var.get()
if hasattr(self, "ld_window_luminance_var")
else 100
)
if luminance_percent < 1 or luminance_percent > 100:
raise ValueError("亮度范围应为 1-100")
except Exception as e:
messagebox.showwarning("参数错误", f"窗口亮度参数无效: {e}")
return
window_level = int(round(luminance_percent / 100.0 * 255.0))
self.log_gui.log(
f"🔆 发送 {percentage}% 窗口(亮度{luminance_percent:.0f}%...",
level="info",
)
_set_current_ld_pattern(
self,
"峰值亮度",
f"{percentage}%窗口({luminance_percent:.0f}%亮度)",
percentage,
)
def send():
if not _apply_ld_ucd_params(self):
return
width, height = self.signal_service.current_resolution()
try:
image_path = _ensure_window_image(width, height, percentage)
image_path = _ensure_window_image(
width,
height,
percentage,
window_level,
)
except Exception as e:
self._dispatch_ui(self.log_gui.log, f"图像生成失败: {e}")
return
@@ -416,14 +445,27 @@ def send_ld_window(self: "PQAutomationApp", percentage):
except Exception:
ok = False
msg = (
f"{percentage}% 窗口已发送" if ok
else f"{percentage}% 窗口发送失败"
f"{percentage}% 窗口({luminance_percent:.0f}%亮度)已发送" if ok
else f"{percentage}% 窗口({luminance_percent:.0f}%亮度)发送失败"
)
self._dispatch_ui(self.log_gui.log, msg)
threading.Thread(target=send, daemon=True).start()
def send_ld_manual_window(self: "PQAutomationApp"):
"""按手动输入的窗口百分比和亮度直接发送窗口图案。"""
try:
percentage = int(float(self.ld_window_percentage_var.get()))
if percentage < 1 or percentage > 100:
raise ValueError("窗口范围应为 1-100")
except Exception as e:
messagebox.showwarning("参数错误", f"窗口百分比无效: {e}")
return
self.send_ld_window(percentage)
def send_ld_checkerboard(self: "PQAutomationApp", center_white):
"""发送棋盘格图案(手动模式)。"""
if not self.signal_service.is_connected:
@@ -797,6 +839,63 @@ def save_local_dimming_results(self: "PQAutomationApp"):
messagebox.showerror("错误", f"保存失败: {str(e)}")
def plot_ld_instant_peak_curve(self: "PQAutomationApp"):
"""从测试表格提取瞬时峰值曲线点并生成亮度-时间曲线图。"""
curve_points = []
pattern = re.compile(r"t\s*=\s*([0-9]+(?:\.[0-9]+)?)s")
for item in self.ld_tree.get_children():
values = self.ld_tree.item(item, "values")
if len(values) < 3:
continue
test_item = str(values[0])
pattern_text = str(values[1])
lv_text = str(values[2])
if test_item != "瞬时峰值曲线":
continue
match = pattern.search(pattern_text)
if not match:
continue
try:
t_sec = float(match.group(1))
lv = float(lv_text)
except Exception:
continue
curve_points.append((t_sec, lv))
if not curve_points:
messagebox.showinfo("提示", "没有可绘制的瞬时峰值曲线数据")
return
curve_points.sort(key=lambda x: x[0])
t_data = [p[0] for p in curve_points]
lv_data = [p[1] for p in curve_points]
fig = plt.figure(figsize=(8.6, 4.6))
ax = fig.add_subplot(111)
ax.plot(t_data, lv_data, "-o", linewidth=1.8, markersize=3.5, color="#2a9d8f")
ax.set_title("Instant Peak Luminance Curve")
ax.set_xlabel("Time (s)")
ax.set_ylabel("Luminance (cd/m²)")
ax.grid(True, linestyle="--", alpha=0.35)
peak_idx = int(np.argmax(lv_data))
ax.scatter([t_data[peak_idx]], [lv_data[peak_idx]], color="#e76f51", zorder=3)
ax.annotate(
f"Peak: {lv_data[peak_idx]:.2f} cd/m² @ {t_data[peak_idx]:.2f}s",
(t_data[peak_idx], lv_data[peak_idx]),
xytext=(8, 10),
textcoords="offset points",
fontsize=9,
color="#333333",
)
fig.tight_layout()
plt.show(block=False)
self.log_gui.log("已生成瞬时峰值曲线图", level="success")
class LocalDimmingMixin:
"""由 tools/refactor_to_mixins.py 自动生成。
把本模块的自由函数挂到 PQAutomationApp 上,便于 F12 跳转与类型推断。
@@ -805,6 +904,7 @@ class LocalDimmingMixin:
update_ld_results = update_ld_results
stop_local_dimming_test = stop_local_dimming_test
send_ld_window = send_ld_window
send_ld_manual_window = send_ld_manual_window
send_ld_checkerboard = send_ld_checkerboard
send_ld_black_pattern = send_ld_black_pattern
send_ld_instant_peak = send_ld_instant_peak
@@ -813,3 +913,4 @@ class LocalDimmingMixin:
measure_ld_luminance = measure_ld_luminance
clear_ld_records = clear_ld_records
save_local_dimming_results = save_local_dimming_results
plot_ld_instant_peak_curve = plot_ld_instant_peak_curve

View File

@@ -60,6 +60,50 @@ def create_local_dimming_panel(self: "PQAutomationApp"):
style="SuccessState.TLabel",
).pack(pady=(0, 8))
window_level_row = ttk.Frame(window_frame)
window_level_row.pack(fill=tk.X, pady=(0, 8))
ttk.Label(window_level_row, text="窗口(%):").pack(side=tk.LEFT)
self.ld_window_percentage_var = tk.StringVar(value="10")
ld_window_percentage_entry = ttk.Entry(
window_level_row,
textvariable=self.ld_window_percentage_var,
width=8,
)
ld_window_percentage_entry.pack(side=tk.LEFT, padx=(6, 10))
ttk.Label(window_level_row, text="窗口亮度(%):").pack(side=tk.LEFT)
self.ld_window_luminance_var = tk.StringVar(value="100")
ld_window_luminance_entry = ttk.Entry(
window_level_row,
textvariable=self.ld_window_luminance_var,
width=8,
)
ld_window_luminance_entry.pack(side=tk.LEFT, padx=(6, 10))
ttk.Button(
window_level_row,
text="生成窗口",
command=self.send_ld_manual_window,
bootstyle="success-outline",
width=12,
).pack(side=tk.LEFT)
ld_window_percentage_entry.bind(
"<Return>",
lambda _event: self.send_ld_manual_window(),
)
ld_window_luminance_entry.bind(
"<Return>",
lambda _event: self.send_ld_manual_window(),
)
ttk.Label(
window_level_row,
text="输入后可直接点生成或回车",
style="InfoState.TLabel",
).pack(side=tk.LEFT, padx=(8, 0))
# 第一行1%, 2%, 5%, 10%, 18%
row1 = ttk.Frame(window_frame)
row1.pack(fill=tk.X, pady=(0, 5))
@@ -118,14 +162,6 @@ def create_local_dimming_panel(self: "PQAutomationApp"):
width=14,
).pack(side=tk.LEFT, padx=3)
ttk.Button(
pattern_row,
text="瞬时峰值",
command=self.send_ld_instant_peak,
bootstyle="warning",
width=12,
).pack(side=tk.LEFT, padx=3)
ttk.Button(
pattern_row,
text="全黑画面",
@@ -285,6 +321,15 @@ def create_local_dimming_panel(self: "PQAutomationApp"):
)
self.ld_save_btn.pack(side=tk.LEFT)
self.ld_plot_btn = ttk.Button(
bottom_frame,
text="📈 生成峰值曲线",
command=self.plot_ld_instant_peak_curve,
bootstyle="warning-outline",
width=14,
)
self.ld_plot_btn.pack(side=tk.LEFT, padx=(5, 0))
# 默认隐藏
self.local_dimming_visible = False

View File

@@ -1,5 +1,5 @@
{
"current_test_type": "screen_module",
"current_test_type": "local_dimming",
"test_types": {
"screen_module": {
"name": "屏模组性能测试",