Files
pqAutomationApp/app/plots/plot_accuracy.py
2026-04-20 11:13:57 +08:00

318 lines
8.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""色准测试结果绘制。
Step 2 重构:从 pqAutomationApp.PQAutomationApp.plot_accuracy 原样搬迁。
"""
from matplotlib.patches import Rectangle
def plot_accuracy(self, accuracy_data, test_type):
"""绘制色准测试结果 - 29色显示 - 简洁版布局(显示 Gamma"""
self.accuracy_ax.clear()
self.accuracy_ax.set_xlim(0, 1)
self.accuracy_ax.set_ylim(0, 1)
self.accuracy_ax.axis("off")
self.accuracy_fig.subplots_adjust(
left=0.05,
right=0.95,
top=0.95,
bottom=0.02,
)
# 获取色准数据
color_patches = accuracy_data.get("color_patches", [])
delta_e_values = accuracy_data.get("delta_e_values", [])
avg_delta_e = accuracy_data.get("avg_delta_e", 0)
max_delta_e = accuracy_data.get("max_delta_e", 0)
min_delta_e = accuracy_data.get("min_delta_e", 0)
excellent_count = accuracy_data.get("excellent_count", 0)
good_count = accuracy_data.get("good_count", 0)
poor_count = accuracy_data.get("poor_count", 0)
# 获取 Gamma 值
target_gamma = accuracy_data.get("target_gamma", 2.2)
test_type_name = self.get_test_type_name(test_type)
# ========== 标题(动态显示 Gamma==========
if test_type == "sdr_movie":
title = f"{test_type_name} - 色准测试(全 29色 | Gamma {target_gamma}"
elif test_type == "hdr_movie":
title = f"{test_type_name} - 色准测试(全 29色 | PQ EOTF"
else: # screen_module
title = f"{test_type_name} - 色准测试(全 29色 | Gamma {target_gamma}"
self.accuracy_fig.suptitle(
title,
fontsize=11,
y=0.98,
fontweight="bold",
)
# ========== 29色6行5列布局 ==========
cols = 5
rows = 6
patch_width = 0.135
patch_height = 0.085
x_start = 0.08
y_start = 0.90
x_gap = 0.035
y_gap = 0.050
# ========== 绘制色块 ==========
for i, (color_name, delta_e) in enumerate(zip(color_patches, delta_e_values)):
row = i // cols
col = i % cols
x = x_start + col * (patch_width + x_gap)
y = y_start - row * (patch_height + y_gap)
# 颜色映射
color_map = {
# 灰阶
"White": "#FFFFFF",
"Gray 80": "#E6E6E6",
"Gray 65": "#D1D1D1",
"Gray 50": "#BABABA",
"Gray 35": "#9E9E9E",
# 饱和色
"100% Red": "#FF0000",
"100% Green": "#00FF00",
"100% Blue": "#0000FF",
"100% Cyan": "#00FFFF",
"100% Magenta": "#FF00FF",
"100% Yellow": "#FFFF00",
# ColorChecker 颜色
"Dark Skin": "#735242",
"Light Skin": "#C29682",
"Blue Sky": "#5E7A9C",
"Foliage": "#596B42",
"Blue Flower": "#8280B0",
"Bluish Green": "#63BDA8",
"Orange": "#D97829",
"Purplish Blue": "#4A5CA3",
"Moderate Red": "#C25461",
"Purple": "#5C3D6B",
"Yellow Green": "#9EBA40",
"Orange Yellow": "#E6A12E",
"Blue (Legacy)": "#333D96",
"Green (Legacy)": "#479447",
"Red (Legacy)": "#B0303B",
"Yellow (Legacy)": "#EDC721",
"Magenta (Legacy)": "#BA5491",
"Cyan (Legacy)": "#0085A3",
}
patch_color = color_map.get(color_name, "#808080")
# ΔE 等级颜色
if delta_e < 3:
edge_color = "green"
elif delta_e < 5:
edge_color = "orange"
else:
edge_color = "red"
# 绘制色块
rect = Rectangle(
(x, y),
patch_width,
patch_height,
transform=self.accuracy_ax.transAxes,
facecolor=patch_color,
edgecolor=edge_color,
linewidth=1.8,
)
self.accuracy_ax.add_patch(rect)
# ========== 标注色块名称(上方)==========
self.accuracy_ax.text(
x + patch_width / 2,
y + patch_height + 0.015,
color_name,
ha="center",
va="bottom",
fontsize=5.5,
fontweight="bold",
transform=self.accuracy_ax.transAxes,
clip_on=False,
)
# ========== 标注 ΔE 值(中心)==========
dark_colors = [
"100% Red",
"100% Green",
"100% Blue",
"Gray 35",
"Dark Skin",
"Foliage",
"Purple",
"Purplish Blue",
"Blue (Legacy)",
"Green (Legacy)",
"Red (Legacy)",
"Magenta (Legacy)",
"Cyan (Legacy)",
]
text_color = "white" if color_name in dark_colors else "black"
self.accuracy_ax.text(
x + patch_width / 2,
y + patch_height / 2,
f"ΔE\n{delta_e:.2f}",
ha="center",
va="center",
fontsize=5.2,
fontweight="bold",
color=text_color,
transform=self.accuracy_ax.transAxes,
bbox=dict(
boxstyle="round,pad=0.22",
facecolor="white" if text_color == "black" else "black",
alpha=0.75,
edgecolor=edge_color,
linewidth=1.0,
),
)
# ========== 统计信息卡片(只保留外框)==========
card_width = 0.84
card_height = 0.15
card_x = 0.08
card_y = 0.01
info_card = Rectangle(
(card_x, card_y),
card_width,
card_height,
transform=self.accuracy_ax.transAxes,
facecolor="#F0F0F0",
edgecolor="black",
linewidth=1.5,
)
self.accuracy_ax.add_patch(info_card)
# ========== 标题(带说明)==========
self.accuracy_ax.text(
card_x + card_width / 2,
card_y + card_height - 0.008,
"色准统计5灰阶 + 18 ColorChecker + 6饱和色 | ΔE 2000 标准)",
ha="center",
va="top",
fontsize=7.5,
fontweight="bold",
transform=self.accuracy_ax.transAxes,
)
# ========== 统计内容(无内部框)==========
stats_y = card_y + card_height * 0.55
# 左侧ΔE 统计
left_x = card_x + 0.02
stats_text = [
f"平均 ΔE: {avg_delta_e:.2f}",
f"最大 ΔE: {max_delta_e:.2f}",
f"最小 ΔE: {min_delta_e:.2f}",
]
for i, text in enumerate(stats_text):
self.accuracy_ax.text(
left_x,
stats_y - i * 0.030,
text,
ha="left",
va="center",
fontsize=7,
fontweight="bold",
transform=self.accuracy_ax.transAxes,
)
# 中间:色块统计
middle_x = card_x + card_width * 0.32
self.accuracy_ax.text(
middle_x,
stats_y,
f"优秀 (ΔE<3): {excellent_count}",
ha="left",
va="center",
fontsize=7,
color="green",
fontweight="bold",
transform=self.accuracy_ax.transAxes,
)
self.accuracy_ax.text(
middle_x,
stats_y - 0.030,
f"良好 (3≤ΔE<5): {good_count}",
ha="left",
va="center",
fontsize=7,
color="orange",
fontweight="bold",
transform=self.accuracy_ax.transAxes,
)
self.accuracy_ax.text(
middle_x,
stats_y - 0.060,
f"偏差 (ΔE≥5): {poor_count}",
ha="left",
va="center",
fontsize=7,
color="red",
fontweight="bold",
transform=self.accuracy_ax.transAxes,
)
# 右侧:总体评价
right_x = card_x + card_width - 0.02
if avg_delta_e < 2:
grade = "专业级"
grade_icon = "★★★"
grade_color = "darkgreen"
elif avg_delta_e < 3:
grade = "优秀"
grade_icon = "✓✓"
grade_color = "green"
elif avg_delta_e < 5:
grade = "良好"
grade_icon = ""
grade_color = "orange"
else:
grade = "需要校准"
grade_icon = ""
grade_color = "red"
self.accuracy_ax.text(
right_x,
stats_y + 0.020,
"总体评价:",
ha="right",
va="bottom",
fontsize=7,
fontweight="bold",
transform=self.accuracy_ax.transAxes,
)
self.accuracy_ax.text(
right_x,
stats_y - 0.025,
f"{grade} {grade_icon}",
ha="right",
va="top",
fontsize=11,
fontweight="bold",
color=grade_color,
transform=self.accuracy_ax.transAxes,
)
self.accuracy_canvas.draw()
self.chart_notebook.select(self.accuracy_chart_frame)