从零搭建化工园区 AI 安防监控系统:技术方案、落地实现与工程反思

引言

工业安防领域对 AI 视觉检测的需求日益迫切------火焰识别、安全帽检测、区域入侵告警等场景看似标准,但真正要在一个化工园区内实现多品牌摄像头统一接入、边缘实时推理、告警闭环处理,会面临大量工程细节。本文将从技术选型、系统架构、核心代码实现、到 NPU 部署和优化策略,完整复盘一套基于 YOLO + RK3588 的工业 AI 监控系统的构建过程,并给出中肯的"锐评"和优化路线图。


一、需求分析:8 项核心功能

这套系统瞄准化工园区、智慧工地的安监痛点,覆盖以下检测能力:

  1. 火焰检测 -- 罐区、装置区、泵房、装卸区早期火焰识别
  2. 烟雾检测 -- 电缆沟、配电室、仓库、密闭空间烟雾识别,区分粉尘/雾气
  3. 未佩戴安全帽识别 -- 生产区、巡检、检修、装卸作业实时告警
  4. 人员区域入侵/越界检测 -- 重大危险源、高压区、罐区、危化仓库禁入报警
  5. 离岗/睡岗/脱岗检测 -- 中控室、机柜间、压缩机房关键岗位无人值守告警
  6. 消防通道/安全出口占用检测 -- 消防车通道被车辆货物堵塞告警
  7. 人员违规行为(抽烟/玩手机/未穿工服) -- 防爆区、动火区、装卸区违规抓拍
  8. 视频设备异常诊断 -- 摄像头遮挡、黑屏、断线、移位、模糊、强光自动上报

所有功能统一使用 YOLO 目标检测 作为算法基座,并在边缘端(RK3588)完成推理,支持多品牌摄像头 RTSP 拉流。


二、技术选型与架构设计

2.1 为什么选择 YOLO + RK3588?

  • 算法成熟度:YOLOv5/v8 在工业安防领域是最主流的目标检测方案,8 项功能均可通过微调数据集实现,难度属于"简单~中等"。
  • 边缘部署:RK3588 自带 6TOPS NPU,支持将 PT 模型转换为 RKNN 格式,可实现毫秒级推理,不需依赖云端 GPU。
  • 多品牌兼容:采用标准 RTSP 协议,通过 FFmpeg 拉流,适配海康、大华、宇视等主流摄像头。
  • 开发效率:Spring Boot 单体架构足够承载管理后台与实时监测调度,搭配 C 语言推理服务实现高性能检测,前后端分离,部署灵活。

2.2 系统架构


(示意图:前端→Spring Boot 管理后台→C 推理服务→RK3588 NPU)

  • 前端:Vue/React 管理界面,展示实时监控、告警列表、系统资源看板
  • 后端:Spring Boot 3 + SQLite(边缘轻量数据库),负责设备管理、算法绑定、告警记录、流媒体转换
  • 推理引擎:C 语言 HTTP 服务(基于 RKNN API 和 libmicrohttpd),接收图片路径,返回检测结果
  • 媒体处理:FFmpeg 实现 RTSP→MJPEG 预览、RTSP 抽帧、图片序列合成录像
  • 硬件:RK3588 开发板(运行 Linux),连接多个摄像头

2.3 核心流程

复制代码
摄像头 RTSP → FFmpeg 抽帧 (RtspFrameGrabber)
    → 帧图像文件 → Java 服务调用 C 推理 HTTP 接口
    → 返回检测框 → 告警去重 (AlarmDeduplicator)
    → 证据生成 (抓拍图 + 前后帧合成 MP4)
    → 告警入库 → 前端推送

三、关键代码实现剖析

3.1 数据库设计(SQLite,边缘友好)

系统包含 4 张核心表:cameramodelsalgorithmscamera_algorithm_bindingalarm_record。表结构通过 Spring Boot 启动时自动创建,并添加了关键索引(如告警时间、状态)。

这种设计支持 "一个摄像头绑定多个算法",例如罐区同一路视频既做火焰检测又做入侵检测。

sql 复制代码
-- 摄像头算法绑定关系表(简化版)
CREATE TABLE camera_algorithm_binding (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    camera_id INTEGER NOT NULL,
    algorithm_id INTEGER NOT NULL,
    recognition_params TEXT,   -- JSON: 检测区域坐标、阈值
    alarm_enabled INTEGER DEFAULT 1,
    running_status TEXT DEFAULT '运行中',
    ...
);

