引言
人群密度计数是指估计图像或视频中人群的数量、密度或分布,它是智能视频监控分析领域的关键问题和研究热点,也是后续行为分析、拥塞分析、异常检测和事件检测等高级视频处理任务的基础。随着城市化进程的快速推进,城市人口数量急剧增长,导致各种人员高度聚集的社会活动频繁发生,如果管控不当,极易发生拥挤踩踏事故。例如上海“12.31”外滩踩踏事故中,由于现场管理和应对措施不当,引发了人群拥挤和摔倒,最终造成了重大人员伤亡的严重后果。如果有精度良好的人群计数系统实时统计相关场所的人群数量、分布或密度等信息,及时发现人群拥挤和异常行为并进行预警,以便采取措施进行疏导,就可以避免悲剧的发生。性能良好的人群计数算法也可以迁移到其他目标计数领域,如显微图片中的细菌与细胞计数、拥挤道路上的汽车计数等,拓展人群计数算法的应用范围.因此,人群计数方法的研究有着重要的现实意义和应用价值。
显然的是传统的人群计数方法具有一定局限性,无法从图像中提取更抽象的有助于完成人群计数任务的语义特征,使得面对背景复杂、人群密集、遮挡严重的场景时,计数精度无法满足实际需求。近年来,深度学习技术发展迅猛,在许多计算机视觉任务中得到成功应用,促使研究人员开始探索基于卷积神经网络的人群计数办法.相比于传统方法,基于CNN的人群计数方法在处理场景适应性、尺度多样性等问题时表现更优。而且由于特征是自学习的,不需要人工选取,可以显著提升计数效果,因此已经成为当前人群计数领域的研究热点。使用CNN的人群计数方法主要分为直接回归计数法和密度图估计法2类。直接回归法只需向CNN送入人群图片,就可以直接输出人群数量,适用于人群稀疏场景。在密度图法中,CNN输出的是人群密度图,再以数学积分求和的方式计算出人数.这类方法性能的好坏一定程度上依赖于密度图的质量。为了提升密度图质量,会引入新的损失函数来提高密度图的清晰度和准确度
故本项目通过采用深度学习方法获取人群密度图已估计人群数量,使用python语言搭建MSCNN网络实现实时生成人群密度图以达到估计人群数量的目的。其最终实现效果如下图可见:
01基本介绍
1.1 环境要求
本次环境使用的是python3.6.5+windows平台。主要用的库有:
opencv模块。在计算机视觉项目的开发中,opencv作为较大众的开源库,拥有了丰富的常用图像处理函数库,采用C/C++语言编写,可以运行在Linux/Windows/Mac等操作系统上,能够快速的实现一些图像处理和识别的任务。
numpy模块。numpy系统是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表结构要高效得多(该结构也可以用来表示矩阵。
pillow模块。PIL是理想的图像存档和批处理应用程序。您可以使用库创建缩略图,在文件格式、打印图像等之间进行转换。它提供了广泛的文件格式支持、高效的内部表示和相当强大的图像处理功能。核心图像库是为快速访问以几种基本像素格式存储的数据而设计的。为通用图像处理工具提供了坚实的基础。
keras模块。Keras是一个由Python编写的开源人工神经网络库,可以作为Tensorflow、Microsoft-CNTK和Theano的高阶应用程序接口,进行深度学习模型的设计、调试、评估、应用和可视化。
1.2MSCNN网络介绍
MSCNN作为多尺度卷积神经网络与传统机器学习算法相比,深度学习模型能更有效地从高维复杂输入中自动提取特征。卷积神经网络是应用最广泛的深度学习模型之一,通过卷积、池化等操作提取原始数据的特征,并通过权连接层输出模型的计算结果。其中,卷积核的大小在一定程度上影响着特征提取的效果和模型的故障识别能力。MSCNN是一种改进的卷积神经网络,通过不同大小的卷积核从多尺度挖掘特征信息,有效解决了传统CNN模型卷积核的自适应选择问题。其网络流程如下可见:
02模型搭建
2.1MSCNN网络搭建
在CNN网络的基础上搭建多尺度技术,其实现过程为将某一中间层或某几层中间层的输出特征与最后一层的输出特征连接、展平,作为 CNN 的输出,结合高低层次的输出可以对设备退化过程进行更全面地学习。
def MSCNN(input_shape):
inputs = Input(shape=input_shape)
x = Conv2D(64, 9, activation='relu', padding='same')(inputs)
x = MSB(4 * 16)(x)
x = MaxPooling2D()(x)
x = MSB(4 * 32)(x)
x = MSB(4 * 32)(x)
x = MaxPooling2D()(x)
x = MSB(3 * 64)(x)
x = MSB(3 * 64)(x)
x = Conv2D(1000, 1, activation='relu', kernel_regularizer=l2(5e-4))(x)
x = Conv2D(1, 1, activation='relu')(x)
model = Model(inputs=inputs, outputs=x)
return model
2.2MSB结构创建
通过使用multi-scale blob模块(类Inception结构)可以实现对相关特征的提取,搭建Mult
def MSB(filters):
params = {'activation': 'relu', 'padding': 'same',
'kernel_regularizer': l2(5e-4)}
def f(x):
x1 = Conv2D(filters, 9, **params)(x)
x2 = Conv2D(filters, 7, **params)(x)
x3 = Conv2D(filters, 5, **params)(x)
x4 = Conv2D(filters, 3, **params)(x)
x = concatenate([x1, x2, x3, x4])
x = BatchNormalization()(x)
x = Activation('relu')(x)
return x
return f
03密度图可视化
3.1密度图的建立
人群密度图的生成需要使用高斯滤波处理,原因在于在空间中计数时,每个人只占一个像素点导致最终得到的密度分布图特别稀疏,会导致模型收敛到全0状态。因此通过高斯处理后,密度图呈现出热力图的形式,一定程度上解决了稀疏问题。而且高斯处理后的密度图,总计数是不变的。
其中生成密度图代码如下:
model = MSCNN((224, 224, 3))
model.load_weights('model\\final_weights.h5')
cap=cv2.VideoCapture("test.mp4")
while True:
ret,frame=cap.read()
img = frame
ori_img=img.copy()
img = cv2.resize(img, (224, 224))
img = img / 255.
img = np.expand_dims(img, axis=0)
dmap = model.predict(img)[0][:, :, 0]
dmap = cv2.GaussianBlur(dmap, (15, 15), 0)
height, width = dmap.shape
fig, ax = plt.subplots()
plt.figure(figsize=(10, 10))
fig.set_size_inches(width / 100.0 / 3.0, height / 100.0 / 3.0)
plt.gca().xaxis.set_major_locator(plt.NullLocator())
plt.gca().yaxis.set_major_locator(plt.NullLocator())
plt.subplots_adjust(top=1, bottom=0, left=0, right=1, hspace=0, wspace=0)
plt.margins(0, 0)
plt.imshow(dmap)
plt.savefig("result.jpg")
re_img=cv2.imread("result.jpg")
ori_img=cv2.resize(ori_img,(400,400))
re_img = cv2.resize(re_img, (400, 400))
cv2.imshow("mg0",ori_img)
cv2.imshow("img1", re_img)
cv2.waitKey(1)
#visualization(img[0], dmap)
print('count:', int(np.sum(dmap)))
完整代码:
链接:
https://pan.baidu.com/s/1rzMZ...
提取码:0w78
李秋键,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等。