Files
rtsp-video-analysis-system/INSPECTION-FEATURE-SUMMARY.md
2025-09-30 14:23:33 +08:00

12 KiB
Raw Blame History

巡检任务功能更新总结

🎯 功能实现

根据需求已实现完整的巡检任务记录和AI识别流程。

📋 新增功能

1. 自动创建巡检记录

何时创建:巡检任务启动时自动创建

InspectionTaskRecord字段

  • recordId: 自动生成的记录ID
  • taskId: 关联的巡检任务ID
  • executeTime: 执行开始时间
  • duration: 执行时长(秒)
  • accessory: 视频URL原始;处理后)
  • result: AI识别结果摘要
  • status: 0=成功, 1=失败, 2=部分成功

2. 自动保存视频

视频保存流程

  1. 从RTSP流录制视频按task.duration时长
  2. 上传原始视频到MinIO
  3. 保存URL到record.accessory
  4. 继续分析处理

3. 调用Python服务识别

识别流程

  1. 创建HttpYoloDetector连接Python服务
  2. 逐帧提取并调用YOLOv8检测
  3. 每10帧检测一次可调整
  4. 绘制检测框到视频上
  5. 生成带标注的处理后视频

4. 更新识别结果

result字段内容

共检测到 5 个问题,详情:垃圾(3) 烟雾(2)

5. 创建不重复告警

去重机制

  • 使用位置+类别生成唯一键
  • 相同对象只创建一次告警
  • 允许10像素的位置波动
  • 60秒未检测到自动清除

AlarmRecord包含

  • 告警类型、内容、置信度
  • 关联的任务ID和设备ID
  • 告警图片MinIO存储
  • 视频帧位置
  • 未处理状态

🔄 完整执行流程

1. 用户启动巡检任务
   ↓
2. InspectionTaskServiceImpl.executeInspectionTask()
   ├── 创建InspectionTaskRecord (status=1执行中)
   ├── 更新InspectionTask (status=1执行中)
   └── 调用performVideoAnalysisWithRecord()
   ↓
3. performVideoAnalysisWithRecord()
   ├── 录制RTSP视频流30秒
   ├── 上传原始视频到MinIO
   ├── 更新record.accessory = "原始视频URL"
   └── 调用analyzeVideoAndUpdateRecord()
   ↓
4. VideoAnalysisService.analyzeVideoWithRecord()
   ├── 逐帧分析视频
   ├── 每10帧调用Python API检测
   ├── 发现新对象 → createAlarmRecordForRecord()
   │   ├── 提取检测区域图片
   │   ├── 上传告警图片到MinIO
   │   └── 创建AlarmRecord去重
   ├── 绘制检测框
   ├── 保存处理后视频
   ├── 上传处理后视频到MinIO
   ├── 更新record.accessory += ";处理后视频URL"
   └── 更新record.result = "检测结果摘要"
   ↓
5. 完成
   ├── 更新record.status = 0 (成功)
   ├── 更新record.duration = 实际执行时长
   └── 更新task.status = 2 (已完成)

📦 新增/修改的文件

新增文件

  1. IInspectionTaskRecordService.java

    • 巡检记录服务接口
  2. IInspectionTaskRecordServiceImpl.java

    • 巡检记录服务实现
  3. INSPECTION-WORKFLOW.md

    • 详细工作流程文档
  4. INSPECTION-FEATURE-SUMMARY.md

    • 本文档

修改文件

  1. InspectionTaskServiceImpl.java

    • 添加依赖注入InspectionTaskRecordMapper, MinioService, VMinioObjectService
    • 修改executeInspectionTask() - 创建记录
    • 新增performVideoAnalysisWithRecord() - 录制视频并分析
    • 新增analyzeVideoAndUpdateRecord() - 调用分析服务
    • 新增updateRecordFailed() - 更新失败状态
  2. VideoAnalysisService.java

    • 添加InspectionTaskRecordMapper依赖
    • 更新Python服务URL为容器名
    • 更新模型名称为yolov8_detector
    • 新增analyzeVideoWithRecord() - 带记录的视频分析
    • 新增processVideoWithRecord() - 处理视频并记录结果
    • 新增createAlarmRecordForRecord() - 创建去重告警
    • 新增uploadProcessedVideoForRecord() - 上传处理后视频

🎯 数据流转

InspectionTaskRecord字段变化

创建时:
  recordId: [auto]
  taskId: 1001
  executeTime: 2025-09-30 14:30:00
  status: 1 (执行中)
  accessory: null
  result: null
  duration: null

录制视频后:
  accessory: "http://.../inspection_1001_xxx.mp4"
  
