681 lines
27 KiB
Python
681 lines
27 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
参数控制面板配置文件
|
||
|
||
参数说明:
|
||
|
||
1. 曝光时间 (exposure)
|
||
- 范围:100-50000微秒
|
||
- 作用:控制相机传感器的曝光时间
|
||
- 效果:
|
||
- 增大:画面变亮,激光点更明显,但可能过曝
|
||
- 减小:画面变暗,减少过曝,激光点更清晰
|
||
- 建议值:5000微秒(激光检测默认值),光线暗时可适当增加
|
||
|
||
2. 增益 (gain)
|
||
- 范围:0-24dB
|
||
- 作用:放大传感器信号,增强画面亮度
|
||
- 效果:
|
||
- 增大:画面变亮,噪声也会增加
|
||
- 减小:画面变暗,噪声减少
|
||
- 建议值:0dB(激光检测默认值),仅在光线极暗时使用
|
||
|
||
3. 帧率 (fps)
|
||
- 范围:1-120 FPS
|
||
- 作用:控制相机采集图像的频率
|
||
- 效果:
|
||
- 增大:画面流畅度提高,CPU占用增加
|
||
- 减小:画面流畅度降低,CPU占用减少
|
||
- 建议值:30 FPS(平衡流畅度和性能)
|
||
|
||
4. ROI设置 (roi_x, roi_y, roi_width, roi_height)
|
||
- 作用:设置感兴趣区域,仅处理指定区域的图像
|
||
- 效果:
|
||
- 减小ROI:提高处理速度,减少CPU占用
|
||
- 增大ROI:处理范围更广,CPU占用增加
|
||
- 建议值:默认全画幅(0, 0, 640, 480),激光点固定时可缩小ROI
|
||
|
||
5. HSV调节
|
||
- H通道 (H_low, H_high):控制颜色范围
|
||
- 范围:0-255
|
||
- 作用:识别绿色激光的颜色范围
|
||
- 建议值:35-85(绿色激光默认范围)
|
||
- S通道 (S_low, S_high):控制饱和度范围
|
||
- 范围:0-255
|
||
- 作用:区分激光点和背景
|
||
- 建议值:80-255(过滤低饱和度背景)
|
||
- V通道 (V_low, V_high):控制亮度范围
|
||
- 范围:0-255
|
||
- 作用:区分激光点和暗背景
|
||
- 建议值:80-255(过滤暗背景)
|
||
"""
|
||
import tkinter as tk
|
||
from tkinter import ttk
|
||
import threading
|
||
import queue
|
||
|
||
class ConfigPanel:
|
||
def __init__(self, update_callback):
|
||
"""
|
||
初始化参数控制面板
|
||
|
||
Args:
|
||
update_callback: 参数更新回调函数
|
||
"""
|
||
self.update_callback = update_callback
|
||
self.root = None
|
||
self.queue = queue.Queue()
|
||
self.thread = None
|
||
|
||
# 默认参数
|
||
self.defaults = {
|
||
'exposure': 5000, # 曝光时间(微秒)
|
||
'gain': 0, # 增益(dB)
|
||
'fps': 60, # 帧率(FPS)
|
||
'roi_x': 0, # ROI起始X坐标
|
||
'roi_y': 0, # ROI起始Y坐标
|
||
'roi_width': 640, # ROI宽度
|
||
'roi_height': 480, # ROI高度
|
||
'h_low': 35, # H通道最小值
|
||
'h_high': 85, # H通道最大值
|
||
's_low': 80, # S通道最小值
|
||
's_high': 255, # S通道最大值
|
||
'v_low': 80, # V通道最小值
|
||
'v_high': 255 # V通道最大值
|
||
}
|
||
|
||
# 当前参数
|
||
self.current = self.defaults.copy()
|
||
|
||
def start(self):
|
||
"""启动参数控制面板线程"""
|
||
self.thread = threading.Thread(target=self._run)
|
||
self.thread.daemon = True
|
||
self.thread.start()
|
||
|
||
def _run(self):
|
||
"""运行Tkinter主循环"""
|
||
self.root = tk.Tk()
|
||
self.root.title("参数控制面板")
|
||
self.root.geometry("400x600")
|
||
|
||
# 创建主框架
|
||
main_frame = ttk.Frame(self.root, padding="10")
|
||
main_frame.pack(fill=tk.BOTH, expand=True)
|
||
|
||
# 创建标签页
|
||
notebook = ttk.Notebook(main_frame)
|
||
notebook.pack(fill=tk.BOTH, expand=True)
|
||
|
||
# 曝光增益页面
|
||
exp_gain_frame = ttk.Frame(notebook, padding="10")
|
||
notebook.add(exp_gain_frame, text="曝光增益")
|
||
|
||
# 帧率页面
|
||
fps_frame = ttk.Frame(notebook, padding="10")
|
||
notebook.add(fps_frame, text="帧率")
|
||
|
||
# ROI页面
|
||
roi_frame = ttk.Frame(notebook, padding="10")
|
||
notebook.add(roi_frame, text="ROI设置")
|
||
|
||
# HSV页面
|
||
hsv_frame = ttk.Frame(notebook, padding="10")
|
||
notebook.add(hsv_frame, text="HSV调节")
|
||
|
||
# 形态学参数页面
|
||
morph_frame = ttk.Frame(notebook, padding="10")
|
||
notebook.add(morph_frame, text="形态学参数")
|
||
|
||
# 几何参数页面
|
||
geometry_frame = ttk.Frame(notebook, padding="10")
|
||
notebook.add(geometry_frame, text="几何参数")
|
||
|
||
# 检测模式页面
|
||
mode_frame = ttk.Frame(notebook, padding="10")
|
||
notebook.add(mode_frame, text="检测模式")
|
||
|
||
# 曝光滑块
|
||
self._create_exposure_controls(exp_gain_frame)
|
||
|
||
# 增益滑块
|
||
self._create_gain_controls(exp_gain_frame)
|
||
|
||
# 帧率滑块
|
||
self._create_fps_controls(fps_frame)
|
||
|
||
# ROI设置
|
||
self._create_roi_controls(roi_frame)
|
||
|
||
# HSV调节
|
||
self._create_hsv_controls(hsv_frame)
|
||
|
||
# 形态学参数设置
|
||
self._create_morph_controls(morph_frame)
|
||
|
||
# 几何参数设置
|
||
self._create_geometry_controls(geometry_frame)
|
||
|
||
# 检测模式设置
|
||
self._create_mode_controls(mode_frame)
|
||
|
||
# 启动队列处理
|
||
self.root.after(100, self._process_queue)
|
||
|
||
# 运行主循环
|
||
self.root.mainloop()
|
||
|
||
def _create_exposure_controls(self, parent):
|
||
"""创建曝光控制滑块"""
|
||
# 曝光时间说明
|
||
ttk.Label(parent, text="曝光时间 (100-50000μs):").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 控制相机传感器曝光时间", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
ttk.Label(parent, text="增大: 画面变亮,激光点更明显,但可能过曝", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="减小: 画面变暗,减少过曝,激光点更清晰", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="建议值: 5000μs(激光检测默认值)", font=('Arial', 8), foreground='green').pack(pady=2)
|
||
|
||
def on_exposure_change(value):
|
||
self.current['exposure'] = int(float(value))
|
||
self.update_callback('exposure', int(float(value)))
|
||
|
||
exposure_scale = ttk.Scale(
|
||
parent,
|
||
from_=100,
|
||
to=50000,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_exposure_change
|
||
)
|
||
exposure_scale.set(self.defaults['exposure'])
|
||
exposure_scale.pack(pady=5)
|
||
|
||
self.exposure_var = tk.StringVar(value=str(self.defaults['exposure']))
|
||
ttk.Entry(parent, textvariable=self.exposure_var, width=10).pack(pady=5)
|
||
|
||
def update_exposure_from_entry():
|
||
try:
|
||
value = int(self.exposure_var.get())
|
||
if 100 <= value <= 50000:
|
||
exposure_scale.set(value)
|
||
on_exposure_change(value)
|
||
except ValueError:
|
||
pass
|
||
|
||
ttk.Button(parent, text="应用", command=update_exposure_from_entry).pack(pady=5)
|
||
|
||
def _create_gain_controls(self, parent):
|
||
"""创建增益控制滑块"""
|
||
# 增益说明
|
||
ttk.Label(parent, text="增益 (0-24dB):").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 放大传感器信号,增强画面亮度", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
ttk.Label(parent, text="增大: 画面变亮,噪声也会增加", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="减小: 画面变暗,噪声减少", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="建议值: 0dB(激光检测默认值),仅在光线极暗时使用", font=('Arial', 8), foreground='green').pack(pady=2)
|
||
|
||
def on_gain_change(value):
|
||
gain_value = float(value) / 10.0
|
||
self.current['gain'] = gain_value
|
||
self.update_callback('gain', gain_value)
|
||
|
||
gain_scale = ttk.Scale(
|
||
parent,
|
||
from_=0,
|
||
to=240,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_gain_change
|
||
)
|
||
gain_scale.set(self.defaults['gain'] * 10)
|
||
gain_scale.pack(pady=5)
|
||
|
||
self.gain_var = tk.StringVar(value=str(self.defaults['gain']))
|
||
ttk.Entry(parent, textvariable=self.gain_var, width=10).pack(pady=5)
|
||
|
||
def update_gain_from_entry():
|
||
try:
|
||
value = float(self.gain_var.get())
|
||
if 0 <= value <= 24:
|
||
gain_scale.set(value * 10)
|
||
on_gain_change(value * 10)
|
||
except ValueError:
|
||
pass
|
||
|
||
ttk.Button(parent, text="应用", command=update_gain_from_entry).pack(pady=5)
|
||
|
||
def _create_fps_controls(self, parent):
|
||
"""创建帧率控制滑块"""
|
||
# 帧率说明
|
||
ttk.Label(parent, text="帧率 (1-120 FPS):").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 控制相机采集图像的频率", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
ttk.Label(parent, text="增大: 画面流畅度提高,CPU占用增加", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="减小: 画面流畅度降低,CPU占用减少", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="建议值: 30 FPS(平衡流畅度和性能)", font=('Arial', 8), foreground='green').pack(pady=2)
|
||
|
||
def on_fps_change(value):
|
||
self.current['fps'] = int(float(value))
|
||
self.update_callback('fps', int(float(value)))
|
||
|
||
fps_scale = ttk.Scale(
|
||
parent,
|
||
from_=1,
|
||
to=120,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_fps_change
|
||
)
|
||
fps_scale.set(self.defaults['fps'])
|
||
fps_scale.pack(pady=5)
|
||
|
||
self.fps_var = tk.StringVar(value=str(self.defaults['fps']))
|
||
ttk.Entry(parent, textvariable=self.fps_var, width=10).pack(pady=5)
|
||
|
||
def update_fps_from_entry():
|
||
try:
|
||
value = int(self.fps_var.get())
|
||
if 1 <= value <= 120:
|
||
fps_scale.set(value)
|
||
on_fps_change(value)
|
||
except ValueError:
|
||
pass
|
||
|
||
ttk.Button(parent, text="应用", command=update_fps_from_entry).pack(pady=5)
|
||
|
||
def _create_roi_controls(self, parent):
|
||
"""创建ROI控制输入框"""
|
||
# ROI设置说明
|
||
ttk.Label(parent, text="ROI设置:").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 设置感兴趣区域,仅处理指定区域的图像", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
ttk.Label(parent, text="减小ROI: 提高处理速度,减少CPU占用", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="增大ROI: 处理范围更广,CPU占用增加", font=('Arial', 8), foreground='gray').pack(pady=1)
|
||
ttk.Label(parent, text="建议值: 默认全画幅(0, 0, 640, 480)", font=('Arial', 8), foreground='green').pack(pady=2)
|
||
|
||
# ROI输入框
|
||
roi_frame = ttk.Frame(parent)
|
||
roi_frame.pack(fill=tk.X, pady=5)
|
||
|
||
# X坐标
|
||
ttk.Label(roi_frame, text="X:").grid(row=0, column=0, padx=5)
|
||
self.roi_x_var = tk.StringVar(value=str(self.defaults['roi_x']))
|
||
ttk.Entry(roi_frame, textvariable=self.roi_x_var, width=10).grid(row=0, column=1, padx=5)
|
||
|
||
# Y坐标
|
||
ttk.Label(roi_frame, text="Y:").grid(row=0, column=2, padx=5)
|
||
self.roi_y_var = tk.StringVar(value=str(self.defaults['roi_y']))
|
||
ttk.Entry(roi_frame, textvariable=self.roi_y_var, width=10).grid(row=0, column=3, padx=5)
|
||
|
||
# Width
|
||
ttk.Label(roi_frame, text="Width:").grid(row=1, column=0, padx=5)
|
||
self.roi_width_var = tk.StringVar(value=str(self.defaults['roi_width']))
|
||
ttk.Entry(roi_frame, textvariable=self.roi_width_var, width=10).grid(row=1, column=1, padx=5)
|
||
|
||
# Height
|
||
ttk.Label(roi_frame, text="Height:").grid(row=1, column=2, padx=5)
|
||
self.roi_height_var = tk.StringVar(value=str(self.defaults['roi_height']))
|
||
ttk.Entry(roi_frame, textvariable=self.roi_height_var, width=10).grid(row=1, column=3, padx=5)
|
||
|
||
def apply_roi():
|
||
try:
|
||
x = int(self.roi_x_var.get())
|
||
y = int(self.roi_y_var.get())
|
||
width = int(self.roi_width_var.get())
|
||
height = int(self.roi_height_var.get())
|
||
|
||
if x >= 0 and y >= 0 and width > 0 and height > 0:
|
||
self.current['roi_x'] = x
|
||
self.current['roi_y'] = y
|
||
self.current['roi_width'] = width
|
||
self.current['roi_height'] = height
|
||
self.update_callback('roi', (x, y, width, height))
|
||
except ValueError:
|
||
pass
|
||
|
||
ttk.Button(parent, text="应用ROI", command=apply_roi).pack(pady=10)
|
||
|
||
def _create_hsv_controls(self, parent):
|
||
"""创建HSV控制滑块"""
|
||
# HSV调节说明
|
||
ttk.Label(parent, text="HSV范围调节:").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 微调绿色激光的识别范围", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
|
||
# H通道说明
|
||
ttk.Label(parent, text="H通道: 控制颜色范围(绿色激光默认35-85)", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
|
||
# S通道说明
|
||
ttk.Label(parent, text="S通道: 控制饱和度范围(过滤低饱和度背景)", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
|
||
# V通道说明
|
||
ttk.Label(parent, text="V通道: 控制亮度范围(过滤暗背景)", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
ttk.Label(parent, text="建议值: H(35-85), S(80-255), V(80-255)", font=('Arial', 8), foreground='green').pack(pady=2)
|
||
|
||
# H通道
|
||
h_frame = ttk.Frame(parent)
|
||
h_frame.pack(fill=tk.X, pady=5)
|
||
|
||
ttk.Label(h_frame, text="H_low:").grid(row=0, column=0, padx=5)
|
||
self.h_low_var = tk.StringVar(value=str(self.defaults['h_low']))
|
||
ttk.Entry(h_frame, textvariable=self.h_low_var, width=5).grid(row=0, column=1, padx=5)
|
||
|
||
ttk.Label(h_frame, text="H_high:").grid(row=0, column=2, padx=5)
|
||
self.h_high_var = tk.StringVar(value=str(self.defaults['h_high']))
|
||
ttk.Entry(h_frame, textvariable=self.h_high_var, width=5).grid(row=0, column=3, padx=5)
|
||
|
||
# S通道
|
||
s_frame = ttk.Frame(parent)
|
||
s_frame.pack(fill=tk.X, pady=5)
|
||
|
||
ttk.Label(s_frame, text="S_low:").grid(row=0, column=0, padx=5)
|
||
self.s_low_var = tk.StringVar(value=str(self.defaults['s_low']))
|
||
ttk.Entry(s_frame, textvariable=self.s_low_var, width=5).grid(row=0, column=1, padx=5)
|
||
|
||
ttk.Label(s_frame, text="S_high:").grid(row=0, column=2, padx=5)
|
||
self.s_high_var = tk.StringVar(value=str(self.defaults['s_high']))
|
||
ttk.Entry(s_frame, textvariable=self.s_high_var, width=5).grid(row=0, column=3, padx=5)
|
||
|
||
# V通道
|
||
v_frame = ttk.Frame(parent)
|
||
v_frame.pack(fill=tk.X, pady=5)
|
||
|
||
ttk.Label(v_frame, text="V_low:").grid(row=0, column=0, padx=5)
|
||
self.v_low_var = tk.StringVar(value=str(self.defaults['v_low']))
|
||
ttk.Entry(v_frame, textvariable=self.v_low_var, width=5).grid(row=0, column=1, padx=5)
|
||
|
||
ttk.Label(v_frame, text="V_high:").grid(row=0, column=2, padx=5)
|
||
self.v_high_var = tk.StringVar(value=str(self.defaults['v_high']))
|
||
ttk.Entry(v_frame, textvariable=self.v_high_var, width=5).grid(row=0, column=3, padx=5)
|
||
|
||
def apply_hsv():
|
||
try:
|
||
h_low = int(self.h_low_var.get())
|
||
h_high = int(self.h_high_var.get())
|
||
s_low = int(self.s_low_var.get())
|
||
s_high = int(self.s_high_var.get())
|
||
v_low = int(self.v_low_var.get())
|
||
v_high = int(self.v_high_var.get())
|
||
|
||
# 验证范围
|
||
if all(0 <= val <= 255 for val in [h_low, h_high, s_low, s_high, v_low, v_high]):
|
||
self.current['h_low'] = h_low
|
||
self.current['h_high'] = h_high
|
||
self.current['s_low'] = s_low
|
||
self.current['s_high'] = s_high
|
||
self.current['v_low'] = v_low
|
||
self.current['v_high'] = v_high
|
||
self.update_callback('hsv', (h_low, h_high, s_low, s_high, v_low, v_high))
|
||
except ValueError:
|
||
pass
|
||
|
||
ttk.Button(parent, text="应用HSV", command=apply_hsv).pack(pady=10)
|
||
|
||
def _process_queue(self):
|
||
"""处理队列中的消息"""
|
||
try:
|
||
while not self.queue.empty():
|
||
msg = self.queue.get_nowait()
|
||
# 处理消息
|
||
if msg['type'] == 'update_value':
|
||
param = msg['param']
|
||
value = msg['value']
|
||
if param in self.current:
|
||
self.current[param] = value
|
||
except queue.Empty:
|
||
pass
|
||
finally:
|
||
self.root.after(100, self._process_queue)
|
||
|
||
def stop(self):
|
||
"""停止参数控制面板"""
|
||
if self.root:
|
||
try:
|
||
# 使用after方法在Tkinter主线程中执行销毁操作
|
||
self.root.after(0, lambda: self._safe_destroy())
|
||
# 给Tkinter一些时间来处理销毁操作
|
||
import time
|
||
time.sleep(0.1)
|
||
except Exception as e:
|
||
print(f"停止控制面板时出错: {e}")
|
||
|
||
def _safe_destroy(self):
|
||
"""安全销毁Tkinter窗口"""
|
||
if self.root:
|
||
try:
|
||
self.root.quit()
|
||
self.root.destroy()
|
||
except Exception:
|
||
pass
|
||
|
||
def _create_morph_controls(self, parent):
|
||
"""创建形态学参数控制面板"""
|
||
# 形态学参数说明
|
||
ttk.Label(parent, text="形态学参数设置:").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 控制LED点阵的聚合效果", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
|
||
# 闭运算核大小
|
||
ttk.Label(parent, text="闭运算核大小 (5-50):").pack(pady=5)
|
||
def on_kernel_size_change(value):
|
||
kernel_size = int(float(value))
|
||
open_kernel = 5 # 固定开运算核大小
|
||
self.update_callback('morph', (kernel_size, open_kernel))
|
||
|
||
kernel_scale = ttk.Scale(
|
||
parent,
|
||
from_=5,
|
||
to=50,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_kernel_size_change
|
||
)
|
||
kernel_scale.set(20) # 默认值
|
||
kernel_scale.pack(pady=5)
|
||
|
||
# 开运算核大小
|
||
ttk.Label(parent, text="开运算核大小 (3-15):").pack(pady=5)
|
||
def on_open_kernel_change(value):
|
||
open_kernel = int(float(value))
|
||
kernel_size = 20 # 固定闭运算核大小
|
||
self.update_callback('morph', (kernel_size, open_kernel))
|
||
|
||
open_kernel_scale = ttk.Scale(
|
||
parent,
|
||
from_=3,
|
||
to=15,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_open_kernel_change
|
||
)
|
||
open_kernel_scale.set(5) # 默认值
|
||
open_kernel_scale.pack(pady=5)
|
||
|
||
def _create_geometry_controls(self, parent):
|
||
"""创建几何参数控制面板"""
|
||
# 几何参数说明
|
||
ttk.Label(parent, text="几何参数设置:").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 控制灯盘的几何特征过滤", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
|
||
# 最小灯盘面积
|
||
ttk.Label(parent, text="最小灯盘面积 (100-5000):").pack(pady=5)
|
||
def on_min_area_change(value):
|
||
min_area = int(float(value))
|
||
min_leds = 10 # 默认值
|
||
circularity = 0.4 # 默认值
|
||
self.update_callback('geometry', (min_area, min_leds, circularity))
|
||
|
||
min_area_scale = ttk.Scale(
|
||
parent,
|
||
from_=100,
|
||
to=5000,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_min_area_change
|
||
)
|
||
min_area_scale.set(500) # 默认值
|
||
min_area_scale.pack(pady=5)
|
||
|
||
# 最小LED数量
|
||
ttk.Label(parent, text="最小LED数量 (5-50):").pack(pady=5)
|
||
def on_min_leds_change(value):
|
||
min_leds = int(float(value))
|
||
min_area = 500 # 默认值
|
||
circularity = 0.4 # 默认值
|
||
self.update_callback('geometry', (min_area, min_leds, circularity))
|
||
|
||
min_leds_scale = ttk.Scale(
|
||
parent,
|
||
from_=5,
|
||
to=50,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_min_leds_change
|
||
)
|
||
min_leds_scale.set(10) # 默认值
|
||
min_leds_scale.pack(pady=5)
|
||
|
||
# 圆度阈值
|
||
ttk.Label(parent, text="圆度阈值 (0.1-1.0):").pack(pady=5)
|
||
def on_circularity_change(value):
|
||
circularity = float(value)
|
||
min_area = 500 # 默认值
|
||
min_leds = 10 # 默认值
|
||
self.update_callback('geometry', (min_area, min_leds, circularity))
|
||
|
||
circularity_scale = ttk.Scale(
|
||
parent,
|
||
from_=0.1,
|
||
to=1.0,
|
||
orient=tk.HORIZONTAL,
|
||
length=300,
|
||
command=on_circularity_change
|
||
)
|
||
circularity_scale.set(0.4) # 默认值
|
||
circularity_scale.pack(pady=5)
|
||
|
||
def _create_mode_controls(self, parent):
|
||
"""创建双模式控制界面"""
|
||
# 双模式说明
|
||
ttk.Label(parent, text="双模式激光识别系统设置:").pack(pady=5)
|
||
ttk.Label(parent, text="作用: 配置单点光斑和点阵灯盘双模式检测", font=('Arial', 8), foreground='gray').pack(pady=2)
|
||
|
||
# 算法使能区
|
||
ttk.Label(parent, text="算法使能:").pack(pady=5)
|
||
|
||
enable_a_var = tk.BooleanVar(value=True)
|
||
enable_b_var = tk.BooleanVar(value=True)
|
||
|
||
def on_enable_change():
|
||
enable_a = enable_a_var.get()
|
||
enable_b = enable_b_var.get()
|
||
# 确保至少启用一项
|
||
if not enable_a and not enable_b:
|
||
enable_b_var.set(True)
|
||
enable_b = True
|
||
self.update_callback('algorithm_enable', (enable_a, enable_b))
|
||
|
||
# 启用单点光斑检测
|
||
ttk.Checkbutton(
|
||
parent,
|
||
text="启用单点光斑检测 (模式A)",
|
||
variable=enable_a_var,
|
||
command=on_enable_change
|
||
).pack(pady=2, anchor=tk.W)
|
||
|
||
# 启用点阵灯盘检测
|
||
ttk.Checkbutton(
|
||
parent,
|
||
text="启用点阵灯盘检测 (模式B)",
|
||
variable=enable_b_var,
|
||
command=on_enable_change
|
||
).pack(pady=2, anchor=tk.W)
|
||
|
||
# 工作模式选择
|
||
ttk.Label(parent, text="工作模式:").pack(pady=5)
|
||
|
||
work_mode_var = tk.StringVar(value='auto')
|
||
|
||
def on_work_mode_change():
|
||
mode = work_mode_var.get()
|
||
self.update_callback('work_mode', mode)
|
||
|
||
# 全自动仲裁
|
||
ttk.Radiobutton(
|
||
parent,
|
||
text="全自动仲裁 (系统自动选择最优结果)",
|
||
variable=work_mode_var,
|
||
value='auto',
|
||
command=on_work_mode_change
|
||
).pack(pady=2, anchor=tk.W)
|
||
|
||
# 强制单点模式
|
||
ttk.Radiobutton(
|
||
parent,
|
||
text="强制单点模式 (仅运行模式A)",
|
||
variable=work_mode_var,
|
||
value='forced_single',
|
||
command=on_work_mode_change
|
||
).pack(pady=2, anchor=tk.W)
|
||
|
||
# 强制灯盘模式
|
||
ttk.Radiobutton(
|
||
parent,
|
||
text="强制灯盘模式 (仅运行模式B)",
|
||
variable=work_mode_var,
|
||
value='forced_lamp',
|
||
command=on_work_mode_change
|
||
).pack(pady=2, anchor=tk.W)
|
||
|
||
# 双模显示
|
||
ttk.Radiobutton(
|
||
parent,
|
||
text="双模显示 (同时显示两种模式结果)",
|
||
variable=work_mode_var,
|
||
value='dual_display',
|
||
command=on_work_mode_change
|
||
).pack(pady=2, anchor=tk.W)
|
||
|
||
# 性能优化设置
|
||
ttk.Label(parent, text="性能优化:").pack(pady=5)
|
||
|
||
use_alternating_var = tk.BooleanVar(value=False)
|
||
|
||
def on_performance_change():
|
||
use_alternating = use_alternating_var.get()
|
||
self.update_callback('performance_optimization', use_alternating)
|
||
|
||
ttk.Checkbutton(
|
||
parent,
|
||
text="使用交替帧策略 (减少CPU占用)",
|
||
variable=use_alternating_var,
|
||
command=on_performance_change
|
||
).pack(pady=2, anchor=tk.W)
|
||
|
||
# 手动干预按钮
|
||
ttk.Label(parent, text="手动干预:").pack(pady=5)
|
||
|
||
button_frame = ttk.Frame(parent)
|
||
button_frame.pack(fill=tk.X, pady=5)
|
||
|
||
ttk.Button(
|
||
button_frame,
|
||
text="锁定当前模式",
|
||
command=lambda: self.update_callback('lock_mode', True)
|
||
).pack(side=tk.LEFT, padx=5)
|
||
|
||
ttk.Button(
|
||
button_frame,
|
||
text="重置仲裁",
|
||
command=lambda: self.update_callback('reset_arbiter', True)
|
||
).pack(side=tk.LEFT, padx=5)
|
||
|
||
# 状态显示区域
|
||
ttk.Label(parent, text="系统状态:").pack(pady=5)
|
||
|
||
self.status_var = tk.StringVar(value="就绪")
|
||
ttk.Label(parent, textvariable=self.status_var, font=('Arial', 10), foreground='green').pack(pady=2)
|
||
|
||
self.mode_a_status_var = tk.StringVar(value="模式A: 未检测")
|
||
ttk.Label(parent, textvariable=self.mode_a_status_var, font=('Arial', 9)).pack(pady=1, anchor=tk.W)
|
||
|
||
self.mode_b_status_var = tk.StringVar(value="模式B: 未检测")
|
||
ttk.Label(parent, textvariable=self.mode_b_status_var, font=('Arial', 9)).pack(pady=1, anchor=tk.W)
|
||
|
||
self.decision_var = tk.StringVar(value="决策: 等待输入")
|
||
ttk.Label(parent, textvariable=self.decision_var, font=('Arial', 9), foreground='blue').pack(pady=1, anchor=tk.W)
|