|
@@ -27,38 +27,50 @@ class PerformanceAnalyzer:
|
|
|
total_samples = len(df['Image File'].unique())
|
|
|
|
|
|
# 初始化统计
|
|
|
- stats = {
|
|
|
- 'TP': 0, # 真阳性
|
|
|
- 'FP': 0, # 假阳性
|
|
|
+ detection_stats = {
|
|
|
+ 'TP': len(true_targets), # 真阳性:targets_all_True文件夹中的所有文件
|
|
|
+ 'FP': len(all_targets - true_targets), # 假阳性:在targets_all中但不在targets_all_True中的文件
|
|
|
'FN': 0, # 假阴性
|
|
|
- 'TN': 0 # 真阴性
|
|
|
+ 'TN': total_samples - (len(true_targets) + len(all_targets - true_targets)) # 真阴性:总样本数减去TP和FP
|
|
|
}
|
|
|
|
|
|
- # 计算真阳性(TP):targets_all_True文件夹中的所有文件
|
|
|
- stats['TP'] = len(true_targets)
|
|
|
-
|
|
|
- # 计算假阳性(FP):在targets_all中但不在targets_all_True中的文件
|
|
|
- stats['FP'] = len(all_targets - true_targets)
|
|
|
-
|
|
|
- # 计算真阴性(TN):总样本数减去TP和FP
|
|
|
- stats['TN'] = total_samples - (stats['TP'] + stats['FP'])
|
|
|
-
|
|
|
# 计算性能指标
|
|
|
- total = stats['TP'] + stats['FP'] + stats['TN']
|
|
|
- accuracy = (stats['TP'] + stats['TN']) / total if total > 0 else 0
|
|
|
- precision = stats['TP'] / (stats['TP'] + stats['FP']) if (stats['TP'] + stats['FP']) > 0 else 0
|
|
|
- recall = stats['TP'] / (stats['TP'] + stats['FN']) if (stats['TP'] + stats['FN']) > 0 else 0
|
|
|
+ total = detection_stats['TP'] + detection_stats['FP'] + detection_stats['TN']
|
|
|
+ accuracy = (detection_stats['TP'] + detection_stats['TN']) / total if total > 0 else 0
|
|
|
+ precision = detection_stats['TP'] / (detection_stats['TP'] + detection_stats['FP']) if (detection_stats['TP'] + detection_stats['FP']) > 0 else 0
|
|
|
+ recall = detection_stats['TP'] / (detection_stats['TP'] + detection_stats['FN']) if (detection_stats['TP'] + detection_stats['FN']) > 0 else 0
|
|
|
f1_score = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0
|
|
|
# 计算误报率(虚警率):FP / (TN + FP)
|
|
|
- false_alarm_rate = stats['FP'] / (stats['TN'] + stats['FP']) if (stats['TN'] + stats['FP']) > 0 else 0
|
|
|
+ false_alarm_rate = detection_stats['FP'] / (detection_stats['TN'] + detection_stats['FP']) if (detection_stats['TN'] + detection_stats['FP']) > 0 else 0
|
|
|
+
|
|
|
+ # 统计每个镜头的报警数量
|
|
|
+ camera_stats = {}
|
|
|
+ for target_file in all_targets:
|
|
|
+ # 提取镜头编号(cam_xx)
|
|
|
+ parts = target_file.split('_')
|
|
|
+ camera_id = None
|
|
|
+ for i in range(len(parts)):
|
|
|
+ if parts[i] == 'cam' and i + 1 < len(parts):
|
|
|
+ camera_id = f"cam_{parts[i+1]}"
|
|
|
+ break
|
|
|
+
|
|
|
+ if camera_id:
|
|
|
+ if camera_id not in camera_stats:
|
|
|
+ camera_stats[camera_id] = {
|
|
|
+ 'total_alarms': 0,
|
|
|
+ 'false_alarms': 0
|
|
|
+ }
|
|
|
+ camera_stats[camera_id]['total_alarms'] += 1
|
|
|
+ if target_file not in true_targets:
|
|
|
+ camera_stats[camera_id]['false_alarms'] += 1
|
|
|
|
|
|
# 打印详细统计信息
|
|
|
print("\n详细统计信息:")
|
|
|
print(f"总样本数(CSV中唯一图像数): {total_samples}")
|
|
|
print(f"检测到的目标总数: {len(all_targets)}")
|
|
|
- print(f"真实目标总数(TP): {len(true_targets)}")
|
|
|
- print(f"误报目标数(FP): {len(all_targets - true_targets)}")
|
|
|
- print(f"真阴性数量(TN): {stats['TN']}")
|
|
|
+ print(f"真实目标总数(TP): {detection_stats['TP']}")
|
|
|
+ print(f"误报目标数(FP): {detection_stats['FP']}")
|
|
|
+ print(f"真阴性数量(TN): {detection_stats['TN']}")
|
|
|
|
|
|
# 保存统计结果到文件
|
|
|
stats_file = os.path.join(self.result_dir, 'performance_stats.txt')
|
|
@@ -69,28 +81,39 @@ class PerformanceAnalyzer:
|
|
|
f.write("详细统计信息:\n")
|
|
|
f.write(f"总样本数(CSV中唯一图像数): {total_samples}\n")
|
|
|
f.write(f"检测到的目标总数: {len(all_targets)}\n")
|
|
|
- f.write(f"真实目标总数(TP): {len(true_targets)}\n")
|
|
|
- f.write(f"误报目标数(FP): {len(all_targets - true_targets)}\n")
|
|
|
- f.write(f"真阴性数量(TN): {stats['TN']}\n\n")
|
|
|
+ f.write(f"真实目标总数(TP): {detection_stats['TP']}\n")
|
|
|
+ f.write(f"误报目标数(FP): {detection_stats['FP']}\n")
|
|
|
+ f.write(f"真阴性数量(TN): {detection_stats['TN']}\n\n")
|
|
|
|
|
|
f.write("性能指标:\n")
|
|
|
f.write(f"准确率: {accuracy:.4f}\n")
|
|
|
f.write(f"精确率: {precision:.4f}\n")
|
|
|
f.write(f"召回率: {recall:.4f}\n")
|
|
|
f.write(f"F1分数: {f1_score:.4f}\n")
|
|
|
- f.write(f"误报率(虚警率): {false_alarm_rate:.4f}\n")
|
|
|
+ f.write(f"误报率(虚警率): {false_alarm_rate:.4f}\n\n")
|
|
|
+
|
|
|
+ f.write("镜头统计信息:\n")
|
|
|
+ f.write("-" * 30 + "\n")
|
|
|
+ for camera_id, cam_stats in sorted(camera_stats.items()):
|
|
|
+ f.write(f"镜头 {camera_id}:\n")
|
|
|
+ f.write(f" 总报警数: {cam_stats['total_alarms']}\n")
|
|
|
+ f.write(f" 误报数: {cam_stats['false_alarms']}\n")
|
|
|
+ f.write(f" 误报率: {cam_stats['false_alarms']/cam_stats['total_alarms']:.4f}\n")
|
|
|
+ f.write("-" * 30 + "\n")
|
|
|
|
|
|
print(f"\n统计结果已保存到: {stats_file}")
|
|
|
|
|
|
+ # 确保返回的字典结构正确
|
|
|
return {
|
|
|
- 'stats': stats,
|
|
|
+ 'stats': detection_stats,
|
|
|
'metrics': {
|
|
|
'accuracy': accuracy,
|
|
|
'precision': precision,
|
|
|
'recall': recall,
|
|
|
'f1_score': f1_score,
|
|
|
'false_alarm_rate': false_alarm_rate
|
|
|
- }
|
|
|
+ },
|
|
|
+ 'camera_stats': camera_stats
|
|
|
}
|
|
|
|
|
|
def mark_true_targets(self, true_target_files: List[str]):
|
|
@@ -104,7 +127,7 @@ class PerformanceAnalyzer:
|
|
|
|
|
|
def main():
|
|
|
# 示例使用
|
|
|
- result_dir = r"D:\PythonProject\Model\output_20250329_130338_results"
|
|
|
+ result_dir = r"D:\PythonProject\Model\Output\output_20250329_100448_results"
|
|
|
analyzer = PerformanceAnalyzer(result_dir)
|
|
|
|
|
|
# 分析性能
|
|
@@ -123,6 +146,16 @@ def main():
|
|
|
print(f"召回率: {results['metrics']['recall']:.4f}")
|
|
|
print(f"F1分数: {results['metrics']['f1_score']:.4f}")
|
|
|
print(f"误报率(虚警率): {results['metrics']['false_alarm_rate']:.4f}")
|
|
|
+
|
|
|
+ # 打印镜头统计信息
|
|
|
+ print("\n镜头统计信息:")
|
|
|
+ print("-" * 30)
|
|
|
+ for camera_id, stats in sorted(results['camera_stats'].items()):
|
|
|
+ print(f"镜头 {camera_id}:")
|
|
|
+ print(f" 总报警数: {stats['total_alarms']}")
|
|
|
+ print(f" 误报数: {stats['false_alarms']}")
|
|
|
+ print(f" 误报率: {stats['false_alarms']/stats['total_alarms']:.4f}")
|
|
|
+ print("-" * 30)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
main()
|