公路灾害 AI 视频检测系统
部署于鲁班猫 RK3588 边缘板卡的高速公路灾害实时检测与报警系统:YOLOv8s + RKNN int8 量化、ByteTrack 跟踪、多级规则报警与 I~IV 级灾害分级、报警取证与 HTTP 可靠上报
公路灾害 AI 视频检测系统技术文档
1. 项目概述
本项目是一套面向高速公路场景的自然灾害实时视频检测与报警系统,用于自动识别并上报公路上发生的倒伏树木(fallen tree)、滑坡(landslide)、路面坍塌(road collapse)、落石(stone) 四类灾害事件。
系统采用”边缘计算 + 云端平台”的架构形态:
- 前端(本系统):部署于鲁班猫 RK3588 边缘计算板卡上,直接对接多路海康黑光球机(RTSP 视频流),本地完成视频解码、AI 推理、目标跟踪、灾害判定、报警取证(截图 + 报警前录像),并通过 HTTP 接口将报警推送到云端管理平台。
- 后端(云端平台,不在本工程内):接收报警消息(含项目号、设备号、报警类别、灾害等级、报警时间、图片与视频 base64),并持续接收各路相机的在线心跳。
系统核心能力:
| 能力 | 说明 |
|---|---|
| 多路视频并行检测 | 每路相机独立进程 + 独立绑定 NPU 内核,单板可支持多路实时检测 |
| 边缘侧轻量化模型 | YOLOv8s 自定义 4 类模型,经 RKNN int8 量化后在 RK3588 的 3 核 NPU 上运行 |
| 多目标跟踪 | ByteTrack 算法对检测目标跨帧关联,抑制单帧误报 |
| 分级报警 | 灾害按 I~IV 级分级(透视修正尺寸/滑坡侵入路面比),误报过滤采用多级规则 |
| 云台巡航联动 | 支持海康球机 ISAPI 预置点巡航,逐预置点切换 ROI 与分级标定参数 |
| 报警取证推送 | 报警瞬间生成带等级的截图与”报警前”录像并 base64 上传 |
| 高可靠推送 | Token 鉴权、失败落盘定时补发、心跳保活、报警超时丢弃(防陈旧) |
| 进程自愈 | 相机进程崩溃/卡死自动重启,单路故障不影响其他路 |
2. 系统总体架构
2.1 进程架构(主进程 + 每相机子进程)
系统采用 Python multiprocessing(强制 spawn 启动方式)构建 1 个主进程 + N 个相机子进程 的架构,每路相机一个独立子进程,进程间互不通信、完全隔离。
┌─────────────────── 主进程(main_multi.py)────────────────────┐
│ 1. 解析配置文件(config/config.yaml,支持命令行参数覆盖) │
│ 2. 初始化全局日志(logs/detection.log) │
│ 3. 创建 shutdown_event(multiprocessing.Event) │
│ 注册 SIGINT/SIGTERM 处理 → 置位事件优雅退出 │
│ 4. 启动 FileServer 线程(HTTP 8080,提供报警图片目录静态访问) │
│ 5. 为每路相机创建 CameraSupervisor(进程监督器)并启动子进程 │
│ 6. 主循环:每 0.5s 轮询所有监督器的健康状态 │
└──────────────────────────▲─────────────────────────────────────┘
│ spawn(每路独立进程,daemon)
│ 传参:相机配置 / 全局配置 / 关闭事件 / 存活共享内存
┌──────── CameraSupervisor(每路相机的"守护")───────────────────┐
│ - multiprocessing.Value("d") 存活心跳:相机进程每帧写入时间戳 │
│ - 进程异常退出 → 记录原因并按策略延迟重启 │
│ - 心跳超时(> hang_timeout 未上报)→ 判定卡死 → terminate/kill → 重启 │
│ - 重启次数受时间窗口预算限制,预算耗尽改为低频探活(不永久放弃) │
└──────────────────────────▲─────────────────────────────────────┘
│
┌──── 相机子进程(camera_pipeline.CameraPipeline × N)────────────┐
│ 绑定 NPU 内核 npu_core(0/1/2,与 RK3588 三核 NPU 对应) │
│ 内部多线程协作(见 2.2) │
└─────────────────────────────────────────────────────────────────┘
2.2 相机子进程内部线程模型
每一路 CameraPipeline 内部以”主检测线程 + 若干后台线程”方式协作,避免媒体编码、网络上传阻塞检测主流程:
| 线程 | 职责 |
|---|---|
| RTSP 采集线程(RTSPCapture) | 独立线程 OpenCV/FFmpeg 拉流,帧跳读,断线自动重连,维护”最新帧 + 帧号” |
| 主检测线程(主循环) | 取帧 → 检测 → ROI 过滤 → 跟踪 → 报警判定 → 画面标注 → 写入视频缓冲 → 触发报警处理 |
| 媒体工作线程(media worker) | 报警后异步生成:报警截图 base64、拼接”报警前”录像 base64 |
| 推送线程(push worker) | 将报警数据 + 图片 + 视频经 HTTP 推送到平台 |
| 视频分片写入线程(VideoBuffer writer) | 恒定帧率把标注帧喂给 ffmpeg,滚动产出 TS 分片 |
| 心跳线程 + 补发线程(HttpClient) | 周期上报设备在线状态;扫描重发失败落盘的报警 |
线程间通过容量为 1 的 queue.Queue 传递任务,并采用”只留最新”策略(放入新任务前清空旧任务),保证报警处理紧跟最新画面;报警数据带生成时间戳,超过 TTL(默认 30s)未完成媒体加工或推送则直接丢弃,避免陈旧报警。
2.3 数据流总览
RTSP 视频流
│ (RTSPCapture 采集线程,frame_skip 跳帧)
▼
最新帧
│ (主线程)
├─→ RKNNDetector.detect() 目标检测(RKNN NPU 推理 + 后处理)
├─→ ROI 多边形过滤(中心点在 ROI 内,滑坡类例外始终保留)
├─→ ByteTracker.update() 跨帧跟踪,输出带 track_id 的轨迹
├─→ AlarmManager.process() 多级规则报警判定(命中→输出 alarm_data)
├─→ 画面标注(类别框/置信度/跟踪号/报警红框+等级水印)
├─→ VideoBuffer.add_frame() 标注帧写入滚动分片缓冲
└─→ (命中报警) 触发 LocalAlarm + 入媒体队列
│ media worker:报警截图 + 拼接报警前视频(base64)
▼
push worker:HttpClient.push_alarm()
│ 失败 → 落盘 pending → 后台线程定时补发
▼
云端报警管理平台(HTTP JSON)
3. 运行环境与硬件部署
3.1 边缘板卡:鲁班猫 RK3588
- 主控 SoC:RK3588,板卡集成 3 个独立 NPU 内核(0/1/2),可并行运行多路神经网络推理;系统将每路相机绑定一个 NPU 内核,实现”3 相机 × 3 核 NPU”的并行吞吐。
- NPU 运行时:系统层安装瑞芯微
librknnrt.so(rknpu2 runtime,aarch64);Python 侧使用rknnlite(rknn-toolkit-lite2,1.6.0,aarch64 wheel)完成模型加载与推理调用。 - 硬件视频编码:视频缓冲优先探测使用 ffmpeg 的 h264_rkmpp(RK3588 硬件 H.264 编码),不可用时自动降级 libx264、再降级 OpenCV avc1。
- GPIO 输出:可通过 libgpiod 控制板卡 GPIO(chip 0 / line 16)驱动蜂鸣器/指示灯等本地声光报警。
3.2 前端视频设备
- 海康黑光球机(支持 RTSP 拉流 + ISAPI 云台控制)。
- 视频分辨率按画面像素坐标体系设计(含 ROI 多边形、透视标定均按 2560×1440 图像坐标系配置)。
3.3 网络与平台
- 板卡通过局域网访问相机 RTSP;通过公网 HTTP 接口与报警平台通信(token 获取、报警上报、心跳上报)。
- 账号/密钥等敏感信息全部集中放置于配置文件,不写入代码。
4. 目标检测模型与推理
4.1 模型选型:YOLOv8s 轻量化模型
- 采用 YOLOv8s(small 档,约 168 层、1115 万参数,原始权重约 21.5MB)作为检测主干,属于可在 RK3588 NPU 上实时运行的轻量化配置;工程内置 ultralytics 源码,用于训练/导出/验证与 PyTorch 调试推理。
- 使用高速公路灾害自建数据集训练,共 4 个类别(类别 ID 自 0 起):
| ID | 类别 key | 中文含义 |
|---|---|---|
| 0 | fallen tree | 倒伏树木 |
| 1 | landslide | 滑坡 |
| 2 | road collapse | 路面坍塌 |
| 3 | stone | 落石 |
4.2 RKNN 模型转换链路(PT → TorchScript → RKNN)
模型转换在 PC 端完成,板卡只做推理:
PyTorch .pt ──①──> TorchScript(.torchscript/.pt) ──②──> RKNN(.rknn) ──③──> 板卡推理
(airockchip/ultralytics_yolov8 (RKNN-Toolkit2 1.6.0) (rknnlite + librknnrt)
rk_opt_v1 分支导出)
- 结构优化导出:使用 airockchip 的优化版 YOLOv8(
rk_opt_v1分支)导出 TorchScript,该分支针对 RK NPU 做了结构优化:将 DFL(Distribution Focal Loss)解码移出网络,减少 NPU 计算量;输出改为 9 个张量(3 个检测尺度 × 每组 reg + cls + cls_sum);其中cls_sum用于部署端快速过滤低置信度框(运行时忽略)。 - RKNN 转换:由 RKNN-Toolkit2 的
rknn.config(mean/std)+load_pytorch+build(do_quantization)+export_rknn完成;本项目实际采用 int8 量化(以现场报警样本图片做校准集),输入1×3×640×640,归一化均值 0、标准差 255。 - 板卡加载:运行时使用
RKNNLite.load_rknn + init_runtime(core_mask=NPU_CORE_0/1/2/AUTO),每路相机通过cameras[].npu_core指定绑定内核。
仓库 weights/ 中保留了多套产物:PyTorch 训练权重(.pt,x86 调试)、RKNN NPU 权重(.rknn,板卡生产)。
4.3 推理引擎 RKNNDetector(多后端封装)
检测器按模型文件后缀自动选择后端:
| 后缀 | 后端 | 用途 |
|---|---|---|
.rknn | RKNNLite(NPU) | RK3588 板卡生产推理,可绑定指定 NPU 内核 |
.pt | ultralytics YOLO(CUDA/CPU) | x86 开发机调试与验证 |
.onnx | onnxruntime CPU | 无 NPU 环境下的推理 |
主要实现方法:
- 预处理(letterbox):保持宽高比缩放至 640×640 并四周补 0(黑边),以匹配模型输入;RKNN 后端额外做 BGR→RGB、NHWC 4 维输入适配。
- 后处理(纯 numpy,不依赖 torch):
- 对 3 个尺度(80/40/20 网格,stride 8/16/32)输出的 reg 分支做 DFL 解码:4 条边分别对 16 bin 做 softmax 后与 0~15 加权求和得到边距;
- 由
xyxy = (grid + 0.5 ± 边距) × stride还原检测框(像素级,先于缩放); - 类别置信度 = cls × 目标分数,阈值过滤(全局阈值 + 每类别独立阈值,如落石类阈值单独放宽到 0.15);
- 类别白名单过滤(只保留训练配置中定义的类别 ID);
- 按类别分组 NMS 去重重叠框;
- letterbox 黑边与缩放坐标还原 + 越界裁剪。
- 类别形状过滤器(降误报):支持按类别配置规则化过滤,如:
aspect_ratio:倒树应为横向长条,要求框宽/高比 ≥ 阈值,竖条目标(如杆、柱)被过滤;dynamic_size:按目标中心 Y 做透视缩放动态限定尺寸上下限(用于过滤远处极小/近处过大的虚检)。
- 性能优化:帧跳读(
frame_skip,隔 N 帧处理一次);检测每 30 帧主动gc.collect()释放中间张量内存;对推理预处理/推理/后处理分别计时上报,供性能统计汇总。
5. 视频采集与目标跟踪
5.1 RTSP 视频采集(RTSPCapture)
- 独立采集线程持续
cap.read(),设置解码缓冲为 1、5s 打开/读取超时;读帧失败自动释放句柄并 2s 后重连,避免长时间阻塞主流程。 - 采用帧跳读机制:每
frame_skip帧才递增一次帧号,主线程按帧号判断”是否处理过该帧”,从而在保证检测效果的前提下降低 NPU/CPU 负载。 - 对外暴露”最新帧 + 帧号”与在线状态(
is_ready:最近 10s 内有新帧),在线状态用于控制心跳发送。
5.2 多目标跟踪(ByteTrack)
- 复用 ultralytics 官方 ByteTrack 实现,参数化配置:高分阈值(直接建轨迹)、低分阈值(参与二次关联)、新轨迹阈值、轨迹缓冲帧数、关联 IoU 阈值。ByteTrack 通过”高分框优先关联 + 低分框补关联”的两阶段匹配策略保持长时跟踪稳定。
- 在跟踪输出基础上,为每条轨迹额外计算相邻帧中心点位移(displacement,像素),供报警逻辑”运动物体(车辆)排除”使用。
5.3 检测区域 ROI 与预置点联动
config/roi_config.yaml按”相机 → 预置点”维护每路相机在各云台视角下的 ROI 多边形(检测区域/车道区域)。- 管线级 ROI 过滤以目标框中心点是否落入多边形(point-in-polygon)为准;滑坡类例外:因滑坡需结合边坡整面判定,不做中心点过滤。
- 当相机启用云台巡航并切换到某个预置点时,自动热更新当前 ROI 与报警分级参数(见 7.4),保证不同视角下检测区域与定级语义正确。
5.4 云台巡航联动(PTZController)
- 通过海康 ISAPI 协议(HTTP + Digest 摘要认证)控制球机:登录握手(拉取系统状态)、枚举/列出预置点、调用预置点
goto转向、支持连续运动控制与停止。 - 巡航逻辑在主检测线程内联驱动:到达预置点后等待 稳定延迟(期间暂停检测,避免画面抖动误报);停留达到间隔后切下一个预置点,切换时同步更新 ROI/分级参数并清空视频分片缓冲(避免跨视角拼接录像)。
6. 报警判定逻辑(AlarmManager)
报警判定是整个系统正确性的核心,采用”逐轨迹状态机 + 多级规则准入 + 滑窗确认 + 分级”的方法,每类灾害可按其特征配置不同规则,实现在低误报率下不漏报。
6.1 报警类别与规则差异
四个报警类别(内部 key 为类别名去空格下划线化:fallen_tree / landslide / road_collapse / stone)分别采用差异化规则:
| 类别 | 目标特征 | 差异化处理要点 |
|---|---|---|
fallen_tree 倒树 | 横向倒伏在路面的树木 | 形状过滤(宽高比);透视修正尺寸分级 |
landslide 滑坡 | 边坡滑体侵入路面 | 独有”路面侵入比 R”判定与分级,不走尺寸分级 |
road_collapse 路面坍塌 | 路面坑洞/坍塌 | 开启”位移排除”滤除经过的车辆;需更多帧确认(10 帧 ≥ 5 帧) |
stone 落石 | 路面落石 | 允许移动目标报警(滚动落石也要报);滑窗 window=1 立即报警 |
6.2 单帧准入规则(每帧对每条轨迹依次判定)
① 全局冷却:上次任意报警后 alarm_cooldown 秒内,不再触发任何新报警
② 逐轨迹冷却:同一条轨迹上次报警后冷却期内跳过
③ 位移判定(按类别开关):
对开启的类别(默认仅 road_collapse),若相邻帧中心位移 > moving_threshold_px(10px),
判定为"运动 = 车辆经过",本帧记为不命中;
静止目标永不过滤(静止的落石/倒树同样危险)
④ 滑坡路面接触判定(仅 landslide):
计算侵入路面比 R = 目标底边与"车道线区间"重叠长度 / 该行路面宽度
R = 0(纯边坡滑坡、未压路面)→ 不报警;
R > 0 才进入后续判定
⑤ 尺寸/比例下限过滤:
滑坡按侵入比 R 是否达到最低档;其余类别将目标尺寸做透视归一化后与
该类最小阈值比较,低于下限(过小虚检)记为不命中
⑥ 滑窗确认:轨迹命中历史维护为滑动窗口(窗口宽度 = 该类 window),
窗口内命中帧数 ≥ min_hits 才最终放行(可容忍偶发漏检;
可选 consecutive=严格连续命中模式)
⑦ 命中 → 记录该轨迹冷却时间,纳入本帧报警集合
任意报警命中后置位全局冷却,防止连环报警刷屏。
滑窗确认参数示例:
| 类别 | window | min_hits | 说明 |
|---|---|---|---|
| fallen_tree | 10 | 6 | 10 帧窗口内 ≥ 6 帧命中(约 1~1.5s) |
| landslide | 10 | 6 | 同上 |
| road_collapse | 10 | 5 | 相对宽松 + 位移排除,滤掉快速经过的车辆 |
| stone | 1 | 1 | 落石事件短暂,命中即报 |
6.3 灾害分级(I~IV 级)
- 默认分级模式:
size_based(按目标尺寸)。 - 目标在画面中的像素尺寸随距离大幅变化,直接按像素分级会导致远处大目标被低估、近处小目标被高估。因此采用透视修正:
- 支持由标定工具(
calib_tool.py,另见项目配套文档)导出的缩放系数公式:linear / quadratic / fractional_linear / robust_fractional / piecewise_linear五种曲线,根据目标中心纵坐标 y 求该位置的像素→归一化缩放系数; - 归一化尺寸 = 目标最大边长 ÷ 该位置的缩放系数;
- 对配置非法(公式/参数缺失或错误)自动回退经验公式并打日志告警,防止静默误判。
- 支持由标定工具(
- 归一化尺寸落入类别阈值区间即定级:
[下限, 上限, 等级]数组,等级为 IV级(最轻)→ I级(最严重);未配置的类别使用default兜底档;多目标同帧取最严重等级。 - 滑坡例外分级:不使用尺寸,而按侵入路面比 R 查独立档位表(如 R<0.15 为 IV 级,0.60~1.01 为 I 级),语义为”封路/侵占路面程度”。
- 兼容模式:非 size_based 时按全局最大置信度落区间定级。
- 置信度模式下按每类各帧最高置信度归并
alarm_type。
6.4 报警数据结构
一次触发输出(内部 alarm_data):
alarm_type:字典{类别 key: 该类最高置信度}(R=0 的滑坡目标剔除,防止误上报);disaster_level:I~IV 级;alarm_time、confidence(全场最高置信度);triggered_track_ids:触发报警的轨迹号列表。
推送时对外映射为平台字段:projectId / deviceId / alarmTime / disasterLevel / imageBase64 / videoBase64 / alarmType。
6.5 逐预置点分级热切换
config/alarm.yaml 提供 preset_alarm → camera_N → 预置点 的分级参数映射(每预置点独立:透视标定公式/参数 + 各类阈值 + 滑坡侵入比档位)。云台切到某预置点时,若存在该预置点配置则热更新 AlarmManager,否则使用全局默认分级;该机制解决”同一目标在不同预置点视角下画面大小不同”的定级一致性问题。
6.6 画面表现
- 检测/跟踪结果实时绘制:类别中文名/置信度/跟踪号、按类别着色框;报警轨迹在
alarm_highlight_duration秒内显示红色高亮框与 ”!ALARM!” 标记。 - 报警截图叠加”灾害等级”红色大字水印(中文字体渲染)。
7. 报警取证:截图与录像
7.1 报警图片
- 报警帧即时编码为 JPEG(质量可配,默认 60)生成 base64 用于推送;
- 同时按
alarm_records/camera_N/YYYY-MM-DD/目录落盘(开关控制),保留最近 N 天(默认 90 天),超期目录自动清理; - 主进程另起一个轻量 HTTP 文件服务器(0.0.0.0:8080) 将
alarm_records目录以静态网页方式暴露,便于后台/浏览器直接查看报警截图。
7.2 滚动录像缓冲(VideoBuffer)
为避免”报警后才开始录”遗漏现场,系统对每路视频做持续滚动分片缓冲,报警时取”报警触发时刻之前”的画面:
- 检测主线程把每帧标注图写入缓冲;独立 writer 线程按目标帧率节拍将最新帧送入 ffmpeg 编码进程(避免突发帧率导致文件时长失真);
- 编码器自动选择可用项:
h264_rkmpp(RK3588 硬编)→libx264(软编)→ OpenCVavc1兜底;码率 2Mbps,GOP 与分片时长对齐; - ffmpeg 以
segment模式输出 1 秒一个的 mpegts 分片(seg_000000NNNN.ts),分片在磁盘保留cache_seconds(默认 25s)后自动清理; - 报警导出规则:只采用”报警时间戳之前已写完且稳定”的分片(保证严格”报警前”视频,不含报警后画面);按序取最近若干分片用 ffmpeg concat(流复制、faststart)合成 MP4;可用分片不足时”有多少取多少”,全无时退化为单帧视频兜底;
- 产物以
data:video/mp4;base64,前缀编码后随报警推送;keep_local控制是否保留本地副本用于检查,默认自动删除临时产物。
8. 报警上报与通信可靠性
8.1 HTTP 上报通道(HttpClient,主通道)
- Token 鉴权:启动后向平台鉴权接口以 GET + 账号参数换取 token(响应 msg 字段),缓存 1500s 自动刷新;请求携带
Authorization: Bearer;收到 401 判定 token 失效,自动重取并重推一次。 - 报警上报:
POST push_url,JSON body 字段见 6.4;浮点数统一保留 2 位小数编码;超时 5s。 - 心跳保活:每
heartbeat_interval(默认 30s)向心跳接口 POST{projectId, deviceId, deivceStatus:"1"};发送前回调检查相机 RTSP 流是否就绪——流离线即暂停心跳,平台据此判定该路离线,流恢复后自动恢复心跳,实现设备在线状态的真实映射。 - 失败补发(磁盘队列):推送失败把 payload 落盘到
pending/<日期>/;后台补发线程每 30s 扫描,从旧到新重发,收到 200 才删除;限制保留天数与每日文件数,防磁盘膨胀。 - JSON 调试落盘:可按开关把每次报警/心跳的推送 JSON 存到
alarm_payloads/camera_N/、heartbeat_payloads/camera_N/(按日期分目录),便于回溯排查。
8.2 报警生命周期保护
- 媒体线程、推送线程均对报警做 TTL 检查(30s):从触发到完成推送超过 TTL 的报警直接丢弃,防止”僵尸报警”上报平台。
- 队列”只留最新”策略确保高并发报警下永远优先处理最新现场。
8.3 备用/扩展通道
- MQTT 通道(mqtt_client):实现 paho MQTT 发布,topic 为
highway/alarm/{alarm_type},QoS=1;发布失败写入 SQLite 缓存(AlarmCacheDB),后台线程周期重连与补发。该通道为早期/备选方案,当前主链路以 HTTP 为准。 - 图片二次上传(image_uploader):支持把报警图片再上传到 HTTP(multipart)或阿里云 OSS(S3 v4 签名)取回 URL;配置为示例地址时自动禁用。
- 接收演示(receiver/):MQTT 订阅端脚本,用于本地联调观察报警消息,非板卡生产组件。
8.4 本地声光报警(LocalAlarm)
- 支持两种触发后端:
- GPIO:libgpiod 控制 RK3588 板载引脚(chip 0 / line 16)输出高电平,驱动蜂鸣器/警示灯;
- 海康 SDK 报警输出:ctypes 加载 ARM 版海康 HCNetSDK 动态库(alarm/corearm),登录设备后置位报警输出通道。
- 可按灾害等级过滤(如仅 I/II 级触发),触发后保持
hold_seconds自动复位。
9. 进程守护与稳定性设计
- spawn 启动:子进程仅通过函数参数继承可序列化配置,规避共享内存/句柄冲突;
- 存活心跳:相机子进程每处理一帧即向共享内存写入时间戳;主进程若发现超过
hang_timeout(默认 30s)未上报即判定卡死,先 terminate、3s 不退再 kill,然后自动重启; - 重启预算:
window_seconds窗口内重启不超过max_restarts次;预算耗尽后按低频间隔持续探活重拉,不永久放弃该相机(网络/相机恢复后自动恢复); - 故障隔离:任一路相机崩溃/卡死自动重启,不影响其他路;可配置关闭监督(恢复”任一路退出即全停”的旧行为);
- 优雅退出:仅 SIGINT/SIGTERM 触发全系统关闭,逐个停止心跳/补发/媒体/推送线程、释放模型(RKNN runtime)、登出云台、关闭视频缓冲与显示窗口。
10. 日志、监控与辅助工具
- 日志系统:全局单例 logger;文件按午夜轮转(保留 30 天),每相机独立目录
logs/camera_N/;控制台/文件开关、级别可配;检测明细、报警触发过程(含各规则命中/等待原因)、性能统计均有分级日志。 - 性能画像(performance_profile):可按开关统计各阶段耗时(取帧/预处理/推理/后处理/ROI 过滤/跟踪/报警逻辑/标注/缓冲/推送等)的 avg/max/帧数,周期输出。
- 内存监控(mem_monitor):独立脚本周期性采样板卡内存占用,用于长时间运行的内存泄漏排查。
- 配套工具脚本:离线视频检测(detect_videos)、JSON 报警解码还原(decode_video_from_json)、抽帧(extract_frames)、图片转 base64(shipin2base64)、接口自测(http_test)、透视缩放系数标定(calib_tool,含标定结果导出到配置)等,均为开发/标定/联调辅助,不进生产主链路。
11. 工程目录与模块职责
| 目录/文件 | 职责 |
|---|---|
main_multi.py | 多进程主入口、进程监督器、优雅关闭 |
camera_pipeline.py | 单相机流水线(线程模型、主循环、报警媒体验证与推送编排) |
camera/ | rtsp_capture.py 采集、ptz_controller.py 海康 ISAPI 云台控制 |
detection/ | rknn_infer.py 多后端推理引擎、byte_tracker.py ByteTrack 封装 |
alarm/ | alarm_manager.py 报警判定核心、local_alarm.py 声光报警、海康 SDK 封装 |
transmission/ | http_client.py 主上报(token/心跳/补发)、file_server.py 图片服务器、mqtt_client.py、image_uploader.py |
utils/ | logger.py 日志、video_buffer.py 滚动录像缓冲、image_storage.py 图片存储、cache_db.py SQLite 报警缓存 |
config/ | 主配置 config.yaml、预置点分级 alarm.yaml、预置点 ROI roi_config.yaml |
weights/ | PyTorch / RKNN 模型权重 |
logs/、alarm_records/、temp_videos/、alarm_payloads/、heartbeat_payloads/ | 日志 / 报警图片 / 录像分片 / 上报 JSON 记录 |
| 顶层各类 .md / 脚本 | 模型部署说明、透视标定文档与工具、测试脚本等 |
12. 关键技术特点总结
- 边缘实时性:RK3588 三核 NPU 并行绑定多路相机;YOLOv8s + RKNN int8 量化 + DFL 外置结构优化 + letterbox 640 输入 + 帧跳读,在板端即可满足实时多路检测。
- 多级报警过滤:冷却 + 位移(车辆)排除 + 滑坡”是否压路”语义判定 + 尺寸下限 + 滑窗确认,从检测框到最终报警层层收敛,兼顾低误报与低漏报。
- 透视归一化分级:通过标定公式把任意视角/任意距离的目标尺寸换算到同一物理尺度再定 I~IV 级,配合云台逐预置点独立标定参数,实现”定级不随视角漂移”。
- 取证完备性:滚动分片录像保证报警必有”报警前 N 秒”录像;报警截图叠加等级水印;报警严格限于触发时刻之前画面。
- 链路可靠性:token 自刷新 + 401 自动重推、失败落盘补发(成功才删)、相机流离线暂停心跳(平台在线状态真实)、陈旧报警 TTL 丢弃、队列只留最新。
- 运行自愈:进程级守护(崩溃/卡死自动重启、窗口限流、低频探活不放弃),单路故障隔离,适合无人值守的边缘长期运行。