5个课时完成智慧社区AI实战项目!
欢迎大家来到AidLux零基础边缘端智慧社区训练营~
本节课为训练营的第二节,内容框架如下:
1 高空抛物场景的背景
2 高空抛物的方案设计
3 高空抛物的算法实现
4 PC端以及AidLux的推理测试
5 课堂小作业
(操作演示视频和开发所需资源物料包可在“AidLux”公众号后台回复“训练营”获取)
1. 高空抛物场景的背景
高空抛物是智慧社区的重要部分之一,主要为主动识别高空中抛下的物体,一般场景为以监看和事后取证为主。
比如上面的图片,我们在很多小区经常会看到类似的高空抛物相机,以仰视的角度。
往住宅楼的角度拍摄,当发生抛物事件的时候,可以实时监测,当发生危险事故时,可以实时追溯,查看当时高空抛物的视频,追溯到底是从哪家的窗口抛出的。
2. 高空抛物的方案设计
高空抛物一般以事件为指标,需要识别出抛出的物体,并完成报警。
当然在实际应用中,也会存在很多难点,主要的难点在于以下几点:
(1)抛出的物体相对于整个楼栋的目标太小;
(2)干扰因素较多,如白天的飞鸟、飘落的树叶、夜晚的背景楼栋灯光等;
(3)环境影响如雨天、雾天、逆光等环境对结果影响较大。
所以在方案设计中需要考虑以上几点,同时考虑整个系统的部署方式、数据采集方式、对于异常的考虑等。
设计整个方案类似如下,通过枪机固定角度位置来采集视频、图片数据,通过交换机传入硬盘上落盘,同时传输到设备端完成算法的推理,将结果反馈到PC端和手机端。
2.1 数据采集
首先是数据采集模块,数据采集模块的难点在于相机的位置和角度的安装,以下是不同层高的楼栋的相机的安装位置的大概参考:
对于不同的层高,建议的安装距离和分辨率选择对应的相机焦距等可以参考如下:
高空抛物的相机可以查看主流一线安防厂家海康,大华,它们都有类似的产品,具体型号可以咨询对应的厂商,以厂商技术人员现场勘测后提供的产品型号为准:
大华的部分设备参考
海康威视的部分设备参考
针对夜间低照度,小区夜间光照不足,不建议通过补光的方式来提高环境照度,这样的环境下可以选型超星光摄像头,最低支持0.0002lux,可以有效保障夜间环境下的监控。
此外白天高空抛物摄像头对着天空,白天有强烈的太阳光会造成逆光现象,可以选型摄像头支持120db的宽动态摄像头,同时也支持背光补偿,在光线复杂和强烈的环境下,仍然能显示好的图像效果。
2.2 算法设计
在相机选型,尽可能规避一些环境影响后,我们开始对算法设计。
高空抛物的场景主要是识别出抛出来的物体,有几种识别方式:
- 使用传统的动态目标检测,如光流检测和帧差法;
- 使用目标检测+目标追踪算法,对抛出的物体先做目标检测,并对检测到的物体做追踪;
- 使用物体追踪+过滤算法;
- 使用视频分类的算法。
对于第一种方法传统方法的动态目标检测,如光流检测和帧差法,稳定性稍差,优点在于对于数据要求低。
对于第二种方法,使用目标检测检测被抛物体,并通过目标追踪对抛出物体的运动轨迹做追踪,会受到背景的影响很大,因为楼宇间的灯光等,同时使用目标检测+目标追踪的方法,其难点在于小目标的检测,很容易出现漏检。
同时运动的物体很多,如晒得被子等,容易出现误检,同时需要大量的数据。
对于第三种方法,针对第二种方法中的目标检测算法的效果不佳,采用高斯背景建模的方法,过滤背景信息;
再使用目标追踪如kalman滤波,完成运动轨迹的记录,同时针对第二种方法中视频中会出现的树叶、飞鸟以及晒衣服等的摆动等不符合抛物运动的轨迹的误检,通过SOM网络进行聚类,SOM(自组织映射神经网络)会对不同运动的轨迹进行分析:
对运动轨迹进行分类:
排除掉不符合抛物运动的轨迹。
另外可以对卡尔曼滤波追踪的前景图像块,做图像分类,做一次筛选,排除掉不是抛物的物体轨迹。
以上三种方法的识别逻辑是一样的,都是先做目标检测,再对目标检测的物体做追踪。
第二种方法相对于第一种方法,在目标检测环节采用的是深度学习方法;
第三种方法相对于第二种方法,在目标追踪后,针对运动的干扰项,通过SOM对运动轨迹过滤,通过图像分类对目标过滤;
同时目标检测环节用的是传统动态目标检测,这里也可以换成第二种方法中的深度学习目标检测的方法(如果不考虑实时性)。
对于第四种方法,使用视频分类的方式,即对一段时间内的视频流做视频分类,这里可以通过第三步中先通过视频抽帧完成高斯背景建模,过滤掉背景后,再对前处理后的视频完成视频的分类,使用视频分类的方式。
在后处理时,对分类阈值的判断逻辑,以及对输入模型的视频时长等比较讲究,这种方法目前看在满足实时性和精确性时较为折中的一种方法。
3. 高空抛物的算法实现
3.1 算法方案选择
本次训练营课程中,因为涉及到高空抛物数据集的缺乏,所以在上面的四种方法中,主要选择第一种方法。
大家在有数据集支撑的情况下,可以选择第三种或者第四种方法。
第二种方法目标检测+追踪的方式,对上游任务目标检测的要求较高,实际情况下的小目标容易漏检和误检,不建议使用。
3.2 算法实现
我们的流程是先在PC端完成算法的实现后,再移植到安卓端。所以大家可以看到我们的百度网盘里面的代码有两个文件夹,highthrow_b文件夹为在PC端运行的代码,aidlux_highBuildingThrow为在android端运行的代码。
而针对于第一种的传统算法中,一般会有帧差法或者光流检测。
但是这都是最初级的方法,因为有许多局限性,比如帧差法对噪声敏感,无法避免对树叶的误检,在摄像头有轻微摇晃的情况下也会有很多误检,也无法适应光线变化等;
光流法也是相同的问题,而且光流法还有另外一个最大的问题是其基于稀疏特征点匹配的算法,因此实际上没有很好的办法将整张图的特征点分为不同的目标——虽然有稠密光流检测算法,但是耗时较长。基于此,我们可以将第三种方法中的“背景建模”加入第一种方法中。
只要一定量高质量的图片,仍然可以产生非常有价值的东西,例如高速场景危险事件告警。
3.2.1去抖动
背景建模的前提是保证摄像机拍摄位置不变,保证背景是基本不发生变化的。
如路口的监控摄像机,只有车流人流等前景部分能发生移动,而马路树木等背景不能发生移动。
所以这里我们防止相机镜头发生抖动,可以加上去抖动的算法,通过匹配算法实现,在第二节课代码的,highthrow_b/adjuster.py下:
去抖动后的效果如下:
其主要的原理是通过每张图的特征,找到两个图片的关键点,并基于关键点获得变换矩阵后,将原图通过变换矩阵变换后,与第一张原始图片对齐。
在去抖动后,将当前图与初始图对比,获得图片的差分图,在adjuster.py下:
获得的差分图如下:
由此可见差分图能显示出初始化图片与后面的图片之间的差别。
3.2.2 背景建模
背景建模主要是为了检测运动物体,输出前景图片
在获得图片的差分图后,将差分图放入背景建模中,获取前景运动图。
背景建模在opencv中主要包含knn建模和高斯建模(MOG2)两种方法,这里我们选择的是KNN的方法,在knnDetector.py文件下: 其中history表示影响背景模型的历史帧数,dist2Threshold 表示像素和样本之间平方距离的阈值,当大于阈值的话,则为前景:
获得结果如下:
大家会发现通过knn的方法对后面的背景中的光线变化敏感,但是也不太容易丢失掉小物体,这里高空抛物的目标一般为小目标,所以选择这个算法。这里大家可以试试高斯混合建模、MOG2等其他方法。
3.2.3 形态学处理
从上图中可以看到,前景的mask 中存在很多的干扰,如灯光的干扰等,再通过形态学处理将干扰项移除。
首先通过开运算将前景中的毛刺过滤掉,在knnDetector.py代码中:
在通过膨胀操作,将目标项变大,方便后面的目标追踪:
获得效果如下:
3.2.4 目标检测
在第三步过滤掉干扰过后,找到目标的外接轮廓,同时过滤掉小的斑点干扰后,提取目标的外接矩形:
至此,基于传统视觉的目标检测完成。
3.2.5 目标追踪
因为动态目标检测出来的是一个个的目标块,这个时候根本不知道上一帧与下一帧的目标对应关系,也就谈不上移动距离。
因此需要跟踪算法,将目标一一对应起来。
传统的跟踪算法,要么是根据HOG特征,要么是根据特征点来进行跟踪。
但是因为高空抛物目标很小,而且移动速度较快,所以不能用传统的基于特征的方式进行跟踪。
我们唯一知道的就是在一帧里面的许多目标框,能不能只依据坐标来跟踪多个目标呢?
答案是有,那就是SORT算法(注意,不是DeepSort,DeepSort依旧会用到特征,在这里不适用)。
SORT是 SIMPLE ONLINE AND REALTIME TRACKING 的简写,并不是什么排序算法。
其核心算法是匈牙利算法+卡尔曼滤波。
SORT算法没有用到特征跟踪,其本质实际上是根据观测的位置预测下一帧出现的位置,而我们预测的高空抛物实际上是有很强的规律的(重物规律强,较轻的物体如塑料袋或者纸板等,不是很规律,但是其速度不快,在每一帧之间基本上都有IOU重叠,因此也不会漏检),所以完全可以用此算法。
(1)sort 算法的初始化
sort初始化的代码,在highthrow_b/main.py 文件中:
(2)sort 算法的更新:
在找到目标后,基于当前帧目标和之前帧目标的kalman滤波的轨迹预测和匈牙利的目标匹配,完成目标追踪:
至此,基于传统视觉的目标高空抛物项目大功告成。
运营main.py代码,我们可以看到整个高空抛物的Demo效果视频。
4. AidLux的推理测试
4.1 AidLux平台介绍
AidLux主打的是基于ARM架构的跨生态(Android/鸿蒙+Linux)一站式AIOT应用开发平台。
用比较简单的方式理解,我们平时编写训练模型,测试模型的时候,常用的是Linux/window系统。
而实际部署到现场的时候,通常会以几种形态:
GPU服务器、嵌入式设备(比如Android手机、人脸识别闸机等)、边缘设备。
GPU服务器我们好理解,而Android嵌入式设备的底层芯片,通常是ARM架构。
而Linux底层也是ARM架构,并且Android又是基于Linux内核开发的操作系统,两者可以共享Linux内核。
因此就产生了从底层开发一套应用系统的方式,在此基础上同时带来原生Android和原生Linux使用体验。
基于ARM芯片,阿加犀开发了Aidlux平台,可以在安卓手机上直接下载Aidlux使用。
再看一下常规的方式,我们想要将算法应用在手机Android时,需要将PC上编写的代码,封装成Android SO库(C++)。
经过测试后,封装JNI调用SO库,最终在Android上使用Java调用JNI,最终再进行测试发布。
因此我们可以看到,这样的流程需要一系列的工作人员参与,比如C++、Java、Python的工程师。
但是大多数算法人员可能会用Python更多一些,比如上面编写的整套算法。
Aidlux将其中的整个开发流程,全部打通,通过Aidlux平台,可以将PC端编写的代码,快速应用到Android系统上。
Aidlux内部一方面内置了多种深度学习框架,便于快速开发。
另外对于多种算子进行了优化加速,很多算法的性能,也都能达到实时使用。
4.2 AidLux平台的使用
目前使用Aidlux主要有两种方式:
(1)边缘设备的方式:阿加犀用高通芯片的S855,和S865制作了两款边缘设备,一款提供7T算力,一款提供15T算力。
(2)手机设备的方式:没有边缘设备的情况下,也可以使用手机版本的Aidlux,尝试边缘设备的所有功能。
并且目前Aidlux已对基本市面上所有的芯片都进行了适配,在手机上运行算法模型,也可以体验优化的效果。
当然在使用过程中,有个共同点,即手机设备和边缘设备采用的Aidlux软件,都是一样的。
因此可以先尝试手机设备的方式,在后期需要更多算力的时候,使用边缘设备,就可以无缝衔接。打开安卓手机的应用商城,搜索AidLux即可下载安装。
打开手机版本的Aidlux软件APP,第一次进入的时候,APP自带的系统会进行初始化。
初始化好后,进入系统登录页面,这一步最好可以用手机注册一下,当然也可以直接点击“我已阅读并同意”,然后点击跳过登录。
进入主页面后,可以点击左上角的红色叉号,将说明页面关闭。
有了手机版本的Aidlux软件,我们可以尝试一系列的AI案例。
当然如果后面在手机上操作编程,还是有点麻烦,因此可以通过IP的方式,直接映射到电脑上操作。
可以点击页面最上方的Cloud_ip。
比如这里是192.168.0.13:8000,打开电脑浏览器地址,输入相应的ip
进入主页面后,可以点击左上角的红色叉号,将说明页面关闭。
有了手机版本的Aidlux软件,我们可以尝试一系列的AI案例。
当然如果后面在手机上操作编程,还是有点麻烦,因此可以通过IP的方式,直接映射到电脑上操作。
可以点击页面最上方的Cloud_ip。
比如这里是192.168.0.111:8000,打开电脑浏览器地址,输入相应的ip。
密码默认是aidlux,输入后即可进入主页面,可以看到其中的内容和手机端是一样的。
至此,我们就可以在电脑上进行操作。按照以下步骤先打开文件管理器,点到home目录下面,第三步upload上传代码文件夹。
得到的文件夹目录如下:
4.3 算法部署
4.3.1VScode的远程连接
在平台上直接修改和运行代码不如在vscode编辑器上修改运行方便,所以这里我们需要通过vscode 远程连接手机ip,首先在vscode中点击左侧栏中的remote explore 按钮。
弹出下面的界面,点击ssh 旁边的设置按钮,出现右侧的下拉选项,选择.ssh/config这个配置:
进入到config配置页面:
Hostname修改成你们手机上面显示的对应的ip地址
Port这里统一默认为9022,不是我们输入PC端的8000端口
User 为root
配置好后,点击进入按钮,需要输入密码,这里密码统一为aidlux
这样就进入了远程界面,我们定位到home 目录下:
这样我们就可以在vscode远程操作手机端了。
4.3.2 移动端适配
在移动端,我们的android端的代码在aidlux_highBuildingThrow文件夹中,在main文件中,导入opencv 使用同时 我们使用的是cvs 的方式来显示图片:
修改cvs读取视频和显示视频的方式:
在终端先cd到项目文件夹下,使用Python main.py:
报错没有安装skimage 库,使用pip 安装skimage库,并使用豆瓣源:
pip install scikit-image -i https://pypi.douban.com/simple/
细心的小伙伴会发现,我们安装的库是aarch64结尾的,aarch64是armv8的一种执行状态,说明这些库是我们安装在android 上的:
安装成功如下:
运行python main.py 命令,结果如下:
至此高空抛物算法在android端的部署完成。
5. 课堂小作业
以上为在智慧社区中的高空抛物算法的解决方案,从摄像头等硬件的选择到算法方案的选择,以及算法的实现,大家可以在数据集充足的情况下尝试第三和第四种方案。
同时作为本节课的小作业,大家可以尝试调试不同的参数,来看看对算法结果的影响,如背景建模方法,这里采用的是knn方法,也可以试试高斯混合建模;
还有sort追踪中的max_age, min_hits等参数,大家尝试完后,最好准备至少两个不同超参对比视频,并能检测到高空抛物行为(视频中能追踪到高空抛物物体)。
将不同参数生成的视频录屏,以及修改参数的图片说明,发给AidLux小助手,针对每个同学的完成情况进行统计。
大家可以在AidLux公众号后台回复“训练营”,获取本次(智慧社区)训练营所需物料资源包,以及智慧安防、智慧交通训练营全部课程内容及对应资源包。
也可以添加AidLux小助手好友,申请加入AI开发者交流群,群内有AidLux工程师和江大白、Rocky、张大刀等众多AI行业专家,可以给予技术指导以及进行交流互动。