3.2 算法-摄像头动态绑定与监测启动

CameraAlgorithmBindingServiceImpl.startYoloMonitoring() 是整个系统的"开关"函数:

根据绑定 ID 获取摄像头 RTSP 地址,解析报警区域参数,然后调用 FrameCaptureService.startCaptureWithConfig() 启动实时监测线程。

java 复制代码
public boolean startYoloMonitoring(Integer id) {
    CameraAlgorithmBinding cb = getInfoById(id);
    Camera camera = cameraService.getDetail(cb.getCameraId());
    AlarmZoneConfig zoneConfig = parseAlarmConfig(cb.getRecognitionParams());
    frameCaptureService.startCaptureWithConfig(camera, zoneConfig);
    updateRunningStatus(id, "运行中");
    return true;
}

3.3 RTSP 抽帧与帧缓冲(环形队列)

RtspFrameGrabber 通过 FFmpeg 以固定帧率将 RTSP 流抽成单帧 JPEG 图片(覆盖模式,避免磁盘写爆),然后通过 Java 的 WatchService 监听文件修改事件,将新帧推入 CircularFrameBuffer 环形缓冲区。

这个设计保证了检测线程始终能从缓冲区拿到最新的几帧,同时支持回溯生成报警录像。

java 复制代码
// 单帧覆盖模式 FFmpeg 命令
ffmpeg -rtsp_transport tcp -i rtsp://... -vf fps=5 -update 1 current_frame.jpg

3.4 YOLO 推理客户端与 C 服务交互

Java 端 YoloDetectorClient 通过 HTTP GET 请求将图片路径、报警区域坐标、输出目录传给 C 推理服务,C 服务加载 RKNN 模型完成前处理、推理、后处理,返回 JSON(包含检测框和抓拍图路径)。

C 服务核心实现要点:

  • 图像预处理:letterbox 缩放 + 填充到 640x640
  • 推理:使用 RKNN API,三尺度特征图解码(YOLOv5 head)
  • 后处理:移除多余 sigmoid(RKNN 输出已包含),NMS 去重
  • 报警区域判断:仅当目标中心点落入指定区域且类别符合时才计为违规
  • 抓拍图绘制:在违规目标周围画红色边界框,并自动保存到输出目录
c 复制代码
// 检测接口伪代码
if (strncmp(url, "/detect", 7) == 0) {
    char* json = detect_and_draw(img_path, ax1, ay1, ax2, ay2, out_dir);
    // 返回JSON:{"code":0, "violation":2, "boxes":[...], "snapshot":"/path/to/snapshot.jpg"}
}

3.5 告警去重策略

工业现场最忌"告警风暴"。AlarmDeduplicator 采用"类别 + 中心坐标距离 + 时间窗口"三重抑制:

  • 计算检测框中心点,若与缓存中某目标距离小于 80 像素且 5 分钟内曾报警,则忽略
  • 缓存自动清理过期记录
  • 使用 synchronized 确保线程安全(边缘场景摄像头数量有限,简单同步即可)
java 复制代码
public synchronized boolean shouldAlarm(Integer cameraId, DetectionBox box) {
    String key = makeKey(box);
    // 遍历同摄像头的历史记录,判断是否接近
    for (Map.Entry<String, LocalDateTime> entry : history.entrySet()) {
        if (isClose(entry.getKey(), box)) {
            return false;  // 抑制
        }
    }
    history.put(key, LocalDateTime.now());
    return true;
}

3.6 证据留存:抓拍图 + 录像合成

触发告警后,系统从帧缓冲区取出前后几秒的图片序列,调用 VideoRecorder.imagesToMp4() 通过 FFmpeg 合成为 MP4 录像。同时抓拍图已由 C 服务直接生成(带框),两者路径一同存入 alarm_record 表。

前端可直接通过 /api/alarm/{id}/snapshot/api/alarm/{id}/video 接口访问。

3.7 系统监控与 NPU 使用率

SystemMonitorUtil 使用 OSHI 库获取 CPU、内存、磁盘信息,并针对 RK3588 读取 /sys/kernel/debug/rknpu/load 文件,解析三核平均使用率。这解决了前期 NPU 使用率始终为 0 的问题,让运维人员能实时看到推理负载。


