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

525 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ✅ 巡检任务功能更新总结
## 🎯 功能实现
根据需求已实现完整的巡检任务记录和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参数
## 💾 数据库查询示例
### 查看任务执行历史
```sql
-- 查看任务的所有执行记录
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;
```
### 查看记录详情
```sql
-- 查看单条记录的完整信息
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;
```
### 查看记录的所有告警
```sql
-- 查看某次执行产生的告警
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**:
```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服务接口
**请求**
```http
POST http://rtsp-python-service:8000/api/detect/file
Content-Type: multipart/form-data
model_name: yolov8_detector
file: [图像文件]
```
**响应**
```json
{
"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: 创建并执行巡检任务
```java
// 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: 查询告警
```java
// 查询某任务的所有告警
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服务可访问
```bash
curl http://rtsp-python-service:8000/health
curl http://rtsp-python-service:8000/api/models
```
- [ ] MinIO bucket已创建
```bash
# 登录MinIO管理界面创建bucket
# 或使用mc命令创建
```
- [ ] 创建测试任务
```sql
INSERT INTO v_inspection_task (device_id, duration, status) VALUES (1, 30, 0);
```
- [ ] 执行任务并查看记录
```sql
SELECT * FROM v_inspection_task_record ORDER BY create_time DESC LIMIT 1;
```
- [ ] 查看生成的告警
```sql
SELECT * FROM v_alarm_record ORDER BY create_time DESC LIMIT 10;
```
- [ ] 验证视频URL可访问
```
访问record.accessory中的URL
```
## 📊 预期结果
### 成功执行的记录
```json
{
"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
}
```
### 生成的告警
```json
{
"alarmId": 3001,
"deviceId": 5001,
"taskId": 1001,
"alarmType": "detection",
"alarmContent": "垃圾 - 置信度: 0.95",
"imageOssId": 4001,
"framePosition": 150,
"confidence": 0.95,
"status": 0
}
```
## 🛠️ 维护和优化
### 1. 清理历史数据
```sql
-- 删除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. 性能监控
```sql
-- 查看最近的执行统计
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. 告警统计
```sql
-- 查看最近的告警统计
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`表无数据
**检查**
```sql
SELECT * FROM v_inspection_task WHERE task_id = ?;
```
**解决**
- 确认任务状态为0待执行
- 查看后端日志
- 检查Mapper XML配置
### 问题2: Accessory为空
**症状**Record创建了但accessory字段为空
**检查**
```bash
# 查看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字段为空
**检查**
```bash
# 查看Python服务日志
docker-compose logs python-service
# 测试Python服务
curl http://rtsp-python-service:8000/api/models
```
**解决**
- 确认Python服务运行正常
- 确认best.pt模型文件存在
- 检查容器间网络通信
### 问题4: 告警重复
**症状**:相同对象产生多个告警
**调整去重参数**
```java
// 在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> **巡检任务记录功能已完整实现!**