浏览代码

feat(performance_analyzer): 添加时间统计信息到性能报告

在性能分析报告中新增时间统计信息,包括采集开始时间、结束时间和持续时长,以便更好地跟踪和分析检测任务的执行情况。
Hannnk 3 周之前
父节点
当前提交
f6cfcb641e

+ 5 - 0
Output/output_20250329_100448_results/performance_stats.txt

@@ -1,6 +1,11 @@
 检测性能统计报告
 检测性能统计报告
 ==================================================
 ==================================================
 
 
+时间统计信息:
+采集开始时间: 2025-03-29 10:04:48
+采集结束时间: 2025-03-29 10:26:52
+持续时长: 1324秒
+
 详细统计信息:
 详细统计信息:
 总样本数(CSV中唯一图像数): 32850
 总样本数(CSV中唯一图像数): 32850
 检测到的目标总数: 444
 检测到的目标总数: 444

+ 5 - 0
Output/output_20250329_111006_results/performance_stats.txt

@@ -1,6 +1,11 @@
 检测性能统计报告
 检测性能统计报告
 ==================================================
 ==================================================
 
 
+时间统计信息:
+采集开始时间: 2025-03-29 11:10:06
+采集结束时间: 2025-03-29 11:16:01
+持续时长: 355秒
+
 详细统计信息:
 详细统计信息:
 总样本数(CSV中唯一图像数): 8136
 总样本数(CSV中唯一图像数): 8136
 检测到的目标总数: 109
 检测到的目标总数: 109

+ 5 - 0
Output/output_20250329_130338_results/performance_stats.txt

@@ -1,6 +1,11 @@
 检测性能统计报告
 检测性能统计报告
 ==================================================
 ==================================================
 
 
+时间统计信息:
+采集开始时间: 2025-03-29 13:03:38
+采集结束时间: 2025-03-29 13:27:23
+持续时长: 1425秒
+
 详细统计信息:
 详细统计信息:
 总样本数(CSV中唯一图像数): 34562
 总样本数(CSV中唯一图像数): 34562
 检测到的目标总数: 644
 检测到的目标总数: 644

+ 93 - 0
Output/output_20250329_133810_results/performance_stats.txt

@@ -1,6 +1,11 @@
 检测性能统计报告
 检测性能统计报告
 ==================================================
 ==================================================
 
 
+时间统计信息:
+采集开始时间: 2025-03-29 13:38:10
+采集结束时间: 2025-03-29 14:02:17
+持续时长: 1447秒
+
 详细统计信息:
 详细统计信息:
 总样本数(CSV中唯一图像数): 36540
 总样本数(CSV中唯一图像数): 36540
 检测到的目标总数: 347
 检测到的目标总数: 347
@@ -14,3 +19,91 @@
 召回率: 1.0000
 召回率: 1.0000
 F1分数: 0.4847
 F1分数: 0.4847
 误报率(虚警率): 0.0065
 误报率(虚警率): 0.0065
+
+镜头统计信息:
+------------------------------
+镜头 cam_00:
+  总报警数: 16
+  误报数: 0
+  误报率: 0.0000
+------------------------------
+镜头 cam_01:
+  总报警数: 47
+  误报数: 44
+  误报率: 0.9362
+------------------------------
+镜头 cam_02:
+  总报警数: 8
+  误报数: 8
+  误报率: 1.0000
+------------------------------
+镜头 cam_03:
+  总报警数: 11
+  误报数: 9
+  误报率: 0.8182
+------------------------------
+镜头 cam_04:
+  总报警数: 34
+  误报数: 30
+  误报率: 0.8824
+------------------------------
+镜头 cam_05:
+  总报警数: 89
+  误报数: 78
+  误报率: 0.8764
+------------------------------
+镜头 cam_06:
+  总报警数: 50
+  误报数: 43
+  误报率: 0.8600
+------------------------------
+镜头 cam_07:
+  总报警数: 28
+  误报数: 4
+  误报率: 0.1429
+------------------------------
+镜头 cam_08:
+  总报警数: 7
+  误报数: 0
+  误报率: 0.0000
+------------------------------
+镜头 cam_09:
+  总报警数: 7
+  误报数: 1
+  误报率: 0.1429
+------------------------------
+镜头 cam_10:
+  总报警数: 10
+  误报数: 7
+  误报率: 0.7000
+------------------------------
+镜头 cam_11:
+  总报警数: 10
+  误报数: 0
+  误报率: 0.0000
+------------------------------
+镜头 cam_13:
+  总报警数: 8
+  误报数: 0
+  误报率: 0.0000
+------------------------------
+镜头 cam_14:
+  总报警数: 16
+  误报数: 12
+  误报率: 0.7500
+------------------------------
+镜头 cam_15:
+  总报警数: 1
+  误报数: 0
+  误报率: 0.0000
+------------------------------
+镜头 cam_16:
+  总报警数: 4
+  误报数: 0
+  误报率: 0.0000
+------------------------------
+镜头 cam_17:
+  总报警数: 1
+  误报数: 0
+  误报率: 0.0000
+------------------------------

+ 5 - 0
Output/output_20250329_140816_results/performance_stats.txt

@@ -1,6 +1,11 @@
 检测性能统计报告
 检测性能统计报告
 ==================================================
 ==================================================
 
 
+时间统计信息:
+采集开始时间: 2025-03-29 14:08:16
+采集结束时间: 2025-03-29 14:28:47
+持续时长: 1231秒
+
 详细统计信息:
 详细统计信息:
 总样本数(CSV中唯一图像数): 31086
 总样本数(CSV中唯一图像数): 31086
 检测到的目标总数: 361
 检测到的目标总数: 361

