采集卡bug修复
This commit is contained in:
@@ -200,26 +200,37 @@ class ConfigGUI:
|
|||||||
def scan_cameras(self, max_index: int = 10):
|
def scan_cameras(self, max_index: int = 10):
|
||||||
"""扫描系统可用的采集卡索引,并填充下拉框"""
|
"""扫描系统可用的采集卡索引,并填充下拉框"""
|
||||||
import warnings
|
import warnings
|
||||||
|
import sys
|
||||||
|
import io
|
||||||
found = []
|
found = []
|
||||||
|
|
||||||
# 临时设置OpenCV日志级别(兼容不同版本)
|
# 临时设置OpenCV日志级别(兼容不同版本)
|
||||||
import os
|
import os
|
||||||
old_level = os.environ.get('OPENCV_LOG_LEVEL', '')
|
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不同)
|
# 尝试设置日志级别(不同版本的OpenCV API不同)
|
||||||
try:
|
try:
|
||||||
if hasattr(cv2, 'setLogLevel'):
|
if hasattr(cv2, 'setLogLevel'):
|
||||||
# OpenCV 4.x
|
# 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)
|
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
|
||||||
elif hasattr(cv2, 'utils'):
|
elif hasattr(cv2, 'utils'):
|
||||||
# 某些版本的OpenCV
|
cv2.utils.setLogLevel(0) # 0=SILENT/ERROR级别
|
||||||
cv2.utils.setLogLevel(0) # 0=ERROR级别
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # 如果设置失败,继续执行
|
pass
|
||||||
|
|
||||||
|
# 重定向stderr来捕获OpenCV的错误输出
|
||||||
|
old_stderr = sys.stderr
|
||||||
|
suppressed_output = io.StringIO()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# 暂时重定向stderr以抑制OpenCV的错误消息
|
||||||
|
sys.stderr = suppressed_output
|
||||||
|
|
||||||
for idx in range(max_index + 1):
|
for idx in range(max_index + 1):
|
||||||
cap = None
|
cap = None
|
||||||
try:
|
try:
|
||||||
@@ -245,11 +256,14 @@ class ConfigGUI:
|
|||||||
pass
|
pass
|
||||||
continue
|
continue
|
||||||
finally:
|
finally:
|
||||||
|
# 恢复stderr
|
||||||
|
sys.stderr = old_stderr
|
||||||
# 恢复原来的日志级别
|
# 恢复原来的日志级别
|
||||||
if old_level:
|
if old_level:
|
||||||
os.environ['OPENCV_LOG_LEVEL'] = old_level
|
os.environ['OPENCV_LOG_LEVEL'] = old_level
|
||||||
else:
|
else:
|
||||||
os.environ.pop('OPENCV_LOG_LEVEL', None)
|
os.environ.pop('OPENCV_LOG_LEVEL', None)
|
||||||
|
os.environ.pop('OPENCV_IO_ENABLE_OPENEXR', None)
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
found = ["0"] # 至少给一个默认项,避免为空
|
found = ["0"] # 至少给一个默认项,避免为空
|
||||||
@@ -320,29 +334,46 @@ class ConfigGUI:
|
|||||||
def save_config(self):
|
def save_config(self):
|
||||||
"""保存当前编辑的配置"""
|
"""保存当前编辑的配置"""
|
||||||
# 检查索引有效性
|
# 检查索引有效性
|
||||||
if self.selected_index >= len(config_manager.config['groups']):
|
if self.selected_index < 0 or self.selected_index >= len(config_manager.config['groups']):
|
||||||
messagebox.showerror("错误", f"配置组索引 {self.selected_index} 无效")
|
messagebox.showerror("错误", f"请先选择一个有效的配置组")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 保存当前组的配置
|
# 保存当前组的配置
|
||||||
group = config_manager.get_group_by_index(self.selected_index)
|
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():
|
for key, var in self.config_vars.items():
|
||||||
if not key.startswith('display_'):
|
if not key.startswith('display_'):
|
||||||
try:
|
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']:
|
if key in ['camera_index', 'camera_width', 'camera_height', 'serial_baudrate', 'move_velocity']:
|
||||||
try:
|
try:
|
||||||
value = int(value_str) if value_str else group.get(key, 0)
|
# 如果为空,使用当前值或默认值
|
||||||
except:
|
if value_str:
|
||||||
value = group.get(key, 0)
|
value = int(value_str)
|
||||||
else:
|
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, '')
|
value = value_str if value_str else group.get(key, '')
|
||||||
|
|
||||||
group[key] = value
|
group[key] = value
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"保存字段 {key} 时出错: {e}")
|
print(f"保存字段 {key} 时出错: {e}")
|
||||||
pass
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
# 保存失败时使用当前值
|
||||||
|
if key in group:
|
||||||
|
pass # 保持原值不变
|
||||||
|
|
||||||
# 保存预览配置
|
# 保存预览配置
|
||||||
display = config_manager.config.get('display', {})
|
display = config_manager.config.get('display', {})
|
||||||
@@ -384,28 +415,43 @@ class ConfigGUI:
|
|||||||
def save_config_silent(self):
|
def save_config_silent(self):
|
||||||
"""静默保存配置(不显示消息框)"""
|
"""静默保存配置(不显示消息框)"""
|
||||||
# 保存当前组的配置
|
# 保存当前组的配置
|
||||||
if self.selected_index >= len(config_manager.config['groups']):
|
if self.selected_index < 0 or self.selected_index >= len(config_manager.config['groups']):
|
||||||
print(f"⚠️ 选中索引 {self.selected_index} 超出范围")
|
print(f"⚠️ 选中索引 {self.selected_index} 无效")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
group = config_manager.get_group_by_index(self.selected_index)
|
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():
|
for key, var in self.config_vars.items():
|
||||||
if not key.startswith('display_'):
|
if not key.startswith('display_'):
|
||||||
try:
|
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']:
|
if key in ['camera_index', 'camera_width', 'camera_height', 'serial_baudrate', 'move_velocity']:
|
||||||
try:
|
try:
|
||||||
value = int(value_str) if value_str else group.get(key, 0)
|
# 如果为空,使用当前值或默认值
|
||||||
except:
|
if value_str:
|
||||||
value = group.get(key, 0)
|
value = int(value_str)
|
||||||
else:
|
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, '')
|
value = value_str if value_str else group.get(key, '')
|
||||||
|
|
||||||
group[key] = value
|
group[key] = value
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"保存字段 {key} 时出错: {e}")
|
print(f"保存字段 {key} 时出错: {e}")
|
||||||
pass
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
# 保存失败时保持原值不变
|
||||||
|
|
||||||
# 保存预览配置
|
# 保存预览配置
|
||||||
display = config_manager.config.get('display', {})
|
display = config_manager.config.get('display', {})
|
||||||
|
|||||||
26
preview.py
26
preview.py
@@ -9,16 +9,22 @@ import os
|
|||||||
from config import config_manager
|
from config import config_manager
|
||||||
|
|
||||||
# 抑制OpenCV的警告信息(兼容不同版本)
|
# 抑制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:
|
try:
|
||||||
if hasattr(cv2, 'setLogLevel'):
|
if hasattr(cv2, 'setLogLevel'):
|
||||||
# OpenCV 4.x
|
if hasattr(cv2, 'LOG_LEVEL_SILENT'):
|
||||||
if hasattr(cv2, 'LOG_LEVEL_ERROR'):
|
cv2.setLogLevel(cv2.LOG_LEVEL_SILENT)
|
||||||
|
elif hasattr(cv2, 'LOG_LEVEL_ERROR'):
|
||||||
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
|
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
|
||||||
elif hasattr(cv2, 'utils'):
|
elif hasattr(cv2, 'utils'):
|
||||||
cv2.utils.setLogLevel(0) # 0=ERROR级别
|
cv2.utils.setLogLevel(0)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # 如果设置失败,继续执行
|
pass
|
||||||
|
|
||||||
class PreviewWindow:
|
class PreviewWindow:
|
||||||
"""采集卡预览窗口"""
|
"""采集卡预览窗口"""
|
||||||
@@ -40,6 +46,13 @@ class PreviewWindow:
|
|||||||
print("⚠️ 没有活动的配置组,将尝试加载所有配置组")
|
print("⚠️ 没有活动的配置组,将尝试加载所有配置组")
|
||||||
active_groups = self.config['groups']
|
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):
|
for i, group in enumerate(active_groups):
|
||||||
try:
|
try:
|
||||||
cam_idx = group['camera_index']
|
cam_idx = group['camera_index']
|
||||||
@@ -99,6 +112,9 @@ class PreviewWindow:
|
|||||||
print(f" ❌ 采集卡 {group.get('camera_index', '?')} 初始化失败: {e}")
|
print(f" ❌ 采集卡 {group.get('camera_index', '?')} 初始化失败: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
# 恢复stderr
|
||||||
|
sys.stderr = old_stderr
|
||||||
|
|
||||||
if loaded_count == 0:
|
if loaded_count == 0:
|
||||||
print("⚠️ 警告:没有成功加载任何采集卡!")
|
print("⚠️ 警告:没有成功加载任何采集卡!")
|
||||||
|
|||||||
@@ -45,16 +45,21 @@ import warnings
|
|||||||
|
|
||||||
# 抑制OpenCV的警告信息(兼容不同版本)
|
# 抑制OpenCV的警告信息(兼容不同版本)
|
||||||
import os
|
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:
|
try:
|
||||||
if hasattr(cv2, 'setLogLevel'):
|
if hasattr(cv2, 'setLogLevel'):
|
||||||
# OpenCV 4.x
|
if hasattr(cv2, 'LOG_LEVEL_SILENT'):
|
||||||
if hasattr(cv2, 'LOG_LEVEL_ERROR'):
|
cv2.setLogLevel(cv2.LOG_LEVEL_SILENT)
|
||||||
|
elif hasattr(cv2, 'LOG_LEVEL_ERROR'):
|
||||||
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
|
cv2.setLogLevel(cv2.LOG_LEVEL_ERROR)
|
||||||
elif hasattr(cv2, 'utils'):
|
elif hasattr(cv2, 'utils'):
|
||||||
cv2.utils.setLogLevel(0) # 0=ERROR级别
|
cv2.utils.setLogLevel(0)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass # 如果设置失败,继续执行
|
pass
|
||||||
|
|
||||||
class GetImage:
|
class GetImage:
|
||||||
def __init__(self, cam_index=0, width=1920, height=1080):
|
def __init__(self, cam_index=0, width=1920, height=1080):
|
||||||
@@ -71,6 +76,13 @@ class GetImage:
|
|||||||
(cam_index, None), # 默认后端
|
(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:
|
for idx, backend in backends_to_try:
|
||||||
try:
|
try:
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
@@ -97,6 +109,9 @@ class GetImage:
|
|||||||
pass
|
pass
|
||||||
self.cap = None
|
self.cap = None
|
||||||
continue
|
continue
|
||||||
|
finally:
|
||||||
|
# 恢复stderr
|
||||||
|
sys.stderr = old_stderr
|
||||||
|
|
||||||
if self.cap is None or not self.cap.isOpened():
|
if self.cap is None or not self.cap.isOpened():
|
||||||
print(f"❌ 无法打开采集卡 {cam_index}")
|
print(f"❌ 无法打开采集卡 {cam_index}")
|
||||||
|
|||||||
Reference in New Issue
Block a user