Skip to content

Commit 674840f

Browse files
authored
Add pphuman doc (PaddlePaddle#5403)
* add pphuman doc * add pphuman doc & add enable_attr, enable_action * update doc * update pphuman-tech.png
1 parent 6c61979 commit 674840f

File tree

5 files changed

+201
-8
lines changed

5 files changed

+201
-8
lines changed

deploy/pphuman/README.md

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
[English](README_en.md) | 简体中文
2+
3+
# 实时行人分析 PP-Human
4+
5+
PP-Human是基于飞桨深度学习框架的业界首个开源的实时行人分析工具,具有功能丰富,应用广泛和部署高效三大优势。PP-Human
6+
支持图片/单镜头视频/多镜头视频多种输入方式,功能覆盖多目标跟踪、属性识别和行为分析。能够广泛应用于智慧交通、智慧社区、工业巡检等领域。支持服务器端部署及TensorRT加速,T4服务器上可达到实时。
7+
8+
9+
## 一、环境准备
10+
11+
环境要求: PaddleDetection版本 >= release/2.4
12+
13+
PaddlePaddle和PaddleDetection安装
14+
15+
```
16+
# PaddlePaddle CUDA10.1
17+
python -m pip install paddlepaddle-gpu==2.2.2.post101 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
18+
19+
# PaddlePaddle CPU
20+
python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
21+
22+
# 克隆PaddleDetection仓库
23+
cd <path/to/clone/PaddleDetection>
24+
git clone https://github.com/PaddlePaddle/PaddleDetection.git
25+
26+
# 安装其他依赖
27+
cd PaddleDetection
28+
pip install -r requirements.txt
29+
```
30+
31+
详细安装文档参考[文档](docs/tutorials/INSTALL_cn.md)
32+
33+
## 二、快速开始
34+
35+
### 1. 模型下载
36+
37+
PP-Human提供了目标检测、属性识别、行为识别、ReID预训练模型,以实现不同使用场景,用户可以直接下载使用
38+
39+
| 任务 | 适用场景 | 精度 | 预测速度(FPS) | 预测部署模型 |
40+
| :---------: |:---------: |:--------------- | :-------: | :------: |
41+
| 目标检测 | 图片/视频输入 | - | - | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/mot_ppyoloe_l_36e_pipeline.zip) |
42+
| 属性识别 | 图片/视频输入 属性识别 | - | - | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/strongbaseline_r50_30e_pa100k.tar) |
43+
| 关键点检测 | 视频输入 行为识别 | - | - | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/dark_hrnet_w32_256x192.zip)
44+
| 行为识别 | 视频输入 行为识别 | - | - | [下载链接](https://bj.bcebos.com/v1/paddledet/models/pipeline/STGCN.zip) |
45+
| ReID | 视频输入 跨镜跟踪 | - | - | [下载链接]() |
46+
47+
下载模型后,解压至`./output_inference`文件夹
48+
49+
**注意:**
50+
51+
- 模型精度为融合数据集结果,数据集包含开源数据集和企业数据集
52+
- 预测速度为T4下,开启TensorRT FP16的效果
53+
54+
### 2. 配置文件准备
55+
56+
PP-Human相关配置位于```deploy/pphuman/config/infer_cfg.yml```中,存放模型路径,完成不同功能需要设置不同的任务类型
57+
58+
功能及任务类型对应表单如下:
59+
60+
| 输入类型 | 功能 | 任务类型 | 配置项 |
61+
|-------|-------|----------|-----|
62+
| 图片 | 属性识别 | 目标检测 属性识别 | DET ATTR |
63+
| 单镜头视频 | 属性识别 | 多目标跟踪 属性识别 | MOT ATTR |
64+
| 单镜头视频 | 行为识别 | 多目标跟踪 关键点检测 行为识别 | MOT KPT ACTION |
65+
66+
例如基于视频输入的属性识别,任务类型包含多目标跟踪和属性识别,具体配置如下:
67+
68+
```
69+
crop_thresh: 0.5
70+
attr_thresh: 0.5
71+
visual: True
72+
73+
MOT:
74+
model_dir: output_inference/mot_ppyoloe_l_36e_pipeline/
75+
tracker_config: deploy/pphuman/config/tracker_config.yml
76+
batch_size: 1
77+
78+
ATTR:
79+
model_dir: output_inference/strongbaseline_r50_30e_pa100k/
80+
batch_size: 8
81+
```
82+
83+
84+
85+
### 3. 预测部署
86+
87+
```
88+
# 指定配置文件路径和测试图片
89+
python deploy/pphuman/pipeline.py --config deploy/pphuman/config/infer_cfg.yml --image_file=test_image.jpg --device=gpu
90+
91+
# 指定配置文件路径和测试视频,完成属性识别
92+
python deploy/pphuman/pipeline.py --config deploy/pphuman/config/infer_cfg.yml --video_file=test_video.mp4 --device=gpu --enable_attr=True
93+
94+
# 指定配置文件路径和测试视频,完成行为识别
95+
python deploy/pphuman/pipeline.py --config deploy/pphuman/config/infer_cfg.yml --video_file=test_video.mp4 --device=gpu --enable_action=True
96+
97+
# 指定配置文件路径,模型路径和测试视频,完成多目标跟踪
98+
# 命令行中指定的模型路径优先级高于配置文件
99+
python deploy/pphuman/pipeline.py --config deploy/pphuman/config/infer_cfg.yml --video_file=test_video.mp4 --device=gpu --model_dir det=ppyoloe/
100+
```
101+
102+
#### 3.1 参数说明
103+
104+
| 参数 | 是否必须|含义 |
105+
|-------|-------|----------|
106+
| --config | Yes | 配置文件路径 |
107+
| --model_dir | Option | PP-Human中各任务模型路径,优先级高于配置文件 |
108+
| --image_file | Option | 需要预测的图片 |
109+
| --image_dir | Option | 要预测的图片文件夹路径 |
110+
| --video_file | Option | 需要预测的视频 |
111+
| --camera_id | Option | 用来预测的摄像头ID,默认为-1(表示不使用摄像头预测,可设置为:0 - (摄像头数目-1) ),预测过程中在可视化界面按`q`退出输出预测结果到:output/output.mp4|
112+
| --enable_attr| Option | 是否进行属性识别 |
113+
| --enable_action| Option | 是否进行行为识别 |
114+
| --device | Option | 运行时的设备,可选择`CPU/GPU/XPU`,默认为`CPU`|
115+
| --output_dir | Option|可视化结果保存的根目录,默认为output/|
116+
| --run_mode | Option |使用GPU时,默认为paddle, 可选(paddle/trt_fp32/trt_fp16/trt_int8)|
117+
| --enable_mkldnn | Option | CPU预测中是否开启MKLDNN加速,默认为False |
118+
| --cpu_threads | Option| 设置cpu线程数,默认为1 |
119+
| --trt_calib_mode | Option| TensorRT是否使用校准功能,默认为False。使用TensorRT的int8功能时,需设置为True,使用PaddleSlim量化后的模型时需要设置为False |
120+
121+
122+
## 三、方案介绍
123+
124+
PP-Human整体方案如下图所示
125+
126+
<div width="1000" align="center">
127+
<img src="../../docs/images/pphuman-tech.png"/>
128+
</div>
129+
130+
131+
### 1. 目标检测
132+
- 采用PP-YOLOE L 作为目标检测模型
133+
- 详细文档参考[PP-YOLOE](configs/ppyoloe/)
134+
135+
### 2. 多目标跟踪
136+
- 采用SDE方案完成多目标跟踪
137+
- 检测模型使用PP-YOLOE L
138+
- 跟踪模块采用Bytetrack方案
139+
- 详细文档参考[Bytetrack](configs/mot/bytetrack)
140+
141+
### 3. 跨镜跟踪
142+
- 使用PP-YOLOE + Bytetrack得到单镜头多目标跟踪轨迹
143+
- 使用ReID(centroid网络)对每一帧的检测结果提取特征
144+
- 多镜头轨迹特征进行匹配,得到跨镜头跟踪结果
145+
- 详细文档参考[跨镜跟踪](doc/mtmct.md)
146+
147+
### 4. 属性识别
148+
- 使用PP-YOLOE + Bytetrack跟踪人体
149+
- 使用StrongBaseline(多分类模型)完成识别属性,主要属性包括年龄、性别、帽子、眼睛、上衣下衣款式、背包等
150+
- 详细文档参考[属性识别](doc/attribute.md)
151+
152+
### 5. 行为识别:
153+
- 使用PP-YOLOE + Bytetrack跟踪人体
154+
- 使用HRNet进行关键点检测得到人体17个骨骼点
155+
- 结合100帧内同一个人骨骼点的变化,通过ST-GCN判断100帧内发生的动作是否为摔倒
156+
- 详细文档参考[行为识别](doc/action.md)

deploy/pphuman/pipe_utils.py

+10
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ def argsparser():
5252
type=int,
5353
default=-1,
5454
help="device id of camera to predict.")
55+
parser.add_argument(
56+
"--enable_attr",
57+
type=ast.literal_eval,
58+
default=False,
59+
help="Whether use attribute recognition.")
60+
parser.add_argument(
61+
"--enable_action",
62+
type=ast.literal_eval,
63+
default=False,
64+
help="Whether use action recognition.")
5565
parser.add_argument(
5666
"--output_dir",
5767
type=str,

deploy/pphuman/pipeline.py

+33-6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class Pipeline(object):
4848
then all the images in directory will be predicted, default as None
4949
video_file (string|None): the path of video file, default as None
5050
camera_id (int): the device id of camera to predict, default as -1
51+
enable_attr (bool): whether use attribute recognition, default as false
52+
enable_action (bool): whether use action recognition, default as false
5153
device (string): the device to predict, options are: CPU/GPU/XPU,
5254
default as CPU
5355
run_mode (string): the mode of prediction, options are:
@@ -68,6 +70,8 @@ def __init__(self,
6870
image_dir=None,
6971
video_file=None,
7072
camera_id=-1,
73+
enable_attr=False,
74+
enable_action=True,
7175
device='CPU',
7276
run_mode='paddle',
7377
trt_min_shape=1,
@@ -87,6 +91,8 @@ def __init__(self,
8791
cfg,
8892
is_video=True,
8993
multi_camera=True,
94+
enable_attr=enable_attr,
95+
enable_action=enable_action,
9096
device=device,
9197
run_mode=run_mode,
9298
trt_min_shape=trt_min_shape,
@@ -100,6 +106,8 @@ def __init__(self,
100106
self.predictor = PipePredictor(
101107
cfg,
102108
self.is_video,
109+
enable_attr=enable_attr,
110+
enable_action=enable_action,
103111
device=device,
104112
run_mode=run_mode,
105113
trt_min_shape=trt_min_shape,
@@ -172,7 +180,7 @@ def update(self, res, name):
172180
self.res_dict[name].update(res)
173181

174182
def get(self, name):
175-
if name in self.res_dict:
183+
if name in self.res_dict and len(self.res_dict[name]) > 0:
176184
return self.res_dict[name]
177185
return None
178186

@@ -198,6 +206,8 @@ class PipePredictor(object):
198206
multi_camera (bool): whether to use multi camera in pipeline,
199207
default as False
200208
camera_id (int): the device id of camera to predict, default as -1
209+
enable_attr (bool): whether use attribute recognition, default as false
210+
enable_action (bool): whether use action recognition, default as false
201211
device (string): the device to predict, options are: CPU/GPU/XPU,
202212
default as CPU
203213
run_mode (string): the mode of prediction, options are:
@@ -216,6 +226,8 @@ def __init__(self,
216226
cfg,
217227
is_video=True,
218228
multi_camera=False,
229+
enable_attr=False,
230+
enable_action=False,
219231
device='CPU',
220232
run_mode='paddle',
221233
trt_min_shape=1,
@@ -226,8 +238,22 @@ def __init__(self,
226238
enable_mkldnn=False,
227239
output_dir='output'):
228240

229-
self.with_attr = cfg.get('ATTR', False)
230-
self.with_action = cfg.get('ACTION', False)
241+
if enable_attr and not cfg.get('ATTR', False):
242+
ValueError(
243+
'enable_attr is set to True, please set ATTR in config file')
244+
if enable_action and (not cfg.get('ACTION', False) or
245+
not cfg.get('KPT', False)):
246+
ValueError(
247+
'enable_action is set to True, please set KPT and ACTION in config file'
248+
)
249+
250+
self.with_attr = cfg.get('ATTR', False) and enable_attr
251+
self.with_action = cfg.get('ACTION', False) and enable_action
252+
if self.with_attr:
253+
print('Attribute Recognition enabled')
254+
if self.with_action:
255+
print('Action Recognition enabled')
256+
231257
self.is_video = is_video
232258
self.multi_camera = multi_camera
233259
self.cfg = cfg
@@ -483,9 +509,10 @@ def main():
483509
print_arguments(cfg)
484510
pipeline = Pipeline(
485511
cfg, FLAGS.image_file, FLAGS.image_dir, FLAGS.video_file,
486-
FLAGS.camera_id, FLAGS.device, FLAGS.run_mode, FLAGS.trt_min_shape,
487-
FLAGS.trt_max_shape, FLAGS.trt_opt_shape, FLAGS.trt_calib_mode,
488-
FLAGS.cpu_threads, FLAGS.enable_mkldnn, FLAGS.output_dir)
512+
FLAGS.camera_id, FLAGS.enable_attr, FLAGS.enable_action, FLAGS.device,
513+
FLAGS.run_mode, FLAGS.trt_min_shape, FLAGS.trt_max_shape,
514+
FLAGS.trt_opt_shape, FLAGS.trt_calib_mode, FLAGS.cpu_threads,
515+
FLAGS.enable_mkldnn, FLAGS.output_dir)
489516

490517
pipeline.run()
491518

deploy/python/visualize.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,8 @@ def visualize_attr(im, results, boxes=None):
338338
im = np.ascontiguousarray(np.copy(im))
339339

340340
im_h, im_w = im.shape[:2]
341-
text_scale = max(1, int(im.shape[0] / 1200.))
342-
text_thickness = 3
341+
text_scale = max(1, int(im.shape[0] / 1600.))
342+
text_thickness = 2
343343

344344
line_inter = im.shape[0] / 50.
345345
for i, res in enumerate(results):

docs/images/pphuman-tech.png

69 KB
Loading

0 commit comments

Comments
 (0)