+ 83 - 1
src/analysis/performance_analyzer.py

@@ -3,6 +3,7 @@ import pandas as pd
 import numpy as np
 import numpy as np
 from typing import List, Dict
 from typing import List, Dict
 import shutil
 import shutil
+from datetime import datetime
 
 
 class PerformanceAnalyzer:
 class PerformanceAnalyzer:
     def __init__(self, result_dir: str):
     def __init__(self, result_dir: str):
@@ -14,11 +15,86 @@ class PerformanceAnalyzer:
         # 确保目录存在
         # 确保目录存在
         os.makedirs(self.true_targets_dir, exist_ok=True)
         os.makedirs(self.true_targets_dir, exist_ok=True)
         
         
+    def _extract_timestamp(self, filename: str) -> str:
+        """从文件名中提取时间戳"""
+        try:
+            import re
+            
+            # 方法1:查找连续的14位数字(不依赖分隔符)
+            match = re.search(r'(?<!\d)\d{14}(?!\d)', filename)
+            if match:
+                return match.group()
+            
+            # 方法2:查找带分隔符的14位数字(如2024_03_29_140816)
+            match = re.search(r'(\d{4})_?(\d{2})_?(\d{2})_?(\d{2})_?(\d{2})_?(\d{2})', filename)
+            if match:
+                return f"{match.group(1)}{match.group(2)}{match.group(3)}{match.group(4)}{match.group(5)}{match.group(6)}"
+            
+            # 方法3:保留原下划线分隔的查找方式
+            parts = filename.split('_')
+            for part in parts:
+                if part.isdigit() and len(part) == 14:
+                    return part
+                    
+            print(f"警告:无法从文件名中提取时间戳: {filename}")  # 添加调试信息
+            return ""
+        except Exception as e:
+            print(f"提取时间戳时出错: {e}, 文件名: {filename}")
+            return ""
+    
+    def _get_time_stats(self, df: pd.DataFrame) -> Dict:
+        """获取时间相关的统计信息"""
+        # 提取所有文件名中的时间戳
+        timestamps = []
+        for f in df['Image File']:
+            ts = self._extract_timestamp(f)
+            if not ts:
+                print(f"无法提取时间戳的文件: {f}")  # 添加调试信息
+            timestamps.append(ts)
+            
+        timestamps = [ts for ts in timestamps if ts]  # 过滤掉无效时间戳
+        
+        if not timestamps:
+            return {
+                'start_time': 'N/A',
+                'end_time': 'N/A',
+                'duration': 'N/A'
+            }
+            
+        # 转换为datetime对象
+        start_ts = min(timestamps)
+        end_ts = max(timestamps)
+        
+        # 解析时间戳
+        def parse_timestamp(ts):
+            year = int(ts[:4])
+            month = int(ts[4:6])
+            day = int(ts[6:8])
+            hour = int(ts[8:10])
+            minute = int(ts[10:12])
+            second = int(ts[12:14])
+            return datetime(year, month, day, hour, minute, second)
+        
+        start_dt = parse_timestamp(start_ts)
+        end_dt = parse_timestamp(end_ts)
+        
+        # 计算持续时间(秒)
+        duration_seconds = (end_dt - start_dt).total_seconds()
+        
+        return {
+            'start_time': start_dt.strftime('%Y-%m-%d %H:%M:%S'),
+            'end_time': end_dt.strftime('%Y-%m-%d %H:%M:%S'),
+            'duration': f"{duration_seconds:.0f}秒"
+        }
+        
     def analyze(self) -> Dict:
     def analyze(self) -> Dict:
         """分析检测性能"""
         """分析检测性能"""
         # 读取CSV文件
         # 读取CSV文件
         df = pd.read_csv(self.csv_path)
         df = pd.read_csv(self.csv_path)
         
         
+        # 获取时间统计信息
+        time_stats = self._get_time_stats(df)
+        
         # 获取所有检测到的目标
         # 获取所有检测到的目标
         all_targets = set(os.listdir(self.targets_dir))
         all_targets = set(os.listdir(self.targets_dir))
         true_targets = set(os.listdir(self.true_targets_dir))
         true_targets = set(os.listdir(self.true_targets_dir))
@@ -78,6 +154,11 @@ class PerformanceAnalyzer:
             f.write("检测性能统计报告\n")
             f.write("检测性能统计报告\n")
             f.write("=" * 50 + "\n\n")
             f.write("=" * 50 + "\n\n")
             
             
+            f.write("时间统计信息:\n")
+            f.write(f"采集开始时间: {time_stats['start_time']}\n")
+            f.write(f"采集结束时间: {time_stats['end_time']}\n")
+            f.write(f"持续时长: {time_stats['duration']}\n\n")
+            
             f.write("详细统计信息:\n")
             f.write("详细统计信息:\n")
             f.write(f"总样本数(CSV中唯一图像数): {total_samples}\n")
             f.write(f"总样本数(CSV中唯一图像数): {total_samples}\n")
             f.write(f"检测到的目标总数: {len(all_targets)}\n")
             f.write(f"检测到的目标总数: {len(all_targets)}\n")
@@ -105,6 +186,7 @@ class PerformanceAnalyzer:
         
         
         # 确保返回的字典结构正确
         # 确保返回的字典结构正确
         return {
         return {
+            'time_stats': time_stats,
             'stats': detection_stats,
             'stats': detection_stats,
             'metrics': {
             'metrics': {
                 'accuracy': accuracy,
                 'accuracy': accuracy,
@@ -158,4 +240,4 @@ def main():
         print("-" * 30)
         print("-" * 30)
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':
-    main() 
+    main()