四、从"空框架"到"可运行"的演进与锐评

4.1 已完成的关键里程碑

  • 端到端监测流水线 从摄像头绑定到告警入库全链路跑通
  • NPU 推理落地 C 服务调用 RKNN 模型,真实利用硬件加速
  • 告警去重与证据链 抑制重复报警,抓拍图与录像完整可追溯
  • 模型转换工具链 Python Flask 服务支持 PT→ONNX→RKNN,带 WebSocket 进度通知
  • 多品牌摄像头接入 通过 RTSP 统一管理,FFmpeg 转换预览流

4.2 仍待补齐的"硬伤"

  1. 缺少置信度阈值业务过滤

    尽管 C 端已有基础阈值,但未按告警类型(如火焰、安全帽)设置差异化阈值,低分误检仍可能触发报警。

  2. RTSP 断流无自动重连

    FFmpeg 进程退出后不会自动重启,工业网络抖动会导致监测中断。

  3. 视频设备异常诊断功能缺失

    摄像头遮挡、模糊、移位等诊断代码为零,无法满足 P1 优先级的运维需求。

  4. 告警推送渠道未实现

    告警仅入库,未对接微信/短信/声光报警器,现场人员无法第一时间获知。

  5. 硬编码路径残留

    模型更新接口中仍写死测试路径,模型文件管理混乱。

  6. 缺乏 API 文档和参数校验

    所有接口无验证,输入异常可能直接导致 500 错误。

4.3 下一步优化清单(按优先级)

优先级 任务 说明
P0 增加按告警类型的置信度阈值配置 在应用层过滤低分告警
P0 RtspFrameGrabber 添加自动重连 监测 FFmpeg 退出,延迟 5 秒重启
P1 实现基础视频异常检测(模糊、遮挡) 使用拉普拉斯方差、画面标准差
P1 接入企业微信/短信告警推送 Webhook 实现,成本低
P2 训练专用模型(安全帽、火焰、烟雾等) 利用转换服务生成 RKNN 文件
P3 增加全局异常处理和参数校验 使用 @RestControllerAdvice 和 Validation
P3 完善模型版本管理界面 支持回滚、批量下载

五、总结

这套 YOLO + Spring Boot + RK3588 的 AI 监控系统,已经从方案设计走到了可实际运行的初版产品。它证明了在化工园区这类苛刻场景下,用成熟的目标检测算法配合边缘 NPU 实现实时安防是完全可行的。尽管还有多项工程细节需要打磨,但其清晰的架构分层、解耦的推理服务、务实的去重策略,为后续迭代打下了坚实基础。

对于有类似需求的开发者,这套系统可以直接作为参考实现,根据自己的现场需求裁剪功能、补充数据集、完善告警联动,就能快速落地一套工业级安监平台。


欢迎交流:如果你有任何关于边缘 AI 部署、YOLO 调优或工业安防系统的疑问,欢迎在评论区留言讨论。

相关推荐
linyanRPA36 分钟前
影刀RPA店群自动化实战:多店铺活动自动报名与促销管理架构设计
运维·自动化·办公自动化·rpa·python脚本·爬虫自动化·店群自动化
mounter6251 小时前
现代 Linux 内存管理的演进与变革:从传统 LRU 到多代架构 MGLRU
linux·服务器·kernel
会Tk矩阵群控的小木1 小时前
安卓群控系统对于游戏工作室实战教程
android·运维·游戏·adb·开源软件·个人开发
佛山个人技术开发2 小时前
GitCode SSH连接配置教程
运维·ssh·gitcode
The Sheep 20232 小时前
Vue复习
linux·服务器·数据库
OpsEye3 小时前
系统负载高一定是CPU问题吗?
运维·cpu·it
源图客3 小时前
Minio配置HTTPS服务
服务器·网络协议·https
修炼室3 小时前
外网环境原生直连校内服务器:基于内网穿透 + SSH 密钥认证的完整实践指南
服务器·ssh·php
Titan20244 小时前
Linux动静态库
linux·服务器·c++
AOwhisky4 小时前
MySQL 学习笔记(第六期):MySQL 备份与恢复
运维·数据库·笔记·学习·mysql·云计算