人群计数的方法分为传统的视频和图像人群计数算法以及基于深度学习的人群计数算法,深度学习方法由于能够方便高效地提取高层特征而获得优越的性能是传统方法无法比拟的。本文简单了秒速了近几年,基于单张图像利用CNN估计人群密度图和计数的方法。

  1. 传统的人群计数方法

    传统的人群计数方法可以分为两类,基于检测的方法和基于回归的方法。

    • 基于检测的方法

      早期的计数方法主要是基于检测的方法,使用一个滑动窗口来检测场景中的人群,并统计人数。 基于检测的方法可以分为两类:

      • 基于整体的检测,训练一个分类器,利用从行人全身提取到的小波,HOG,边缘等特征检测行人。 学习的方法有SVM,boosting和随机森林等。 基于整体的方法主要适用于稀疏人群,随着人群密度的提升,人与人之间的遮挡越来越严重,这种方法就不再适用。
      • 基于部分的身体的检测。 为了处理人与人的遮挡问题,主要通过检测身体的部分结构,例如头,肩膀等去统计人群的数量。这种方法比之基于整体的检测,在效果上有略微的提升。
    • 基于回归的方法

      论何种基于检测的方法,都很难处理人群之间严重的遮挡问题。所以,基于回归的方法逐渐被用来解决人群计数的问题。 基于回归的方法,主要思想是学习一种特征到人群数量的映射。该类方法主要分为两步:1. 提取场景的低级特征,例如例如前景特征,边缘特征,纹理和梯度特征;2. 学习一个回归模型,例如线性回归,岭回归或者高斯过程回归,学习一个低级特征到人群数的映射关系。

    • 基于密度图的方法

      基于回归的方法虽然能在一定程度上解决遮挡的问题,但是由于是使用整幅图像的特征进行回归技术,从而忽略了图像的空间信息。在2010年的Visual Geometry Group University of Oxford提出了:学习图像的局部特征和其相应的密度图之间的映射,从而在计数的过程中加入图像的空间信息。 论文地址:Learning To Count Objects in Images . 该论文最早提出使用密度图来进行计数的方法,后来很多的图像计数多数基于此方法。

  2. 基于深度学习的方法

深度学习在计算机的视觉的识别,分割,检测相比传统的方法都取得了很大的进步,人群计数也不例外,近年来的方法多数是使用深度学习的方法,利用深度学习的学历能力得到图像到其相应的人群密度图或者数量。

传统的方法通常都是输入图像的一个patch,并且通常分为两个步骤:特征的提取,回归或者分类,而基于CNN的方法则输入是一种完整的图片,并且进行end-to-end的训练。无论是使用回归或者密度图,CNN的方法都能取得较好的结果。

本文主要总结下,近几年关于使用CNN基于单幅人群图像生成密度图的方法。

MCNN (cvpr2016)

zhang等人提出了 Multi-column Convolutional Neural Network (MCNN)网络来预测人群的密度图。MCNN中有三大创新:

  • 提出了MCNN网络,能够处理任意大小的图像,并且使利用3个具有不同卷积核大小的网络来分别提取人群图像的特征,来适应人群头部大小的变化。
  • 提出一种根据人头标记生成人群密度图的方法
  • 构建了一个新的数据集 Shanghaitech ,包含1198张图像约有330000个人头标记数据。

作者认为,人群计数存在着以下的困难:

  1. 前景的分割,现有的计数方法通常需要前景分割,而前景分割是很困难的。使用MCNN网络则不需要进行前景分割,输入任意的人群图像,通过CNN网络直接估计其密度图。
  2. 密集人群存在严重的遮挡
  3. 人群图像中人的尺度存在着较大的差异就需要融合多种图像的特征来估计人群的数量,这些特征人工则很难设计。

为了应对以上问题,作者提出了MCNN网络,使用3个不同尺度的卷积网络提取图像的多尺度特征,并使用\(1 \times 1\)的卷积核将多尺度的特征融合到一起。 其网络结构如下:

这类利用多个网络的模型具有较多的参数,计算量大,无法进行实时的人群计数预测。而且多阵列的网络并不能如所描述的一般,提取不同的尺度的人头特征。

