analysis_report.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import pandas as pd
  2. import re
  3. from pathlib import Path
  4. def load_detection_data(csv_path):
  5. """加载检测报告CSV数据"""
  6. df = pd.read_csv(csv_path)
  7. df['Camera'] = df['Image File'].apply(lambda x: re.search(r'cam_(\d+)_', x).group(1) if re.search(r'cam_(\d+)_', x) else None)
  8. return df[df['Object Count'] > 0] # 过滤有效检测记录
  9. def generate_analysis_report(df):
  10. """生成分析报告"""
  11. report = {
  12. 'total_detections': df.groupby('Camera')['Object Count'].sum().to_dict(),
  13. 'confirmed_positives': df.groupby('Camera')['Confirmed Positive'].sum().to_dict(),
  14. 'average_sizes': {
  15. cam: {
  16. 'width': round(group['BBox Width'].mean(), 2),
  17. 'height': round(group['BBox Height'].mean(), 2)
  18. } for cam, group in df.groupby('Camera')
  19. },
  20. 'false_positives': {
  21. cam: len(group[~group['Confirmed Positive']])
  22. for cam, group in df.groupby('Camera')
  23. },
  24. 'true_positives': {
  25. cam: len(group[group['Confirmed Positive']])
  26. for cam, group in df.groupby('Camera')
  27. }
  28. }
  29. return report
  30. def save_report(report, output_path):
  31. """保存分析报告"""
  32. with open(output_path, 'w', encoding='gbk') as f:
  33. f.write("摄像头检测分析报告\n=====================\n\n")
  34. # 目标数量统计
  35. f.write("各摄像头目标数量统计:\n")
  36. for cam, count in report['total_detections'].items():
  37. f.write(f"摄像头 {cam}: {count} 个目标\n")
  38. # 确认阳性统计
  39. f.write("\n确认阳性目标统计:\n")
  40. for cam, count in report['confirmed_positives'].items():
  41. f.write(f"摄像头 {cam}: {count} 个确认阳性目标\n")
  42. # 真阳性/假阳性统计
  43. f.write("\n真阳性/假阳性统计:\n")
  44. for cam in report['total_detections'].keys():
  45. total = report['total_detections'][cam]
  46. true_pos = report['true_positives'][cam]
  47. false_pos = report['false_positives'][cam]
  48. f.write(f"摄像头 {cam}:\n")
  49. f.write(f" 总检测数: {total}\n")
  50. f.write(f" 真阳性数: {true_pos} ({true_pos/total*100:.2f}%)\n")
  51. f.write(f" 假阳性数: {false_pos} ({false_pos/total*100:.2f}%)\n")
  52. # 平均尺寸统计
  53. f.write("\n目标平均尺寸统计:\n")
  54. for cam, sizes in report['average_sizes'].items():
  55. f.write(f"摄像头 {cam}: 平均宽度 {sizes['width']}px, 平均高度 {sizes['height']}px\n")
  56. # 总体统计
  57. total_detections = sum(report['total_detections'].values())
  58. total_true_positives = sum(report['true_positives'].values())
  59. total_false_positives = sum(report['false_positives'].values())
  60. f.write("\n总体统计:\n")
  61. f.write(f"总检测数: {total_detections}\n")
  62. f.write(f"总真阳性数: {total_true_positives} ({total_true_positives/total_detections*100:.2f}%)\n")
  63. f.write(f"总假阳性数: {total_false_positives} ({total_false_positives/total_detections*100:.2f}%)\n")
  64. if __name__ == "__main__":
  65. import argparse
  66. parser = argparse.ArgumentParser(description='检测报告分析工具')
  67. parser.add_argument('input_csv', help='输入CSV文件路径')
  68. parser.add_argument('--output', '-o', default=None, help='输出报告路径')
  69. args = parser.parse_args()
  70. # 设置默认输出路径
  71. if not args.output:
  72. csv_dir = Path(args.input_csv).parent
  73. args.output = csv_dir / "analysis_report.txt"
  74. # 执行分析流程
  75. df = load_detection_data(args.input_csv)
  76. report = generate_analysis_report(df)
  77. save_report(report, args.output)
  78. print(f"分析完成!报告已保存至:{args.output}")