Skip to content

Commit 772d180

Browse files
author
LokeZhou
authored
[MOT] Add BoT-SORT and MOT speed optimization (#7591)
* Add BOTSORTTracker * pptracking/python/mot/tracker/botsort_tracker.py * ppdet/modeling/mot/tracker/botsort_tracker.py fix OCSORTTracker * * botsort kalman_filter.py float64->float32 * requirements.txt add numba * [Mot] kalman_filter.py lazy import numba * add code source and modify comments * [MOT] fix numba lazy import bug * [MOT] botsort add README.md * delete comment code
1 parent 2acf9cf commit 772d180

27 files changed

+2136
-152
lines changed

configs/mot/botsort/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
English | [简体中文](README_cn.md)
2+
3+
# BOT_SORT (BoT-SORT: Robust Associations Multi-Pedestrian Tracking)
4+
5+
## content
6+
- [introduction](#introduction)
7+
- [model zoo](#modelzoo)
8+
- [Quick Start](#QuickStart)
9+
- [Citation](Citation)
10+
11+
## introduction
12+
[BOT_SORT](https://arxiv.org/pdf/2206.14651v2.pdf)(BoT-SORT: Robust Associations Multi-Pedestrian Tracking). The configuration of common detectors is provided here for reference. Because different training data sets, input scales, number of training epochs, NMS threshold settings, etc. will lead to differences in model accuracy and performance, please adapt according to your needs
13+
14+
## modelzoo
15+
16+
### BOT_SORT在MOT-17 half Val Set
17+
18+
| Dataset | detector | input size | detector mAP | MOTA | IDF1 | config |
19+
| :-------- | :----- | :----: | :------: | :----: |:-----: |:----: |
20+
| MOT-17 half train | PP-YOLOE-l | 640x640 | 52.7 | 55.5 | 64.2 |[config](./botsort_ppyoloe.yml) |
21+
22+
23+
**Attention:**
24+
- Model weight download link in the configuration file ` ` ` det_ Weights ` ` `, run the verification command to automatically download.
25+
- **MOT17-half train** is a data set composed of pictures and labels of the first half frames of each video in the MOT17 train sequence (7 in total). To verify the accuracy, we can use the **MOT17-half val** to eval,It is composed of the second half frame of each video,download [link](https://bj.bcebos.com/v1/paddledet/data/mot/MOT17.zip),decompression `dataset/mot/`
26+
27+
- BOT_ SORT training is a separate detector training MOT dataset, reasoning is to assemble a tracker to evaluate MOT indicators, and a separate detection model can also evaluate detection indicators.
28+
- BOT_SORT export deployment is to export the detection model separately and then assemble the tracker for operation. Refer to [PP-Tracking](../../../deploy/pptracking/python)
29+
- BOT_SORT is the main scheme for PP Human, PP Vehicle and other pipelines to analyze the project tracking direction. For specific use, please refer to [Pipeline](../../../deploy/pipeline) and [MOT](../../../deploy/pipeline/docs/tutorials/pphuman_mot.md).
30+
31+
32+
## QuickStart
33+
34+
### 1. train
35+
Start training and evaluation with the following command
36+
```bash
37+
#Single gpu
38+
CUDA_VISIBLE_DEVICES=0 python tools/train.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml --eval --amp
39+
40+
#Multi gpu
41+
python -m paddle.distributed.launch --log_dir=ppyoloe --gpus 0,1,2,3,4,5,6,7 tools/train.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml --eval --amp
42+
```
43+
44+
### 2. evaluate
45+
#### 2.1 detection
46+
```bash
47+
CUDA_VISIBLE_DEVICES=0 python tools/eval.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml
48+
```
49+
50+
**Attention:**
51+
- eval detection use ```tools/eval.py```,eval mot use ```tools/eval_mot.py```.
52+
53+
#### 2.2 mot
54+
```bash
55+
CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/botsort/botsort_ppyoloe.yml --scaled=True
56+
```
57+
**Attention:**
58+
- `--scaled` indicates whether the coordinates of the output results of the model have been scaled back to the original drawing. If the detection model used is JDE YOLOv3, it is false. If the universal detection model is used, it is true. The default value is false.
59+
- mot result save `{output_dir}/mot_results/`,each video sequence in it corresponds to a txt, and each line of information in each txt file is `frame,id,x1,y1,w,h,score,-1,-1,-1`, and `{output_dir}` could use `--output_dir` to set.
60+
61+
### 3. export detection model
62+
63+
```bash
64+
python tools/export_model.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml --output_dir=output_inference -o weights=https://bj.bcebos.com/v1/paddledet/models/mot/ppyoloe_crn_l_36e_640x640_mot17half.pdparams
65+
```
66+
67+
### 4. Use the export model to predict
68+
69+
```bash
70+
# download demo video
71+
wget https://bj.bcebos.com/v1/paddledet/data/mot/demo/mot17_demo.mp4
72+
73+
CUDA_VISIBLE_DEVICES=0 python deploy/pptracking/python/mot_sde_infer.py --model_dir=output_inference/ppyoloe_crn_l_36e_640x640_mot17half --tracker_config=deploy/pptracking/python/tracker_config.yml --video_file=mot17_demo.mp4 --device=GPU --threshold=0.5
74+
```
75+
**Attention:**
76+
- You must fix `tracker_config.yml` tracker `type: BOTSORTTracker`,if you want to use BOT_SORT.
77+
- The tracking model is used to predict videos. It does not support prediction of a single image. By default, the videos with visualized tracking results are saved. You can add `--save_mot_txts` (save a txt for each video) or `--save_mot_txt_per_img`(Save a txt for each image) or `--save_images` save the visualization picture of tracking results.
78+
- Each line of the trace result txt file format `frame,id,x1,y1,w,h,score,-1,-1,-1`
79+
80+
81+
## Citation
82+
```
83+
@article{aharon2022bot,
84+
title={BoT-SORT: Robust Associations Multi-Pedestrian Tracking},
85+
author={Aharon, Nir and Orfaig, Roy and Bobrovsky, Ben-Zion},
86+
journal={arXiv preprint arXiv:2206.14651},
87+
year={2022}
88+
}
89+
```

configs/mot/botsort/README_cn.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
简体中文 | [English](README.md)
2+
3+
# BOT_SORT (BoT-SORT: Robust Associations Multi-Pedestrian Tracking)
4+
5+
## 内容
6+
- [简介](#简介)
7+
- [模型库](#模型库)
8+
- [快速开始](#快速开始)
9+
- [引用](#引用)
10+
11+
## 简介
12+
[BOT_SORT](https://arxiv.org/pdf/2206.14651v2.pdf)(BoT-SORT: Robust Associations Multi-Pedestrian Tracking)。此处提供了常用检测器的配置作为参考。由于训练数据集、输入尺度、训练epoch数、NMS阈值设置等的不同均会导致模型精度和性能的差异,请自行根据需求进行适配。
13+
14+
## 模型库
15+
16+
### BOT_SORT在MOT-17 half Val Set上结果
17+
18+
| 检测训练数据集 | 检测器 | 输入尺度 | 检测mAP | MOTA | IDF1 | 配置文件 |
19+
| :-------- | :----- | :----: | :------: | :----: |:-----: |:----: |
20+
| MOT-17 half train | PP-YOLOE-l | 640x640 | 52.7 | 55.5 | 64.2 |[配置文件](./botsort_ppyoloe.yml) |
21+
22+
23+
**注意:**
24+
- 模型权重下载链接在配置文件中的```det_weights```,运行验证的命令即可自动下载。
25+
- **MOT17-half train**是MOT17的train序列(共7个)每个视频的前一半帧的图片和标注组成的数据集,而为了验证精度可以都用**MOT17-half val**数据集去评估,它是每个视频的后一半帧组成的,数据集可以从[此链接](https://bj.bcebos.com/v1/paddledet/data/mot/MOT17.zip)下载,并解压放在`dataset/mot/`文件夹下。
26+
27+
- BOT_SORT的训练是单独的检测器训练MOT数据集,推理是组装跟踪器去评估MOT指标,单独的检测模型也可以评估检测指标。
28+
- BOT_SORT的导出部署,是单独导出检测模型,再组装跟踪器运行的,参照[PP-Tracking](../../../deploy/pptracking/python)
29+
- BOT_SORT是PP-Human和PP-Vehicle等Pipeline分析项目跟踪方向的主要方案,具体使用参照[Pipeline](../../../deploy/pipeline)[MOT](../../../deploy/pipeline/docs/tutorials/pphuman_mot.md)
30+
31+
32+
## 快速开始
33+
34+
### 1. 训练
35+
通过如下命令一键式启动训练和评估
36+
```bash
37+
#单卡训练
38+
CUDA_VISIBLE_DEVICES=0 python tools/train.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml --eval --amp
39+
40+
#多卡训练
41+
python -m paddle.distributed.launch --log_dir=ppyoloe --gpus 0,1,2,3,4,5,6,7 tools/train.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml --eval --amp
42+
```
43+
44+
### 2. 评估
45+
#### 2.1 评估检测效果
46+
```bash
47+
CUDA_VISIBLE_DEVICES=0 python tools/eval.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml
48+
```
49+
50+
**注意:**
51+
- 评估检测使用的是```tools/eval.py```, 评估跟踪使用的是```tools/eval_mot.py```
52+
53+
#### 2.2 评估跟踪效果
54+
```bash
55+
CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/botsort/botsort_ppyoloe.yml --scaled=True
56+
```
57+
**注意:**
58+
- `--scaled`表示在模型输出结果的坐标是否已经是缩放回原图的,如果使用的检测模型是JDE YOLOv3则为False,如果使用通用检测模型则为True, 默认值是False。
59+
- 跟踪结果会存于`{output_dir}/mot_results/`中,里面每个视频序列对应一个txt,每个txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`, 此外`{output_dir}`可通过`--output_dir`设置。
60+
61+
### 3. 导出预测模型
62+
63+
```bash
64+
python tools/export_model.py -c configs/mot/bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml --output_dir=output_inference -o weights=https://bj.bcebos.com/v1/paddledet/models/mot/ppyoloe_crn_l_36e_640x640_mot17half.pdparams
65+
```
66+
67+
### 4. 用导出的模型基于Python去预测
68+
69+
```bash
70+
# 下载demo视频
71+
wget https://bj.bcebos.com/v1/paddledet/data/mot/demo/mot17_demo.mp4
72+
73+
CUDA_VISIBLE_DEVICES=0 python deploy/pptracking/python/mot_sde_infer.py --model_dir=output_inference/ppyoloe_crn_l_36e_640x640_mot17half --tracker_config=deploy/pptracking/python/tracker_config.yml --video_file=mot17_demo.mp4 --device=GPU --threshold=0.5
74+
```
75+
**注意:**
76+
- 运行前需要手动修改`tracker_config.yml`的跟踪器类型为`type: BOTSORTTracker`
77+
- 跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`(对每个视频保存一个txt)或`--save_mot_txt_per_img`(对每张图片保存一个txt)表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
78+
- 跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
79+
80+
81+
## 引用
82+
```
83+
@article{aharon2022bot,
84+
title={BoT-SORT: Robust Associations Multi-Pedestrian Tracking},
85+
author={Aharon, Nir and Orfaig, Roy and Bobrovsky, Ben-Zion},
86+
journal={arXiv preprint arXiv:2206.14651},
87+
year={2022}
88+
}
89+
```
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# This config is an assembled config for ByteTrack MOT, used as eval/infer mode for MOT.
2+
_BASE_: [
3+
'../bytetrack/detector/ppyoloe_crn_l_36e_640x640_mot17half.yml',
4+
'../bytetrack/_base_/mot17.yml',
5+
'../bytetrack/_base_/ppyoloe_mot_reader_640x640.yml'
6+
]
7+
weights: output/botsort_ppyoloe/model_final
8+
log_iter: 20
9+
snapshot_epoch: 2
10+
11+
metric: MOT # eval/infer mode, set 'COCO' can be training mode
12+
num_classes: 1
13+
14+
architecture: ByteTrack
15+
pretrain_weights: https://bj.bcebos.com/v1/paddledet/models/ppyoloe_crn_l_300e_coco.pdparams
16+
ByteTrack:
17+
detector: YOLOv3 # PPYOLOe version
18+
reid: None
19+
tracker: BOTSORTTracker
20+
det_weights: https://bj.bcebos.com/v1/paddledet/models/mot/ppyoloe_crn_l_36e_640x640_mot17half.pdparams
21+
reid_weights: None
22+
23+
YOLOv3:
24+
backbone: CSPResNet
25+
neck: CustomCSPPAN
26+
yolo_head: PPYOLOEHead
27+
post_process: ~
28+
29+
# Tracking requires higher quality boxes, so NMS score_threshold will be higher
30+
PPYOLOEHead:
31+
fpn_strides: [32, 16, 8]
32+
grid_cell_scale: 5.0
33+
grid_cell_offset: 0.5
34+
static_assigner_epoch: -1 # 100
35+
use_varifocal_loss: True
36+
loss_weight: {class: 1.0, iou: 2.5, dfl: 0.5}
37+
static_assigner:
38+
name: ATSSAssigner
39+
topk: 9
40+
assigner:
41+
name: TaskAlignedAssigner
42+
topk: 13
43+
alpha: 1.0
44+
beta: 6.0
45+
nms:
46+
name: MultiClassNMS
47+
nms_top_k: 1000
48+
keep_top_k: 100
49+
score_threshold: 0.1 # 0.01 in original detector
50+
nms_threshold: 0.4 # 0.6 in original detector
51+
52+
53+
BOTSORTTracker:
54+
track_high_thresh: 0.3
55+
track_low_thresh: 0.2
56+
new_track_thresh: 0.4
57+
match_thresh: 0.7
58+
track_buffer: 30
59+
min_box_area: 0
60+
camera_motion: False
61+
cmc_method: 'sparseOptFlow' # only camera_motion is True,
62+
# sparseOptFlow | files (Vidstab GMC) | orb | ecc
63+
64+
65+
# MOTDataset for MOT evaluation and inference
66+
EvalMOTDataset:
67+
!MOTImageFolder
68+
dataset_dir: dataset/mot
69+
data_root: MOT17/images/half
70+
keep_ori_im: True # set as True in DeepSORT and ByteTrack
71+
72+
TestMOTDataset:
73+
!MOTImageFolder
74+
dataset_dir: dataset/mot
75+
keep_ori_im: True # set True if save visualization images or video

configs/mot/ocsort/ocsort_ppyoloe.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,14 @@ OCSORTTracker:
6060
vertical_ratio: 0
6161
min_box_area: 0
6262
use_byte: False
63+
use_angle_cost: False
6364

6465

6566
# MOTDataset for MOT evaluation and inference
6667
EvalMOTDataset:
6768
!MOTImageFolder
6869
dataset_dir: dataset/mot
69-
data_root: MOT17/images/half
70+
data_root: MOT17_test/images/half
7071
keep_ori_im: True # set as True in DeepSORT and ByteTrack
7172

7273
TestMOTDataset:

deploy/pptracking/python/mot/matching/ocsort_matching.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def linear_assignment(cost_matrix):
5757
try:
5858
import lap
5959
_, x, y = lap.lapjv(cost_matrix, extend_cost=True)
60-
return np.array([[y[i], i] for i in x if i >= 0]) #
60+
match = np.array([[y[i], i] for i in x if i >= 0])
61+
return match
6162
except ImportError:
6263
from scipy.optimize import linear_sum_assignment
6364
x, y = linear_sum_assignment(cost_matrix)
@@ -125,3 +126,44 @@ def associate(detections, trackers, iou_threshold, velocities, previous_obs,
125126
matches = np.concatenate(matches, axis=0)
126127

127128
return matches, np.array(unmatched_detections), np.array(unmatched_trackers)
129+
130+
131+
def associate_only_iou(detections, trackers, iou_threshold):
132+
if (len(trackers) == 0):
133+
return np.empty(
134+
(0, 2), dtype=int), np.arange(len(detections)), np.empty(
135+
(0, 5), dtype=int)
136+
137+
iou_matrix = iou_batch(detections, trackers)
138+
139+
if min(iou_matrix.shape) > 0:
140+
a = (iou_matrix > iou_threshold).astype(np.int32)
141+
if a.sum(1).max() == 1 and a.sum(0).max() == 1:
142+
matched_indices = np.stack(np.where(a), axis=1)
143+
else:
144+
matched_indices = linear_assignment(-iou_matrix)
145+
else:
146+
matched_indices = np.empty(shape=(0, 2))
147+
148+
unmatched_detections = []
149+
for d, det in enumerate(detections):
150+
if (d not in matched_indices[:, 0]):
151+
unmatched_detections.append(d)
152+
unmatched_trackers = []
153+
for t, trk in enumerate(trackers):
154+
if (t not in matched_indices[:, 1]):
155+
unmatched_trackers.append(t)
156+
157+
# filter out matched with low IOU
158+
matches = []
159+
for m in matched_indices:
160+
if (iou_matrix[m[0], m[1]] < iou_threshold):
161+
unmatched_detections.append(m[0])
162+
unmatched_trackers.append(m[1])
163+
else:
164+
matches.append(m.reshape(1, 2))
165+
if (len(matches) == 0):
166+
matches = np.empty((0, 2), dtype=int)
167+
else:
168+
matches = np.concatenate(matches, axis=0)
169+
return matches, np.array(unmatched_detections), np.array(unmatched_trackers)

deploy/pptracking/python/mot/motion/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@
1515
from . import kalman_filter
1616

1717
from .kalman_filter import *
18+
from .gmc import *
19+
from .ocsort_kalman_filter import *

0 commit comments

Comments
 (0)