密度图的生成

人群计数的数据集,通常是标记了人头的位置,就需要根据人头位置的数据来生成相应的人群密度图。 MCNN种提出了一种自适应卷积核的方法,来生成相应的密度图。

在由标记生成密度图的过程,首先将每个人头对应的位置设置为1,然后对该图像进行高斯卷积。

代码如下:

img = cv2.imread(path)
density = np.zeros((img.shape[0],img.shape[1])) for i inr range(0,len(gt)):
if int(gt[i][1]) < img.shape[0] and int(gt[i][0]) < img.shape[1]:
density[int(gt[i][1]),int(gt[i][0])] = 1
density = cv2.GaussianBlur(density,(5,5))

这种构建的密度图是假设人头相对于图像平面是独立存在的,事实上,由于透视畸变的村子,不同位置人头对应着不同大小的像素区域。 因此,要想生成精确的人群密度图像,就要考虑单应性引起的畸变,但是畸变参数是不容易得到的。故,作者假设每个头部周围的人群分布比较均匀,那么头部与其最近的k个邻居之间的平均距离,给出了一个合理的几何失真估计(由透视效果引起)。而且作者在拥挤的场景中,头部的大小通常与相邻两个人中心的距离有关。 作为一种折衷,对于那些拥挤场景的密度图,建议根据每个人与其邻居的平均距离来自适应地确定每个人的扩展参数,也就是高斯卷积核的方差。

也是就,其为每个人头位置根据其与周围相邻的人头的距离来构建卷积的方差,然后将所有人头点卷积后的结果累加到一起,就是最终生成的密度图。具体代码如下:

    gt_count = np.count_nonzero(gt)
if gt_count == 0:
return density # FInd out the K nearest neighbours using a KDTree
pts = np.array(list(zip(np.nonzero(gt)[1].ravel(), np.nonzero(gt)[0].ravel())))
leafsize = 2048 # build kdtree
tree = scipy.spatial.KDTree(pts.copy(), leafsize=leafsize) # query kdtree
distances, locations = tree.query(pts, k=4) for i, pt in enumerate(pts):
pt2d = np.zeros(gt.shape, dtype=np.float32)
pt2d[pt[1],pt[0]] = 1.
if gt_count > 1:
sigma = (distances[i][1]+distances[i][2]+distances[i][3])*0.1
else:
sigma = np.average(np.array(gt.shape))/2./2. #case: 1 point #Convolve with the gaussian filter
density += scipy.ndimage.filters.gaussian_filter(pt2d, sigma, mode='constant')

CP-CNN (cvpr 2017)

CP-CNN( Generating High-Quality Crowd Density Maps using Contextual Pyramid CNNs) 使用图像的全局和局部特征信息生成估计人群图像的密度图。

其网络结构如下:

绿色子网络表示对整张输入图像做特征提取并分类(类别为作者分好的密度等级,即当前输入图像属于哪个密度等级),并将分类结果张成一个与密度特征具有相同高和宽的图像(全局上下文);蓝色子网络对原图中割出的patch做同样的操作,得到局部上下文。最终将全局和局部上下文特征与原图产生的密度图(黄色部分)在通道维度拼接(concate)。该方法的初衷是为了考虑一幅图像中人群的全局密度和局部密度信息,最后对整个特征做约束,使得网络对任何一张图像都自适应的学到相应密度等级的特征。

CSRNet (cvpr 2018)

CSRnet网络模型主要分为前端和后端网络,采用剔除了全连接层的VGG-16作为CSRnet的前端网络,提取图像的特征,输出密度图的大小为原始输入图像的1/8。采用空洞卷积神经网络作为后端网络,在保持分辨率的同时扩大感知域, 生成高质量的人群分布密度图。

采用剔除了全连接层的VGG-16网络,并且采用3×3的卷积核。研究表明,对于相同大小的感知域,卷积核越小,卷积层数越多的模型要优于那些有着更大卷积核且卷积层数较少的模型。为了平衡准确性和资源开销,这里的VGG-16网络采用10层卷积层和3层池化层的组合。后端网络采用六层空洞卷积层,空洞率相同。最后采用一层1×1的普通卷积层输出结果,其网络结构如下:

CSRNet的主要思路是,使用预训练的VGG进行特征提取,后面再使用空洞卷积,在扩大感受野的同时,生成人群的密度图。

ic-CNN (ECCV 2018)

Iterative Crowd Counting,其采取的思路是首先生成低分辨率的密度图,然后进一步的细化来生成高分辨率的密度图。该网络结构由两个CNN分支组成,一个分支用来生成低分辨率的密度图,另一个使用生成的低分辨率的密度图以及提取的特征图的基础上,生成高分辨率的密度图。其网络结构如下:

该网络的输入是一个三元组\(\mathcal{D}=\left\{\left(X_{1}, Y_{1}, Z_{1}\right), \ldots,\left(X_{n}, Y_{n}, Z_{n}\right)\right\}\),其中\(X_i\)是输入的图像,\(Y_i\)是和原图像相同分辨率的密度图,\(Z_i\)则是低分辨率的密度图。

对于生成低分辨率密度图的分支LR-CNN,其输入是\(X_i\),则可以用如下公式表示

\[\hat{Z}_{i}=f_{l}\left(X_{i} ; \theta_{l}\right)
\]

其中,\(\hat{Z}_{i}\)是生成的低分辨率的密度图。

对于生成高分辨率的分支HR-CNN,其输入则是\(X_i,\hat{Z_i}\),其表示如下

\[\hat{Y}_{i}=f_{h}\left(X_{i}, \hat{Z}_{i} ; \theta_{l}, \theta_{h}\right)
\]

其损失函数为

\[\mathcal{L}\left(\theta_{l}, \theta_{h}\right)=\frac{1}{n} \sum_{i=1}^{n}\left(\lambda_{l} L\left(\hat{Z}_{i}, Z_{i}\right)+\lambda_{h} L\left(\hat{Y}_{i}, Y_{i}\right)\right)
\]

使用HR-CNN输出的高分辨率的密度图作为最终的输出结果。其表现如下

SANet(ECCV 2018)

Scale Aggregation Network for Accurate and Efficient Crowd Counting,该方法同样考虑要提取每个图像的多个尺度的人头信息,但并不采取类似MCNN的多阵列网络结构,其使用了类似于Inception架构的模块,在每个卷积层都同时使用不同大小的卷积核,最后通过反卷积得到最终的密度图。

简单来说,就是使用一系列的Inception结构提取不同尺度的特征,再使用反卷积(Transposed CONV)生成高分辨率的密度图,其网络结构如下:

Summary

简单的梳理了下2016年到2018年出现的一些基于CNN生成人群密度图的方法。 可以看出,生成人群密度图的难点仍然是:人头的重叠以及人头尺度的变化。 这两个困难有时候有可以看作是一个:人头尺度变小了,其看着就重叠到了一起。 所以目前主流的方法,仍然是提取多尺度的人头特征信息,当然也有ic-CNN这样的从低分辨率密度图细化到高分辨率的密度图。

