采集卡bug修复

This commit is contained in:
Ray
2025-10-29 16:28:06 +08:00
parent f0fc28d827
commit 7af3e2353a
3 changed files with 211 additions and 134 deletions

View File

@@ -200,26 +200,37 @@ class ConfigGUI:
def scan_cameras(self, max_index: int = 10):
"""扫描系统可用的采集卡索引,并填充下拉框"""
import warnings
import sys
import io
found = []
# 临时设置OpenCV日志级别兼容不同版本
import os
old_level = os.environ.get('OPENCV_LOG_LEVEL', '')
os.environ['OPENCV_LOG_LEVEL'] = 'ERROR'
os.environ['OPENCV_LOG_LEVEL'] = 'SILENT' # 尝试更严格的级别
os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '0'
# 尝试设置日志级别不同版本的OpenCV API不同
try:
if hasattr(cv2, 'setLogLevel'):
# OpenCV 4.x
if hasattr(cv2, 'LOG_LEVEL_ERROR'):
if hasattr(cv2, 'LOG_LEVEL_SILENT'):
cv2.setLogLevel(cv2.LOG_LEVEL_SILENT)
elif hasattr(cv2, 'LOG_LEVEL_ERROR'):
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
elif hasattr(cv2, 'utils'):
# 某些版本的OpenCV
cv2.utils.setLogLevel(0) # 0=ERROR级别
cv2.utils.setLogLevel(0) # 0=SILENT/ERROR级别
except Exception:
pass # 如果设置失败,继续执行
pass
# 重定向stderr来捕获OpenCV的错误输出
old_stderr = sys.stderr
suppressed_output = io.StringIO()
try:
# 暂时重定向stderr以抑制OpenCV的错误消息
sys.stderr = suppressed_output
for idx in range(max_index + 1):
cap = None
try:
@@ -245,11 +256,14 @@ class ConfigGUI:
pass
continue
finally:
# 恢复stderr
sys.stderr = old_stderr
# 恢复原来的日志级别
if old_level:
os.environ['OPENCV_LOG_LEVEL'] = old_level
else:
os.environ.pop('OPENCV_LOG_LEVEL', None)
os.environ.pop('OPENCV_IO_ENABLE_OPENEXR', None)
if not found:
found = ["0"] # 至少给一个默认项,避免为空
@@ -320,29 +334,46 @@ class ConfigGUI:
def save_config(self):
"""保存当前编辑的配置"""
# 检查索引有效性
if self.selected_index >= len(config_manager.config['groups']):
messagebox.showerror("错误", f"配置组索引 {self.selected_index} 无效")
if self.selected_index < 0 or self.selected_index >= len(config_manager.config['groups']):
messagebox.showerror("错误", f"请先选择一个有效的配置组")
return False
# 保存当前组的配置
group = config_manager.get_group_by_index(self.selected_index)
if group:
if not group:
messagebox.showerror("错误", f"配置组不存在")
return False
for key, var in self.config_vars.items():
if not key.startswith('display_'):
try:
value_str = var.get().strip()
value_str = var.get().strip() if var.get() else ""
# 特殊处理:某些字段需要转换为整数
if key in ['camera_index', 'camera_width', 'camera_height', 'serial_baudrate', 'move_velocity']:
try:
value = int(value_str) if value_str else group.get(key, 0)
except:
value = group.get(key, 0)
# 如果为空,使用当前值或默认值
if value_str:
value = int(value_str)
else:
# 如果下拉框为空,尝试从当前配置获取
value = group.get(key, 0)
except ValueError:
# 转换失败,使用当前值
value = group.get(key, 0)
print(f"⚠️ 字段 {key} 的值 '{value_str}' 无效,使用当前值 {value}")
else:
# 字符串字段
value = value_str if value_str else group.get(key, '')
group[key] = value
except Exception as e:
print(f"保存字段 {key} 时出错: {e}")
pass
import traceback
traceback.print_exc()
# 保存失败时使用当前值
if key in group:
pass # 保持原值不变
# 保存预览配置
display = config_manager.config.get('display', {})
@@ -384,28 +415,43 @@ class ConfigGUI:
def save_config_silent(self):
"""静默保存配置(不显示消息框)"""
# 保存当前组的配置
if self.selected_index >= len(config_manager.config['groups']):
print(f"⚠️ 选中索引 {self.selected_index} 超出范围")
if self.selected_index < 0 or self.selected_index >= len(config_manager.config['groups']):
print(f"⚠️ 选中索引 {self.selected_index} 无效")
return False
group = config_manager.get_group_by_index(self.selected_index)
if group:
if not group:
print(f"⚠️ 配置组不存在")
return False
for key, var in self.config_vars.items():
if not key.startswith('display_'):
try:
value_str = var.get().strip()
value_str = var.get().strip() if var.get() else ""
# 特殊处理:某些字段需要转换为整数
if key in ['camera_index', 'camera_width', 'camera_height', 'serial_baudrate', 'move_velocity']:
try:
value = int(value_str) if value_str else group.get(key, 0)
except:
value = group.get(key, 0)
# 如果为空,使用当前值或默认值
if value_str:
value = int(value_str)
else:
# 如果下拉框为空,尝试从当前配置获取
value = group.get(key, 0)
except ValueError:
# 转换失败,使用当前值
value = group.get(key, 0)
print(f"⚠️ 字段 {key} 的值 '{value_str}' 无效,使用当前值 {value}")
else:
# 字符串字段
value = value_str if value_str else group.get(key, '')
group[key] = value
except Exception as e:
print(f"保存字段 {key} 时出错: {e}")
pass
import traceback
traceback.print_exc()
# 保存失败时保持原值不变
# 保存预览配置
display = config_manager.config.get('display', {})

