更换检测模型best-768.rknn

This commit is contained in:
haotian 2026-02-27 16:23:39 +08:00
parent 88333a1e40
commit f52ec05384
3 changed files with 527 additions and 0 deletions

View File

@ -0,0 +1,329 @@
{
"queue": {
"size": 8,
"strategy": "drop_oldest"
},
"graphs": [
{
"name": "cam_ppe11_detection",
"nodes": [
{
"id": "in_cam1",
"type": "input_rtsp",
"role": "source",
"enable": true,
"url": "rtsp://10.0.0.49:8554/cam",
"fps": 30,
"width": 1280,
"height": 720,
"use_mpp": true,
"use_ffmpeg": false,
"force_tcp": true,
"reconnect_sec": 5,
"reconnect_backoff_max_sec": 30
},
{
"id": "pre_cam1",
"type": "preprocess",
"role": "filter",
"enable": true,
"dst_w": 768,
"dst_h": 768,
"dst_format": "rgb",
"dst_packed": true,
"keep_ratio": false,
"rga_gate": "cam_ppe11_detection",
"use_rga": true
},
{
"id": "yolo_cam1",
"type": "ai_yolo",
"role": "filter",
"enable": true,
"infer_fps": 10,
"model_path": "./models/best-768.rknn",
"model_version": "v8",
"model_w": 768,
"model_h": 768,
"num_classes": 11,
"conf": 0.35,
"nms": 0.45,
"class_filter": [3, 6]
},
{
"id": "face_det_cam1",
"type": "ai_face_det",
"role": "filter",
"enable": true,
"model_path": "./models/RetinaFace_mobile320.rknn",
"conf": 0.7,
"nms": 0.4,
"max_faces": 10,
"output_landmarks": true,
"input_format": "rgb"
},
{
"id": "face_recog_cam1",
"type": "ai_face_recog",
"role": "filter",
"enable": true,
"model_path": "./models/mobilefacenet_arcface.rknn",
"align": true,
"emit_embedding": false,
"max_faces": 10,
"input_format": "rgb",
"input_dtype": "uint8",
"threshold": {
"accept": 0.45,
"margin": 0.05
},
"gallery": {
"backend": "sqlite",
"path": "./models/face_gallery.db",
"load_on_start": true,
"expected_dim": 512,
"dtype": "auto"
}
},
{
"id": "trk_cam1",
"type": "tracker",
"role": "filter",
"enable": true,
"mode": "bytetrack_lite",
"per_class": true,
"state_key": "cam_ppe11_detection",
"track_classes": [3, 6],
"ignore_classes": [],
"allowed_models": ["yolov8"],
"high_th": 0.5,
"low_th": 0.1,
"iou_th": 0.3,
"max_age_ms": 1500,
"min_hits": 2,
"max_tracks": 128
},
{
"id": "pre_face_cam1",
"type": "preprocess",
"role": "filter",
"enable": true,
"dst_w": 0,
"dst_h": 0,
"dst_format": "rgb",
"dst_packed": true,
"keep_ratio": false,
"rga_gate": "cam_ppe11_detection",
"use_rga": true
},
{
"id": "osd_cam1",
"type": "osd",
"role": "filter",
"enable": true,
"draw_bbox": true,
"draw_text": true,
"draw_face_det": false,
"draw_face_bbox": false,
"line_width": 2,
"font_scale": 1,
"use_rga_bbox": false,
"labels": ["helmet", "gloves", "vest", "boots", "goggles", "none", "Person", "no_helmet", "no_goggle", "no_gloves", "no_boots"]
},
{
"id": "post_cam1",
"type": "preprocess",
"role": "filter",
"enable": true,
"dst_w": 1280,
"dst_h": 720,
"dst_format": "nv12",
"keep_ratio": false,
"rga_gate": "cam_ppe11_detection",
"use_rga": true
},
{
"id": "pub_cam1",
"type": "publish",
"role": "filter",
"enable": true,
"codec": "h264",
"fps": 30,
"gop": 60,
"bitrate_kbps": 2000,
"use_mpp": true,
"use_ffmpeg_mux": true,
"outputs": [
{
"proto": "hls",
"path": "./web/hls/cam1/index.m3u8",
"segment_sec": 2
},
{
"proto": "rtsp_server",
"port": 8555,
"path": "/live/cam1"
}
]
},
{
"id": "alarm_cam1",
"type": "alarm",
"role": "sink",
"enable": true,
"eval_fps": 10,
"labels": ["helmet", "gloves", "vest", "boots", "goggles", "none", "Person", "no_helmet", "no_goggle", "no_gloves", "no_boots"],
"rules": [
{
"name": "ppe_violation",
"class_ids": [3, 6],
"roi": {
"x": 0.0,
"y": 0.0,
"w": 1.0,
"h": 1.0
},
"min_score": 0.4,
"min_box_area_ratio": 0.02,
"require_track_id": true,
"min_duration_ms": 1500,
"min_hits": 3,
"hit_window_ms": 1500,
"cooldown_ms": 5000,
"per_track_cooldown_ms": 5000
}
],
"face_rules": [],
"actions": {
"log": {
"enable": true,
"level": "info"
},
"snapshot": {
"enable": true,
"format": "jpg",
"quality": 85,
"upload": {
"type": "minio",
"endpoint": "http://10.0.0.49:9000",
"bucket": "myminio",
"region": "us-east-1",
"access_key": "minioadmin",
"secret_key": "minioadmin"
}
},
"clip": {
"enable": true,
"pre_sec": 5,
"post_sec": 10,
"format": "mp4",
"fps": 30,
"upload": {
"type": "minio",
"endpoint": "http://10.0.0.49:9000",
"bucket": "myminio",
"region": "us-east-1",
"access_key": "minioadmin",
"secret_key": "minioadmin"
}
},
"http": {
"enable": false,
"url": "http://127.0.0.1:8080/api/alarm",
"timeout_ms": 3000,
"include_media_url": true,
"method": "POST"
},
"external_api": {
"enable": true,
"getTokenUrl": "http://10.0.0.49:8080/api/getToken",
"putMessageUrl": "http://10.0.0.49:8080/api/putMessage",
"tenantCode": "32",
"channelNo": "${vod_channelNo}",
"timeout_ms": 3000,
"include_media_url": true,
"token_header": "X-Access-Token",
"token_json_path": "responseBody.token",
"token_cache_sec": 1200
}
}
},
{
"id": "alarm_face_cam1",
"type": "alarm",
"role": "sink",
"enable": true,
"eval_fps": 5,
"labels": [],
"rules": [],
"face_rules": [
{
"name": "unknown_face",
"type": "unknown",
"cooldown_ms": 7000,
"min_sim": 0.35,
"min_hits": 2,
"hit_window_ms": 1500,
"min_face_area_ratio": 0.01,
"min_face_aspect": 0.6,
"max_face_aspect": 1.6
},
{
"name": "known_person",
"type": "person",
"cooldown_ms": 7000,
"min_sim": 0.6,
"min_hits": 2,
"hit_window_ms": 1500,
"min_face_area_ratio": 0.01,
"min_face_aspect": 0.6,
"max_face_aspect": 1.6
}
],
"actions": {
"log": {
"enable": false,
"level": "info"
},
"snapshot": {
"enable": true,
"format": "jpg",
"quality": 85,
"upload": {
"type": "minio",
"endpoint": "http://10.0.0.49:9000",
"bucket": "myminio",
"region": "us-east-1",
"access_key": "minioadmin",
"secret_key": "minioadmin"
}
},
"clip": {
"enable": false
},
"http": {
"enable": true,
"url": "http://127.0.0.1:8080/api/alarm",
"timeout_ms": 3000,
"include_media_url": true,
"method": "POST"
}
}
}
],
"edges": [
["in_cam1", "pre_cam1"],
["in_cam1", "pre_face_cam1"],
["pre_cam1", "yolo_cam1"],
["yolo_cam1", "trk_cam1"],
["trk_cam1", "osd_cam1"],
["osd_cam1", "post_cam1"],
["post_cam1", "pub_cam1"],
["pub_cam1", "alarm_cam1"],
["pre_face_cam1", "face_det_cam1"],
["face_det_cam1", "face_recog_cam1"],
["face_recog_cam1", "alarm_face_cam1"]
]
}
]
}