基于CNN的人群密度图估计方法简述的更多相关文章

  1. 利用opencv作透明重叠人群密度热度图

    在作热度图的时候我们经常需要将热度图调整透明度后叠加在原图上达到更好的展示效果.比如检测人气密度的热度图: (来自sensetime) 一般作图的时候会第一时间想到matplotlib,因为可以很方便 ...

  2. 人群密度检测MCNN+CSRnet

    MCNN(简单理解): 三列卷积神经网络,分别为大中小三种不同尺度的卷积核,表示为L列(使用大尺度卷积核: 9*9, 7*7, 7*7,7*7), M(使用中等尺度卷积核: 7*7, 5*5, 5*5 ...

  3. 第六篇:R语言数据可视化之数据分布图(直方图、密度曲线、箱线图、等高线、2D密度图)

    数据分布图简介 中医上讲看病四诊法为:望闻问切.而数据分析师分析数据的过程也有点相似,我们需要望:看看数据长什么样:闻:仔细分析数据是否合理:问:针对前两步工作搜集到的问题与业务方交流:切:结合业务方 ...

  4. cvpr2017:branchout——基于CNN的在线集成跟踪

    1.引言 2017年CVPR上有不少关于跟踪的paper.CF方面最引人瞩目的应该是ECO了,CNN方面也有一些新的进展.Branchout是一个基于CNN用bagging集成的在线跟踪方法. con ...

  5. LSF-SCNN:一种基于 CNN 的短文本表达模型及相似度计算的全新优化模型

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 本篇文章是我在读期间,对自然语言处理中的文本相似度问题研究取得的一点小成果.如果你对自然语言处理 (natural language proc ...

  6. Deep Snake : 基于轮廓调整的SOTA实例分割方法,速度32.3fps | CVPR 2020

    论文提出基于轮廓的实例分割方法Deep snake,轮廓调整是个很不错的方向,引入循环卷积,不仅提升了性能还减少了计算量,保持了实时性,但是Deep snake的大体结构不够优雅,应该还有一些工作可以 ...

  7. 基于ros2 dashing的建图导航探索

    基于ros2 dashing的建图导航探索 1. 环境准备 安装ros2 dashing, 参考链接: https://index.ros.org/doc/ros2/Installation/Dash ...

  8. 基于Delphi的三层数据库系统的实现方法

    基于Delphi的三层数据库系统的实现方法   1  引言 当前的数据库应用系统中,按其结构划分为两类,一类是两层结构的数据库应系统,另一类是多层结构的数据库应用系统. 两层结构的数据库应用系统包括客 ...

  9. Pathchirp—有效的带宽估计方法(二)

    上一个blog介绍了有效带宽估计方法:pathload.http://blog.csdn.net/ice110956/article/details/11126491. 做一个小小的总结:pathlo ...

随机推荐

  1. 深入理解SpringAOP之代理对象

    本篇文章主要带大家简单分析一下AOP的代理对象,至于AOP是什么,如何配置等基础性知识,不在这里讨论.阅读前请先参考:代理模式,在这之前我们需要了解springframework的三个核心接口与get ...

  2. Python人脸识别最佳教材典范,40行代码搭建人脸识别系统!

    Face Id是一款高端的人脸解锁软件,官方称:"在一百万张脸中识别出你的脸."百度.谷歌.腾讯等各大企业都花费数亿来鞭策人工智能的崛起,而实际的人脸识别技术是否有那么神奇? 绿帽 ...

  3. .NET开发微信小程序-微信支付

    前台MD5加密代码 /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algor ...

  4. MySQL性能调优——锁定机制与锁优化分析

    针对多线程的并发访问,任何一个数据库都有其锁定机制,它的优劣直接关系着数据的一致完整性与数据库系统的高并发处理性能.锁定机制也因此成了各种数据库的核心技术之一.不同数据库存储引擎的锁定机制是不同的,本 ...

  5. java并发之ReentrantLock学习理解

    简介 java多线程中可以使用synchronized关键字来实现线程间同步互斥,但在jdk1.5中新增加了ReentrantLock类也能实现同样的效果,并且在扩展功能上也更加强大,比如具有嗅探锁定 ...

  6. SSM-SpringMVC-20:SpringMVC中处理器方法之返回值void篇

      ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 处理器的方法我们之前做过,返回值为String的,返回值为ModelAndView的,我们这个讲的这个返回 ...

  7. jQuery 素材 缩略图轮播集合

    http://www.17sucai.com/pins/demo-show?id=27124 http://www.17sucai.com/pins/demo-show?id=4712  楼盘详情缩略 ...

  8. Spring Security 实战:QQ登录实现

    准备工作 1.在 QQ互联 申请成为开发者,并创建应用,得到APP ID 和 APP Key.2.了解QQ登录时的 网站应用接入流程.(必须看完看懂) 为了方便各位测试,直接把我自己申请的贡献出来:A ...

  9. Spring Boot中使用Actuator的/info端点输出Git版本信息

    对于Spring Boot的Actuator模块相信大家已经不陌生了,尤其对于其中的/health./metrics等强大端点已经不陌生(如您还不了解Actuator模块,建议先阅读<Sprin ...

  10. LaTeX 中图片格式错误情况

    Unknown graphics extension: .eps 利用宏包usepackage {graphicx} 是图片和pdflatex一起用时的错误.注:{不是所有的时候,有时候也能通过} 两 ...