Commit 1e0485c8 by Yuhaibo

feat: 完成模型训练流程优化和结果格式转换

- 优化了模型保存流程,训练完成的模型直接保存在detection_model目录,避免重复移动操作
- 实现了检测结果格式转换功能,确保新旧格式兼容性,支持多区域液位检测数据转换
- 增强了页面同步机制,训练完成后自动刷新模型集管理、模型测试和训练页面的模型列表
- 添加了自动生成模型描述文件功能,包含模型基础信息、技术特性和使用说明
- 改
parents c3d7c4a2 ed53cf16
epoch,time,train/box_loss,train/seg_loss,train/cls_loss,train/dfl_loss,metrics/precision(B),metrics/recall(B),metrics/mAP50(B),metrics/mAP50-95(B),metrics/precision(M),metrics/recall(M),metrics/mAP50(M),metrics/mAP50-95(M),val/box_loss,val/seg_loss,val/cls_loss,val/dfl_loss,lr/pg0,lr/pg1,lr/pg2
1,928.936,0.83523,1.3075,0.46573,1.05864,0.87981,0.85416,0.91902,0.70839,0.8784,0.85371,0.91642,0.68473,0.89994,1.39776,0.62225,1.11979,0.0700103,0.00333218,0.00333218
2,1745.63,0.87012,1.35322,0.51061,1.07759,0.92936,0.89401,0.95387,0.72198,0.93047,0.89384,0.9537,0.70371,0.88167,1.35963,0.54179,1.08754,0.0393505,0.00600563,0.00600563
3,2568.99,0.9039,1.39713,0.56215,1.10027,0.92337,0.89082,0.95288,0.72543,0.92112,0.89467,0.95309,0.71126,0.88062,1.34921,0.54834,1.08423,0.00803057,0.00801908,0.00801908
......@@ -705,7 +705,7 @@ class ModelSetHandler:
if model_path.endswith('.pt'):
model_type = "PyTorch (YOLOv5/v8)"
elif model_path.endswith('.dat'):
model_type = "加密模型 (.dat)"
model_type = ".dat"
else:
model_type = "未知格式"
......
......@@ -136,6 +136,7 @@ class ModelTestThread(QThread):
# 读取标注数据
self.progress_updated.emit(45, "正在读取标注数据...")
import yaml
with open(annotation_file, 'r', encoding='utf-8') as f:
try:
annotation_data = yaml.safe_load(f)
......@@ -158,6 +159,7 @@ class ModelTestThread(QThread):
# 配置标注数据
self.progress_updated.emit(70, "正在配置检测参数...")
<<<<<<< HEAD
# 提取标注数据
test_model_data = annotation_data.get('test_model', {})
boxes = test_model_data.get('boxes', [])
......@@ -172,6 +174,14 @@ class ModelTestThread(QThread):
actual_heights = test_model_data.get('actual_heights', [20.0] * len(boxes))
# 配置检测引擎
=======
# 从annotation_data中提取配置参数
boxes = annotation_data.get('boxes', [])
fixed_bottoms = annotation_data.get('fixed_bottoms', [])
fixed_tops = annotation_data.get('fixed_tops', [])
actual_heights = annotation_data.get('actual_heights', [20.0] * len(boxes))
>>>>>>> ed53cf16e35be94b62ee54dddc99b5e7e2dbe200
detection_engine.configure(boxes, fixed_bottoms, fixed_tops, actual_heights)
# 执行检测
......@@ -182,10 +192,14 @@ class ModelTestThread(QThread):
if detection_result is None or not detection_result.get('success', False):
raise RuntimeError("检测结果为空或检测失败")
self._detection_result = detection_result
# 转换检测结果格式以兼容现有代码
converted_result = self._convertDetectionResult(detection_result)
self._detection_result = converted_result
self.progress_updated.emit(90, "正在保存测试结果...")
self._saveImageTestResults(model_path, test_frame, detection_result, annotation_file)
# 通过handler调用保存方法
handler = self.test_params['handler']
handler._saveImageTestResults(model_path, test_frame, converted_result, annotation_file)
except Exception as e:
raise
......@@ -212,6 +226,59 @@ class ModelTestThread(QThread):
def get_detection_result(self):
"""获取检测结果"""
return self._detection_result
def _convertDetectionResult(self, detection_result):
"""
转换检测结果格式以兼容现有代码
Args:
detection_result: detect方法返回的结果格式
{
'liquid_line_positions': {
0: {'y': y坐标, 'height_mm': 高度毫米, 'height_px': 高度像素},
1: {...},
...
},
'success': bool
}
Returns:
dict: 转换后的结果格式,包含 liquid_level_mm 字段
"""
try:
if not detection_result or not detection_result.get('success', False):
return {'liquid_level_mm': 0.0, 'success': False}
liquid_positions = detection_result.get('liquid_line_positions', {})
if not liquid_positions:
return {'liquid_level_mm': 0.0, 'success': False}
# 取第一个检测区域的液位高度
first_position = next(iter(liquid_positions.values()))
liquid_level_mm = first_position.get('height_mm', 0.0)
# 构建兼容格式的结果
converted_result = {
'liquid_level_mm': liquid_level_mm,
'success': True,
'areas': {}
}
# 转换所有区域的数据
for idx, position_data in liquid_positions.items():
area_name = f'区域{idx + 1}'
converted_result['areas'][area_name] = {
'liquid_height': position_data.get('height_mm', 0.0),
'y_position': position_data.get('y', 0),
'height_px': position_data.get('height_px', 0)
}
return converted_result
except Exception as e:
print(f"[结果转换] 转换检测结果失败: {e}")
return {'liquid_level_mm': 0.0, 'success': False}
class ModelTestHandler:
......@@ -1793,7 +1860,6 @@ class ModelTestHandler:
<h4 style="margin: 0 0 10px 0; color: #333333; font-size: 16px; font-weight: 500;">检测结果视频</h4>
<video width="100%" height="auto" controls style="border: none; border-radius: 6px; max-height: 400px; background: #f8f9fa;">
<source src="file:///{video_path_formatted}" type="video/mp4">
您的浏览器不支持视频播放
</video>
</div>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -941,8 +941,8 @@ class BackgroundStyleManager:
"""全局背景颜色管理器"""
# 全局背景颜色配置
GLOBAL_BACKGROUND_COLOR = "white" # 统一白色背景
GLOBAL_BACKGROUND_STYLE = "background-color: white;"
GLOBAL_BACKGROUND_COLOR = "#f8f9fa" # 统一浅灰色背景,消除纯白色
GLOBAL_BACKGROUND_STYLE = "background-color: #f8f9fa;"
@classmethod
def applyToWidget(cls, widget):
......@@ -1208,6 +1208,112 @@ def setMenuBarHoverColor(color):
# ============================================================================
# 曲线显示样式管理器 (Curve Display Style Manager)
# ============================================================================
class CurveDisplayStyleManager:
"""曲线显示样式管理器"""
# 统一的颜色配置
BACKGROUND_COLOR = "#f8f9fa" # 统一背景色
PLOT_BACKGROUND_COLOR = "#f8f9fa" # 图表背景色
CONTAINER_BACKGROUND_COLOR = "#ffffff" # 容器背景色
BORDER_COLOR = "#dee2e6" # 边框颜色
TEXT_COLOR = "#333333" # 文本颜色
# 图表尺寸配置
CHART_WIDTH = 600
CHART_HEIGHT = 350
CHART_DPI = 100
@classmethod
def getBackgroundColor(cls):
"""获取统一背景色"""
return cls.BACKGROUND_COLOR
@classmethod
def getPlotBackgroundColor(cls):
"""获取图表背景色"""
return cls.PLOT_BACKGROUND_COLOR
@classmethod
def getContainerBackgroundColor(cls):
"""获取容器背景色"""
return cls.CONTAINER_BACKGROUND_COLOR
@classmethod
def getBorderColor(cls):
"""获取边框颜色"""
return cls.BORDER_COLOR
@classmethod
def getTextColor(cls):
"""获取文本颜色"""
return cls.TEXT_COLOR
@classmethod
def getChartSize(cls):
"""获取图表尺寸"""
return cls.CHART_WIDTH, cls.CHART_HEIGHT
@classmethod
def getChartDPI(cls):
"""获取图表DPI"""
return cls.CHART_DPI
@classmethod
def generateCurveHTML(cls, curve_image_path, stats_html=""):
"""生成统一样式的曲线HTML"""
return f"""
<div style="font-family: 'Microsoft YaHei', 'SimHei', Arial, sans-serif; padding: 20px; background: {cls.BACKGROUND_COLOR}; color: {cls.TEXT_COLOR};">
<div style="margin-bottom: 20px;">
<h3 style="margin: 0 0 15px 0; color: {cls.TEXT_COLOR}; font-size: 18px; font-weight: 600;">液位检测曲线结果</h3>
</div>
{stats_html}
<div style="text-align: center; margin-bottom: 15px; background: {cls.CONTAINER_BACKGROUND_COLOR}; padding: 8px; border-radius: 6px; border: 1px solid {cls.BORDER_COLOR};">
<img src="file:///{curve_image_path.replace(chr(92), '/')}" style="max-width: 100%; height: auto; border-radius: 4px;">
</div>
<div style="padding: 10px; background: {cls.CONTAINER_BACKGROUND_COLOR}; border: 1px solid {cls.BORDER_COLOR}; border-radius: 5px; font-size: 12px; color: #666;">
<p style="margin: 0;"><strong>说明:</strong> 曲线显示了液位检测的结果变化趋势。X轴表示帧序号,Y轴表示液位高度(毫米)。</p>
</div>
</div>
"""
@classmethod
def setBackgroundColor(cls, color):
"""设置背景颜色"""
cls.BACKGROUND_COLOR = color
cls.PLOT_BACKGROUND_COLOR = color
@classmethod
def setChartSize(cls, width, height):
"""设置图表尺寸"""
cls.CHART_WIDTH = width
cls.CHART_HEIGHT = height
# 曲线显示样式管理器便捷函数
def getCurveBackgroundColor():
"""获取曲线背景色的便捷函数"""
return CurveDisplayStyleManager.getBackgroundColor()
def getCurvePlotBackgroundColor():
"""获取曲线图表背景色的便捷函数"""
return CurveDisplayStyleManager.getPlotBackgroundColor()
def getCurveChartSize():
"""获取曲线图表尺寸的便捷函数"""
return CurveDisplayStyleManager.getChartSize()
def generateCurveHTML(curve_image_path, stats_html=""):
"""生成曲线HTML的便捷函数"""
return CurveDisplayStyleManager.generateCurveHTML(curve_image_path, stats_html)
# ============================================================================
# 测试代码
# ============================================================================
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment