赛题名称:公共地点人流量计算的云监管平台
获奖名次:二等奖
项目主要分工:
周泽淼 云端全部业务
张宗浩 边缘端核心业务与算法部分
杨帆 前端框架 部分业务逻辑及宣传视频
针对比赛我们想了很多点子,只可惜好多都没时间去尝试,做出来的云端业务功能又因为快到饭点了也没有给完整演示,而且没想到准备宣传册,稀疏和密集切换的演示视频也忘记准备了只好现场去下视频Σ( °△°|||)所以有点遗憾。
我会把这次比赛中想到的所有想法都罗列在这里,有些是还有待实现但觉得可行的方案分享给大家,一起交流。
在算法部分,我们在比赛中主要做的工作有:
边缘端算法:
1.数据增强及数据集选取 :使用手工标注加网络搜集的人头数据集共1000张,通过亮度变换、对比度、添加噪声、水平翻转等方式增强数据集。之所以使用人头作为数据集的原因是考虑到人身体容易被遮挡,使用人头检测会更精确些
2.稀疏场景检测 :在稀疏场景下,分别对yolov3 yolov3-spp ssd dssd mtcnn FCHD 在人头数据集上训练并比较,初赛时选取FCHD算法,决赛时采用mtcnn算法。另外如果采用人身作为数据集,在yolov3稀疏场景下作为检测,也能达到很好的准确率,但问题是模型过大,如果需要做模型优化建议去做剪枝处理,而mtcnn模型小,在cpu下也有好的效果。(顺便安利下google colab 我们用这个训练算法)
3.精确度的提高 :为了提高算法的精确度,我们借鉴了FCHD及Faster-rcnn调整anchor大小的思想,对anchor进行了调整
比如yolov3原始论文里的anchor如下
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
而实际上在监控画面下,对于人头检测来说根本用不到像373*326这么大的anchor,我们使用K-means聚类生成合适的anchor 使得算法更为准确
另外我们借鉴了yolov3-spp的网络结构 ,在mtcnn的结构基础上适当增加了卷积层和池化层以提取到更多的特征。测试发现,在改进后测试发现在cpu下仍能达到9fps
4.密集场景检测 :为了应对密集场景下使用目标检测不精确的问题,在密集场景下使用mcnn作为人数估计。即稀疏用mtcnn 密集用mcnn。我们根据上一帧检测到的人头数,自动切换相应算法。
5.目标跟踪 为了解决稀疏场景下人群遮挡的问题,我们对KCF goturn sort 进行了测试,最终使用deep-sort作为多目标跟踪,同时也解决了检测算法偶尔的误检问题。不过deep-sort是针对人群重识别做训练的,针对人头数据集应该要重新训练下否则ID显示效果不好,由于时间不允许,所以去掉了deep-sort中的显示跟踪对象ID,只保留了跟踪功能
6.光照检测 自动检测亮度,通过直方图将图像分为过亮、过暗、正常三个等级(等级还可以继续划分,但需要实际去测试),在亮度过暗或过亮的情况下适当调整亮度(建议调整成和训练集图片的平均亮度类似),从而提高准确度。(因此功能需要大量真实数据集做测试,时间不允许,决赛时就采用数据增强的方式代替)
云端算法:
1.人流量预测:云端使用ARMA回归滑动平均模型进行未来人流量预测
2.阈值推荐为了解决安保人员在设置阈值时可能不确定阈值的问题,用户输入摄像头高度及勾画行人可站立区域。通过叉乘法计算圈住的面积,最后通过图片尺寸、圈住的面积、图片人均占地面积、真实地面面积做关系映射,从而实现阈值推荐。
下面是还有待实现但觉得可行的方案
1.算法的融合以提高稀疏场景和密集场景下的检测
之前的思路是采取根据上一帧检测人头结果,超过阈值后切换mtcnn和mcnn 但有个问题就是如果检测算法在某些场景下检测不出人头,比如人数过于密集且小到难以分辨,始终没有超过切换算法的阈值。或者是密度估计法误检率过大,因为环境因素导致画面检测出的人头远远大于正常数且高于阈值,并始终没有低于阈值,这就导致从两个算法退化成了一个算法。
想到的解决方案是同时并行运行两个算法,对两个算法的结果做加权平均处理,对算法加权的值取值多少,则可以通过算法加边云协同解决。
2算法加边云协同 ,提高算法通用性
目前目标检测算法最大的问题就是通用性不够强,可能在某些场合下表现不理想,同时目前的算法部署后很少更新。我们想到了算法加边云协同的思想去解决这个问题。云端就好像是老师,边缘端就好像是学生,我们希望算法拥有“”自学习能力“”。云端部署准确度最高的算法但不要求速度的算法,边缘端首先部署普通的人头目标检测算法,之后每隔1分钟上传一次视频画面,云端收集画面并做数据增强,同时使用准确度最高的算法做标注,此算法仅作为标注使用且无需人工干预,当收集到一定的数据集后云端gpu训练边缘端算法,最后将算法模型传回给特定的边缘端。
边缘端接收到算法模型后会去先每隔k(k=1)分钟做一次效果评价,并将结果反馈回云端,如果效果不好,会将此时的图片交给云端标注并继续训练,如果效果好,会在2k分钟后重新检测并上传(避免每次都上传重新训练)
这样做的优势是每个边缘端都有一套独立的算法,能够针对特定场景下做到准确度最高且无需人工干预,另外由于边缘端是专用场景下目标算法检测,相比通用目标检测可以进一步减少模型深度。虽然加大了云端gpu训练的工作量,但相信在两三周后每个边缘端所需的训练次数将大大减少。
这种思想同样可以应用在第一条中如何设置算法融合加权的数值问题。只要稀疏检测和密集检测的结果相差过大,边缘端将画面反馈回云端,由云端给出结果并重新训练边缘端的两套算法。
3 下雨环境下的人群检测及场景感知能力
下雨环境下影响的主要为室外环境,我觉得使用图像识别最好的方案是在入口处放置一个摄像头,另外此区域可以避雨游客在这里不会打伞,比如景区门禁处。通过统计出入数以计算人流量。如果在入口处没有这样的条件比如要统计某个角落的人流量。由于雨伞或遮挡住头部和上半身,使用密集场景检测和人头检测都很困难,系统便可以和天气系统对接,当此时下雨时切换到检测下半身的算法。
所以通过场景感知能力可以进一步提高算法的准确度。比如检测到场景过于黑暗,可以适当调整亮度和对比,另外还可以和摄像头拍摄角度相结合(比如垂直拍摄和45°俯拍)
4.进一步在anchor上做文章以提高算法精度和速度
目前的通用目标检测是对图像中每个区域都要使用全部的anchor遍历一遍,再使用极大值抑制法去掉一些重合区域高的检测框
(图中只画了3次,太多框了理解下吧=_=)
但由于监控摄像头的角度问题,所以远处的人头尺度较小,近处的人头尺度较大。如果远处目标只用几个小的anchor,图像中间区域只用部分anchor 近处用全部的anchor,使得算法在准确率、速度、召回率等性能上有极大的提升。另外,可以不光用在人头检测,人身检测也同样适用。
5 行人跨摄像头多目标跟踪
很遗憾这方面的内容了解较少,不过也想了一个解决方案
下图中红圈的部分为摄像头,边缘端摄像头通过云端和附近的摄像头共享位置、行人特征、行人位移方向等信息,由云监管平台负责统一指挥这些摄像头以实现跨摄像头跟踪。
目前的MOT多目标跟踪进展还是很有限,我对于目前排名第一的跟踪算法ECO了解也很有限,查到的资料很多都是基于位置或光流法以达到行人跟踪的目的,deep-sort也仅仅是在卡尔曼滤波的基础上加入了行人重识别深度特征以解决ID切换的人体,很多算法还是只解决了单摄像头下短期或长期遮挡的问题,对于跨摄像头跟踪还有待进一步学习。
如果有感兴趣的同学可以去搜一下目前行人重识别RE-ID以及车辆跨目跟踪的解决方案,这里就不再赘述。
6 实际环境下的问题:
通用性是否好?是否能够在黑白(红外)摄像头及鱼眼摄像头下仍能有很好的表现力。黑白摄像头可以使用增强数据集解决,但鱼眼摄像头可能就有点困难。
是否可以在CPU甚至嵌入式环境下运行?因为实际环境下人流量计数仅仅是一个功能,往往是多任务并行的。目前了解到的可行的方法有模型剪枝、tf-lite编译
最后我会抽时间去测试,欢迎对列出的算法思路感兴趣的同学一起私信交流,共同进步。之后会更新业务部分思路分享。