dnt 0.2.4__py3-none-any.whl → 0.3.1.3__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.
Potentially problematic release.
This version of dnt might be problematic. Click here for more details.
- dnt/__init__.py +3 -2
- dnt/analysis/__init__.py +3 -2
- dnt/analysis/interaction.py +503 -0
- dnt/analysis/stop.py +22 -17
- dnt/analysis/stop2.py +289 -0
- dnt/analysis/stop3.py +754 -0
- dnt/detect/signal/detector.py +317 -0
- dnt/detect/yolov8/detector.py +116 -16
- 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 +321 -1
- dnt/label/labeler.py +4 -4
- dnt/label/labeler2.py +502 -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 +28 -18
- 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/dsort.py +21 -28
- dnt/track/re_class.py +94 -0
- dnt/track/sort/sort.py +5 -1
- dnt/track/tracker.py +207 -30
- {dnt-0.2.4.dist-info → dnt-0.3.1.3.dist-info}/METADATA +30 -10
- dnt-0.3.1.3.dist-info/RECORD +314 -0
- {dnt-0.2.4.dist-info → dnt-0.3.1.3.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/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.3.dist-info}/LICENSE +0 -0
- {dnt-0.2.4.dist-info → dnt-0.3.1.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import cv2, os
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import numpy as np
|
|
5
|
+
from tqdm import tqdm
|
|
6
|
+
from PIL import Image
|
|
7
|
+
from typing import List
|
|
8
|
+
import torch
|
|
9
|
+
import torch.nn as nn
|
|
10
|
+
import torchvision.models as models
|
|
11
|
+
import torchvision.transforms as transforms
|
|
12
|
+
from torchvision.models.resnet import ResNet18_Weights
|
|
13
|
+
from shared.download import download_file
|
|
14
|
+
from matplotlib import pyplot as plt
|
|
15
|
+
|
|
16
|
+
class Model(nn.Module):
|
|
17
|
+
def __init__(self):
|
|
18
|
+
super(Model, self).__init__()
|
|
19
|
+
|
|
20
|
+
self.resnet18 = models.resnet18(weights=ResNet18_Weights.DEFAULT)
|
|
21
|
+
self.resnet18.fc = nn.Linear(512, 2)
|
|
22
|
+
|
|
23
|
+
def forward(self, x):
|
|
24
|
+
return self.resnet18(x)
|
|
25
|
+
|
|
26
|
+
class SignalDetector:
|
|
27
|
+
def __init__(self, det_zones:list, model:str='ped', weights:str=None, batchsz:int=64, threshold:float=0.98, device='auto'):
|
|
28
|
+
'''
|
|
29
|
+
Detect traffic signal status
|
|
30
|
+
|
|
31
|
+
Parameters:
|
|
32
|
+
- det_zones: cropped zones for detection list[(x, y, w, h)]
|
|
33
|
+
- model: detection model, default is 'ped', 'custom'
|
|
34
|
+
- weights: path of weights, default is None
|
|
35
|
+
- batchsz: the batch size for prediction, default is 64
|
|
36
|
+
- threshold: the threshold for detection, default is 0.98
|
|
37
|
+
'''
|
|
38
|
+
|
|
39
|
+
self.det_zones = det_zones
|
|
40
|
+
|
|
41
|
+
cwd = Path(__file__).parent.absolute()
|
|
42
|
+
if not weights:
|
|
43
|
+
if (model == 'ped'):
|
|
44
|
+
weights = os.path.join(cwd, 'weights', 'ped_signal.pt')
|
|
45
|
+
|
|
46
|
+
if not os.path.exists(weights):
|
|
47
|
+
url = 'https://its.cutr.usf.edu/alms/downloads/ped_signal.pt'
|
|
48
|
+
download_file(url, weights)
|
|
49
|
+
|
|
50
|
+
self.model = Model()
|
|
51
|
+
if device == 'auto':
|
|
52
|
+
self.device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
|
|
53
|
+
elif device == 'cuda' and torch.cuda.is_available():
|
|
54
|
+
self.device = 'cuda'
|
|
55
|
+
elif device == 'mps' and torch.backends.mps.is_available():
|
|
56
|
+
self.device = 'mps'
|
|
57
|
+
else:
|
|
58
|
+
self.device = 'cpu'
|
|
59
|
+
|
|
60
|
+
self.model.load_state_dict(torch.load(weights))
|
|
61
|
+
self.model.to(self.device)
|
|
62
|
+
|
|
63
|
+
self.batchsz = batchsz
|
|
64
|
+
self.threshold = threshold
|
|
65
|
+
|
|
66
|
+
def detect(self, input_video:str, det_file:str=None,
|
|
67
|
+
video_index:int=None, video_tot:int=None):
|
|
68
|
+
'''
|
|
69
|
+
Parameters:
|
|
70
|
+
- input_video: the video path
|
|
71
|
+
- det_file: the file name for output
|
|
72
|
+
- video_index: the index of video
|
|
73
|
+
- video_tot: the total number of videos
|
|
74
|
+
|
|
75
|
+
Return:
|
|
76
|
+
- a dataframe with prediction results, ['frame', 'zone0', 'zone1', ...]
|
|
77
|
+
'''
|
|
78
|
+
|
|
79
|
+
# initialize the result array
|
|
80
|
+
results = np.array([]) #np.full((0, len(self.det_zones)), -1)
|
|
81
|
+
frames = np.array([])
|
|
82
|
+
zones = np.array([])
|
|
83
|
+
batch = []
|
|
84
|
+
temp_frames=[]
|
|
85
|
+
|
|
86
|
+
# open input video
|
|
87
|
+
cap = cv2.VideoCapture(input_video)
|
|
88
|
+
if not cap.isOpened():
|
|
89
|
+
print('Failed to open the video!')
|
|
90
|
+
|
|
91
|
+
tot_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
92
|
+
pbar = tqdm(total=tot_frames, unit=' frame')
|
|
93
|
+
if video_index and video_tot:
|
|
94
|
+
pbar.set_description_str("Detecting signals {} of {}".format(video_index, video_tot))
|
|
95
|
+
else:
|
|
96
|
+
pbar.set_description_str("Detecting signals ")
|
|
97
|
+
|
|
98
|
+
while cap.isOpened():
|
|
99
|
+
pos_frame = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
|
|
100
|
+
ret, frame = cap.read()
|
|
101
|
+
if not ret:
|
|
102
|
+
break
|
|
103
|
+
|
|
104
|
+
crop_img = self.crop_zone(frame)
|
|
105
|
+
batch.append(crop_img)
|
|
106
|
+
temp_frames.append(pos_frame)
|
|
107
|
+
|
|
108
|
+
if ((pos_frame+1) % self.batchsz == 0) or (pos_frame >= tot_frames-1):
|
|
109
|
+
#batch_pred = self.predict(batch).reshape(-1, len(self.det_zones))
|
|
110
|
+
#results = np.append(results, batch_pred, axis=0)
|
|
111
|
+
|
|
112
|
+
batch_pred = self.predict(batch).flatten()
|
|
113
|
+
results = np.append(results, batch_pred, axis=0)
|
|
114
|
+
zones = np.append(zones, np.tile(np.array(list(range(len(self.det_zones)))), self.batchsz), axis=0)
|
|
115
|
+
frames = np.append(frames, np.repeat(np.array(temp_frames), len(self.det_zones)), axis=0)
|
|
116
|
+
|
|
117
|
+
batch=[]
|
|
118
|
+
temp_frames = []
|
|
119
|
+
|
|
120
|
+
pbar.update()
|
|
121
|
+
|
|
122
|
+
pbar.close()
|
|
123
|
+
cap.release()
|
|
124
|
+
|
|
125
|
+
df = pd.DataFrame(list(zip(frames, zones, results)), columns=['frame', 'signal', 'detection'])
|
|
126
|
+
|
|
127
|
+
if det_file:
|
|
128
|
+
df.to_csv(det_file, index=False)
|
|
129
|
+
|
|
130
|
+
return df
|
|
131
|
+
|
|
132
|
+
def gen_ped_interval(self, dets:pd.DataFrame, input_video:str, walk_interval:int, countdown_interval:int,
|
|
133
|
+
out_file:str, factor:float=0.75, video_index:int=None, video_tot:int=None):
|
|
134
|
+
'''
|
|
135
|
+
Parameters:
|
|
136
|
+
- dets: the dataframe for signal detections
|
|
137
|
+
- input_video: the video path
|
|
138
|
+
- walk_interval: the pedestrian walking interval 4s to 7s
|
|
139
|
+
- countdown_interval: the pedestrian countdown interval, cross-length(ft)/4(ft/s)
|
|
140
|
+
- factor: the factor to identify a walking signal (0, 1),
|
|
141
|
+
default is 0.75 (75% of frames in a sliding window is walking, then walking is identified)
|
|
142
|
+
|
|
143
|
+
Return:
|
|
144
|
+
- a dataframe of ped sigal intervals ['signal', 'walk_beg', 'walk_end', 'countdown_beg', 'countdown_end']
|
|
145
|
+
'''
|
|
146
|
+
|
|
147
|
+
# open input video
|
|
148
|
+
cap = cv2.VideoCapture(input_video)
|
|
149
|
+
if not cap.isOpened():
|
|
150
|
+
print('Failed to open the video!')
|
|
151
|
+
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
152
|
+
cap.release()
|
|
153
|
+
|
|
154
|
+
results = []
|
|
155
|
+
for i in range(len(self.det_zones)):
|
|
156
|
+
dets_i = dets[dets['signal']==i]
|
|
157
|
+
results.append(self.scan_walk_interval(dets_i, int(fps*walk_interval), factor, i, fps))
|
|
158
|
+
|
|
159
|
+
df = pd.concat(results, axis=0)
|
|
160
|
+
if out_file:
|
|
161
|
+
df.to_csv(out_file, index=False)
|
|
162
|
+
|
|
163
|
+
return df
|
|
164
|
+
|
|
165
|
+
def scan_walk_interval(self, dets:pd.DataFrame, window:int, factor:float, zone:int, fps:int=30,
|
|
166
|
+
video_index:int=None, video_tot:int=None) -> pd.DataFrame:
|
|
167
|
+
|
|
168
|
+
sequence = dets['detection'].to_numpy()
|
|
169
|
+
|
|
170
|
+
if len(sequence) == 0:
|
|
171
|
+
return []
|
|
172
|
+
|
|
173
|
+
frame_intervals = []
|
|
174
|
+
pre_walk = False
|
|
175
|
+
tmp_cnt = 0
|
|
176
|
+
|
|
177
|
+
pbar = tqdm(total=len(sequence)-window, unit=' frame')
|
|
178
|
+
if video_index and video_tot:
|
|
179
|
+
pbar.set_description_str("Scanning intervals for signal {}, {} of {}".format(zone, video_index, video_tot))
|
|
180
|
+
else:
|
|
181
|
+
pbar.set_description_str("Scanning intervals for signal {}".format(zone))
|
|
182
|
+
|
|
183
|
+
for i in range(len(sequence) - window):
|
|
184
|
+
count = sum(sequence[i:i+window])
|
|
185
|
+
|
|
186
|
+
# check if the current frame can be a start of green light
|
|
187
|
+
if count >= factor * window:
|
|
188
|
+
is_walking = True
|
|
189
|
+
else:
|
|
190
|
+
is_walking = False
|
|
191
|
+
|
|
192
|
+
# if the current is green
|
|
193
|
+
# 1) if prev status is green, update the latest interval
|
|
194
|
+
# 2) if prev status is not green, append a new interval
|
|
195
|
+
if is_walking:
|
|
196
|
+
if not pre_walk:
|
|
197
|
+
frame_intervals.append([i, i + window])
|
|
198
|
+
tmp_cnt = 0
|
|
199
|
+
else:
|
|
200
|
+
if count > tmp_cnt:
|
|
201
|
+
tmp_cnt = count
|
|
202
|
+
frame_intervals[-1] = [i, i + window]
|
|
203
|
+
|
|
204
|
+
pre_walk = is_walking
|
|
205
|
+
|
|
206
|
+
pbar.update()
|
|
207
|
+
pbar.close()
|
|
208
|
+
|
|
209
|
+
results = []
|
|
210
|
+
for start, end in frame_intervals:
|
|
211
|
+
results.append([zone, 1, int(dets['frame'].iloc[start]), int(dets['frame'].iloc[end])])
|
|
212
|
+
results.append([zone, 2, int(dets['frame'].iloc[end])+1, int(dets['frame'].iloc[end]+int(10*fps))])
|
|
213
|
+
|
|
214
|
+
df = pd.DataFrame(results, columns=['signal', 'status', 'beg_frame', 'end_frame'])
|
|
215
|
+
return df
|
|
216
|
+
|
|
217
|
+
def crop_zone(self, frame:np.ndarray)->list[np.ndarray]:
|
|
218
|
+
'''
|
|
219
|
+
Parameters:
|
|
220
|
+
- frame: frame of the video
|
|
221
|
+
|
|
222
|
+
Return:
|
|
223
|
+
- list of cropped zones
|
|
224
|
+
'''
|
|
225
|
+
crop_regions = []
|
|
226
|
+
for i, region in enumerate(self.det_zones):
|
|
227
|
+
x, y, w, h = region
|
|
228
|
+
cropped = frame[y:y + h, x:x + w]
|
|
229
|
+
cropped = Image.fromarray(cropped)
|
|
230
|
+
crop_regions.append(cropped)
|
|
231
|
+
return crop_regions
|
|
232
|
+
|
|
233
|
+
def predict(self, batch:list):
|
|
234
|
+
"""
|
|
235
|
+
Parameters:
|
|
236
|
+
batch: the cropped batch of images
|
|
237
|
+
Returns:
|
|
238
|
+
pred_array: the corresponding traffic signal predictions with format (zone0_pred, zone1_pred, ...)
|
|
239
|
+
"""
|
|
240
|
+
self.model.eval()
|
|
241
|
+
sf = nn.Softmax(dim=1)
|
|
242
|
+
batchsz = len(batch)
|
|
243
|
+
num_group = len(batch[0])
|
|
244
|
+
|
|
245
|
+
# define the image transform
|
|
246
|
+
transform = transforms.Compose([
|
|
247
|
+
transforms.Resize((64, 64)),
|
|
248
|
+
transforms.ToTensor(),
|
|
249
|
+
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
|
|
250
|
+
])
|
|
251
|
+
|
|
252
|
+
# Transform all images and stack to different groups(corresponding light)
|
|
253
|
+
transformed_crops = [[transform(image) for image in crop] for crop in batch]
|
|
254
|
+
transformed_batch = [torch.stack([transformed_crops[j][i] for j in range(batchsz)]) for i in range(num_group)]
|
|
255
|
+
|
|
256
|
+
# send to model and make predictions zone by zone
|
|
257
|
+
batch_pred = []
|
|
258
|
+
for group in transformed_batch:
|
|
259
|
+
# compute the probability of the detections
|
|
260
|
+
outputs = self.model(group.to(self.device))
|
|
261
|
+
sf_output = sf(outputs)
|
|
262
|
+
|
|
263
|
+
# predict green only if the probability > threshold
|
|
264
|
+
y_pred = (sf_output[:, 1] > self.threshold).int()
|
|
265
|
+
batch_pred.append(y_pred.data.cpu().numpy())
|
|
266
|
+
|
|
267
|
+
pred_array = np.array(batch_pred).T
|
|
268
|
+
# prob_array = np.array(batch_prob).T
|
|
269
|
+
|
|
270
|
+
return pred_array
|
|
271
|
+
|
|
272
|
+
def generate_labels(self, signals:pd.DataFrame, input_video:str, label_file:str,
|
|
273
|
+
size_factor:float=1.5, thick:int=1, video_index:int=None, video_tot:int=None)->pd.DataFrame:
|
|
274
|
+
|
|
275
|
+
# open input video
|
|
276
|
+
cap = cv2.VideoCapture(input_video)
|
|
277
|
+
if not cap.isOpened():
|
|
278
|
+
print('Failed to open the video!')
|
|
279
|
+
tot_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
280
|
+
cap.release()
|
|
281
|
+
|
|
282
|
+
pbar = tqdm(total= tot_frames)
|
|
283
|
+
if video_index and video_tot:
|
|
284
|
+
pbar.set_description_str("Generating signal labeles for {} of {}".format(video_index, video_tot))
|
|
285
|
+
else:
|
|
286
|
+
pbar.set_description_str("Generating signal labels")
|
|
287
|
+
|
|
288
|
+
results = []
|
|
289
|
+
for i in range(tot_frames):
|
|
290
|
+
for j in range(len(self.det_zones)):
|
|
291
|
+
status = 0 # no walking
|
|
292
|
+
selected = signals[(signals['beg_frame']<=i) & (signals['end_frame']>=i) & (signals['signal']==j)]
|
|
293
|
+
if len(selected) > 0:
|
|
294
|
+
status = selected['status'].iloc[0]
|
|
295
|
+
|
|
296
|
+
x, y, w, h = self.det_zones[j]
|
|
297
|
+
cx = int(x + w/2)
|
|
298
|
+
cy = int(y + h/2)
|
|
299
|
+
r = int(max(w, h) * size_factor)
|
|
300
|
+
|
|
301
|
+
if status == 0:
|
|
302
|
+
results.append([i, 'circle', [(cx, cy)], (0, 0, 255), r, thick, ''])
|
|
303
|
+
elif status == 1:
|
|
304
|
+
results.append([i, 'circle', [(cx, cy)], (0, 255, 0), r, thick, ''])
|
|
305
|
+
elif status == 2:
|
|
306
|
+
results.append([i, 'circle', [(cx, cy)], (0, 255, 255), r, thick, ''])
|
|
307
|
+
|
|
308
|
+
pbar.update()
|
|
309
|
+
|
|
310
|
+
df = pd.DataFrame(results, columns=['frame','type','coords','color','size','thick','desc'])
|
|
311
|
+
df.sort_values(by='frame')
|
|
312
|
+
|
|
313
|
+
if label_file:
|
|
314
|
+
df.to_csv(label_file, index=False)
|
|
315
|
+
|
|
316
|
+
return df
|
|
317
|
+
|
dnt/detect/yolov8/detector.py
CHANGED
|
@@ -1,27 +1,68 @@
|
|
|
1
|
-
from ultralytics import YOLO
|
|
1
|
+
from ultralytics import YOLO, RTDETR
|
|
2
2
|
import cv2
|
|
3
3
|
import pandas as pd
|
|
4
4
|
from tqdm import tqdm
|
|
5
5
|
import random, os
|
|
6
6
|
from pathlib import Path
|
|
7
|
+
import torch
|
|
7
8
|
|
|
8
9
|
class Detector:
|
|
9
|
-
def __init__(self, yolo:str='x', conf:float=0.25, nms:float=0.7, max_det:int=300
|
|
10
|
+
def __init__(self, model:str='yolo', weights:str='x', conf:float=0.25, nms:float=0.7, max_det:int=300,
|
|
11
|
+
device:str='auto', half:bool=False):
|
|
10
12
|
'''
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
n - yolov8n.pt
|
|
13
|
+
model: 'yolo' (default), 'rtdetr'
|
|
14
|
+
weights: 'x' - extra-large (default), 'l' - large, 'm' - mdium, 's' - small, 'n' - nano, '.pt' - custom model weights
|
|
15
|
+
device: 'auto' (default), 'cuda', 'cpu', 'mps'
|
|
16
|
+
half: False (default), True
|
|
16
17
|
'''
|
|
17
18
|
# Load YOLOV8 model
|
|
18
19
|
cwd = Path(__file__).parent.absolute()
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
if model == 'yolo':
|
|
21
|
+
if weights in ['x', 'l', 'm', 's', 'n']:
|
|
22
|
+
model_path = os.path.join(cwd, 'models/yolov8'+weights+'.pt')
|
|
23
|
+
elif ".pt" in weights:
|
|
24
|
+
model_path = os.path.join(cwd, 'models/'+weights)
|
|
25
|
+
elif model == 'rtdetr':
|
|
26
|
+
if weights in ['x', 'l']:
|
|
27
|
+
model_path = os.path.join(cwd, 'models/rtdetr-'+weights+'.pt')
|
|
28
|
+
elif ".pt" in weights:
|
|
29
|
+
model_path = os.path.join(cwd, 'models/'+weights)
|
|
30
|
+
else:
|
|
31
|
+
model_path = os.path.join(cwd, 'models/rtdetr-x.pt')
|
|
32
|
+
#elif model == 'nas':
|
|
33
|
+
# if weights in ['l', 'm', 's']:
|
|
34
|
+
# model_path = os.path.join(cwd, 'models/yolo_nas_'+weights+'.pt')
|
|
35
|
+
# elif ".pt" in weights:
|
|
36
|
+
# model_path = os.path.join(cwd, 'models/'+weights)
|
|
37
|
+
# else:
|
|
38
|
+
# model_path = os.path.join(cwd, 'models/yolo_nas_l.pt')
|
|
39
|
+
else:
|
|
40
|
+
raise Exception('Invalid detection model type!')
|
|
41
|
+
|
|
42
|
+
if model == 'yolo':
|
|
43
|
+
self.model = YOLO(model_path)
|
|
44
|
+
elif model == 'rtdetr':
|
|
45
|
+
self.model = RTDETR(model_path)
|
|
46
|
+
#elif model == 'nas':
|
|
47
|
+
# self.model = NAS(model_path)
|
|
48
|
+
else:
|
|
49
|
+
raise Exception('Invalid model weights!')
|
|
50
|
+
|
|
21
51
|
self.conf = conf
|
|
22
52
|
self.nms = nms
|
|
23
53
|
self.max_det = max_det
|
|
24
54
|
|
|
55
|
+
if device == 'auto':
|
|
56
|
+
self.device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
|
|
57
|
+
elif device == 'cuda' and torch.cuda.is_available():
|
|
58
|
+
self.device = 'cuda'
|
|
59
|
+
elif device == 'mps' and torch.backends.mps.is_available():
|
|
60
|
+
self.device = 'mps'
|
|
61
|
+
else:
|
|
62
|
+
self.device = 'cpu'
|
|
63
|
+
|
|
64
|
+
self.half = half
|
|
65
|
+
|
|
25
66
|
def detect(self, input_video:str, iou_file:str=None,
|
|
26
67
|
video_index:int=None, video_tot:int=None,
|
|
27
68
|
start_time:int=None, end_time:int=None, verbose:bool=False) -> pd.DataFrame:
|
|
@@ -66,7 +107,8 @@ class Detector:
|
|
|
66
107
|
if (not ret) or (pos_frame>end_frame):
|
|
67
108
|
break
|
|
68
109
|
|
|
69
|
-
detects = self.model.predict(frame, verbose=False, conf=self.conf, iou=self.nms, max_det=self.max_det
|
|
110
|
+
detects = self.model.predict(frame, verbose=False, conf=self.conf, iou=self.nms, max_det=self.max_det,
|
|
111
|
+
device=self.device, half=self.half)
|
|
70
112
|
if len(detects)>0:
|
|
71
113
|
detect = detects[0]
|
|
72
114
|
|
|
@@ -82,9 +124,10 @@ class Detector:
|
|
|
82
124
|
|
|
83
125
|
pbar.close()
|
|
84
126
|
cap.release()
|
|
85
|
-
cv2.destroyAllWindows()
|
|
127
|
+
#cv2.destroyAllWindows()
|
|
86
128
|
|
|
87
|
-
df = pd.concat(results)
|
|
129
|
+
df = pd.concat(d for d in results if not d.empty) # remove empty dataframes
|
|
130
|
+
#df = pd.concat(results)
|
|
88
131
|
df['x'] = round(df['x'], 1)
|
|
89
132
|
df['y'] = round(df['y'], 1)
|
|
90
133
|
df['w'] = round(df['x2']-df['x'], 0)
|
|
@@ -99,9 +142,57 @@ class Detector:
|
|
|
99
142
|
|
|
100
143
|
return df
|
|
101
144
|
|
|
145
|
+
def detect_frames(self, input_video:str, frames:list[int], verbose:bool=False)->pd.DataFrame:
|
|
146
|
+
# open input video
|
|
147
|
+
cap = cv2.VideoCapture(input_video)
|
|
148
|
+
if not cap.isOpened():
|
|
149
|
+
print('Failed to open the video!')
|
|
150
|
+
|
|
151
|
+
random.seed(3) # deterministic bbox colors
|
|
152
|
+
results = []
|
|
153
|
+
|
|
154
|
+
if verbose:
|
|
155
|
+
pbar = tqdm(total=len(frames), unit=" frames")
|
|
156
|
+
for pos_frame in frames:
|
|
157
|
+
cap.set(cv2.CAP_PROP_POS_FRAMES, pos_frame)
|
|
158
|
+
ret, frame = cap.read()
|
|
159
|
+
if not ret:
|
|
160
|
+
break
|
|
161
|
+
|
|
162
|
+
detects = self.model.predict(frame, verbose=False, conf=self.conf, iou=self.nms, max_det=self.max_det,
|
|
163
|
+
device=self.device, half=self.half)
|
|
164
|
+
if len(detects)>0:
|
|
165
|
+
detect = detects[0]
|
|
166
|
+
|
|
167
|
+
xyxy = pd.DataFrame(detect.boxes.xyxy.tolist(), columns=['x', 'y', 'x2', 'y2'])
|
|
168
|
+
cls = pd.DataFrame(detect.boxes.cls.tolist(), columns=['class'])
|
|
169
|
+
conf = pd.DataFrame(detect.boxes.conf.tolist(), columns = ['conf'])
|
|
170
|
+
result = pd.concat([xyxy, conf, cls], axis=1)
|
|
171
|
+
result.insert(0, 'frame', pos_frame)
|
|
172
|
+
result.insert(1, 'res', -1)
|
|
173
|
+
results.append(result)
|
|
174
|
+
|
|
175
|
+
if verbose:
|
|
176
|
+
pbar.update()
|
|
177
|
+
|
|
178
|
+
if verbose:
|
|
179
|
+
pbar.close()
|
|
180
|
+
cap.release()
|
|
181
|
+
|
|
182
|
+
df = pd.concat(results)
|
|
183
|
+
df['x'] = round(df['x'], 1)
|
|
184
|
+
df['y'] = round(df['y'], 1)
|
|
185
|
+
df['w'] = round(df['x2']-df['x'], 0)
|
|
186
|
+
df['h'] = round(df['y2']-df['y'], 0)
|
|
187
|
+
df['class'] = round(df['class'], 0)
|
|
188
|
+
df['conf'] = round(df['conf'], 2)
|
|
189
|
+
df = df[['frame', 'res', 'x', 'y', 'w', 'h', 'conf', 'class']].reset_index(drop=True)
|
|
190
|
+
|
|
191
|
+
return df
|
|
192
|
+
|
|
102
193
|
def detect_v8(self, input_video:str, iou_file:str=None, save:bool=False, verbose:bool=False, show:bool=False):
|
|
103
194
|
detects = self.model.predict(input_video,
|
|
104
|
-
verbose=verbose, stream=True, save=save, show=show)
|
|
195
|
+
verbose=verbose, stream=True, save=save, show=show, device=self.device, half=self.half)
|
|
105
196
|
|
|
106
197
|
if iou_file:
|
|
107
198
|
results = []
|
|
@@ -163,14 +254,23 @@ class Detector:
|
|
|
163
254
|
return results
|
|
164
255
|
|
|
165
256
|
@staticmethod
|
|
166
|
-
def get_fps(
|
|
167
|
-
cap = cv2.VideoCapture(
|
|
257
|
+
def get_fps(video:str)->float:
|
|
258
|
+
cap = cv2.VideoCapture(video)
|
|
168
259
|
if not cap.isOpened():
|
|
169
260
|
print('Failed to open the video!')
|
|
170
261
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
171
262
|
return fps
|
|
263
|
+
|
|
264
|
+
@staticmethod
|
|
265
|
+
def get_frames(video:str)->int:
|
|
266
|
+
cap = cv2.VideoCapture(video)
|
|
267
|
+
if not cap.isOpened():
|
|
268
|
+
print('Failed to open the video!')
|
|
269
|
+
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
|
270
|
+
return frames
|
|
172
271
|
|
|
173
272
|
if __name__=='__main__':
|
|
174
273
|
|
|
175
274
|
detector = Detector()
|
|
176
|
-
detector.
|
|
275
|
+
result = detector.detect_frames('/mnt/d/videos/samples/traffic_short.mp4', [0, 1])
|
|
276
|
+
print(result)
|
dnt/engine/__init__.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# bbox_interpolation.pyx
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy.interpolate import CubicSpline, interp1d
|
|
5
|
+
|
|
6
|
+
# Define the function signature
|
|
7
|
+
def interpolate_bbox(boxes:np.ndarray, frames:np.ndarray, target_frame:int, method='cubic')->np.ndarray:
|
|
8
|
+
"""
|
|
9
|
+
Interpolates bounding boxes using cubic splines.
|
|
10
|
+
|
|
11
|
+
Parameters:
|
|
12
|
+
- boxes: a (n, 4) array of bounding box coordinates (x, y, width, height).
|
|
13
|
+
- frames: a (n,) array of frame indices corresponding to the bounding boxes.
|
|
14
|
+
- target_frame: the frame index at which to interpolate the bounding box.
|
|
15
|
+
- method: the spline function, default is 'cubic', 'nearest', 'linear'
|
|
16
|
+
Returns:
|
|
17
|
+
- A 1d array (x, y, width, height) representing the interpolated bounding box.
|
|
18
|
+
"""
|
|
19
|
+
n = boxes.shape[0]
|
|
20
|
+
|
|
21
|
+
if n != frames.shape[0]:
|
|
22
|
+
raise ValueError("Length of boxes and frames must be equal.")
|
|
23
|
+
|
|
24
|
+
if n == 0:
|
|
25
|
+
raise ValueError("Input arrays must not be empty.")
|
|
26
|
+
|
|
27
|
+
if target_frame < frames[0] or target_frame > frames[-1]:
|
|
28
|
+
raise ValueError("Target frame is out of bounds.")
|
|
29
|
+
|
|
30
|
+
# Unpack the boxes into separate arrays for x, y, width, and height
|
|
31
|
+
x = boxes[:, 0]
|
|
32
|
+
y = boxes[:, 1]
|
|
33
|
+
w = boxes[:, 2]
|
|
34
|
+
h = boxes[:, 3]
|
|
35
|
+
|
|
36
|
+
# Create the cubic splines for each parameter
|
|
37
|
+
if method == 'cubic':
|
|
38
|
+
spline_x = CubicSpline(frames, x)
|
|
39
|
+
spline_y = CubicSpline(frames, y)
|
|
40
|
+
spline_w = CubicSpline(frames, w)
|
|
41
|
+
spline_h = CubicSpline(frames, h)
|
|
42
|
+
elif method == 'nearest':
|
|
43
|
+
spline_x = interp1d(frames, x, kind='nearest')
|
|
44
|
+
spline_y = interp1d(frames, y, kind='nearest')
|
|
45
|
+
spline_w = interp1d(frames, w, kind='nearest')
|
|
46
|
+
spline_h = interp1d(frames, h, kind='nearest')
|
|
47
|
+
else:
|
|
48
|
+
spline_x = interp1d(frames, x, kind='linear')
|
|
49
|
+
spline_y = interp1d(frames, y, kind='linear')
|
|
50
|
+
spline_w = interp1d(frames, w, kind='linear')
|
|
51
|
+
spline_h = interp1d(frames, h, kind='linear')
|
|
52
|
+
|
|
53
|
+
# Evaluate the splines at the target frame
|
|
54
|
+
x_t = int(spline_x(target_frame))
|
|
55
|
+
y_t = int(spline_y(target_frame))
|
|
56
|
+
w_t = int(spline_w(target_frame))
|
|
57
|
+
h_t = int(spline_h(target_frame))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
return np.array([x_t, y_t, w_t, h_t])
|
|
61
|
+
|
|
62
|
+
def interpolate_bboxes(boxes:np.ndarray, frames:np.ndarray, target_frames:np.ndarray, method='cubic')->np.ndarray:
|
|
63
|
+
"""
|
|
64
|
+
Interpolates bounding boxes using cubic splines.
|
|
65
|
+
|
|
66
|
+
Parameters:
|
|
67
|
+
- boxes: a (n, 4) array of bounding box coordinates (x, y, width, height).
|
|
68
|
+
- frames: a (n,) array of frame indices corresponding to the bounding boxes.
|
|
69
|
+
- target_frames: the frame indexes at which to interpolate the bounding boxes.
|
|
70
|
+
- method: the spline function, default is 'cubic', 'nearest', 'linear'
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
- List of tuple (x, y, width, height) representing the interpolated bounding boxes.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
n_frames = target_frames.shape[0]
|
|
77
|
+
results = []
|
|
78
|
+
|
|
79
|
+
for i in range(n_frames):
|
|
80
|
+
target_frame = target_frames[i]
|
|
81
|
+
results.append(interpolate_bbox(boxes, frames, target_frame, method))
|
|
82
|
+
|
|
83
|
+
return np.vstack(results)
|
dnt/engine/bbox_iou.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from cython_bbox import bbox_overlaps
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
def ious(atlbrs, btlbrs):
|
|
5
|
+
"""
|
|
6
|
+
Compute cost based on IoU
|
|
7
|
+
:type atlbrs: list[tlbr] | np.ndarray
|
|
8
|
+
:type atlbrs: list[tlbr] | np.ndarray
|
|
9
|
+
|
|
10
|
+
:rtype ious np.ndarray
|
|
11
|
+
"""
|
|
12
|
+
ious = np.zeros((len(atlbrs), len(btlbrs)), dtype=np.float64)
|
|
13
|
+
if ious.size == 0:
|
|
14
|
+
return ious
|
|
15
|
+
|
|
16
|
+
ious = bbox_overlaps(
|
|
17
|
+
np.ascontiguousarray(atlbrs, dtype=np.float64),
|
|
18
|
+
np.ascontiguousarray(btlbrs, dtype=np.float64))
|
|
19
|
+
|
|
20
|
+
return ious
|
dnt/engine/cluster.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
def cluster_by_gap(arr:np.ndarray, gap:int)->list:
|
|
4
|
+
'''
|
|
5
|
+
Parameters:
|
|
6
|
+
- arr: a 1d array for clustering
|
|
7
|
+
- gap: the threshold to break (> gap)
|
|
8
|
+
|
|
9
|
+
Returns:
|
|
10
|
+
- list of clustered numbers (lists)
|
|
11
|
+
'''
|
|
12
|
+
# Sort the array to process it in order
|
|
13
|
+
arr.sort()
|
|
14
|
+
clusters = []
|
|
15
|
+
current_cluster = [arr[0]]
|
|
16
|
+
|
|
17
|
+
# Iterate through the sorted list
|
|
18
|
+
for i in range(1, len(arr)):
|
|
19
|
+
if arr[i] - arr[i-1] <= gap:
|
|
20
|
+
# If the gap condition is met, add to the current cluster
|
|
21
|
+
current_cluster.append(arr[i])
|
|
22
|
+
else:
|
|
23
|
+
# If the gap condition is not met, start a new cluster
|
|
24
|
+
clusters.append(current_cluster)
|
|
25
|
+
current_cluster = [arr[i]]
|
|
26
|
+
|
|
27
|
+
# Add the last cluster
|
|
28
|
+
clusters.append(current_cluster)
|
|
29
|
+
|
|
30
|
+
return clusters
|
|
31
|
+
|