PyPeriShield: “PeriShield”结合了“Perimeter” 周界 和“Shield” 盾牌
****智慧入侵检测系统(主要功能是检测园区周界是否有人入侵,在周界围墙边部署安防摄像头, 因为终端摄像头的算法准确率太低且误判高)
- topic: 分布式集群推理、三维可视化、轨迹跟踪、入侵报警与人脸识别
- 介绍:本项目开发了一套集成多种先进视觉技术的智能园区安全解决方案。 利用分布式集群推理实现高效并行处理,支持大规模数据和复杂场景。 三维可视化平台提供直观的园区实时监控,用户可多视角查看人员和车辆活动,在报警页面能够实时查看报警事件,且可以通过钉钉推送告警。 三维系统支持自定义警戒线和警戒区域,通过实时轨迹跟踪和违规视频回放,自动检测异常行为并保存相关片段,便于事后审查。 设置虚拟围栏进行区域入侵报警,确保及时响应未经授权的进入。 人脸识别技术用于识别已注册人员,并对未授权人员发出警报。(未提供接口) 该系统适用于智慧园区、企业园区和公共场所,提升安全管理效率和安全性。支持1000路视频流实时处理。 项目目标:事件准确率高于98%,每小时误报率低于0.5次,事件及时性小于5s,事件可追溯6个月。
- 客户端入口
- 三维智慧园区:控制摄像头算法开关和参数配置,并展示和交互报警信息。
- Redis
- 参数中心:统一由一个2核2G的容器来解耦三维智慧园区的参数配置,所有的生产容器均通过Redis来获取参数。
- 采集层
- RTSP/SDK服务:通过大华或海康的SDK获取视频流。(5S视频帧批处理)
- 消息队列:用于解耦视频流获取与模型推理,保证高并发下的稳定性和高可用性。
- 处理层
- GPU集群:
- 目标检测与跟踪服务:每个容器运行目标检测和跟踪算法。
- 消息队列:用于解耦模型推理结果和结果后处理,保证负载均衡和高可用性。
- 轨迹管理与报警判断:实时管理目标轨迹,并根据预定义区域和判定线判断是否存在翻围墙行为。
- 存储层
- 硬盘池:临时保存30分钟内的待推理视频和图,以及保存生成的视频回放和入侵图片(通过Nginx暴露地址用于三维播放)。
- 交互层
- 消息队列:用于解耦报警信息和回放获取与推送服务。
- 回放获取与推送服务:从海康和大华服务器下载视频片段并推送到三维智慧园区。
- 报警信息推送服务:将报警信息推送到三维智慧园区后端的API(消息确认机制保证报警信息不丢失)。
- 人脸识别服务:用于识别已注册人员,并对未授权人员发出一级警报推送。(暂时未提供接口)
初始架构设计:架构设计
- 硬盘池iops负载过低导致消费端阻塞。(抽帧处理算法要求10帧/秒)
- 理论单个摄像头的IOPS需求 每秒钟的图像数量 = 10(帧/秒) 每张图像的大小 = 500KB (取最大值) 每个摄像头每秒需要写入的数据量 = 10 * 500KB = 5,000KB = 5MB
- 所有摄像头的总IOPS需求 104个摄像头每秒总共需要写入的数据量 = 104 * 5MB = 520MB
- 转换为IOPS 按每次写入操作对应一个4KB的数据块(最小写入单位),可以计算出总的IOPS需求。 每个摄像头的IOPS = (10帧/秒) * (500KB / 4KB) = 10 * 125 = 1,250 IOPS 104个摄像头的总IOPS = 1,250 IOPS * 104 = 130,000 IOPS
- WD Blue SA500 SATA SSD 4TB 的IOPS性能 4K随机写入 IOPS:约88,000 IOPS (Pcie性能5倍以上成本原因只能申请到SATA SSD)
- 结论 104个摄像头每秒抽取10帧并存储500KB的图像,总共需要130,000 IOPS。而WD Blue SA500 SATA SSD 4TB 的 4K随机写入 IOPS 仅为 88,000 IOPS,因此单个WD Blue SA500 SATA SSD 4TB 无法满足这种高IOPS需求。
- 解决方案:
- 1、替换为SATA SSD(每台主机新申请两个500GB), 硬盘池容量缩小到2T (运维说可以使用到只有1/5) 104个摄像头在30分钟内总共需要存储的数据量 = 520MB/秒 * 1800秒 = 936,000MB < 1TB
- 2、采图改为SDK获取视频帧,批处理存放到硬盘池,减少IOPS需求。推理也获取视频帧,进行批处理推理 减少IOPS需求。(需要保证数据顺序性)
- 3、扩展点: 硬盘池本身支持S3协议, 使用对象存储的方式存储图像和视频。
- cpu资源消耗的问题:RTSP协议采集视频帧,20core 只能保证12路比较合适。
- 采图改为SDK获取视频帧,测试30路视频流,cpu只消耗了10%左右
- 新申请了没有计算卡的主机做采图服务器。
- 采集层和推理层都改为SDK处理5s的视频帧,极大的减少cpu资源消耗(推理需要采用跳帧而不是抽帧的方式)
- 保证采图与推理的高可用性。
- 原先方案是每台主机在本地配置文件安装摄像头id起服务(采集和推理都是这样的方式)。(如果某台主机挂了,则会导致这批摄像头算法失效)
- 解决方案:
- 1、按照是否存在cuda环境变量判断是采图服务还是推理服务。设置采图容器摄像头的上限和推理服务容器的摄像头上限。启动服务容器时,先向Redis服务器 获取任务(以摄像头为任务),任务开始后守护进程需要与Redis服务器保持心跳(10S), 如何采图任务挂了或者主机故障,Redis服务器都会释放任务。这个时候Redis服务器会重新挂起该摄像头,分配到空闲的容器。
- 2、解耦推理和推理数据后处理。推理服务容器只负责推理,推理结果后处理服务容器负责结果后处理(目标跟踪和检测) 。推理服务容器和推理结果后处理服务容器都向Redis服务器注册任务,当服务容器挂了,Redis服务器会释放任务。这个机制与采图一致。(可以当做为抢单系统的机制)
- 3、添加一个监控服务,监控生产容器的生产情况,提供汇报API和实现Redis的广播消息。
- 注意点:方案2 需要加分布式锁,保证共享资源中任务的唯一性。以及注意网络延时问题,避免Redis多次分配任务。(第二点采过坑了)。目前是采用了方案3
- 检测头的性能决定追踪器的性能。尤其是晚上弱光的环境(数据增强和知识蒸馏)
- 实际生产中采集层和推理层的消息,不需要持久化。(已测试)
- 后续新增加的视频流任务,只把自己的服务代码放到容器中。写好与Redis和RabbitMQ的交互代码,然后启动服务即可。不会影响以前的任务。(分布式集群部署请脱离py程序内的思想)
- 网络io的并发,设计初期考虑到了交换机是千兆口,怕承受不住采图的网络io,实际SDK采集视频帧,网络IO也不高(给大华海康点赞-5s视频帧只有130kb OMG)
- 1 demo的效果视频已经上传到tests文件夹下。在摄像头的15米内。准确率高达95%。但是判定线的选取十分的关键。因为项目场景摄像头是50米对射的。需要针对小目标进行优化。 误判率基本保持在每日1-2个
- 2 我们对分布式集群进行了架构的优化,目前是102路视频流,3台20core主机采流,3台A4000推理。比初期架构减少了6台服务器。(已测试)。
- 3 由于保密协议, 我们无法提供生产源码。目前项目中的代码是原型测试代码,用于原型测试, 提供部署思路。