# 前言

CrowdNet模型是2016年提出的人流密度估计模型，论文为《CrowdNet: A Deep Convolutional Network for DenseCrowd Counting》，CrowdNet模型主要有深层卷积神经网络和浅层卷积神经组成，通过输入原始图像和高斯滤波器得到的密度图进行训练，最终得到的模型估计图像中的行人的数量。当然这不仅仅可以用于人流密度估计，理论上其他的动物等等的密度估计应该也可以。

• Windows 10
• Python 3.7
• PaddlePaddle 2.0.0a0

# CrowdNet模型实现

```def deep_network(img):
x = img
x = conv_bn(input=x, num_filters=64, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=64, filter_size=3, padding=1, act='relu')
x = fluid.layers.pool2d(input=x, pool_size=2, pool_stride=2)
x = fluid.layers.dropout(x=x, dropout_prob=0.25)
x = conv_bn(input=x, num_filters=128, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=128, filter_size=3, padding=1, act='relu')
x = fluid.layers.pool2d(input=x, pool_size=2, pool_stride=2)
x = fluid.layers.dropout(x=x, dropout_prob=0.25)
x = conv_bn(input=x, num_filters=256, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=256, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=256, filter_size=3, padding=1, act='relu')
x = fluid.layers.pool2d(input=x, pool_size=2, pool_stride=2)
x = fluid.layers.dropout(x=x, dropout_prob=0.5)
x = conv_bn(input=x, num_filters=512, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=512, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=512, filter_size=3, padding=1, act='relu')
x = fluid.layers.pool2d(input=x, pool_size=3, pool_stride=1, pool_padding=1)
x = conv_bn(input=x, num_filters=512, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=512, filter_size=3, padding=1, act='relu')
x = conv_bn(input=x, num_filters=512, filter_size=3, padding=1)
x = fluid.layers.dropout(x=x, dropout_prob=0.5)
return x

def shallow_network(img):
x = img
x = conv_bn(input=x, num_filters=24, filter_size=5, padding=3, act='relu')
x = fluid.layers.pool2d(input=x, pool_size=5, pool_type='avg', pool_stride=2)
x = conv_bn(input=x, num_filters=24, filter_size=5, padding=3, act='relu')
x = fluid.layers.pool2d(input=x, pool_size=5, pool_type='avg', pool_stride=2)
x = conv_bn(input=x, num_filters=24, filter_size=5, padding=4, act='relu')
x = fluid.layers.pool2d(input=x, pool_size=5, pool_type='avg', pool_stride=2)
return x

# 创建CrowdNet网络模型
net_out1 = deep_network(images)
net_out2 = shallow_network(images)
concat_out = fluid.layers.concat([net_out1, net_out2], axis=1)
conv_end = fluid.layers.conv2d(input=concat_out, num_filters=1, filter_size=1)
# 双向性插值
map_out = fluid.layers.resize_bilinear(conv_end, out_shape=(80, 60))
# 避开Batch维度求和
sum_ = fluid.layers.reduce_sum(map_out, dim=[1, 2, 3])
sum_ = fluid.layers.reshape(sum_, [-1, 1])```

# 训练模型

• `train.json`文件存放在`data`目录
• `test_new.zip`解压到`data`目录
• `train_new.zip`解压到`data`目录

```data/train/4c93da45f7dc854a31a4f75b1ee30056.jpg	[(171, 200), (365, 144), (306, 155), (451, 204), (436, 252), (600, 235)]
data/train/3a8c1ed636145f23e2c5eafce3863bb2.jpg	[(788, 205), (408, 250), (115, 233), (160, 261), (226, 225), (329, 161)]
data/train/075ed038030094f43f5e7b902d41d223.jpg	[(892, 646), (826, 763), (845, 75), (896, 260), (773, 752)]```

