diff --git a/docs/config_guide.md b/docs/config_guide.md index 4a35d1b..43dd1a5 100644 --- a/docs/config_guide.md +++ b/docs/config_guide.md @@ -1,104 +1,102 @@ # 配置文件编写指南 -本文档详细说明如何编写和定制 RK3588 Media Server 的配置文件。 +本文档说明当前项目主线配置的写法,重点覆盖两阶段鞋检测、劳保鞋颜色判断、告警节流,以及 RK3588 上与性能稳定性直接相关的参数。 --- -## 1. 配置文件结构 +## 1. 当前推荐架构 -配置文件采用 **JSON 格式**,分为四个主要部分: +对车间劳保鞋场景,当前推荐链路是: -```json -{ - "global": { ... }, // 全局设置 - "queue": { ... }, // 队列策略 - "templates": { ... }, // 节点模板定义 - "instances": [ ... ] // 实例化配置 -} +```text +input_rtsp + -> preprocess(rgb) + -> ai_yolo(person only) + -> tracker(person only) + -> ai_shoe_det(dynamic roi) + -> logic_gate(person_shoe_check) + -> logic_gate(ppe_boots_check) + -> osd + -> preprocess(nv12) + -> publish + -> alarm ``` -### 1.1 全局设置 (global) +业务目标: -```json -{ - "global": { - "metrics_port": 9000, // HTTP 服务端口(监控/HLS) - "web_root": "web" // Web 静态文件根目录 - } -} -``` +- 先检测到人 +- 再只在脚部 ROI 检鞋 +- 只关心“检测到鞋后,颜色是否接近黑色劳保鞋” +- 不再把“没穿鞋”作为主告警目标 -### 1.2 队列策略 (queue) +--- + +## 2. 配置结构 + +当前项目常用的是 graph 模式: ```json { "queue": { - "size": 4, // 队列长度 - "strategy": "drop_oldest" // 队列满时的策略 - } -} -``` - -**strategy 选项:** -- `drop_oldest` - 丢弃最旧的帧(推荐,实时性好) -- `drop_newest` - 丢弃最新的帧 -- `block` - 阻塞等待(可能导致延迟累积) - ---- - -## 2. 模板定义 (templates) - -模板定义了一组节点和连接关系,可以被多个实例复用。 - -### 2.1 模板基本结构 - -```json -{ - "templates": { - "template_name": { - "nodes": [ ... ], // 节点列表 - "edges": [ ... ] // 连接关系 + "size": 8, + "strategy": "drop_oldest" + }, + "graphs": [ + { + "name": "person_shoe_two_stage_workshoe_alarm", + "executor": { + "batch_size": 2, + "run_budget": 8 + }, + "nodes": [ ... ], + "edges": [ ... ] } + ] +} +``` + +### 2.1 queue + +```json +{ + "queue": { + "size": 8, + "strategy": "drop_oldest" } } ``` -### 2.2 节点 (nodes) +说明: -每个节点必须包含以下字段: +- `size`:默认队列长度 +- `strategy` + - `drop_oldest`:推荐,实时性最好 + - `drop_newest` + - `block` + +### 2.2 executor ```json { - "id": "node_id", // 节点唯一标识 - "type": "node_type", // 节点类型 - "role": "source/filter/sink", // 角色 - "enable": true // 是否启用 + "executor": { + "batch_size": 2, + "run_budget": 8 + } } ``` -**节点类型说明:** +说明: -| 类型 | 角色 | 功能 | -|------|------|------| -| `input_rtsp` | source | 拉取 RTSP 视频流 | -| `input_file` | source | 读取本地视频文件 | -| `preprocess` | filter | 图像预处理(缩放/格式转换)| -| `ai_yolo` | filter | YOLO 目标检测 | -| `ai_face_det` | filter | 人脸检测 | -| `ai_face_recog` | filter | 人脸识别 | -| `tracker` | filter | 目标跟踪 | -| `osd` | filter | 绘制检测框/文字 | -| `alarm` | sink | 报警规则处理 | -| `publish` | sink | 视频编码输出 | -| `storage` | sink | 录像存储 | +- `batch_size`:执行器单次批量处理帧数 +- `run_budget`:单次调度预算 + +在 RK3588 上,如果出现“隔几秒卡一下”,通常先减小 `run_budget`,再看是否需要调 `batch_size`。 --- -## 3. 节点详细配置 +## 3. 关键节点 -### 3.1 输入节点 - -#### input_rtsp(RTSP 拉流) +### 3.1 input_rtsp ```json { @@ -106,158 +104,243 @@ "type": "input_rtsp", "role": "source", "enable": true, - "url": "rtsp://10.0.0.49:8554/cam", // RTSP 地址 - "fps": 30, // 预期帧率 - "width": 1920, // 预期宽度 - "height": 1080, // 预期高度 - "use_mpp": true, // 使用 MPP 硬件解码 - "use_ffmpeg": false, // 是否使用 FFmpeg - "force_tcp": true, // 强制 TCP 传输 - "reconnect_sec": 5, // 重连间隔 - "reconnect_backoff_max_sec": 30 // 最大重连间隔 + "url": "rtsp://10.0.0.49:8554/cam", + "fps": 30, + "width": 1920, + "height": 1080, + "use_ffmpeg": true, + "use_mpp": false, + "force_tcp": true } ``` -#### input_file(文件输入) +当前推荐: + +- 对会在固定画面卡顿的 RTSP 源,优先使用 `use_ffmpeg: true`、`use_mpp: false` +- 原因是部分源流在 `ffmpeg demux + mpp decode` 路径上会出现固定位置卡顿,而 VLC 直拉源流正常 + +### 3.2 preprocess ```json { - "id": "in", - "type": "input_file", - "role": "source", - "enable": true, - "path": "/path/to/video.mp4", - "loop": true, // 循环播放 - "fps": 30 -} -``` - -### 3.2 预处理节点 - -#### preprocess(图像预处理) - -```json -{ - "id": "pre", + "id": "pre_rgb", "type": "preprocess", "role": "filter", "enable": true, - "dst_w": 768, // 输出宽度 - "dst_h": 768, // 输出高度 - "dst_format": "rgb", // 输出格式 - "dst_packed": true, // 是否 packed 格式 - "resize_mode": "stretch", // 缩放模式(推荐) - "rga_gate": "cam1", // RGA 资源锁(同名互斥) - "use_rga": true // 使用 RGA 硬件 + "dst_w": 1920, + "dst_h": 1080, + "dst_format": "rgb", + "dst_packed": true, + "resize_mode": "stretch", + "rga_gate": "person_shoe_two_stage_workshoe_alarm", + "use_rga": true } ``` -**resize_mode 选项:** -- `stretch` - 拉伸填充(**推荐**,生产环境默认使用) -- `keep_ratio` - 保持比例(可能留黑边) -- `letterbox` - 保持比例,边缘填充黑色(保留功能,当前有稳定性问题) +说明: -> **注意**:`stretch` 模式在输入输出比例相同时(如 16:9→16:9)不会有明显变形。当输入 16:9 拉伸到模型 1:1 再拉伸回 16:9 输出时,两次变形相互抵消,最终画面正常。该模式性能更好、画面更稳定,推荐生产环境使用。 +- 前级 `pre_rgb` 准备共享的高分辨率 RGB 主帧 +- 后级 `post` 再转回 `nv12` 给编码器 +- `use_rga: true` 是 RK3588 上的推荐项 -**dst_format 选项:** -- `rgb` - RGB24 -- `bgr` - BGR24 -- `nv12` - NV12 (YUV420SP) -- `yuv420` - YUV420P - -### 3.3 AI 节点 - -#### ai_yolo(YOLO 目标检测) +### 3.3 ai_yolo ```json { - "id": "ai", + "id": "person_det", "type": "ai_yolo", "role": "filter", "enable": true, - "infer_fps": 10, // 推理帧率 - "model_path": "./models/best-768.rknn", - "model_version": "v8", // v5 或 v8 - "model_w": 768, // 模型输入宽度 - "model_h": 768, // 模型输入高度 - "num_classes": 11, // 类别数 - "conf": 0.35, // 置信度阈值 - "nms": 0.45, // NMS IoU 阈值 - "class_filter": [3, 6] // 只检测指定类别 -} -``` - -#### ai_face_det(人脸检测) - -```json -{ - "id": "face_det", - "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" // 输入格式 -} -``` - -#### ai_face_recog(人脸识别) - -```json -{ - "id": "face_recog", - "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" + "infer_fps": 2, + "infer_phase_ms": 0, + "use_rga": true, + "use_dma_input": true, + "model_path": "./models/yolov8n-640.rknn", + "model_version": "v8", + "model_w": 640, + "model_h": 640, + "num_classes": 80, + "conf": 0.35, + "nms": 0.45, + "class_filter": [0], + "bbox_expand": { + "enable": true, + "class_id": 0, + "left": 0.06, + "right": 0.06, + "top": 0.04, + "bottom": 0.16 } } ``` -### 3.4 跟踪节点 +当前用途: -#### tracker(目标跟踪) +- 只做人检测前级 +- 不再直接承担鞋检测 + +关键参数: + +| 参数 | 作用 | 当前建议 | +|------|------|----------| +| `infer_fps` | 人体检测频率 | `2` | +| `infer_phase_ms` | 与鞋检错峰 | `0` | +| `class_filter` | 只保留 `person` | `[0]` | +| `bbox_expand.bottom` | 补偿漏脚 | `0.16` 左右 | +| `use_rga` / `use_dma_input` | 输入性能优化 | 建议开启 | + +### 3.4 tracker ```json { - "id": "trk", + "id": "person_trk", "type": "tracker", "role": "filter", "enable": true, - "mode": "bytetrack_lite", // 跟踪算法 - "per_class": true, // 按类别分别跟踪 - "state_key": "cam1", // 状态键(多路隔离) - "track_classes": [3, 6], // 跟踪的类别 - "high_th": 0.5, // 高分阈值 - "low_th": 0.1, // 低分阈值 - "iou_th": 0.3, // IOU 阈值 - "max_age_ms": 1500, // 最大丢失时间 - "min_hits": 2, // 最小确认帧数 - "max_tracks": 128 // 最大跟踪数 + "mode": "bytetrack_lite", + "per_class": true, + "track_classes": [0], + "high_th": 0.55, + "low_th": 0.10, + "iou_th": 0.3, + "max_age_ms": 900, + "min_hits": 2 } ``` -### 3.5 显示节点 +当前用途: -#### osd(屏幕显示) +- 稳定人框 +- 为鞋子关联和按人节流提供 `track_id` + +### 3.5 ai_shoe_det + +```json +{ + "id": "shoe_det", + "type": "ai_shoe_det", + "role": "filter", + "enable": true, + "infer_fps": 2, + "infer_phase_ms": 150, + "use_rga": true, + "use_dma_input": false, + "model_path": "./models/shoe_detector_openimages_ppe_v1.rknn", + "model_w": 640, + "model_h": 640, + "conf": 0.15, + "nms": 0.45, + "v8_box_format": "cxcywh", + "append_detections": true, + "dynamic_roi": { + "enable": true, + "person_class_id": 0, + "shoe_class_id": 1, + "debug_roi_class_id": -1, + "max_rois": 3, + "min_person_height": 60, + "x_offset": -0.24, + "y_offset": 0.64, + "width_scale": 1.48, + "height_scale": 0.58 + } +} +``` + +当前用途: + +- 从人框动态生成脚部 ROI +- 只在 ROI 内跑鞋模型 +- 将鞋框追加回 `frame->det` + +关键参数: + +| 参数 | 作用 | 当前建议 | +|------|------|----------| +| `conf` | 鞋候选召回阈值 | `0.15` | +| `append_detections` | 保留人框并追加鞋框 | 必须 `true` | +| `dynamic_roi.max_rois` | 每帧最多处理多少人 | `3` | +| `dynamic_roi.min_person_height` | 过滤太远的人 | `60` | +| `x_offset/y_offset/width_scale/height_scale` | 脚部 ROI 形状 | 按高机位场景调优 | + +说明: + +- `shoe_det.conf` 看起来偏低,这是有意为之 +- 当前方案依赖“低阈值召回 + 人鞋关联 + 颜色判断 + 告警节流”整体收敛 +- 在高机位小鞋场景中,如果把这里直接调到 `0.4` 或 `0.5`,通常会明显漏检 + +### 3.6 logic_gate + +#### 模式一:person_shoe_check + +```json +{ + "id": "shoe_assoc", + "type": "logic_gate", + "role": "filter", + "enable": true, + "mode": "person_shoe_check", + "person_shoe_check": { + "person_class": 0, + "shoe_class": 1, + "violation_class": 2, + "min_person_score": 0.30, + "min_shoe_score": 0.15, + "require_person_track_id": true, + "attach_person_track_to_shoe": true, + "emit_missing_violation": false, + "foot_region": { + "x_offset": -0.24, + "y_offset": 0.64, + "width_scale": 1.48, + "height_scale": 0.58 + } + } +} +``` + +当前用途: + +- 把鞋关联到对应的人 +- 把人的 `track_id` 传给鞋 +- 不再输出“没鞋违规” + +#### 模式二:ppe_boots_check + +```json +{ + "id": "shoe_color", + "type": "logic_gate", + "role": "filter", + "enable": true, + "mode": "ppe_boots_check", + "anchor_class": 0, + "boots_class": 1, + "violation_class": 2, + "color_check": { + "enable": true, + "method": "brightness", + "dark_threshold": 90, + "roi_expand": 1.0 + } +} +``` + +当前用途: + +- 只对已检测到的鞋做颜色判断 +- 深色鞋:视为合规 +- 非深色鞋:追加 `cls=2` 的违规框,供 OSD 和 alarm 使用 + +颜色参数建议: + +| 参数 | 含义 | 当前建议 | +|------|------|----------| +| `method` | 颜色判断方式 | `brightness` | +| `dark_threshold` | 深色阈值 | `90` | +| `roi_expand` | 颜色分析区域扩展 | `1.0` | + +### 3.7 osd ```json { @@ -265,73 +348,20 @@ "type": "osd", "role": "filter", "enable": true, - "draw_bbox": true, // 绘制检测框 - "draw_text": true, // 绘制文字 - "draw_face_det": true, // 绘制人脸框 - "draw_face_bbox": true, // 绘制人脸边框 - "line_width": 2, // 线宽 - "font_scale": 1, // 字体缩放 - "use_rga_bbox": false, // 使用 RGA 绘制框 - "labels": ["helmet", "gloves", "vest", "boots", ...] // 类别标签 + "draw_bbox": true, + "draw_text": false, + "use_rga_bbox": false, + "labels": ["person", "shoe", "non_black_shoe"] } ``` -### 3.6 报警节点 +当前显示含义: -#### alarm(报警处理) +- `person` +- `shoe` +- `non_black_shoe` -```json -{ - "id": "alarm", - "type": "alarm", - "role": "sink", - "enable": true, - "eval_fps": 10, // 评估帧率 - "labels": ["helmet", "gloves", ...], // 类别标签 - "rules": [ - { - "name": "ppe_violation", // 规则名称 - "class_ids": [3, 6], // 触发类别 - "roi": {"x": 0.0, "y": 0.0, "w": 1.0, "h": 1.0}, // ROI - "min_score": 0.4, // 最小置信度 - "min_box_area_ratio": 0.02, // 最小框面积比 - "require_track_id": true, // 需要跟踪ID - "min_duration_ms": 1500, // 最小持续时间 - "min_hits": 3, // 最小命中次数 - "hit_window_ms": 1500, // 命中窗口 - "cooldown_ms": 5000 // 冷却时间 - } - ], - "actions": { - "log": {"enable": true, "level": "info"}, - "snapshot": { - "enable": true, - "min_interval_ms": 15000, - "format": "jpg", - "quality": 85, - "upload": { - "type": "minio", - "endpoint": "http://10.0.0.49:9000", - "bucket": "myminio", - "access_key": "minioadmin", - "secret_key": "minioadmin" - } - }, - "clip": { - "enable": true, - "min_interval_ms": 15000, - "pre_sec": 5, - "post_sec": 10, - "format": "mp4", - "upload": { ... } - } - } -} -``` - -### 3.7 输出节点 - -#### publish(视频输出) +### 3.8 publish ```json { @@ -339,367 +369,143 @@ "type": "publish", "role": "filter", "enable": true, - "queue": {"size": 2, "policy": "drop_oldest"}, - "codec": "h264", // 编码格式 - "fps": 30, // 输出帧率 - "gop": 60, // GOP 大小 - "bitrate_kbps": 4000, // 码率 - "use_mpp": true, // 使用 MPP 编码 - "use_ffmpeg_mux": true, // 使用 FFmpeg 封装 + "codec": "h264", + "fps": 30, + "bitrate_kbps": 2000, + "mpp_output_timeout_ms": 50, + "mpp_packet_wait_ms": 10, + "use_mpp": true, "outputs": [ - { - "proto": "rtsp_server", // RTSP 输出 - "port": 8555, - "path": "/live/cam1" - }, - { - "proto": "hls", // HLS 输出 - "path": "./web/hls/cam1/index.m3u8", - "segment_sec": 2 // 切片时长 - } + {"proto": "rtsp_server", "port": 8555, "path": "/live/cam1"} ] } ``` -#### logic_gate(逻辑门 - PPE合规检测) +当前推荐: -用于空间关联检测和颜色分析,典型场景:检测人是否穿劳保鞋及颜色是否合规。 +- 输入端优先 FFmpeg CPU decode +- 输出端继续使用 MPP 编码 + +### 3.9 alarm ```json { - "id": "logic_ppe", - "type": "logic_gate", - "role": "filter", + "id": "alarm", + "type": "alarm", + "role": "sink", "enable": true, - "mode": "ppe_boots_check", // 工作模式 - "anchor_class": 6, // 基准类别:人(Person) - "boots_class": 3, // 目标类别:鞋(boots) - "color_check": { - "enable": true, // 启用颜色检测 - "method": "hsv", // 颜色空间:hsv/rgb/brightness - "dark_threshold": 80, // 深色阈值(0-255) - "roi_expand": 1.0 // 检测框扩大系数 - }, - "debug": false // 调试输出 + "eval_fps": 2, + "labels": ["person", "shoe", "non_black_shoe"], + "rules": [ + { + "name": "non_compliant_workshoe", + "class_ids": [2], + "roi": {"x": 0.0, "y": 0.0, "w": 1.0, "h": 1.0}, + "min_score": 0.30, + "require_track_id": false, + "min_duration_ms": 800, + "min_hits": 2, + "hit_window_ms": 2000, + "cooldown_ms": 15000, + "per_track_cooldown_ms": 0 + } + ], + "actions": { + "log": { + "enable": true, + "level": "info", + "include_detections": true, + "min_interval_ms": 2000 + } + } } ``` -**颜色阈值调整建议:** +当前告警策略: -| 阈值 | 效果 | 适用场景 | -|------|------|----------| -| **60** | 很严格,只有纯黑才算深色 | 环境光很暗 | -| **80** (默认) | 适中,黑色/深灰通过 | 正常室内光 | -| **100** | 较宽松,灰色也算深色 | 环境光很亮 | -| **120** | 很宽松,浅灰也算深色 | 强光/反光环境 | - -**判断逻辑:** -``` -is_dark = (平均亮度 < dark_threshold) && (深色像素比例 > 60%) -``` - -**使用示例流程:** -``` -input → preprocess → ai_yolo(Person+boots) → tracker → logic_gate → osd → publish - ↓ - 判断:人+鞋同时存在? - ↓ - 是 → 检查鞋颜色 - ↓ - 深色 → 合规 - 浅色 → 告警 -``` +- 只对 `cls=2 non_black_shoe` 告警 +- 蓝框稳定出现 2 次以上,且持续约 `800ms`,才触发 +- 触发后进入 `15s` 冷却,避免反复刷屏 --- -## 4. 连接关系 (edges) - -edges 定义了数据流向: +## 4. 连接关系 ```json { "edges": [ - ["in", "pre"], // in -> pre - ["pre", "ai"], // pre -> ai - ["ai", "trk"], // ai -> trk - ["trk", "osd"], // trk -> osd - ["osd", "post"], // osd -> post - ["post", "pub"], // post -> pub - ["pub", "alarm"] // pub -> alarm + ["in", "pre_rgb"], + ["pre_rgb", "person_det"], + ["person_det", "person_trk"], + ["person_trk", "shoe_det"], + ["shoe_det", "shoe_assoc"], + ["shoe_assoc", "shoe_color"], + ["shoe_color", "osd"], + ["osd", "post"], + ["post", "pub"], + ["pub", "alarm"] ] } ``` -**注意:** 数据流是单向的,从 source 到 sink。 +说明: + +- `publish -> alarm` 是合法链路 +- `alarm` 会继续读取前面节点保留下来的 `frame->det` --- -## 5. 实例化 (instances) +## 5. 推荐配置 -实例化将模板应用到具体配置: - -```json -{ - "instances": [ - { - "name": "cam1", // 实例名称 - "template": "ppe_detection_pipeline", // 使用的模板 - "params": { // 参数替换 - "name": "cam1", - "url": "rtsp://10.0.0.49:8554/cam1", - "face_gallery_path": "./models/face_gallery.db", - "minio_endpoint": "http://10.0.0.49:9000", - "minio_bucket": "myminio", - "minio_ak": "minioadmin", - "minio_sk": "minioadmin" - } - } - ] -} -``` - -### 5.1 变量替换 - -模板中使用 `${variable}` 定义变量,在实例的 `params` 中提供值: - -**模板中:** -```json -"url": "${url}", -"face_gallery_path": "${face_gallery_path}" -``` - -**实例中:** -```json -"params": { - "url": "rtsp://10.0.0.49:8554/cam1", - "face_gallery_path": "./models/face_gallery.db" -} -``` +| 配置文件 | 说明 | +|----------|------| +| `configs/person_shoe_two_stage_recommended.json` | 单路两阶段鞋检测稳定版 | +| `configs/person_shoe_two_stage_recommended_recall.json` | 单路两阶段鞋检测高召回版 | +| `configs/person_shoe_two_stage_workshoe_alarm.json` | 单路劳保鞋颜色告警主线配置 | --- -## 6. 完整配置示例 +## 6. 调参顺序 -### 6.1 单路 PPE 检测(完整) +建议按下面顺序调,不要同时乱改: -```json -{ - "global": { - "metrics_port": 9000, - "web_root": "web" - }, - "queue": { - "size": 4, - "strategy": "drop_oldest" - }, - "templates": { - "ppe_pipeline": { - "nodes": [ - { - "id": "in", - "type": "input_rtsp", - "role": "source", - "enable": true, - "url": "${url}", - "fps": 30, - "use_mpp": true, - "force_tcp": true, - "reconnect_sec": 5 - }, - { - "id": "pre", - "type": "preprocess", - "role": "filter", - "enable": true, - "dst_w": 768, - "dst_h": 768, - "dst_format": "rgb", - "resize_mode": "stretch", - "use_rga": true - }, - { - "id": "ai", - "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": "trk", - "type": "tracker", - "role": "filter", - "enable": true, - "mode": "bytetrack_lite", - "per_class": true, - "track_classes": [3, 6], - "max_age_ms": 1500 - }, - { - "id": "osd", - "type": "osd", - "role": "filter", - "enable": true, - "draw_bbox": true, - "draw_text": true - }, - { - "id": "post", - "type": "preprocess", - "role": "filter", - "enable": true, - "dst_w": 1920, - "dst_h": 1080, - "dst_format": "nv12", - "resize_mode": "keep_ratio", - "use_rga": true - }, - { - "id": "alarm", - "type": "alarm", - "role": "sink", - "enable": true, - "eval_fps": 10, - "rules": [ - { - "name": "ppe_violation", - "class_ids": [3, 6], - "min_score": 0.4, - "min_duration_ms": 1500 - } - ], - "actions": { - "log": {"enable": true} - } - }, - { - "id": "pub", - "type": "publish", - "role": "filter", - "enable": true, - "codec": "h264", - "fps": 30, - "bitrate_kbps": 4000, - "outputs": [ - {"proto": "rtsp_server", "port": 8555, "path": "/live/${name}"}, - {"proto": "hls", "path": "./web/hls/${name}/index.m3u8", "segment_sec": 2} - ] - } - ], - "edges": [ - ["in", "pre"], - ["pre", "ai"], - ["ai", "trk"], - ["trk", "osd"], - ["osd", "post"], - ["post", "pub"], - ["pub", "alarm"] - ] - } - }, - "instances": [ - { - "name": "cam1", - "template": "ppe_pipeline", - "params": { - "name": "cam1", - "url": "rtsp://10.0.0.49:8554/cam1" - } - } - ] -} -``` - -### 6.2 多路复用模板 - -```json -{ - "instances": [ - { - "name": "cam1", - "template": "ppe_pipeline", - "params": { - "name": "cam1", - "url": "rtsp://10.0.0.49:8554/cam1" - } - }, - { - "name": "cam2", - "template": "ppe_pipeline", - "params": { - "name": "cam2", - "url": "rtsp://10.0.0.49:8554/cam2" - } - }, - { - "name": "cam3", - "template": "ppe_pipeline", - "params": { - "name": "cam3", - "url": "rtsp://10.0.0.49:8554/cam3" - } - }, - { - "name": "cam4", - "template": "ppe_pipeline", - "params": { - "name": "cam4", - "url": "rtsp://10.0.0.49:8554/cam4" - } - } - ] -} -``` +1. `ai_yolo.conf` 和 `bbox_expand` + 目标:先保证人体框稳定且脚下留出空间 +2. `ai_shoe_det.conf` 和 `dynamic_roi` + 目标:先让鞋框能出来 +3. `logic_gate.color_check.dark_threshold` + 目标:区分黑色劳保鞋和拖鞋/浅色鞋 +4. `alarm.min_hits / min_duration_ms / cooldown_ms` + 目标:把“会报警”收敛成“稳一点再报警” --- ## 7. 常见问题 -### Q: 如何禁用某个节点? +### Q1: 为什么鞋子检测阈值只有 0.15? + +因为当前场景是高机位、小鞋目标,单纯靠高阈值会先漏掉大量鞋框。系统依赖多级过滤,而不是单级高阈值。 + +### Q2: 为什么有蓝框却不告警? + +优先检查: + +- 是否跑的是 `person_shoe_two_stage_workshoe_alarm.json` +- `alarm.rules[].class_ids` 是否包含 `2` +- `min_score / min_hits / min_duration_ms` 是否过严 + +### Q3: 为什么 RTSP 会固定画面卡顿? + +如果 VLC 直拉源流不卡,而项目里卡,优先切到: ```json -"enable": false +"use_ffmpeg": true, +"use_mpp": false ``` -### Q: 如何修改日志级别? - -节点级别的 debug 配置: -```json -"debug": { - "stats": false, // 关闭统计日志 - "stats_interval": 100, // 统计间隔(帧数) - "detections": false // 关闭检测日志 -} -``` - -### Q: 配置错误如何排查? - -```bash -# 检查 JSON 格式 -python3 -m json.tool config.json > /dev/null - -# 启动时查看错误日志 -./build/media-server --config config.json 2>&1 | grep -i error -``` +这通常说明问题在输入解码兼容性,而不是 AI 链路。 --- -## 8. 参考配置 - -| 配置文件 | 说明 | -|----------|------| -| `configs/production_4ch.json` | 4路生产环境配置(1080p)| -| `configs/stress_5ch_face_recog.json` | 5路压力测试配置 | -| `configs/sample_cam_ppe11.json` | 单路 PPE 检测示例 | - ---- - -**版本**:v1.0 -**更新日期**:2026-02-28 +**版本**:v2.0 +**更新日期**:2026-03-15 diff --git a/docs/design/detection_parameters_guide.md b/docs/design/detection_parameters_guide.md index 982a74e..7e577f7 100644 --- a/docs/design/detection_parameters_guide.md +++ b/docs/design/detection_parameters_guide.md @@ -258,6 +258,109 @@ const int out_n = std::min(cfg.max_faces, static_cast(keep.size())); ## 四、人脸识别参数 (`ai_face_recog`) +--- + +## 五、车间劳保鞋检测参数(当前主线) + +当前项目的鞋检测不再走“人鞋一体全图检测”思路,而是: + +```text +ai_yolo(person only) + -> tracker(person only) + -> ai_shoe_det(dynamic foot roi) + -> logic_gate(person_shoe_check) + -> logic_gate(ppe_boots_check) + -> alarm +``` + +也就是说,鞋子相关参数不再只看一个 `detect.conf`,而是分成 4 层: + +1. 人体前级参数 +2. 鞋检测参数 +3. 颜色判断参数 +4. 告警稳定性参数 + +### 1. 人体前级参数(`ai_yolo`) + +| 参数 | 当前建议 | 作用 | +|------|----------|------| +| `conf` | `0.35` | 人体候选阈值 | +| `nms` | `0.45` | 人框去重 | +| `infer_fps` | `2` | 人检频率 | +| `bbox_expand.bottom` | `0.16` | 补偿高机位下漏脚问题 | + +调参原则: + +- 人框太紧、脚经常漏在外面:优先增大 `bbox_expand.bottom` +- 人漏检明显:适当降低 `conf` +- 周期性卡顿:先不要盲目提 `infer_fps` + +### 2. 鞋检测参数(`ai_shoe_det`) + +| 参数 | 当前建议 | 作用 | +|------|----------|------| +| `conf` | `0.15` | 鞋候选召回阈值 | +| `nms` | `0.45` | 鞋框去重 | +| `infer_fps` | `2` | 鞋检频率 | +| `dynamic_roi.max_rois` | `3` | 单帧最多处理多少人 | +| `dynamic_roi.min_person_height` | `60` | 过滤太远的人 | +| `x_offset/y_offset/width_scale/height_scale` | 见推荐配置 | 控制脚部 ROI 形状 | + +为什么 `shoe_det.conf` 只有 `0.15`? + +- 当前场景是高机位、小目标、遮挡多 +- 如果把鞋阈值直接提到常规检测项目里的 `0.4~0.5` + 通常先发生的是严重漏检,而不是“更稳” +- 当前链路依赖: + - 低阈值鞋候选召回 + - 人鞋空间关联 + - 鞋颜色判断 + - 告警去抖和冷却 + +所以这里的思路是: + +```text +前面低阈值多召回,后面多级逻辑再收紧 +``` + +### 3. 颜色判断参数(`logic_gate -> ppe_boots_check`) + +| 参数 | 当前建议 | 作用 | +|------|----------|------| +| `method` | `brightness` | 颜色判断方式 | +| `dark_threshold` | `90` | 黑鞋/深色鞋阈值 | +| `roi_expand` | `1.0` | 颜色分析区域放大比例 | + +调参原则: + +- 黑鞋也经常被判成违规:适当提高 `dark_threshold` +- 拖鞋/浅色鞋经常被放过:适当降低 `dark_threshold` + +### 4. 告警稳定性参数(`alarm`) + +| 参数 | 当前建议 | 作用 | +|------|----------|------| +| `min_score` | `0.30` | 蓝框进入告警的最低分数 | +| `min_hits` | `2` | 2 秒内至少出现几次 | +| `hit_window_ms` | `2000` | 命中窗口 | +| `min_duration_ms` | `800` | 持续多久才报警 | +| `cooldown_ms` | `15000` | 告警后的冷却时间 | + +调参原则: + +- 蓝框已经稳定出现,但不告警:先看 `min_score / min_hits / min_duration_ms` +- 告警过于频繁:提高 `cooldown_ms` +- 闪一下就报警:提高 `min_duration_ms` + +### 推荐调参顺序 + +1. 先让人框稳定,脚不要漏 +2. 再让鞋框能稳定出来 +3. 再调颜色判断黑白边界 +4. 最后再调告警节流 + +不要一开始就只改 `alarm`,否则常常会把“检测问题”误判成“规则问题”。 + `ai_face_recog` 节点接收人脸检测结果,提取人脸特征向量并与特征库进行比对,完成人脸识别。 ### 4.1 参数概览