├── .gitignore ├── LICENSE.md ├── README.md ├── README_CN.md ├── cfg ├── baseline │ ├── r50-csp.yaml │ ├── x50-csp.yaml │ ├── yolor-csp-x.yaml │ ├── yolor-csp.yaml │ ├── yolor-d6.yaml │ ├── yolor-e6.yaml │ ├── yolor-p6.yaml │ ├── yolor-w6.yaml │ ├── yolov3-spp.yaml │ ├── yolov3.yaml │ └── yolov4-csp.yaml ├── deploy │ ├── yolov7-d6.yaml │ ├── yolov7-e6.yaml │ ├── yolov7-e6e.yaml │ ├── yolov7-tiny-silu.yaml │ ├── yolov7-tiny.yaml │ ├── yolov7-w6.yaml │ ├── yolov7.yaml │ └── yolov7x.yaml └── training │ ├── yolov7-d6.yaml │ ├── yolov7-e6.yaml │ ├── yolov7-e6e.yaml │ ├── yolov7-tiny.yaml │ ├── yolov7-w6.yaml │ ├── yolov7.yaml │ └── yolov7x.yaml ├── data ├── coco.yaml ├── hyp.scratch.custom.yaml ├── hyp.scratch.p5.yaml ├── hyp.scratch.p6.yaml ├── hyp.scratch.tiny.yaml ├── mot17.yaml ├── uavdt.yaml ├── visdrone_all.yaml └── visdrone_half_car.yaml ├── detect.py ├── figure ├── demo.gif ├── horses_prediction.jpg ├── mask.png ├── performance.png └── pose.png ├── hubconf.py ├── inference └── images │ └── horses.jpg ├── models ├── __init__.py ├── common.py ├── experimental.py ├── export.py └── yolo.py ├── requirements.txt ├── scripts └── get_coco.sh ├── test.py ├── tools ├── convert_MOT17_to_yolo.py ├── convert_UAVDT_to_yolo.py ├── convert_VisDrone_to_yolo.py ├── convert_VisDrone_to_yolov2.py └── reparameterization.ipynb ├── tracker ├── cam_param_files │ └── uavdt │ │ ├── M0101.txt │ │ ├── M0202.txt │ │ ├── M0203.txt │ │ ├── M0402.txt │ │ ├── M0601.txt │ │ ├── M0604.txt │ │ ├── M1002.txt │ │ ├── M1003.txt │ │ ├── M1008.txt │ │ └── M1202.txt ├── config_files │ ├── mot17.yaml │ ├── uavdt.yaml │ ├── visdrone.yaml │ └── visdrone_part.yaml ├── my_timer.py ├── track.py ├── track_demo.py ├── tracker_dataloader.py ├── trackers │ ├── basetrack.py │ ├── botsort_tracker.py │ ├── byte_tracker.py │ ├── c_biou_tracker.py │ ├── camera_motion_compensation │ │ └── cmc.py │ ├── deepsort_tracker.py │ ├── hybridsort_tracker.py │ ├── kalman_filters │ │ ├── base_kalman.py │ │ ├── botsort_kalman.py │ │ ├── bytetrack_kalman.py │ │ ├── hybridsort_kalman.py │ │ ├── ocsort_kalman.py │ │ ├── sort_kalman.py │ │ ├── strongsort_kalman.py │ │ └── ucmctrack_kalman.py │ ├── matching.py │ ├── ocsort_tracker.py │ ├── reid_models │ │ ├── AFLink.py │ │ ├── DeepsortReID.py │ │ ├── MobileNetv2.py │ │ ├── OSNet.py │ │ ├── ShuffleNetv2.py │ │ ├── VehicleNet.py │ │ ├── __init__.py │ │ └── engine.py │ ├── sort_tracker.py │ ├── sparse_tracker.py │ ├── strongsort_tracker.py │ ├── tracklet.py │ └── ucmc_tracker.py ├── trackeval │ ├── __init__.py │ ├── _timing.py │ ├── baselines │ │ ├── __init__.py │ │ ├── baseline_utils.py │ │ ├── non_overlap.py │ │ ├── pascal_colormap.py │ │ ├── stp.py │ │ ├── thresholder.py │ │ └── vizualize.py │ ├── datasets │ │ ├── __init__.py │ │ ├── _base_dataset.py │ │ ├── bdd100k.py │ │ ├── burst.py │ │ ├── burst_helpers │ │ │ ├── BURST_SPECIFIC_ISSUES.md │ │ │ ├── __init__.py │ │ │ ├── burst_base.py │ │ │ ├── burst_ow_base.py │ │ │ ├── convert_burst_format_to_tao_format.py │ │ │ ├── format_converter.py │ │ │ └── tao_categories.json │ │ ├── burst_ow.py │ │ ├── davis.py │ │ ├── head_tracking_challenge.py │ │ ├── kitti_2d_box.py │ │ ├── kitti_mots.py │ │ ├── mot_challenge_2d_box.py │ │ ├── mots_challenge.py │ │ ├── person_path_22.py │ │ ├── rob_mots.py │ │ ├── rob_mots_classmap.py │ │ ├── run_rob_mots.py │ │ ├── tao.py │ │ ├── tao_ow.py │ │ ├── visdrone.py │ │ └── youtube_vis.py │ ├── eval.py │ ├── metrics │ │ ├── __init__.py │ │ ├── _base_metric.py │ │ ├── clear.py │ │ ├── count.py │ │ ├── hota.py │ │ ├── identity.py │ │ ├── ideucl.py │ │ ├── j_and_f.py │ │ ├── track_map.py │ │ └── vace.py │ ├── plotting.py │ └── utils.py ├── tracking_utils │ ├── envs.py │ ├── tools.py │ └── visualization.py ├── yolo_ultralytics_utils │ ├── data_cfgs │ │ ├── airmot.yaml │ │ ├── uavdt.yaml │ │ ├── visdrone.yaml │ │ └── visdrone_det.yaml │ ├── postprocess.py │ └── train_yolo_ultralytics.py ├── yolov7_utils │ └── postprocess.py └── yolox_utils │ ├── mot_dataset.py │ ├── postprocess.py │ ├── train_yolox.py │ ├── yolox_m.py │ └── yolox_x.py ├── train.py ├── train_aux.py ├── utils ├── __init__.py ├── activations.py ├── autoanchor.py ├── aws │ ├── __init__.py │ ├── mime.sh │ ├── resume.py │ └── userdata.sh ├── datasets.py ├── general.py ├── google_app_engine │ ├── Dockerfile │ └── app.yaml ├── google_utils.py ├── loss.py ├── metrics.py ├── plots.py ├── torch_utils.py └── wandb_logging │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-37.pyc │ └── wandb_utils.cpython-37.pyc │ ├── log_dataset.py │ └── wandb_utils.py └── weights ├── DHN.pth ├── ckpt.t7 └── osnet_x0_25.pth /.gitignore: -------------------------------------------------------------------------------- 1 | # Customized 2 | weights/* 3 | !weights/ckpt.t7 4 | !weights/DHN.pth 5 | !weights/osnet_x0_25.pth 6 | visdrone/* 7 | uavdt/* 8 | mot17/* 9 | runs/* 10 | wandb/* 11 | track_result.txt 12 | .idea/ 13 | track_results/* 14 | *.mp4 15 | *.mkv 16 | temp.py 17 | demo_result/ 18 | 19 | # Byte-compiled / optimized / DLL files 20 | __pycache__/ 21 | *.py[cod] 22 | *$py.class 23 | .vscode 24 | 25 | # C extensions 26 | *.so 27 | 28 | # Distribution / packaging 29 | .Python 30 | build/ 31 | develop-eggs/ 32 | dist/ 33 | downloads/ 34 | eggs/ 35 | .eggs/ 36 | lib/ 37 | lib64/ 38 | parts/ 39 | sdist/ 40 | var/ 41 | wheels/ 42 | share/python-wheels/ 43 | *.egg-info/ 44 | .installed.cfg 45 | *.egg 46 | MANIFEST 47 | 48 | # PyInstaller 49 | # Usually these files are written by a python script from a template 50 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 51 | *.manifest 52 | *.spec 53 | 54 | # Installer logs 55 | pip-log.txt 56 | pip-delete-this-directory.txt 57 | 58 | # Unit test / coverage reports 59 | htmlcov/ 60 | .tox/ 61 | .nox/ 62 | .coverage 63 | .coverage.* 64 | .cache 65 | nosetests.xml 66 | coverage.xml 67 | *.cover 68 | *.py,cover 69 | .hypothesis/ 70 | .pytest_cache/ 71 | cover/ 72 | 73 | # Translations 74 | *.mo 75 | *.pot 76 | 77 | # Django stuff: 78 | *.log 79 | local_settings.py 80 | db.sqlite3 81 | db.sqlite3-journal 82 | 83 | # Flask stuff: 84 | instance/ 85 | .webassets-cache 86 | 87 | # Scrapy stuff: 88 | .scrapy 89 | 90 | # Sphinx documentation 91 | docs/_build/ 92 | 93 | # PyBuilder 94 | .pybuilder/ 95 | target/ 96 | 97 | # Jupyter Notebook 98 | .ipynb_checkpoints 99 | 100 | # IPython 101 | profile_default/ 102 | ipython_config.py 103 | 104 | # pyenv 105 | # For a library or package, you might want to ignore these files since the code is 106 | # intended to run in multiple environments; otherwise, check them in: 107 | # .python-version 108 | 109 | # pipenv 110 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 111 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 112 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 113 | # install all needed dependencies. 114 | #Pipfile.lock 115 | 116 | # poetry 117 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 118 | # This is especially recommended for binary packages to ensure reproducibility, and is more 119 | # commonly ignored for libraries. 120 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 121 | #poetry.lock 122 | 123 | # pdm 124 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 125 | #pdm.lock 126 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 127 | # in version control. 128 | # https://pdm.fming.dev/#use-with-ide 129 | .pdm.toml 130 | 131 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 132 | __pypackages__/ 133 | 134 | # Celery stuff 135 | celerybeat-schedule 136 | celerybeat.pid 137 | 138 | # SageMath parsed files 139 | *.sage.py 140 | 141 | # Environments 142 | .env 143 | .venv 144 | env/ 145 | venv/ 146 | ENV/ 147 | env.bak/ 148 | venv.bak/ 149 | 150 | # Spyder project settings 151 | .spyderproject 152 | .spyproject 153 | 154 | # Rope project settings 155 | .ropeproject 156 | 157 | # mkdocs documentation 158 | /site 159 | 160 | # mypy 161 | .mypy_cache/ 162 | .dmypy.json 163 | dmypy.json 164 | 165 | # Pyre type checker 166 | .pyre/ 167 | 168 | # pytype static type analyzer 169 | .pytype/ 170 | 171 | # Cython debug symbols 172 | cython_debug/ 173 | 174 | # PyCharm 175 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 176 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 177 | # and can be added to the global gitignore or merged into this file. For a more nuclear 178 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 179 | #.idea/ -------------------------------------------------------------------------------- /cfg/baseline/r50-csp.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # CSP-ResNet backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Stem, [128]], # 0-P1/2 16 | [-1, 3, ResCSPC, [128]], 17 | [-1, 1, Conv, [256, 3, 2]], # 2-P3/8 18 | [-1, 4, ResCSPC, [256]], 19 | [-1, 1, Conv, [512, 3, 2]], # 4-P3/8 20 | [-1, 6, ResCSPC, [512]], 21 | [-1, 1, Conv, [1024, 3, 2]], # 6-P3/8 22 | [-1, 3, ResCSPC, [1024]], # 7 23 | ] 24 | 25 | # CSP-Res-PAN head 26 | head: 27 | [[-1, 1, SPPCSPC, [512]], # 8 28 | [-1, 1, Conv, [256, 1, 1]], 29 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 30 | [5, 1, Conv, [256, 1, 1]], # route backbone P4 31 | [[-1, -2], 1, Concat, [1]], 32 | [-1, 2, ResCSPB, [256]], # 13 33 | [-1, 1, Conv, [128, 1, 1]], 34 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 35 | [3, 1, Conv, [128, 1, 1]], # route backbone P3 36 | [[-1, -2], 1, Concat, [1]], 37 | [-1, 2, ResCSPB, [128]], # 18 38 | [-1, 1, Conv, [256, 3, 1]], 39 | [-2, 1, Conv, [256, 3, 2]], 40 | [[-1, 13], 1, Concat, [1]], # cat 41 | [-1, 2, ResCSPB, [256]], # 22 42 | [-1, 1, Conv, [512, 3, 1]], 43 | [-2, 1, Conv, [512, 3, 2]], 44 | [[-1, 8], 1, Concat, [1]], # cat 45 | [-1, 2, ResCSPB, [512]], # 26 46 | [-1, 1, Conv, [1024, 3, 1]], 47 | 48 | [[19,23,27], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5) 49 | ] 50 | -------------------------------------------------------------------------------- /cfg/baseline/x50-csp.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # CSP-ResNeXt backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Stem, [128]], # 0-P1/2 16 | [-1, 3, ResXCSPC, [128]], 17 | [-1, 1, Conv, [256, 3, 2]], # 2-P3/8 18 | [-1, 4, ResXCSPC, [256]], 19 | [-1, 1, Conv, [512, 3, 2]], # 4-P3/8 20 | [-1, 6, ResXCSPC, [512]], 21 | [-1, 1, Conv, [1024, 3, 2]], # 6-P3/8 22 | [-1, 3, ResXCSPC, [1024]], # 7 23 | ] 24 | 25 | # CSP-ResX-PAN head 26 | head: 27 | [[-1, 1, SPPCSPC, [512]], # 8 28 | [-1, 1, Conv, [256, 1, 1]], 29 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 30 | [5, 1, Conv, [256, 1, 1]], # route backbone P4 31 | [[-1, -2], 1, Concat, [1]], 32 | [-1, 2, ResXCSPB, [256]], # 13 33 | [-1, 1, Conv, [128, 1, 1]], 34 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 35 | [3, 1, Conv, [128, 1, 1]], # route backbone P3 36 | [[-1, -2], 1, Concat, [1]], 37 | [-1, 2, ResXCSPB, [128]], # 18 38 | [-1, 1, Conv, [256, 3, 1]], 39 | [-2, 1, Conv, [256, 3, 2]], 40 | [[-1, 13], 1, Concat, [1]], # cat 41 | [-1, 2, ResXCSPB, [256]], # 22 42 | [-1, 1, Conv, [512, 3, 1]], 43 | [-2, 1, Conv, [512, 3, 2]], 44 | [[-1, 8], 1, Concat, [1]], # cat 45 | [-1, 2, ResXCSPB, [512]], # 26 46 | [-1, 1, Conv, [1024, 3, 1]], 47 | 48 | [[19,23,27], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5) 49 | ] 50 | -------------------------------------------------------------------------------- /cfg/baseline/yolor-csp-x.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.33 # model depth multiple 4 | width_multiple: 1.25 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # CSP-Darknet backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 17 | [-1, 1, Bottleneck, [64]], 18 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 19 | [-1, 2, BottleneckCSPC, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 21 | [-1, 8, BottleneckCSPC, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 23 | [-1, 8, BottleneckCSPC, [512]], 24 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 25 | [-1, 4, BottleneckCSPC, [1024]], # 10 26 | ] 27 | 28 | # CSP-Dark-PAN head 29 | head: 30 | [[-1, 1, SPPCSPC, [512]], # 11 31 | [-1, 1, Conv, [256, 1, 1]], 32 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 33 | [8, 1, Conv, [256, 1, 1]], # route backbone P4 34 | [[-1, -2], 1, Concat, [1]], 35 | [-1, 2, BottleneckCSPB, [256]], # 16 36 | [-1, 1, Conv, [128, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [6, 1, Conv, [128, 1, 1]], # route backbone P3 39 | [[-1, -2], 1, Concat, [1]], 40 | [-1, 2, BottleneckCSPB, [128]], # 21 41 | [-1, 1, Conv, [256, 3, 1]], 42 | [-2, 1, Conv, [256, 3, 2]], 43 | [[-1, 16], 1, Concat, [1]], # cat 44 | [-1, 2, BottleneckCSPB, [256]], # 25 45 | [-1, 1, Conv, [512, 3, 1]], 46 | [-2, 1, Conv, [512, 3, 2]], 47 | [[-1, 11], 1, Concat, [1]], # cat 48 | [-1, 2, BottleneckCSPB, [512]], # 29 49 | [-1, 1, Conv, [1024, 3, 1]], 50 | 51 | [[22,26,30], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5) 52 | ] 53 | -------------------------------------------------------------------------------- /cfg/baseline/yolor-csp.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # CSP-Darknet backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 17 | [-1, 1, Bottleneck, [64]], 18 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 19 | [-1, 2, BottleneckCSPC, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 21 | [-1, 8, BottleneckCSPC, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 23 | [-1, 8, BottleneckCSPC, [512]], 24 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 25 | [-1, 4, BottleneckCSPC, [1024]], # 10 26 | ] 27 | 28 | # CSP-Dark-PAN head 29 | head: 30 | [[-1, 1, SPPCSPC, [512]], # 11 31 | [-1, 1, Conv, [256, 1, 1]], 32 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 33 | [8, 1, Conv, [256, 1, 1]], # route backbone P4 34 | [[-1, -2], 1, Concat, [1]], 35 | [-1, 2, BottleneckCSPB, [256]], # 16 36 | [-1, 1, Conv, [128, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [6, 1, Conv, [128, 1, 1]], # route backbone P3 39 | [[-1, -2], 1, Concat, [1]], 40 | [-1, 2, BottleneckCSPB, [128]], # 21 41 | [-1, 1, Conv, [256, 3, 1]], 42 | [-2, 1, Conv, [256, 3, 2]], 43 | [[-1, 16], 1, Concat, [1]], # cat 44 | [-1, 2, BottleneckCSPB, [256]], # 25 45 | [-1, 1, Conv, [512, 3, 1]], 46 | [-2, 1, Conv, [512, 3, 2]], 47 | [[-1, 11], 1, Concat, [1]], # cat 48 | [-1, 2, BottleneckCSPB, [512]], # 29 49 | [-1, 1, Conv, [1024, 3, 1]], 50 | 51 | [[22,26,30], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5) 52 | ] 53 | -------------------------------------------------------------------------------- /cfg/baseline/yolor-d6.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # expand model depth 4 | width_multiple: 1.25 # expand layer channels 5 | 6 | # anchors 7 | anchors: 8 | - [ 19,27, 44,40, 38,94 ] # P3/8 9 | - [ 96,68, 86,152, 180,137 ] # P4/16 10 | - [ 140,301, 303,264, 238,542 ] # P5/32 11 | - [ 436,615, 739,380, 925,792 ] # P6/64 12 | 13 | # CSP-Darknet backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, ReOrg, []], # 0 17 | [-1, 1, Conv, [64, 3, 1]], # 1-P1/2 18 | [-1, 1, DownC, [128]], # 2-P2/4 19 | [-1, 3, BottleneckCSPA, [128]], 20 | [-1, 1, DownC, [256]], # 4-P3/8 21 | [-1, 15, BottleneckCSPA, [256]], 22 | [-1, 1, DownC, [512]], # 6-P4/16 23 | [-1, 15, BottleneckCSPA, [512]], 24 | [-1, 1, DownC, [768]], # 8-P5/32 25 | [-1, 7, BottleneckCSPA, [768]], 26 | [-1, 1, DownC, [1024]], # 10-P6/64 27 | [-1, 7, BottleneckCSPA, [1024]], # 11 28 | ] 29 | 30 | # CSP-Dark-PAN head 31 | head: 32 | [[-1, 1, SPPCSPC, [512]], # 12 33 | [-1, 1, Conv, [384, 1, 1]], 34 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 35 | [-6, 1, Conv, [384, 1, 1]], # route backbone P5 36 | [[-1, -2], 1, Concat, [1]], 37 | [-1, 3, BottleneckCSPB, [384]], # 17 38 | [-1, 1, Conv, [256, 1, 1]], 39 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 40 | [-13, 1, Conv, [256, 1, 1]], # route backbone P4 41 | [[-1, -2], 1, Concat, [1]], 42 | [-1, 3, BottleneckCSPB, [256]], # 22 43 | [-1, 1, Conv, [128, 1, 1]], 44 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 45 | [-20, 1, Conv, [128, 1, 1]], # route backbone P3 46 | [[-1, -2], 1, Concat, [1]], 47 | [-1, 3, BottleneckCSPB, [128]], # 27 48 | [-1, 1, Conv, [256, 3, 1]], 49 | [-2, 1, DownC, [256]], 50 | [[-1, 22], 1, Concat, [1]], # cat 51 | [-1, 3, BottleneckCSPB, [256]], # 31 52 | [-1, 1, Conv, [512, 3, 1]], 53 | [-2, 1, DownC, [384]], 54 | [[-1, 17], 1, Concat, [1]], # cat 55 | [-1, 3, BottleneckCSPB, [384]], # 35 56 | [-1, 1, Conv, [768, 3, 1]], 57 | [-2, 1, DownC, [512]], 58 | [[-1, 12], 1, Concat, [1]], # cat 59 | [-1, 3, BottleneckCSPB, [512]], # 39 60 | [-1, 1, Conv, [1024, 3, 1]], 61 | 62 | [[28,32,36,40], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5, P6) 63 | ] -------------------------------------------------------------------------------- /cfg/baseline/yolor-e6.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # expand model depth 4 | width_multiple: 1.25 # expand layer channels 5 | 6 | # anchors 7 | anchors: 8 | - [ 19,27, 44,40, 38,94 ] # P3/8 9 | - [ 96,68, 86,152, 180,137 ] # P4/16 10 | - [ 140,301, 303,264, 238,542 ] # P5/32 11 | - [ 436,615, 739,380, 925,792 ] # P6/64 12 | 13 | # CSP-Darknet backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, ReOrg, []], # 0 17 | [-1, 1, Conv, [64, 3, 1]], # 1-P1/2 18 | [-1, 1, DownC, [128]], # 2-P2/4 19 | [-1, 3, BottleneckCSPA, [128]], 20 | [-1, 1, DownC, [256]], # 4-P3/8 21 | [-1, 7, BottleneckCSPA, [256]], 22 | [-1, 1, DownC, [512]], # 6-P4/16 23 | [-1, 7, BottleneckCSPA, [512]], 24 | [-1, 1, DownC, [768]], # 8-P5/32 25 | [-1, 3, BottleneckCSPA, [768]], 26 | [-1, 1, DownC, [1024]], # 10-P6/64 27 | [-1, 3, BottleneckCSPA, [1024]], # 11 28 | ] 29 | 30 | # CSP-Dark-PAN head 31 | head: 32 | [[-1, 1, SPPCSPC, [512]], # 12 33 | [-1, 1, Conv, [384, 1, 1]], 34 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 35 | [-6, 1, Conv, [384, 1, 1]], # route backbone P5 36 | [[-1, -2], 1, Concat, [1]], 37 | [-1, 3, BottleneckCSPB, [384]], # 17 38 | [-1, 1, Conv, [256, 1, 1]], 39 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 40 | [-13, 1, Conv, [256, 1, 1]], # route backbone P4 41 | [[-1, -2], 1, Concat, [1]], 42 | [-1, 3, BottleneckCSPB, [256]], # 22 43 | [-1, 1, Conv, [128, 1, 1]], 44 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 45 | [-20, 1, Conv, [128, 1, 1]], # route backbone P3 46 | [[-1, -2], 1, Concat, [1]], 47 | [-1, 3, BottleneckCSPB, [128]], # 27 48 | [-1, 1, Conv, [256, 3, 1]], 49 | [-2, 1, DownC, [256]], 50 | [[-1, 22], 1, Concat, [1]], # cat 51 | [-1, 3, BottleneckCSPB, [256]], # 31 52 | [-1, 1, Conv, [512, 3, 1]], 53 | [-2, 1, DownC, [384]], 54 | [[-1, 17], 1, Concat, [1]], # cat 55 | [-1, 3, BottleneckCSPB, [384]], # 35 56 | [-1, 1, Conv, [768, 3, 1]], 57 | [-2, 1, DownC, [512]], 58 | [[-1, 12], 1, Concat, [1]], # cat 59 | [-1, 3, BottleneckCSPB, [512]], # 39 60 | [-1, 1, Conv, [1024, 3, 1]], 61 | 62 | [[28,32,36,40], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5, P6) 63 | ] -------------------------------------------------------------------------------- /cfg/baseline/yolor-p6.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # expand model depth 4 | width_multiple: 1.0 # expand layer channels 5 | 6 | # anchors 7 | anchors: 8 | - [ 19,27, 44,40, 38,94 ] # P3/8 9 | - [ 96,68, 86,152, 180,137 ] # P4/16 10 | - [ 140,301, 303,264, 238,542 ] # P5/32 11 | - [ 436,615, 739,380, 925,792 ] # P6/64 12 | 13 | # CSP-Darknet backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, ReOrg, []], # 0 17 | [-1, 1, Conv, [64, 3, 1]], # 1-P1/2 18 | [-1, 1, Conv, [128, 3, 2]], # 2-P2/4 19 | [-1, 3, BottleneckCSPA, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 4-P3/8 21 | [-1, 7, BottleneckCSPA, [256]], 22 | [-1, 1, Conv, [384, 3, 2]], # 6-P4/16 23 | [-1, 7, BottleneckCSPA, [384]], 24 | [-1, 1, Conv, [512, 3, 2]], # 8-P5/32 25 | [-1, 3, BottleneckCSPA, [512]], 26 | [-1, 1, Conv, [640, 3, 2]], # 10-P6/64 27 | [-1, 3, BottleneckCSPA, [640]], # 11 28 | ] 29 | 30 | # CSP-Dark-PAN head 31 | head: 32 | [[-1, 1, SPPCSPC, [320]], # 12 33 | [-1, 1, Conv, [256, 1, 1]], 34 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 35 | [-6, 1, Conv, [256, 1, 1]], # route backbone P5 36 | [[-1, -2], 1, Concat, [1]], 37 | [-1, 3, BottleneckCSPB, [256]], # 17 38 | [-1, 1, Conv, [192, 1, 1]], 39 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 40 | [-13, 1, Conv, [192, 1, 1]], # route backbone P4 41 | [[-1, -2], 1, Concat, [1]], 42 | [-1, 3, BottleneckCSPB, [192]], # 22 43 | [-1, 1, Conv, [128, 1, 1]], 44 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 45 | [-20, 1, Conv, [128, 1, 1]], # route backbone P3 46 | [[-1, -2], 1, Concat, [1]], 47 | [-1, 3, BottleneckCSPB, [128]], # 27 48 | [-1, 1, Conv, [256, 3, 1]], 49 | [-2, 1, Conv, [192, 3, 2]], 50 | [[-1, 22], 1, Concat, [1]], # cat 51 | [-1, 3, BottleneckCSPB, [192]], # 31 52 | [-1, 1, Conv, [384, 3, 1]], 53 | [-2, 1, Conv, [256, 3, 2]], 54 | [[-1, 17], 1, Concat, [1]], # cat 55 | [-1, 3, BottleneckCSPB, [256]], # 35 56 | [-1, 1, Conv, [512, 3, 1]], 57 | [-2, 1, Conv, [320, 3, 2]], 58 | [[-1, 12], 1, Concat, [1]], # cat 59 | [-1, 3, BottleneckCSPB, [320]], # 39 60 | [-1, 1, Conv, [640, 3, 1]], 61 | 62 | [[28,32,36,40], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5, P6) 63 | ] -------------------------------------------------------------------------------- /cfg/baseline/yolor-w6.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # expand model depth 4 | width_multiple: 1.0 # expand layer channels 5 | 6 | # anchors 7 | anchors: 8 | - [ 19,27, 44,40, 38,94 ] # P3/8 9 | - [ 96,68, 86,152, 180,137 ] # P4/16 10 | - [ 140,301, 303,264, 238,542 ] # P5/32 11 | - [ 436,615, 739,380, 925,792 ] # P6/64 12 | 13 | # CSP-Darknet backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, ReOrg, []], # 0 17 | [-1, 1, Conv, [64, 3, 1]], # 1-P1/2 18 | [-1, 1, Conv, [128, 3, 2]], # 2-P2/4 19 | [-1, 3, BottleneckCSPA, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 4-P3/8 21 | [-1, 7, BottleneckCSPA, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 6-P4/16 23 | [-1, 7, BottleneckCSPA, [512]], 24 | [-1, 1, Conv, [768, 3, 2]], # 8-P5/32 25 | [-1, 3, BottleneckCSPA, [768]], 26 | [-1, 1, Conv, [1024, 3, 2]], # 10-P6/64 27 | [-1, 3, BottleneckCSPA, [1024]], # 11 28 | ] 29 | 30 | # CSP-Dark-PAN head 31 | head: 32 | [[-1, 1, SPPCSPC, [512]], # 12 33 | [-1, 1, Conv, [384, 1, 1]], 34 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 35 | [-6, 1, Conv, [384, 1, 1]], # route backbone P5 36 | [[-1, -2], 1, Concat, [1]], 37 | [-1, 3, BottleneckCSPB, [384]], # 17 38 | [-1, 1, Conv, [256, 1, 1]], 39 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 40 | [-13, 1, Conv, [256, 1, 1]], # route backbone P4 41 | [[-1, -2], 1, Concat, [1]], 42 | [-1, 3, BottleneckCSPB, [256]], # 22 43 | [-1, 1, Conv, [128, 1, 1]], 44 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 45 | [-20, 1, Conv, [128, 1, 1]], # route backbone P3 46 | [[-1, -2], 1, Concat, [1]], 47 | [-1, 3, BottleneckCSPB, [128]], # 27 48 | [-1, 1, Conv, [256, 3, 1]], 49 | [-2, 1, Conv, [256, 3, 2]], 50 | [[-1, 22], 1, Concat, [1]], # cat 51 | [-1, 3, BottleneckCSPB, [256]], # 31 52 | [-1, 1, Conv, [512, 3, 1]], 53 | [-2, 1, Conv, [384, 3, 2]], 54 | [[-1, 17], 1, Concat, [1]], # cat 55 | [-1, 3, BottleneckCSPB, [384]], # 35 56 | [-1, 1, Conv, [768, 3, 1]], 57 | [-2, 1, Conv, [512, 3, 2]], 58 | [[-1, 12], 1, Concat, [1]], # cat 59 | [-1, 3, BottleneckCSPB, [512]], # 39 60 | [-1, 1, Conv, [1024, 3, 1]], 61 | 62 | [[28,32,36,40], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5, P6) 63 | ] -------------------------------------------------------------------------------- /cfg/baseline/yolov3-spp.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # darknet53 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 17 | [-1, 1, Bottleneck, [64]], 18 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 19 | [-1, 2, Bottleneck, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 21 | [-1, 8, Bottleneck, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 23 | [-1, 8, Bottleneck, [512]], 24 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 25 | [-1, 4, Bottleneck, [1024]], # 10 26 | ] 27 | 28 | # YOLOv3-SPP head 29 | head: 30 | [[-1, 1, Bottleneck, [1024, False]], 31 | [-1, 1, SPP, [512, [5, 9, 13]]], 32 | [-1, 1, Conv, [1024, 3, 1]], 33 | [-1, 1, Conv, [512, 1, 1]], 34 | [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) 35 | 36 | [-2, 1, Conv, [256, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [[-1, 8], 1, Concat, [1]], # cat backbone P4 39 | [-1, 1, Bottleneck, [512, False]], 40 | [-1, 1, Bottleneck, [512, False]], 41 | [-1, 1, Conv, [256, 1, 1]], 42 | [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) 43 | 44 | [-2, 1, Conv, [128, 1, 1]], 45 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 46 | [[-1, 6], 1, Concat, [1]], # cat backbone P3 47 | [-1, 1, Bottleneck, [256, False]], 48 | [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) 49 | 50 | [[27, 22, 15], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 51 | ] 52 | -------------------------------------------------------------------------------- /cfg/baseline/yolov3.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # darknet53 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 17 | [-1, 1, Bottleneck, [64]], 18 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 19 | [-1, 2, Bottleneck, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 21 | [-1, 8, Bottleneck, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 23 | [-1, 8, Bottleneck, [512]], 24 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 25 | [-1, 4, Bottleneck, [1024]], # 10 26 | ] 27 | 28 | # YOLOv3 head 29 | head: 30 | [[-1, 1, Bottleneck, [1024, False]], 31 | [-1, 1, Conv, [512, [1, 1]]], 32 | [-1, 1, Conv, [1024, 3, 1]], 33 | [-1, 1, Conv, [512, 1, 1]], 34 | [-1, 1, Conv, [1024, 3, 1]], # 15 (P5/32-large) 35 | 36 | [-2, 1, Conv, [256, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [[-1, 8], 1, Concat, [1]], # cat backbone P4 39 | [-1, 1, Bottleneck, [512, False]], 40 | [-1, 1, Bottleneck, [512, False]], 41 | [-1, 1, Conv, [256, 1, 1]], 42 | [-1, 1, Conv, [512, 3, 1]], # 22 (P4/16-medium) 43 | 44 | [-2, 1, Conv, [128, 1, 1]], 45 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 46 | [[-1, 6], 1, Concat, [1]], # cat backbone P3 47 | [-1, 1, Bottleneck, [256, False]], 48 | [-1, 2, Bottleneck, [256, False]], # 27 (P3/8-small) 49 | 50 | [[27, 22, 15], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 51 | ] 52 | -------------------------------------------------------------------------------- /cfg/baseline/yolov4-csp.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # CSP-Darknet backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 17 | [-1, 1, Bottleneck, [64]], 18 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 19 | [-1, 2, BottleneckCSPC, [128]], 20 | [-1, 1, Conv, [256, 3, 2]], # 5-P3/8 21 | [-1, 8, BottleneckCSPC, [256]], 22 | [-1, 1, Conv, [512, 3, 2]], # 7-P4/16 23 | [-1, 8, BottleneckCSPC, [512]], 24 | [-1, 1, Conv, [1024, 3, 2]], # 9-P5/32 25 | [-1, 4, BottleneckCSPC, [1024]], # 10 26 | ] 27 | 28 | # CSP-Dark-PAN head 29 | head: 30 | [[-1, 1, SPPCSPC, [512]], # 11 31 | [-1, 1, Conv, [256, 1, 1]], 32 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 33 | [8, 1, Conv, [256, 1, 1]], # route backbone P4 34 | [[-1, -2], 1, Concat, [1]], 35 | [-1, 2, BottleneckCSPB, [256]], # 16 36 | [-1, 1, Conv, [128, 1, 1]], 37 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 38 | [6, 1, Conv, [128, 1, 1]], # route backbone P3 39 | [[-1, -2], 1, Concat, [1]], 40 | [-1, 2, BottleneckCSPB, [128]], # 21 41 | [-1, 1, Conv, [256, 3, 1]], 42 | [-2, 1, Conv, [256, 3, 2]], 43 | [[-1, 16], 1, Concat, [1]], # cat 44 | [-1, 2, BottleneckCSPB, [256]], # 25 45 | [-1, 1, Conv, [512, 3, 1]], 46 | [-2, 1, Conv, [512, 3, 2]], 47 | [[-1, 11], 1, Concat, [1]], # cat 48 | [-1, 2, BottleneckCSPB, [512]], # 29 49 | [-1, 1, Conv, [1024, 3, 1]], 50 | 51 | [[22,26,30], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 52 | ] 53 | -------------------------------------------------------------------------------- /cfg/deploy/yolov7-tiny-silu.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # YOLOv7-tiny backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 2]], # 0-P1/2 16 | 17 | [-1, 1, Conv, [64, 3, 2]], # 1-P2/4 18 | 19 | [-1, 1, Conv, [32, 1, 1]], 20 | [-2, 1, Conv, [32, 1, 1]], 21 | [-1, 1, Conv, [32, 3, 1]], 22 | [-1, 1, Conv, [32, 3, 1]], 23 | [[-1, -2, -3, -4], 1, Concat, [1]], 24 | [-1, 1, Conv, [64, 1, 1]], # 7 25 | 26 | [-1, 1, MP, []], # 8-P3/8 27 | [-1, 1, Conv, [64, 1, 1]], 28 | [-2, 1, Conv, [64, 1, 1]], 29 | [-1, 1, Conv, [64, 3, 1]], 30 | [-1, 1, Conv, [64, 3, 1]], 31 | [[-1, -2, -3, -4], 1, Concat, [1]], 32 | [-1, 1, Conv, [128, 1, 1]], # 14 33 | 34 | [-1, 1, MP, []], # 15-P4/16 35 | [-1, 1, Conv, [128, 1, 1]], 36 | [-2, 1, Conv, [128, 1, 1]], 37 | [-1, 1, Conv, [128, 3, 1]], 38 | [-1, 1, Conv, [128, 3, 1]], 39 | [[-1, -2, -3, -4], 1, Concat, [1]], 40 | [-1, 1, Conv, [256, 1, 1]], # 21 41 | 42 | [-1, 1, MP, []], # 22-P5/32 43 | [-1, 1, Conv, [256, 1, 1]], 44 | [-2, 1, Conv, [256, 1, 1]], 45 | [-1, 1, Conv, [256, 3, 1]], 46 | [-1, 1, Conv, [256, 3, 1]], 47 | [[-1, -2, -3, -4], 1, Concat, [1]], 48 | [-1, 1, Conv, [512, 1, 1]], # 28 49 | ] 50 | 51 | # YOLOv7-tiny head 52 | head: 53 | [[-1, 1, Conv, [256, 1, 1]], 54 | [-2, 1, Conv, [256, 1, 1]], 55 | [-1, 1, SP, [5]], 56 | [-2, 1, SP, [9]], 57 | [-3, 1, SP, [13]], 58 | [[-1, -2, -3, -4], 1, Concat, [1]], 59 | [-1, 1, Conv, [256, 1, 1]], 60 | [[-1, -7], 1, Concat, [1]], 61 | [-1, 1, Conv, [256, 1, 1]], # 37 62 | 63 | [-1, 1, Conv, [128, 1, 1]], 64 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 65 | [21, 1, Conv, [128, 1, 1]], # route backbone P4 66 | [[-1, -2], 1, Concat, [1]], 67 | 68 | [-1, 1, Conv, [64, 1, 1]], 69 | [-2, 1, Conv, [64, 1, 1]], 70 | [-1, 1, Conv, [64, 3, 1]], 71 | [-1, 1, Conv, [64, 3, 1]], 72 | [[-1, -2, -3, -4], 1, Concat, [1]], 73 | [-1, 1, Conv, [128, 1, 1]], # 47 74 | 75 | [-1, 1, Conv, [64, 1, 1]], 76 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 77 | [14, 1, Conv, [64, 1, 1]], # route backbone P3 78 | [[-1, -2], 1, Concat, [1]], 79 | 80 | [-1, 1, Conv, [32, 1, 1]], 81 | [-2, 1, Conv, [32, 1, 1]], 82 | [-1, 1, Conv, [32, 3, 1]], 83 | [-1, 1, Conv, [32, 3, 1]], 84 | [[-1, -2, -3, -4], 1, Concat, [1]], 85 | [-1, 1, Conv, [64, 1, 1]], # 57 86 | 87 | [-1, 1, Conv, [128, 3, 2]], 88 | [[-1, 47], 1, Concat, [1]], 89 | 90 | [-1, 1, Conv, [64, 1, 1]], 91 | [-2, 1, Conv, [64, 1, 1]], 92 | [-1, 1, Conv, [64, 3, 1]], 93 | [-1, 1, Conv, [64, 3, 1]], 94 | [[-1, -2, -3, -4], 1, Concat, [1]], 95 | [-1, 1, Conv, [128, 1, 1]], # 65 96 | 97 | [-1, 1, Conv, [256, 3, 2]], 98 | [[-1, 37], 1, Concat, [1]], 99 | 100 | [-1, 1, Conv, [128, 1, 1]], 101 | [-2, 1, Conv, [128, 1, 1]], 102 | [-1, 1, Conv, [128, 3, 1]], 103 | [-1, 1, Conv, [128, 3, 1]], 104 | [[-1, -2, -3, -4], 1, Concat, [1]], 105 | [-1, 1, Conv, [256, 1, 1]], # 73 106 | 107 | [57, 1, Conv, [128, 3, 1]], 108 | [65, 1, Conv, [256, 3, 1]], 109 | [73, 1, Conv, [512, 3, 1]], 110 | 111 | [[74,75,76], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 112 | ] 113 | -------------------------------------------------------------------------------- /cfg/deploy/yolov7-tiny.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # yolov7-tiny backbone 13 | backbone: 14 | # [from, number, module, args] c2, k=1, s=1, p=None, g=1, act=True 15 | [[-1, 1, Conv, [32, 3, 2, None, 1, nn.LeakyReLU(0.1)]], # 0-P1/2 16 | 17 | [-1, 1, Conv, [64, 3, 2, None, 1, nn.LeakyReLU(0.1)]], # 1-P2/4 18 | 19 | [-1, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 20 | [-2, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 21 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 22 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 23 | [[-1, -2, -3, -4], 1, Concat, [1]], 24 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 7 25 | 26 | [-1, 1, MP, []], # 8-P3/8 27 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 28 | [-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 29 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 30 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 31 | [[-1, -2, -3, -4], 1, Concat, [1]], 32 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 14 33 | 34 | [-1, 1, MP, []], # 15-P4/16 35 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 36 | [-2, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 37 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 38 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 39 | [[-1, -2, -3, -4], 1, Concat, [1]], 40 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 21 41 | 42 | [-1, 1, MP, []], # 22-P5/32 43 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 44 | [-2, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 45 | [-1, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 46 | [-1, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 47 | [[-1, -2, -3, -4], 1, Concat, [1]], 48 | [-1, 1, Conv, [512, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 28 49 | ] 50 | 51 | # yolov7-tiny head 52 | head: 53 | [[-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 54 | [-2, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 55 | [-1, 1, SP, [5]], 56 | [-2, 1, SP, [9]], 57 | [-3, 1, SP, [13]], 58 | [[-1, -2, -3, -4], 1, Concat, [1]], 59 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 60 | [[-1, -7], 1, Concat, [1]], 61 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 37 62 | 63 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 64 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 65 | [21, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # route backbone P4 66 | [[-1, -2], 1, Concat, [1]], 67 | 68 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 69 | [-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 70 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 71 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 72 | [[-1, -2, -3, -4], 1, Concat, [1]], 73 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 47 74 | 75 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 76 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 77 | [14, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # route backbone P3 78 | [[-1, -2], 1, Concat, [1]], 79 | 80 | [-1, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 81 | [-2, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 82 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 83 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 84 | [[-1, -2, -3, -4], 1, Concat, [1]], 85 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 57 86 | 87 | [-1, 1, Conv, [128, 3, 2, None, 1, nn.LeakyReLU(0.1)]], 88 | [[-1, 47], 1, Concat, [1]], 89 | 90 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 91 | [-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 92 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 93 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 94 | [[-1, -2, -3, -4], 1, Concat, [1]], 95 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 65 96 | 97 | [-1, 1, Conv, [256, 3, 2, None, 1, nn.LeakyReLU(0.1)]], 98 | [[-1, 37], 1, Concat, [1]], 99 | 100 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 101 | [-2, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 102 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 103 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 104 | [[-1, -2, -3, -4], 1, Concat, [1]], 105 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 73 106 | 107 | [57, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 108 | [65, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 109 | [73, 1, Conv, [512, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 110 | 111 | [[74,75,76], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 112 | ] 113 | -------------------------------------------------------------------------------- /cfg/deploy/yolov7-w6.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [ 19,27, 44,40, 38,94 ] # P3/8 9 | - [ 96,68, 86,152, 180,137 ] # P4/16 10 | - [ 140,301, 303,264, 238,542 ] # P5/32 11 | - [ 436,615, 739,380, 925,792 ] # P6/64 12 | 13 | # yolov7-w6 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, ReOrg, []], # 0 17 | [-1, 1, Conv, [64, 3, 1]], # 1-P1/2 18 | 19 | [-1, 1, Conv, [128, 3, 2]], # 2-P2/4 20 | [-1, 1, Conv, [64, 1, 1]], 21 | [-2, 1, Conv, [64, 1, 1]], 22 | [-1, 1, Conv, [64, 3, 1]], 23 | [-1, 1, Conv, [64, 3, 1]], 24 | [-1, 1, Conv, [64, 3, 1]], 25 | [-1, 1, Conv, [64, 3, 1]], 26 | [[-1, -3, -5, -6], 1, Concat, [1]], 27 | [-1, 1, Conv, [128, 1, 1]], # 10 28 | 29 | [-1, 1, Conv, [256, 3, 2]], # 11-P3/8 30 | [-1, 1, Conv, [128, 1, 1]], 31 | [-2, 1, Conv, [128, 1, 1]], 32 | [-1, 1, Conv, [128, 3, 1]], 33 | [-1, 1, Conv, [128, 3, 1]], 34 | [-1, 1, Conv, [128, 3, 1]], 35 | [-1, 1, Conv, [128, 3, 1]], 36 | [[-1, -3, -5, -6], 1, Concat, [1]], 37 | [-1, 1, Conv, [256, 1, 1]], # 19 38 | 39 | [-1, 1, Conv, [512, 3, 2]], # 20-P4/16 40 | [-1, 1, Conv, [256, 1, 1]], 41 | [-2, 1, Conv, [256, 1, 1]], 42 | [-1, 1, Conv, [256, 3, 1]], 43 | [-1, 1, Conv, [256, 3, 1]], 44 | [-1, 1, Conv, [256, 3, 1]], 45 | [-1, 1, Conv, [256, 3, 1]], 46 | [[-1, -3, -5, -6], 1, Concat, [1]], 47 | [-1, 1, Conv, [512, 1, 1]], # 28 48 | 49 | [-1, 1, Conv, [768, 3, 2]], # 29-P5/32 50 | [-1, 1, Conv, [384, 1, 1]], 51 | [-2, 1, Conv, [384, 1, 1]], 52 | [-1, 1, Conv, [384, 3, 1]], 53 | [-1, 1, Conv, [384, 3, 1]], 54 | [-1, 1, Conv, [384, 3, 1]], 55 | [-1, 1, Conv, [384, 3, 1]], 56 | [[-1, -3, -5, -6], 1, Concat, [1]], 57 | [-1, 1, Conv, [768, 1, 1]], # 37 58 | 59 | [-1, 1, Conv, [1024, 3, 2]], # 38-P6/64 60 | [-1, 1, Conv, [512, 1, 1]], 61 | [-2, 1, Conv, [512, 1, 1]], 62 | [-1, 1, Conv, [512, 3, 1]], 63 | [-1, 1, Conv, [512, 3, 1]], 64 | [-1, 1, Conv, [512, 3, 1]], 65 | [-1, 1, Conv, [512, 3, 1]], 66 | [[-1, -3, -5, -6], 1, Concat, [1]], 67 | [-1, 1, Conv, [1024, 1, 1]], # 46 68 | ] 69 | 70 | # yolov7-w6 head 71 | head: 72 | [[-1, 1, SPPCSPC, [512]], # 47 73 | 74 | [-1, 1, Conv, [384, 1, 1]], 75 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 76 | [37, 1, Conv, [384, 1, 1]], # route backbone P5 77 | [[-1, -2], 1, Concat, [1]], 78 | 79 | [-1, 1, Conv, [384, 1, 1]], 80 | [-2, 1, Conv, [384, 1, 1]], 81 | [-1, 1, Conv, [192, 3, 1]], 82 | [-1, 1, Conv, [192, 3, 1]], 83 | [-1, 1, Conv, [192, 3, 1]], 84 | [-1, 1, Conv, [192, 3, 1]], 85 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 86 | [-1, 1, Conv, [384, 1, 1]], # 59 87 | 88 | [-1, 1, Conv, [256, 1, 1]], 89 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 90 | [28, 1, Conv, [256, 1, 1]], # route backbone P4 91 | [[-1, -2], 1, Concat, [1]], 92 | 93 | [-1, 1, Conv, [256, 1, 1]], 94 | [-2, 1, Conv, [256, 1, 1]], 95 | [-1, 1, Conv, [128, 3, 1]], 96 | [-1, 1, Conv, [128, 3, 1]], 97 | [-1, 1, Conv, [128, 3, 1]], 98 | [-1, 1, Conv, [128, 3, 1]], 99 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 100 | [-1, 1, Conv, [256, 1, 1]], # 71 101 | 102 | [-1, 1, Conv, [128, 1, 1]], 103 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 104 | [19, 1, Conv, [128, 1, 1]], # route backbone P3 105 | [[-1, -2], 1, Concat, [1]], 106 | 107 | [-1, 1, Conv, [128, 1, 1]], 108 | [-2, 1, Conv, [128, 1, 1]], 109 | [-1, 1, Conv, [64, 3, 1]], 110 | [-1, 1, Conv, [64, 3, 1]], 111 | [-1, 1, Conv, [64, 3, 1]], 112 | [-1, 1, Conv, [64, 3, 1]], 113 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 114 | [-1, 1, Conv, [128, 1, 1]], # 83 115 | 116 | [-1, 1, Conv, [256, 3, 2]], 117 | [[-1, 71], 1, Concat, [1]], # cat 118 | 119 | [-1, 1, Conv, [256, 1, 1]], 120 | [-2, 1, Conv, [256, 1, 1]], 121 | [-1, 1, Conv, [128, 3, 1]], 122 | [-1, 1, Conv, [128, 3, 1]], 123 | [-1, 1, Conv, [128, 3, 1]], 124 | [-1, 1, Conv, [128, 3, 1]], 125 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 126 | [-1, 1, Conv, [256, 1, 1]], # 93 127 | 128 | [-1, 1, Conv, [384, 3, 2]], 129 | [[-1, 59], 1, Concat, [1]], # cat 130 | 131 | [-1, 1, Conv, [384, 1, 1]], 132 | [-2, 1, Conv, [384, 1, 1]], 133 | [-1, 1, Conv, [192, 3, 1]], 134 | [-1, 1, Conv, [192, 3, 1]], 135 | [-1, 1, Conv, [192, 3, 1]], 136 | [-1, 1, Conv, [192, 3, 1]], 137 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 138 | [-1, 1, Conv, [384, 1, 1]], # 103 139 | 140 | [-1, 1, Conv, [512, 3, 2]], 141 | [[-1, 47], 1, Concat, [1]], # cat 142 | 143 | [-1, 1, Conv, [512, 1, 1]], 144 | [-2, 1, Conv, [512, 1, 1]], 145 | [-1, 1, Conv, [256, 3, 1]], 146 | [-1, 1, Conv, [256, 3, 1]], 147 | [-1, 1, Conv, [256, 3, 1]], 148 | [-1, 1, Conv, [256, 3, 1]], 149 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 150 | [-1, 1, Conv, [512, 1, 1]], # 113 151 | 152 | [83, 1, Conv, [256, 3, 1]], 153 | [93, 1, Conv, [512, 3, 1]], 154 | [103, 1, Conv, [768, 3, 1]], 155 | [113, 1, Conv, [1024, 3, 1]], 156 | 157 | [[114,115,116,117], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5, P6) 158 | ] 159 | -------------------------------------------------------------------------------- /cfg/deploy/yolov7.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # yolov7 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | 17 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 18 | [-1, 1, Conv, [64, 3, 1]], 19 | 20 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 21 | [-1, 1, Conv, [64, 1, 1]], 22 | [-2, 1, Conv, [64, 1, 1]], 23 | [-1, 1, Conv, [64, 3, 1]], 24 | [-1, 1, Conv, [64, 3, 1]], 25 | [-1, 1, Conv, [64, 3, 1]], 26 | [-1, 1, Conv, [64, 3, 1]], 27 | [[-1, -3, -5, -6], 1, Concat, [1]], 28 | [-1, 1, Conv, [256, 1, 1]], # 11 29 | 30 | [-1, 1, MP, []], 31 | [-1, 1, Conv, [128, 1, 1]], 32 | [-3, 1, Conv, [128, 1, 1]], 33 | [-1, 1, Conv, [128, 3, 2]], 34 | [[-1, -3], 1, Concat, [1]], # 16-P3/8 35 | [-1, 1, Conv, [128, 1, 1]], 36 | [-2, 1, Conv, [128, 1, 1]], 37 | [-1, 1, Conv, [128, 3, 1]], 38 | [-1, 1, Conv, [128, 3, 1]], 39 | [-1, 1, Conv, [128, 3, 1]], 40 | [-1, 1, Conv, [128, 3, 1]], 41 | [[-1, -3, -5, -6], 1, Concat, [1]], 42 | [-1, 1, Conv, [512, 1, 1]], # 24 43 | 44 | [-1, 1, MP, []], 45 | [-1, 1, Conv, [256, 1, 1]], 46 | [-3, 1, Conv, [256, 1, 1]], 47 | [-1, 1, Conv, [256, 3, 2]], 48 | [[-1, -3], 1, Concat, [1]], # 29-P4/16 49 | [-1, 1, Conv, [256, 1, 1]], 50 | [-2, 1, Conv, [256, 1, 1]], 51 | [-1, 1, Conv, [256, 3, 1]], 52 | [-1, 1, Conv, [256, 3, 1]], 53 | [-1, 1, Conv, [256, 3, 1]], 54 | [-1, 1, Conv, [256, 3, 1]], 55 | [[-1, -3, -5, -6], 1, Concat, [1]], 56 | [-1, 1, Conv, [1024, 1, 1]], # 37 57 | 58 | [-1, 1, MP, []], 59 | [-1, 1, Conv, [512, 1, 1]], 60 | [-3, 1, Conv, [512, 1, 1]], 61 | [-1, 1, Conv, [512, 3, 2]], 62 | [[-1, -3], 1, Concat, [1]], # 42-P5/32 63 | [-1, 1, Conv, [256, 1, 1]], 64 | [-2, 1, Conv, [256, 1, 1]], 65 | [-1, 1, Conv, [256, 3, 1]], 66 | [-1, 1, Conv, [256, 3, 1]], 67 | [-1, 1, Conv, [256, 3, 1]], 68 | [-1, 1, Conv, [256, 3, 1]], 69 | [[-1, -3, -5, -6], 1, Concat, [1]], 70 | [-1, 1, Conv, [1024, 1, 1]], # 50 71 | ] 72 | 73 | # yolov7 head 74 | head: 75 | [[-1, 1, SPPCSPC, [512]], # 51 76 | 77 | [-1, 1, Conv, [256, 1, 1]], 78 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 79 | [37, 1, Conv, [256, 1, 1]], # route backbone P4 80 | [[-1, -2], 1, Concat, [1]], 81 | 82 | [-1, 1, Conv, [256, 1, 1]], 83 | [-2, 1, Conv, [256, 1, 1]], 84 | [-1, 1, Conv, [128, 3, 1]], 85 | [-1, 1, Conv, [128, 3, 1]], 86 | [-1, 1, Conv, [128, 3, 1]], 87 | [-1, 1, Conv, [128, 3, 1]], 88 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 89 | [-1, 1, Conv, [256, 1, 1]], # 63 90 | 91 | [-1, 1, Conv, [128, 1, 1]], 92 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 93 | [24, 1, Conv, [128, 1, 1]], # route backbone P3 94 | [[-1, -2], 1, Concat, [1]], 95 | 96 | [-1, 1, Conv, [128, 1, 1]], 97 | [-2, 1, Conv, [128, 1, 1]], 98 | [-1, 1, Conv, [64, 3, 1]], 99 | [-1, 1, Conv, [64, 3, 1]], 100 | [-1, 1, Conv, [64, 3, 1]], 101 | [-1, 1, Conv, [64, 3, 1]], 102 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 103 | [-1, 1, Conv, [128, 1, 1]], # 75 104 | 105 | [-1, 1, MP, []], 106 | [-1, 1, Conv, [128, 1, 1]], 107 | [-3, 1, Conv, [128, 1, 1]], 108 | [-1, 1, Conv, [128, 3, 2]], 109 | [[-1, -3, 63], 1, Concat, [1]], 110 | 111 | [-1, 1, Conv, [256, 1, 1]], 112 | [-2, 1, Conv, [256, 1, 1]], 113 | [-1, 1, Conv, [128, 3, 1]], 114 | [-1, 1, Conv, [128, 3, 1]], 115 | [-1, 1, Conv, [128, 3, 1]], 116 | [-1, 1, Conv, [128, 3, 1]], 117 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 118 | [-1, 1, Conv, [256, 1, 1]], # 88 119 | 120 | [-1, 1, MP, []], 121 | [-1, 1, Conv, [256, 1, 1]], 122 | [-3, 1, Conv, [256, 1, 1]], 123 | [-1, 1, Conv, [256, 3, 2]], 124 | [[-1, -3, 51], 1, Concat, [1]], 125 | 126 | [-1, 1, Conv, [512, 1, 1]], 127 | [-2, 1, Conv, [512, 1, 1]], 128 | [-1, 1, Conv, [256, 3, 1]], 129 | [-1, 1, Conv, [256, 3, 1]], 130 | [-1, 1, Conv, [256, 3, 1]], 131 | [-1, 1, Conv, [256, 3, 1]], 132 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 133 | [-1, 1, Conv, [512, 1, 1]], # 101 134 | 135 | [75, 1, RepConv, [256, 3, 1]], 136 | [88, 1, RepConv, [512, 3, 1]], 137 | [101, 1, RepConv, [1024, 3, 1]], 138 | 139 | [[102,103,104], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 140 | ] 141 | -------------------------------------------------------------------------------- /cfg/deploy/yolov7x.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # yolov7x backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [40, 3, 1]], # 0 16 | 17 | [-1, 1, Conv, [80, 3, 2]], # 1-P1/2 18 | [-1, 1, Conv, [80, 3, 1]], 19 | 20 | [-1, 1, Conv, [160, 3, 2]], # 3-P2/4 21 | [-1, 1, Conv, [64, 1, 1]], 22 | [-2, 1, Conv, [64, 1, 1]], 23 | [-1, 1, Conv, [64, 3, 1]], 24 | [-1, 1, Conv, [64, 3, 1]], 25 | [-1, 1, Conv, [64, 3, 1]], 26 | [-1, 1, Conv, [64, 3, 1]], 27 | [-1, 1, Conv, [64, 3, 1]], 28 | [-1, 1, Conv, [64, 3, 1]], 29 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 30 | [-1, 1, Conv, [320, 1, 1]], # 13 31 | 32 | [-1, 1, MP, []], 33 | [-1, 1, Conv, [160, 1, 1]], 34 | [-3, 1, Conv, [160, 1, 1]], 35 | [-1, 1, Conv, [160, 3, 2]], 36 | [[-1, -3], 1, Concat, [1]], # 18-P3/8 37 | [-1, 1, Conv, [128, 1, 1]], 38 | [-2, 1, Conv, [128, 1, 1]], 39 | [-1, 1, Conv, [128, 3, 1]], 40 | [-1, 1, Conv, [128, 3, 1]], 41 | [-1, 1, Conv, [128, 3, 1]], 42 | [-1, 1, Conv, [128, 3, 1]], 43 | [-1, 1, Conv, [128, 3, 1]], 44 | [-1, 1, Conv, [128, 3, 1]], 45 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 46 | [-1, 1, Conv, [640, 1, 1]], # 28 47 | 48 | [-1, 1, MP, []], 49 | [-1, 1, Conv, [320, 1, 1]], 50 | [-3, 1, Conv, [320, 1, 1]], 51 | [-1, 1, Conv, [320, 3, 2]], 52 | [[-1, -3], 1, Concat, [1]], # 33-P4/16 53 | [-1, 1, Conv, [256, 1, 1]], 54 | [-2, 1, Conv, [256, 1, 1]], 55 | [-1, 1, Conv, [256, 3, 1]], 56 | [-1, 1, Conv, [256, 3, 1]], 57 | [-1, 1, Conv, [256, 3, 1]], 58 | [-1, 1, Conv, [256, 3, 1]], 59 | [-1, 1, Conv, [256, 3, 1]], 60 | [-1, 1, Conv, [256, 3, 1]], 61 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 62 | [-1, 1, Conv, [1280, 1, 1]], # 43 63 | 64 | [-1, 1, MP, []], 65 | [-1, 1, Conv, [640, 1, 1]], 66 | [-3, 1, Conv, [640, 1, 1]], 67 | [-1, 1, Conv, [640, 3, 2]], 68 | [[-1, -3], 1, Concat, [1]], # 48-P5/32 69 | [-1, 1, Conv, [256, 1, 1]], 70 | [-2, 1, Conv, [256, 1, 1]], 71 | [-1, 1, Conv, [256, 3, 1]], 72 | [-1, 1, Conv, [256, 3, 1]], 73 | [-1, 1, Conv, [256, 3, 1]], 74 | [-1, 1, Conv, [256, 3, 1]], 75 | [-1, 1, Conv, [256, 3, 1]], 76 | [-1, 1, Conv, [256, 3, 1]], 77 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 78 | [-1, 1, Conv, [1280, 1, 1]], # 58 79 | ] 80 | 81 | # yolov7x head 82 | head: 83 | [[-1, 1, SPPCSPC, [640]], # 59 84 | 85 | [-1, 1, Conv, [320, 1, 1]], 86 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 87 | [43, 1, Conv, [320, 1, 1]], # route backbone P4 88 | [[-1, -2], 1, Concat, [1]], 89 | 90 | [-1, 1, Conv, [256, 1, 1]], 91 | [-2, 1, Conv, [256, 1, 1]], 92 | [-1, 1, Conv, [256, 3, 1]], 93 | [-1, 1, Conv, [256, 3, 1]], 94 | [-1, 1, Conv, [256, 3, 1]], 95 | [-1, 1, Conv, [256, 3, 1]], 96 | [-1, 1, Conv, [256, 3, 1]], 97 | [-1, 1, Conv, [256, 3, 1]], 98 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 99 | [-1, 1, Conv, [320, 1, 1]], # 73 100 | 101 | [-1, 1, Conv, [160, 1, 1]], 102 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 103 | [28, 1, Conv, [160, 1, 1]], # route backbone P3 104 | [[-1, -2], 1, Concat, [1]], 105 | 106 | [-1, 1, Conv, [128, 1, 1]], 107 | [-2, 1, Conv, [128, 1, 1]], 108 | [-1, 1, Conv, [128, 3, 1]], 109 | [-1, 1, Conv, [128, 3, 1]], 110 | [-1, 1, Conv, [128, 3, 1]], 111 | [-1, 1, Conv, [128, 3, 1]], 112 | [-1, 1, Conv, [128, 3, 1]], 113 | [-1, 1, Conv, [128, 3, 1]], 114 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 115 | [-1, 1, Conv, [160, 1, 1]], # 87 116 | 117 | [-1, 1, MP, []], 118 | [-1, 1, Conv, [160, 1, 1]], 119 | [-3, 1, Conv, [160, 1, 1]], 120 | [-1, 1, Conv, [160, 3, 2]], 121 | [[-1, -3, 73], 1, Concat, [1]], 122 | 123 | [-1, 1, Conv, [256, 1, 1]], 124 | [-2, 1, Conv, [256, 1, 1]], 125 | [-1, 1, Conv, [256, 3, 1]], 126 | [-1, 1, Conv, [256, 3, 1]], 127 | [-1, 1, Conv, [256, 3, 1]], 128 | [-1, 1, Conv, [256, 3, 1]], 129 | [-1, 1, Conv, [256, 3, 1]], 130 | [-1, 1, Conv, [256, 3, 1]], 131 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 132 | [-1, 1, Conv, [320, 1, 1]], # 102 133 | 134 | [-1, 1, MP, []], 135 | [-1, 1, Conv, [320, 1, 1]], 136 | [-3, 1, Conv, [320, 1, 1]], 137 | [-1, 1, Conv, [320, 3, 2]], 138 | [[-1, -3, 59], 1, Concat, [1]], 139 | 140 | [-1, 1, Conv, [512, 1, 1]], 141 | [-2, 1, Conv, [512, 1, 1]], 142 | [-1, 1, Conv, [512, 3, 1]], 143 | [-1, 1, Conv, [512, 3, 1]], 144 | [-1, 1, Conv, [512, 3, 1]], 145 | [-1, 1, Conv, [512, 3, 1]], 146 | [-1, 1, Conv, [512, 3, 1]], 147 | [-1, 1, Conv, [512, 3, 1]], 148 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 149 | [-1, 1, Conv, [640, 1, 1]], # 117 150 | 151 | [87, 1, Conv, [320, 3, 1]], 152 | [102, 1, Conv, [640, 3, 1]], 153 | [117, 1, Conv, [1280, 3, 1]], 154 | 155 | [[118,119,120], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) 156 | ] 157 | -------------------------------------------------------------------------------- /cfg/training/yolov7-tiny.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [10,13, 16,30, 33,23] # P3/8 9 | - [30,61, 62,45, 59,119] # P4/16 10 | - [116,90, 156,198, 373,326] # P5/32 11 | 12 | # yolov7-tiny backbone 13 | backbone: 14 | # [from, number, module, args] c2, k=1, s=1, p=None, g=1, act=True 15 | [[-1, 1, Conv, [32, 3, 2, None, 1, nn.LeakyReLU(0.1)]], # 0-P1/2 16 | 17 | [-1, 1, Conv, [64, 3, 2, None, 1, nn.LeakyReLU(0.1)]], # 1-P2/4 18 | 19 | [-1, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 20 | [-2, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 21 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 22 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 23 | [[-1, -2, -3, -4], 1, Concat, [1]], 24 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 7 25 | 26 | [-1, 1, MP, []], # 8-P3/8 27 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 28 | [-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 29 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 30 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 31 | [[-1, -2, -3, -4], 1, Concat, [1]], 32 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 14 33 | 34 | [-1, 1, MP, []], # 15-P4/16 35 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 36 | [-2, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 37 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 38 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 39 | [[-1, -2, -3, -4], 1, Concat, [1]], 40 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 21 41 | 42 | [-1, 1, MP, []], # 22-P5/32 43 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 44 | [-2, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 45 | [-1, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 46 | [-1, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 47 | [[-1, -2, -3, -4], 1, Concat, [1]], 48 | [-1, 1, Conv, [512, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 28 49 | ] 50 | 51 | # yolov7-tiny head 52 | head: 53 | [[-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 54 | [-2, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 55 | [-1, 1, SP, [5]], 56 | [-2, 1, SP, [9]], 57 | [-3, 1, SP, [13]], 58 | [[-1, -2, -3, -4], 1, Concat, [1]], 59 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 60 | [[-1, -7], 1, Concat, [1]], 61 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 37 62 | 63 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 64 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 65 | [21, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # route backbone P4 66 | [[-1, -2], 1, Concat, [1]], 67 | 68 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 69 | [-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 70 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 71 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 72 | [[-1, -2, -3, -4], 1, Concat, [1]], 73 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 47 74 | 75 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 76 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 77 | [14, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # route backbone P3 78 | [[-1, -2], 1, Concat, [1]], 79 | 80 | [-1, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 81 | [-2, 1, Conv, [32, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 82 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 83 | [-1, 1, Conv, [32, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 84 | [[-1, -2, -3, -4], 1, Concat, [1]], 85 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 57 86 | 87 | [-1, 1, Conv, [128, 3, 2, None, 1, nn.LeakyReLU(0.1)]], 88 | [[-1, 47], 1, Concat, [1]], 89 | 90 | [-1, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 91 | [-2, 1, Conv, [64, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 92 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 93 | [-1, 1, Conv, [64, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 94 | [[-1, -2, -3, -4], 1, Concat, [1]], 95 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 65 96 | 97 | [-1, 1, Conv, [256, 3, 2, None, 1, nn.LeakyReLU(0.1)]], 98 | [[-1, 37], 1, Concat, [1]], 99 | 100 | [-1, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 101 | [-2, 1, Conv, [128, 1, 1, None, 1, nn.LeakyReLU(0.1)]], 102 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 103 | [-1, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 104 | [[-1, -2, -3, -4], 1, Concat, [1]], 105 | [-1, 1, Conv, [256, 1, 1, None, 1, nn.LeakyReLU(0.1)]], # 73 106 | 107 | [57, 1, Conv, [128, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 108 | [65, 1, Conv, [256, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 109 | [73, 1, Conv, [512, 3, 1, None, 1, nn.LeakyReLU(0.1)]], 110 | 111 | [[74,75,76], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5) 112 | ] 113 | -------------------------------------------------------------------------------- /cfg/training/yolov7-w6.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [ 19,27, 44,40, 38,94 ] # P3/8 9 | - [ 96,68, 86,152, 180,137 ] # P4/16 10 | - [ 140,301, 303,264, 238,542 ] # P5/32 11 | - [ 436,615, 739,380, 925,792 ] # P6/64 12 | 13 | # yolov7 backbone 14 | backbone: 15 | # [from, number, module, args] 16 | [[-1, 1, ReOrg, []], # 0 17 | [-1, 1, Conv, [64, 3, 1]], # 1-P1/2 18 | 19 | [-1, 1, Conv, [128, 3, 2]], # 2-P2/4 20 | [-1, 1, Conv, [64, 1, 1]], 21 | [-2, 1, Conv, [64, 1, 1]], 22 | [-1, 1, Conv, [64, 3, 1]], 23 | [-1, 1, Conv, [64, 3, 1]], 24 | [-1, 1, Conv, [64, 3, 1]], 25 | [-1, 1, Conv, [64, 3, 1]], 26 | [[-1, -3, -5, -6], 1, Concat, [1]], 27 | [-1, 1, Conv, [128, 1, 1]], # 10 28 | 29 | [-1, 1, Conv, [256, 3, 2]], # 11-P3/8 30 | [-1, 1, Conv, [128, 1, 1]], 31 | [-2, 1, Conv, [128, 1, 1]], 32 | [-1, 1, Conv, [128, 3, 1]], 33 | [-1, 1, Conv, [128, 3, 1]], 34 | [-1, 1, Conv, [128, 3, 1]], 35 | [-1, 1, Conv, [128, 3, 1]], 36 | [[-1, -3, -5, -6], 1, Concat, [1]], 37 | [-1, 1, Conv, [256, 1, 1]], # 19 38 | 39 | [-1, 1, Conv, [512, 3, 2]], # 20-P4/16 40 | [-1, 1, Conv, [256, 1, 1]], 41 | [-2, 1, Conv, [256, 1, 1]], 42 | [-1, 1, Conv, [256, 3, 1]], 43 | [-1, 1, Conv, [256, 3, 1]], 44 | [-1, 1, Conv, [256, 3, 1]], 45 | [-1, 1, Conv, [256, 3, 1]], 46 | [[-1, -3, -5, -6], 1, Concat, [1]], 47 | [-1, 1, Conv, [512, 1, 1]], # 28 48 | 49 | [-1, 1, Conv, [768, 3, 2]], # 29-P5/32 50 | [-1, 1, Conv, [384, 1, 1]], 51 | [-2, 1, Conv, [384, 1, 1]], 52 | [-1, 1, Conv, [384, 3, 1]], 53 | [-1, 1, Conv, [384, 3, 1]], 54 | [-1, 1, Conv, [384, 3, 1]], 55 | [-1, 1, Conv, [384, 3, 1]], 56 | [[-1, -3, -5, -6], 1, Concat, [1]], 57 | [-1, 1, Conv, [768, 1, 1]], # 37 58 | 59 | [-1, 1, Conv, [1024, 3, 2]], # 38-P6/64 60 | [-1, 1, Conv, [512, 1, 1]], 61 | [-2, 1, Conv, [512, 1, 1]], 62 | [-1, 1, Conv, [512, 3, 1]], 63 | [-1, 1, Conv, [512, 3, 1]], 64 | [-1, 1, Conv, [512, 3, 1]], 65 | [-1, 1, Conv, [512, 3, 1]], 66 | [[-1, -3, -5, -6], 1, Concat, [1]], 67 | [-1, 1, Conv, [1024, 1, 1]], # 46 68 | ] 69 | 70 | # yolov7 head 71 | head: 72 | [[-1, 1, SPPCSPC, [512]], # 47 73 | 74 | [-1, 1, Conv, [384, 1, 1]], 75 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 76 | [37, 1, Conv, [384, 1, 1]], # route backbone P5 77 | [[-1, -2], 1, Concat, [1]], 78 | 79 | [-1, 1, Conv, [384, 1, 1]], 80 | [-2, 1, Conv, [384, 1, 1]], 81 | [-1, 1, Conv, [192, 3, 1]], 82 | [-1, 1, Conv, [192, 3, 1]], 83 | [-1, 1, Conv, [192, 3, 1]], 84 | [-1, 1, Conv, [192, 3, 1]], 85 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 86 | [-1, 1, Conv, [384, 1, 1]], # 59 87 | 88 | [-1, 1, Conv, [256, 1, 1]], 89 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 90 | [28, 1, Conv, [256, 1, 1]], # route backbone P4 91 | [[-1, -2], 1, Concat, [1]], 92 | 93 | [-1, 1, Conv, [256, 1, 1]], 94 | [-2, 1, Conv, [256, 1, 1]], 95 | [-1, 1, Conv, [128, 3, 1]], 96 | [-1, 1, Conv, [128, 3, 1]], 97 | [-1, 1, Conv, [128, 3, 1]], 98 | [-1, 1, Conv, [128, 3, 1]], 99 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 100 | [-1, 1, Conv, [256, 1, 1]], # 71 101 | 102 | [-1, 1, Conv, [128, 1, 1]], 103 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 104 | [19, 1, Conv, [128, 1, 1]], # route backbone P3 105 | [[-1, -2], 1, Concat, [1]], 106 | 107 | [-1, 1, Conv, [128, 1, 1]], 108 | [-2, 1, Conv, [128, 1, 1]], 109 | [-1, 1, Conv, [64, 3, 1]], 110 | [-1, 1, Conv, [64, 3, 1]], 111 | [-1, 1, Conv, [64, 3, 1]], 112 | [-1, 1, Conv, [64, 3, 1]], 113 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 114 | [-1, 1, Conv, [128, 1, 1]], # 83 115 | 116 | [-1, 1, Conv, [256, 3, 2]], 117 | [[-1, 71], 1, Concat, [1]], # cat 118 | 119 | [-1, 1, Conv, [256, 1, 1]], 120 | [-2, 1, Conv, [256, 1, 1]], 121 | [-1, 1, Conv, [128, 3, 1]], 122 | [-1, 1, Conv, [128, 3, 1]], 123 | [-1, 1, Conv, [128, 3, 1]], 124 | [-1, 1, Conv, [128, 3, 1]], 125 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 126 | [-1, 1, Conv, [256, 1, 1]], # 93 127 | 128 | [-1, 1, Conv, [384, 3, 2]], 129 | [[-1, 59], 1, Concat, [1]], # cat 130 | 131 | [-1, 1, Conv, [384, 1, 1]], 132 | [-2, 1, Conv, [384, 1, 1]], 133 | [-1, 1, Conv, [192, 3, 1]], 134 | [-1, 1, Conv, [192, 3, 1]], 135 | [-1, 1, Conv, [192, 3, 1]], 136 | [-1, 1, Conv, [192, 3, 1]], 137 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 138 | [-1, 1, Conv, [384, 1, 1]], # 103 139 | 140 | [-1, 1, Conv, [512, 3, 2]], 141 | [[-1, 47], 1, Concat, [1]], # cat 142 | 143 | [-1, 1, Conv, [512, 1, 1]], 144 | [-2, 1, Conv, [512, 1, 1]], 145 | [-1, 1, Conv, [256, 3, 1]], 146 | [-1, 1, Conv, [256, 3, 1]], 147 | [-1, 1, Conv, [256, 3, 1]], 148 | [-1, 1, Conv, [256, 3, 1]], 149 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 150 | [-1, 1, Conv, [512, 1, 1]], # 113 151 | 152 | [83, 1, Conv, [256, 3, 1]], 153 | [93, 1, Conv, [512, 3, 1]], 154 | [103, 1, Conv, [768, 3, 1]], 155 | [113, 1, Conv, [1024, 3, 1]], 156 | 157 | [83, 1, Conv, [320, 3, 1]], 158 | [71, 1, Conv, [640, 3, 1]], 159 | [59, 1, Conv, [960, 3, 1]], 160 | [47, 1, Conv, [1280, 3, 1]], 161 | 162 | [[114,115,116,117,118,119,120,121], 1, IAuxDetect, [nc, anchors]], # Detect(P3, P4, P5, P6) 163 | ] 164 | -------------------------------------------------------------------------------- /cfg/training/yolov7.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # yolov7 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [32, 3, 1]], # 0 16 | 17 | [-1, 1, Conv, [64, 3, 2]], # 1-P1/2 18 | [-1, 1, Conv, [64, 3, 1]], 19 | 20 | [-1, 1, Conv, [128, 3, 2]], # 3-P2/4 21 | [-1, 1, Conv, [64, 1, 1]], 22 | [-2, 1, Conv, [64, 1, 1]], 23 | [-1, 1, Conv, [64, 3, 1]], 24 | [-1, 1, Conv, [64, 3, 1]], 25 | [-1, 1, Conv, [64, 3, 1]], 26 | [-1, 1, Conv, [64, 3, 1]], 27 | [[-1, -3, -5, -6], 1, Concat, [1]], 28 | [-1, 1, Conv, [256, 1, 1]], # 11 29 | 30 | [-1, 1, MP, []], 31 | [-1, 1, Conv, [128, 1, 1]], 32 | [-3, 1, Conv, [128, 1, 1]], 33 | [-1, 1, Conv, [128, 3, 2]], 34 | [[-1, -3], 1, Concat, [1]], # 16-P3/8 35 | [-1, 1, Conv, [128, 1, 1]], 36 | [-2, 1, Conv, [128, 1, 1]], 37 | [-1, 1, Conv, [128, 3, 1]], 38 | [-1, 1, Conv, [128, 3, 1]], 39 | [-1, 1, Conv, [128, 3, 1]], 40 | [-1, 1, Conv, [128, 3, 1]], 41 | [[-1, -3, -5, -6], 1, Concat, [1]], 42 | [-1, 1, Conv, [512, 1, 1]], # 24 43 | 44 | [-1, 1, MP, []], 45 | [-1, 1, Conv, [256, 1, 1]], 46 | [-3, 1, Conv, [256, 1, 1]], 47 | [-1, 1, Conv, [256, 3, 2]], 48 | [[-1, -3], 1, Concat, [1]], # 29-P4/16 49 | [-1, 1, Conv, [256, 1, 1]], 50 | [-2, 1, Conv, [256, 1, 1]], 51 | [-1, 1, Conv, [256, 3, 1]], 52 | [-1, 1, Conv, [256, 3, 1]], 53 | [-1, 1, Conv, [256, 3, 1]], 54 | [-1, 1, Conv, [256, 3, 1]], 55 | [[-1, -3, -5, -6], 1, Concat, [1]], 56 | [-1, 1, Conv, [1024, 1, 1]], # 37 57 | 58 | [-1, 1, MP, []], 59 | [-1, 1, Conv, [512, 1, 1]], 60 | [-3, 1, Conv, [512, 1, 1]], 61 | [-1, 1, Conv, [512, 3, 2]], 62 | [[-1, -3], 1, Concat, [1]], # 42-P5/32 63 | [-1, 1, Conv, [256, 1, 1]], 64 | [-2, 1, Conv, [256, 1, 1]], 65 | [-1, 1, Conv, [256, 3, 1]], 66 | [-1, 1, Conv, [256, 3, 1]], 67 | [-1, 1, Conv, [256, 3, 1]], 68 | [-1, 1, Conv, [256, 3, 1]], 69 | [[-1, -3, -5, -6], 1, Concat, [1]], 70 | [-1, 1, Conv, [1024, 1, 1]], # 50 71 | ] 72 | 73 | # yolov7 head 74 | head: 75 | [[-1, 1, SPPCSPC, [512]], # 51 76 | 77 | [-1, 1, Conv, [256, 1, 1]], 78 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 79 | [37, 1, Conv, [256, 1, 1]], # route backbone P4 80 | [[-1, -2], 1, Concat, [1]], 81 | 82 | [-1, 1, Conv, [256, 1, 1]], 83 | [-2, 1, Conv, [256, 1, 1]], 84 | [-1, 1, Conv, [128, 3, 1]], 85 | [-1, 1, Conv, [128, 3, 1]], 86 | [-1, 1, Conv, [128, 3, 1]], 87 | [-1, 1, Conv, [128, 3, 1]], 88 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 89 | [-1, 1, Conv, [256, 1, 1]], # 63 90 | 91 | [-1, 1, Conv, [128, 1, 1]], 92 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 93 | [24, 1, Conv, [128, 1, 1]], # route backbone P3 94 | [[-1, -2], 1, Concat, [1]], 95 | 96 | [-1, 1, Conv, [128, 1, 1]], 97 | [-2, 1, Conv, [128, 1, 1]], 98 | [-1, 1, Conv, [64, 3, 1]], 99 | [-1, 1, Conv, [64, 3, 1]], 100 | [-1, 1, Conv, [64, 3, 1]], 101 | [-1, 1, Conv, [64, 3, 1]], 102 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 103 | [-1, 1, Conv, [128, 1, 1]], # 75 104 | 105 | [-1, 1, MP, []], 106 | [-1, 1, Conv, [128, 1, 1]], 107 | [-3, 1, Conv, [128, 1, 1]], 108 | [-1, 1, Conv, [128, 3, 2]], 109 | [[-1, -3, 63], 1, Concat, [1]], 110 | 111 | [-1, 1, Conv, [256, 1, 1]], 112 | [-2, 1, Conv, [256, 1, 1]], 113 | [-1, 1, Conv, [128, 3, 1]], 114 | [-1, 1, Conv, [128, 3, 1]], 115 | [-1, 1, Conv, [128, 3, 1]], 116 | [-1, 1, Conv, [128, 3, 1]], 117 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 118 | [-1, 1, Conv, [256, 1, 1]], # 88 119 | 120 | [-1, 1, MP, []], 121 | [-1, 1, Conv, [256, 1, 1]], 122 | [-3, 1, Conv, [256, 1, 1]], 123 | [-1, 1, Conv, [256, 3, 2]], 124 | [[-1, -3, 51], 1, Concat, [1]], 125 | 126 | [-1, 1, Conv, [512, 1, 1]], 127 | [-2, 1, Conv, [512, 1, 1]], 128 | [-1, 1, Conv, [256, 3, 1]], 129 | [-1, 1, Conv, [256, 3, 1]], 130 | [-1, 1, Conv, [256, 3, 1]], 131 | [-1, 1, Conv, [256, 3, 1]], 132 | [[-1, -2, -3, -4, -5, -6], 1, Concat, [1]], 133 | [-1, 1, Conv, [512, 1, 1]], # 101 134 | 135 | [75, 1, RepConv, [256, 3, 1]], 136 | [88, 1, RepConv, [512, 3, 1]], 137 | [101, 1, RepConv, [1024, 3, 1]], 138 | 139 | [[102,103,104], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5) 140 | ] 141 | -------------------------------------------------------------------------------- /cfg/training/yolov7x.yaml: -------------------------------------------------------------------------------- 1 | # parameters 2 | nc: 80 # number of classes 3 | depth_multiple: 1.0 # model depth multiple 4 | width_multiple: 1.0 # layer channel multiple 5 | 6 | # anchors 7 | anchors: 8 | - [12,16, 19,36, 40,28] # P3/8 9 | - [36,75, 76,55, 72,146] # P4/16 10 | - [142,110, 192,243, 459,401] # P5/32 11 | 12 | # yolov7 backbone 13 | backbone: 14 | # [from, number, module, args] 15 | [[-1, 1, Conv, [40, 3, 1]], # 0 16 | 17 | [-1, 1, Conv, [80, 3, 2]], # 1-P1/2 18 | [-1, 1, Conv, [80, 3, 1]], 19 | 20 | [-1, 1, Conv, [160, 3, 2]], # 3-P2/4 21 | [-1, 1, Conv, [64, 1, 1]], 22 | [-2, 1, Conv, [64, 1, 1]], 23 | [-1, 1, Conv, [64, 3, 1]], 24 | [-1, 1, Conv, [64, 3, 1]], 25 | [-1, 1, Conv, [64, 3, 1]], 26 | [-1, 1, Conv, [64, 3, 1]], 27 | [-1, 1, Conv, [64, 3, 1]], 28 | [-1, 1, Conv, [64, 3, 1]], 29 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 30 | [-1, 1, Conv, [320, 1, 1]], # 13 31 | 32 | [-1, 1, MP, []], 33 | [-1, 1, Conv, [160, 1, 1]], 34 | [-3, 1, Conv, [160, 1, 1]], 35 | [-1, 1, Conv, [160, 3, 2]], 36 | [[-1, -3], 1, Concat, [1]], # 18-P3/8 37 | [-1, 1, Conv, [128, 1, 1]], 38 | [-2, 1, Conv, [128, 1, 1]], 39 | [-1, 1, Conv, [128, 3, 1]], 40 | [-1, 1, Conv, [128, 3, 1]], 41 | [-1, 1, Conv, [128, 3, 1]], 42 | [-1, 1, Conv, [128, 3, 1]], 43 | [-1, 1, Conv, [128, 3, 1]], 44 | [-1, 1, Conv, [128, 3, 1]], 45 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 46 | [-1, 1, Conv, [640, 1, 1]], # 28 47 | 48 | [-1, 1, MP, []], 49 | [-1, 1, Conv, [320, 1, 1]], 50 | [-3, 1, Conv, [320, 1, 1]], 51 | [-1, 1, Conv, [320, 3, 2]], 52 | [[-1, -3], 1, Concat, [1]], # 33-P4/16 53 | [-1, 1, Conv, [256, 1, 1]], 54 | [-2, 1, Conv, [256, 1, 1]], 55 | [-1, 1, Conv, [256, 3, 1]], 56 | [-1, 1, Conv, [256, 3, 1]], 57 | [-1, 1, Conv, [256, 3, 1]], 58 | [-1, 1, Conv, [256, 3, 1]], 59 | [-1, 1, Conv, [256, 3, 1]], 60 | [-1, 1, Conv, [256, 3, 1]], 61 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 62 | [-1, 1, Conv, [1280, 1, 1]], # 43 63 | 64 | [-1, 1, MP, []], 65 | [-1, 1, Conv, [640, 1, 1]], 66 | [-3, 1, Conv, [640, 1, 1]], 67 | [-1, 1, Conv, [640, 3, 2]], 68 | [[-1, -3], 1, Concat, [1]], # 48-P5/32 69 | [-1, 1, Conv, [256, 1, 1]], 70 | [-2, 1, Conv, [256, 1, 1]], 71 | [-1, 1, Conv, [256, 3, 1]], 72 | [-1, 1, Conv, [256, 3, 1]], 73 | [-1, 1, Conv, [256, 3, 1]], 74 | [-1, 1, Conv, [256, 3, 1]], 75 | [-1, 1, Conv, [256, 3, 1]], 76 | [-1, 1, Conv, [256, 3, 1]], 77 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 78 | [-1, 1, Conv, [1280, 1, 1]], # 58 79 | ] 80 | 81 | # yolov7 head 82 | head: 83 | [[-1, 1, SPPCSPC, [640]], # 59 84 | 85 | [-1, 1, Conv, [320, 1, 1]], 86 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 87 | [43, 1, Conv, [320, 1, 1]], # route backbone P4 88 | [[-1, -2], 1, Concat, [1]], 89 | 90 | [-1, 1, Conv, [256, 1, 1]], 91 | [-2, 1, Conv, [256, 1, 1]], 92 | [-1, 1, Conv, [256, 3, 1]], 93 | [-1, 1, Conv, [256, 3, 1]], 94 | [-1, 1, Conv, [256, 3, 1]], 95 | [-1, 1, Conv, [256, 3, 1]], 96 | [-1, 1, Conv, [256, 3, 1]], 97 | [-1, 1, Conv, [256, 3, 1]], 98 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 99 | [-1, 1, Conv, [320, 1, 1]], # 73 100 | 101 | [-1, 1, Conv, [160, 1, 1]], 102 | [-1, 1, nn.Upsample, [None, 2, 'nearest']], 103 | [28, 1, Conv, [160, 1, 1]], # route backbone P3 104 | [[-1, -2], 1, Concat, [1]], 105 | 106 | [-1, 1, Conv, [128, 1, 1]], 107 | [-2, 1, Conv, [128, 1, 1]], 108 | [-1, 1, Conv, [128, 3, 1]], 109 | [-1, 1, Conv, [128, 3, 1]], 110 | [-1, 1, Conv, [128, 3, 1]], 111 | [-1, 1, Conv, [128, 3, 1]], 112 | [-1, 1, Conv, [128, 3, 1]], 113 | [-1, 1, Conv, [128, 3, 1]], 114 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 115 | [-1, 1, Conv, [160, 1, 1]], # 87 116 | 117 | [-1, 1, MP, []], 118 | [-1, 1, Conv, [160, 1, 1]], 119 | [-3, 1, Conv, [160, 1, 1]], 120 | [-1, 1, Conv, [160, 3, 2]], 121 | [[-1, -3, 73], 1, Concat, [1]], 122 | 123 | [-1, 1, Conv, [256, 1, 1]], 124 | [-2, 1, Conv, [256, 1, 1]], 125 | [-1, 1, Conv, [256, 3, 1]], 126 | [-1, 1, Conv, [256, 3, 1]], 127 | [-1, 1, Conv, [256, 3, 1]], 128 | [-1, 1, Conv, [256, 3, 1]], 129 | [-1, 1, Conv, [256, 3, 1]], 130 | [-1, 1, Conv, [256, 3, 1]], 131 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 132 | [-1, 1, Conv, [320, 1, 1]], # 102 133 | 134 | [-1, 1, MP, []], 135 | [-1, 1, Conv, [320, 1, 1]], 136 | [-3, 1, Conv, [320, 1, 1]], 137 | [-1, 1, Conv, [320, 3, 2]], 138 | [[-1, -3, 59], 1, Concat, [1]], 139 | 140 | [-1, 1, Conv, [512, 1, 1]], 141 | [-2, 1, Conv, [512, 1, 1]], 142 | [-1, 1, Conv, [512, 3, 1]], 143 | [-1, 1, Conv, [512, 3, 1]], 144 | [-1, 1, Conv, [512, 3, 1]], 145 | [-1, 1, Conv, [512, 3, 1]], 146 | [-1, 1, Conv, [512, 3, 1]], 147 | [-1, 1, Conv, [512, 3, 1]], 148 | [[-1, -3, -5, -7, -8], 1, Concat, [1]], 149 | [-1, 1, Conv, [640, 1, 1]], # 117 150 | 151 | [87, 1, Conv, [320, 3, 1]], 152 | [102, 1, Conv, [640, 3, 1]], 153 | [117, 1, Conv, [1280, 3, 1]], 154 | 155 | [[118,119,120], 1, IDetect, [nc, anchors]], # Detect(P3, P4, P5) 156 | ] 157 | -------------------------------------------------------------------------------- /data/coco.yaml: -------------------------------------------------------------------------------- 1 | # COCO 2017 dataset http://cocodataset.org 2 | 3 | # download command/URL (optional) 4 | download: bash ./scripts/get_coco.sh 5 | 6 | # train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/] 7 | train: ./coco/train2017.txt # 118287 images 8 | val: ./coco/val2017.txt # 5000 images 9 | test: ./coco/test-dev2017.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794 10 | 11 | # number of classes 12 | nc: 80 13 | 14 | # class names 15 | names: [ 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 16 | 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 17 | 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 18 | 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 19 | 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 20 | 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', 21 | 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 22 | 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 23 | 'hair drier', 'toothbrush' ] 24 | -------------------------------------------------------------------------------- /data/hyp.scratch.custom.yaml: -------------------------------------------------------------------------------- 1 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 2 | lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf) 3 | momentum: 0.937 # SGD momentum/Adam beta1 4 | weight_decay: 0.0005 # optimizer weight decay 5e-4 5 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 6 | warmup_momentum: 0.8 # warmup initial momentum 7 | warmup_bias_lr: 0.1 # warmup initial bias lr 8 | box: 0.05 # box loss gain 9 | cls: 0.3 # cls loss gain 10 | cls_pw: 1.0 # cls BCELoss positive_weight 11 | obj: 0.7 # obj loss gain (scale with pixels) 12 | obj_pw: 1.0 # obj BCELoss positive_weight 13 | iou_t: 0.20 # IoU training threshold 14 | anchor_t: 4.0 # anchor-multiple threshold 15 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 16 | hsv_h: 0.015 # image HSV-Hue augmentation (fraction) 17 | hsv_s: 0.7 # image HSV-Saturation augmentation (fraction) 18 | hsv_v: 0.4 # image HSV-Value augmentation (fraction) 19 | degrees: 0.0 # image rotation (+/- deg) 20 | translate: 0.2 # image translation (+/- fraction) 21 | scale: 0.5 # image scale (+/- gain) 22 | shear: 0.0 # image shear (+/- deg) 23 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 24 | flipud: 0.0 # image flip up-down (probability) 25 | fliplr: 0.5 # image flip left-right (probability) 26 | mosaic: 1.0 # image mosaic (probability) 27 | mixup: 0.0 # image mixup (probability) 28 | copy_paste: 0.0 # image copy paste (probability) 29 | paste_in: 0.0 # image copy paste (probability) 30 | -------------------------------------------------------------------------------- /data/hyp.scratch.p5.yaml: -------------------------------------------------------------------------------- 1 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 2 | lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf) 3 | momentum: 0.937 # SGD momentum/Adam beta1 4 | weight_decay: 0.0005 # optimizer weight decay 5e-4 5 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 6 | warmup_momentum: 0.8 # warmup initial momentum 7 | warmup_bias_lr: 0.1 # warmup initial bias lr 8 | box: 0.05 # box loss gain 9 | cls: 0.3 # cls loss gain 10 | cls_pw: 1.0 # cls BCELoss positive_weight 11 | obj: 0.7 # obj loss gain (scale with pixels) 12 | obj_pw: 1.0 # obj BCELoss positive_weight 13 | iou_t: 0.20 # IoU training threshold 14 | anchor_t: 4.0 # anchor-multiple threshold 15 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 16 | hsv_h: 0.015 # image HSV-Hue augmentation (fraction) 17 | hsv_s: 0.7 # image HSV-Saturation augmentation (fraction) 18 | hsv_v: 0.4 # image HSV-Value augmentation (fraction) 19 | degrees: 0.0 # image rotation (+/- deg) 20 | translate: 0.2 # image translation (+/- fraction) 21 | scale: 0.9 # image scale (+/- gain) 22 | shear: 0.0 # image shear (+/- deg) 23 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 24 | flipud: 0.0 # image flip up-down (probability) 25 | fliplr: 0.5 # image flip left-right (probability) 26 | mosaic: 1.0 # image mosaic (probability) 27 | mixup: 0.15 # image mixup (probability) 28 | copy_paste: 0.0 # image copy paste (probability) 29 | paste_in: 0.15 # image copy paste (probability) 30 | -------------------------------------------------------------------------------- /data/hyp.scratch.p6.yaml: -------------------------------------------------------------------------------- 1 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 2 | lrf: 0.2 # final OneCycleLR learning rate (lr0 * lrf) 3 | momentum: 0.937 # SGD momentum/Adam beta1 4 | weight_decay: 0.0005 # optimizer weight decay 5e-4 5 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 6 | warmup_momentum: 0.8 # warmup initial momentum 7 | warmup_bias_lr: 0.1 # warmup initial bias lr 8 | box: 0.05 # box loss gain 9 | cls: 0.3 # cls loss gain 10 | cls_pw: 1.0 # cls BCELoss positive_weight 11 | obj: 0.7 # obj loss gain (scale with pixels) 12 | obj_pw: 1.0 # obj BCELoss positive_weight 13 | iou_t: 0.20 # IoU training threshold 14 | anchor_t: 4.0 # anchor-multiple threshold 15 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 16 | hsv_h: 0.015 # image HSV-Hue augmentation (fraction) 17 | hsv_s: 0.7 # image HSV-Saturation augmentation (fraction) 18 | hsv_v: 0.4 # image HSV-Value augmentation (fraction) 19 | degrees: 0.0 # image rotation (+/- deg) 20 | translate: 0.2 # image translation (+/- fraction) 21 | scale: 0.9 # image scale (+/- gain) 22 | shear: 0.0 # image shear (+/- deg) 23 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 24 | flipud: 0.0 # image flip up-down (probability) 25 | fliplr: 0.5 # image flip left-right (probability) 26 | mosaic: 1.0 # image mosaic (probability) 27 | mixup: 0.15 # image mixup (probability) 28 | copy_paste: 0.0 # image copy paste (probability) 29 | paste_in: 0.15 # image copy paste (probability) 30 | -------------------------------------------------------------------------------- /data/hyp.scratch.tiny.yaml: -------------------------------------------------------------------------------- 1 | lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) 2 | lrf: 0.01 # final OneCycleLR learning rate (lr0 * lrf) 3 | momentum: 0.937 # SGD momentum/Adam beta1 4 | weight_decay: 0.0005 # optimizer weight decay 5e-4 5 | warmup_epochs: 3.0 # warmup epochs (fractions ok) 6 | warmup_momentum: 0.8 # warmup initial momentum 7 | warmup_bias_lr: 0.1 # warmup initial bias lr 8 | box: 0.05 # box loss gain 9 | cls: 0.5 # cls loss gain 10 | cls_pw: 1.0 # cls BCELoss positive_weight 11 | obj: 1.0 # obj loss gain (scale with pixels) 12 | obj_pw: 1.0 # obj BCELoss positive_weight 13 | iou_t: 0.20 # IoU training threshold 14 | anchor_t: 4.0 # anchor-multiple threshold 15 | fl_gamma: 0.0 # focal loss gamma (efficientDet default gamma=1.5) 16 | hsv_h: 0.015 # image HSV-Hue augmentation (fraction) 17 | hsv_s: 0.7 # image HSV-Saturation augmentation (fraction) 18 | hsv_v: 0.4 # image HSV-Value augmentation (fraction) 19 | degrees: 0.0 # image rotation (+/- deg) 20 | translate: 0.1 # image translation (+/- fraction) 21 | scale: 0.5 # image scale (+/- gain) 22 | shear: 0.0 # image shear (+/- deg) 23 | perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 24 | flipud: 0.0 # image flip up-down (probability) 25 | fliplr: 0.5 # image flip left-right (probability) 26 | mosaic: 1.0 # image mosaic (probability) 27 | mixup: 0.05 # image mixup (probability) 28 | copy_paste: 0.0 # image copy paste (probability) 29 | paste_in: 0.05 # image copy paste (probability) 30 | -------------------------------------------------------------------------------- /data/mot17.yaml: -------------------------------------------------------------------------------- 1 | train: ./mot17/train.txt 2 | val: ./mot17/val.txt 3 | test: ./mot17/val.txt 4 | 5 | nc: 1 6 | 7 | names: ['pedestrain'] -------------------------------------------------------------------------------- /data/uavdt.yaml: -------------------------------------------------------------------------------- 1 | train: ./uavdt/train.txt 2 | val: ./uavdt/test.txt 3 | test: ./uavdt/test.txt 4 | 5 | nc: 1 6 | 7 | names: ['car'] -------------------------------------------------------------------------------- /data/visdrone_all.yaml: -------------------------------------------------------------------------------- 1 | 2 | train: ./visdrone/train.txt 3 | val: ./visdrone/val.txt 4 | test: ./visdrone/test.txt 5 | 6 | nc: 10 7 | 8 | names: ['pedestrain', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor'] -------------------------------------------------------------------------------- /data/visdrone_half_car.yaml: -------------------------------------------------------------------------------- 1 | 2 | train: ./visdrone/train.txt 3 | val: ./visdrone/val.txt 4 | test: ./visdrone/test.txt 5 | 6 | nc: 4 7 | 8 | names: ['car', 'van', 'truck', 'bus'] -------------------------------------------------------------------------------- /figure/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/figure/demo.gif -------------------------------------------------------------------------------- /figure/horses_prediction.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/figure/horses_prediction.jpg -------------------------------------------------------------------------------- /figure/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/figure/mask.png -------------------------------------------------------------------------------- /figure/performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/figure/performance.png -------------------------------------------------------------------------------- /figure/pose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/figure/pose.png -------------------------------------------------------------------------------- /hubconf.py: -------------------------------------------------------------------------------- 1 | """PyTorch Hub models 2 | 3 | Usage: 4 | import torch 5 | model = torch.hub.load('repo', 'model') 6 | """ 7 | 8 | from pathlib import Path 9 | 10 | import torch 11 | 12 | from models.yolo import Model 13 | from utils.general import check_requirements, set_logging 14 | from utils.google_utils import attempt_download 15 | from utils.torch_utils import select_device 16 | 17 | dependencies = ['torch', 'yaml'] 18 | check_requirements(Path(__file__).parent / 'requirements.txt', exclude=('pycocotools', 'thop')) 19 | set_logging() 20 | 21 | 22 | def create(name, pretrained, channels, classes, autoshape): 23 | """Creates a specified model 24 | 25 | Arguments: 26 | name (str): name of model, i.e. 'yolov7' 27 | pretrained (bool): load pretrained weights into the model 28 | channels (int): number of input channels 29 | classes (int): number of model classes 30 | 31 | Returns: 32 | pytorch model 33 | """ 34 | try: 35 | cfg = list((Path(__file__).parent / 'cfg').rglob(f'{name}.yaml'))[0] # model.yaml path 36 | model = Model(cfg, channels, classes) 37 | if pretrained: 38 | fname = f'{name}.pt' # checkpoint filename 39 | attempt_download(fname) # download if not found locally 40 | ckpt = torch.load(fname, map_location=torch.device('cpu')) # load 41 | msd = model.state_dict() # model state_dict 42 | csd = ckpt['model'].float().state_dict() # checkpoint state_dict as FP32 43 | csd = {k: v for k, v in csd.items() if msd[k].shape == v.shape} # filter 44 | model.load_state_dict(csd, strict=False) # load 45 | if len(ckpt['model'].names) == classes: 46 | model.names = ckpt['model'].names # set class names attribute 47 | if autoshape: 48 | model = model.autoshape() # for file/URI/PIL/cv2/np inputs and NMS 49 | device = select_device('0' if torch.cuda.is_available() else 'cpu') # default to GPU if available 50 | return model.to(device) 51 | 52 | except Exception as e: 53 | s = 'Cache maybe be out of date, try force_reload=True.' 54 | raise Exception(s) from e 55 | 56 | 57 | def custom(path_or_model='path/to/model.pt', autoshape=True): 58 | """custom mode 59 | 60 | Arguments (3 options): 61 | path_or_model (str): 'path/to/model.pt' 62 | path_or_model (dict): torch.load('path/to/model.pt') 63 | path_or_model (nn.Module): torch.load('path/to/model.pt')['model'] 64 | 65 | Returns: 66 | pytorch model 67 | """ 68 | model = torch.load(path_or_model) if isinstance(path_or_model, str) else path_or_model # load checkpoint 69 | if isinstance(model, dict): 70 | model = model['ema' if model.get('ema') else 'model'] # load model 71 | 72 | hub_model = Model(model.yaml).to(next(model.parameters()).device) # create 73 | hub_model.load_state_dict(model.float().state_dict()) # load state_dict 74 | hub_model.names = model.names # class names 75 | if autoshape: 76 | hub_model = hub_model.autoshape() # for file/URI/PIL/cv2/np inputs and NMS 77 | device = select_device('0' if torch.cuda.is_available() else 'cpu') # default to GPU if available 78 | return hub_model.to(device) 79 | 80 | 81 | def yolov7(pretrained=True, channels=3, classes=80, autoshape=True): 82 | return create('yolov7', pretrained, channels, classes, autoshape) 83 | 84 | 85 | if __name__ == '__main__': 86 | model = custom(path_or_model='yolov7.pt') # custom example 87 | # model = create(name='yolov7', pretrained=True, channels=3, classes=80, autoshape=True) # pretrained example 88 | 89 | # Verify inference 90 | import numpy as np 91 | from PIL import Image 92 | 93 | imgs = [np.zeros((640, 480, 3))] 94 | 95 | results = model(imgs) # batched inference 96 | results.print() 97 | results.save() 98 | -------------------------------------------------------------------------------- /inference/images/horses.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/inference/images/horses.jpg -------------------------------------------------------------------------------- /models/__init__.py: -------------------------------------------------------------------------------- 1 | # init -------------------------------------------------------------------------------- /models/experimental.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import torch 3 | import torch.nn as nn 4 | 5 | from models.common import Conv, DWConv 6 | from utils.google_utils import attempt_download 7 | 8 | 9 | class CrossConv(nn.Module): 10 | # Cross Convolution Downsample 11 | def __init__(self, c1, c2, k=3, s=1, g=1, e=1.0, shortcut=False): 12 | # ch_in, ch_out, kernel, stride, groups, expansion, shortcut 13 | super(CrossConv, self).__init__() 14 | c_ = int(c2 * e) # hidden channels 15 | self.cv1 = Conv(c1, c_, (1, k), (1, s)) 16 | self.cv2 = Conv(c_, c2, (k, 1), (s, 1), g=g) 17 | self.add = shortcut and c1 == c2 18 | 19 | def forward(self, x): 20 | return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x)) 21 | 22 | 23 | class Sum(nn.Module): 24 | # Weighted sum of 2 or more layers https://arxiv.org/abs/1911.09070 25 | def __init__(self, n, weight=False): # n: number of inputs 26 | super(Sum, self).__init__() 27 | self.weight = weight # apply weights boolean 28 | self.iter = range(n - 1) # iter object 29 | if weight: 30 | self.w = nn.Parameter(-torch.arange(1., n) / 2, requires_grad=True) # layer weights 31 | 32 | def forward(self, x): 33 | y = x[0] # no weight 34 | if self.weight: 35 | w = torch.sigmoid(self.w) * 2 36 | for i in self.iter: 37 | y = y + x[i + 1] * w[i] 38 | else: 39 | for i in self.iter: 40 | y = y + x[i + 1] 41 | return y 42 | 43 | 44 | class MixConv2d(nn.Module): 45 | # Mixed Depthwise Conv https://arxiv.org/abs/1907.09595 46 | def __init__(self, c1, c2, k=(1, 3), s=1, equal_ch=True): 47 | super(MixConv2d, self).__init__() 48 | groups = len(k) 49 | if equal_ch: # equal c_ per group 50 | i = torch.linspace(0, groups - 1E-6, c2).floor() # c2 indices 51 | c_ = [(i == g).sum() for g in range(groups)] # intermediate channels 52 | else: # equal weight.numel() per group 53 | b = [c2] + [0] * groups 54 | a = np.eye(groups + 1, groups, k=-1) 55 | a -= np.roll(a, 1, axis=1) 56 | a *= np.array(k) ** 2 57 | a[0] = 1 58 | c_ = np.linalg.lstsq(a, b, rcond=None)[0].round() # solve for equal weight indices, ax = b 59 | 60 | self.m = nn.ModuleList([nn.Conv2d(c1, int(c_[g]), k[g], s, k[g] // 2, bias=False) for g in range(groups)]) 61 | self.bn = nn.BatchNorm2d(c2) 62 | self.act = nn.LeakyReLU(0.1, inplace=True) 63 | 64 | def forward(self, x): 65 | return x + self.act(self.bn(torch.cat([m(x) for m in self.m], 1))) 66 | 67 | 68 | class Ensemble(nn.ModuleList): 69 | # Ensemble of models 70 | def __init__(self): 71 | super(Ensemble, self).__init__() 72 | 73 | def forward(self, x, augment=False): 74 | y = [] 75 | for module in self: 76 | y.append(module(x, augment)[0]) 77 | # y = torch.stack(y).max(0)[0] # max ensemble 78 | # y = torch.stack(y).mean(0) # mean ensemble 79 | y = torch.cat(y, 1) # nms ensemble 80 | return y, None # inference, train output 81 | 82 | 83 | def attempt_load(weights, map_location=None): 84 | # Loads an ensemble of models weights=[a,b,c] or a single model weights=[a] or weights=a 85 | model = Ensemble() 86 | for w in weights if isinstance(weights, list) else [weights]: 87 | # attempt_download(w) 88 | ckpt = torch.load(w, map_location=map_location) # load 89 | model.append(ckpt['ema' if ckpt.get('ema') else 'model'].float().fuse().eval()) # FP32 model 90 | 91 | # Compatibility updates 92 | for m in model.modules(): 93 | if type(m) in [nn.Hardswish, nn.LeakyReLU, nn.ReLU, nn.ReLU6, nn.SiLU]: 94 | m.inplace = True # pytorch 1.7.0 compatibility 95 | elif type(m) is nn.Upsample: 96 | m.recompute_scale_factor = None # torch 1.11.0 compatibility 97 | elif type(m) is Conv: 98 | m._non_persistent_buffers_set = set() # pytorch 1.6.0 compatibility 99 | 100 | if len(model) == 1: 101 | return model[-1] # return model 102 | else: 103 | print('Ensemble created with %s\n' % weights) 104 | for k in ['names', 'stride']: 105 | setattr(model, k, getattr(model[-1], k)) 106 | return model # return ensemble 107 | -------------------------------------------------------------------------------- /models/export.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import sys 3 | import time 4 | 5 | sys.path.append('./') # to run '$ python *.py' files in subdirectories 6 | 7 | import torch 8 | import torch.nn as nn 9 | 10 | import models 11 | from models.experimental import attempt_load 12 | from utils.activations import Hardswish, SiLU 13 | from utils.general import set_logging, check_img_size 14 | from utils.torch_utils import select_device 15 | 16 | if __name__ == '__main__': 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument('--weights', type=str, default='./yolor-csp-c.pt', help='weights path') 19 | parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='image size') # height, width 20 | parser.add_argument('--batch-size', type=int, default=1, help='batch size') 21 | parser.add_argument('--dynamic', action='store_true', help='dynamic ONNX axes') 22 | parser.add_argument('--grid', action='store_true', help='export Detect() layer grid') 23 | parser.add_argument('--device', default='cpu', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') 24 | opt = parser.parse_args() 25 | opt.img_size *= 2 if len(opt.img_size) == 1 else 1 # expand 26 | print(opt) 27 | set_logging() 28 | t = time.time() 29 | 30 | # Load PyTorch model 31 | device = select_device(opt.device) 32 | model = attempt_load(opt.weights, map_location=device) # load FP32 model 33 | labels = model.names 34 | 35 | # Checks 36 | gs = int(max(model.stride)) # grid size (max stride) 37 | opt.img_size = [check_img_size(x, gs) for x in opt.img_size] # verify img_size are gs-multiples 38 | 39 | # Input 40 | img = torch.zeros(opt.batch_size, 3, *opt.img_size).to(device) # image size(1,3,320,192) iDetection 41 | 42 | # Update model 43 | for k, m in model.named_modules(): 44 | m._non_persistent_buffers_set = set() # pytorch 1.6.0 compatibility 45 | if isinstance(m, models.common.Conv): # assign export-friendly activations 46 | if isinstance(m.act, nn.Hardswish): 47 | m.act = Hardswish() 48 | elif isinstance(m.act, nn.SiLU): 49 | m.act = SiLU() 50 | # elif isinstance(m, models.yolo.Detect): 51 | # m.forward = m.forward_export # assign forward (optional) 52 | model.model[-1].export = not opt.grid # set Detect() layer grid export 53 | y = model(img) # dry run 54 | 55 | # TorchScript export 56 | try: 57 | print('\nStarting TorchScript export with torch %s...' % torch.__version__) 58 | f = opt.weights.replace('.pt', '.torchscript.pt') # filename 59 | ts = torch.jit.trace(model, img, strict=False) 60 | ts.save(f) 61 | print('TorchScript export success, saved as %s' % f) 62 | except Exception as e: 63 | print('TorchScript export failure: %s' % e) 64 | 65 | # ONNX export 66 | try: 67 | import onnx 68 | 69 | print('\nStarting ONNX export with onnx %s...' % onnx.__version__) 70 | f = opt.weights.replace('.pt', '.onnx') # filename 71 | torch.onnx.export(model, img, f, verbose=False, opset_version=12, input_names=['images'], 72 | output_names=['classes', 'boxes'] if y is None else ['output'], 73 | dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'}, # size(1,3,640,640) 74 | 'output': {0: 'batch', 2: 'y', 3: 'x'}} if opt.dynamic else None) 75 | 76 | # Checks 77 | onnx_model = onnx.load(f) # load onnx model 78 | onnx.checker.check_model(onnx_model) # check onnx model 79 | # print(onnx.helper.printable_graph(onnx_model.graph)) # print a human readable model 80 | print('ONNX export success, saved as %s' % f) 81 | except Exception as e: 82 | print('ONNX export failure: %s' % e) 83 | 84 | # CoreML export 85 | try: 86 | import coremltools as ct 87 | 88 | print('\nStarting CoreML export with coremltools %s...' % ct.__version__) 89 | # convert model from torchscript and apply pixel scaling as per detect.py 90 | model = ct.convert(ts, inputs=[ct.ImageType(name='image', shape=img.shape, scale=1 / 255.0, bias=[0, 0, 0])]) 91 | f = opt.weights.replace('.pt', '.mlmodel') # filename 92 | model.save(f) 93 | print('CoreML export success, saved as %s' % f) 94 | except Exception as e: 95 | print('CoreML export failure: %s' % e) 96 | 97 | # Finish 98 | print('\nExport complete (%.2fs). Visualize with https://github.com/lutzroeder/netron.' % (time.time() - t)) 99 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | cython-bbox==0.1.3 3 | loguru 4 | motmetrics==1.4.0 5 | ninja 6 | 7 | pandas 8 | Pillow 9 | 10 | PyYAML 11 | 12 | scikit-learn 13 | scipy 14 | seaborn 15 | 16 | thop 17 | tensorboard 18 | lap 19 | tabulate 20 | tqdm 21 | 22 | wandb 23 | 24 | gdown 25 | -------------------------------------------------------------------------------- /scripts/get_coco.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # COCO 2017 dataset http://cocodataset.org 3 | # Download command: bash ./scripts/get_coco.sh 4 | 5 | # Download/unzip labels 6 | d='./' # unzip directory 7 | url=https://github.com/ultralytics/yolov5/releases/download/v1.0/ 8 | f='coco2017labels-segments.zip' # or 'coco2017labels.zip', 68 MB 9 | echo 'Downloading' $url$f ' ...' 10 | curl -L $url$f -o $f && unzip -q $f -d $d && rm $f & # download, unzip, remove in background 11 | 12 | # Download/unzip images 13 | d='./coco/images' # unzip directory 14 | url=http://images.cocodataset.org/zips/ 15 | f1='train2017.zip' # 19G, 118k images 16 | f2='val2017.zip' # 1G, 5k images 17 | f3='test2017.zip' # 7G, 41k images (optional) 18 | for f in $f1 $f2 $f3; do 19 | echo 'Downloading' $url$f '...' 20 | curl -L $url$f -o $f && unzip -q $f -d $d && rm $f & # download, unzip, remove in background 21 | done 22 | wait # finish background tasks 23 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M0101.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.8979905814549864 -0.39754048571901224 0.18861197690610634 3 | -0.11475152919221074 -0.6253973983846266 -0.7718226354816174 4 | 0.4247881850595499 0.6714459444423146 -0.607219352067917 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M0202.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.9032157300195275 -0.42859525452700087 0.02252671396874304 3 | -0.19012553250747607 -0.44662008618260757 -0.8742898721287973 4 | 0.3847773732095512 0.7853894616145389 -0.4848811881799312 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M0203.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.9184529838275687 -0.3941594264594937 -0.032900805937865915 3 | -0.33168018518486475 -0.7222023632569826 -0.6069695225147331 4 | 0.21548171907141328 0.5683855144522528 -0.7940437870211415 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M0402.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.9900225296679271 0.13563763189861872 0.03818145574562663 3 | 0.09507946439276654 -0.4430504618529409 -0.8914405104675692 4 | -0.10399656821599908 0.8861764615835999 -0.45152629240661585 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M0601.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.9965360219425241 0.07908685280531619 -0.025714328385584462 3 | 0.009986822246025843 -0.42077701740785656 -0.9071091251898942 4 | -0.08256040426498443 0.9037101146577359 -0.4201092813934298 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 725 0 512 11 | 0 725 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M0604.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.999783748579928 -0.008142098538121654 -0.019135367957401395 3 | -0.020538893739341778 -0.242485078238191 -0.9699376993785647 4 | 0.003257287127912365 0.9701209682628312 -0.24259987019236565 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M1002.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.958995837118094 0.2784639208312455 -0.05277148079653312 3 | 0.0558475988637905 -0.3682090522307261 -0.9280641893514154 4 | -0.2778633298787693 0.887062533675411 -0.36866248962708675 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M1003.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.997881807190502 -0.009330599286301164 -0.06438042245263502 3 | -0.058971643889622644 -0.5475526162640636 -0.8346906478686194 4 | -0.027463504786840724 0.8367192314864867 -0.5469430350278591 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M1008.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.9941156935168154 0.06039358449950929 -0.08992554061491932 3 | -0.036689756467594016 -0.5933614281160473 -0.8040995444560548 4 | -0.10192080098749955 0.8026673224788619 -0.5876540817102196 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/cam_param_files/uavdt/M1202.txt: -------------------------------------------------------------------------------- 1 | RotationMatrices 2 | 0.9993294906377356 -0.012829960883434719 -0.03429229134160642 3 | -0.03522538794712723 -0.5923724138185908 -0.80489384106894 4 | -0.009987050901165704 0.8055621114789755 -0.592427162918643 5 | 6 | TranslationVectors 7 | 0 1000 33640 8 | 9 | IntrinsicMatrix 10 | 1000 0 512 11 | 0 1000 270 12 | 0 0 1 13 | -------------------------------------------------------------------------------- /tracker/config_files/mot17.yaml: -------------------------------------------------------------------------------- 1 | # Config file of MOT17 dataset 2 | 3 | DATASET_ROOT: '/data/wujiapeng/datasets/MOT17' # your dataset root 4 | SPLIT: test 5 | CATEGORY_NAMES: # category names to show 6 | - 'pedestrian' 7 | 8 | CATEGORY_DICT: 9 | 0: 'pedestrian' 10 | 11 | CERTAIN_SEQS: 12 | - 13 | IGNORE_SEQS: # Seqs you want to ignore 14 | - 15 | 16 | YAML_DICT: '' # NOTE: ONLY for yolo v5 model loader(func DetectMultiBackend) 17 | 18 | TRACK_EVAL: # If use TrackEval to evaluate, use these configs 19 | 'DISPLAY_LESS_PROGRESS': False 20 | 'GT_FOLDER': '/data/wujiapeng/datasets/MOT17/train' 21 | 'TRACKERS_FOLDER': './tracker/results' 22 | 'SKIP_SPLIT_FOL': True 23 | 'TRACKER_SUB_FOLDER': '' 24 | 'SEQ_INFO': 25 | 'MOT17-02-SDP': null 26 | 'MOT17-04-SDP': null 27 | 'MOT17-05-SDP': null 28 | 'MOT17-09-SDP': null 29 | 'MOT17-10-SDP': null 30 | 'MOT17-11-SDP': null 31 | 'MOT17-13-SDP': null 32 | 'GT_LOC_FORMAT': '{gt_folder}/{seq}/gt/gt.txt' 33 | -------------------------------------------------------------------------------- /tracker/config_files/uavdt.yaml: -------------------------------------------------------------------------------- 1 | # Config file of UAVDT dataset 2 | 3 | DATASET_ROOT: '/data/wujiapeng/datasets/UAVDT' # your dataset root 4 | SPLIT: test 5 | CATEGORY_NAMES: # category names to show 6 | - 'car' 7 | 8 | CATEGORY_DICT: 9 | 0: 'car' 10 | 11 | CERTAIN_SEQS: 12 | - 13 | IGNORE_SEQS: # Seqs you want to ignore 14 | - 15 | 16 | YAML_DICT: './data/UAVDT.yaml' # NOTE: ONLY for yolo v5 model loader(func DetectMultiBackend) 17 | 18 | TRACK_EVAL: # If use TrackEval to evaluate, use these configs 19 | 'DISPLAY_LESS_PROGRESS': False 20 | 'GT_FOLDER': '/data/wujiapeng/datasets/UAVDT/UAV-benchmark-M' 21 | 'TRACKERS_FOLDER': './tracker/results' 22 | 'SKIP_SPLIT_FOL': True 23 | 'TRACKER_SUB_FOLDER': '' 24 | 'SEQ_INFO': 25 | 'M0101': 407 26 | 'GT_LOC_FORMAT': '{gt_folder}/{seq}/gt/gt.txt' -------------------------------------------------------------------------------- /tracker/config_files/visdrone.yaml: -------------------------------------------------------------------------------- 1 | # Config file of VisDrone dataset 2 | 3 | DATASET_ROOT: '/data/wujiapeng/datasets/VisDrone2019/VisDrone2019' 4 | SPLIT: test 5 | CATEGORY_NAMES: 6 | - 'pedestrain' 7 | - 'people' 8 | - 'bicycle' 9 | - 'car' 10 | - 'van' 11 | - 'truck' 12 | - 'tricycle' 13 | - 'awning-tricycle' 14 | - 'bus' 15 | - 'motor' 16 | 17 | CATEGORY_DICT: 18 | 0: 'pedestrain' 19 | 1: 'people' 20 | 2: 'bicycle' 21 | 3: 'car' 22 | 4: 'van' 23 | 5: 'truck' 24 | 6: 'tricycle' 25 | 7: 'awning-tricycle' 26 | 8: 'bus' 27 | 9: 'motor' 28 | 29 | CERTAIN_SEQS: 30 | - 31 | 32 | IGNORE_SEQS: # Seqs you want to ignore 33 | - 34 | 35 | YAML_DICT: './data/Visdrone_all.yaml' # NOTE: ONLY for yolo v5 model loader(func DetectMultiBackend) 36 | 37 | TRACK_EVAL: # If use TrackEval to evaluate, use these configs 38 | 'DISPLAY_LESS_PROGRESS': False 39 | 'GT_FOLDER': '/data/wujiapeng/datasets/VisDrone2019/VisDrone2019/VisDrone2019-MOT-test-dev/annotations' 40 | 'TRACKERS_FOLDER': './tracker/results' 41 | 'SKIP_SPLIT_FOL': True 42 | 'TRACKER_SUB_FOLDER': '' 43 | 'SEQ_INFO': 44 | 'uav0000009_03358_v': 219 45 | 'uav0000073_00600_v': 328 46 | 'uav0000073_04464_v': 312 47 | 'uav0000077_00720_v': 780 48 | 'uav0000088_00290_v': 296 49 | 'uav0000119_02301_v': 179 50 | 'uav0000120_04775_v': 1000 51 | 'uav0000161_00000_v': 308 52 | 'uav0000188_00000_v': 260 53 | 'uav0000201_00000_v': 677 54 | 'uav0000249_00001_v': 360 55 | 'uav0000249_02688_v': 244 56 | 'uav0000297_00000_v': 146 57 | 'uav0000297_02761_v': 373 58 | 'uav0000306_00230_v': 420 59 | 'uav0000355_00001_v': 468 60 | 'uav0000370_00001_v': 265 61 | 'GT_LOC_FORMAT': '{gt_folder}/{seq}.txt' -------------------------------------------------------------------------------- /tracker/config_files/visdrone_part.yaml: -------------------------------------------------------------------------------- 1 | # Config file of VisDrone dataset 2 | 3 | DATASET_ROOT: '/data/wujiapeng/datasets/VisDrone2019/VisDrone2019' 4 | SPLIT: val 5 | CATEGORY_NAMES: 6 | - 'pedestrain' 7 | - 'car' 8 | - 'van' 9 | - 'truck' 10 | - 'bus' 11 | 12 | CATEGORY_DICT: 13 | 0: 'pedestrain' 14 | 1: 'car' 15 | 2: 'van' 16 | 3: 'truck' 17 | 4: 'bus' 18 | 19 | CERTAIN_SEQS: 20 | - 21 | 22 | IGNORE_SEQS: # Seqs you want to ignore 23 | - 24 | 25 | YAML_DICT: './data/Visdrone_all.yaml' # NOTE: ONLY for yolo v5 model loader(func DetectMultiBackend) 26 | 27 | TRACK_EVAL: # If use TrackEval to evaluate, use these configs 28 | 'DISPLAY_LESS_PROGRESS': False 29 | 'GT_FOLDER': '/data/wujiapeng/datasets/VisDrone2019/VisDrone2019/VisDrone2019-MOT-test-dev/annotations' 30 | 'TRACKERS_FOLDER': './tracker/results' 31 | 'SKIP_SPLIT_FOL': True 32 | 'TRACKER_SUB_FOLDER': '' 33 | 'SEQ_INFO': 34 | 'uav0000009_03358_v': 219 35 | 'uav0000073_00600_v': 328 36 | 'uav0000073_04464_v': 312 37 | 'uav0000077_00720_v': 780 38 | 'uav0000088_00290_v': 296 39 | 'uav0000119_02301_v': 179 40 | 'uav0000120_04775_v': 1000 41 | 'uav0000161_00000_v': 308 42 | 'uav0000188_00000_v': 260 43 | 'uav0000201_00000_v': 677 44 | 'uav0000249_00001_v': 360 45 | 'uav0000249_02688_v': 244 46 | 'uav0000297_00000_v': 146 47 | 'uav0000297_02761_v': 373 48 | 'uav0000306_00230_v': 420 49 | 'uav0000355_00001_v': 468 50 | 'uav0000370_00001_v': 265 51 | 'GT_LOC_FORMAT': '{gt_folder}/{seq}.txt' -------------------------------------------------------------------------------- /tracker/my_timer.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | 4 | class Timer(object): 5 | """A simple timer.""" 6 | def __init__(self): 7 | self.total_time = 0. 8 | self.calls = 0 9 | self.start_time = 0. 10 | self.diff = 0. 11 | self.average_time = 0. 12 | 13 | self.duration = 0. 14 | 15 | def tic(self): 16 | # using time.time instead of time.clock because time time.clock 17 | # does not normalize for multithreading 18 | self.start_time = time.time() 19 | 20 | def toc(self, average=True): 21 | self.diff = time.time() - self.start_time 22 | self.total_time += self.diff 23 | self.calls += 1 24 | self.average_time = self.total_time / self.calls 25 | if average: 26 | self.duration = self.average_time 27 | else: 28 | self.duration = self.diff 29 | return self.duration 30 | 31 | def clear(self): 32 | self.total_time = 0. 33 | self.calls = 0 34 | self.start_time = 0. 35 | self.diff = 0. 36 | self.average_time = 0. 37 | self.duration = 0. -------------------------------------------------------------------------------- /tracker/trackers/basetrack.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from collections import OrderedDict 3 | 4 | 5 | class TrackState(object): 6 | New = 0 7 | Tracked = 1 8 | Lost = 2 9 | Removed = 3 10 | 11 | 12 | class BaseTrack(object): 13 | _count = 0 14 | 15 | track_id = 0 16 | is_activated = False 17 | state = TrackState.New 18 | 19 | history = OrderedDict() 20 | features = [] 21 | curr_feature = None 22 | score = 0 23 | start_frame = 0 24 | frame_id = 0 25 | time_since_update = 0 26 | 27 | # multi-camera 28 | location = (np.inf, np.inf) 29 | 30 | @property 31 | def end_frame(self): 32 | return self.frame_id 33 | 34 | @staticmethod 35 | def next_id(): 36 | BaseTrack._count += 1 37 | return BaseTrack._count 38 | 39 | @staticmethod 40 | def clear_count(): 41 | BaseTrack._count = 0 42 | 43 | def activate(self, *args): 44 | raise NotImplementedError 45 | 46 | def predict(self): 47 | raise NotImplementedError 48 | 49 | def update(self, *args, **kwargs): 50 | raise NotImplementedError 51 | 52 | def mark_lost(self): 53 | self.state = TrackState.Lost 54 | 55 | def mark_removed(self): 56 | self.state = TrackState.Removed 57 | 58 | @property 59 | def tlwh(self): 60 | """Get current position in bounding box format `(top left x, top left y, 61 | width, height)`. 62 | """ 63 | raise NotImplementedError # implented in class Tracklet(BaseTrack) 64 | 65 | @property 66 | def tlbr(self): 67 | """Convert bounding box to format `(min x, min y, max x, max y)`, i.e., 68 | `(top left, bottom right)`. 69 | """ 70 | ret = self.tlwh.copy() 71 | ret[2:] += ret[:2] 72 | return ret 73 | @property 74 | def xywh(self): 75 | """Convert bounding box to format `(min x, min y, max x, max y)`, i.e., 76 | `(top left, bottom right)`. 77 | """ 78 | ret = self.tlwh.copy() 79 | ret[:2] += ret[2:] / 2.0 80 | return ret 81 | 82 | @staticmethod 83 | # @jit(nopython=True) 84 | def tlwh_to_xyah(tlwh): 85 | """Convert bounding box to format `(center x, center y, aspect ratio, 86 | height)`, where the aspect ratio is `width / height`. 87 | """ 88 | ret = np.asarray(tlwh).copy() 89 | ret[:2] += ret[2:] / 2 90 | ret[2] /= ret[3] 91 | return ret 92 | 93 | @staticmethod 94 | def tlwh_to_xywh(tlwh): 95 | """Convert bounding box to format `(center x, center y, width, 96 | height)`. 97 | """ 98 | ret = np.asarray(tlwh).copy() 99 | ret[:2] += ret[2:] / 2 100 | return ret 101 | 102 | @staticmethod 103 | def tlwh_to_xysa(tlwh): 104 | """Convert bounding box to format `(center x, center y, width, 105 | height)`. 106 | """ 107 | ret = np.asarray(tlwh).copy() 108 | ret[:2] += ret[2:] / 2 109 | ret[2] = tlwh[2] * tlwh[3] 110 | ret[3] = tlwh[2] / tlwh[3] 111 | return ret 112 | 113 | @staticmethod 114 | def tlbr_to_tlwh(tlbr): 115 | ret = np.asarray(tlbr).copy() 116 | ret[2:] -= ret[:2] 117 | return ret 118 | 119 | @staticmethod 120 | # @jit(nopython=True) 121 | def tlwh_to_tlbr(tlwh): 122 | ret = np.asarray(tlwh).copy() 123 | ret[2:] += ret[:2] 124 | return ret 125 | 126 | def to_xyah(self): 127 | return self.tlwh_to_xyah(self.tlwh) 128 | 129 | def to_xywh(self): 130 | return self.tlwh_to_xywh(self.tlwh) 131 | 132 | def __repr__(self): 133 | return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame, self.end_frame) 134 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/base_kalman.py: -------------------------------------------------------------------------------- 1 | from filterpy.kalman import KalmanFilter 2 | import numpy as np 3 | import scipy 4 | 5 | class BaseKalman: 6 | 7 | def __init__(self, 8 | state_dim: int = 8, 9 | observation_dim: int = 4, 10 | F: np.ndarray = np.zeros((0, )), 11 | P: np.ndarray = np.zeros((0, )), 12 | Q: np.ndarray = np.zeros((0, )), 13 | H: np.ndarray = np.zeros((0, )), 14 | R: np.ndarray = np.zeros((0, )), 15 | ) -> None: 16 | 17 | self.kf = KalmanFilter(dim_x=state_dim, dim_z=observation_dim, dim_u=0) 18 | if F.shape[0] > 0: self.kf.F = F # if valid 19 | if P.shape[0] > 0: self.kf.P = P 20 | if Q.shape[0] > 0: self.kf.Q = Q 21 | if H.shape[0] > 0: self.kf.H = H 22 | if R.shape[0] > 0: self.kf.R = R 23 | 24 | def initialize(self, observation): 25 | return NotImplementedError 26 | 27 | def predict(self, ): 28 | self.kf.predict() 29 | 30 | def update(self, observation, **kwargs): 31 | self.kf.update(observation, self.R, self.H) 32 | 33 | def get_state(self, ): 34 | return self.kf.x 35 | 36 | def gating_distance(self, measurements, only_position=False): 37 | """Compute gating distance between state distribution and measurements. 38 | A suitable distance threshold can be obtained from `chi2inv95`. If 39 | `only_position` is False, the chi-square distribution has 4 degrees of 40 | freedom, otherwise 2. 41 | Parameters 42 | ---------- 43 | measurements : ndarray 44 | An Nx4 dimensional matrix of N measurements, note the format (whether xywh or xyah or others) 45 | should be identical to state definition 46 | only_position : Optional[bool] 47 | If True, distance computation is done with respect to the bounding 48 | box center position only. 49 | Returns 50 | ------- 51 | ndarray 52 | Returns an array of length N, where the i-th element contains the 53 | squared Mahalanobis distance between (mean, covariance) and 54 | `measurements[i]`. 55 | """ 56 | 57 | # map state space to measurement space 58 | mean = self.kf.x.copy() 59 | mean = np.dot(self.kf.H, mean) 60 | covariance = np.linalg.multi_dot((self.kf.H, self.kf.P, self.kf.H.T)) 61 | 62 | if only_position: 63 | mean, covariance = mean[:2], covariance[:2, :2] 64 | measurements = measurements[:, :2] 65 | 66 | cholesky_factor = np.linalg.cholesky(covariance) 67 | d = measurements - mean 68 | z = scipy.linalg.solve_triangular( 69 | cholesky_factor, d.T, lower=True, check_finite=False, 70 | overwrite_b=True) 71 | squared_maha = np.sum(z * z, axis=0) 72 | return squared_maha 73 | 74 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/botsort_kalman.py: -------------------------------------------------------------------------------- 1 | from numpy.core.multiarray import zeros as zeros 2 | from .base_kalman import BaseKalman 3 | import numpy as np 4 | import cv2 5 | 6 | class BotKalman(BaseKalman): 7 | 8 | def __init__(self, ): 9 | 10 | state_dim = 8 # [x, y, w, h, vx, vy, vw, vh] 11 | observation_dim = 4 12 | 13 | F = np.eye(state_dim, state_dim) 14 | ''' 15 | [1, 0, 0, 0, 1, 0, 0, 0] 16 | [0, 1, 0, 0, 0, 1, 0, 0] 17 | ... 18 | ''' 19 | for i in range(state_dim // 2): 20 | F[i, i + state_dim // 2] = 1 21 | 22 | H = np.eye(state_dim // 2, state_dim) 23 | 24 | super().__init__(state_dim=state_dim, 25 | observation_dim=observation_dim, 26 | F=F, 27 | H=H) 28 | 29 | self._std_weight_position = 1. / 20 30 | self._std_weight_velocity = 1. / 160 31 | 32 | def initialize(self, observation): 33 | """ init x, P, Q, R 34 | 35 | Args: 36 | observation: x-y-w-h format 37 | """ 38 | # init x, P, Q, R 39 | 40 | mean_pos = observation 41 | mean_vel = np.zeros_like(observation) 42 | self.kf.x = np.r_[mean_pos, mean_vel] # x_{0, 0} 43 | 44 | std = [ 45 | 2 * self._std_weight_position * observation[2], # related to h 46 | 2 * self._std_weight_position * observation[3], 47 | 2 * self._std_weight_position * observation[2], 48 | 2 * self._std_weight_position * observation[3], 49 | 10 * self._std_weight_velocity * observation[2], 50 | 10 * self._std_weight_velocity * observation[3], 51 | 10 * self._std_weight_velocity * observation[2], 52 | 10 * self._std_weight_velocity * observation[3], 53 | ] 54 | 55 | self.kf.P = np.diag(np.square(std)) # P_{0, 0} 56 | 57 | def predict(self, is_activated=True): 58 | """ predict step 59 | 60 | x_{n + 1, n} = F * x_{n, n} 61 | P_{n + 1, n} = F * P_{n, n} * F^T + Q 62 | 63 | """ 64 | 65 | if not is_activated: 66 | # if not activated, set the velocity of w and h to 0 67 | self.kf.x[6] = 0.0 68 | self.kf.x[7] = 0.0 69 | 70 | std_pos = [ 71 | self._std_weight_position * self.kf.x[2], 72 | self._std_weight_position * self.kf.x[3], 73 | self._std_weight_position * self.kf.x[2], 74 | self._std_weight_position * self.kf.x[3]] 75 | std_vel = [ 76 | self._std_weight_velocity * self.kf.x[2], 77 | self._std_weight_velocity * self.kf.x[3], 78 | self._std_weight_velocity * self.kf.x[2], 79 | self._std_weight_velocity * self.kf.x[3]] 80 | 81 | Q = np.diag(np.square(np.r_[std_pos, std_vel])) 82 | 83 | self.kf.predict(Q=Q) 84 | 85 | def update(self, z): 86 | """ update step 87 | 88 | Args: 89 | z: observation x-y-w-h format 90 | 91 | K_n = P_{n, n - 1} * H^T * (H P_{n, n - 1} H^T + R)^{-1} 92 | x_{n, n} = x_{n, n - 1} + K_n * (z - H * x_{n, n - 1}) 93 | P_{n, n} = (I - K_n * H) P_{n, n - 1} (I - K_n * H)^T + K_n R_n 94 | 95 | """ 96 | 97 | std = [ 98 | self._std_weight_position * self.kf.x[2], 99 | self._std_weight_position * self.kf.x[3], 100 | self._std_weight_position * self.kf.x[2], 101 | self._std_weight_position * self.kf.x[3]] 102 | 103 | R = np.diag(np.square(std)) 104 | 105 | self.kf.update(z=z, R=R) 106 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/bytetrack_kalman.py: -------------------------------------------------------------------------------- 1 | from .base_kalman import BaseKalman 2 | import numpy as np 3 | 4 | class ByteKalman(BaseKalman): 5 | 6 | def __init__(self, ): 7 | 8 | state_dim = 8 # [x, y, a, h, vx, vy, va, vh] 9 | observation_dim = 4 10 | 11 | F = np.eye(state_dim, state_dim) 12 | ''' 13 | [1, 0, 0, 0, 1, 0, 0] 14 | [0, 1, 0, 0, 0, 1, 0] 15 | ... 16 | ''' 17 | for i in range(state_dim // 2): 18 | F[i, i + state_dim // 2] = 1 19 | 20 | H = np.eye(state_dim // 2, state_dim) 21 | 22 | super().__init__(state_dim=state_dim, 23 | observation_dim=observation_dim, 24 | F=F, 25 | H=H) 26 | 27 | self._std_weight_position = 1. / 20 28 | self._std_weight_velocity = 1. / 160 29 | 30 | def initialize(self, observation): 31 | """ init x, P, Q, R 32 | 33 | Args: 34 | observation: x-y-a-h format 35 | """ 36 | # init x, P, Q, R 37 | 38 | mean_pos = observation 39 | mean_vel = np.zeros_like(observation) 40 | self.kf.x = np.r_[mean_pos, mean_vel] # x_{0, 0} 41 | 42 | std = [ 43 | 2 * self._std_weight_position * observation[3], # related to h 44 | 2 * self._std_weight_position * observation[3], 45 | 1e-2, 46 | 2 * self._std_weight_position * observation[3], 47 | 10 * self._std_weight_velocity * observation[3], 48 | 10 * self._std_weight_velocity * observation[3], 49 | 1e-5, 50 | 10 * self._std_weight_velocity * observation[3], 51 | ] 52 | 53 | self.kf.P = np.diag(np.square(std)) # P_{0, 0} 54 | 55 | def predict(self, is_activated=True): 56 | """ predict step 57 | 58 | x_{n + 1, n} = F * x_{n, n} 59 | P_{n + 1, n} = F * P_{n, n} * F^T + Q 60 | 61 | """ 62 | 63 | if not is_activated: 64 | # if not activated, set the velocity of h to 0 65 | self.kf.x[7] = 0.0 66 | 67 | std_pos = [ 68 | self._std_weight_position * self.kf.x[3], 69 | self._std_weight_position * self.kf.x[3], 70 | 1e-2, 71 | self._std_weight_position * self.kf.x[3]] 72 | std_vel = [ 73 | self._std_weight_velocity * self.kf.x[3], 74 | self._std_weight_velocity * self.kf.x[3], 75 | 1e-5, 76 | self._std_weight_velocity * self.kf.x[3]] 77 | 78 | Q = np.diag(np.square(np.r_[std_pos, std_vel])) 79 | 80 | self.kf.predict(Q=Q) 81 | 82 | def update(self, z): 83 | """ update step 84 | 85 | Args: 86 | z: observation x-y-a-h format 87 | 88 | K_n = P_{n, n - 1} * H^T * (H P_{n, n - 1} H^T + R)^{-1} 89 | x_{n, n} = x_{n, n - 1} + K_n * (z - H * x_{n, n - 1}) 90 | P_{n, n} = (I - K_n * H) P_{n, n - 1} (I - K_n * H)^T + K_n R_n 91 | 92 | """ 93 | 94 | std = [ 95 | self._std_weight_position * self.kf.x[3], 96 | self._std_weight_position * self.kf.x[3], 97 | 1e-1, 98 | self._std_weight_position * self.kf.x[3]] 99 | 100 | R = np.diag(np.square(std)) 101 | 102 | self.kf.update(z=z, R=R) 103 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/hybridsort_kalman.py: -------------------------------------------------------------------------------- 1 | from .base_kalman import BaseKalman 2 | import numpy as np 3 | from copy import deepcopy 4 | 5 | class HybridSORTKalman(BaseKalman): 6 | 7 | def __init__(self, ): 8 | 9 | state_dim = 9 # [x, y, s, c, a, vx, vy, vs, vc] s: area c: confidence score 10 | observation_dim = 5 # confidence score is additional 11 | 12 | F = np.eye(state_dim) 13 | for i in range(4): 14 | F[i, (state_dim + 1) // 2 + i] = 1 # x = x + vx, y = y + vy, s = s + vs, c = c + vc in predict step 15 | 16 | H = np.eye(state_dim // 2 + 1, state_dim) 17 | 18 | super().__init__(state_dim=state_dim, 19 | observation_dim=observation_dim, 20 | F=F, 21 | H=H) 22 | 23 | # TODO check 24 | # give high uncertainty to the unobservable initial velocities 25 | self.kf.R[2:, 2:] *= 10 # [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 10, 0], [0, 0, 0, 10]] 26 | self.kf.P[5:, 5:] *= 1000 27 | self.kf.P *= 10 28 | self.kf.Q[-1, -1] *= 0.01 # score 29 | self.kf.Q[-2, -2] *= 0.01 30 | self.kf.Q[5:, 5:] *= 0.01 31 | 32 | def initialize(self, observation): 33 | """ 34 | Args: 35 | observation: x-y-s-c-a 36 | """ 37 | self.kf.x = self.kf.x.flatten() 38 | self.kf.x[:5] = observation 39 | 40 | 41 | def predict(self, is_activated=True): 42 | """ predict step 43 | 44 | """ 45 | 46 | # s + vs 47 | if (self.kf.x[7] + self.kf.x[2] <= 0): 48 | self.kf.x[7] *= 0.0 49 | 50 | self.kf.predict() 51 | 52 | 53 | def update(self, z): 54 | """ update step 55 | 56 | Args: 57 | z: observation x-y-s-a format 58 | """ 59 | 60 | self.kf.update(z) 61 | 62 | 63 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/ocsort_kalman.py: -------------------------------------------------------------------------------- 1 | from .base_kalman import BaseKalman 2 | import numpy as np 3 | from copy import deepcopy 4 | 5 | class OCSORTKalman(BaseKalman): 6 | 7 | def __init__(self, ): 8 | 9 | state_dim = 7 # [x, y, s, a, vx, vy, vs] s: area 10 | observation_dim = 4 11 | 12 | F = np.array([[1, 0, 0, 0, 1, 0, 0], 13 | [0, 1, 0, 0, 0, 1, 0], 14 | [0, 0, 1, 0, 0, 0, 1], 15 | [0, 0, 0, 1, 0, 0, 0], 16 | [0, 0, 0, 0, 1, 0, 0], 17 | [0, 0, 0, 0, 0, 1, 0], 18 | [0, 0, 0, 0, 0, 0, 1]]) 19 | 20 | H = np.eye(state_dim // 2 + 1, state_dim) 21 | 22 | super().__init__(state_dim=state_dim, 23 | observation_dim=observation_dim, 24 | F=F, 25 | H=H) 26 | 27 | # TODO check 28 | # give high uncertainty to the unobservable initial velocities 29 | self.kf.R[2:, 2:] *= 10 # [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 10, 0], [0, 0, 0, 10]] 30 | self.kf.P[4:, 4:] *= 1000 31 | self.kf.P *= 10 32 | self.kf.Q[-1, -1] *= 0.01 33 | self.kf.Q[4:, 4:] *= 0.01 34 | 35 | # keep all observations 36 | self.history_obs = [] 37 | self.attr_saved = None 38 | self.observed = False 39 | 40 | def initialize(self, observation): 41 | """ 42 | Args: 43 | observation: x-y-s-a 44 | """ 45 | self.kf.x = self.kf.x.flatten() 46 | self.kf.x[:4] = observation 47 | 48 | 49 | def predict(self, is_activated=True): 50 | """ predict step 51 | 52 | """ 53 | 54 | # s + vs 55 | if (self.kf.x[6] + self.kf.x[2] <= 0): 56 | self.kf.x[6] *= 0.0 57 | 58 | self.kf.predict() 59 | 60 | def _freeze(self, ): 61 | """ freeze all the param of Kalman 62 | 63 | """ 64 | self.attr_saved = deepcopy(self.kf.__dict__) 65 | 66 | def _unfreeze(self, ): 67 | """ when observe an lost object again, use the virtual trajectory 68 | 69 | """ 70 | if self.attr_saved is not None: 71 | new_history = deepcopy(self.history_obs) 72 | self.kf.__dict__ = self.attr_saved 73 | 74 | self.history_obs = self.history_obs[:-1] 75 | 76 | occur = [int(d is None) for d in new_history] 77 | indices = np.where(np.array(occur)==0)[0] 78 | index1 = indices[-2] 79 | index2 = indices[-1] 80 | box1 = new_history[index1] 81 | x1, y1, s1, r1 = box1 82 | w1 = np.sqrt(s1 * r1) 83 | h1 = np.sqrt(s1 / r1) 84 | box2 = new_history[index2] 85 | x2, y2, s2, r2 = box2 86 | w2 = np.sqrt(s2 * r2) 87 | h2 = np.sqrt(s2 / r2) 88 | time_gap = index2 - index1 89 | dx = (x2-x1)/time_gap 90 | dy = (y2-y1)/time_gap 91 | dw = (w2-w1)/time_gap 92 | dh = (h2-h1)/time_gap 93 | for i in range(index2 - index1): 94 | """ 95 | The default virtual trajectory generation is by linear 96 | motion (constant speed hypothesis), you could modify this 97 | part to implement your own. 98 | """ 99 | x = x1 + (i+1) * dx 100 | y = y1 + (i+1) * dy 101 | w = w1 + (i+1) * dw 102 | h = h1 + (i+1) * dh 103 | s = w * h 104 | r = w / float(h) 105 | new_box = np.array([x, y, s, r]).reshape((4, 1)) 106 | """ 107 | I still use predict-update loop here to refresh the parameters, 108 | but this can be faster by directly modifying the internal parameters 109 | as suggested in the paper. I keep this naive but slow way for 110 | easy read and understanding 111 | """ 112 | self.kf.update(new_box) 113 | if not i == (index2-index1-1): 114 | self.kf.predict() 115 | 116 | 117 | def update(self, z): 118 | """ update step 119 | 120 | For simplicity, directly change the self.kf as OCSORT modify the intrinsic Kalman 121 | 122 | Args: 123 | z: observation x-y-s-a format 124 | """ 125 | 126 | self.history_obs.append(z) 127 | 128 | if z is None: 129 | if self.observed: 130 | self._freeze() 131 | self.observed = False 132 | 133 | self.kf.update(z) 134 | 135 | return 136 | 137 | else: 138 | if not self.observed: # Get observation, use online smoothing to re-update parameters 139 | self._unfreeze() 140 | 141 | self.kf.update(z) 142 | 143 | self.observed = True 144 | 145 | 146 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/sort_kalman.py: -------------------------------------------------------------------------------- 1 | from numpy.core.multiarray import zeros as zeros 2 | from .base_kalman import BaseKalman 3 | import numpy as np 4 | from copy import deepcopy 5 | 6 | class SORTKalman(BaseKalman): 7 | 8 | def __init__(self, ): 9 | 10 | state_dim = 7 # [x, y, s, a, vx, vy, vs] s: area 11 | observation_dim = 4 12 | 13 | F = np.array([[1, 0, 0, 0, 1, 0, 0], 14 | [0, 1, 0, 0, 0, 1, 0], 15 | [0, 0, 1, 0, 0, 0, 1], 16 | [0, 0, 0, 1, 0, 0, 0], 17 | [0, 0, 0, 0, 1, 0, 0], 18 | [0, 0, 0, 0, 0, 1, 0], 19 | [0, 0, 0, 0, 0, 0, 1]]) 20 | 21 | H = np.eye(state_dim // 2 + 1, state_dim) 22 | 23 | super().__init__(state_dim=state_dim, 24 | observation_dim=observation_dim, 25 | F=F, 26 | H=H) 27 | 28 | # TODO check 29 | # give high uncertainty to the unobservable initial velocities 30 | self.kf.R[2:, 2:] *= 10 # [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 10, 0], [0, 0, 0, 10]] 31 | self.kf.P[4:, 4:] *= 1000 32 | self.kf.P *= 10 33 | self.kf.Q[-1, -1] *= 0.01 34 | self.kf.Q[4:, 4:] *= 0.01 35 | 36 | # keep all observations 37 | self.history_obs = [] 38 | self.attr_saved = None 39 | self.observed = False 40 | 41 | def initialize(self, observation): 42 | """ 43 | Args: 44 | observation: x-y-s-a 45 | """ 46 | self.kf.x = self.kf.x.flatten() 47 | self.kf.x[:4] = observation 48 | 49 | 50 | def predict(self, is_activated=True): 51 | """ predict step 52 | 53 | """ 54 | 55 | # s + vs 56 | if (self.kf.x[6] + self.kf.x[2] <= 0): 57 | self.kf.x[6] *= 0.0 58 | 59 | self.kf.predict() 60 | 61 | def update(self, z): 62 | """ update step 63 | 64 | For simplicity, directly change the self.kf as OCSORT modify the intrinsic Kalman 65 | 66 | Args: 67 | z: observation x-y-s-a format 68 | """ 69 | 70 | self.kf.update(z) 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/strongsort_kalman.py: -------------------------------------------------------------------------------- 1 | from .base_kalman import BaseKalman 2 | import numpy as np 3 | 4 | class NSAKalman(BaseKalman): 5 | 6 | def __init__(self, ): 7 | 8 | state_dim = 8 # [x, y, a, h, vx, vy, va, vh] 9 | observation_dim = 4 10 | 11 | F = np.eye(state_dim, state_dim) 12 | ''' 13 | [1, 0, 0, 0, 1, 0, 0] 14 | [0, 1, 0, 0, 0, 1, 0] 15 | ... 16 | ''' 17 | for i in range(state_dim // 2): 18 | F[i, i + state_dim // 2] = 1 19 | 20 | H = np.eye(state_dim // 2, state_dim) 21 | 22 | super().__init__(state_dim=state_dim, 23 | observation_dim=observation_dim, 24 | F=F, 25 | H=H) 26 | 27 | self._std_weight_position = 1. / 20 28 | self._std_weight_velocity = 1. / 160 29 | 30 | def initialize(self, observation): 31 | """ init x, P, Q, R 32 | 33 | Args: 34 | observation: x-y-a-h format 35 | """ 36 | # init x, P, Q, R 37 | 38 | mean_pos = observation 39 | mean_vel = np.zeros_like(observation) 40 | self.kf.x = np.r_[mean_pos, mean_vel] # x_{0, 0} 41 | 42 | std = [ 43 | 2 * self._std_weight_position * observation[3], # related to h 44 | 2 * self._std_weight_position * observation[3], 45 | 1e-2, 46 | 2 * self._std_weight_position * observation[3], 47 | 10 * self._std_weight_velocity * observation[3], 48 | 10 * self._std_weight_velocity * observation[3], 49 | 1e-5, 50 | 10 * self._std_weight_velocity * observation[3], 51 | ] 52 | 53 | self.kf.P = np.diag(np.square(std)) # P_{0, 0} 54 | 55 | def predict(self, is_activated=True): 56 | """ predict step 57 | 58 | x_{n + 1, n} = F * x_{n, n} 59 | P_{n + 1, n} = F * P_{n, n} * F^T + Q 60 | 61 | """ 62 | std_pos = [ 63 | self._std_weight_position * self.kf.x[3], 64 | self._std_weight_position * self.kf.x[3], 65 | 1e-2, 66 | self._std_weight_position * self.kf.x[3]] 67 | std_vel = [ 68 | self._std_weight_velocity * self.kf.x[3], 69 | self._std_weight_velocity * self.kf.x[3], 70 | 1e-5, 71 | self._std_weight_velocity * self.kf.x[3]] 72 | 73 | Q = np.diag(np.square(np.r_[std_pos, std_vel])) 74 | 75 | self.kf.predict(Q=Q) 76 | 77 | def update(self, z, score): 78 | """ update step 79 | 80 | Args: 81 | z: observation x-y-a-h format 82 | score: the detection score/confidence required by NSA kalman 83 | 84 | K_n = P_{n, n - 1} * H^T * (H P_{n, n - 1} H^T + R)^{-1} 85 | x_{n, n} = x_{n, n - 1} + K_n * (z - H * x_{n, n - 1}) 86 | P_{n, n} = (I - K_n * H) P_{n, n - 1} (I - K_n * H)^T + K_n R_n 87 | 88 | """ 89 | 90 | std = [ 91 | self._std_weight_position * self.kf.x[3], 92 | self._std_weight_position * self.kf.x[3], 93 | 1e-1, 94 | self._std_weight_position * self.kf.x[3]] 95 | 96 | # NSA 97 | std = [(1. - score) * x for x in std] 98 | 99 | R = np.diag(np.square(std)) 100 | 101 | self.kf.update(z=z, R=R) 102 | -------------------------------------------------------------------------------- /tracker/trackers/kalman_filters/ucmctrack_kalman.py: -------------------------------------------------------------------------------- 1 | from .base_kalman import BaseKalman 2 | import numpy as np 3 | 4 | class UCMCKalman(BaseKalman): 5 | def __init__(self, 6 | sigma_x=1.0, # noise factor in x axis (Eq. 11) 7 | sigma_y=1.0, # noise factor in y axis (Eq. 11) 8 | vmax=1.0, # TODO 9 | dt=1/30, # interval between frames 10 | **kwargs 11 | ): 12 | 13 | state_dim = 4 # [x, dx, y, dy] where x, y is the corr on ground 14 | observation_dim = 2 # [x, y] 15 | 16 | F = np.array([[1, dt, 0, 0], 17 | [0, 1, 0, 0], 18 | [0, 0, 1, dt], 19 | [0, 0, 0, 1]]) 20 | 21 | H = np.array([[1, 0, 0, 0], 22 | [0, 0, 1, 0]]) 23 | 24 | P = np.array([[1, 0, 0, 0], 25 | [0, vmax**2 / 3.0, 0, 0], 26 | [0, 0, 1, 0], 27 | [0, 0, 0, vmax**2 / 3.0]]) 28 | 29 | # noise compensation to initialize Q by Eq. 10 and 11 30 | G = np.array([[0.5*dt*dt, 0], 31 | [dt, 0], 32 | [0, 0.5*dt*dt], 33 | [0, dt]]) 34 | Q0 = np.array([[sigma_x, 0], [0, sigma_y]]) 35 | Q = np.dot(np.dot(G, Q0), G.T) 36 | 37 | super().__init__(state_dim=state_dim, 38 | observation_dim=observation_dim, 39 | F=F, 40 | H=H, 41 | P=P, 42 | Q=Q) 43 | 44 | def initialize(self, observation, R): 45 | """ 46 | observation: [x, y] where x y is the grounding coordinate 47 | R: the cov matrix of observation (2, 2) 48 | """ 49 | 50 | self.kf.x[0] = observation[0] 51 | self.kf.x[1] = 0 52 | self.kf.x[2] = observation[1] 53 | self.kf.x[3] = 0 54 | 55 | self.kf.R = R 56 | 57 | def predict(self, is_activated=True): 58 | self.kf.predict() 59 | 60 | def update(self, z, R): 61 | self.kf.update(z=z, R=R) -------------------------------------------------------------------------------- /tracker/trackers/reid_models/AFLink.py: -------------------------------------------------------------------------------- 1 | """ 2 | AFLink code in StrongSORT(StrongSORT: Make DeepSORT Great Again(arxiv)) 3 | 4 | copied from origin repo 5 | """ 6 | import torch 7 | import torch.nn as nn 8 | import torch.nn.functional as F 9 | import numpy as np 10 | import cv2 11 | import logging 12 | import torchvision.transforms as transforms 13 | 14 | 15 | class TemporalBlock(nn.Module): 16 | def __init__(self, cin, cout): 17 | super(TemporalBlock, self).__init__() 18 | self.conv = nn.Conv2d(cin, cout, (7, 1), bias=False) 19 | self.relu = nn.ReLU(inplace=True) 20 | self.bnf = nn.BatchNorm1d(cout) 21 | self.bnx = nn.BatchNorm1d(cout) 22 | self.bny = nn.BatchNorm1d(cout) 23 | 24 | def bn(self, x): 25 | x[:, :, :, 0] = self.bnf(x[:, :, :, 0]) 26 | x[:, :, :, 1] = self.bnx(x[:, :, :, 1]) 27 | x[:, :, :, 2] = self.bny(x[:, :, :, 2]) 28 | return x 29 | 30 | def forward(self, x): 31 | x = self.conv(x) 32 | x = self.bn(x) 33 | x = self.relu(x) 34 | return x 35 | 36 | 37 | class FusionBlock(nn.Module): 38 | def __init__(self, cin, cout): 39 | super(FusionBlock, self).__init__() 40 | self.conv = nn.Conv2d(cin, cout, (1, 3), bias=False) 41 | self.bn = nn.BatchNorm2d(cout) 42 | self.relu = nn.ReLU(inplace=True) 43 | 44 | def forward(self, x): 45 | x = self.conv(x) 46 | x = self.bn(x) 47 | x = self.relu(x) 48 | return x 49 | 50 | 51 | class Classifier(nn.Module): 52 | def __init__(self, cin): 53 | super(Classifier, self).__init__() 54 | self.fc1 = nn.Linear(cin*2, cin//2) 55 | self.relu = nn.ReLU(inplace=True) 56 | self.fc2 = nn.Linear(cin//2, 2) 57 | 58 | def forward(self, x1, x2): 59 | x = torch.cat((x1, x2), dim=1) 60 | x = self.fc1(x) 61 | x = self.relu(x) 62 | x = self.fc2(x) 63 | return x 64 | 65 | 66 | class PostLinker(nn.Module): 67 | def __init__(self): 68 | super(PostLinker, self).__init__() 69 | self.TemporalModule_1 = nn.Sequential( 70 | TemporalBlock(1, 32), 71 | TemporalBlock(32, 64), 72 | TemporalBlock(64, 128), 73 | TemporalBlock(128, 256) 74 | ) 75 | self.TemporalModule_2 = nn.Sequential( 76 | TemporalBlock(1, 32), 77 | TemporalBlock(32, 64), 78 | TemporalBlock(64, 128), 79 | TemporalBlock(128, 256) 80 | ) 81 | self.FusionBlock_1 = FusionBlock(256, 256) 82 | self.FusionBlock_2 = FusionBlock(256, 256) 83 | self.pooling = nn.AdaptiveAvgPool2d((1, 1)) 84 | self.classifier = Classifier(256) 85 | 86 | def forward(self, x1, x2): 87 | x1 = x1[:, :, :, :3] 88 | x2 = x2[:, :, :, :3] 89 | x1 = self.TemporalModule_1(x1) # [B,1,30,3] -> [B,256,6,3] 90 | x2 = self.TemporalModule_2(x2) 91 | x1 = self.FusionBlock_1(x1) 92 | x2 = self.FusionBlock_2(x2) 93 | x1 = self.pooling(x1).squeeze(-1).squeeze(-1) 94 | x2 = self.pooling(x2).squeeze(-1).squeeze(-1) 95 | y = self.classifier(x1, x2) 96 | if not self.training: 97 | y = torch.softmax(y, dim=1) 98 | return y -------------------------------------------------------------------------------- /tracker/trackers/reid_models/DeepsortReID.py: -------------------------------------------------------------------------------- 1 | """ 2 | file for DeepSORT Re-ID model 3 | """ 4 | 5 | import torch 6 | import torch.nn as nn 7 | import torch.nn.functional as F 8 | import numpy as np 9 | import cv2 10 | import logging 11 | import torchvision.transforms as transforms 12 | 13 | 14 | class BasicBlock(nn.Module): 15 | def __init__(self, c_in, c_out, is_downsample=False): 16 | super(BasicBlock, self).__init__() 17 | self.is_downsample = is_downsample 18 | if is_downsample: 19 | self.conv1 = nn.Conv2d( 20 | c_in, c_out, 3, stride=2, padding=1, bias=False) 21 | else: 22 | self.conv1 = nn.Conv2d( 23 | c_in, c_out, 3, stride=1, padding=1, bias=False) 24 | self.bn1 = nn.BatchNorm2d(c_out) 25 | self.relu = nn.ReLU(True) 26 | self.conv2 = nn.Conv2d(c_out, c_out, 3, stride=1, 27 | padding=1, bias=False) 28 | self.bn2 = nn.BatchNorm2d(c_out) 29 | if is_downsample: 30 | self.downsample = nn.Sequential( 31 | nn.Conv2d(c_in, c_out, 1, stride=2, bias=False), 32 | nn.BatchNorm2d(c_out) 33 | ) 34 | elif c_in != c_out: 35 | self.downsample = nn.Sequential( 36 | nn.Conv2d(c_in, c_out, 1, stride=1, bias=False), 37 | nn.BatchNorm2d(c_out) 38 | ) 39 | self.is_downsample = True 40 | 41 | def forward(self, x): 42 | y = self.conv1(x) 43 | y = self.bn1(y) 44 | y = self.relu(y) 45 | y = self.conv2(y) 46 | y = self.bn2(y) 47 | if self.is_downsample: 48 | x = self.downsample(x) 49 | return F.relu(x.add(y), True) 50 | 51 | 52 | def make_layers(c_in, c_out, repeat_times, is_downsample=False): 53 | blocks = [] 54 | for i in range(repeat_times): 55 | if i == 0: 56 | blocks += [BasicBlock(c_in, c_out, is_downsample=is_downsample), ] 57 | else: 58 | blocks += [BasicBlock(c_out, c_out), ] 59 | return nn.Sequential(*blocks) 60 | 61 | 62 | class Net(nn.Module): 63 | def __init__(self, num_classes=751, reid=False): 64 | super(Net, self).__init__() 65 | # 3 128 64 66 | self.conv = nn.Sequential( 67 | nn.Conv2d(3, 64, 3, stride=1, padding=1), 68 | nn.BatchNorm2d(64), 69 | nn.ReLU(inplace=True), 70 | # nn.Conv2d(32,32,3,stride=1,padding=1), 71 | # nn.BatchNorm2d(32), 72 | # nn.ReLU(inplace=True), 73 | nn.MaxPool2d(3, 2, padding=1), 74 | ) 75 | # 32 64 32 76 | self.layer1 = make_layers(64, 64, 2, False) 77 | # 32 64 32 78 | self.layer2 = make_layers(64, 128, 2, True) 79 | # 64 32 16 80 | self.layer3 = make_layers(128, 256, 2, True) 81 | # 128 16 8 82 | self.layer4 = make_layers(256, 512, 2, True) 83 | # 256 8 4 84 | self.avgpool = nn.AvgPool2d((8, 4), 1) 85 | # 256 1 1 86 | self.reid = reid 87 | self.classifier = nn.Sequential( 88 | nn.Linear(512, 256), 89 | nn.BatchNorm1d(256), 90 | nn.ReLU(inplace=True), 91 | nn.Dropout(), 92 | nn.Linear(256, num_classes), 93 | ) 94 | 95 | def forward(self, x): 96 | x = self.conv(x) 97 | x = self.layer1(x) 98 | x = self.layer2(x) 99 | x = self.layer3(x) 100 | x = self.layer4(x) 101 | x = self.avgpool(x) 102 | x = x.view(x.size(0), -1) 103 | # B x 128 104 | if self.reid: 105 | x = x.div(x.norm(p=2, dim=1, keepdim=True)) 106 | return x 107 | # classifier 108 | x = self.classifier(x) 109 | return x 110 | 111 | 112 | class Extractor(object): 113 | def __init__(self, model_path, device=None): 114 | self.net = Net(reid=True) 115 | self.device = device 116 | state_dict = torch.load(model_path, map_location=torch.device(self.device))[ 117 | 'net_dict'] 118 | self.net.load_state_dict(state_dict) 119 | logger = logging.getLogger("root.tracker") 120 | logger.info("Loading weights from {}... Done!".format(model_path)) 121 | self.net.to(self.device) 122 | self.size = (64, 128) 123 | self.norm = transforms.Compose([ 124 | transforms.ToTensor(), 125 | transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), 126 | ]) 127 | 128 | def _preprocess(self, im_crops): 129 | """ 130 | TODO: 131 | 1. to float with scale from 0 to 1 132 | 2. resize to (64, 128) as Market1501 dataset did 133 | 3. concatenate to a numpy array 134 | 3. to torch Tensor 135 | 4. normalize 136 | """ 137 | def _resize(im, size): 138 | try: 139 | return cv2.resize(im.astype(np.float32)/255., size) 140 | except: 141 | print('Error: size in bbox exists zero, ', im.shape) 142 | exit(0) 143 | 144 | im_batch = torch.cat([self.norm(_resize(im, self.size)).unsqueeze( 145 | 0) for im in im_crops], dim=0).float() 146 | return im_batch 147 | 148 | def __call__(self, im_crops): 149 | if isinstance(im_crops, list): # always false because im_crops is a tensor 150 | im_batch = self._preprocess(im_crops) 151 | else: 152 | im_batch = im_crops 153 | 154 | with torch.no_grad(): 155 | im_batch = im_batch.to(self.device) 156 | features = self.net(im_batch) 157 | return features 158 | -------------------------------------------------------------------------------- /tracker/trackers/reid_models/VehicleNet.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Vehicle net for AICity challenge 2020 3 | https://github.com/layumi/AICIty-reID-2020/ 4 | ''' 5 | import torch 6 | import torch.nn as nn 7 | from torch.nn import init 8 | from torchvision.models import resnet50 9 | 10 | def weights_init_kaiming(m): 11 | classname = m.__class__.__name__ 12 | # print(classname) 13 | if classname.find('Conv') != -1: 14 | init.kaiming_normal_(m.weight.data, a=0, mode='fan_in') # For old pytorch, you may use kaiming_normal. 15 | elif classname.find('Linear') != -1: 16 | init.kaiming_normal_(m.weight.data, a=0, mode='fan_out') 17 | init.constant_(m.bias.data, 0.0) 18 | elif classname.find('BatchNorm1d') != -1: 19 | init.normal_(m.weight.data, 1.0, 0.02) 20 | init.constant_(m.bias.data, 0.0) 21 | 22 | def weights_init_classifier(m): 23 | classname = m.__class__.__name__ 24 | if classname.find('Linear') != -1: 25 | init.normal_(m.weight.data, std=0.001) 26 | init.constant_(m.bias.data, 0.0) 27 | 28 | class ClassBlock(nn.Module): 29 | def __init__(self, input_dim, num_classes, droprate, relu=False, bnorm=True, num_bottleneck=512, linear=True, return_f = False): 30 | super(ClassBlock, self).__init__() 31 | self.return_f = return_f 32 | add_block = [] 33 | if linear: 34 | add_block += [nn.Linear(input_dim, num_bottleneck)] 35 | else: 36 | num_bottleneck = input_dim 37 | if bnorm: 38 | add_block += [nn.BatchNorm1d(num_bottleneck)] 39 | if relu: 40 | add_block += [nn.LeakyReLU(0.1)] 41 | if droprate>0: 42 | add_block += [nn.Dropout(p=droprate)] 43 | add_block = nn.Sequential(*add_block) 44 | add_block.apply(weights_init_kaiming) 45 | 46 | classifier = [] 47 | classifier += [nn.Linear(num_bottleneck, num_classes)] 48 | classifier = nn.Sequential(*classifier) 49 | classifier.apply(weights_init_classifier) 50 | 51 | self.add_block = add_block 52 | self.classifier = classifier 53 | def forward(self, x): 54 | x = self.add_block(x) 55 | if self.return_f: 56 | f = x 57 | x = self.classifier(x) 58 | return x,f 59 | else: 60 | x = self.classifier(x) 61 | return x 62 | 63 | class ft_net(nn.Module): 64 | 65 | def __init__(self, num_classes, droprate=0.5, stride=2, init_model=None, pool='avg', pretrained=False): 66 | super(ft_net, self).__init__() 67 | model_ft = resnet50(pretrained=pretrained) 68 | # avg pooling to global pooling 69 | if stride == 1: 70 | model_ft.layer4[0].downsample[0].stride = (1,1) 71 | model_ft.layer4[0].conv2.stride = (1,1) 72 | 73 | self.pool = pool 74 | if pool == 'avg+max': # False 75 | model_ft.avgpool2 = nn.AdaptiveAvgPool2d((1,1)) 76 | model_ft.maxpool2 = nn.AdaptiveMaxPool2d((1,1)) 77 | self.model = model_ft 78 | self.classifier = ClassBlock(4096, num_classes, droprate) 79 | elif pool == 'avg': 80 | model_ft.avgpool = nn.AdaptiveAvgPool2d((1,1)) 81 | self.model = model_ft 82 | self.classifier = ClassBlock(2048, num_classes, droprate) 83 | 84 | self.flag = False 85 | if init_model is not None: # False 86 | self.flag = True 87 | self.model = init_model.model 88 | self.pool = init_model.pool 89 | self.classifier.add_block = init_model.classifier.add_block 90 | self.new_dropout = nn.Sequential(nn.Dropout(p=droprate)) 91 | # avg pooling to global pooling 92 | 93 | def forward(self, x): 94 | x = self.model.conv1(x) 95 | x = self.model.bn1(x) 96 | x = self.model.relu(x) 97 | x = self.model.maxpool(x) 98 | x = self.model.layer1(x) 99 | x = self.model.layer2(x) 100 | x = self.model.layer3(x) 101 | x = self.model.layer4(x) 102 | if self.pool == 'avg+max': 103 | x1 = self.model.avgpool2(x) 104 | x2 = self.model.maxpool2(x) 105 | x = torch.cat((x1,x2), dim = 1) 106 | x = x.view(x.size(0), x.size(1)) 107 | elif self.pool == 'avg': 108 | x = self.model.avgpool(x) 109 | x = x.view(x.size(0), x.size(1)) 110 | 111 | 112 | # return embedding in test stage 113 | if not self.training: 114 | return x 115 | 116 | if self.flag: 117 | x = self.classifier.add_block(x) 118 | x = self.new_dropout(x) 119 | x = self.classifier.classifier(x) 120 | else: 121 | x = self.classifier(x) 122 | return x -------------------------------------------------------------------------------- /tracker/trackers/reid_models/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | file for reid_models folder 3 | """ -------------------------------------------------------------------------------- /tracker/trackeval/__init__.py: -------------------------------------------------------------------------------- 1 | from .eval import Evaluator 2 | from . import datasets 3 | from . import metrics 4 | from . import plotting 5 | from . import utils 6 | -------------------------------------------------------------------------------- /tracker/trackeval/_timing.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | from time import perf_counter 3 | import inspect 4 | 5 | DO_TIMING = False 6 | DISPLAY_LESS_PROGRESS = False 7 | timer_dict = {} 8 | counter = 0 9 | 10 | 11 | def time(f): 12 | @wraps(f) 13 | def wrap(*args, **kw): 14 | if DO_TIMING: 15 | # Run function with timing 16 | ts = perf_counter() 17 | result = f(*args, **kw) 18 | te = perf_counter() 19 | tt = te-ts 20 | 21 | # Get function name 22 | arg_names = inspect.getfullargspec(f)[0] 23 | if arg_names[0] == 'self' and DISPLAY_LESS_PROGRESS: 24 | return result 25 | elif arg_names[0] == 'self': 26 | method_name = type(args[0]).__name__ + '.' + f.__name__ 27 | else: 28 | method_name = f.__name__ 29 | 30 | # Record accumulative time in each function for analysis 31 | if method_name in timer_dict.keys(): 32 | timer_dict[method_name] += tt 33 | else: 34 | timer_dict[method_name] = tt 35 | 36 | # If code is finished, display timing summary 37 | if method_name == "Evaluator.evaluate": 38 | print("") 39 | print("Timing analysis:") 40 | for key, value in timer_dict.items(): 41 | print('%-70s %2.4f sec' % (key, value)) 42 | else: 43 | # Get function argument values for printing special arguments of interest 44 | arg_titles = ['tracker', 'seq', 'cls'] 45 | arg_vals = [] 46 | for i, a in enumerate(arg_names): 47 | if a in arg_titles: 48 | arg_vals.append(args[i]) 49 | arg_text = '(' + ', '.join(arg_vals) + ')' 50 | 51 | # Display methods and functions with different indentation. 52 | if arg_names[0] == 'self': 53 | print('%-74s %2.4f sec' % (' '*4 + method_name + arg_text, tt)) 54 | elif arg_names[0] == 'test': 55 | pass 56 | else: 57 | global counter 58 | counter += 1 59 | print('%i %-70s %2.4f sec' % (counter, method_name + arg_text, tt)) 60 | 61 | return result 62 | else: 63 | # If config["TIME_PROGRESS"] is false, or config["USE_PARALLEL"] is true, run functions normally without timing. 64 | return f(*args, **kw) 65 | return wrap 66 | -------------------------------------------------------------------------------- /tracker/trackeval/baselines/__init__.py: -------------------------------------------------------------------------------- 1 | import baseline_utils 2 | import stp 3 | import non_overlap 4 | import pascal_colormap 5 | import thresholder 6 | import vizualize -------------------------------------------------------------------------------- /tracker/trackeval/baselines/non_overlap.py: -------------------------------------------------------------------------------- 1 | """ 2 | Non-Overlap: Code to take in a set of raw detections and produce a set of non-overlapping detections from it. 3 | 4 | Author: Jonathon Luiten 5 | """ 6 | 7 | import os 8 | import sys 9 | from multiprocessing.pool import Pool 10 | from multiprocessing import freeze_support 11 | 12 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) 13 | from trackeval.baselines import baseline_utils as butils 14 | from trackeval.utils import get_code_path 15 | 16 | code_path = get_code_path() 17 | config = { 18 | 'INPUT_FOL': os.path.join(code_path, 'data/detections/rob_mots/{split}/raw_supplied/data/'), 19 | 'OUTPUT_FOL': os.path.join(code_path, 'data/detections/rob_mots/{split}/non_overlap_supplied/data/'), 20 | 'SPLIT': 'train', # valid: 'train', 'val', 'test'. 21 | 'Benchmarks': None, # If None, all benchmarks in SPLIT. 22 | 23 | 'Num_Parallel_Cores': None, # If None, run without parallel. 24 | 25 | 'THRESHOLD_NMS_MASK_IOU': 0.5, 26 | } 27 | 28 | 29 | def do_sequence(seq_file): 30 | 31 | # Load input data from file (e.g. provided detections) 32 | # data format: data['cls'][t] = {'ids', 'scores', 'im_hs', 'im_ws', 'mask_rles'} 33 | data = butils.load_seq(seq_file) 34 | 35 | # Converts data from a class-separated to a class-combined format. 36 | # data[t] = {'ids', 'scores', 'im_hs', 'im_ws', 'mask_rles', 'cls'} 37 | data = butils.combine_classes(data) 38 | 39 | # Where to accumulate output data for writing out 40 | output_data = [] 41 | 42 | # Run for each timestep. 43 | for timestep, t_data in enumerate(data): 44 | 45 | # Remove redundant masks by performing non-maximum suppression (NMS) 46 | t_data = butils.mask_NMS(t_data, nms_threshold=config['THRESHOLD_NMS_MASK_IOU']) 47 | 48 | # Perform non-overlap, to get non_overlapping masks. 49 | t_data = butils.non_overlap(t_data, already_sorted=True) 50 | 51 | # Save result in output format to write to file later. 52 | # Output Format = [timestep ID class score im_h im_w mask_RLE] 53 | for i in range(len(t_data['ids'])): 54 | row = [timestep, int(t_data['ids'][i]), t_data['cls'][i], t_data['scores'][i], t_data['im_hs'][i], 55 | t_data['im_ws'][i], t_data['mask_rles'][i]] 56 | output_data.append(row) 57 | 58 | # Write results to file 59 | out_file = seq_file.replace(config['INPUT_FOL'].format(split=config['SPLIT']), 60 | config['OUTPUT_FOL'].format(split=config['SPLIT'])) 61 | butils.write_seq(output_data, out_file) 62 | 63 | print('DONE:', seq_file) 64 | 65 | 66 | if __name__ == '__main__': 67 | 68 | # Required to fix bug in multiprocessing on windows. 69 | freeze_support() 70 | 71 | # Obtain list of sequences to run tracker for. 72 | if config['Benchmarks']: 73 | benchmarks = config['Benchmarks'] 74 | else: 75 | benchmarks = ['davis_unsupervised', 'kitti_mots', 'youtube_vis', 'ovis', 'bdd_mots', 'tao'] 76 | if config['SPLIT'] != 'train': 77 | benchmarks += ['waymo', 'mots_challenge'] 78 | seqs_todo = [] 79 | for bench in benchmarks: 80 | bench_fol = os.path.join(config['INPUT_FOL'].format(split=config['SPLIT']), bench) 81 | seqs_todo += [os.path.join(bench_fol, seq) for seq in os.listdir(bench_fol)] 82 | 83 | # Run in parallel 84 | if config['Num_Parallel_Cores']: 85 | with Pool(config['Num_Parallel_Cores']) as pool: 86 | results = pool.map(do_sequence, seqs_todo) 87 | 88 | # Run in series 89 | else: 90 | for seq_todo in seqs_todo: 91 | do_sequence(seq_todo) 92 | 93 | -------------------------------------------------------------------------------- /tracker/trackeval/baselines/thresholder.py: -------------------------------------------------------------------------------- 1 | """ 2 | Thresholder 3 | 4 | Author: Jonathon Luiten 5 | 6 | Simply reads in a set of detection, thresholds them at a certain score threshold, and writes them out again. 7 | """ 8 | 9 | import os 10 | import sys 11 | from multiprocessing.pool import Pool 12 | from multiprocessing import freeze_support 13 | 14 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) 15 | from trackeval.baselines import baseline_utils as butils 16 | from trackeval.utils import get_code_path 17 | 18 | THRESHOLD = 0.2 19 | 20 | code_path = get_code_path() 21 | config = { 22 | 'INPUT_FOL': os.path.join(code_path, 'data/detections/rob_mots/{split}/non_overlap_supplied/data/'), 23 | 'OUTPUT_FOL': os.path.join(code_path, 'data/detections/rob_mots/{split}/threshold_' + str(100*THRESHOLD) + '/data/'), 24 | 'SPLIT': 'train', # valid: 'train', 'val', 'test'. 25 | 'Benchmarks': None, # If None, all benchmarks in SPLIT. 26 | 27 | 'Num_Parallel_Cores': None, # If None, run without parallel. 28 | 29 | 'DETECTION_THRESHOLD': THRESHOLD, 30 | } 31 | 32 | 33 | def do_sequence(seq_file): 34 | 35 | # Load input data from file (e.g. provided detections) 36 | # data format: data['cls'][t] = {'ids', 'scores', 'im_hs', 'im_ws', 'mask_rles'} 37 | data = butils.load_seq(seq_file) 38 | 39 | # Where to accumulate output data for writing out 40 | output_data = [] 41 | 42 | # Run for each class. 43 | for cls, cls_data in data.items(): 44 | 45 | # Run for each timestep. 46 | for timestep, t_data in enumerate(cls_data): 47 | 48 | # Threshold detections. 49 | t_data = butils.threshold(t_data, config['DETECTION_THRESHOLD']) 50 | 51 | # Save result in output format to write to file later. 52 | # Output Format = [timestep ID class score im_h im_w mask_RLE] 53 | for i in range(len(t_data['ids'])): 54 | row = [timestep, int(t_data['ids'][i]), cls, t_data['scores'][i], t_data['im_hs'][i], 55 | t_data['im_ws'][i], t_data['mask_rles'][i]] 56 | output_data.append(row) 57 | 58 | # Write results to file 59 | out_file = seq_file.replace(config['INPUT_FOL'].format(split=config['SPLIT']), 60 | config['OUTPUT_FOL'].format(split=config['SPLIT'])) 61 | butils.write_seq(output_data, out_file) 62 | 63 | print('DONE:', seq_todo) 64 | 65 | 66 | if __name__ == '__main__': 67 | 68 | # Required to fix bug in multiprocessing on windows. 69 | freeze_support() 70 | 71 | # Obtain list of sequences to run tracker for. 72 | if config['Benchmarks']: 73 | benchmarks = config['Benchmarks'] 74 | else: 75 | benchmarks = ['davis_unsupervised', 'kitti_mots', 'youtube_vis', 'ovis', 'bdd_mots', 'tao'] 76 | if config['SPLIT'] != 'train': 77 | benchmarks += ['waymo', 'mots_challenge'] 78 | seqs_todo = [] 79 | for bench in benchmarks: 80 | bench_fol = os.path.join(config['INPUT_FOL'].format(split=config['SPLIT']), bench) 81 | seqs_todo += [os.path.join(bench_fol, seq) for seq in os.listdir(bench_fol)] 82 | 83 | # Run in parallel 84 | if config['Num_Parallel_Cores']: 85 | with Pool(config['Num_Parallel_Cores']) as pool: 86 | results = pool.map(do_sequence, seqs_todo) 87 | 88 | # Run in series 89 | else: 90 | for seq_todo in seqs_todo: 91 | do_sequence(seq_todo) 92 | 93 | -------------------------------------------------------------------------------- /tracker/trackeval/baselines/vizualize.py: -------------------------------------------------------------------------------- 1 | """ 2 | Vizualize: Code which converts .txt rle tracking results into a visual .png format. 3 | 4 | Author: Jonathon Luiten 5 | """ 6 | 7 | import os 8 | import sys 9 | from multiprocessing.pool import Pool 10 | from multiprocessing import freeze_support 11 | 12 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) 13 | from trackeval.baselines import baseline_utils as butils 14 | from trackeval.utils import get_code_path 15 | from trackeval.datasets.rob_mots_classmap import cls_id_to_name 16 | 17 | code_path = get_code_path() 18 | config = { 19 | # Tracker format: 20 | 'INPUT_FOL': os.path.join(code_path, 'data/trackers/rob_mots/{split}/STP/data/{bench}'), 21 | 'OUTPUT_FOL': os.path.join(code_path, 'data/viz/rob_mots/{split}/STP/data/{bench}'), 22 | # GT format: 23 | # 'INPUT_FOL': os.path.join(code_path, 'data/gt/rob_mots/{split}/{bench}/data/'), 24 | # 'OUTPUT_FOL': os.path.join(code_path, 'data/gt_viz/rob_mots/{split}/{bench}/'), 25 | 'SPLIT': 'train', # valid: 'train', 'val', 'test'. 26 | 'Benchmarks': None, # If None, all benchmarks in SPLIT. 27 | 'Num_Parallel_Cores': None, # If None, run without parallel. 28 | } 29 | 30 | 31 | def do_sequence(seq_file): 32 | # Folder to save resulting visualization in 33 | out_fol = seq_file.replace(config['INPUT_FOL'].format(split=config['SPLIT'], bench=bench), 34 | config['OUTPUT_FOL'].format(split=config['SPLIT'], bench=bench)).replace('.txt', '') 35 | 36 | # Load input data from file (e.g. provided detections) 37 | # data format: data['cls'][t] = {'ids', 'scores', 'im_hs', 'im_ws', 'mask_rles'} 38 | data = butils.load_seq(seq_file) 39 | 40 | # Get frame size for visualizing empty frames 41 | im_h, im_w = butils.get_frame_size(data) 42 | 43 | # First run for each class. 44 | for cls, cls_data in data.items(): 45 | 46 | if cls >= 100: 47 | continue 48 | 49 | # Run for each timestep. 50 | for timestep, t_data in enumerate(cls_data): 51 | # Save out visualization 52 | out_file = os.path.join(out_fol, cls_id_to_name[cls], str(timestep).zfill(5) + '.png') 53 | butils.save_as_png(t_data, out_file, im_h, im_w) 54 | 55 | 56 | # Then run for all classes combined 57 | # Converts data from a class-separated to a class-combined format. 58 | data = butils.combine_classes(data) 59 | 60 | # Run for each timestep. 61 | for timestep, t_data in enumerate(data): 62 | # Save out visualization 63 | out_file = os.path.join(out_fol, 'all_classes', str(timestep).zfill(5) + '.png') 64 | butils.save_as_png(t_data, out_file, im_h, im_w) 65 | 66 | print('DONE:', seq_file) 67 | 68 | 69 | if __name__ == '__main__': 70 | 71 | # Required to fix bug in multiprocessing on windows. 72 | freeze_support() 73 | 74 | # Obtain list of sequences to run tracker for. 75 | if config['Benchmarks']: 76 | benchmarks = config['Benchmarks'] 77 | else: 78 | benchmarks = ['davis_unsupervised', 'kitti_mots', 'youtube_vis', 'ovis', 'bdd_mots', 'tao'] 79 | if config['SPLIT'] != 'train': 80 | benchmarks += ['waymo', 'mots_challenge'] 81 | seqs_todo = [] 82 | for bench in benchmarks: 83 | bench_fol = config['INPUT_FOL'].format(split=config['SPLIT'], bench=bench) 84 | seqs_todo += [os.path.join(bench_fol, seq) for seq in os.listdir(bench_fol)] 85 | 86 | # Run in parallel 87 | if config['Num_Parallel_Cores']: 88 | with Pool(config['Num_Parallel_Cores']) as pool: 89 | results = pool.map(do_sequence, seqs_todo) 90 | 91 | # Run in series 92 | else: 93 | for seq_todo in seqs_todo: 94 | do_sequence(seq_todo) 95 | -------------------------------------------------------------------------------- /tracker/trackeval/datasets/__init__.py: -------------------------------------------------------------------------------- 1 | from .kitti_2d_box import Kitti2DBox 2 | from .kitti_mots import KittiMOTS 3 | from .mot_challenge_2d_box import MotChallenge2DBox 4 | from .mots_challenge import MOTSChallenge 5 | from .bdd100k import BDD100K 6 | from .davis import DAVIS 7 | from .tao import TAO 8 | from .tao_ow import TAO_OW 9 | from .burst import BURST 10 | from .burst_ow import BURST_OW 11 | from .youtube_vis import YouTubeVIS 12 | from .head_tracking_challenge import HeadTrackingChallenge 13 | from .rob_mots import RobMOTS 14 | from .person_path_22 import PersonPath22 15 | from .visdrone import VisDrone2DBox 16 | -------------------------------------------------------------------------------- /tracker/trackeval/datasets/burst.py: -------------------------------------------------------------------------------- 1 | import os 2 | from .burst_helpers.burst_base import BURSTBase 3 | from .burst_helpers.format_converter import GroundTruthBURSTFormatToTAOFormatConverter, PredictionBURSTFormatToTAOFormatConverter 4 | from .. import utils 5 | 6 | 7 | class BURST(BURSTBase): 8 | """Dataset class for TAO tracking""" 9 | 10 | @staticmethod 11 | def get_default_dataset_config(): 12 | tao_config = BURSTBase.get_default_dataset_config() 13 | code_path = utils.get_code_path() 14 | 15 | # e.g. 'data/gt/tsunami/exemplar_guided/' 16 | tao_config['GT_FOLDER'] = os.path.join( 17 | code_path, 'data/gt/burst/val/') # Location of GT data 18 | # e.g. 'data/trackers/tsunami/exemplar_guided/mask_guided/validation/' 19 | tao_config['TRACKERS_FOLDER'] = os.path.join( 20 | code_path, 'data/trackers/burst/class-guided/') # Trackers location 21 | # set to True or False 22 | tao_config['EXEMPLAR_GUIDED'] = False 23 | return tao_config 24 | 25 | def _iou_type(self): 26 | return 'mask' 27 | 28 | def _box_or_mask_from_det(self, det): 29 | return det['segmentation'] 30 | 31 | def _calculate_area_for_ann(self, ann): 32 | import pycocotools.mask as cocomask 33 | return cocomask.area(ann["segmentation"]) 34 | 35 | def _calculate_similarities(self, gt_dets_t, tracker_dets_t): 36 | similarity_scores = self._calculate_mask_ious(gt_dets_t, tracker_dets_t, is_encoded=True, do_ioa=False) 37 | return similarity_scores 38 | 39 | def _is_exemplar_guided(self): 40 | exemplar_guided = self.config['EXEMPLAR_GUIDED'] 41 | return exemplar_guided 42 | 43 | def _postproc_ground_truth_data(self, data): 44 | return GroundTruthBURSTFormatToTAOFormatConverter(data).convert() 45 | 46 | def _postproc_prediction_data(self, data): 47 | return PredictionBURSTFormatToTAOFormatConverter( 48 | self.gt_data, data, 49 | exemplar_guided=self._is_exemplar_guided()).convert() 50 | -------------------------------------------------------------------------------- /tracker/trackeval/datasets/burst_helpers/BURST_SPECIFIC_ISSUES.md: -------------------------------------------------------------------------------- 1 | The track ids in both ground truth and predictions are not globally unique, but 2 | start from 1 for each video. At the moment when converting from Ali format to 3 | TAO format, we remap the ids to be globally unique. It would be better to 4 | directly have this in the data though. 5 | 6 | 7 | Improve setting of EXEMPLAR_GUIDED flag, maybe this can be done automatically. 8 | -------------------------------------------------------------------------------- /tracker/trackeval/datasets/burst_helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/tracker/trackeval/datasets/burst_helpers/__init__.py -------------------------------------------------------------------------------- /tracker/trackeval/datasets/burst_helpers/convert_burst_format_to_tao_format.py: -------------------------------------------------------------------------------- 1 | import json 2 | import argparse 3 | from .format_converter import GroundTruthBURSTFormatToTAOFormatConverter, PredictionBURSTFormatToTAOFormatConverter 4 | 5 | 6 | def main(args): 7 | with open(args.gt_input_file) as f: 8 | ali_format_gt = json.load(f) 9 | tao_format_gt = GroundTruthBURSTFormatToTAOFormatConverter( 10 | ali_format_gt, args.split).convert() 11 | with open(args.gt_output_file, 'w') as f: 12 | json.dump(tao_format_gt, f) 13 | 14 | if args.pred_input_file is None: 15 | return 16 | with open(args.pred_input_file) as f: 17 | ali_format_pred = json.load(f) 18 | tao_format_pred = PredictionBURSTFormatToTAOFormatConverter( 19 | tao_format_gt, ali_format_pred, args.split, 20 | args.exemplar_guided).convert() 21 | with open(args.pred_output_file, 'w') as f: 22 | json.dump(tao_format_pred, f) 23 | 24 | 25 | if __name__ == '__main__': 26 | parser = argparse.ArgumentParser() 27 | parser.add_argument( 28 | '--gt_input_file', type=str, 29 | default='../data/gt/tsunami/exemplar_guided/validation_all_annotations.json') 30 | parser.add_argument('--gt_output_file', type=str, 31 | default='/tmp/val_gt.json') 32 | parser.add_argument('--pred_input_file', type=str, 33 | default='../data/trackers/tsunami/exemplar_guided/STCN_off_the_shelf/data/results.json') 34 | parser.add_argument('--pred_output_file', type=str, 35 | default='/tmp/pred.json') 36 | parser.add_argument('--split', type=str, default='validation') 37 | parser.add_argument('--exemplar_guided', type=bool, default=True) 38 | args_ = parser.parse_args() 39 | main(args_) 40 | -------------------------------------------------------------------------------- /tracker/trackeval/datasets/burst_ow.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | from .burst_helpers.burst_ow_base import BURST_OW_Base 4 | from .burst_helpers.format_converter import GroundTruthBURSTFormatToTAOFormatConverter, PredictionBURSTFormatToTAOFormatConverter 5 | from .. import utils 6 | 7 | 8 | class BURST_OW(BURST_OW_Base): 9 | """Dataset class for TAO tracking""" 10 | 11 | @staticmethod 12 | def get_default_dataset_config(): 13 | tao_config = BURST_OW_Base.get_default_dataset_config() 14 | code_path = utils.get_code_path() 15 | tao_config['GT_FOLDER'] = os.path.join( 16 | code_path, 'data/gt/burst/all_classes/val/') # Location of GT data 17 | tao_config['TRACKERS_FOLDER'] = os.path.join( 18 | code_path, 'data/trackers/burst/open-world/val/') # Trackers location 19 | return tao_config 20 | 21 | def _iou_type(self): 22 | return 'mask' 23 | 24 | def _box_or_mask_from_det(self, det): 25 | if "segmentation" in det: 26 | return det["segmentation"] 27 | else: 28 | return det["mask"] 29 | 30 | def _calculate_area_for_ann(self, ann): 31 | import pycocotools.mask as cocomask 32 | seg = self._box_or_mask_from_det(ann) 33 | return cocomask.area(seg) 34 | 35 | def _calculate_similarities(self, gt_dets_t, tracker_dets_t): 36 | similarity_scores = self._calculate_mask_ious(gt_dets_t, tracker_dets_t, is_encoded=True, do_ioa=False) 37 | return similarity_scores 38 | 39 | def _postproc_ground_truth_data(self, data): 40 | return GroundTruthBURSTFormatToTAOFormatConverter(data).convert() 41 | 42 | def _postproc_prediction_data(self, data): 43 | # if it's a list, it's already in TAO format and not in Ali format 44 | # however the image ids do not match and need to be remapped 45 | if isinstance(data, list): 46 | _remap_image_ids(data, self.gt_data) 47 | return data 48 | 49 | return PredictionBURSTFormatToTAOFormatConverter( 50 | self.gt_data, data, 51 | exemplar_guided=False).convert() 52 | 53 | 54 | def _remap_image_ids(pred_data, ali_gt_data): 55 | code_path = utils.get_code_path() 56 | if 'split' in ali_gt_data: 57 | split = ali_gt_data['split'] 58 | else: 59 | split = 'val' 60 | 61 | if split in ('val', 'validation'): 62 | tao_gt_path = os.path.join( 63 | code_path, 'data/gt/tao/tao_validation/gt.json') 64 | else: 65 | tao_gt_path = os.path.join( 66 | code_path, 'data/gt/tao/tao_test/test_without_annotations.json') 67 | 68 | with open(tao_gt_path) as f: 69 | tao_gt = json.load(f) 70 | 71 | tao_img_by_id = {} 72 | for img in tao_gt['images']: 73 | img_id = img['id'] 74 | tao_img_by_id[img_id] = img 75 | 76 | ali_img_id_by_filename = {} 77 | for ali_img in ali_gt_data['images']: 78 | ali_img_id = ali_img['id'] 79 | file_name = ali_img['file_name'].replace("validation", "val") 80 | ali_img_id_by_filename[file_name] = ali_img_id 81 | 82 | ali_img_id_by_tao_img_id = {} 83 | for tao_img_id, tao_img in tao_img_by_id.items(): 84 | file_name = tao_img['file_name'] 85 | ali_img_id = ali_img_id_by_filename[file_name] 86 | ali_img_id_by_tao_img_id[tao_img_id] = ali_img_id 87 | 88 | for det in pred_data: 89 | tao_img_id = det['image_id'] 90 | ali_img_id = ali_img_id_by_tao_img_id[tao_img_id] 91 | det['image_id'] = ali_img_id 92 | -------------------------------------------------------------------------------- /tracker/trackeval/datasets/rob_mots_classmap.py: -------------------------------------------------------------------------------- 1 | cls_id_to_name = { 2 | 1: 'person', 3 | 2: 'bicycle', 4 | 3: 'car', 5 | 4: 'motorcycle', 6 | 5: 'airplane', 7 | 6: 'bus', 8 | 7: 'train', 9 | 8: 'truck', 10 | 9: 'boat', 11 | 10: 'traffic light', 12 | 11: 'fire hydrant', 13 | 12: 'stop sign', 14 | 13: 'parking meter', 15 | 14: 'bench', 16 | 15: 'bird', 17 | 16: 'cat', 18 | 17: 'dog', 19 | 18: 'horse', 20 | 19: 'sheep', 21 | 20: 'cow', 22 | 21: 'elephant', 23 | 22: 'bear', 24 | 23: 'zebra', 25 | 24: 'giraffe', 26 | 25: 'backpack', 27 | 26: 'umbrella', 28 | 27: 'handbag', 29 | 28: 'tie', 30 | 29: 'suitcase', 31 | 30: 'frisbee', 32 | 31: 'skis', 33 | 32: 'snowboard', 34 | 33: 'sports ball', 35 | 34: 'kite', 36 | 35: 'baseball bat', 37 | 36: 'baseball glove', 38 | 37: 'skateboard', 39 | 38: 'surfboard', 40 | 39: 'tennis racket', 41 | 40: 'bottle', 42 | 41: 'wine glass', 43 | 42: 'cup', 44 | 43: 'fork', 45 | 44: 'knife', 46 | 45: 'spoon', 47 | 46: 'bowl', 48 | 47: 'banana', 49 | 48: 'apple', 50 | 49: 'sandwich', 51 | 50: 'orange', 52 | 51: 'broccoli', 53 | 52: 'carrot', 54 | 53: 'hot dog', 55 | 54: 'pizza', 56 | 55: 'donut', 57 | 56: 'cake', 58 | 57: 'chair', 59 | 58: 'couch', 60 | 59: 'potted plant', 61 | 60: 'bed', 62 | 61: 'dining table', 63 | 62: 'toilet', 64 | 63: 'tv', 65 | 64: 'laptop', 66 | 65: 'mouse', 67 | 66: 'remote', 68 | 67: 'keyboard', 69 | 68: 'cell phone', 70 | 69: 'microwave', 71 | 70: 'oven', 72 | 71: 'toaster', 73 | 72: 'sink', 74 | 73: 'refrigerator', 75 | 74: 'book', 76 | 75: 'clock', 77 | 76: 'vase', 78 | 77: 'scissors', 79 | 78: 'teddy bear', 80 | 79: 'hair drier', 81 | 80: 'toothbrush'} -------------------------------------------------------------------------------- /tracker/trackeval/metrics/__init__.py: -------------------------------------------------------------------------------- 1 | from .hota import HOTA 2 | from .clear import CLEAR 3 | from .identity import Identity 4 | from .count import Count 5 | from .j_and_f import JAndF 6 | from .track_map import TrackMAP 7 | from .vace import VACE 8 | from .ideucl import IDEucl -------------------------------------------------------------------------------- /tracker/trackeval/metrics/_base_metric.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | from abc import ABC, abstractmethod 4 | from .. import _timing 5 | from ..utils import TrackEvalException 6 | 7 | 8 | class _BaseMetric(ABC): 9 | @abstractmethod 10 | def __init__(self): 11 | self.plottable = False 12 | self.integer_fields = [] 13 | self.float_fields = [] 14 | self.array_labels = [] 15 | self.integer_array_fields = [] 16 | self.float_array_fields = [] 17 | self.fields = [] 18 | self.summary_fields = [] 19 | self.registered = False 20 | 21 | ##################################################################### 22 | # Abstract functions for subclasses to implement 23 | 24 | @_timing.time 25 | @abstractmethod 26 | def eval_sequence(self, data): 27 | ... 28 | 29 | @abstractmethod 30 | def combine_sequences(self, all_res): 31 | ... 32 | 33 | @abstractmethod 34 | def combine_classes_class_averaged(self, all_res, ignore_empty_classes=False): 35 | ... 36 | 37 | @ abstractmethod 38 | def combine_classes_det_averaged(self, all_res): 39 | ... 40 | 41 | def plot_single_tracker_results(self, all_res, tracker, output_folder, cls): 42 | """Plot results of metrics, only valid for metrics with self.plottable""" 43 | if self.plottable: 44 | raise NotImplementedError('plot_results is not implemented for metric %s' % self.get_name()) 45 | else: 46 | pass 47 | 48 | ##################################################################### 49 | # Helper functions which are useful for all metrics: 50 | 51 | @classmethod 52 | def get_name(cls): 53 | return cls.__name__ 54 | 55 | @staticmethod 56 | def _combine_sum(all_res, field): 57 | """Combine sequence results via sum""" 58 | return sum([all_res[k][field] for k in all_res.keys()]) 59 | 60 | @staticmethod 61 | def _combine_weighted_av(all_res, field, comb_res, weight_field): 62 | """Combine sequence results via weighted average""" 63 | return sum([all_res[k][field] * all_res[k][weight_field] for k in all_res.keys()]) / np.maximum(1.0, comb_res[ 64 | weight_field]) 65 | 66 | def print_table(self, table_res, tracker, cls): 67 | """Prints table of results for all sequences""" 68 | print('') 69 | metric_name = self.get_name() 70 | self._row_print([metric_name + ': ' + tracker + '-' + cls] + self.summary_fields) 71 | for seq, results in sorted(table_res.items()): 72 | if seq == 'COMBINED_SEQ': 73 | continue 74 | summary_res = self._summary_row(results) 75 | self._row_print([seq] + summary_res) 76 | summary_res = self._summary_row(table_res['COMBINED_SEQ']) 77 | self._row_print(['COMBINED'] + summary_res) 78 | 79 | def _summary_row(self, results_): 80 | vals = [] 81 | for h in self.summary_fields: 82 | if h in self.float_array_fields: 83 | vals.append("{0:1.5g}".format(100 * np.mean(results_[h]))) 84 | elif h in self.float_fields: 85 | vals.append("{0:1.5g}".format(100 * float(results_[h]))) 86 | elif h in self.integer_fields: 87 | vals.append("{0:d}".format(int(results_[h]))) 88 | else: 89 | raise NotImplementedError("Summary function not implemented for this field type.") 90 | return vals 91 | 92 | @staticmethod 93 | def _row_print(*argv): 94 | """Prints results in an evenly spaced rows, with more space in first row""" 95 | if len(argv) == 1: 96 | argv = argv[0] 97 | to_print = '%-35s' % argv[0] 98 | for v in argv[1:]: 99 | to_print += '%-10s' % str(v) 100 | print(to_print) 101 | 102 | def summary_results(self, table_res): 103 | """Returns a simple summary of final results for a tracker""" 104 | return dict(zip(self.summary_fields, self._summary_row(table_res['COMBINED_SEQ']))) 105 | 106 | def detailed_results(self, table_res): 107 | """Returns detailed final results for a tracker""" 108 | # Get detailed field information 109 | detailed_fields = self.float_fields + self.integer_fields 110 | for h in self.float_array_fields + self.integer_array_fields: 111 | for alpha in [int(100*x) for x in self.array_labels]: 112 | detailed_fields.append(h + '___' + str(alpha)) 113 | detailed_fields.append(h + '___AUC') 114 | 115 | # Get detailed results 116 | detailed_results = {} 117 | for seq, res in table_res.items(): 118 | detailed_row = self._detailed_row(res) 119 | if len(detailed_row) != len(detailed_fields): 120 | raise TrackEvalException( 121 | 'Field names and data have different sizes (%i and %i)' % (len(detailed_row), len(detailed_fields))) 122 | detailed_results[seq] = dict(zip(detailed_fields, detailed_row)) 123 | return detailed_results 124 | 125 | def _detailed_row(self, res): 126 | detailed_row = [] 127 | for h in self.float_fields + self.integer_fields: 128 | detailed_row.append(res[h]) 129 | for h in self.float_array_fields + self.integer_array_fields: 130 | for i, alpha in enumerate([int(100 * x) for x in self.array_labels]): 131 | detailed_row.append(res[h][i]) 132 | detailed_row.append(np.mean(res[h])) 133 | return detailed_row 134 | -------------------------------------------------------------------------------- /tracker/trackeval/metrics/count.py: -------------------------------------------------------------------------------- 1 | 2 | from ._base_metric import _BaseMetric 3 | from .. import _timing 4 | 5 | 6 | class Count(_BaseMetric): 7 | """Class which simply counts the number of tracker and gt detections and ids.""" 8 | def __init__(self, config=None): 9 | super().__init__() 10 | self.integer_fields = ['Dets', 'GT_Dets', 'IDs', 'GT_IDs'] 11 | self.fields = self.integer_fields 12 | self.summary_fields = self.fields 13 | 14 | @_timing.time 15 | def eval_sequence(self, data): 16 | """Returns counts for one sequence""" 17 | # Get results 18 | res = {'Dets': data['num_tracker_dets'], 19 | 'GT_Dets': data['num_gt_dets'], 20 | 'IDs': data['num_tracker_ids'], 21 | 'GT_IDs': data['num_gt_ids'], 22 | 'Frames': data['num_timesteps']} 23 | return res 24 | 25 | def combine_sequences(self, all_res): 26 | """Combines metrics across all sequences""" 27 | res = {} 28 | for field in self.integer_fields: 29 | res[field] = self._combine_sum(all_res, field) 30 | return res 31 | 32 | def combine_classes_class_averaged(self, all_res, ignore_empty_classes=None): 33 | """Combines metrics across all classes by averaging over the class values""" 34 | res = {} 35 | for field in self.integer_fields: 36 | res[field] = self._combine_sum(all_res, field) 37 | return res 38 | 39 | def combine_classes_det_averaged(self, all_res): 40 | """Combines metrics across all classes by averaging over the detection values""" 41 | res = {} 42 | for field in self.integer_fields: 43 | res[field] = self._combine_sum(all_res, field) 44 | return res 45 | -------------------------------------------------------------------------------- /tracker/tracking_utils/envs.py: -------------------------------------------------------------------------------- 1 | """ 2 | set gpus and ramdom seeds 3 | """ 4 | 5 | import os 6 | import random 7 | import numpy as np 8 | from loguru import logger 9 | 10 | import torch 11 | import torch.backends.cudnn as cudnn 12 | 13 | def select_device(device): 14 | """ set device 15 | Args: 16 | device: str, 'cpu' or '0' or '1,2,3'-like 17 | 18 | Return: 19 | torch.device 20 | 21 | """ 22 | 23 | if device == 'cpu': 24 | logger.info('Use CPU for training') 25 | 26 | elif ',' in device: # multi-gpu 27 | logger.error('Multi-GPU currently not supported') 28 | 29 | else: 30 | logger.info(f'set gpu {device}') 31 | os.environ['CUDA_VISIBLE_DEVICES'] = device 32 | assert torch.cuda.is_available() 33 | 34 | cuda = device != 'cpu' and torch.cuda.is_available() 35 | device = torch.device('cuda:0' if cuda else 'cpu') 36 | return device -------------------------------------------------------------------------------- /tracker/tracking_utils/tools.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import os 4 | 5 | def save_results(save_dir, seq_name, results, data_type='default'): 6 | """ 7 | write results to txt file 8 | 9 | results: list row format: frame id, target id, box coordinate, class(optional) 10 | to_file: file path(optional) 11 | data_type: 'default' | 'mot_challenge', write data format, default or MOT submission 12 | """ 13 | assert len(results) 14 | 15 | if not os.path.exists(save_dir): 16 | os.makedirs(save_dir) 17 | 18 | with open(os.path.join(save_dir, seq_name + '.txt'), 'w') as f: 19 | for frame_id, target_ids, tlwhs, clses, scores in results: 20 | for id, tlwh, score in zip(target_ids, tlwhs, scores): 21 | f.write(f'{frame_id},{id},{tlwh[0]:.2f},{tlwh[1]:.2f},{tlwh[2]:.2f},{tlwh[3]:.2f},{score:.2f},-1,-1,-1\n') 22 | 23 | f.close() 24 | 25 | return save_dir 26 | -------------------------------------------------------------------------------- /tracker/tracking_utils/visualization.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import os 3 | import numpy as np 4 | from PIL import Image 5 | 6 | def plot_img(img, frame_id, results, save_dir): 7 | """ 8 | img: np.ndarray: (H, W, C) 9 | frame_id: int 10 | results: [tlwhs, ids, clses] 11 | save_dir: sr 12 | 13 | plot images with bboxes of a seq 14 | """ 15 | if not os.path.exists(save_dir): 16 | os.makedirs(save_dir) 17 | 18 | assert img is not None 19 | 20 | if len(img.shape) > 3: 21 | img = img.squeeze(0) 22 | 23 | img_ = np.ascontiguousarray(np.copy(img)) 24 | 25 | tlwhs, ids, clses = results[0], results[1], results[2] 26 | for tlwh, id, cls in zip(tlwhs, ids, clses): 27 | 28 | # convert tlwh to tlbr 29 | tlbr = tuple([int(tlwh[0]), int(tlwh[1]), int(tlwh[0] + tlwh[2]), int(tlwh[1] + tlwh[3])]) 30 | # draw a rect 31 | cv2.rectangle(img_, tlbr[:2], tlbr[2:], get_color(id), thickness=3, ) 32 | # note the id and cls 33 | text = f'{int(cls)}_{id}' 34 | cv2.putText(img_, text, (tlbr[0], tlbr[1]), fontFace=cv2.FONT_HERSHEY_PLAIN, fontScale=1, 35 | color=(255, 164, 0), thickness=2) 36 | 37 | cv2.imwrite(filename=os.path.join(save_dir, f'{frame_id:05d}.jpg'), img=img_) 38 | 39 | def get_color(idx): 40 | """ 41 | aux func for plot_seq 42 | get a unique color for each id 43 | """ 44 | idx = idx * 3 45 | color = ((37 * idx) % 255, (17 * idx) % 255, (29 * idx) % 255) 46 | 47 | return color 48 | 49 | def save_video(images_path): 50 | """ 51 | save images (frames) to a video 52 | """ 53 | 54 | images_list = sorted(os.listdir(images_path)) 55 | save_video_path = os.path.join(images_path, images_path.split('/')[-1] + '.mp4') 56 | 57 | fourcc = cv2.VideoWriter_fourcc(*"mp4v") 58 | 59 | img0 = Image.open(os.path.join(images_path, images_list[0])) 60 | vw = cv2.VideoWriter(save_video_path, fourcc, 15, img0.size) 61 | 62 | for image_name in images_list: 63 | image = cv2.imread(filename=os.path.join(images_path, image_name)) 64 | vw.write(image) 65 | -------------------------------------------------------------------------------- /tracker/yolo_ultralytics_utils/data_cfgs/airmot.yaml: -------------------------------------------------------------------------------- 1 | train: /data/wujiapeng/codes/DroneGraphTracker/airmot/train.txt 2 | val: /data/wujiapeng/codes/DroneGraphTracker/airmot/test.txt 3 | test: /data/wujiapeng/codes/DroneGraphTracker/airmot/test.txt 4 | 5 | nc: 2 6 | 7 | names: ['plane', 'ship'] -------------------------------------------------------------------------------- /tracker/yolo_ultralytics_utils/data_cfgs/uavdt.yaml: -------------------------------------------------------------------------------- 1 | train: /data/wujiapeng/codes/DroneGraphTracker/uavdt/train.txt 2 | val: /data/wujiapeng/codes/DroneGraphTracker/uavdt/test.txt 3 | test: /data/wujiapeng/codes/DroneGraphTracker/uavdt/test.txt 4 | 5 | nc: 1 6 | 7 | names: ['car'] -------------------------------------------------------------------------------- /tracker/yolo_ultralytics_utils/data_cfgs/visdrone.yaml: -------------------------------------------------------------------------------- 1 | train: /data/wujiapeng/codes/DroneGraphTracker/visdrone/train.txt 2 | val: /data/wujiapeng/codes/DroneGraphTracker/visdrone/test.txt 3 | test: /data/wujiapeng/codes/DroneGraphTracker/visdrone/test.txt 4 | 5 | nc: 5 6 | 7 | names: ['pedestrain', 'car', 'van', 'truck', 'bus'] -------------------------------------------------------------------------------- /tracker/yolo_ultralytics_utils/data_cfgs/visdrone_det.yaml: -------------------------------------------------------------------------------- 1 | train: /data/wujiapeng/codes/DroneGraphTracker/visdrone_det/train.txt 2 | val: /data/wujiapeng/codes/DroneGraphTracker/visdrone_det/test.txt 3 | test: /data/wujiapeng/codes/DroneGraphTracker/visdrone_det/test.txt 4 | 5 | nc: 5 6 | 7 | names: ['pedestrain', 'car', 'van', 'truck', 'bus'] -------------------------------------------------------------------------------- /tracker/yolo_ultralytics_utils/postprocess.py: -------------------------------------------------------------------------------- 1 | from ultralytics import YOLO 2 | 3 | def postprocess(out): 4 | 5 | out = out[0].boxes 6 | return out.data -------------------------------------------------------------------------------- /tracker/yolo_ultralytics_utils/train_yolo_ultralytics.py: -------------------------------------------------------------------------------- 1 | import torch 2 | from ultralytics import YOLO 3 | import numpy as np 4 | 5 | import argparse 6 | 7 | def main(args): 8 | """ main func 9 | 10 | """ 11 | 12 | model = YOLO(model=args.model_weight) 13 | model.train( 14 | data=args.data_cfg, 15 | epochs=args.epochs, 16 | batch=args.batch_size, 17 | imgsz=args.img_sz, 18 | patience=50, # epochs to wait for no observable improvement for early stopping of training 19 | device=args.device, 20 | ) 21 | 22 | 23 | if __name__ == '__main__': 24 | parser = argparse.ArgumentParser("YOLO train parser") 25 | 26 | parser.add_argument('--model', type=str, default='yolov8s.yaml', help='yaml or pt file') 27 | parser.add_argument('--model_weight', type=str, default='yolov8s.pt', help='') 28 | parser.add_argument('--data_cfg', type=str, default='yolov8_utils/data_cfgs/visdrone.yaml', help='') 29 | parser.add_argument('--epochs', type=int, default=30, help='') 30 | parser.add_argument('--batch_size', type=int, default=8, help='') 31 | parser.add_argument('--img_sz', type=int, default=1280, help='') 32 | parser.add_argument('--device', type=str, default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') 33 | 34 | args = parser.parse_args() 35 | 36 | main(args) 37 | 38 | # python tracker/yolo_ultralytics_utils/train_yolo_ultralytics.py --model_weight weights/yolo11m.pt --data_cfg tracker/yolo_ultralytics_utils/data_cfgs/visdrone_det.yaml --epochs 30 --batch_size 8 --img_sz 1280 --device 0 -------------------------------------------------------------------------------- /tracker/yolov7_utils/postprocess.py: -------------------------------------------------------------------------------- 1 | from utils.general import non_max_suppression, scale_coords 2 | 3 | def postprocess(out, conf_thresh, nms_thresh, img_size, ori_img_size): 4 | """ 5 | Args: 6 | out: out from v7 model 7 | det_config: configs 8 | """ 9 | 10 | out = out[0] 11 | out = non_max_suppression(out, conf_thresh, nms_thresh, )[0] 12 | out[:, :4] = scale_coords(img_size, out[:, :4], ori_img_size, ratio_pad=None).round() 13 | 14 | # out: tlbr, conf, cls 15 | 16 | return out -------------------------------------------------------------------------------- /tracker/yolox_utils/postprocess.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | from yolox.utils import postprocess 4 | 5 | def postprocess_yolox(out, num_classes, conf_thresh, img, ori_img): 6 | """ 7 | convert out to -> (tlbr, conf, cls) 8 | """ 9 | 10 | out = postprocess(out, num_classes, conf_thresh, )[0] # (tlbr, obj_conf, cls_conf, cls) 11 | 12 | if out is None: return out 13 | 14 | # merge conf 15 | out[:, 4] *= out[:, 5] 16 | out[:, 5] = out[:, -1] 17 | out = out[:, :-1] 18 | 19 | # scale to origin size 20 | 21 | img_size = [img.shape[-2], img.shape[-1]] # h, w 22 | ori_img_size = [ori_img.shape[0], ori_img.shape[1]] # h0, w0 23 | img_h, img_w = img_size[0], img_size[1] 24 | 25 | scale = min(float(img_h) / ori_img_size[0], float(img_w) / ori_img_size[1]) 26 | 27 | out[:, :4] /= scale 28 | 29 | return out 30 | -------------------------------------------------------------------------------- /tracker/yolox_utils/train_yolox.py: -------------------------------------------------------------------------------- 1 | from loguru import logger 2 | 3 | import torch 4 | import torch.backends.cudnn as cudnn 5 | 6 | from yolox.core import Trainer, launch 7 | from yolox.exp import get_exp 8 | 9 | import argparse 10 | import random 11 | import warnings 12 | 13 | 14 | def make_parser(): 15 | parser = argparse.ArgumentParser("YOLOX train parser") 16 | parser.add_argument("-expn", "--experiment-name", type=str, default=None) 17 | parser.add_argument("-n", "--name", type=str, default=None, help="model name") 18 | 19 | # distributed 20 | parser.add_argument( 21 | "--dist-backend", default="nccl", type=str, help="distributed backend" 22 | ) 23 | parser.add_argument( 24 | "--dist-url", 25 | default=None, 26 | type=str, 27 | help="url used to set up distributed training", 28 | ) 29 | parser.add_argument("-b", "--batch-size", type=int, default=64, help="batch size") 30 | parser.add_argument( 31 | "-d", "--devices", default=None, type=int, help="device for training" 32 | ) 33 | parser.add_argument( 34 | "--local_rank", default=0, type=int, help="local rank for dist training" 35 | ) 36 | parser.add_argument( 37 | "-f", 38 | "--exp_file", 39 | default=None, 40 | type=str, 41 | help="plz input your expriment description file", 42 | ) 43 | parser.add_argument( 44 | "--resume", default=False, action="store_true", help="resume training" 45 | ) 46 | parser.add_argument("-c", "--ckpt", default=None, type=str, help="checkpoint file") 47 | parser.add_argument( 48 | "-e", 49 | "--start_epoch", 50 | default=None, 51 | type=int, 52 | help="resume training start epoch", 53 | ) 54 | parser.add_argument( 55 | "--num_machines", default=1, type=int, help="num of node for training" 56 | ) 57 | parser.add_argument( 58 | "--machine_rank", default=0, type=int, help="node rank for multi-node training" 59 | ) 60 | parser.add_argument( 61 | "--fp16", 62 | dest="fp16", 63 | default=True, 64 | action="store_true", 65 | help="Adopting mix precision training.", 66 | ) 67 | parser.add_argument( 68 | "-o", 69 | "--occupy", 70 | dest="occupy", 71 | default=False, 72 | action="store_true", 73 | help="occupy GPU memory first for training.", 74 | ) 75 | parser.add_argument( 76 | "opts", 77 | help="Modify config options using the command-line", 78 | default=None, 79 | nargs=argparse.REMAINDER, 80 | ) 81 | return parser 82 | 83 | 84 | @logger.catch 85 | def main(exp, args): 86 | if exp.seed is not None: 87 | random.seed(exp.seed) 88 | torch.manual_seed(exp.seed) 89 | cudnn.deterministic = True 90 | warnings.warn( 91 | "You have chosen to seed training. This will turn on the CUDNN deterministic setting, " 92 | "which can slow down your training considerably! You may see unexpected behavior " 93 | "when restarting from checkpoints." 94 | ) 95 | 96 | # set environment variables for distributed training 97 | cudnn.benchmark = True 98 | 99 | trainer = Trainer(exp, args) 100 | trainer.train() 101 | 102 | 103 | if __name__ == "__main__": 104 | args = make_parser().parse_args() 105 | exp = get_exp(args.exp_file, args.name) 106 | exp.merge(args.opts) 107 | 108 | if not args.experiment_name: 109 | args.experiment_name = exp.exp_name 110 | 111 | num_gpu = torch.cuda.device_count() if args.devices is None else args.devices 112 | assert num_gpu <= torch.cuda.device_count() 113 | 114 | launch( 115 | main, 116 | num_gpu, 117 | args.num_machines, 118 | args.machine_rank, 119 | backend=args.dist_backend, 120 | dist_url=args.dist_url, 121 | args=(exp, args), 122 | ) 123 | -------------------------------------------------------------------------------- /tracker/yolox_utils/yolox_m.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import os 3 | import random 4 | import torch 5 | import torch.nn as nn 6 | import torch.distributed as dist 7 | 8 | from yolox.exp import Exp as MyExp 9 | from yolox.data import get_yolox_datadir 10 | 11 | class Exp(MyExp): 12 | def __init__(self): 13 | super(Exp, self).__init__() 14 | self.num_classes = 1 # 1 for uavdt mot17 15 | self.depth = 0.67 16 | self.width = 0.75 17 | self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0] 18 | self.train_ann = "train.json" 19 | self.val_ann = "test.json" 20 | self.input_size = (800, 1440) 21 | self.test_size = (800, 1440) 22 | self.random_size = (18, 32) 23 | self.max_epoch = 80 24 | self.print_interval = 20 25 | self.eval_interval = 5 26 | self.test_conf = 0.001 27 | self.nmsthre = 0.7 28 | self.no_aug_epochs = 10 29 | self.basic_lr_per_img = 0.001 / 64.0 30 | self.warmup_epochs = 1 31 | 32 | def get_data_loader(self, batch_size, is_distributed, no_aug=False): 33 | from yolox.data import ( 34 | TrainTransform, 35 | YoloBatchSampler, 36 | DataLoader, 37 | InfiniteSampler, 38 | MosaicDetection, 39 | ) 40 | 41 | from mot_dataset import MOTDataset 42 | 43 | dataset = MOTDataset( 44 | # data_dir=os.path.join(get_yolox_datadir(), "mot"), 45 | # data_dir='/data/wujiapeng/datasets/UAVDT', 46 | data_dir='/data/wujiapeng/datasets/VisDrone2019/VisDrone2019', 47 | json_file=self.train_ann, 48 | name='train', 49 | img_size=self.input_size, 50 | preproc=TrainTransform( 51 | rgb_means=(0.485, 0.456, 0.406), 52 | std=(0.229, 0.224, 0.225), 53 | max_labels=500, 54 | ), 55 | ) 56 | 57 | dataset = MosaicDetection( 58 | dataset, 59 | mosaic=not no_aug, 60 | img_size=self.input_size, 61 | preproc=TrainTransform( 62 | rgb_means=(0.485, 0.456, 0.406), 63 | std=(0.229, 0.224, 0.225), 64 | max_labels=1000, 65 | ), 66 | degrees=self.degrees, 67 | translate=self.translate, 68 | scale=self.scale, 69 | shear=self.shear, 70 | perspective=self.perspective, 71 | enable_mixup=self.enable_mixup, 72 | ) 73 | 74 | self.dataset = dataset 75 | 76 | if is_distributed: 77 | batch_size = batch_size // dist.get_world_size() 78 | 79 | sampler = InfiniteSampler( 80 | len(self.dataset), seed=self.seed if self.seed else 0 81 | ) 82 | 83 | batch_sampler = YoloBatchSampler( 84 | sampler=sampler, 85 | batch_size=batch_size, 86 | drop_last=False, 87 | input_dimension=self.input_size, 88 | mosaic=not no_aug, 89 | ) 90 | 91 | dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True} 92 | dataloader_kwargs["batch_sampler"] = batch_sampler 93 | train_loader = DataLoader(self.dataset, **dataloader_kwargs) 94 | 95 | return train_loader 96 | 97 | def get_eval_loader(self, batch_size, is_distributed, testdev=False): 98 | from yolox.data import ValTransform 99 | from mot_dataset import MOTDataset 100 | 101 | valdataset = MOTDataset( 102 | # data_dir=os.path.join(get_yolox_datadir(), "mot"), 103 | # data_dir='/data/wujiapeng/datasets/UAVDT', 104 | data_dir='/data/wujiapeng/datasets/VisDrone2019/VisDrone2019', 105 | json_file=self.val_ann, 106 | img_size=self.test_size, 107 | name='test', 108 | preproc=ValTransform( 109 | rgb_means=(0.485, 0.456, 0.406), 110 | std=(0.229, 0.224, 0.225), 111 | ), 112 | ) 113 | 114 | if is_distributed: 115 | batch_size = batch_size // dist.get_world_size() 116 | sampler = torch.utils.data.distributed.DistributedSampler( 117 | valdataset, shuffle=False 118 | ) 119 | else: 120 | sampler = torch.utils.data.SequentialSampler(valdataset) 121 | 122 | dataloader_kwargs = { 123 | "num_workers": self.data_num_workers, 124 | "pin_memory": True, 125 | "sampler": sampler, 126 | } 127 | dataloader_kwargs["batch_size"] = batch_size 128 | val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs) 129 | 130 | return val_loader 131 | 132 | def get_evaluator(self, batch_size, is_distributed, testdev=False): 133 | from yolox.evaluators import COCOEvaluator 134 | 135 | val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev) 136 | evaluator = COCOEvaluator( 137 | dataloader=val_loader, 138 | img_size=self.test_size, 139 | confthre=self.test_conf, 140 | nmsthre=self.nmsthre, 141 | num_classes=self.num_classes, 142 | testdev=testdev, 143 | ) 144 | return evaluator 145 | -------------------------------------------------------------------------------- /tracker/yolox_utils/yolox_x.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import os 3 | import random 4 | import torch 5 | import torch.nn as nn 6 | import torch.distributed as dist 7 | 8 | from yolox.exp import Exp as MyExp 9 | from yolox.data import get_yolox_datadir 10 | 11 | class Exp(MyExp): 12 | def __init__(self): 13 | super(Exp, self).__init__() 14 | self.num_classes = 1 15 | self.depth = 1.33 16 | self.width = 1.25 17 | self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0] 18 | self.train_ann = "train.json" 19 | self.val_ann = "test.json" 20 | self.input_size = (800, 1440) 21 | self.test_size = (800, 1440) 22 | self.random_size = (18, 32) 23 | self.max_epoch = 80 24 | self.print_interval = 20 25 | self.eval_interval = 5 26 | self.test_conf = 0.001 27 | self.nmsthre = 0.7 28 | self.no_aug_epochs = 10 29 | self.basic_lr_per_img = 0.001 / 64.0 30 | self.warmup_epochs = 1 31 | 32 | def get_data_loader(self, batch_size, is_distributed, no_aug=False): 33 | from yolox.data import ( 34 | TrainTransform, 35 | YoloBatchSampler, 36 | DataLoader, 37 | InfiniteSampler, 38 | MosaicDetection, 39 | ) 40 | 41 | from mot_dataset import MOTDataset 42 | 43 | dataset = MOTDataset( 44 | # data_dir=os.path.join(get_yolox_datadir(), "mot"), 45 | data_dir='/data/wujiapeng/datasets/UAVDT', 46 | json_file=self.train_ann, 47 | name='train', 48 | img_size=self.input_size, 49 | preproc=TrainTransform( 50 | rgb_means=(0.485, 0.456, 0.406), 51 | std=(0.229, 0.224, 0.225), 52 | max_labels=500, 53 | ), 54 | ) 55 | 56 | dataset = MosaicDetection( 57 | dataset, 58 | mosaic=not no_aug, 59 | img_size=self.input_size, 60 | preproc=TrainTransform( 61 | rgb_means=(0.485, 0.456, 0.406), 62 | std=(0.229, 0.224, 0.225), 63 | max_labels=1000, 64 | ), 65 | degrees=self.degrees, 66 | translate=self.translate, 67 | scale=self.scale, 68 | shear=self.shear, 69 | perspective=self.perspective, 70 | enable_mixup=self.enable_mixup, 71 | ) 72 | 73 | self.dataset = dataset 74 | 75 | if is_distributed: 76 | batch_size = batch_size // dist.get_world_size() 77 | 78 | sampler = InfiniteSampler( 79 | len(self.dataset), seed=self.seed if self.seed else 0 80 | ) 81 | 82 | batch_sampler = YoloBatchSampler( 83 | sampler=sampler, 84 | batch_size=batch_size, 85 | drop_last=False, 86 | input_dimension=self.input_size, 87 | mosaic=not no_aug, 88 | ) 89 | 90 | dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True} 91 | dataloader_kwargs["batch_sampler"] = batch_sampler 92 | train_loader = DataLoader(self.dataset, **dataloader_kwargs) 93 | 94 | return train_loader 95 | 96 | def get_eval_loader(self, batch_size, is_distributed, testdev=False): 97 | from yolox.data import ValTransform 98 | from mot_dataset import MOTDataset 99 | 100 | valdataset = MOTDataset( 101 | # data_dir=os.path.join(get_yolox_datadir(), "mot"), 102 | data_dir='/data/wujiapeng/datasets/UAVDT', 103 | json_file=self.val_ann, 104 | img_size=self.test_size, 105 | name='test', 106 | preproc=ValTransform( 107 | rgb_means=(0.485, 0.456, 0.406), 108 | std=(0.229, 0.224, 0.225), 109 | ), 110 | ) 111 | 112 | if is_distributed: 113 | batch_size = batch_size // dist.get_world_size() 114 | sampler = torch.utils.data.distributed.DistributedSampler( 115 | valdataset, shuffle=False 116 | ) 117 | else: 118 | sampler = torch.utils.data.SequentialSampler(valdataset) 119 | 120 | dataloader_kwargs = { 121 | "num_workers": self.data_num_workers, 122 | "pin_memory": True, 123 | "sampler": sampler, 124 | } 125 | dataloader_kwargs["batch_size"] = batch_size 126 | val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs) 127 | 128 | return val_loader 129 | 130 | def get_evaluator(self, batch_size, is_distributed, testdev=False): 131 | from yolox.evaluators import COCOEvaluator 132 | 133 | val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev) 134 | evaluator = COCOEvaluator( 135 | dataloader=val_loader, 136 | img_size=self.test_size, 137 | confthre=self.test_conf, 138 | nmsthre=self.nmsthre, 139 | num_classes=self.num_classes, 140 | testdev=testdev, 141 | ) 142 | return evaluator 143 | -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- 1 | # init -------------------------------------------------------------------------------- /utils/activations.py: -------------------------------------------------------------------------------- 1 | # Activation functions 2 | 3 | import torch 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | 7 | 8 | # SiLU https://arxiv.org/pdf/1606.08415.pdf ---------------------------------------------------------------------------- 9 | class SiLU(nn.Module): # export-friendly version of nn.SiLU() 10 | @staticmethod 11 | def forward(x): 12 | return x * torch.sigmoid(x) 13 | 14 | 15 | class Hardswish(nn.Module): # export-friendly version of nn.Hardswish() 16 | @staticmethod 17 | def forward(x): 18 | # return x * F.hardsigmoid(x) # for torchscript and CoreML 19 | return x * F.hardtanh(x + 3, 0., 6.) / 6. # for torchscript, CoreML and ONNX 20 | 21 | 22 | class MemoryEfficientSwish(nn.Module): 23 | class F(torch.autograd.Function): 24 | @staticmethod 25 | def forward(ctx, x): 26 | ctx.save_for_backward(x) 27 | return x * torch.sigmoid(x) 28 | 29 | @staticmethod 30 | def backward(ctx, grad_output): 31 | x = ctx.saved_tensors[0] 32 | sx = torch.sigmoid(x) 33 | return grad_output * (sx * (1 + x * (1 - sx))) 34 | 35 | def forward(self, x): 36 | return self.F.apply(x) 37 | 38 | 39 | # Mish https://github.com/digantamisra98/Mish -------------------------------------------------------------------------- 40 | class Mish(nn.Module): 41 | @staticmethod 42 | def forward(x): 43 | return x * F.softplus(x).tanh() 44 | 45 | 46 | class MemoryEfficientMish(nn.Module): 47 | class F(torch.autograd.Function): 48 | @staticmethod 49 | def forward(ctx, x): 50 | ctx.save_for_backward(x) 51 | return x.mul(torch.tanh(F.softplus(x))) # x * tanh(ln(1 + exp(x))) 52 | 53 | @staticmethod 54 | def backward(ctx, grad_output): 55 | x = ctx.saved_tensors[0] 56 | sx = torch.sigmoid(x) 57 | fx = F.softplus(x).tanh() 58 | return grad_output * (fx + x * sx * (1 - fx * fx)) 59 | 60 | def forward(self, x): 61 | return self.F.apply(x) 62 | 63 | 64 | # FReLU https://arxiv.org/abs/2007.11824 ------------------------------------------------------------------------------- 65 | class FReLU(nn.Module): 66 | def __init__(self, c1, k=3): # ch_in, kernel 67 | super().__init__() 68 | self.conv = nn.Conv2d(c1, c1, k, 1, 1, groups=c1, bias=False) 69 | self.bn = nn.BatchNorm2d(c1) 70 | 71 | def forward(self, x): 72 | return torch.max(x, self.bn(self.conv(x))) 73 | -------------------------------------------------------------------------------- /utils/aws/__init__.py: -------------------------------------------------------------------------------- 1 | #init -------------------------------------------------------------------------------- /utils/aws/mime.sh: -------------------------------------------------------------------------------- 1 | # AWS EC2 instance startup 'MIME' script https://aws.amazon.com/premiumsupport/knowledge-center/execute-user-data-ec2/ 2 | # This script will run on every instance restart, not only on first start 3 | # --- DO NOT COPY ABOVE COMMENTS WHEN PASTING INTO USERDATA --- 4 | 5 | Content-Type: multipart/mixed; boundary="//" 6 | MIME-Version: 1.0 7 | 8 | --// 9 | Content-Type: text/cloud-config; charset="us-ascii" 10 | MIME-Version: 1.0 11 | Content-Transfer-Encoding: 7bit 12 | Content-Disposition: attachment; filename="cloud-config.txt" 13 | 14 | #cloud-config 15 | cloud_final_modules: 16 | - [scripts-user, always] 17 | 18 | --// 19 | Content-Type: text/x-shellscript; charset="us-ascii" 20 | MIME-Version: 1.0 21 | Content-Transfer-Encoding: 7bit 22 | Content-Disposition: attachment; filename="userdata.txt" 23 | 24 | #!/bin/bash 25 | # --- paste contents of userdata.sh here --- 26 | --// 27 | -------------------------------------------------------------------------------- /utils/aws/resume.py: -------------------------------------------------------------------------------- 1 | # Resume all interrupted trainings in yolor/ dir including DDP trainings 2 | # Usage: $ python utils/aws/resume.py 3 | 4 | import os 5 | import sys 6 | from pathlib import Path 7 | 8 | import torch 9 | import yaml 10 | 11 | sys.path.append('./') # to run '$ python *.py' files in subdirectories 12 | 13 | port = 0 # --master_port 14 | path = Path('').resolve() 15 | for last in path.rglob('*/**/last.pt'): 16 | ckpt = torch.load(last) 17 | if ckpt['optimizer'] is None: 18 | continue 19 | 20 | # Load opt.yaml 21 | with open(last.parent.parent / 'opt.yaml') as f: 22 | opt = yaml.load(f, Loader=yaml.SafeLoader) 23 | 24 | # Get device count 25 | d = opt['device'].split(',') # devices 26 | nd = len(d) # number of devices 27 | ddp = nd > 1 or (nd == 0 and torch.cuda.device_count() > 1) # distributed data parallel 28 | 29 | if ddp: # multi-GPU 30 | port += 1 31 | cmd = f'python -m torch.distributed.launch --nproc_per_node {nd} --master_port {port} train.py --resume {last}' 32 | else: # single-GPU 33 | cmd = f'python train.py --resume {last}' 34 | 35 | cmd += ' > /dev/null 2>&1 &' # redirect output to dev/null and run in daemon thread 36 | print(cmd) 37 | os.system(cmd) 38 | -------------------------------------------------------------------------------- /utils/aws/userdata.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # AWS EC2 instance startup script https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html 3 | # This script will run only once on first instance start (for a re-start script see mime.sh) 4 | # /home/ubuntu (ubuntu) or /home/ec2-user (amazon-linux) is working dir 5 | # Use >300 GB SSD 6 | 7 | cd home/ubuntu 8 | if [ ! -d yolor ]; then 9 | echo "Running first-time script." # install dependencies, download COCO, pull Docker 10 | git clone -b paper https://github.com/WongKinYiu/yolor && sudo chmod -R 777 yolor 11 | cd yolor 12 | bash data/scripts/get_coco.sh && echo "Data done." & 13 | sudo docker pull nvcr.io/nvidia/pytorch:21.08-py3 && echo "Docker done." & 14 | python -m pip install --upgrade pip && pip install -r requirements.txt && python detect.py && echo "Requirements done." & 15 | wait && echo "All tasks done." # finish background tasks 16 | else 17 | echo "Running re-start script." # resume interrupted runs 18 | i=0 19 | list=$(sudo docker ps -qa) # container list i.e. $'one\ntwo\nthree\nfour' 20 | while IFS= read -r id; do 21 | ((i++)) 22 | echo "restarting container $i: $id" 23 | sudo docker start $id 24 | # sudo docker exec -it $id python train.py --resume # single-GPU 25 | sudo docker exec -d $id python utils/aws/resume.py # multi-scenario 26 | done <<<"$list" 27 | fi 28 | -------------------------------------------------------------------------------- /utils/google_app_engine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gcr.io/google-appengine/python 2 | 3 | # Create a virtualenv for dependencies. This isolates these packages from 4 | # system-level packages. 5 | # Use -p python3 or -p python3.7 to select python version. Default is version 2. 6 | RUN virtualenv /env -p python3 7 | 8 | # Setting these environment variables are the same as running 9 | # source /env/bin/activate. 10 | ENV VIRTUAL_ENV /env 11 | ENV PATH /env/bin:$PATH 12 | 13 | RUN apt-get update && apt-get install -y python-opencv 14 | 15 | # Copy the application's requirements.txt and run pip to install all 16 | # dependencies into the virtualenv. 17 | ADD requirements.txt /app/requirements.txt 18 | RUN pip install -r /app/requirements.txt 19 | 20 | # Add the application source code. 21 | ADD . /app 22 | 23 | # Run a WSGI server to serve the application. gunicorn must be declared as 24 | # a dependency in requirements.txt. 25 | CMD gunicorn -b :$PORT main:app 26 | -------------------------------------------------------------------------------- /utils/google_app_engine/app.yaml: -------------------------------------------------------------------------------- 1 | runtime: custom 2 | env: flex 3 | 4 | service: yolorapp 5 | 6 | liveness_check: 7 | initial_delay_sec: 600 8 | 9 | manual_scaling: 10 | instances: 1 11 | resources: 12 | cpu: 1 13 | memory_gb: 4 14 | disk_size_gb: 20 -------------------------------------------------------------------------------- /utils/google_utils.py: -------------------------------------------------------------------------------- 1 | # Google utils: https://cloud.google.com/storage/docs/reference/libraries 2 | 3 | import os 4 | import platform 5 | import subprocess 6 | import time 7 | from pathlib import Path 8 | 9 | import requests 10 | import torch 11 | 12 | 13 | def gsutil_getsize(url=''): 14 | # gs://bucket/file size https://cloud.google.com/storage/docs/gsutil/commands/du 15 | s = subprocess.check_output(f'gsutil du {url}', shell=True).decode('utf-8') 16 | return eval(s.split(' ')[0]) if len(s) else 0 # bytes 17 | 18 | 19 | def attempt_download(file, repo='WongKinYiu/yolov7'): 20 | # Attempt file download if does not exist 21 | file = Path(str(file).strip().replace("'", '').lower()) 22 | 23 | if not file.exists(): 24 | try: 25 | response = requests.get(f'https://api.github.com/repos/{repo}/releases/latest').json() # github api 26 | assets = [x['name'] for x in response['assets']] # release assets 27 | tag = response['tag_name'] # i.e. 'v1.0' 28 | except: # fallback plan 29 | assets = ['yolov7.pt'] 30 | tag = subprocess.check_output('git tag', shell=True).decode().split()[-1] 31 | 32 | name = file.name 33 | if name in assets: 34 | msg = f'{file} missing, try downloading from https://github.com/{repo}/releases/' 35 | redundant = False # second download option 36 | try: # GitHub 37 | url = f'https://github.com/{repo}/releases/download/{tag}/{name}' 38 | print(f'Downloading {url} to {file}...') 39 | torch.hub.download_url_to_file(url, file) 40 | assert file.exists() and file.stat().st_size > 1E6 # check 41 | except Exception as e: # GCP 42 | print(f'Download error: {e}') 43 | assert redundant, 'No secondary mirror' 44 | url = f'https://storage.googleapis.com/{repo}/ckpt/{name}' 45 | print(f'Downloading {url} to {file}...') 46 | os.system(f'curl -L {url} -o {file}') # torch.hub.download_url_to_file(url, weights) 47 | finally: 48 | if not file.exists() or file.stat().st_size < 1E6: # check 49 | file.unlink(missing_ok=True) # remove partial downloads 50 | print(f'ERROR: Download failure: {msg}') 51 | print('') 52 | return 53 | 54 | 55 | def gdrive_download(id='', file='tmp.zip'): 56 | # Downloads a file from Google Drive. from yolov7.utils.google_utils import *; gdrive_download() 57 | t = time.time() 58 | file = Path(file) 59 | cookie = Path('cookie') # gdrive cookie 60 | print(f'Downloading https://drive.google.com/uc?export=download&id={id} as {file}... ', end='') 61 | file.unlink(missing_ok=True) # remove existing file 62 | cookie.unlink(missing_ok=True) # remove existing cookie 63 | 64 | # Attempt file download 65 | out = "NUL" if platform.system() == "Windows" else "/dev/null" 66 | os.system(f'curl -c ./cookie -s -L "drive.google.com/uc?export=download&id={id}" > {out}') 67 | if os.path.exists('cookie'): # large file 68 | s = f'curl -Lb ./cookie "drive.google.com/uc?export=download&confirm={get_token()}&id={id}" -o {file}' 69 | else: # small file 70 | s = f'curl -s -L -o {file} "drive.google.com/uc?export=download&id={id}"' 71 | r = os.system(s) # execute, capture return 72 | cookie.unlink(missing_ok=True) # remove existing cookie 73 | 74 | # Error check 75 | if r != 0: 76 | file.unlink(missing_ok=True) # remove partial 77 | print('Download error ') # raise Exception('Download error') 78 | return r 79 | 80 | # Unzip if archive 81 | if file.suffix == '.zip': 82 | print('unzipping... ', end='') 83 | os.system(f'unzip -q {file}') # unzip 84 | file.unlink() # remove zip to free space 85 | 86 | print(f'Done ({time.time() - t:.1f}s)') 87 | return r 88 | 89 | 90 | def get_token(cookie="./cookie"): 91 | with open(cookie) as f: 92 | for line in f: 93 | if "download" in line: 94 | return line.split()[-1] 95 | return "" 96 | 97 | # def upload_blob(bucket_name, source_file_name, destination_blob_name): 98 | # # Uploads a file to a bucket 99 | # # https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-python 100 | # 101 | # storage_client = storage.Client() 102 | # bucket = storage_client.get_bucket(bucket_name) 103 | # blob = bucket.blob(destination_blob_name) 104 | # 105 | # blob.upload_from_filename(source_file_name) 106 | # 107 | # print('File {} uploaded to {}.'.format( 108 | # source_file_name, 109 | # destination_blob_name)) 110 | # 111 | # 112 | # def download_blob(bucket_name, source_blob_name, destination_file_name): 113 | # # Uploads a blob from a bucket 114 | # storage_client = storage.Client() 115 | # bucket = storage_client.get_bucket(bucket_name) 116 | # blob = bucket.blob(source_blob_name) 117 | # 118 | # blob.download_to_filename(destination_file_name) 119 | # 120 | # print('Blob {} downloaded to {}.'.format( 121 | # source_blob_name, 122 | # destination_file_name)) 123 | -------------------------------------------------------------------------------- /utils/wandb_logging/__init__.py: -------------------------------------------------------------------------------- 1 | # init -------------------------------------------------------------------------------- /utils/wandb_logging/__pycache__/__init__.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/utils/wandb_logging/__pycache__/__init__.cpython-37.pyc -------------------------------------------------------------------------------- /utils/wandb_logging/__pycache__/wandb_utils.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/utils/wandb_logging/__pycache__/wandb_utils.cpython-37.pyc -------------------------------------------------------------------------------- /utils/wandb_logging/log_dataset.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | import yaml 4 | 5 | from wandb_utils import WandbLogger 6 | 7 | WANDB_ARTIFACT_PREFIX = 'wandb-artifact://' 8 | 9 | 10 | def create_dataset_artifact(opt): 11 | with open(opt.data) as f: 12 | data = yaml.load(f, Loader=yaml.SafeLoader) # data dict 13 | logger = WandbLogger(opt, '', None, data, job_type='Dataset Creation') 14 | 15 | 16 | if __name__ == '__main__': 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument('--data', type=str, default='data/coco.yaml', help='data.yaml path') 19 | parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset') 20 | parser.add_argument('--project', type=str, default='YOLOR', help='name of W&B Project') 21 | opt = parser.parse_args() 22 | opt.resume = False # Explicitly disallow resume check for dataset upload job 23 | 24 | create_dataset_artifact(opt) 25 | -------------------------------------------------------------------------------- /weights/DHN.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/weights/DHN.pth -------------------------------------------------------------------------------- /weights/ckpt.t7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/weights/ckpt.t7 -------------------------------------------------------------------------------- /weights/osnet_x0_25.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JackWoo0831/Yolov7-tracker/ae281420953a40230a5c97689bcabd53614f9e65/weights/osnet_x0_25.pth --------------------------------------------------------------------------------