```import json
import numpy as np
import scipy
from PIL import Image
import matplotlib.pyplot as plt
from matplotlib import cm as CM
import scipy
import scipy.spatial
from PIL import Image
from scipy.ndimage.filters import gaussian_filter
import os

# 图片预处理
def picture_opt(img, ann):
# 缩放的图像大小
train_img_size = (640, 480)
gt = []
size_x, size_y = img.size
img = img.resize(train_img_size, Image.ANTIALIAS)

for b_l in range(len(ann)):
x = ann[b_l][0]
y = ann[b_l][1]
x = (x * train_img_size[0] / size_x) / 8
y = (y * train_img_size[1] / size_y) / 8
gt.append((x, y))

img = np.array(img) / 255.0
return img, gt

# 高斯滤波
def gaussian_filter_density(gt):
density = np.zeros(gt.shape, dtype=np.float32)
gt_count = np.count_nonzero(gt)
if gt_count == 0:
return density
pts = np.array(list(zip(np.nonzero(gt)[1].ravel(), np.nonzero(gt)[0].ravel())))
tree = scipy.spatial.KDTree(pts.copy(), leafsize=2048)
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.
density += scipy.ndimage.filters.gaussian_filter(pt2d, sigma, mode='constant')
return density

# 密度图处理
def ground(img, gt):
imgs = img
x = imgs.shape[0] / 8
y = imgs.shape[1] / 8
k = np.zeros((int(x), int(y)))
for i in range(0, len(gt)):
if int(gt[i][1]) < int(x) and int(gt[i][0]) < int(y):
k[int(gt[i][1]), int(gt[i][0])] = 1
img_sum = np.sum(k)
k = gaussian_filter_density(k)
return k, img_sum```

```# 读取数据列表
with open('data/data_list.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()

line = lines[50]
img_path, gt = line.replace('\n', '').split('\t')
gt = eval(gt)
img = Image.open(img_path)
im, gt = picture_opt(img, gt)

print(im.shape)
plt.imshow(im)```

```k, img_sum = ground(im, gt)
groundtruth = np.asarray(k)
groundtruth = groundtruth.astype('float32')

print("实际人数：", img_sum)
print("密度图人数：", np.sum(groundtruth))
print("密度图大小：", groundtruth.shape)

plt.imshow(groundtruth,cmap=CM.jet)```

## 训练程序

```loss = fluid.layers.square_error_cost(input=map_out, label=label) * 6e5
loss = fluid.layers.mean(loss)```

```py_reader = fluid.io.PyReader(feed_list=[images, label, img_num],
capacity=32,
iterable=True,
return_list=False)
py_reader.decorate_sample_list_generator(paddle.batch(reader.train_reader(data_list_file), batch_size=BATCH_SIZE),
places=fluid.core.CPUPlace())```

```if PERSISTABLES_MODEL_PATH is not None and os.path.exists(PERSISTABLES_MODEL_PATH):
def if_exist(var):
if os.path.exists(os.path.join(PERSISTABLES_MODEL_PATH, var.name)):
print('loaded: %s' % var.name)
return os.path.exists(os.path.join(PERSISTABLES_MODEL_PATH, var.name))

fluid.io.load_vars(exe, PERSISTABLES_MODEL_PATH, main_program=fluid.default_main_program(), predicate=if_exist)```

```# 是否使用GPU
USE_CUDA = True
# 模型参数保存路径
PERSISTABLES_MODEL_PATH = 'persistables_model/'
# 预测模型保存路径
INFER_MODEL = 'infer_model/'
# 训练轮数
EPOCHS_SUM = 800
# Batch大小
BATCH_SIZE = 6
# 图像列表路径
data_list_file = 'data/data_list.txt'```

# 预测

```import matplotlib.pyplot as plt
from matplotlib import cm as CM
import os
import numpy as np
import paddle.fluid as fluid
from PIL import Image

# 是否使用GPU
USE_CUDA = True
INFER_MODEL = 'infer_model/'

place = fluid.CUDAPlace(0) if USE_CUDA else fluid.CPUPlace()
exe = fluid.Executor(place)

[inference_program,
feed_target_names,
fetch_targets] = fluid.io.load_inference_model(INFER_MODEL, exe)```

```image_path = "data/test/00bdc7546131db72333c3e0ac9cf5478.jpg"
test_img = Image.open(image_path)
plt.imshow(test_img)```

```test_img = test_img.resize((640, 480), Image.ANTIALIAS)
test_im = np.array(test_img) / 255.0
test_im = test_im.transpose().reshape(1, 3, 640, 480).astype('float32')

results = exe.run(program=inference_program,
feed={feed_target_names[0]: test_im},
fetch_list=fetch_targets)
density, quantity = results[0], results[1]
q = int(abs(quantity) + 0.5)

print("预测人数：", q)
plt.imshow(density[0][0].T,cmap=CM.jet)```