198
docs/models.md Normal file
View File

@ -0,0 +1,198 @@
# AI 模型说明文档
本文档说明 `models/` 目录中各 AI 模型的用途、类别映射及配置参数。
## 目录结构
```
models/
├── best-640.rknn # YOLO 通用检测模型 (3类)
├── best-768.rknn # YOLO PPE检测模型 (11类)
├── yolov5s-640-640.rknn # YOLOv5 COCO预训练模型 (80类)
├── yolov8n-640.rknn # YOLOv8n COCO预训练模型 (80类)
├── RetinaFace_mobile320.rknn # 人脸检测模型
├── mobilefacenet_arcface.rknn # 人脸识别模型
└── face_gallery.db # 人脸特征库 (SQLite)
```
## 模型详情
### 1. best-640.rknn
**类型**: YOLOv8 目标检测
**输入尺寸**: 640x640
**类别数**: 3
| 索引 | 类别名 | 说明 |
|------|--------|------|
| 0 | person | 人 |
| 1 | vest | 反光背心 |
| 2 | boots | 安全靴 |
**配置示例**:
```json
{
"type": "ai_yolo",
"model_path": "./models/best-640.rknn",
"model_version": "v8",
"num_classes": 3,
"conf": 0.35,
"nms": 0.45
}
```
---
### 2. best-768.rknn (PPE11)
**类型**: YOLOv8 PPE检测模型
**输入尺寸**: 768x768
**类别数**: 11
**模型名**: ppe11_person_boots_boost
| 索引 | 类别名 | 业务使用 | 说明 |
|------|--------|----------|------|
| 0 | helmet | ❌ | 安全帽 |
| 1 | gloves | ❌ | 手套 |
| 2 | vest | ❌ | 反光背心 |
| 3 | **boots** | ✅ | 安全靴 |
| 4 | goggles | ❌ | 护目镜 |
| 5 | none | ❌ | 无/背景 |
| 6 | **Person** | ✅ | 人 |
| 7 | no_helmet | ❌ | 未戴安全帽 |
| 8 | no_goggle | ❌ | 未戴护目镜 |
| 9 | no_gloves | ❌ | 未戴手套 |
| 10 | no_boots | ❌ | 未穿安全靴 (不作为告警依据) |
**业务侧只消费**: `class_id in {3, 6}` (boots 和 Person)
**配置示例**:
```json
{
"type": "ai_yolo",
"model_path": "./models/best-768.rknn",
"model_version": "v8",
"model_w": 768,
"model_h": 768,
"num_classes": 11,
"conf": 0.35,
"nms": 0.45,
"class_filter": [3, 6]
}
```
**OSD标签配置**:
```json
{
"type": "osd",
"labels": ["helmet", "gloves", "vest", "boots", "goggles", "none", "Person", "no_helmet", "no_goggle", "no_gloves", "no_boots"]
}
```
---
### 3. yolov5s-640-640.rknn
**类型**: YOLOv5s COCO预训练模型
**输入尺寸**: 640x640
**类别数**: 80 (COCO标准类别)
使用标准 COCO 类别映射,详见代码中 `kCocoLabels` 数组。
**配置示例**:
```json
{
"type": "ai_yolo",
"model_path": "./models/yolov5s-640-640.rknn",
"model_version": "v5",
"num_classes": 80,
"conf": 0.25,
"nms": 0.45
}
```
---
### 4. yolov8n-640.rknn
**类型**: YOLOv8n COCO预训练模型
**输入尺寸**: 640x640
**类别数**: 80 (COCO标准类别)
使用标准 COCO 类别映射。
**配置示例**:
```json
{
"type": "ai_yolo",
"model_path": "./models/yolov8n-640.rknn",
"model_version": "v8",
"num_classes": 80,
"conf": 0.25,
"nms": 0.45
}
```
---
### 5. RetinaFace_mobile320.rknn
**类型**: RetinaFace 人脸检测
**输入尺寸**: 320x320
**输出**: 人脸框 + 5点关键点
**配置示例**:
```json
{
"type": "ai_face_det",
"model_path": "./models/RetinaFace_mobile320.rknn",
"conf": 0.7,
"nms": 0.4,
"max_faces": 10,
"output_landmarks": true
}
```
---
### 6. mobilefacenet_arcface.rknn
**类型**: MobileFaceNet + ArcFace 人脸识别
**输入尺寸**: 112x112
**输出维度**: 512
**配置示例**:
```json
{
"type": "ai_face_recog",
"model_path": "./models/mobilefacenet_arcface.rknn",
"align": true,
"threshold": {
"accept": 0.45,
"margin": 0.05
},
"gallery": {
"backend": "sqlite",
"path": "./models/face_gallery.db",
"expected_dim": 512
}
}
```
---
## 模型选择建议
| 场景 | 推荐模型 | 说明 |
|------|----------|------|
| 通用目标检测 | yolov8n-640.rknn | 80类COCO通用性强 |
| 工地安全检测 | best-640.rknn | 人/背心/安全靴 |
| PPE完整检测 | best-768.rknn | 11类PPE含正反例 |
| 人脸检测+识别 | RetinaFace + MobileFaceNet | 人脸识别链路 |
## 注意事项
1. **模型尺寸匹配**: `preprocess` 节点的 `dst_w/dst_h` 必须与模型输入尺寸一致
2. **num_classes**: 必须与模型实际类别数一致,否则后处理会出错
3. **class_filter**: 用于过滤只关心的类别,减少后续处理负载
4. **best-768.rknn**: 只消费类别 3(boots) 和 6(Person),其他类别可忽略

BIN
models/best-768.rknn Normal file

Binary file not shown.