View File

@@ -9,16 +9,22 @@ import os
from config import config_manager
# 抑制OpenCV的警告信息兼容不同版本
os.environ['OPENCV_LOG_LEVEL'] = 'ERROR'
import sys
import io
os.environ['OPENCV_LOG_LEVEL'] = 'SILENT'
os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '0'
try:
if hasattr(cv2, 'setLogLevel'):
# OpenCV 4.x
if hasattr(cv2, 'LOG_LEVEL_ERROR'):
if hasattr(cv2, 'LOG_LEVEL_SILENT'):
cv2.setLogLevel(cv2.LOG_LEVEL_SILENT)
elif hasattr(cv2, 'LOG_LEVEL_ERROR'):
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
elif hasattr(cv2, 'utils'):
cv2.utils.setLogLevel(0) # 0=ERROR级别
cv2.utils.setLogLevel(0)
except Exception:
pass # 如果设置失败,继续执行
pass
class PreviewWindow:
"""采集卡预览窗口"""
@@ -40,6 +46,13 @@ class PreviewWindow:
print("⚠️ 没有活动的配置组,将尝试加载所有配置组")
active_groups = self.config['groups']
# 重定向stderr来抑制OpenCV的错误输出
old_stderr = sys.stderr
suppressed_output = io.StringIO()
try:
sys.stderr = suppressed_output
for i, group in enumerate(active_groups):
try:
cam_idx = group['camera_index']
@@ -99,6 +112,9 @@ class PreviewWindow:
print(f" ❌ 采集卡 {group.get('camera_index', '?')} 初始化失败: {e}")
import traceback
traceback.print_exc()
finally:
# 恢复stderr
sys.stderr = old_stderr
if loaded_count == 0:
print("⚠️ 警告:没有成功加载任何采集卡!")

View File

@@ -45,16 +45,21 @@ import warnings
# 抑制OpenCV的警告信息兼容不同版本
import os
os.environ['OPENCV_LOG_LEVEL'] = 'ERROR'
import sys
import io
os.environ['OPENCV_LOG_LEVEL'] = 'SILENT'
os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '0'
try:
if hasattr(cv2, 'setLogLevel'):
# OpenCV 4.x
if hasattr(cv2, 'LOG_LEVEL_ERROR'):
if hasattr(cv2, 'LOG_LEVEL_SILENT'):
cv2.setLogLevel(cv2.LOG_LEVEL_SILENT)
elif hasattr(cv2, 'LOG_LEVEL_ERROR'):
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
elif hasattr(cv2, 'utils'):
cv2.utils.setLogLevel(0) # 0=ERROR级别
cv2.utils.setLogLevel(0)
except Exception:
pass # 如果设置失败,继续执行
pass
class GetImage:
def __init__(self, cam_index=0, width=1920, height=1080):
@@ -71,6 +76,13 @@ class GetImage:
(cam_index, None), # 默认后端
]
# 重定向stderr来抑制OpenCV的错误输出
old_stderr = sys.stderr
suppressed_output = io.StringIO()
try:
sys.stderr = suppressed_output
for idx, backend in backends_to_try:
try:
with warnings.catch_warnings():
@@ -97,6 +109,9 @@ class GetImage:
pass
self.cap = None
continue
finally:
# 恢复stderr
sys.stderr = old_stderr
if self.cap is None or not self.cap.isOpened():
print(f"❌ 无法打开采集卡 {cam_index}")