AlertGateway
基于RK3588S的4K边缘视觉网关:支持V4L2/RTMP/RTSP视频源、RKNN YOLOv8s推理、RGA+MPP硬件加速、RTMP推流、MQTT上报及多路NPU调度。
Install / Use
npx skills add johnjiamzhong-project/AlertGatewayInstalls into whichever agent you are using.
README
AlertGateway
基于 RK3588S 的智能边缘网关,面向 4K 视频流的实时目标检测与告警。
边缘端 C++ 应用,运行在 Firefly ROC-RK3588S-PC 开发板上。视频来源支持本地 V4L2 摄像头与 RTMP/RTSP 拉流(SRS 转发)两种可配置模式,实现视频采集/拉流、NPU 推理、检测结果画框、硬件编码推流、MQTT 上报的完整业务闭环。推理侧支持三类可配置图像处理任务:Thumbnail 缩略图、ROI 区域追踪、ROI Tiling 小目标增强。
经过多轮性能调优,当前生产配置使用 Rockchip 官方九输出 YOLOv8s INT8 模型,NPU 阶段中位数约 26.7 ms(performance 锁频),后处理中位数 2.86 ms(L1/L2 缓存优化),完整推理链路约 30.65 ms。编码推流稳定运行在视频源实际帧率,RTMP 端到端延迟 < 1s,支持断线自动重连。
系统架构
┌──────────────────────────────────────────────────────────┐
│ AlertGateway │
│ │
│ 视频源(可配置) │
│ V4L2 本地摄像头 ─┐ │
│ RTMP/RTSP 拉流 ─┤──→ 推理线程(含图像处理任务) │
│ (SRS 转发) │ RKNN NPU / YOLOv8s │
│ │ · Thumbnail 缩略图 │
│ │ · ROI 过滤 / 追踪 │
│ │ · ROI Tiling 小目标增强 │
│ │ │ │
│ │ SharedDetections │
│ │ ↓ │
│ ├──────→ 编码线程 → 推流线程 │
│ │ MPP H.264 RTMP 推流 │
│ │ 叠加检测框 │
│ └──────→ MQTT 线程 │
│ 检测结果上报 │
└───────────────────────┬──────────────────────────────────┘
│
┌────────────┴────────────┐
▼ ▼
SRS(主机) MqttMonitor(主机)
RTMP 转发 / 4K 中继 检测结果实时显示
│
▼
播放器(主机)
拉流播放(含检测框画面)
功能说明
核心业务
- 支持 V4L2 本地摄像头与 RTMP/RTSP 拉流(SRS 转发)两种视频来源,通过
source.type配置切换 - YOLOv8s NPU 推理,检测画面中的目标物品(手机、杯子、键盘等)
- 检测结果叠加画框(类别 + 置信度)后硬编码推流到 RTMP 服务器
- 检测结果(物品种类、数量、置信度)通过 MQTT 周期上报到上位机
可配置图像处理任务
三类任务可独立开启,默认全部关闭,不影响基础链路:
| 任务 | 说明 | |------|------| | Thumbnail 缩略图 | 检测后生成指定尺寸 NV12 缩略图并附加到 MQTT payload(当前为 CPU 正确性路径,RGA/JPEG 为后续优化)| | ROI 区域追踪 | 圈定感兴趣区域(归一化坐标),仅保留 ROI 内目标,支持停留时长追踪与进出事件上报;代码已实现,板端专项验证待完成 | | ROI Tiling 推理 | 对 ROI 内区域做网格切分分别推理,弥补 4K 缩放后小目标漏检,结果合并全局 NMS;代码已实现,板端专项验证待完成 |
检测目标类别
基于 COCO 预训练的 YOLOv8s 模型,关注以下桌面常见物品类别(可在配置文件中调整):
| 类别(英文) | COCO ID | 说明 | |------|------|------| | cell phone | 67 | 手机 | | cup | 41 | 杯子 | | keyboard | 66 | 键盘 | | mouse | 64 | 鼠标 | | laptop | 63 | 笔记本电脑 | | book | 73 | 书本 |
4K 场景准确率提升
对于真实 4K 场景中杯子、书类/说明书、笔记本的漏检或框不贴合,应从已有 4K 测试视频按 1 FPS 抽帧、筛选、人工标注,并在 WSL/Linux GPU 环境微调后再进行 INT8 转换。量化校准只保证训练后 模型的 RKNN INT8 转换质量,不能替代标注和微调,也不能单独提升识别率。完整可执行流程见 4K 准确率微调与 INT8 校准。
本轮已完成冻结的 4K final test 验收:166 张图片、221 个标注框。浮点模型 Precision 为 89.6%、Recall 为 82.3%、mAP50 为 92.22%;同一评估口径下,ONNX mAP50 为 87.73%,RKNN INT8 mAP50 为 87.79%。4K 专用候选已在 RK3588 上完成 3840×2160 拉流、YOLO 推理、叠框、 MPP 编码和 RTMP 回推验证,但仍保持为独立候选,不替换 V4L2 生产模型。
检测结果处理
替代原有的离岗/睡岗告警状态机,逻辑更简单:
- 推理线程(
InferThread)对每帧画面做目标检测,按target_classes过滤出关心的物品,结果写入共享结构SharedDetections - 编码线程(
EncodeThread)每帧编码前从SharedDetections读取最新检测结果,将检测框 + 类别 + 置信度叠加到画面上,再交给硬编码器 - 推理线程按固定周期(如 1 秒,
report_interval_sec可配置)汇总当前帧检测到的物品种类与数量 - 与上一次汇总结果对比,发生变化(新增/消失/数量变化)时通过 MQTT 上报一条 JSON 消息
上报消息示例:
{
"timestamp": 1718000000,
"objects": [
{"label": "cell phone", "count": 1, "score": 0.87},
{"label": "cup", "count": 1, "score": 0.91},
{"label": "keyboard", "count": 1, "score": 0.95}
]
}
性能优化与工程特点
Pipeline 并行解耦
采集/拉流、推理、编码三条线程通过独立队列解耦:视频源同时向编码队列(阻塞、不丢帧)和推理队列(非阻塞、可丢帧,始终推理最新帧)推送数据,推理速度不决定编码推流帧率,编码线程稳定运行在视频源帧率。推理结果通过线程安全的共享结构传递给编码线程叠加画框,两条线程互不阻塞。
NPU 推理性能
- Rockchip 官方九输出 INT8 模型:生产配置默认使用
model/yolov8s_rockchip_dfl.rknn和model.output_layout=rockchip_dfl,在 CPU 端完成 DFL、坐标解码和 NMS - 后处理循环优化:重构类别筛选内层循环为顺序内存访问,改善 L1/L2 缓存命中,后处理中位数从 4.14 ms 降至 2.86 ms(降幅 31%)
- Zero-copy 输入 + RGA 硬件预处理:视频源 YUYV / NV12 帧通过 RGA 一次性完成颜色空间转换与缩放,直接写入 NPU DMA 输入缓冲区
- 各实验详情见
docs/YOLOv8s-RK3588推理优化实验记录.md
视频叠框与标签
- 编码线程在 NV12 DRM Buffer 上直接绘制检测框和“类别 + 置信度”标签,不依赖 OpenCV
- 中文类别名仅用于视频绘制层,内部检测标签和 MQTT payload 仍保持英文 COCO 类别名
stream.draw_detection_labels可开关标签绘制,stream.bitrate_kbps控制 MPP CBR 目标码率;当前生产建议为 2000 kbps
推流稳定性
- RTMP 推流参数(GOP、编码 profile、队列深度)针对低延迟场景调优,端到端延迟控制在 1 秒以内
- 推流连接具备自动断线重连能力;
PullStreamThread拉流模式同样支持断线重连
摄像头帧率自适应
根据 USB 摄像头在当前采集格式下的真实可达帧率配置采集参数,保证画面时间戳节奏与实际出帧速度一致,避免播放端缓冲异常。
技术栈
| 模块 | 技术 | |------|------| | 开发语言 | C++17 | | 开发环境 | VSCode + Remote-WSL | | 构建系统 | CMake | | 交叉编译 | aarch64-linux-gnu-g++ 11.4.0 | | 视频采集 | V4L2(本地)/ FFmpeg avformat+avcodec(RTMP/RTSP 拉流)| | AI 推理 | RKNN Lite2 C API + YOLOv8s | | 硬件编码 | Rockchip MPP(h264_rkmpp) | | 图像处理 | RGA 硬件加速(格式转换 / 缩放 / crop)| | 推流 | RTMP | | 消息上报 | Paho MQTT C++ | | 线程通信 | 有界阻塞队列 + 条件变量 | | 配置管理 | JSON(nlohmann/json) |
目录结构
AlertGateway/
├── CMakeLists.txt
├── readme.md
├── config/
│ ├── config.json # 公共配置与 active_config 入口
│ ├── config_v4l2.json # V4L2 摄像头配置
│ ├── config_4k_18mbps.json # 4K pull_stream、18 Mbps 基础配置
│ ├── config_4k_8mbps.json # 4K pull_stream、8 Mbps 观看配置
│ ├── config_4k_candidate_20260719.json # 4K 专用模型隔离候选
│ └── config_multi_1080p_candidate.json # 单进程双路 ChannelPipeline 验证配置
├── src/
│ ├── main.cpp
│ ├── app/ChannelPipeline.cpp # 路级流水线与生命周期管理
│ ├── common/
│ │ ├── BlockingQueue.hpp # 有界阻塞队列
│ │ └── Frame.hpp # 帧数据结构(含 pixel_format 字段)
│ ├── capture/
│ │ ├── IVideoSource.hpp # 视频源抽象接口
│ │ ├── CaptureThread.cpp # V4L2 采集线程
│ │ └── PullStreamThread.cpp # RTMP/RTSP 拉流线程
│ ├── infer/
│ │ ├── InferThread.cpp # RKNN 推理线程
│ │ ├── RockchipYoloPostprocess.cpp # 官方九输出后处理
│ │ ├── YoloPostprocess.cpp # 旧双输出后处理 + 类别过滤
│ │ ├── ThumbnailTask.cpp # 缩略图生成任务
│ │ ├── RoiFilter.cpp # ROI 过滤与追踪
│ │ └── TilingTask.cpp # ROI Tiling 推理
│ ├── encode/
│ │ ├── EncodeThread.cpp # MPP 硬编线程
│ │ ├── font8x16.h # ASCII 标签字体
│ │ └── font16x16.h # 中文标签字体
│ ├── stream/
│ │ └── StreamThread.cpp # RTMP 推流线程
│ └── mqtt/
│ └── MqttThread.cpp # MQTT 上报线程
├── model/
│ └── .gitkeep # RKNN 模型文件不纳入 Git
└── third_party/
├── rknn/ # RKNN Lite2 头文件
├── mpp/ # MPP 头文件
├── rga/ # RGA 头文件和链接库
├── paho/ # Paho MQTT 头文件和链接库
└── nlohmann/ # JSON 库
配置文件
config/config.json 保存公共配置,并只保留当前要使用的分配置文件名:
{
"active_config": "config_4k_18mbps.json",
"model": { "path": "model/yolov8s_rockchip_dfl.rknn", "output_layout": "rockchip_dfl", "conf_threshold": 0.25, "iou_threshold": 0.45 },
"detection": { "target_classes": ["cell phone", "cup", "keyboard", "mouse", "laptop", "book"], "report_interval_sec": 1 },
"stream": { "draw_detection_labels": true },
"mqtt": { "broker": "192.168.0.168", "port": 1883, "topic": "desk/detect", "client_id": "AlertGateway-01" }
}
两个分配置文件分别保存对应运行模式的完整差异配置:
config/config_v4l2.json:V4L2 源、640×480、3 Mbps、对应 RTMP 地址,以及 Thumbnail/ROI/Tiling 开关。config/config_4k_18mbps.json:4Kpull_stream源、3840×2160、18 Mbps、对应 RTMP 地址,以及 4K 专用的 Thumbnail/ROI/Tiling 开关。config/config_4k_8mbps.json:4Kpull_stream源、3840×2160、8 Mbps,供高码率播放受限时观看结果流。config/config_4k_candidate_20260719.json:独立 4K 专用 RKNN 候选,显式启用已验收的检测框跟踪平滑参数,不能替代config/config.json的生产入口。config/config_multi_1080p_candidate.json:单个 AlertGateway 进程内的双路 1080p 验证配置;两路分别输出到与通道 ID 对应的 RTMP 地址。
切换 4K 时只将 active_config 改为 "config_4k_18mbps.json"。程序会先加载公共配置,
再递归合并选中的分配置;视频源、分辨率、码率和图像处理参数均由对应模式配置明确维护。
source.type可设为"v4l2"(本地摄像头,默认)或"pull_stream"(RTMP/RTSP 拉流)。
旧版camera节点继续支持,自动映射为source.type=v4l2,向下兼容。
配置增加 channels 数组时,程序会把顶层模型、检测、图像处理、码率和 MQTT 公共字段递归合并到每一路;
没有 channels 的旧配置会自动归一化为单路 single,并保持结果地址 rtmp://192.168.0.168/live/alertgateway。只有 channels[] 多路配置的每个 fixed_rtmp 地址必须严格为 rtmp://192.168.0.168/live/alertgateway_channel_{channel_id};local_flv 与 metrics_only 仍可用于离线或性能验证。
视频源配置示例:
- V4L2 本地摄像头:将
active_config改为config_v4l2.json后使用config/config.json,或参考runs/testsrc2/config_v4l2_720p.json,配置source.type、source.device、分辨率和帧率。 - RTMP/RTSP 拉流:将
source.type改为"pull_stream",并填写source.url。
V4L2 的采集分辨率必须是摄像头实际支持的分辨率;当前编码输出尺寸跟随视频源尺寸,
不会仅通过配置把 V4L2 画面放大为 4K。4K 原始输入目前使用 pull_stream 配置。
当前工作区的 config/config.json 已选择 config_4k_18mbps.json,用于 192.168.0.200 板 4K 测试。
先将配置部署到 192.168.0.200 板:
scp config/config.json config/config_4k_18mbps.json \
firefly@192.168.0.200:~/AlertGateway/config/
然后在 WSL/主机循环发布输入文件到 SRS;视频不是直接写入板端,.200 板会从该 RTMP 地址拉流:
ffmpeg -re -stream_loop -1 \
-i runs/input_videos/4k/VID_20260712_131410.mp4 \
-map 0:v:0 -c copy -f flv \
rtmp://192.168.0.168/live/testsrc2
在 .200 板启动处理程序:
ssh firefly@192.168.0.200 \
'cd ~/AlertGateway && ./AlertGateway config/config.json'
.200 板拉取 live/testsrc2 输入流,完成 RKNN 推理和 MPP H.264 编码后输出到
rtmp://192.168.0.168/live/alertgateway,播放器可直接查看该地址。项目所有推理结果
推流统一使用该固定地址,实际 4K 输出尺寸为 3840×2160。恢复 V4L2 测试时,将
active_config 改回 config_v4l2.json 并重启程序。
统一测试入口:注释切换单路、双路和多路
在主机项目根目录运行:
./run.sh
run.sh 是统一的一次性测试入口,当前默认启用单进程双路并发:它将两段 4K 视频在主机侧缩放为
1920×1080@30 FPS,分别发布到 live/dual_a 和 live/dual_b,再通过 SSH 在
192.168.0.200 板上启动一个包含两个 ChannelPipeline 的 AlertGateway 进程。A 路结果推送到固定地址
rtmp://192.168.0.168/live/alertgateway_channel_1 与
rtmp://192.168.0.168/live/alertgateway_channel_2,并分别使用 desk/dual/a、desk/dual/b MQTT topic 记录检测数据。
默认运行 180 秒,每路目标码率为 8 Mbps。
需要切换测试类型时,直接编辑 run.sh 的注释:单路测试取消单路 exec 注释并注释双路
exec;未来多路测试新增对应脚本后按同样方式切换。不要同时保留多个未注释的 exec,也不增加命令行参数。
该脚本首先检查 SRS 的 HTTP API 1985 和 RTMP 1935。SRS 必须由用户在 Windows 上手动启动,
并使用唯一的 console.conf 实
Related Skills
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
blender-python-addon
40.5kBlender Python add-on rules for operators, panels, properties, registration, testing, and API-safe scripting
flutter-development-guidelines-cursorrules-prompt-file
40.5kCursor rules for Flutter development with MVVM architecture, Riverpod state management, Material widgets, and Dart style guidelines.
commit-push-pr
140.6kCommit, push, and open a PR
