FEATURED · 精选文章

基于 RK3588 的多输入视频 AI 推理流水线:YOLO 车牌检测、OCR、WebRTC 推流与边缘联动

发布时间 / 2026/8/6 1:25:19
来源 / 创域科博编辑部
栏目 / 资讯中心
基于 RK3588 的多输入视频 AI 推理流水线:YOLO 车牌检测、OCR、WebRTC 推流与边缘联动 基于 RK3588 的多输入视频 AI 推理流水线YOLO 车牌检测、OCR、WebRTC 推流与边缘联动本文介绍一个面向 Rockchip RK3588 的 C 视频智能分析项目。项目将 MP4、USB 摄像头和 RTSP 视频统一接入同一条边缘推理流水线完成目标检测、车牌 OCR、跟踪、OSD、硬件编码和网络分发并可选接入 MQTT 事件上报、OLED 显示和 Modbus 继电器。采用 NPU Core Affinity 机制各推理线程持有独立rknn_context通过 core_mask 绑定不同 NPU 硬件核心实现多路检测任务在多 NPU 上并行执行降低单 NPU 资源争抢提升多路 RTSP 流推理吞吐。GitHubhttps://github.com/shaddockpeel2/Plate_detection_recognition点⭐哦一、项目主要做什么这个项目解决的不是“加载一个 YOLO 模型并输出检测框”这么单一的问题而是一个完整的边缘视频分析链路MP4 / USB 摄像头 / RTSP │ ▼ 解封装、采集与硬件解码 │ ▼ RGA 图像预处理 │ ▼ RKNN YOLO 推理 │ ▼ 后处理、ByteTrack、车牌 OCR │ ▼ OSD 叠加结果 │ ▼ MPP H.264/H.265 编码 │ ┌─────┴──────────────┐ ▼ ▼ 保存 MP4 RTMP 推送到 ZLMediaKit │ WebRTC / HTTP-FLV / HLS项目的典型应用场景包括RK3588 边缘盒子上的车辆和车牌识别停车场、园区或出入口的视频分析需要低延迟预览的智能摄像头网关识别结果需要上传到平台或者需要联动继电器、门禁等设备的场景在一块 RK3588 上运行三路独立推理任务的性能验证。核心程序是rk_mp4_yolo_stage5它负责单路视频从输入到输出的完整处理。rk_yolo_supervisor负责多路 worker 的配置校验、启动、健康检查和重启不直接参与图像推理。二、项目的核心架构1. 多输入统一为DecodedFrame项目将输入分支和后续推理链路解耦。对于 MP4 和 RTSP 输入程序使用 FFmpeg 完成解封装再使用 Rockchip MPP 硬件解码 H.264/H.265。RTSP 采用 TCP 传输并配置读流超时。对于 USB 摄像头程序使用 V4L2 的 MMAP 方式采集YUYV数据在摄像头输入线程内转换为NV12随后也进入DecodedFrameQueue。这样摄像头不需要复制一套后处理、推理和编码逻辑。统一后的DecodedFrame不只是一个图像指针还包含frame_id应用层帧编号pts源视频时间戳source_fps源帧率宽高和 strideMPP 帧对象和 DMA-BUF 文件描述符。后续模块通过 DMA fd 直接访问硬件缓冲区减少不必要的 CPU 拷贝。2. RGA 负责预处理RKNN 负责推理预处理线程从解码队列取帧使用 RGA 完成NV12 到 RGB/BGR 的格式转换缩放Letterbox 填充写入 RKNN 输入张量对量化模型执行必要的输入转换。项目通过RknnInputRuntime在启动时查询模型输入输出属性包括输入尺寸、布局、数据类型和量化信息并创建输入内存池。默认输入池包含多个 DMA 内存槽位使预处理和推理之间可以形成有界流水线而不是每帧重复申请和释放内存。RGA 预处理和 RKNN 输入内存之间通过 DMA fd 连接适合 RK3588 这类需要充分利用硬件加速和共享缓冲区的环境。3. RKNN 推理支持 NPU 核绑定YOLO 模型通过 RKNN Runtime 初始化程序可以使用rknn_set_core_mask将推理上下文绑定到指定 NPU 核--npu-core 0 使用 NPU core 0 --npu-core 1 使用 NPU core 1 --npu-core 2 使用 NPU core 2 --npu-core auto 交给 RKNN 自动调度绑定只作用于 RKNN 推理上下文并不意味着 RGA、MPP、CPU、内存带宽和网络资源也被隔离。三路 worker 即使分别使用 core 0、1、2仍然会共享其他系统资源因此实际部署仍需要根据输入分辨率、帧率、OCR 和编码码率进行容量评估。4. 后处理兼容不同 YOLO 输出布局后处理模块会读取 RKNN 输出张量并根据张量布局解析检测框和类别分数当前代码中包含两类主要路径YOLO26 风格的检测输出YOLOv8 DFL 风格的 box、score 输出。完成输出解码后模块依次执行置信度过滤坐标还原将模型坐标映射回原始图像NMS 去除重复框ByteTrack 关联连续帧中的同一目标为检测结果写入track_id。Detection数据结构同时保存检测框、检测分数、跟踪 ID、车牌文本和 OCR 分数后面的 OCR、OSD、上传和继电器逻辑都基于这份结构继续处理。三、车牌 OCR 是如何接入的车牌 OCR 不是单独的离线工具而是后处理阶段的一部分。当检测到车辆目标并且 ByteTrack 已经分配了track_id后PlateOcrStage会执行以下操作车辆检测框 │ ▼ 扩大并裁剪车牌区域 │ ▼ RGA 缩放到 OCR 模型输入尺寸 │ ├─ 量化输入直接使用 RKNN DMA 输入内存 └─ 浮点输入转为 OpenCV Mat 后归一化 │ ▼ PP-OCRv5 车牌识别模型 │ ▼ CTC 解码 字典映射 │ ▼ plate_text / plate_scoreOCR 阶段包含几个适合实时视频的优化同一帧限制最大 OCR 目标数量同一跟踪目标按帧间隔重新识别识别成功后按track_id缓存结果识别失败时使用较短的重试间隔缓存过期后自动清理避免目标长期消失仍保留旧车牌。需要注意当前 YOLO 和 OCR 默认绑定到同一个 NPU core。启用 OCR 后实际吞吐会下降需要结合目标数量和 OCR 触发频率重新评估而不能只看 YOLO 单模型的速度。四、OSD、编码和播放1. OSD 直接叠加到视频帧后处理线程会在原始 NV12 帧上绘制检测框跟踪 ID车牌识别文字中文或 ASCII 文字。中文文字使用 FreeType 加载系统字体并生成位图缓存重复出现的车牌不会每帧重复生成字形。这样编码输出的视频本身就已经包含检测框和车牌文字浏览器端不需要再次执行绘制。2. MPP 编码支持本地文件和网络输出编码线程使用 MPP 硬件编码器输出 H.264/H.265 码流并根据输出模式选择不同 sinkmp4 - FFmpeg libavformat 封装为 MP4 annexb - 保存裸 H.264/H.265 码流 rtmp - H.264 Annex-B 写入 FFmpeg 子进程再转封装为 FLV/RTMPRTMP 推流使用FfmpegPushSink主程序通过管道把 MPP 输出的 H.264 码流交给 FFmpegFFmpeg 使用视频复制方式转封装并推送到 ZLMediaKit。推流进程异常时支持有限次数重启。ZLMediaKit 负责将 RTMP 转换为浏览器可消费的协议页面可以使用WebRTC低延迟预览HTTP-FLV便于 VLC、ffplay 或接口排障HLS兼容部分原生 HLS 播放器但延迟通常更高。3. 实时帧率和时间戳处理RTSP 实时场景最容易出现的问题不是模型本身而是输入速度、编码声明和媒体时间戳不一致。项目对此做了专门处理--output-fps 25时在 RGA 和 RKNN 之前均匀抽帧避免只修改编码器声明而仍然处理全部输入帧--output-fps auto时跟随 RTSP 建连时探测到的源帧率不主动抽帧输出队列有界系统过载时丢弃最旧帧优先保持实时性RTMP 路径不使用墙钟时间戳也不使用 FFmpeg-re强制限速FFmpeg 根据输入帧率生成连续 PTS避免推理耗时抖动直接变成媒体时间轴抖动MPP 编码输出按 partition 收齐只有完整帧结束后才交给下游避免半帧 H.264 造成推流断开。项目现有技术报告记录了三路1024×576 30 FPS测试流的验证结果每路约 5 秒输出 150 个包PTS 间隔约为0.0330.034秒三个 worker 的重启次数为 0。这个结果说明帧率选择和 RTMP 时间戳链路已经能够稳定工作但不代表任意分辨率、码率和 OCR 配置下都能获得相同吞吐。五、三路独立推理与 supervisor项目提供了一个轻量级的rk_yolo_supervisor。它将三路推理拆成三个独立进程worker.core0 - --npu-core 0 - rtmp://127.0.0.1:1936/live/rk3588-core0 worker.core1 - --npu-core 1 - rtmp://127.0.0.1:1936/live/rk3588-core1 worker.core2 - --npu-core 2 - rtmp://127.0.0.1:1936/live/rk3588-core2supervisor 的职责包括读取config/inference_fleet.ini检查 NPU core、流名、摄像头设备、截图目录、MQTT 标识和外设资源是否冲突为每个 worker 构造命令行并脱敏打印创建独立日志和 health 文件监测 worker 进程和健康心跳对 RTSP、摄像头 worker 进行有限次数的指数退避重启原子生成网页读取的rk-yolo-status.json。浏览器页面web/rk_yolo.html根据状态文件显示三个视频卡片每一路可以独立重试、停止或切换到排障播放地址。因此一路摄像头或 RTSP 断开时不会直接阻塞另外两路。三路模式适合以下两类任务三路独立摄像头分别占用一个 NPU core使用同一个输入源对三份 worker 做性能压测。生产环境不建议让三个 worker 同时打开同一个 USB 摄像头应使用三路独立 RTSP、不同的/dev/video*或混合 MP4 测试源。六、远程事件上报与硬件联动1. HTTP 图片 MQTT 事件远程上报采用“图片和事件分离”的设计检测 / 跟踪 / OCR │ ▼ 阈值判断与去重 │ ▼ 有界 UploadEventQueue │ ▼ 独立上传线程 ├─ 裁剪车辆或车牌截图并编码 JPEG ├─ HTTP multipart 上传图片 └─ MQTT 发布事件 JSON 和 image_urlMQTT 只传事件元数据不传图片二进制。事件通常包含设备 ID、帧号、跟踪 ID、车牌文本、检测分数、OCR 分数、检测框和图片 URL。网络请求全部发生在上传线程中主链路不会因为 HTTP 或 MQTT 服务器不可达而阻塞。上传队列满时丢弃新事件不让网络反压传递到检测、OCR、OSD 和编码线程。当前版本不做失败事件的本地持久化缓存断网期间失败的事件会丢失但视频主链路仍可继续运行。2. 白名单继电器和 OLED继电器功能默认关闭打开后需要同时满足车牌位于白名单文件检测分数达到阈值OCR 分数达到阈值车牌不在冷却时间内。控制器使用 Modbus RTU 通过串口发送线圈开关命令默认脉冲结束后强制关闭。OLED 则通过 I2C 显示近期识别到的车牌。这两个功能都通过独立队列和线程接入不改变主视频处理链路。部署时必须确认串口、I2C 设备和继电器通道的实际硬件参数不能直接照搬示例路径。七、性能监控和背压设计项目没有使用无限队列。解码、预处理、推理和 OSD 之间都使用固定容量队列DecodedFrameQueue 容纳解码帧 PreprocessedFrameQueue 容纳 RGA 处理后的输入 InferenceResultQueue 容纳 RKNN 输出 OsdFrameQueue 容纳待编码帧 UploadEventQueue 容纳待上传事件这样做的取舍很明确MP4 文件处理可以通过阻塞队列保持完整性RTSP 实时处理优先降低延迟队列满时丢弃旧帧上传事件队列满时丢弃新事件不影响视频输出所有队列都支持关闭和唤醒便于程序退出时按顺序回收线程。打开--metrics-interval-ms 1000后程序会输出解封装、MPP 提交、RGA、预处理、RKNN、后处理、编码和 RTMP 写入耗时队列深度、峰值、入队等待和出队等待MPP buffer full、FFmpeg pipe 阻塞、推流重启等事件实际输出 FPS 与声明输出 FPS。这比只查看“平均 FPS”更适合定位实时视频卡顿平均值正常并不代表不存在 P99 延迟或队列积压。八、如何构建和运行1. 环境要求项目主要面向硬件Rockchip RK3588 系统aarch64 Linux 语言C11 构建CMake g 推理RKNN Runtime 图像处理RGA、OpenCV 视频FFmpeg、Rockchip MPP 字体FreeType仓库提供了项目内的 Rockchip 依赖也支持通过RKNPU2_DIR指向外部 SDK。x86 Linux 可以阅读和修改代码但没有对应的 MPP、RGA、RKNN 驱动和库时不能直接完成板端运行。2. 编译cmake-S.-Bbuild cmake--buildbuild\--targetrk_mp4_yolo_stage5 rk_yolo_supervisor\-j$(nproc)如果 CMake 找不到 FFmpeg、OpenCV 或 FreeType 开发库应先检查pkg-config和系统开发包如果运行时找不到 Rockchip 动态库应检查构建出的 RUNPATH 是否指向third_party/rockchip。3. MP4 测试关闭 OCR 进行基础链路验证./build/rk_mp4_yolo_stage5\--inputmp4\--video./video/test-video/5s.mp4\--model./models/car-v8/v8-car-relu-3588.rknn\--ocr-model off\--output./video/output-video/result.mp4启用车牌 OCR 时需要同时指定识别模型和字典./build/rk_mp4_yolo_stage5\--inputmp4\--video./video/test-video/9s.mp4\--model./models/car-v8/v8-car-relu-3588.rknn\--ocr-model ./ppocrv5/PP-OCRv5_mobile_rec_license_plate.rknn\--ocr-vocab ./ppocrv5/model/license_plate_dict.txt\--output./video/output-video/plate-result.mp44. 摄像头测试第一版摄像头输入主要验证YUYV采集链路./build/rk_mp4_yolo_stage5\--inputcamera\--device/dev/video0\--width640\--height480\--fps25\--frame-limit300\--model./models/car-v8/v8-car-relu-3588.rknn\--ocr-model off\--output./video/output-video/camera-result.mp4运行前可以使用v4l2-ctl --list-formats-ext查看摄像头是否支持目标分辨率和像素格式。5. RTSP 推流测试先启动 ZLMediaKit再启动推理程序./build/rk_mp4_yolo_stage5\--inputrtsp\--urlrtsp://camera-ip:8554/live\--model./models/car-v8/v8-car-relu-3588.rknn\--ocr-model off\--output-mode rtmp\--push-url rtmp://127.0.0.1:1936/live/rk3588\--output-fps autoZLMediaKit 的具体端口和页面路径以部署配置为准。通常可以用 WebRTC 查看低延迟画面用 HTTP-FLV 或 HLS 排查推流是否真正进入媒体服务器。6. 三路 supervisorcpconfig/inference_fleet.ini.example config/inference_fleet.ini ./build/rk_yolo_supervisor--configconfig/inference_fleet.ini--check./build/rk_yolo_supervisor--configconfig/inference_fleet.ini --dry-run ./build/rk_yolo_supervisor--configconfig/inference_fleet.ini正式部署前应修改三路输入地址或摄像头设备npu_core确保正好覆盖 0、1、2RTMP 应用名和流名模型和 OCR 资源路径日志、健康文件和状态页面路径MQTT、继电器和 OLED 配置。公开配置或发布文章时不要提交真实 RTSP 凭据、MQTT 密码、服务器地址和设备私钥。九、项目目录说明include/ 模块接口和数据结构 src/main.cpp 单路流水线编排 src/decoder_thread.cpp FFmpeg 解封装与 MPP 解码 src/camera_source_thread.cpp V4L2 摄像头采集与 YUYV/NV12 输入转换 src/preprocess_thread.cpp RGA 预处理和 Letterbox src/inference_thread.cpp RKNN 推理与输出张量复制 src/postprocess_osd_thread.cpp YOLO 后处理、NMS、OSD 和功能分发 src/plate_ocr_stage.cpp 车牌裁剪、OCR 调度和缓存 src/encoder_writer_thread.cpp MPP 编码和 MP4/Annex-B 输出 src/ffmpeg_push_sink.cpp RTMP 推流子进程管理 src/worker_supervisor_main.cpp 多 worker 健康管理和重启 src/worker_fleet_config.cpp INI 配置解析、校验和参数展开 models/ YOLO 模型和标签 ppocrv5/ OCR 模型、字典和测试资源 config/ 多路推理配置模板 web/ ZLMediaKit 播放页面 third_party/rockchip/ MPP、RGA、RKNN 项目依赖 docs/ RTSP、ZLMediaKit、MQTT 技术记录 doc/ 面向公开发布的项目介绍文章十、当前边界和后续方向项目已经形成可运行的端到端框架但仍有明确边界摄像头第一版主要支持 V4L2YUYV如果设备直接输出 NV12、MJPEG 或 H.264需要在摄像头输入模块增加格式分支。NPU core 绑定只隔离 RKNN 上下文三路并发仍需关注 RGA、MPP、CPU 和内存带宽竞争。OCR、上传和外设功能会增加处理开销建议先关闭附加功能完成基础链路验证再逐项打开。单独运行推理程序时RTSP 断流不会自动恢复使用 supervisor 时可以通过 worker 退出或 health 过期触发重启。上传失败事件当前不做本地失败缓存断网期间应由平台侧接受事件丢失或者后续增加持久化队列。WebRTC 依赖 ZLMediaKit 的 WebRTC 构建和端口配置浏览器播放问题应先用 HTTP-FLV 或ffprobe验证上游媒体流。后续可以继续完善增加更多 V4L2 像素格式和硬件零拷贝路径将多路配置、健康状态和性能指标接入统一运维平台对 RGA、RKNN 和编码阶段采集 P95/P99 延迟增加上传事件的本地持久化和断点补传根据不同模型输出定义独立的后处理插件3路扩大至6路引入更完整的测试视频、模型和设备能力探测。总结这个项目的价值在于把 RK3588 上分散的硬件能力组织成了一条可部署的视频 AI 产品链路输入侧兼容文件、摄像头和 RTSP计算侧使用 MPP、RGA 和 RKNN识别侧组合 YOLO、ByteTrack 和车牌 OCR输出侧支持 MP4、RTMP 和 Web 播放业务侧还可以继续连接 MQTT、OLED 和继电器。从代码结构看项目采用“输入分支统一、阶段线程解耦、队列有界、网络异步、worker 进程隔离”的设计。它更适合作为 RK3588 车牌识别、边缘视频网关和多路实时推理系统的工程基础而不仅是一个模型推理样例。关键词RK3588、Rockchip MPP、RGA、RKNN、YOLO、车牌识别、OCR、ByteTrack、RTSP、ZLMediaKit、WebRTC、MQTT、边缘 AI、C 视频处理
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