修改SDR色准深色异常、修改保存结果深色模式异常
This commit is contained in:
@@ -2,15 +2,14 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
_EXPORT_BG_COLOR = "#FFFFFF"
|
def _save_with_theme_background(fig, path, *, dpi=300, bbox_inches=None):
|
||||||
|
"""按图表当前主题背景导出,避免深色模式下被强制写成白底。"""
|
||||||
|
bg = fig.get_facecolor()
|
||||||
def _save_with_light_background(fig, path, *, dpi=300, bbox_inches=None):
|
|
||||||
"""导出统一浅色背景,避免深色主题下图片背景变暗。"""
|
|
||||||
kwargs = {
|
kwargs = {
|
||||||
"dpi": dpi,
|
"dpi": dpi,
|
||||||
"facecolor": _EXPORT_BG_COLOR,
|
"facecolor": bg,
|
||||||
"edgecolor": _EXPORT_BG_COLOR,
|
"edgecolor": bg,
|
||||||
|
"transparent": False,
|
||||||
}
|
}
|
||||||
if bbox_inches is not None:
|
if bbox_inches is not None:
|
||||||
kwargs["bbox_inches"] = bbox_inches
|
kwargs["bbox_inches"] = bbox_inches
|
||||||
@@ -85,7 +84,7 @@ def save_result_images(result_dir, current_test_type, selected_items,
|
|||||||
continue
|
continue
|
||||||
per_ref_name = f"色域测试结果_{ref}.png"
|
per_ref_name = f"色域测试结果_{ref}.png"
|
||||||
path = os.path.join(result_dir, per_ref_name)
|
path = os.path.join(result_dir, per_ref_name)
|
||||||
_save_with_light_background(fig, path, dpi=300)
|
_save_with_theme_background(fig, path, dpi=300)
|
||||||
log(f"已保存: {per_ref_name}")
|
log(f"已保存: {per_ref_name}")
|
||||||
finally:
|
finally:
|
||||||
ref_var.set(original_ref)
|
ref_var.set(original_ref)
|
||||||
@@ -97,7 +96,7 @@ def save_result_images(result_dir, current_test_type, selected_items,
|
|||||||
continue
|
continue
|
||||||
path = os.path.join(result_dir, filename)
|
path = os.path.join(result_dir, filename)
|
||||||
if default_bbox:
|
if default_bbox:
|
||||||
_save_with_light_background(fig, path, dpi=300)
|
_save_with_theme_background(fig, path, dpi=300)
|
||||||
else:
|
else:
|
||||||
_save_with_light_background(fig, path, dpi=300, bbox_inches="tight")
|
_save_with_theme_background(fig, path, dpi=300, bbox_inches="tight")
|
||||||
log(f"已保存: {filename}")
|
log(f"已保存: {filename}")
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
"""CIE 色度图底图渲染与缓存。
|
"""
|
||||||
|
CIE 色度图底图渲染与缓存(工业版)
|
||||||
|
|
||||||
将"重型图像渲染"(colour-science 的谱迹颜色填充)与"轻量框架数据层"
|
特点:
|
||||||
(参考/实测三角形、标签、覆盖率)解耦。
|
- colour-science 谱迹渲染
|
||||||
|
- numpy RGBA 缓存
|
||||||
|
- 内存 + 磁盘缓存
|
||||||
|
- 支持 light / dark UI
|
||||||
|
- 启动预热
|
||||||
|
- 线程安全
|
||||||
|
|
||||||
底图:
|
调用方式:
|
||||||
- 仅在首次调用或缓存失效时通过 colour-science 渲染一次;
|
|
||||||
- 渲染结果保存为 numpy RGBA 数组,同时落盘到 settings/cache/,
|
bg, bbox = get_cie1931_background(mode="dark")
|
||||||
下次启动直接 imread 加载,避免重新跑色彩科学计算。
|
ax.imshow(bg, extent=bbox)
|
||||||
|
|
||||||
调用方在每次绘图时只需 `ax.imshow(bg, extent=bbox)`,再叠加自己的矢量层。
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -20,91 +25,140 @@ from typing import Tuple
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
# 谱迹底图分辨率(边长,单位像素)。1024 对于 14 inch 画布足够细腻,
|
# ----------------------------
|
||||||
# 文件大小 ~1-2MB,单次渲染 ~0.5-1 s,缓存后毫秒级加载。
|
# 配置
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
|
# 渲染分辨率
|
||||||
_DIAGRAM_RES = 1024
|
_DIAGRAM_RES = 1024
|
||||||
|
|
||||||
# 缓存版本号:当渲染参数或风格调整时递增,强制重新生成。
|
# 缓存版本(风格变化时递增)
|
||||||
_CACHE_VERSION = "v1"
|
_CACHE_VERSION = "v2"
|
||||||
|
|
||||||
_BBox = Tuple[float, float, float, float] # (xmin, xmax, ymin, ymax)
|
# UI 颜色
|
||||||
|
_DARK_BG = "#0f1115"
|
||||||
|
_LIGHT_BG = "#ffffff"
|
||||||
|
|
||||||
|
_BBox = Tuple[float, float, float, float]
|
||||||
|
|
||||||
_CIE1931_BBOX: _BBox = (0.0, 0.8, 0.0, 0.9)
|
_CIE1931_BBOX: _BBox = (0.0, 0.8, 0.0, 0.9)
|
||||||
_CIE1976_BBOX: _BBox = (0.0, 0.65, 0.0, 0.6)
|
_CIE1976_BBOX: _BBox = (0.0, 0.65, 0.0, 0.6)
|
||||||
|
|
||||||
|
|
||||||
_memory_cache: dict[str, np.ndarray] = {}
|
_memory_cache: dict[str, np.ndarray] = {}
|
||||||
_lock = threading.Lock()
|
_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# cache path
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
def _cache_dir() -> str:
|
def _cache_dir() -> str:
|
||||||
# 项目根目录通过本文件位置反推:app/plots/ -> 项目根
|
|
||||||
here = os.path.dirname(os.path.abspath(__file__))
|
here = os.path.dirname(os.path.abspath(__file__))
|
||||||
root = os.path.abspath(os.path.join(here, "..", ".."))
|
root = os.path.abspath(os.path.join(here, "..", ".."))
|
||||||
|
|
||||||
d = os.path.join(root, "settings", "cache")
|
d = os.path.join(root, "settings", "cache")
|
||||||
os.makedirs(d, exist_ok=True)
|
os.makedirs(d, exist_ok=True)
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
def _cache_key(kind: str, bbox: _BBox) -> str:
|
def _cache_key(kind: str, bbox: _BBox, mode: str) -> str:
|
||||||
sig = f"{kind}|{bbox}|{_DIAGRAM_RES}|{_CACHE_VERSION}"
|
sig = f"{kind}|{bbox}|{mode}|{_DIAGRAM_RES}|{_CACHE_VERSION}"
|
||||||
h = hashlib.md5(sig.encode("utf-8")).hexdigest()[:10]
|
h = hashlib.md5(sig.encode()).hexdigest()[:10]
|
||||||
return f"chromaticity_{kind}_{h}.npy"
|
|
||||||
|
return f"chromaticity_{kind}_{mode}_{h}.npy"
|
||||||
|
|
||||||
|
|
||||||
def _cache_path(kind: str, bbox: _BBox) -> str:
|
def _cache_path(kind: str, bbox: _BBox, mode: str) -> str:
|
||||||
return os.path.join(_cache_dir(), _cache_key(kind, bbox))
|
return os.path.join(_cache_dir(), _cache_key(kind, bbox, mode))
|
||||||
|
|
||||||
|
|
||||||
def _render_chromaticity(kind: str, bbox: _BBox) -> np.ndarray:
|
# ----------------------------
|
||||||
"""通过 colour-science 离屏渲染谱迹底图,返回 RGBA float 数组。"""
|
# 渲染
|
||||||
# 延迟导入:仅在缓存未命中时支付 colour.plotting 的加载开销。
|
# ----------------------------
|
||||||
|
|
||||||
|
def _render_chromaticity(kind: str, bbox: _BBox, mode: str) -> np.ndarray:
|
||||||
|
"""
|
||||||
|
通过 colour-science 渲染 chromaticity 图。
|
||||||
|
"""
|
||||||
|
|
||||||
import matplotlib
|
import matplotlib
|
||||||
|
|
||||||
prev_backend = matplotlib.get_backend()
|
prev_backend = matplotlib.get_backend()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
matplotlib.use("Agg", force=True)
|
matplotlib.use("Agg", force=True)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
import colour
|
||||||
from colour.plotting import (
|
from colour.plotting import (
|
||||||
plot_chromaticity_diagram_CIE1931,
|
plot_chromaticity_diagram_CIE1931,
|
||||||
plot_chromaticity_diagram_CIE1976UCS,
|
plot_chromaticity_diagram_CIE1976UCS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if mode == "dark":
|
||||||
|
colour.plotting.colour_style("dark")
|
||||||
|
bg_color = _DARK_BG
|
||||||
|
else:
|
||||||
|
colour.plotting.colour_style("light")
|
||||||
|
bg_color = _LIGHT_BG
|
||||||
|
|
||||||
xmin, xmax, ymin, ymax = bbox
|
xmin, xmax, ymin, ymax = bbox
|
||||||
|
|
||||||
aspect = (xmax - xmin) / (ymax - ymin)
|
aspect = (xmax - xmin) / (ymax - ymin)
|
||||||
|
|
||||||
height = _DIAGRAM_RES
|
height = _DIAGRAM_RES
|
||||||
width = int(round(height * aspect))
|
width = int(round(height * aspect))
|
||||||
|
|
||||||
fig = plt.figure(figsize=(width / 100.0, height / 100.0), dpi=100)
|
fig = plt.figure(
|
||||||
ax = fig.add_axes([0.0, 0.0, 1.0, 1.0])
|
figsize=(width / 100.0, height / 100.0),
|
||||||
|
dpi=100
|
||||||
|
)
|
||||||
|
|
||||||
|
fig.patch.set_facecolor(bg_color)
|
||||||
|
|
||||||
|
ax = fig.add_axes([0, 0, 1, 1])
|
||||||
|
ax.set_facecolor(bg_color)
|
||||||
|
|
||||||
if kind == "cie1931":
|
if kind == "cie1931":
|
||||||
|
|
||||||
plot_chromaticity_diagram_CIE1931(
|
plot_chromaticity_diagram_CIE1931(
|
||||||
axes=ax, show=False, title=False,
|
axes=ax,
|
||||||
tight_layout=False, transparent_background=True,
|
show=False,
|
||||||
|
title=False,
|
||||||
|
tight_layout=False,
|
||||||
bounding_box=bbox,
|
bounding_box=bbox,
|
||||||
|
transparent_background=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
elif kind == "cie1976":
|
elif kind == "cie1976":
|
||||||
|
|
||||||
plot_chromaticity_diagram_CIE1976UCS(
|
plot_chromaticity_diagram_CIE1976UCS(
|
||||||
axes=ax, show=False, title=False,
|
axes=ax,
|
||||||
tight_layout=False, transparent_background=True,
|
show=False,
|
||||||
|
title=False,
|
||||||
|
tight_layout=False,
|
||||||
bounding_box=bbox,
|
bounding_box=bbox,
|
||||||
|
transparent_background=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
plt.close(fig)
|
plt.close(fig)
|
||||||
raise ValueError(f"unknown diagram kind: {kind!r}")
|
raise ValueError(f"unknown diagram kind: {kind}")
|
||||||
|
|
||||||
ax.set_xlim(xmin, xmax)
|
ax.set_xlim(xmin, xmax)
|
||||||
ax.set_ylim(ymin, ymax)
|
ax.set_ylim(ymin, ymax)
|
||||||
|
|
||||||
ax.set_axis_off()
|
ax.set_axis_off()
|
||||||
ax.set_position([0.0, 0.0, 1.0, 1.0])
|
ax.set_position([0, 0, 1, 1])
|
||||||
|
|
||||||
fig.canvas.draw()
|
fig.canvas.draw()
|
||||||
# 从 canvas 抓取 RGBA 数组
|
|
||||||
buf = np.asarray(fig.canvas.buffer_rgba()).copy()
|
buf = np.asarray(fig.canvas.buffer_rgba()).copy()
|
||||||
buf = np.flipud(buf)
|
buf = np.flipud(buf)
|
||||||
|
|
||||||
plt.close(fig)
|
plt.close(fig)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -115,52 +169,107 @@ def _render_chromaticity(kind: str, bbox: _BBox) -> np.ndarray:
|
|||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
def _load_or_render(kind: str, bbox: _BBox) -> np.ndarray:
|
# ----------------------------
|
||||||
key = _cache_key(kind, bbox)
|
# load / render
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
|
def _load_or_render(kind: str, bbox: _BBox, mode: str) -> np.ndarray:
|
||||||
|
|
||||||
|
key = _cache_key(kind, bbox, mode)
|
||||||
|
|
||||||
with _lock:
|
with _lock:
|
||||||
|
|
||||||
if key in _memory_cache:
|
if key in _memory_cache:
|
||||||
return _memory_cache[key]
|
return _memory_cache[key]
|
||||||
|
|
||||||
disk = _cache_path(kind, bbox)
|
disk = _cache_path(kind, bbox, mode)
|
||||||
|
|
||||||
if os.path.isfile(disk):
|
if os.path.isfile(disk):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
arr = np.load(disk)
|
arr = np.load(disk)
|
||||||
|
|
||||||
_memory_cache[key] = arr
|
_memory_cache[key] = arr
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# 缓存损坏则重新渲染
|
|
||||||
try:
|
try:
|
||||||
os.remove(disk)
|
os.remove(disk)
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
arr = _render_chromaticity(kind, bbox)
|
arr = _render_chromaticity(kind, bbox, mode)
|
||||||
|
|
||||||
_memory_cache[key] = arr
|
_memory_cache[key] = arr
|
||||||
|
|
||||||
try:
|
try:
|
||||||
np.save(disk, arr)
|
np.save(disk, arr)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
|
|
||||||
def get_cie1931_background() -> Tuple[np.ndarray, _BBox]:
|
# ----------------------------
|
||||||
"""返回 (RGBA 数组, bbox),可直接 ax.imshow(arr, extent=[*bbox])。"""
|
# public API
|
||||||
return _load_or_render("cie1931", _CIE1931_BBOX), _CIE1931_BBOX
|
# ----------------------------
|
||||||
|
|
||||||
|
def get_cie1931_background(mode: str = "dark") -> Tuple[np.ndarray, _BBox]:
|
||||||
|
"""
|
||||||
|
获取 CIE1931 背景图
|
||||||
|
|
||||||
|
mode:
|
||||||
|
"dark"
|
||||||
|
"light"
|
||||||
|
"""
|
||||||
|
|
||||||
|
return _load_or_render("cie1931", _CIE1931_BBOX, mode), _CIE1931_BBOX
|
||||||
|
|
||||||
|
|
||||||
def get_cie1976_background() -> Tuple[np.ndarray, _BBox]:
|
def get_cie1976_background(mode: str = "dark") -> Tuple[np.ndarray, _BBox]:
|
||||||
return _load_or_render("cie1976", _CIE1976_BBOX), _CIE1976_BBOX
|
|
||||||
|
|
||||||
|
return _load_or_render("cie1976", _CIE1976_BBOX, mode), _CIE1976_BBOX
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# cache control
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
def clear_cache(*, disk: bool = False) -> None:
|
def clear_cache(*, disk: bool = False) -> None:
|
||||||
"""清空内存缓存(可选连同磁盘)。供调试/样式调整时使用。"""
|
"""
|
||||||
|
清空缓存
|
||||||
|
"""
|
||||||
|
|
||||||
with _lock:
|
with _lock:
|
||||||
|
|
||||||
_memory_cache.clear()
|
_memory_cache.clear()
|
||||||
|
|
||||||
if disk:
|
if disk:
|
||||||
|
|
||||||
d = _cache_dir()
|
d = _cache_dir()
|
||||||
|
|
||||||
for name in os.listdir(d):
|
for name in os.listdir(d):
|
||||||
if name.startswith("chromaticity_") and name.endswith(".npy"):
|
|
||||||
|
if name.startswith("chromaticity_"):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.remove(os.path.join(d, name))
|
os.remove(os.path.join(d, name))
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------
|
||||||
|
# warmup
|
||||||
|
# ----------------------------
|
||||||
|
|
||||||
|
def warmup_cache(mode: str = "dark") -> None:
|
||||||
|
"""
|
||||||
|
启动预热缓存
|
||||||
|
|
||||||
|
可在软件启动时调用,避免首次绘图卡顿。
|
||||||
|
"""
|
||||||
|
|
||||||
|
get_cie1931_background(mode)
|
||||||
|
get_cie1976_background(mode)
|
||||||
@@ -9,15 +9,10 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from matplotlib.patches import Rectangle
|
from matplotlib.patches import Rectangle
|
||||||
from matplotlib.lines import Line2D
|
from matplotlib.lines import Line2D
|
||||||
import matplotlib.colors as mcolors
|
from matplotlib.ticker import MultipleLocator, AutoMinorLocator
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from app.views.modern_styles import get_theme_palette
|
from app.views.modern_styles import get_theme_palette
|
||||||
|
|
||||||
from app.plots.gamut_background import get_cie1976_background
|
from app.plots.gamut_background import get_cie1976_background
|
||||||
from app.tests.color_accuracy import get_accuracy_color_standards
|
from app.tests.color_accuracy import get_accuracy_color_standards
|
||||||
from app.pq.color_patch_map import get_patch_color
|
|
||||||
from app.pq.color_patch_map import get_patch_color_from_xy
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from pqAutomationApp import PQAutomationApp
|
from pqAutomationApp import PQAutomationApp
|
||||||
@@ -68,13 +63,13 @@ def _xy_to_uv(x: float, y: float):
|
|||||||
return 0.0, 0.0
|
return 0.0, 0.0
|
||||||
return (4.0 * x) / denom, (9.0 * y) / denom
|
return (4.0 * x) / denom, (9.0 * y) / denom
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# 子图:左侧 Calman 风格面板
|
# 子图:左侧 Calman 风格面板
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
def _draw_left_panel(ax, color_patches, delta_e_values, font_scale=1.0, dark_mode=False):
|
def _draw_left_panel(ax, color_patches, delta_e_values, font_scale=1.0, dark_mode=False):
|
||||||
"""左侧仅保留大条形图"""
|
"""左侧仅保留大条形图"""
|
||||||
|
|
||||||
ax.clear()
|
ax.clear()
|
||||||
|
|
||||||
n = len(color_patches)
|
n = len(color_patches)
|
||||||
@@ -85,37 +80,43 @@ def _draw_left_panel(ax, color_patches, delta_e_values, font_scale=1.0, dark_mod
|
|||||||
y_pos = list(range(n))
|
y_pos = list(range(n))
|
||||||
bar_colors = [_COLOR_MAP.get(name, "#888888") for name in color_patches]
|
bar_colors = [_COLOR_MAP.get(name, "#888888") for name in color_patches]
|
||||||
|
|
||||||
|
edgecolor = "#F3F5F7" if dark_mode else "#202020"
|
||||||
|
text_color = "#F3F5F7" if dark_mode else "#111111"
|
||||||
|
bg_color = "#0F1115" if dark_mode else "#FFFFFF"
|
||||||
|
|
||||||
ax.barh(
|
ax.barh(
|
||||||
y_pos,
|
y_pos,
|
||||||
delta_e_values,
|
delta_e_values,
|
||||||
height=0.72,
|
height=0.72,
|
||||||
color=bar_colors,
|
color=bar_colors,
|
||||||
edgecolor="#202020",
|
edgecolor=edgecolor,
|
||||||
linewidth=0.5,
|
linewidth=0.5,
|
||||||
zorder=3,
|
zorder=3,
|
||||||
)
|
)
|
||||||
|
|
||||||
text_color = "#F3F5F7" if dark_mode else "#111111"
|
|
||||||
bg_color = "#0F1115" if dark_mode else "#FFFFFF"
|
|
||||||
spine_color = "#8C8F94" if dark_mode else "#9A9A9A"
|
|
||||||
|
|
||||||
ax.set_yticks(y_pos)
|
ax.set_yticks(y_pos)
|
||||||
ax.set_yticklabels(color_patches, fontsize=max(5, 7 * font_scale), color=text_color)
|
ax.set_yticklabels(color_patches, fontsize=max(5, 7 * font_scale), color=text_color)
|
||||||
ax.invert_yaxis()
|
ax.invert_yaxis()
|
||||||
|
|
||||||
x_max = max(15.0, max(delta_e_values) * 1.15)
|
x_max = max(15.0, max(delta_e_values) * 1.15)
|
||||||
ax.set_xlim(0, x_max)
|
ax.set_xlim(0, x_max)
|
||||||
ax.tick_params(axis="x", labelsize=max(6, 8 * font_scale), colors=text_color)
|
|
||||||
ax.grid(axis="x", linestyle="-", linewidth=0.6, alpha=0.3, zorder=0)
|
ax.tick_params(
|
||||||
ax.grid(axis="y", linestyle=":", linewidth=0.35, alpha=0.15, zorder=0)
|
axis="x",
|
||||||
|
labelsize=max(6, 8 * font_scale),
|
||||||
|
colors=text_color
|
||||||
|
)
|
||||||
|
|
||||||
|
ax.tick_params(
|
||||||
|
axis="y",
|
||||||
|
labelsize=max(5, 7 * font_scale),
|
||||||
|
colors=text_color
|
||||||
|
)
|
||||||
|
|
||||||
ax.set_facecolor(bg_color)
|
ax.set_facecolor(bg_color)
|
||||||
for spine in ax.spines.values():
|
|
||||||
spine.set_color(spine_color)
|
|
||||||
spine.set_linewidth(0.9)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 自动 minor tick
|
||||||
|
ax.xaxis.set_minor_locator(AutoMinorLocator(2))
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
@@ -126,7 +127,7 @@ def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0,
|
|||||||
"""绘制 CIE 1976 u'v' 上的色准对比。"""
|
"""绘制 CIE 1976 u'v' 上的色准对比。"""
|
||||||
ax.clear()
|
ax.clear()
|
||||||
try:
|
try:
|
||||||
bg, bbox = get_cie1976_background()
|
bg, bbox = get_cie1976_background(mode="dark" if dark_mode else "light")
|
||||||
if bg.shape[-1] == 4:
|
if bg.shape[-1] == 4:
|
||||||
bg = bg[:, :, :3]
|
bg = bg[:, :, :3]
|
||||||
xmin, xmax, ymin, ymax = bbox
|
xmin, xmax, ymin, ymax = bbox
|
||||||
@@ -154,6 +155,11 @@ def _draw_uv_diagram(ax, color_patches, measurements, standards, font_scale=1.0,
|
|||||||
|
|
||||||
ax.set_facecolor("#000" if dark_mode else "#FFFFFF")
|
ax.set_facecolor("#000" if dark_mode else "#FFFFFF")
|
||||||
ax.set_aspect("equal", adjustable="box")
|
ax.set_aspect("equal", adjustable="box")
|
||||||
|
ax.xaxis.set_major_locator(MultipleLocator(0.1))
|
||||||
|
ax.yaxis.set_major_locator(MultipleLocator(0.1))
|
||||||
|
|
||||||
|
ax.xaxis.set_minor_locator(MultipleLocator(0.02))
|
||||||
|
ax.yaxis.set_minor_locator(MultipleLocator(0.02))
|
||||||
|
|
||||||
ax.set_title(
|
ax.set_title(
|
||||||
"CIE 1976 u'v'",
|
"CIE 1976 u'v'",
|
||||||
@@ -309,7 +315,7 @@ def _draw_result_judgement(ax, accuracy_data, font_scale=1.0, dark_mode=False):
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
def plot_accuracy(self: "PQAutomationApp", accuracy_data, test_type):
|
def plot_accuracy(self: "PQAutomationApp", accuracy_data, test_type):
|
||||||
"""绘制色准测试结果 - Calman 风格(色块 + CIE 1976 u'v' + 统计)。"""
|
"""绘制色准测试结果"""
|
||||||
palette = get_theme_palette()
|
palette = get_theme_palette()
|
||||||
try:
|
try:
|
||||||
from app.views.theme_manager import is_dark
|
from app.views.theme_manager import is_dark
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
|||||||
# 左图:CIE 1931 xy
|
# 左图:CIE 1931 xy
|
||||||
# ============================================================
|
# ============================================================
|
||||||
try:
|
try:
|
||||||
bg_xy, bbox_xy = get_cie1931_background()
|
bg_xy, bbox_xy = get_cie1931_background(mode="dark" if dark_mode else "light")
|
||||||
_blit_background(ax_xy, bg_xy, bbox_xy)
|
_blit_background(ax_xy, bg_xy, bbox_xy)
|
||||||
_style_axes(
|
_style_axes(
|
||||||
ax_xy,
|
ax_xy,
|
||||||
@@ -343,7 +343,7 @@ def plot_gamut(self: "PQAutomationApp", results, coverage, test_type):
|
|||||||
# 右图:CIE 1976 u'v'
|
# 右图:CIE 1976 u'v'
|
||||||
# ============================================================
|
# ============================================================
|
||||||
try:
|
try:
|
||||||
bg_uv, bbox_uv = get_cie1976_background()
|
bg_uv, bbox_uv = get_cie1976_background(mode="dark" if dark_mode else "light")
|
||||||
_blit_background(ax_uv, bg_uv, bbox_uv)
|
_blit_background(ax_uv, bg_uv, bbox_uv)
|
||||||
_style_axes(
|
_style_axes(
|
||||||
ax_uv,
|
ax_uv,
|
||||||
|
|||||||
@@ -841,6 +841,15 @@ def _refresh_theme_toggle_label(self: "PQAutomationApp") -> None:
|
|||||||
|
|
||||||
def _on_toggle_theme(self: "PQAutomationApp") -> None:
|
def _on_toggle_theme(self: "PQAutomationApp") -> None:
|
||||||
"""切换主题:重新应用 ttk 样式并刷新所有自定义样式相关的标签。"""
|
"""切换主题:重新应用 ttk 样式并刷新所有自定义样式相关的标签。"""
|
||||||
|
# 在测试进行时禁止切换主题,避免影响测量稳定性
|
||||||
|
if getattr(self, "testing", False):
|
||||||
|
try:
|
||||||
|
if hasattr(self, "log_gui"):
|
||||||
|
self.log_gui.log("警告: 测试进行中,禁止切换主题", level="error")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return
|
||||||
|
|
||||||
from app.views.theme_manager import toggle_theme
|
from app.views.theme_manager import toggle_theme
|
||||||
toggle_theme()
|
toggle_theme()
|
||||||
# apply_modern_styles()
|
# apply_modern_styles()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"current_test_type": "local_dimming",
|
"current_test_type": "sdr_movie",
|
||||||
"test_types": {
|
"test_types": {
|
||||||
"screen_module": {
|
"screen_module": {
|
||||||
"name": "屏模组性能测试",
|
"name": "屏模组性能测试",
|
||||||
@@ -21,9 +21,9 @@
|
|||||||
"contrast": "rgb"
|
"contrast": "rgb"
|
||||||
},
|
},
|
||||||
"cct_params": {
|
"cct_params": {
|
||||||
"x_ideal": 0.3127,
|
"x_ideal": 0.303696,
|
||||||
"x_tolerance": 0.003,
|
"x_tolerance": 0.003,
|
||||||
"y_ideal": 0.329,
|
"y_ideal": 0.312349,
|
||||||
"y_tolerance": 0.003
|
"y_tolerance": 0.003
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
"y_ideal": 0.329,
|
"y_ideal": 0.329,
|
||||||
"y_tolerance": 0.003
|
"y_tolerance": 0.003
|
||||||
},
|
},
|
||||||
"gamut_reference": "BT.601"
|
"gamut_reference": "BT.709"
|
||||||
},
|
},
|
||||||
"hdr_movie": {
|
"hdr_movie": {
|
||||||
"name": "HDR Movie测试",
|
"name": "HDR Movie测试",
|
||||||
|
|||||||
Reference in New Issue
Block a user