分析完成后:
  accessory: "http://.../inspection_1001_xxx.mp4;http://.../processed_xxx.mp4"
  result: "共检测到 3 个问题,详情:垃圾(2) 烟雾(1)"
  duration: 32
  status: 0 (成功)

AlarmRecord创建条件

仅当满足以下条件时创建告警:

  1. 检测到新对象(不在缓存中)
  2. 位置和类别不重复
  3. 置信度超过阈值Python服务的conf参数

💾 数据库查询示例

查看任务执行历史

-- 查看任务的所有执行记录
SELECT 
    r.record_id,
    r.execute_time,
    r.duration,
    r.status,
    r.result,
    (SELECT COUNT(*) FROM v_alarm_record a WHERE a.task_id = r.task_id 
     AND a.create_time >= r.execute_time) as alarm_count
FROM v_inspection_task_record r
WHERE r.task_id = 1001
ORDER BY r.execute_time DESC;

查看记录详情

-- 查看单条记录的完整信息
SELECT 
    r.*,
    t.device_id,
    d.ip as device_ip
FROM v_inspection_task_record r
JOIN v_inspection_task t ON r.task_id = t.task_id
JOIN v_device d ON t.device_id = d.device_id
WHERE r.record_id = 2001;

查看记录的所有告警

-- 查看某次执行产生的告警
SELECT 
    a.alarm_id,
    a.alarm_type,
    a.alarm_content,
    a.confidence,
    a.frame_position,
    m.object_url as alarm_image_url
FROM v_alarm_record a
LEFT JOIN v_minio_object m ON a.image_oss_id = m.object_id
WHERE a.task_id = 1001
  AND a.create_time >= (SELECT execute_time FROM v_inspection_task_record WHERE record_id = 2001)
  AND a.create_time <= DATE_ADD((SELECT execute_time FROM v_inspection_task_record WHERE record_id = 2001), 
                                 INTERVAL (SELECT duration FROM v_inspection_task_record WHERE record_id = 2001) SECOND)
ORDER BY a.create_time;

🔧 配置参数

关键配置位置

VideoAnalysisService.java:

// Python服务地址使用容器名
private static final String PYTHON_API_URL = "http://rtsp-python-service:8000/api/detect/file";

// 模型名称
private static final String MODEL_NAME = "yolov8_detector";

// 检测频率每N帧
if (frameCount % 10 == 0) { ... }

// 去重时间窗口60秒
(currentId - entry.getValue()) > grabber.getFrameRate() * 60

可调整参数

参数 位置 默认值 说明
检测频率 processVideoWithRecord 10帧 降低可提升性能
去重容差 generateDetectionKey 10像素 提高容差减少告警
去重时间窗口 processVideoWithRecord 60秒 缩短窗口增加告警
模型名称 MODEL_NAME yolov8_detector 与Python配置对应

🚀 API接口

Python服务接口

请求

POST http://rtsp-python-service:8000/api/detect/file
Content-Type: multipart/form-data

model_name: yolov8_detector
file: [图像文件]

响应

{
  "model_name": "yolov8_detector",
  "detections": [
    {
      "label": "[yolov8_detector] 垃圾",
      "confidence": 0.95,
      "x": 100,
      "y": 200,
      "width": 150,
      "height": 180,
      "color": 65280
    }
  ],
  "inference_time": 45.6
}

🎬 使用示例

示例1: 创建并执行巡检任务

// 1. 创建任务
InspectionTask task = new InspectionTask();
task.setDeviceId(5001L);
task.setDuration(30); // 30秒
task.setStatus(0); // 待执行
inspectionTaskService.insertInspectionTask(task);

// 2. 启动任务(异步)
inspectionTaskService.executeInspectionTask(task.getTaskId());

// 3. 查询执行记录
List<InspectionTaskRecord> records = 
    inspectionTaskRecordService.selectInspectionTaskRecordList(
        new InspectionTaskRecord().setTaskId(task.getTaskId())
    );

示例2: 查询告警

// 查询某任务的所有告警
AlarmRecord query = new AlarmRecord();
query.setTaskId(1001L);
query.setStatus(0); // 未处理
List<AlarmRecord> alarms = alarmRecordService.selectAlarmRecordList(query);

⚠️ 注意事项

1. 执行时间

  • 录制视频需要时间与duration设置一致
  • AI分析需要额外时间取决于视频长度和CPU性能
  • 总执行时间 ≈ duration + 分析时间

2. 存储空间

