未验证 提交 75194b35 编写于 作者: F Feng Ni 提交者: GitHub

[MOT] Fix mot label list, add result txt format (#4682)

* fix label_list for mot, add warnings

* add result txt format, test=document_fix

* fix readme of mtmct, fix paddle.disable_static, test=document_fix

* remove paddle api
上级 8ade6a3e
......@@ -94,6 +94,7 @@ CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/deepsort/deepsort
- JDE YOLOv3行人检测模型是和JDE和FairMOT使用同样的MOT数据集训练的,因此MOTA较高。而其他通用检测模型如PPYOLOv2只使用了MOT17 half数据集训练。
- JDE YOLOv3模型与通用检测模型如YOLOv3和PPYOLOv2最大的区别是使用了JDEBBoxPostProcess后处理,结果输出坐标没有缩放回原图,而通用检测模型输出坐标是缩放回原图的。
- `--scaled`表示在模型输出结果的坐标是否已经是缩放回原图的,如果使用的检测模型是JDE YOLOv3则为False,如果使用通用检测模型则为True, 默认值是False。
- 跟踪结果会存于`{output_dir}/mot_results/`中,里面每个视频序列对应一个txt,每个txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`, 此外`{output_dir}`可通过`--output_dir`设置。
### 2. 预测
......@@ -142,6 +143,7 @@ python deploy/python/mot_sde_infer.py --model_dir=output_inference/ppyolov2_r50v
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`(对每个视频保存一个txt)或`--save_mot_txt_per_img`(对每张图片保存一个txt)表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
`--scaled`表示在模型输出结果的坐标是否已经是缩放回原图的,如果使用的检测模型是JDE的YOLOv3则为False,如果使用通用检测模型则为True。
......
......@@ -92,14 +92,15 @@ CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/fairmot/fairmot_d
CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/fairmot/fairmot_dla34_30e_1088x608.yml -o weights=output/fairmot_dla34_30e_1088x608/model_final.pdparams
```
**Notes:**
The default evaluation dataset is MOT-16 Train Set. If you want to change the evaluation dataset, please refer to the following code and modify `configs/datasets/mot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
```
The default evaluation dataset is MOT-16 Train Set. If you want to change the evaluation dataset, please refer to the following code and modify `configs/datasets/mot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
```
Tracking results will be saved in `{output_dir}/mot_results/`, and every sequence has one txt file, each line of the txt file is `frame,id,x1,y1,w,h,score,-1,-1,-1`, and you can set `{output_dir}` by `--output_dir`.
### 3. Inference
......@@ -126,6 +127,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/fairmot_dla34
```
**Notes:**
The tracking model is used to predict the video, and does not support the prediction of a single image. The visualization video of the tracking results is saved by default. You can add `--save_mot_txts` to save the txt result file, or `--save_images` to save the visualization images.
Each line of the tracking results txt file is `frame,id,x1,y1,w,h,score,-1,-1,-1`.
### 6. Using exported MOT and keypoint model for unite python inference
......
......@@ -91,13 +91,14 @@ CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/fairmot/fairmot_d
```
**注意:**
默认评估的是MOT-16 Train Set数据集, 如需换评估数据集可参照以下代码修改`configs/datasets/mot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
```
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
```
跟踪结果会存于`{output_dir}/mot_results/`中,里面每个视频序列对应一个txt,每个txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`, 此外`{output_dir}`可通过`--output_dir`设置。
### 3. 预测
......@@ -124,6 +125,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/fairmot_dla34
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
### 6. 用导出的跟踪和关键点模型Python联合预测
......
......@@ -61,6 +61,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/fairmot_dla34
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
## 引用
```
......
......@@ -61,14 +61,15 @@ CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/jde/jde_darknet53
CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/jde/jde_darknet53_30e_1088x608.yml -o weights=output/jde_darknet53_30e_1088x608/model_final.pdparams
```
**Notes:**
The default evaluation dataset is MOT-16 Train Set. If you want to change the evaluation dataset, please refer to the following code and modify `configs/datasets/mot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
```
The default evaluation dataset is MOT-16 Train Set. If you want to change the evaluation dataset, please refer to the following code and modify `configs/datasets/mot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
```
Tracking results will be saved in `{output_dir}/mot_results/`, and every sequence has one txt file, each line of the txt file is `frame,id,x1,y1,w,h,score,-1,-1,-1`, and you can set `{output_dir}` by `--output_dir`.
### 3. Inference
......@@ -95,6 +96,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/jde_darknet53
```
**Notes:**
The tracking model is used to predict the video, and does not support the prediction of a single image. The visualization video of the tracking results is saved by default. You can add `--save_mot_txts` to save the txt result file, or `--save_images` to save the visualization images.
Each line of the tracking results txt file is `frame,id,x1,y1,w,h,score,-1,-1,-1`.
## Citations
......
......@@ -62,14 +62,15 @@ CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/jde/jde_darknet53
CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/jde/jde_darknet53_30e_1088x608.yml -o weights=output/jde_darknet53_30e_1088x608/model_final.pdparams
```
**注意:**
默认评估的是MOT-16 Train Set数据集, 如需换评估数据集可参照以下代码修改`configs/datasets/mot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
默认评估的是MOT-16 Train Set数据集, 如需换评估数据集可参照以下代码修改`configs/datasets/mot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: MOT17/images/train
keep_ori_im: False # set True if save visualization images or video
```
跟踪结果会存于`{output_dir}/mot_results/`中,里面每个视频序列对应一个txt,每个txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`, 此外`{output_dir}`可通过`--output_dir`设置。
### 3. 预测
......@@ -95,7 +96,9 @@ CUDA_VISIBLE_DEVICES=0 python tools/export_model.py -c configs/mot/jde/jde_darkn
python deploy/python/mot_jde_infer.py --model_dir=output_inference/jde_darknet53_30e_1088x608 --video_file={your video name}.mp4 --device=GPU --save_mot_txts
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。。
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
## 引用
```
......
......@@ -43,14 +43,15 @@ CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/mcfairmot/mcfairm
CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/mcfairmot/mcfairmot_dla34_30e_1088x608_visdrone.yml -o weights=output/mcfairmot_dla34_30e_1088x608_visdrone/model_final.pdparams
```
**Notes:**
The default evaluation dataset is VisDrone2019 MOT val-set. If you want to change the evaluation dataset, please refer to the following code and modify `configs/datasets/mcmot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: your_dataset/images/val
keep_ori_im: False # set True if save visualization images or video
```
The default evaluation dataset is VisDrone2019 MOT val-set. If you want to change the evaluation dataset, please refer to the following code and modify `configs/datasets/mcmot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: your_dataset/images/val
keep_ori_im: False # set True if save visualization images or video
```
Tracking results will be saved in `{output_dir}/mot_results/`, and every sequence has one txt file, each line of the txt file is `frame,id,x1,y1,w,h,score,cls_id,-1,-1`, and you can set `{output_dir}` by `--output_dir`.
### 3. Inference
Inference a vidoe on single GPU with following command:
......@@ -73,6 +74,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/mcfairmot_dla
```
**Notes:**
The tracking model is used to predict the video, and does not support the prediction of a single image. The visualization video of the tracking results is saved by default. You can add `--save_mot_txts` to save the txt result file, or `--save_images` to save the visualization images.
Each line of the tracking results txt file is `frame,id,x1,y1,w,h,score,cls_id,-1,-1`.
## Citations
......
......@@ -43,14 +43,15 @@ CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/mcfairmot/mcfairm
CUDA_VISIBLE_DEVICES=0 python tools/eval_mot.py -c configs/mot/mcfairmot/mcfairmot_dla34_30e_1088x608_visdrone.yml -o weights=output/mcfairmot_dla34_30e_1088x608_visdrone/model_final.pdparams
```
**注意:**
默认评估的是VisDrone2019 MOT val-set数据集, 如需换评估数据集可参照以下代码修改`configs/datasets/mcmot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: your_dataset/images/val
keep_ori_im: False # set True if save visualization images or video
```
默认评估的是VisDrone2019 MOT val-set数据集, 如需换评估数据集可参照以下代码修改`configs/datasets/mcmot.yml`
```
EvalMOTDataset:
!MOTImageFolder
dataset_dir: dataset/mot
data_root: your_dataset/images/val
keep_ori_im: False # set True if save visualization images or video
```
多类别跟踪结果会存于`{output_dir}/mot_results/`中,里面每个视频序列对应一个txt,每个txt文件每行信息是`frame,id,x1,y1,w,h,score,cls_id,-1,-1`, 此外`{output_dir}`可通过`--output_dir`设置。
### 3. 预测
使用单个GPU通过如下命令预测一个视频,并保存为视频
......@@ -72,6 +73,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/mcfairmot_dla
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
多类别跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,cls_id,-1,-1`
## 引用
......
......@@ -90,13 +90,14 @@ tar -xvf deepsort_pplcnet_vehicle.tar
### 2. 用导出的模型基于Python去预测
```bash
# 用导出PicoDet车辆检测模型和PPLCNet车辆ReID模型
python deploy/pptracking/python/mot_sde_infer.py --model_dir=picodet_l_640_aic21mtmct_vehicle/ --reid_model_dir=deepsort_pplcnet_vehicle/ --mtmct_dir={your mtmct scene video folder} --device=GPU --scaled=True --save_mot_txts --save_images
python deploy/pptracking/python/mot_sde_infer.py --model_dir=picodet_l_640_aic21mtmct_vehicle/ --reid_model_dir=deepsort_pplcnet_vehicle/ --mtmct_dir={your mtmct scene video folder} --mtmct_cfg=mtmct_cfg --device=GPU --scaled=True --save_mot_txts --save_images
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`(对每个视频保存一个txt),或`--save_images`表示保存跟踪结果可视化图片。
`--scaled`表示在模型输出结果的坐标是否已经是缩放回原图的,如果使用的检测模型是JDE的YOLOv3则为False,如果使用通用检测模型则为True。
`--mtmct_dir`是MTMCT预测的某个场景的文件夹名字,里面包含该场景不同摄像头拍摄视频的图片文件夹,其数量至少为两个。
MTMCT跨镜头跟踪输出结果为视频和txt形式。每个图片文件夹各生成一个可视化的跨镜头跟踪结果,与单镜头跟踪的结果是不同的,单镜头跟踪的结果在几个视频文件夹间是独立无关的。MTMCT的结果txt只有一个,比单镜头跟踪结果txt多了第一列镜头id号。
`--mtmct_cfg`是MTMCT预测的某个场景的配置文件,里面包含该一些trick操作的开关和该场景摄像头相关设置的文件路径,用户可以自行更改相关路径以及设置某些操作是否启用。
MTMCT跨镜头跟踪输出结果为视频和txt形式。每个图片文件夹各生成一个可视化的跨镜头跟踪结果,与单镜头跟踪的结果是不同的,单镜头跟踪的结果在几个视频文件夹间是独立无关的。MTMCT的结果txt只有一个,比单镜头跟踪结果txt多了第一列镜头id号,跨镜头跟踪结果txt文件每行信息是`carame_id,frame,id,x1,y1,w,h,-1,-1`
MTMCT是[PP-Tracking](../../../deploy/pptracking)项目中的一个非常重要的方向,具体可前往该目录使用。
......
......@@ -99,6 +99,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/fairmot_dla34
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
## 引用
```
......
......@@ -131,6 +131,7 @@ python deploy/python/mot_jde_infer.py --model_dir=output_inference/fairmot_dla34
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
## 引用
```
......
......@@ -23,6 +23,7 @@ python deploy/pptracking/python/mot_jde_infer.py --model_dir=output_inference/fa
```
**注意:**
- 跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`表示保存跟踪结果的txt文件,或`--save_images`表示保存跟踪结果可视化图片。
- 跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
- 对于多类别或车辆的FairMOT模型的导出和Python预测只需更改相应的config和模型权重即可。如:
```
job_name=mcfairmot_hrnetv2_w18_dlafpn_30e_576x320_visdrone
......@@ -32,6 +33,7 @@ python deploy/pptracking/python/mot_jde_infer.py --model_dir=output_inference/fa
CUDA_VISIBLE_DEVICES=0 python tools/export_model.py -c ${config} -o weights=https://paddledet.bj.bcebos.com/models/mot/${job_name}.pdparams
python deploy/pptracking/python/mot_jde_infer.py --model_dir=output_inference/${job_name} --video_file={your video name}.mp4 --device=GPU --save_mot_txts
```
- 多类别跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,cls_id,-1,-1`
## 2. 对DeepSORT模型的导出和预测
......@@ -65,6 +67,7 @@ python deploy/pptracking/python/mot_sde_infer.py --model_dir=output_inference/pp
```
**注意:**
- 跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`(对每个视频保存一个txt)或`--save_images`表示保存跟踪结果可视化图片。
- 跟踪结果txt文件每行信息是`frame,id,x1,y1,w,h,score,-1,-1,-1`
- `--scaled`表示在模型输出结果的坐标是否已经是缩放回原图的,如果使用的检测模型是JDE的YOLOv3则为False,如果使用通用检测模型则为True。
......@@ -88,8 +91,10 @@ python deploy/pptracking/python/mot_sde_infer.py --model_dir=picodet_l_640_aic21
```
**注意:**
跟踪模型是对视频进行预测,不支持单张图的预测,默认保存跟踪结果可视化后的视频,可添加`--save_mot_txts`(对每个视频保存一个txt),或`--save_images`表示保存跟踪结果可视化图片。
跨镜头跟踪结果txt文件每行信息是`carame_id,frame,id,x1,y1,w,h,-1,-1`
`--scaled`表示在模型输出结果的坐标是否已经是缩放回原图的,如果使用的检测模型是JDE的YOLOv3则为False,如果使用通用检测模型则为True。
`--mtmct_dir`是MTMCT预测的某个场景的文件夹名字,里面包含该场景不同摄像头拍摄视频的图片文件夹,其数量至少为两个。
`--mtmct_cfg`是MTMCT预测的某个场景的配置文件,里面包含该一些trick操作的开关和该场景摄像头相关设置的文件路径,用户可以自行更改相关路径以及设置某些操作是否启用。
## 参数说明:
......
......@@ -20,6 +20,8 @@ import scipy
import numpy as np
from scipy.spatial.distance import cdist
from ..motion import kalman_filter
import warnings
warnings.filterwarnings("ignore")
__all__ = [
'merge_matches',
......
......@@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
This code is based on https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
Note: The following codes are strongly related to carame parameters of the AIC21 test-set S06,
so they can only be used in S06, and can not be used for other MTMCT datasets.
"""
import numpy as np
......
......@@ -12,16 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
This code is based on https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
"""
import os
import re
import cv2
from tqdm import tqdm
import pickle
import os
import os.path as osp
from os.path import join as opj
import numpy as np
import motmetrics as mm
from functools import reduce
......@@ -216,9 +213,6 @@ def get_mtmct_matching_results(pred_mtmct_file, secs_interval=0.5,
res = np.loadtxt(pred_mtmct_file) # 'cid, tid, fid, x1, y1, w, h, -1, -1'
carame_ids = list(map(int, np.unique(res[:, 0])))
num_track_ids = int(np.max(res[:, 1]))
num_frames = int(np.max(res[:, 2]))
res = res[:, :7]
# each line in res: 'cid, tid, fid, x1, y1, w, h'
......@@ -236,7 +230,7 @@ def get_mtmct_matching_results(pred_mtmct_file, secs_interval=0.5,
print(
'No common tracked ids in these videos, please check your MOT result or select new videos.'
)
return None
return None, None
# get mtmct matching results by cid_tid_fid_results[c_id][t_id][f_id]
cid_tid_fid_results = dict()
......@@ -301,9 +295,10 @@ def save_mtmct_crops(cid_tid_fid_res,
im_path = os.path.join(infer_dir, all_images[frame_idx])
im = cv2.imread(im_path) # (H, W, 3)
# only select one track
track = cid_tid_fid_res[c_id][t_id][f_id][0]
track = cid_tid_fid_res[c_id][t_id][f_id][
0] # only select one track
cid, tid, fid, x1, y1, w, h = [int(v) for v in track]
clip = im[y1:(y1 + h), x1:(x1 + w)]
clip = cv2.resize(clip, (width, height))
......
......@@ -12,17 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
This code is based on https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
"""
import os
import re
import cv2
import paddle
import gc
import numpy as np
from sklearn import preprocessing
from sklearn.cluster import AgglomerativeClustering
import gc
import motmetrics as mm
import pandas as pd
from tqdm import tqdm
......@@ -183,14 +182,40 @@ def run_fac(prb_feats,
def euclidean_distance(qf, gf):
m = qf.shape[0]
n = gf.shape[0]
dist_mat = 2 - 2 * paddle.matmul(qf, gf.t())
dist_mat = 2 - 2 * np.matmul(qf, gf.T)
return dist_mat
def batch_paddle_topk(qf, gf, k1, N=6000):
def find_topk(a, k, axis=-1, largest=True, sorted=True):
if axis is None:
axis_size = a.size
else:
axis_size = a.shape[axis]
assert 1 <= k <= axis_size
a = np.asanyarray(a)
if largest:
index_array = np.argpartition(a, axis_size-k, axis=axis)
topk_indices = np.take(index_array, -np.arange(k)-1, axis=axis)
else:
index_array = np.argpartition(a, k-1, axis=axis)
topk_indices = np.take(index_array, np.arange(k), axis=axis)
topk_values = np.take_along_axis(a, topk_indices, axis=axis)
if sorted:
sorted_indices_in_topk = np.argsort(topk_values, axis=axis)
if largest:
sorted_indices_in_topk = np.flip(sorted_indices_in_topk, axis=axis)
sorted_topk_values = np.take_along_axis(
topk_values, sorted_indices_in_topk, axis=axis)
sorted_topk_indices = np.take_along_axis(
topk_indices, sorted_indices_in_topk, axis=axis)
return sorted_topk_values, sorted_topk_indices
return topk_values, topk_indices
def batch_numpy_topk(qf, gf, k1, N=6000):
m = qf.shape[0]
n = gf.shape[0]
dist_mat = []
initial_rank = []
for j in range(n // N + 1):
temp_gf = gf[j * N:j * N + N]
......@@ -199,17 +224,16 @@ def batch_paddle_topk(qf, gf, k1, N=6000):
temp_qf = qf[i * N:i * N + N]
temp_d = euclidean_distance(temp_qf, temp_gf)
temp_qd.append(temp_d)
temp_qd = paddle.concat(temp_qd, axis=0)
temp_qd = temp_qd / (paddle.max(temp_qd, axis=0)[0])
temp_qd = temp_qd.t()
temp_qd = np.concatenate(temp_qd, axis=0)
temp_qd = temp_qd / (np.max(temp_qd, axis=0)[0])
temp_qd = temp_qd.T
initial_rank.append(
paddle.topk(
temp_qd, k=k1, axis=1, largest=False, sorted=True)[1])
find_topk(temp_qd, k=k1, axis=1, largest=False, sorted=True)[1])
del temp_qd
del temp_gf
del temp_qf
del temp_d
initial_rank = paddle.concat(initial_rank, axis=0).cpu().numpy()
initial_rank = np.concatenate(initial_rank, axis=0)
return initial_rank
......@@ -224,14 +248,14 @@ def batch_euclidean_distance(qf, gf, N=6000):
temp_qf = qf[i * N:i * N + N]
temp_d = euclidean_distance(temp_qf, temp_gf)
temp_qd.append(temp_d)
temp_qd = paddle.concat(temp_qd, axis=0)
temp_qd = temp_qd / (paddle.max(temp_qd, axis=0)[0])
dist_mat.append(temp_qd.t()) # transpose
temp_qd = np.concatenate(temp_qd, axis=0)
temp_qd = temp_qd / (np.max(temp_qd, axis=0)[0])
dist_mat.append(temp_qd.T)
del temp_qd
del temp_gf
del temp_qf
del temp_d
dist_mat = paddle.concat(dist_mat, axis=0)
dist_mat = np.concatenate(dist_mat, axis=0)
return dist_mat
......@@ -239,14 +263,13 @@ def batch_v(feat, R, all_num):
V = np.zeros((all_num, all_num), dtype=np.float32)
m = feat.shape[0]
for i in tqdm(range(m)):
temp_gf = feat[i].unsqueeze(0)
temp_gf = feat[i].reshape(1, -1)
temp_qd = euclidean_distance(temp_gf, feat)
temp_qd = temp_qd / (paddle.max(temp_qd))
temp_qd = temp_qd.squeeze()
temp_qd = temp_qd.numpy()[R[i].tolist()]
temp_qd = paddle.to_tensor(temp_qd)
weight = paddle.exp(-temp_qd)
weight = (weight / paddle.sum(weight)).numpy()
temp_qd = temp_qd / (np.max(temp_qd))
temp_qd = temp_qd.reshape(-1)
temp_qd = temp_qd[R[i].tolist()]
weight = np.exp(-temp_qd)
weight = weight / np.sum(weight)
V[i, R[i]] = weight.astype(np.float32)
return V
......@@ -259,13 +282,11 @@ def k_reciprocal_neigh(initial_rank, i, k1):
def ReRank2(probFea, galFea, k1=20, k2=6, lambda_value=0.3):
# The following naming, e.g. gallery_num, is different from outer scope.
# Don't care about it.
query_num = probFea.shape[0]
all_num = query_num + galFea.shape[0]
feat = paddle.concat([probFea, galFea], axis=0)
initial_rank = batch_paddle_topk(feat, feat, k1 + 1, N=6000)
# del feat
feat = np.concatenate((probFea, galFea), axis=0)
initial_rank = batch_numpy_topk(feat, feat, k1 + 1, N=6000)
del probFea
del galFea
gc.collect() # empty memory
......@@ -292,7 +313,8 @@ def ReRank2(probFea, galFea, k1=20, k2=6, lambda_value=0.3):
del R
gc.collect() # empty memory
initial_rank = initial_rank[:, :k2]
### Faster version
# Faster version
if k2 != 1:
V_qe = np.zeros_like(V, dtype=np.float16)
for i in range(all_num):
......@@ -315,7 +337,7 @@ def ReRank2(probFea, galFea, k1=20, k2=6, lambda_value=0.3):
jaccard_dist[i] = 1 - temp_min / (2. - temp_min)
del V
gc.collect() # empty memory
original_dist = batch_euclidean_distance(feat, feat[:query_num, :]).numpy()
original_dist = batch_euclidean_distance(feat, feat[:query_num, :])
final_dist = jaccard_dist * (1 - lambda_value
) + original_dist * lambda_value
del original_dist
......@@ -341,21 +363,16 @@ def visual_rerank(prb_feats,
prb_feats, gal_feats = run_fac(prb_feats, gal_feats, prb_labels,
gal_labels, 0.08, 20, 0.5, 1, 1)
if use_rerank:
paddle.enable_static()
print('current use rerank finetuned parameters....')
# Step2: k-reciprocal. finetuned parameters: [k1,k2,lambda_value]
sims = ReRank2(
paddle.to_tensor(prb_feats),
paddle.to_tensor(gal_feats), 20, 3, 0.3)
sims = ReRank2(prb_feats, gal_feats, 20, 3, 0.3)
else:
# sims = ComputeEuclid(prb_feats, gal_feats, 1)
sims = 1.0 - np.dot(prb_feats, gal_feats.T)
# NOTE: sims here is actually dist, the smaller the more similar
return 1.0 - sims
# sub_cluster
def normalize(nparray, axis=0):
nparray = preprocessing.normalize(nparray, norm='l2', axis=axis)
return nparray
......@@ -512,10 +529,6 @@ def get_labels(cid_tid_dict,
use_rerank=True,
use_st_filter=False):
# 1st cluster
sub_cid_tids = list(cid_tid_dict.keys())
sub_labels = dict()
dis_thrs = [0.7, 0.5, 0.5, 0.5, 0.5, 0.7, 0.5, 0.5, 0.5, 0.5]
sim_matrix = get_sim_matrix(
cid_tid_dict,
cid_tids,
......@@ -532,7 +545,6 @@ def get_labels(cid_tid_dict,
# 2nd cluster
cid_tid_dict_new = combin_feature(cid_tid_dict, sub_cluster)
sub_labels = dict()
sim_matrix = get_sim_matrix(
cid_tid_dict_new,
cid_tids,
......
......@@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
This code is based on https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
Note: The following codes are strongly related to zone of the AIC21 test-set S06,
so they can only be used in S06, and can not be used for other MTMCT datasets.
"""
import os
......
# config for MTMCT
MTMCT: True
cameras_bias:
c041: 0
c042: 0
cameras_bias: # default for scene S01. For S06, should modify as 'c041: 0 c042: 0'
c003: 0
c004: 0
# 1.zone releated parameters
use_zone: True
use_zone: False
zone_path: dataset/mot/aic21mtmct_vehicle/S06/zone
# 2.tricks parameters, can be used for other mtmct dataset
use_ff: True
use_rerank: True
# 3.camera releated parameters
use_camera: True
use_camera: False
use_st_filter: False
# 4.zone releated parameters
use_roi: True
use_roi: False
roi_dir: dataset/mot/aic21mtmct_vehicle/S06
......@@ -92,19 +92,43 @@ def get_categories(metric_type, anno_file=None, arch=None):
return (None, {'id': 'keypoint'})
elif metric_type.lower() in ['mot', 'motdet', 'reid']:
return _mot_category()
if anno_file and os.path.isfile(anno_file):
cats = []
with open(anno_file) as f:
for line in f.readlines():
cats.append(line.strip())
if cats[0] == 'background':
cats = cats[1:]
clsid2catid = {i: i for i in range(len(cats))}
catid2name = {i: name for i, name in enumerate(cats)}
return clsid2catid, catid2name
# anno file not exist, load default category 'pedestrian'.
else:
return _mot_category(category='pedestrian')
elif metric_type.lower() in ['kitti', 'bdd100kmot']:
return _mot_category(category='car')
return _mot_category(category='vehicle')
elif metric_type.lower() in ['mcmot']:
return _visdrone_category()
if anno_file and os.path.isfile(anno_file):
cats = []
with open(anno_file) as f:
for line in f.readlines():
cats.append(line.strip())
if cats[0] == 'background':
cats = cats[1:]
clsid2catid = {i: i for i in range(len(cats))}
catid2name = {i: name for i, name in enumerate(cats)}
return clsid2catid, catid2name
# anno file not exist, load default categories of visdrone all 10 categories
else:
return _visdrone_category()
else:
raise ValueError("unknown metric type {}".format(metric_type))
def _mot_category(category='person'):
def _mot_category(category='pedestrian'):
"""
Get class id to category id map and category id
to category name map of mot dataset
......
......@@ -93,8 +93,10 @@ class MOTDataSet(DetDataset):
if self.image_lists == []:
return
# only used to get categories and metric
return os.path.join(self.dataset_dir, 'image_lists',
self.image_lists[0])
# only check first data, but the label_list of all data should be same.
first_mot_data = self.image_lists[0].split('.')[0]
anno_file = os.path.join(self.dataset_dir, first_mot_data, 'label_list.txt')
return anno_file
def parse_dataset(self):
self.img_files = OrderedDict()
......@@ -272,8 +274,10 @@ class MCMOTDataSet(DetDataset):
if self.image_lists == []:
return
# only used to get categories and metric
return os.path.join(self.dataset_dir, 'image_lists',
self.image_lists[0])
# only check first data, but the label_list of all data should be same.
first_mot_data = self.image_lists[0].split('.')[0]
anno_file = os.path.join(self.dataset_dir, first_mot_data, 'label_list.txt')
return anno_file
def parse_dataset(self):
self.img_files = OrderedDict()
......
......@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is borrow from https://github.com/nwojke/deep_sort/tree/master/deep_sort
This code is based on https://github.com/nwojke/deep_sort/tree/master/deep_sort
"""
import numpy as np
......
......@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is borrow from https://github.com/Zhongdao/Towards-Realtime-MOT/blob/master/tracker/matching.py
This code is based on https://github.com/Zhongdao/Towards-Realtime-MOT/blob/master/tracker/matching.py
"""
import lap
......@@ -20,9 +20,8 @@ import scipy
import numpy as np
from scipy.spatial.distance import cdist
from ..motion import kalman_filter
from ppdet.utils.logger import setup_logger
logger = setup_logger(__name__)
import warnings
warnings.filterwarnings("ignore")
__all__ = [
'merge_matches',
......@@ -76,7 +75,7 @@ def cython_bbox_ious(atlbrs, btlbrs):
try:
import cython_bbox
except Exception as e:
logger.error('cython_bbox not found, please install cython_bbox.'
print('cython_bbox not found, please install cython_bbox.'
'for example: `pip install cython_bbox`.')
raise e
......
......@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is borrow from https://github.com/nwojke/deep_sort/blob/master/deep_sort/kalman_filter.py
This code is based on https://github.com/nwojke/deep_sort/blob/master/deep_sort/kalman_filter.py
"""
import numpy as np
......
......@@ -11,12 +11,17 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/Zhongdao/Towards-Realtime-MOT/blob/master/tracker/multitracker.py
"""
import numpy as np
from collections import defaultdict
from collections import deque, OrderedDict
from ..matching import jde_matching as matching
from ppdet.core.workspace import register, serializable
import warnings
warnings.filterwarnings("ignore")
__all__ = [
'TrackState',
......
......@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is borrow from https://github.com/nwojke/deep_sort/blob/master/deep_sort/track.py
This code is based on https://github.com/nwojke/deep_sort/blob/master/deep_sort/track.py
"""
import datetime
......
......@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is borrow from https://github.com/nwojke/deep_sort/blob/master/deep_sort/tracker.py
This code is based on https://github.com/nwojke/deep_sort/blob/master/deep_sort/tracker.py
"""
import numpy as np
......
......@@ -17,7 +17,6 @@ This code is based on https://github.com/Zhongdao/Towards-Realtime-MOT/blob/mast
import numpy as np
from collections import defaultdict
import paddle
from ..matching import jde_matching as matching
from ..motion import KalmanFilter
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册