dnt 0.2.4__py3-none-any.whl → 0.3.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dnt/__init__.py +3 -2
- dnt/analysis/__init__.py +3 -2
- dnt/analysis/count.py +54 -37
- dnt/analysis/interaction2.py +518 -0
- dnt/analysis/stop.py +22 -17
- dnt/analysis/stop2.py +289 -0
- dnt/analysis/stop3.py +758 -0
- dnt/detect/signal/detector.py +326 -0
- dnt/detect/timestamp.py +105 -0
- dnt/detect/yolov8/detector.py +179 -36
- dnt/detect/yolov8/segmentor.py +60 -2
- dnt/engine/__init__.py +8 -0
- dnt/engine/bbox_interp.py +83 -0
- dnt/engine/bbox_iou.py +20 -0
- dnt/engine/cluster.py +31 -0
- dnt/engine/iob.py +66 -0
- dnt/filter/filter.py +333 -2
- dnt/label/labeler.py +4 -4
- dnt/label/labeler2.py +631 -0
- dnt/shared/__init__.py +2 -1
- dnt/shared/data/coco.names +0 -0
- dnt/shared/data/openimages.names +0 -0
- dnt/shared/data/voc.names +0 -0
- dnt/shared/download.py +12 -0
- dnt/shared/synhcro.py +150 -0
- dnt/shared/util.py +17 -4
- dnt/third_party/fast-reid/__init__.py +1 -0
- dnt/third_party/fast-reid/configs/Base-AGW.yml +19 -0
- dnt/third_party/fast-reid/configs/Base-MGN.yml +12 -0
- dnt/third_party/fast-reid/configs/Base-SBS.yml +63 -0
- dnt/third_party/fast-reid/configs/Base-bagtricks.yml +76 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/AGW_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/AGW_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/AGW_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/AGW_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/bagtricks_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/bagtricks_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/bagtricks_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/bagtricks_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/mgn_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/sbs_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/sbs_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/sbs_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/DukeMTMC/sbs_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT17/AGW_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MOT17/AGW_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT17/AGW_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MOT17/AGW_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT17/bagtricks_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MOT17/bagtricks_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT17/bagtricks_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MOT17/bagtricks_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT17/mgn_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT17/sbs_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MOT17/sbs_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT17/sbs_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MOT17/sbs_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT20/AGW_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MOT20/AGW_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT20/AGW_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MOT20/AGW_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT20/bagtricks_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MOT20/bagtricks_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT20/bagtricks_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MOT20/bagtricks_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT20/mgn_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT20/sbs_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MOT20/sbs_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MOT20/sbs_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MOT20/sbs_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MSMT17/AGW_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MSMT17/AGW_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MSMT17/AGW_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MSMT17/AGW_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/MSMT17/bagtricks_R101-ibn.yml +13 -0
- dnt/third_party/fast-reid/configs/MSMT17/bagtricks_R50-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MSMT17/bagtricks_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MSMT17/bagtricks_S50.yml +12 -0
- dnt/third_party/fast-reid/configs/MSMT17/mgn_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MSMT17/sbs_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/MSMT17/sbs_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/MSMT17/sbs_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/MSMT17/sbs_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/Market1501/AGW_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/Market1501/AGW_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/Market1501/AGW_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/Market1501/AGW_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/Market1501/bagtricks_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/Market1501/bagtricks_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/Market1501/bagtricks_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/Market1501/bagtricks_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/Market1501/bagtricks_vit.yml +88 -0
- dnt/third_party/fast-reid/configs/Market1501/mgn_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/Market1501/sbs_R101-ibn.yml +12 -0
- dnt/third_party/fast-reid/configs/Market1501/sbs_R50-ibn.yml +11 -0
- dnt/third_party/fast-reid/configs/Market1501/sbs_R50.yml +7 -0
- dnt/third_party/fast-reid/configs/Market1501/sbs_S50.yml +11 -0
- dnt/third_party/fast-reid/configs/VERIWild/bagtricks_R50-ibn.yml +35 -0
- dnt/third_party/fast-reid/configs/VeRi/sbs_R50-ibn.yml +35 -0
- dnt/third_party/fast-reid/configs/VehicleID/bagtricks_R50-ibn.yml +36 -0
- dnt/third_party/fast-reid/configs/__init__.py +0 -0
- dnt/third_party/fast-reid/fast_reid_interfece.py +175 -0
- dnt/third_party/fast-reid/fastreid/__init__.py +6 -0
- dnt/third_party/fast-reid/fastreid/config/__init__.py +15 -0
- dnt/third_party/fast-reid/fastreid/config/config.py +319 -0
- dnt/third_party/fast-reid/fastreid/config/defaults.py +329 -0
- dnt/third_party/fast-reid/fastreid/data/__init__.py +17 -0
- dnt/third_party/fast-reid/fastreid/data/build.py +194 -0
- dnt/third_party/fast-reid/fastreid/data/common.py +58 -0
- dnt/third_party/fast-reid/fastreid/data/data_utils.py +202 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/AirportALERT.py +50 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/__init__.py +43 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/bases.py +183 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/caviara.py +44 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/cuhk03.py +274 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/cuhk_sysu.py +58 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/dukemtmcreid.py +70 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/grid.py +44 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/iLIDS.py +45 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/lpw.py +49 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/market1501.py +89 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/msmt17.py +114 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/pes3d.py +44 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/pku.py +44 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/prai.py +43 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/prid.py +41 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/saivt.py +47 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/sensereid.py +47 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/shinpuhkan.py +48 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/sysu_mm.py +47 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/thermalworld.py +43 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/vehicleid.py +126 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/veri.py +69 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/veriwild.py +140 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/viper.py +45 -0
- dnt/third_party/fast-reid/fastreid/data/datasets/wildtracker.py +59 -0
- dnt/third_party/fast-reid/fastreid/data/samplers/__init__.py +18 -0
- dnt/third_party/fast-reid/fastreid/data/samplers/data_sampler.py +85 -0
- dnt/third_party/fast-reid/fastreid/data/samplers/imbalance_sampler.py +67 -0
- dnt/third_party/fast-reid/fastreid/data/samplers/triplet_sampler.py +260 -0
- dnt/third_party/fast-reid/fastreid/data/transforms/__init__.py +11 -0
- dnt/third_party/fast-reid/fastreid/data/transforms/autoaugment.py +806 -0
- dnt/third_party/fast-reid/fastreid/data/transforms/build.py +100 -0
- dnt/third_party/fast-reid/fastreid/data/transforms/functional.py +180 -0
- dnt/third_party/fast-reid/fastreid/data/transforms/transforms.py +161 -0
- dnt/third_party/fast-reid/fastreid/engine/__init__.py +15 -0
- dnt/third_party/fast-reid/fastreid/engine/defaults.py +490 -0
- dnt/third_party/fast-reid/fastreid/engine/hooks.py +534 -0
- dnt/third_party/fast-reid/fastreid/engine/launch.py +103 -0
- dnt/third_party/fast-reid/fastreid/engine/train_loop.py +357 -0
- dnt/third_party/fast-reid/fastreid/evaluation/__init__.py +6 -0
- dnt/third_party/fast-reid/fastreid/evaluation/clas_evaluator.py +81 -0
- dnt/third_party/fast-reid/fastreid/evaluation/evaluator.py +176 -0
- dnt/third_party/fast-reid/fastreid/evaluation/query_expansion.py +46 -0
- dnt/third_party/fast-reid/fastreid/evaluation/rank.py +200 -0
- dnt/third_party/fast-reid/fastreid/evaluation/rank_cylib/__init__.py +20 -0
- dnt/third_party/fast-reid/fastreid/evaluation/rank_cylib/setup.py +32 -0
- dnt/third_party/fast-reid/fastreid/evaluation/rank_cylib/test_cython.py +106 -0
- dnt/third_party/fast-reid/fastreid/evaluation/reid_evaluation.py +143 -0
- dnt/third_party/fast-reid/fastreid/evaluation/rerank.py +73 -0
- dnt/third_party/fast-reid/fastreid/evaluation/roc.py +90 -0
- dnt/third_party/fast-reid/fastreid/evaluation/testing.py +88 -0
- dnt/third_party/fast-reid/fastreid/layers/__init__.py +19 -0
- dnt/third_party/fast-reid/fastreid/layers/activation.py +59 -0
- dnt/third_party/fast-reid/fastreid/layers/any_softmax.py +80 -0
- dnt/third_party/fast-reid/fastreid/layers/batch_norm.py +205 -0
- dnt/third_party/fast-reid/fastreid/layers/context_block.py +113 -0
- dnt/third_party/fast-reid/fastreid/layers/drop.py +161 -0
- dnt/third_party/fast-reid/fastreid/layers/frn.py +199 -0
- dnt/third_party/fast-reid/fastreid/layers/gather_layer.py +30 -0
- dnt/third_party/fast-reid/fastreid/layers/helpers.py +31 -0
- dnt/third_party/fast-reid/fastreid/layers/non_local.py +54 -0
- dnt/third_party/fast-reid/fastreid/layers/pooling.py +124 -0
- dnt/third_party/fast-reid/fastreid/layers/se_layer.py +25 -0
- dnt/third_party/fast-reid/fastreid/layers/splat.py +109 -0
- dnt/third_party/fast-reid/fastreid/layers/weight_init.py +122 -0
- dnt/third_party/fast-reid/fastreid/modeling/__init__.py +23 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/__init__.py +18 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/build.py +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/mobilenet.py +195 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/mobilenetv3.py +283 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/osnet.py +525 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/__init__.py +4 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/config.py +396 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/effnet/EN-B0_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/effnet/EN-B1_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/effnet/EN-B2_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/effnet/EN-B3_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/effnet/EN-B4_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/effnet/EN-B5_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/effnet.py +281 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnet.py +596 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-1.6GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-12GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-16GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-200MF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-3.2GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-32GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-4.0GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-400MF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-6.4GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-600MF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-8.0GF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnetx/RegNetX-800MF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-1.6GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-12GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-16GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-200MF_dds_8gpu.yaml +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-3.2GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-32GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-4.0GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-400MF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-6.4GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-600MF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-8.0GF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/regnet/regnety/RegNetY-800MF_dds_8gpu.yaml +27 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/repvgg.py +309 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/resnest.py +365 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/resnet.py +364 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/resnext.py +335 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/shufflenet.py +203 -0
- dnt/third_party/fast-reid/fastreid/modeling/backbones/vision_transformer.py +399 -0
- dnt/third_party/fast-reid/fastreid/modeling/heads/__init__.py +11 -0
- dnt/third_party/fast-reid/fastreid/modeling/heads/build.py +25 -0
- dnt/third_party/fast-reid/fastreid/modeling/heads/clas_head.py +36 -0
- dnt/third_party/fast-reid/fastreid/modeling/heads/embedding_head.py +151 -0
- dnt/third_party/fast-reid/fastreid/modeling/losses/__init__.py +12 -0
- dnt/third_party/fast-reid/fastreid/modeling/losses/circle_loss.py +71 -0
- dnt/third_party/fast-reid/fastreid/modeling/losses/cross_entroy_loss.py +54 -0
- dnt/third_party/fast-reid/fastreid/modeling/losses/focal_loss.py +92 -0
- dnt/third_party/fast-reid/fastreid/modeling/losses/triplet_loss.py +113 -0
- dnt/third_party/fast-reid/fastreid/modeling/losses/utils.py +48 -0
- dnt/third_party/fast-reid/fastreid/modeling/meta_arch/__init__.py +14 -0
- dnt/third_party/fast-reid/fastreid/modeling/meta_arch/baseline.py +188 -0
- dnt/third_party/fast-reid/fastreid/modeling/meta_arch/build.py +26 -0
- dnt/third_party/fast-reid/fastreid/modeling/meta_arch/distiller.py +140 -0
- dnt/third_party/fast-reid/fastreid/modeling/meta_arch/mgn.py +394 -0
- dnt/third_party/fast-reid/fastreid/modeling/meta_arch/moco.py +126 -0
- dnt/third_party/fast-reid/fastreid/solver/__init__.py +8 -0
- dnt/third_party/fast-reid/fastreid/solver/build.py +348 -0
- dnt/third_party/fast-reid/fastreid/solver/lr_scheduler.py +66 -0
- dnt/third_party/fast-reid/fastreid/solver/optim/__init__.py +10 -0
- dnt/third_party/fast-reid/fastreid/solver/optim/lamb.py +123 -0
- dnt/third_party/fast-reid/fastreid/solver/optim/radam.py +149 -0
- dnt/third_party/fast-reid/fastreid/solver/optim/swa.py +246 -0
- dnt/third_party/fast-reid/fastreid/utils/__init__.py +6 -0
- dnt/third_party/fast-reid/fastreid/utils/checkpoint.py +503 -0
- dnt/third_party/fast-reid/fastreid/utils/collect_env.py +158 -0
- dnt/third_party/fast-reid/fastreid/utils/comm.py +255 -0
- dnt/third_party/fast-reid/fastreid/utils/compute_dist.py +200 -0
- dnt/third_party/fast-reid/fastreid/utils/env.py +119 -0
- dnt/third_party/fast-reid/fastreid/utils/events.py +461 -0
- dnt/third_party/fast-reid/fastreid/utils/faiss_utils.py +127 -0
- dnt/third_party/fast-reid/fastreid/utils/file_io.py +520 -0
- dnt/third_party/fast-reid/fastreid/utils/history_buffer.py +71 -0
- dnt/third_party/fast-reid/fastreid/utils/logger.py +211 -0
- dnt/third_party/fast-reid/fastreid/utils/params.py +103 -0
- dnt/third_party/fast-reid/fastreid/utils/precision_bn.py +94 -0
- dnt/third_party/fast-reid/fastreid/utils/registry.py +66 -0
- dnt/third_party/fast-reid/fastreid/utils/summary.py +120 -0
- dnt/third_party/fast-reid/fastreid/utils/timer.py +68 -0
- dnt/third_party/fast-reid/fastreid/utils/visualizer.py +278 -0
- dnt/track/__init__.py +2 -0
- dnt/track/botsort/__init__.py +4 -0
- dnt/track/botsort/bot_tracker/__init__.py +3 -0
- dnt/track/botsort/bot_tracker/basetrack.py +60 -0
- dnt/track/botsort/bot_tracker/bot_sort.py +473 -0
- dnt/track/botsort/bot_tracker/gmc.py +316 -0
- dnt/track/botsort/bot_tracker/kalman_filter.py +269 -0
- dnt/track/botsort/bot_tracker/matching.py +194 -0
- dnt/track/botsort/bot_tracker/mc_bot_sort.py +505 -0
- dnt/track/{dsort/utils → botsort/bot_tracker/tracking_utils}/evaluation.py +14 -4
- dnt/track/{dsort/utils → botsort/bot_tracker/tracking_utils}/io.py +19 -36
- dnt/track/botsort/bot_tracker/tracking_utils/timer.py +37 -0
- dnt/track/botsort/inference.py +96 -0
- dnt/track/config.py +120 -0
- dnt/track/dsort/configs/bagtricks_R50.yml +7 -0
- dnt/track/dsort/configs/deep_sort.yaml +0 -0
- dnt/track/dsort/configs/fastreid.yaml +1 -1
- dnt/track/dsort/deep_sort/deep/checkpoint/ckpt.t7 +0 -0
- dnt/track/dsort/deep_sort/deep/feature_extractor.py +87 -8
- dnt/track/dsort/deep_sort/deep_sort.py +31 -20
- dnt/track/dsort/deep_sort/sort/detection.py +2 -1
- dnt/track/dsort/deep_sort/sort/iou_matching.py +0 -2
- dnt/track/dsort/deep_sort/sort/linear_assignment.py +0 -3
- dnt/track/dsort/deep_sort/sort/nn_matching.py +5 -5
- dnt/track/dsort/deep_sort/sort/preprocessing.py +1 -2
- dnt/track/dsort/deep_sort/sort/track.py +2 -1
- dnt/track/dsort/deep_sort/sort/tracker.py +1 -1
- dnt/track/dsort/dsort.py +43 -33
- dnt/track/re_class.py +117 -0
- dnt/track/sort/sort.py +9 -6
- dnt/track/tracker.py +213 -32
- dnt-0.3.1.8.dist-info/METADATA +117 -0
- dnt-0.3.1.8.dist-info/RECORD +315 -0
- {dnt-0.2.4.dist-info → dnt-0.3.1.8.dist-info}/WHEEL +1 -1
- dnt/analysis/yield.py +0 -9
- dnt/track/dsort/deep_sort/deep/evaluate.py +0 -15
- dnt/track/dsort/deep_sort/deep/original_model.py +0 -106
- dnt/track/dsort/deep_sort/deep/test.py +0 -77
- dnt/track/dsort/deep_sort/deep/train.py +0 -189
- dnt/track/dsort/utils/asserts.py +0 -13
- dnt/track/dsort/utils/draw.py +0 -36
- dnt/track/dsort/utils/json_logger.py +0 -383
- dnt/track/dsort/utils/log.py +0 -17
- dnt/track/dsort/utils/parser.py +0 -35
- dnt/track/dsort/utils/tools.py +0 -39
- dnt-0.2.4.dist-info/METADATA +0 -35
- dnt-0.2.4.dist-info/RECORD +0 -64
- /dnt/{track/dsort/utils → third_party/fast-reid/checkpoint}/__init__.py +0 -0
- {dnt-0.2.4.dist-info → dnt-0.3.1.8.dist-info/licenses}/LICENSE +0 -0
- {dnt-0.2.4.dist-info → dnt-0.3.1.8.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,6 @@ from . import kalman_filter
|
|
|
8
8
|
|
|
9
9
|
INFTY_COST = 1e+5
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
def min_cost_matching(
|
|
13
12
|
distance_metric, max_distance, tracks, detections, track_indices=None,
|
|
14
13
|
detection_indices=None):
|
|
@@ -76,7 +75,6 @@ def min_cost_matching(
|
|
|
76
75
|
matches.append((track_idx, detection_idx))
|
|
77
76
|
return matches, unmatched_tracks, unmatched_detections
|
|
78
77
|
|
|
79
|
-
|
|
80
78
|
def matching_cascade(
|
|
81
79
|
distance_metric, max_distance, cascade_depth, tracks, detections,
|
|
82
80
|
track_indices=None, detection_indices=None):
|
|
@@ -142,7 +140,6 @@ def matching_cascade(
|
|
|
142
140
|
unmatched_tracks = list(set(track_indices) - set(k for k, _ in matches))
|
|
143
141
|
return matches, unmatched_tracks, unmatched_detections
|
|
144
142
|
|
|
145
|
-
|
|
146
143
|
def gate_cost_matrix(
|
|
147
144
|
kf, cost_matrix, tracks, detections, track_indices, detection_indices,
|
|
148
145
|
gated_cost=INFTY_COST, only_position=False):
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# vim: expandtab:ts=4:sw=4
|
|
2
2
|
import numpy as np
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
def _pdist(a, b):
|
|
6
5
|
"""Compute pair-wise squared distance between points in `a` and `b`.
|
|
7
6
|
|
|
@@ -19,7 +18,7 @@ def _pdist(a, b):
|
|
|
19
18
|
contains the squared distance between `a[i]` and `b[j]`.
|
|
20
19
|
|
|
21
20
|
"""
|
|
22
|
-
a, b = np.asarray(a), np.asarray(b)
|
|
21
|
+
a, b = np.asarray(a), np.asarray(b)
|
|
23
22
|
if len(a) == 0 or len(b) == 0:
|
|
24
23
|
return np.zeros((len(a), len(b)))
|
|
25
24
|
a2, b2 = np.square(a).sum(axis=1), np.square(b).sum(axis=1)
|
|
@@ -27,7 +26,6 @@ def _pdist(a, b):
|
|
|
27
26
|
r2 = np.clip(r2, 0., float(np.inf))
|
|
28
27
|
return r2
|
|
29
28
|
|
|
30
|
-
|
|
31
29
|
def _cosine_distance(a, b, data_is_normalized=False):
|
|
32
30
|
"""Compute pair-wise cosine distance between points in `a` and `b`.
|
|
33
31
|
|
|
@@ -49,8 +47,10 @@ def _cosine_distance(a, b, data_is_normalized=False):
|
|
|
49
47
|
|
|
50
48
|
"""
|
|
51
49
|
if not data_is_normalized:
|
|
52
|
-
a = np.asarray(a) / np.linalg.norm(a, axis=1, keepdims=True)
|
|
53
|
-
b = np.asarray(b) / np.linalg.norm(b, axis=1, keepdims=True)
|
|
50
|
+
#a = np.asarray(a) / np.linalg.norm(a, axis=1, keepdims=True)
|
|
51
|
+
#b = np.asarray(b) / np.linalg.norm(b, axis=1, keepdims=True)
|
|
52
|
+
a = np.array(a, dtype=np.longdouble) / np.linalg.norm(a, axis=1, keepdims=True)
|
|
53
|
+
b = np.array(b, dtype=np.longdouble) / np.linalg.norm(b, axis=1, keepdims=True)
|
|
54
54
|
return 1. - np.dot(a, b.T)
|
|
55
55
|
|
|
56
56
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import numpy as np
|
|
3
3
|
import cv2
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
def non_max_suppression(boxes, max_bbox_overlap, scores=None):
|
|
7
6
|
"""Suppress overlapping detections.
|
|
8
7
|
|
|
@@ -37,7 +36,7 @@ def non_max_suppression(boxes, max_bbox_overlap, scores=None):
|
|
|
37
36
|
if len(boxes) == 0:
|
|
38
37
|
return []
|
|
39
38
|
|
|
40
|
-
boxes = boxes.astype(
|
|
39
|
+
boxes = boxes.astype(np.float64)
|
|
41
40
|
pick = []
|
|
42
41
|
|
|
43
42
|
x1 = boxes[:, 0]
|
|
@@ -64,7 +64,7 @@ class Track:
|
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
66
|
def __init__(self, mean, covariance, track_id, n_init, max_age,
|
|
67
|
-
feature=None):
|
|
67
|
+
feature=None, cls=None):
|
|
68
68
|
self.mean = mean
|
|
69
69
|
self.covariance = covariance
|
|
70
70
|
self.track_id = track_id
|
|
@@ -73,6 +73,7 @@ class Track:
|
|
|
73
73
|
self.time_since_update = 0
|
|
74
74
|
|
|
75
75
|
self.state = TrackState.Tentative
|
|
76
|
+
self.cls = cls
|
|
76
77
|
self.features = []
|
|
77
78
|
if feature is not None:
|
|
78
79
|
self.features.append(feature)
|
dnt/track/dsort/dsort.py
CHANGED
|
@@ -1,37 +1,41 @@
|
|
|
1
|
-
import os
|
|
1
|
+
import os, sys
|
|
2
2
|
import cv2
|
|
3
3
|
import torch
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pandas as pd
|
|
6
6
|
from tqdm import tqdm
|
|
7
|
-
|
|
8
7
|
from deep_sort import DeepSort
|
|
9
|
-
from
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
8
|
+
from config import Config
|
|
9
|
+
|
|
10
|
+
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
11
|
+
|
|
12
|
+
def track(video_file:str,
|
|
13
|
+
det_file:str,
|
|
14
|
+
out_file:str=None,
|
|
15
|
+
device:str='auto',
|
|
16
|
+
half:bool=False,
|
|
17
|
+
cfg:dict=Config.get_cfg_dsort('default'),
|
|
18
|
+
video_index:int=None,
|
|
19
|
+
total_videos:int=None):
|
|
20
|
+
'''
|
|
21
|
+
Track objects in a video using Deep SORT.
|
|
22
|
+
Args:
|
|
23
|
+
video_file (str): Path to the input video file.
|
|
24
|
+
det_file (str): Path to the detection results file.
|
|
25
|
+
out_file (str): Path to save the tracking results.
|
|
26
|
+
device (str): Device to run the model on ('cpu' or 'cuda').
|
|
27
|
+
half (bool): Whether to use half precision.
|
|
28
|
+
cfg (dict): Configuration dictionary for Deep SORT.
|
|
29
|
+
video_index (int): Index of the current video in a batch.
|
|
30
|
+
total_videos (int): Total number of videos in a batch.
|
|
31
|
+
'''
|
|
32
|
+
#device = torch.device('cuda') if (torch.cuda.is_available() and gpu) else torch.device('cpu')
|
|
24
33
|
cap = cv2.VideoCapture(video_file)
|
|
25
34
|
if not cap.isOpened():
|
|
26
35
|
raise IOError("Couldn't open webcam or video")
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
deepsort = DeepSort(model_path=os.path.join(cwd,reid_ckpt),
|
|
31
|
-
max_dist=max_dist, min_confidence=min_confidence,
|
|
32
|
-
nms_max_overlap=nms_max_overlap, max_iou_distance=max_iou_distance,
|
|
33
|
-
max_age=max_age, n_init=n_init, nn_budget=nn_budget, use_cuda=gpu)
|
|
34
|
-
|
|
36
|
+
|
|
37
|
+
deepsort = DeepSort(cfg, device, half)
|
|
38
|
+
|
|
35
39
|
detections = pd.read_csv(det_file, header=None).to_numpy()
|
|
36
40
|
start_frame = int(min(detections[:,0]))
|
|
37
41
|
end_frame = int(max(detections[:,0]))
|
|
@@ -56,17 +60,24 @@ def track(video_file:str, det_file:str, out_file:str = None, gpu:bool = True,
|
|
|
56
60
|
nrows, ncols = frame_dets.shape
|
|
57
61
|
|
|
58
62
|
if nrows > 0:
|
|
59
|
-
bbox_xywh=[]
|
|
63
|
+
bbox_xywh = []
|
|
60
64
|
for det in frame_dets:
|
|
61
65
|
bbox_xywh.append([det[2]+det[4]/2, det[3]+det[5]/2, det[4], det[5]])
|
|
62
66
|
bbox_xywh = np.array(bbox_xywh)
|
|
63
67
|
conf_score = np.array(frame_dets[:,6])
|
|
64
|
-
|
|
65
|
-
outputs = deepsort.update(bbox_xywh, conf_score, im)
|
|
68
|
+
classes = np.array(frame_dets[:,7])
|
|
69
|
+
outputs = deepsort.update(bbox_xywh, conf_score, classes, im)
|
|
66
70
|
|
|
67
71
|
if len(outputs) > 0:
|
|
68
72
|
for output in outputs:
|
|
69
|
-
results.append([pos_frame,
|
|
73
|
+
results.append([pos_frame,
|
|
74
|
+
output[4],
|
|
75
|
+
output[0],
|
|
76
|
+
output[1],
|
|
77
|
+
output[2]-output[0],
|
|
78
|
+
output[3]-output[1],
|
|
79
|
+
output[5],
|
|
80
|
+
-1, -1, -1])
|
|
70
81
|
|
|
71
82
|
pbar.update()
|
|
72
83
|
|
|
@@ -77,10 +88,9 @@ def track(video_file:str, det_file:str, out_file:str = None, gpu:bool = True,
|
|
|
77
88
|
df.to_csv(out_file, index=False, header=None)
|
|
78
89
|
|
|
79
90
|
if __name__ == "__main__":
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
out_file = "/mnt/d/videos/ped2stage/1026_2/tracks/gh011293_ped_track_2.txt"
|
|
91
|
+
video_file = "/mnt/d/videos/sample/traffic.mp4"
|
|
92
|
+
iou_file = "/mnt/d/videos/sample/dets/traffic_det.txt"
|
|
93
|
+
out_file = "/mnt/d/videos/sample/tracks/traffic_track.txt"
|
|
84
94
|
|
|
85
95
|
track(video_file, iou_file, out_file)
|
|
86
96
|
|
dnt/track/re_class.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from tqdm import tqdm
|
|
4
|
+
from ..detect import Detector
|
|
5
|
+
from ..engine.iob import iobs
|
|
6
|
+
|
|
7
|
+
class ReClass:
|
|
8
|
+
def __init__(self,
|
|
9
|
+
num_frames:int=25,
|
|
10
|
+
threshold:float=0.75,
|
|
11
|
+
model:str='rtdetr',
|
|
12
|
+
weights:str='x',
|
|
13
|
+
device:str='auto',
|
|
14
|
+
default_class:int=0,
|
|
15
|
+
match_class:list=[1, 36]) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Re-classify tracks based on detection results
|
|
18
|
+
Parameters:
|
|
19
|
+
num_frames: Number of frames to consider for re-classification, default 25
|
|
20
|
+
threshold: Threshold for matching, default 0.75
|
|
21
|
+
model: Detection model to use, default 'rtdetr'
|
|
22
|
+
weights: Weights for the detection model, default 'x'
|
|
23
|
+
device: Device to use for detection, default 'auto'
|
|
24
|
+
default_class: Default class to assign if no match found, default 0 (pedestrian)
|
|
25
|
+
match_class: List of classes to match, default [1, 36] (bicycle, skateboard/scooter)
|
|
26
|
+
"""
|
|
27
|
+
self.detector = Detector(model=model, device=device)
|
|
28
|
+
self.num_frames = num_frames
|
|
29
|
+
self.threshold = threshold
|
|
30
|
+
self.default_class = default_class
|
|
31
|
+
self.match_class = match_class
|
|
32
|
+
|
|
33
|
+
def match_mmv(self, track:pd.DataFrame, dets:pd.DataFrame)->tuple:
|
|
34
|
+
|
|
35
|
+
score = 0
|
|
36
|
+
cnt = 0
|
|
37
|
+
for idx, row in track.iterrows():
|
|
38
|
+
bboxes = row[['x', 'y', 'w', 'h']].values.reshape(1, -1)
|
|
39
|
+
det = dets[dets['frame'] == row['frame']]
|
|
40
|
+
if len(det) > 0:
|
|
41
|
+
match_bboxes = det[['x', 'y', 'w', 'h']].values
|
|
42
|
+
_, overlaps_mmv = iobs(bboxes, match_bboxes)
|
|
43
|
+
max_overlap = np.max(overlaps_mmv)
|
|
44
|
+
if max_overlap >= self.threshold:
|
|
45
|
+
score += max_overlap
|
|
46
|
+
cnt += 1
|
|
47
|
+
|
|
48
|
+
if cnt > 0:
|
|
49
|
+
avg_score = score/cnt
|
|
50
|
+
else:
|
|
51
|
+
avg_score = 0
|
|
52
|
+
hit = True if avg_score >= self.threshold else False
|
|
53
|
+
|
|
54
|
+
return hit, avg_score
|
|
55
|
+
|
|
56
|
+
def re_classify(self,
|
|
57
|
+
tracks:pd.DataFrame,
|
|
58
|
+
input_video:str,
|
|
59
|
+
track_ids:list=None,
|
|
60
|
+
out_file:str=None,
|
|
61
|
+
verbose:bool=True)->pd.DataFrame:
|
|
62
|
+
"""
|
|
63
|
+
Re-classify tracks
|
|
64
|
+
Parameters:
|
|
65
|
+
tracks: DataFrame with target tracks
|
|
66
|
+
input_video: Path to video
|
|
67
|
+
track_ids: List of track IDs for re-classify, if None re-classify all tracks, default None
|
|
68
|
+
default_cls: Default class to assign if no match found, default 0 (pedestrian)
|
|
69
|
+
match_cls: List of classes to match, default [1, 36] (bicycle, skateboard/scooter)
|
|
70
|
+
out_file: Path to save re-classified tracks, default None
|
|
71
|
+
Returns:
|
|
72
|
+
DataFrame with re-classified tracks (track_id, cls, avg_score)
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
if track_ids is None:
|
|
76
|
+
track_ids = tracks['track'].unique().tolist()
|
|
77
|
+
|
|
78
|
+
results = []
|
|
79
|
+
if verbose:
|
|
80
|
+
pbar = tqdm(total=len(track_ids), unit='track', desc='Re-classifying tracks')
|
|
81
|
+
for track_id in track_ids:
|
|
82
|
+
|
|
83
|
+
target_track = tracks[tracks['track'] == track_id].copy()
|
|
84
|
+
target_track['area'] = target_track['w'] * target_track['h']
|
|
85
|
+
target_track.sort_values(by='area', inplace=True, ascending=False)
|
|
86
|
+
|
|
87
|
+
if len(target_track) >= self.num_frames:
|
|
88
|
+
top_frames = target_track.head(self.num_frames)
|
|
89
|
+
else:
|
|
90
|
+
top_frames = target_track
|
|
91
|
+
|
|
92
|
+
dets = self.detector.detect_frames(input_video, top_frames['frame'].values.tolist())
|
|
93
|
+
|
|
94
|
+
matched = []
|
|
95
|
+
for cls in self.match_class:
|
|
96
|
+
match_dets = dets[dets['class'] == cls]
|
|
97
|
+
hit, avg_score = self.match_mmv(top_frames, match_dets)
|
|
98
|
+
if hit:
|
|
99
|
+
matched.append((cls, avg_score))
|
|
100
|
+
|
|
101
|
+
if len(matched) > 0:
|
|
102
|
+
cls, avg_score = max(matched, key=lambda x: x[1])
|
|
103
|
+
else:
|
|
104
|
+
cls = self.default_class
|
|
105
|
+
avg_score = 0
|
|
106
|
+
|
|
107
|
+
results.append([track_id, cls, round(avg_score, 2)])
|
|
108
|
+
if verbose:
|
|
109
|
+
pbar.update()
|
|
110
|
+
if verbose:
|
|
111
|
+
pbar.close()
|
|
112
|
+
|
|
113
|
+
df = pd.DataFrame(results, columns=['track', 'cls', 'avg_score'])
|
|
114
|
+
if out_file:
|
|
115
|
+
df.to_csv(out_file, index=False)
|
|
116
|
+
|
|
117
|
+
return df
|
dnt/track/sort/sort.py
CHANGED
|
@@ -202,7 +202,7 @@ class Sort(object):
|
|
|
202
202
|
def update(self, dets=np.empty((0, 5))):
|
|
203
203
|
"""
|
|
204
204
|
Params:
|
|
205
|
-
dets - a numpy array of detections in the format [[x1,y1,x2,y2,score]
|
|
205
|
+
dets - a numpy array of detections in the format [[x1,y1,x2,y2,score]
|
|
206
206
|
Requires: this method must be called once for each frame even with empty detections (use np.empty((0, 5)) for frames without detections).
|
|
207
207
|
Returns the a similar array, where the last column is the object ID.
|
|
208
208
|
|
|
@@ -246,9 +246,9 @@ class Sort(object):
|
|
|
246
246
|
|
|
247
247
|
def track(det_file, out_file, max_age=1, min_inits=3, iou_threshold=0.3, video_index = None, total_videos = None):
|
|
248
248
|
|
|
249
|
-
tracker = Sort(max_age=max_age,
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
tracker = Sort(max_age=max_age,
|
|
250
|
+
min_hits=min_inits,
|
|
251
|
+
iou_threshold=iou_threshold)
|
|
252
252
|
dets = np.loadtxt(det_file, delimiter=',')
|
|
253
253
|
start_frame = int(dets[:,0].min())
|
|
254
254
|
end_frame = int(dets[:,0].max())
|
|
@@ -265,7 +265,6 @@ def track(det_file, out_file, max_age=1, min_inits=3, iou_threshold=0.3, video_i
|
|
|
265
265
|
if len(dets_frame)>0:
|
|
266
266
|
dets_revised[:,[0,1]] = dets_frame[:,[2,3]]
|
|
267
267
|
dets_revised[:,2] = dets_frame[:,2] + dets_frame[:,4]
|
|
268
|
-
|
|
269
268
|
dets_revised[:,3] = dets_frame[:,3] + dets_frame[:,5]
|
|
270
269
|
dets_revised[:,4] = dets_frame[:,6] / 100
|
|
271
270
|
|
|
@@ -283,8 +282,12 @@ def track(det_file, out_file, max_age=1, min_inits=3, iou_threshold=0.3, video_i
|
|
|
283
282
|
df = pd.DataFrame(results)
|
|
284
283
|
df[3] = df[3] - df[1]
|
|
285
284
|
df[4] = df[4] - df[2]
|
|
285
|
+
df[6] = -1
|
|
286
|
+
df[7] = -1
|
|
287
|
+
df[8] = -1
|
|
288
|
+
df[9] = -1
|
|
286
289
|
df = df.astype('int')
|
|
287
|
-
df[[0,5,1,2,3,4]].to_csv(out_file, index=False, header=None)
|
|
290
|
+
df[[0,5,1,2,3,4,6,7,8,9]].to_csv(out_file, index=False, header=None)
|
|
288
291
|
|
|
289
292
|
if __name__ == '__main__':
|
|
290
293
|
pass
|
dnt/track/tracker.py
CHANGED
|
@@ -1,37 +1,54 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
4
|
from dsort import track as track_dsort
|
|
5
5
|
from sort import track as track_sort
|
|
6
|
+
from botsort import track as track_botsort
|
|
7
|
+
from config import Config
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
from tqdm import tqdm
|
|
10
|
+
import numpy as np
|
|
11
|
+
from ..engine import interpolate_bbox, interpolate_bboxes, cluster_by_gap
|
|
12
|
+
|
|
13
|
+
sys.path.append(os.path.dirname(__file__))
|
|
14
|
+
|
|
15
|
+
class Tracker(object):
|
|
16
|
+
def __init__(self, cfg: dict = None, device:str='auto', half:bool=False):
|
|
13
17
|
'''
|
|
14
|
-
|
|
18
|
+
Parameters:
|
|
19
|
+
cfg: dict - Configuration for tracking method
|
|
20
|
+
device: str - Device to run the tracking method, default is 'auto', 'cuda','cpu', 'mps'
|
|
21
|
+
half: bool - If True, use half precision for tracking, default is False
|
|
15
22
|
'''
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
if cfg is None:
|
|
24
|
+
self.cfg = Config.get_cfg_dsort()
|
|
25
|
+
else:
|
|
26
|
+
self.cfg = cfg
|
|
27
|
+
self.device = device
|
|
28
|
+
self.half = half
|
|
20
29
|
|
|
21
|
-
|
|
22
30
|
def track(self, det_file:str, out_file:str, video_file:str=None, video_index:int=None, total_videos:int=None):
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
'''
|
|
32
|
+
Parameters:
|
|
33
|
+
- det_file: Detection file path
|
|
34
|
+
- out_file: Output track file path
|
|
35
|
+
- video_file: Video file path
|
|
36
|
+
- video_index: Index of video in the batch
|
|
37
|
+
- total_videos: Total number of videos in the batch
|
|
38
|
+
'''
|
|
39
|
+
|
|
40
|
+
if self.cfg['method'] == 'sort':
|
|
41
|
+
track_sort(det_file, out_file, self.cfg['max_age'], self.cfg['min_inits'],
|
|
42
|
+
self.cfg['iou_threshold'], video_index, total_videos)
|
|
43
|
+
elif self.cfg['method'] == 'dsort':
|
|
27
44
|
if video_file:
|
|
28
|
-
track_dsort(video_file=video_file, det_file=det_file, out_file=out_file,
|
|
29
|
-
max_dist=self.dsort_cfg['max_dist'], min_confidence=self.dsort_cfg['min_confidence'],
|
|
30
|
-
nms_max_overlap=self.dsort_cfg['nms_max_overlap'], max_iou_distance=self.dsort_cfg['max_iou_distance'],
|
|
31
|
-
max_age=self.dsort_cfg['max_age'], n_init=self.dsort_cfg['max_age'], nn_budget=self.dsort_cfg['nn_budget'],
|
|
45
|
+
track_dsort(video_file=video_file, det_file=det_file, out_file=out_file, device=self.device, half=self.half, cfg=self.cfg,
|
|
32
46
|
video_index=video_index, total_videos=total_videos)
|
|
33
47
|
else:
|
|
34
|
-
print('
|
|
48
|
+
print('No video file exists!')
|
|
49
|
+
elif self.cfg['method'] == 'botsort':
|
|
50
|
+
track_botsort(video_file=video_file, det_file=det_file, out_file=out_file, cfg=self.cfg,
|
|
51
|
+
video_index=video_index, total_videos=total_videos)
|
|
35
52
|
else:
|
|
36
53
|
print('Invalid tracking method!')
|
|
37
54
|
|
|
@@ -56,7 +73,7 @@ class Tracker:
|
|
|
56
73
|
continue
|
|
57
74
|
|
|
58
75
|
video_file = None
|
|
59
|
-
if self.method=="dsort":
|
|
76
|
+
if self.cfg['method']=="dsort":
|
|
60
77
|
video_file = video_files[count-1]
|
|
61
78
|
|
|
62
79
|
self.track(det_file=det_file, out_file=track_file, video_file=video_file, video_index=count, total_videos=total_videos)
|
|
@@ -64,17 +81,181 @@ class Tracker:
|
|
|
64
81
|
results.append(track_file)
|
|
65
82
|
|
|
66
83
|
return results
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def export_track_header():
|
|
87
|
+
return ['frame', 'track', 'x', 'y', 'w', 'h', 'score', 'cls', 'infill', 'cluster']
|
|
67
88
|
|
|
68
89
|
@staticmethod
|
|
69
|
-
def
|
|
90
|
+
def infill_frames(tracks:pd.DataFrame, ids:list[int] = None, method:str='cubic', inplace:bool=True, info:str='',
|
|
91
|
+
video_index:int=None, video_tot:int=None, verbose:bool=True) -> pd.DataFrame:
|
|
70
92
|
'''
|
|
71
|
-
|
|
93
|
+
Paramters:
|
|
94
|
+
- tracks: the track dataframe need to be fill
|
|
95
|
+
- ids: track ids need to be fill, if None, all ids will be processed
|
|
96
|
+
- method: interpolation method, 'cubic' (default), 'linear', 'nearest'
|
|
97
|
+
- inplace: if combine filled and raw frames in the output, default is True.
|
|
98
|
+
Return:
|
|
99
|
+
- A dataframe contains infilled frames (inplace=False), or infilled+raw (inplace=True)
|
|
72
100
|
'''
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
101
|
+
results = []
|
|
102
|
+
|
|
103
|
+
tracks.columns = Tracker.export_track_header()
|
|
104
|
+
if ids is None:
|
|
105
|
+
ids = tracks['track'].unique()
|
|
106
|
+
|
|
107
|
+
pbar = tqdm(total=len(ids), unit=' tracks')
|
|
108
|
+
if video_index and video_tot:
|
|
109
|
+
pbar.set_description_str("Infliing frames for {} tracks, {} of {}".format(info, video_index, video_tot))
|
|
110
|
+
else:
|
|
111
|
+
pbar.set_description_str("Inflling frames for {} tracks".format(info))
|
|
112
|
+
for id in ids:
|
|
113
|
+
frames = tracks[tracks['track']==id].copy().sort_values(by='frame')
|
|
114
|
+
f_min = frames['frame'].min()
|
|
115
|
+
f_max = frames['frame'].max()
|
|
116
|
+
|
|
117
|
+
if (f_max-f_min+1) > len(frames):
|
|
118
|
+
raw_fids = frames['frame'].values.tolist()
|
|
119
|
+
missed_fids = Tracker.__find_missing_number(raw_fids)
|
|
120
|
+
|
|
121
|
+
raw_bboxes = frames[['x', 'y', 'w', 'h']].to_numpy()
|
|
122
|
+
infilled_bboxes = interpolate_bboxes(boxes = raw_bboxes, frames = np.array(raw_fids), target_frames=np.array(missed_fids),
|
|
123
|
+
method=method)
|
|
124
|
+
|
|
125
|
+
d = {'frame':missed_fids, 'track':id, 'x': infilled_bboxes[:,0], 'y':infilled_bboxes[:,1],
|
|
126
|
+
'w':infilled_bboxes[:,2], 'h':infilled_bboxes[:,3], 'score':frames['score'].iloc[0],
|
|
127
|
+
'cls':frames['cls'].iloc[0], 'infill':1, 'cluster':frames['cluster'].iloc[0]}
|
|
128
|
+
df = pd.DataFrame(d)
|
|
129
|
+
df = pd.concat([frames, df], ignore_index=True).sort_values(by='frame')
|
|
130
|
+
results.append(df)
|
|
131
|
+
|
|
132
|
+
if verbose:
|
|
133
|
+
pbar.update()
|
|
134
|
+
|
|
135
|
+
pbar.close()
|
|
136
|
+
|
|
137
|
+
if len(results)>0:
|
|
138
|
+
df = pd.concat(results, ignore_index=True)
|
|
139
|
+
if inplace:
|
|
140
|
+
df = pd.concat([tracks, df], ignore_index=True).sort_values(by=['frame', 'track'])
|
|
141
|
+
return df
|
|
78
142
|
else:
|
|
143
|
+
if inplace:
|
|
144
|
+
return tracks
|
|
145
|
+
else:
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def cluster_frames(tracks:pd.DataFrame, ids:list[int] = None, gap_thres:int=100, keep_thres:int=25, inplace:bool=True,
|
|
150
|
+
video_index:int=None, video_tot:int=None, verbose:bool=True) -> pd.DataFrame:
|
|
151
|
+
'''
|
|
152
|
+
Paramters:
|
|
153
|
+
- tracks: a dataframe of tracks need to be clustered by empty frames
|
|
154
|
+
- ids: track ids need to be clustered, if None, all track ids
|
|
155
|
+
- gap_thres: if empty frames > gap_thres, the track will be cut-off, default is 100
|
|
156
|
+
- keep_thres: if the frames of a clustered track is >= keep_thres, the track will be kept, default is 25
|
|
157
|
+
- inplace: if combine filled and raw frames in the output, default is True.
|
|
158
|
+
Return:
|
|
159
|
+
- A dataframe contains infilled frames (inplace=False), or infilled+raw (inplace=True)
|
|
160
|
+
'''
|
|
161
|
+
results = []
|
|
162
|
+
del_ids = []
|
|
163
|
+
|
|
164
|
+
tracks.columns = Tracker.export_track_header()
|
|
165
|
+
if ids is None:
|
|
166
|
+
ids = tracks['track'].unique()
|
|
167
|
+
tracks_grouped = tracks.groupby('track')
|
|
168
|
+
|
|
169
|
+
id_index = max(ids)
|
|
170
|
+
|
|
171
|
+
pbar = tqdm(total=len(ids), unit=' track')
|
|
172
|
+
if video_index and video_tot:
|
|
173
|
+
pbar.set_description_str("Clustering frames {} of {}".format(video_index, video_tot))
|
|
174
|
+
else:
|
|
175
|
+
pbar.set_description_str("Clustering frames")
|
|
176
|
+
for id in ids:
|
|
177
|
+
#frames = tracks[tracks['track']==id].copy().sort_values(by='frame')
|
|
178
|
+
frames = tracks_grouped.get_group(id)
|
|
179
|
+
fids = frames['frame'].values
|
|
180
|
+
clusters = cluster_by_gap(fids, gap_thres)
|
|
181
|
+
|
|
182
|
+
if len(clusters) > 1:
|
|
183
|
+
for cluster in clusters:
|
|
184
|
+
frame_length = max(cluster) - min(cluster) + 1
|
|
185
|
+
if frame_length >= keep_thres:
|
|
186
|
+
#d = tracks[(tracks['track']==id) & (tracks['frame'].isin(cluster))].copy()
|
|
187
|
+
d = frames[frames['frame'].isin(cluster)].copy()
|
|
188
|
+
id_index += 1
|
|
189
|
+
d['track'] = id_index
|
|
190
|
+
d['cluster'] = id
|
|
191
|
+
results.append(d)
|
|
192
|
+
del_ids.append(id)
|
|
193
|
+
|
|
194
|
+
if verbose:
|
|
195
|
+
pbar.update()
|
|
196
|
+
|
|
197
|
+
pbar.close()
|
|
198
|
+
|
|
199
|
+
if results == []:
|
|
79
200
|
return None
|
|
201
|
+
|
|
202
|
+
df = pd.concat(results, ignore_index=True)
|
|
203
|
+
if inplace:
|
|
204
|
+
tracks_del = tracks[~tracks['track'].isin(del_ids)].copy()
|
|
205
|
+
df = pd.concat([tracks_del, df], ignore_index=True).sort_values(by=['frame', 'track'])
|
|
206
|
+
|
|
207
|
+
return df
|
|
208
|
+
|
|
209
|
+
@staticmethod
|
|
210
|
+
def del_short_tracks(tracks:pd.DataFrame, keep_thres:int=25,
|
|
211
|
+
video_index:int=None, video_tot:int=None, verbose:bool=True) -> pd.DataFrame:
|
|
212
|
+
'''
|
|
213
|
+
Paramters:
|
|
214
|
+
- tracks: a dataframe of tracks need to be clustered by empty frames
|
|
215
|
+
- ids: track ids need to be clustered, if None, all track ids
|
|
216
|
+
- gap_thres: if empty frames > gap_thres, the track will be cut-off, default is 100
|
|
217
|
+
- keep_thres: if the frames of a clustered track is >= keep_thres, the track will be kept, default is 25
|
|
218
|
+
- inplace: if combine filled and raw frames in the output, default is True.
|
|
219
|
+
|
|
220
|
+
Return:
|
|
221
|
+
- A dataframe contains infilled frames (inplace=False), or infilled+raw (inplace=True)
|
|
222
|
+
'''
|
|
223
|
+
del_ids = []
|
|
224
|
+
|
|
225
|
+
tracks.columns = Tracker.export_track_header()
|
|
226
|
+
ids = tracks['track'].unique()
|
|
227
|
+
tracks_grouped = tracks.groupby('track')
|
|
228
|
+
|
|
229
|
+
pbar = tqdm(total=len(ids), unit=' track')
|
|
230
|
+
if video_index and video_tot:
|
|
231
|
+
pbar.set_description_str("Scan short tracks {} of {}".format(video_index, video_tot))
|
|
232
|
+
else:
|
|
233
|
+
pbar.set_description_str("Scan short tracks")
|
|
234
|
+
for id in ids:
|
|
235
|
+
frames = tracks_grouped.get_group(id)
|
|
236
|
+
#frames = tracks[tracks['track']==id].copy().sort_values(by='frame')
|
|
237
|
+
frame_max = max(frames['frame'].values)
|
|
238
|
+
frame_min = min(frames['frame'].values)
|
|
239
|
+
frame_length = frame_max - frame_min + 1
|
|
240
|
+
if frame_length < keep_thres:
|
|
241
|
+
del_ids.append(id)
|
|
242
|
+
|
|
243
|
+
if verbose:
|
|
244
|
+
pbar.update()
|
|
245
|
+
pbar.close()
|
|
246
|
+
|
|
247
|
+
tracks_del = tracks[~tracks['track'].isin(del_ids)].copy()
|
|
248
|
+
return tracks_del
|
|
249
|
+
|
|
250
|
+
@staticmethod
|
|
251
|
+
def __find_missing_number(arr: list[int]) -> list[int]:
|
|
252
|
+
full_set = set(range(min(arr), max(arr) + 1))
|
|
253
|
+
arr_set = set(arr)
|
|
254
|
+
missing_numbers = list(full_set - arr_set)
|
|
255
|
+
return missing_numbers
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
80
261
|
|