每次执行会产生:

  • 原始视频(~10-50MB30秒
  • 处理后视频(~10-50MB
  • 告警图片(每个~100-500KB

建议定期清理历史数据。

3. Python服务调用

  • 使用HTTP调用Python服务
  • 每帧调用可能较慢已优化为每10帧
  • CPU模式下建议降低检测频率

4. MinIO存储

  • 确保bucket已创建
    • inspection-videos(巡检视频)
    • alarm-images(告警图片)
  • 确保外部MinIO服务可访问

🔍 测试清单

部署后测试

  • Python服务可访问

    curl http://rtsp-python-service:8000/health
    curl http://rtsp-python-service:8000/api/models
    
  • MinIO bucket已创建

    # 登录MinIO管理界面创建bucket
    # 或使用mc命令创建
    
  • 创建测试任务

    INSERT INTO v_inspection_task (device_id, duration, status) VALUES (1, 30, 0);
    
  • 执行任务并查看记录

    SELECT * FROM v_inspection_task_record ORDER BY create_time DESC LIMIT 1;
    
  • 查看生成的告警

    SELECT * FROM v_alarm_record ORDER BY create_time DESC LIMIT 10;
    
  • 验证视频URL可访问

    访问record.accessory中的URL
    

📊 预期结果

成功执行的记录

{
  "recordId": 2001,
  "taskId": 1001,
  "executeTime": "2025-09-30 14:30:00",
  "duration": 32,
  "accessory": "http://49.232.154.205:10900/inspection-videos/inspection_1001_1696056600000.mp4;http://49.232.154.205:10900/inspection-videos/processed_1696056632000.mp4",
  "result": "共检测到 5 个问题,详情:垃圾(3) 烟雾(2)",
  "status": 0
}

生成的告警

{
  "alarmId": 3001,
  "deviceId": 5001,
  "taskId": 1001,
  "alarmType": "detection",
  "alarmContent": "垃圾 - 置信度: 0.95",
  "imageOssId": 4001,
  "framePosition": 150,
  "confidence": 0.95,
  "status": 0
}

🛠️ 维护和优化

1. 清理历史数据

-- 删除30天前的记录
DELETE FROM v_inspection_task_record 
WHERE execute_time < DATE_SUB(NOW(), INTERVAL 30 DAY);

-- 删除已处理的告警
DELETE FROM v_alarm_record 
WHERE status = 1 AND create_time < DATE_SUB(NOW(), INTERVAL 7 DAY);

2. 性能监控

-- 查看最近的执行统计
SELECT 
    DATE(execute_time) as date,
    COUNT(*) as total_executions,
    SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as success_count,
    AVG(duration) as avg_duration
FROM v_inspection_task_record
WHERE execute_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY DATE(execute_time)
ORDER BY date DESC;

3. 告警统计

-- 查看最近的告警统计
SELECT 
    DATE(create_time) as date,
    alarm_type,
    COUNT(*) as count,
    AVG(confidence) as avg_confidence
FROM v_alarm_record
WHERE create_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY DATE(create_time), alarm_type
ORDER BY date DESC, count DESC;

📞 故障排查

问题1: Record未创建

症状:执行任务但v_inspection_task_record表无数据

检查

SELECT * FROM v_inspection_task WHERE task_id = ?;

解决

  • 确认任务状态为0待执行
  • 查看后端日志
  • 检查Mapper XML配置

问题2: Accessory为空

症状Record创建了但accessory字段为空

检查

# 查看MinIO上传日志
docker-compose logs backend | grep "MinIO"

# 测试MinIO连接
curl http://49.232.154.205:10900/minio/health/live

解决

  • 确认MinIO服务可访问
  • 检查application.yml中的MinIO配置
  • 确认bucket已创建

问题3: Result为空

症状视频已保存但result字段为空

检查

# 查看Python服务日志
docker-compose logs python-service

# 测试Python服务
curl http://rtsp-python-service:8000/api/models

解决

  • 确认Python服务运行正常
  • 确认best.pt模型文件存在
  • 检查容器间网络通信

问题4: 告警重复

症状:相同对象产生多个告警

调整去重参数

// 在generateDetectionKey中增大容差
int x = rect.x() / 20 * 20;  // 从10改为20
int y = rect.y() / 20 * 20;

📖 相关文档

  • INSPECTION-WORKFLOW.md - 详细工作流程
  • YOLOV8-SETUP.md - YOLOv8模型配置
  • DEPLOYMENT-NOTES.md - 部署配置说明
  • DOCKER-QUICK-START.md - Docker快速开始

功能状态: 已实现 测试状态: 待测试 文档版本: 1.0 最后更新: 2025-09-30

<EFBFBD><EFBFBD> 巡检任务记录功能已完整实现!