# 模型下载

0 条评论

• ### 基于PaddlePaddle实现的密度估计模型CrowdNet

CrowdNet模型是2016年提出的人流密度估计模型，论文为《CrowdNet: A Deep Convolutional Network for Dense...

• ### PaddleWeekly | 假期必备！视频版魔法换天小工具开源

开源发展至今，越来越多的开发者共享免费代码的同时，也将自己的项目和代码大方骄傲地分享出来。使用者自由的获得项目成果，贡献者找到成就和价值，然后，更多的开发者加入...

• ### 进展 | 密集人群分布检测与计数

高密度人群聚集容易发生各种意外事件、所以监控与分析高密度人群，防止意外事件发生，具有重要的现实意义，分析高密度人群其中一个最重要的参考就是人群数量、评估聚集人群...

• ### 基于PaddlePaddle实现的目标检测模型SSD

SSD，全称Single Shot MultiBox Detector，是Wei Liu在ECCV 2016上提出的一种目标检测算法，截至目前是主要的检测框架之...

• ### 基于PaddlePaddle实现的目标检测模型SSD

SSD，全称Single Shot MultiBox Detector，是Wei Liu在ECCV 2016上提出的一种目标检测算法，截至目前是主要的检测框架之...

• ### 人群密度估计--CrowdNet: A Deep Convolutional Network for Dense Crowd Counting

CrowdNet: A Deep Convolutional Network for Dense Crowd Counting published in ...

• ### 根植于工业级大规模深度学习应用场景的PaddlePaddle

2018年11月，英特尔人工智能大会（AIDC 2018）在北京国贸酒店举行，这也是英特尔首次专门面向开发者和和技术社区的人工智能大会。PaddlePaddle...

• ### 【词向量】 噪声对比估计加速词向量训练

导语 PaddlePaddle提供了丰富的运算单元，帮助大家以模块化的方式构建起千变万化的深度学习模型来解决不同的应用问题。这里，我们针对常见的机器学习任务，提...

• ### 基于PaddlePaddle语音识别模型

本项目是基于PaddlePaddle的DeepSpeech项目修改的，方便训练中文自定义数据集。

• ### 快到没朋友的YOLO v3有了PaddlePaddle 预训练模型

YOLO作为目标检测领域的创新技术，一经推出就受到开发者的广泛关注。值得一提的是，基于百度自研的开源深度学习平台PaddlePaddle的YOLO v3实现，参...

• ### 快到没朋友的YOLO v3有了PaddlePaddle实现

YOLO作为目标检测领域的创新技术，一经推出就受到开发者的广泛关注。值得一提的是，基于百度自研的开源深度学习平台PaddlePaddle的YOLO v3实现，参...

• ### PaddlePaddle重磅升级，Paddle Fluid v1.4版本发布

继上个版本发布后，PaddlePaddle添加了很多新的特性和工具组件，目前已发展为集核心框架、工具组件和服务平台为一体的端到端开源深度学习平台。

• ### 百度PaddlePaddle开源视频分类模型Attention Cluster，曾夺挑战赛冠军

视频分类问题在视频标签、监控、自动驾驶等领域有着广泛的应用，但它同时也是计算机视觉领域面临的一项重要挑战之一。

• ### 薅百度GPU羊毛！PaddlePaddle大升级，比Google更懂中文，打响AI开发者争夺战

深度学习已经推动人工智能进入工业大生产阶段，而深度学习框架则是智能时代的操作系统。

• ### 基于PaddlePaddle搭建工业级ICNET应用 预测速度超TensorFlow 20%

提起ICNET，就不得不说说ICNET构建的初衷-解决图像语义分割在实时应用中的挑战。图像语义分割（semantic segmentation）是结合了图像分类...

• ### 强烈推荐 | 飞桨最全面的工具组件详解

深度学习技术已经具备了很强的通用性，正在推动人工智能进入工业大生产阶段。飞桨（PaddlePaddle）是百度自研的开源深度学习平台，有全面的官方支持的工业级应...

• ### 强力推荐！飞桨产业级PaddleCV最新全景图

导读：PaddleCV是飞桨开源的产业级CV工具与预训练模型集，提供了依托于百度实际产品打磨，能够极大地方便 CV 研究者和工程师快速应用。使用者可以使用Pad...