您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
Merge `develop` branch into `master` (#3518) * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * update ci-testing.yml (#3322) * update ci-testing.yml * update greetings.yml * bring back os matrix * Enable direct `--weights URL` definition (#3373) * Enable direct `--weights URL` definition @KalenMike this PR will enable direct --weights URL definition. Example use case: ``` python train.py --weights https://storage.googleapis.com/bucket/dir/model.pt ``` * cleanup * bug fixes * weights = attempt_download(weights) * Update experimental.py * Update hubconf.py * return bug fix * comment mirror * min_bytes * Update tutorial.ipynb (#3368) add Open in Kaggle badge * `cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379) * Update datasets.py * comment Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * COCO evolution fix (#3388) * COCO evolution fix * cleanup * update print * print fix * Create `is_pip()` function (#3391) Returns `True` if file is part of pip package. Useful for contextual behavior modification. ```python def is_pip(): # Is file in a pip package? return 'site-packages' in Path(__file__).absolute().parts ``` * Revert "`cv2.imread(img, -1)` for IMREAD_UNCHANGED (#3379)" (#3395) This reverts commit 21a9607e00f1365b21d8c4bd81bdbf5fc0efea24. * Update FLOPs description (#3422) * Update README.md * Changing FLOPS to FLOPs. Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> * Parse URL authentication (#3424) * Parse URL authentication * urllib.parse.unquote() * improved error handling * improved error handling * remove %3F * update check_file() * Add FLOPs title to table (#3453) * Suppress jit trace warning + graph once (#3454) * Suppress jit trace warning + graph once Suppress harmless jit trace warning on TensorBoard add_graph call. Also fix multiple add_graph() calls bug, now only on batch 0. * Update train.py * Update MixUp augmentation `alpha=beta=32.0` (#3455) Per VOC empirical results https://github.com/ultralytics/yolov5/issues/3380#issuecomment-853001307 by @developer0hye * Add `timeout()` class (#3460) * Add `timeout()` class * rearrange order * Faster HSV augmentation (#3462) remove datatype conversion process that can be skipped * Add `check_git_status()` 5 second timeout (#3464) * Add check_git_status() 5 second timeout This should prevent the SSH Git bug that we were discussing @KalenMike * cleanup * replace timeout with check_output built-in timeout * Improved `check_requirements()` offline-handling (#3466) Improve robustness of `check_requirements()` function to offline environments (do not attempt pip installs when offline). * Add `output_names` argument for ONNX export with dynamic axes (#3456) * Add output names & dynamic axes for onnx export Add output_names and dynamic_axes names for all outputs in torch.onnx.export. The first four outputs of the model will have names output0, output1, output2, output3 * use first output only + cleanup Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Revert FP16 `test.py` and `detect.py` inference to FP32 default (#3423) * fixed inference bug ,while use half precision * replace --use-half with --half * replace space and PEP8 in detect.py * PEP8 detect.py * update --half help comment * Update test.py * revert space Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * Add additional links/resources to stale.yml message (#3467) * Update stale.yml * cleanup * Update stale.yml * reformat * Update stale.yml HUB URL (#3468) * Stale `github.actor` bug fix (#3483) * Explicit `model.eval()` call `if opt.train=False` (#3475) * call model.eval() when opt.train is False call model.eval() when opt.train is False * single-line if statement * cleanup Co-authored-by: Glenn Jocher <glenn.jocher@ultralytics.com> * check_requirements() exclude `opencv-python` (#3495) Fix for 3rd party or contrib versions of installed OpenCV as in https://github.com/ultralytics/yolov5/issues/3494. * Earlier `assert` for cpu and half option (#3508) * early assert for cpu and half option early assert for cpu and half option * Modified comment Modified comment * Update tutorial.ipynb (#3510) * Reduce test.py results spacing (#3511) * Update README.md (#3512) * Update README.md Minor modifications * 850 width * Update greetings.yml revert greeting change as PRs will now merge to master. Co-authored-by: Piotr Skalski <SkalskiP@users.noreply.github.com> Co-authored-by: SkalskiP <piotr.skalski92@gmail.com> Co-authored-by: Peretz Cohen <pizzaz93@users.noreply.github.com> Co-authored-by: tudoulei <34886368+tudoulei@users.noreply.github.com> Co-authored-by: chocosaj <chocosaj@users.noreply.github.com> Co-authored-by: BuildTools <unconfigured@null.spigotmc.org> Co-authored-by: Yonghye Kwon <developer.0hye@gmail.com> Co-authored-by: Sam_S <SamSamhuns@users.noreply.github.com> Co-authored-by: Samridha Shrestha <samridha.shrestha@g42.ai> Co-authored-by: edificewang <609552430@qq.com>
3 年前
YOLOv5 Segmentation Dataloader Updates (#2188) * Update C3 module * Update C3 module * Update C3 module * Update C3 module * update * update * update * update * update * update * update * update * update * updates * updates * updates * updates * updates * updates * updates * updates * updates * updates * update * update * update * update * updates * updates * updates * updates * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update datasets * update * update * update * update attempt_downlaod() * merge * merge * update * update * update * update * update * update * update * update * update * update * parameterize eps * comments * gs-multiple * update * max_nms implemented * Create one_cycle() function * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * GitHub API rate limit fix * update * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * astuple * epochs * update * update * ComputeLoss() * update * update * update * update * update * update * update * update * update * update * update * merge * merge * merge * merge * update * update * update * update * commit=tag == tags[-1] * Update cudnn.benchmark * update * update * update * updates * updates * updates * updates * updates * updates * updates * update * update * update * update * update * mosaic9 * update * update * update * update * update * update * institute cache versioning * only display on existing cache * reverse cache exists booleans
3 年前
YOLOv5 Segmentation Dataloader Updates (#2188) * Update C3 module * Update C3 module * Update C3 module * Update C3 module * update * update * update * update * update * update * update * update * update * updates * updates * updates * updates * updates * updates * updates * updates * updates * updates * update * update * update * update * updates * updates * updates * updates * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update datasets * update * update * update * update attempt_downlaod() * merge * merge * update * update * update * update * update * update * update * update * update * update * parameterize eps * comments * gs-multiple * update * max_nms implemented * Create one_cycle() function * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * GitHub API rate limit fix * update * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * astuple * epochs * update * update * ComputeLoss() * update * update * update * update * update * update * update * update * update * update * update * merge * merge * merge * merge * update * update * update * update * commit=tag == tags[-1] * Update cudnn.benchmark * update * update * update * updates * updates * updates * updates * updates * updates * updates * update * update * update * update * update * mosaic9 * update * update * update * update * update * update * institute cache versioning * only display on existing cache * reverse cache exists booleans
3 年前
YOLOv5 Segmentation Dataloader Updates (#2188) * Update C3 module * Update C3 module * Update C3 module * Update C3 module * update * update * update * update * update * update * update * update * update * updates * updates * updates * updates * updates * updates * updates * updates * updates * updates * update * update * update * update * updates * updates * updates * updates * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update datasets * update * update * update * update attempt_downlaod() * merge * merge * update * update * update * update * update * update * update * update * update * update * parameterize eps * comments * gs-multiple * update * max_nms implemented * Create one_cycle() function * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * update * GitHub API rate limit fix * update * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * ComputeLoss * astuple * epochs * update * update * ComputeLoss() * update * update * update * update * update * update * update * update * update * update * update * merge * merge * merge * merge * update * update * update * update * commit=tag == tags[-1] * Update cudnn.benchmark * update * update * update * updates * updates * updates * updates * updates * updates * updates * update * update * update * update * update * mosaic9 * update * update * update * update * update * update * institute cache versioning * only display on existing cache * reverse cache exists booleans
3 年前
4 年前
4 年前
4 年前
4 年前
4 年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. # YOLOv5 🚀 by Ultralytics, GPL-3.0 license
  2. """
  3. General utils
  4. """
  5. import contextlib
  6. import glob
  7. import logging
  8. import math
  9. import os
  10. import platform
  11. import random
  12. import re
  13. import signal
  14. import time
  15. import urllib
  16. from itertools import repeat
  17. from multiprocessing.pool import ThreadPool
  18. from pathlib import Path
  19. from subprocess import check_output
  20. from zipfile import ZipFile
  21. import cv2
  22. import numpy as np
  23. import pandas as pd
  24. import pkg_resources as pkg
  25. import torch
  26. import torchvision
  27. import yaml
  28. from utils.downloads import gsutil_getsize
  29. from utils.metrics import box_iou, fitness
  30. # Settings
  31. torch.set_printoptions(linewidth=320, precision=5, profile='long')
  32. np.set_printoptions(linewidth=320, formatter={'float_kind': '{:11.5g}'.format}) # format short g, %precision=5
  33. pd.options.display.max_columns = 10
  34. cv2.setNumThreads(0) # prevent OpenCV from multithreading (incompatible with PyTorch DataLoader)
  35. os.environ['NUMEXPR_MAX_THREADS'] = str(min(os.cpu_count(), 8)) # NumExpr max threads
  36. FILE = Path(__file__).resolve()
  37. ROOT = FILE.parents[1] # YOLOv5 root directory
  38. def set_logging(name=None, verbose=True):
  39. # Sets level and returns logger
  40. rank = int(os.getenv('RANK', -1)) # rank in world for Multi-GPU trainings
  41. logging.basicConfig(format="%(message)s", level=logging.INFO if (verbose and rank in (-1, 0)) else logging.WARN)
  42. return logging.getLogger(name)
  43. LOGGER = set_logging(__name__) # define globally (used in train.py, val.py, detect.py, etc.)
  44. class Profile(contextlib.ContextDecorator):
  45. # Usage: @Profile() decorator or 'with Profile():' context manager
  46. def __enter__(self):
  47. self.start = time.time()
  48. def __exit__(self, type, value, traceback):
  49. print(f'Profile results: {time.time() - self.start:.5f}s')
  50. class Timeout(contextlib.ContextDecorator):
  51. # Usage: @Timeout(seconds) decorator or 'with Timeout(seconds):' context manager
  52. def __init__(self, seconds, *, timeout_msg='', suppress_timeout_errors=True):
  53. self.seconds = int(seconds)
  54. self.timeout_message = timeout_msg
  55. self.suppress = bool(suppress_timeout_errors)
  56. def _timeout_handler(self, signum, frame):
  57. raise TimeoutError(self.timeout_message)
  58. def __enter__(self):
  59. signal.signal(signal.SIGALRM, self._timeout_handler) # Set handler for SIGALRM
  60. signal.alarm(self.seconds) # start countdown for SIGALRM to be raised
  61. def __exit__(self, exc_type, exc_val, exc_tb):
  62. signal.alarm(0) # Cancel SIGALRM if it's scheduled
  63. if self.suppress and exc_type is TimeoutError: # Suppress TimeoutError
  64. return True
  65. class WorkingDirectory(contextlib.ContextDecorator):
  66. # Usage: @WorkingDirectory(dir) decorator or 'with WorkingDirectory(dir):' context manager
  67. def __init__(self, new_dir):
  68. self.dir = new_dir # new dir
  69. self.cwd = Path.cwd().resolve() # current dir
  70. def __enter__(self):
  71. os.chdir(self.dir)
  72. def __exit__(self, exc_type, exc_val, exc_tb):
  73. os.chdir(self.cwd)
  74. def try_except(func):
  75. # try-except function. Usage: @try_except decorator
  76. def handler(*args, **kwargs):
  77. try:
  78. func(*args, **kwargs)
  79. except Exception as e:
  80. print(e)
  81. return handler
  82. def methods(instance):
  83. # Get class/instance methods
  84. return [f for f in dir(instance) if callable(getattr(instance, f)) and not f.startswith("__")]
  85. def print_args(name, opt):
  86. # Print argparser arguments
  87. LOGGER.info(colorstr(f'{name}: ') + ', '.join(f'{k}={v}' for k, v in vars(opt).items()))
  88. def init_seeds(seed=0):
  89. # Initialize random number generator (RNG) seeds https://pytorch.org/docs/stable/notes/randomness.html
  90. # cudnn seed 0 settings are slower and more reproducible, else faster and less reproducible
  91. import torch.backends.cudnn as cudnn
  92. random.seed(seed)
  93. np.random.seed(seed)
  94. torch.manual_seed(seed)
  95. cudnn.benchmark, cudnn.deterministic = (False, True) if seed == 0 else (True, False)
  96. def get_latest_run(search_dir='.'):
  97. # Return path to most recent 'last.pt' in /runs (i.e. to --resume from)
  98. last_list = glob.glob(f'{search_dir}/**/last*.pt', recursive=True)
  99. return max(last_list, key=os.path.getctime) if last_list else ''
  100. def user_config_dir(dir='Ultralytics', env_var='YOLOV5_CONFIG_DIR'):
  101. # Return path of user configuration directory. Prefer environment variable if exists. Make dir if required.
  102. env = os.getenv(env_var)
  103. if env:
  104. path = Path(env) # use environment variable
  105. else:
  106. cfg = {'Windows': 'AppData/Roaming', 'Linux': '.config', 'Darwin': 'Library/Application Support'} # 3 OS dirs
  107. path = Path.home() / cfg.get(platform.system(), '') # OS-specific config dir
  108. path = (path if is_writeable(path) else Path('/tmp')) / dir # GCP and AWS lambda fix, only /tmp is writeable
  109. path.mkdir(exist_ok=True) # make if required
  110. return path
  111. def is_writeable(dir, test=False):
  112. # Return True if directory has write permissions, test opening a file with write permissions if test=True
  113. if test: # method 1
  114. file = Path(dir) / 'tmp.txt'
  115. try:
  116. with open(file, 'w'): # open file with write permissions
  117. pass
  118. file.unlink() # remove file
  119. return True
  120. except OSError:
  121. return False
  122. else: # method 2
  123. return os.access(dir, os.R_OK) # possible issues on Windows
  124. def is_docker():
  125. # Is environment a Docker container?
  126. return Path('/workspace').exists() # or Path('/.dockerenv').exists()
  127. def is_colab():
  128. # Is environment a Google Colab instance?
  129. try:
  130. import google.colab
  131. return True
  132. except ImportError:
  133. return False
  134. def is_pip():
  135. # Is file in a pip package?
  136. return 'site-packages' in Path(__file__).resolve().parts
  137. def is_ascii(s=''):
  138. # Is string composed of all ASCII (no UTF) characters? (note str().isascii() introduced in python 3.7)
  139. s = str(s) # convert list, tuple, None, etc. to str
  140. return len(s.encode().decode('ascii', 'ignore')) == len(s)
  141. def is_chinese(s='人工智能'):
  142. # Is string composed of any Chinese characters?
  143. return re.search('[\u4e00-\u9fff]', s)
  144. def emojis(str=''):
  145. # Return platform-dependent emoji-safe version of string
  146. return str.encode().decode('ascii', 'ignore') if platform.system() == 'Windows' else str
  147. def file_size(path):
  148. # Return file/dir size (MB)
  149. path = Path(path)
  150. if path.is_file():
  151. return path.stat().st_size / 1E6
  152. elif path.is_dir():
  153. return sum(f.stat().st_size for f in path.glob('**/*') if f.is_file()) / 1E6
  154. else:
  155. return 0.0
  156. def check_online():
  157. # Check internet connectivity
  158. import socket
  159. try:
  160. socket.create_connection(("1.1.1.1", 443), 5) # check host accessibility
  161. return True
  162. except OSError:
  163. return False
  164. @try_except
  165. @WorkingDirectory(ROOT)
  166. def check_git_status():
  167. # Recommend 'git pull' if code is out of date
  168. msg = ', for updates see https://github.com/ultralytics/yolov5'
  169. print(colorstr('github: '), end='')
  170. assert Path('.git').exists(), 'skipping check (not a git repository)' + msg
  171. assert not is_docker(), 'skipping check (Docker image)' + msg
  172. assert check_online(), 'skipping check (offline)' + msg
  173. cmd = 'git fetch && git config --get remote.origin.url'
  174. url = check_output(cmd, shell=True, timeout=5).decode().strip().rstrip('.git') # git fetch
  175. branch = check_output('git rev-parse --abbrev-ref HEAD', shell=True).decode().strip() # checked out
  176. n = int(check_output(f'git rev-list {branch}..origin/master --count', shell=True)) # commits behind
  177. if n > 0:
  178. s = f"⚠️ YOLOv5 is out of date by {n} commit{'s' * (n > 1)}. Use `git pull` or `git clone {url}` to update."
  179. else:
  180. s = f'up to date with {url} ✅'
  181. print(emojis(s)) # emoji-safe
  182. def check_python(minimum='3.6.2'):
  183. # Check current python version vs. required python version
  184. check_version(platform.python_version(), minimum, name='Python ', hard=True)
  185. def check_version(current='0.0.0', minimum='0.0.0', name='version ', pinned=False, hard=False):
  186. # Check version vs. required version
  187. current, minimum = (pkg.parse_version(x) for x in (current, minimum))
  188. result = (current == minimum) if pinned else (current >= minimum) # bool
  189. if hard: # assert min requirements met
  190. assert result, f'{name}{minimum} required by YOLOv5, but {name}{current} is currently installed'
  191. else:
  192. return result
  193. @try_except
  194. def check_requirements(requirements=ROOT / 'requirements.txt', exclude=(), install=True):
  195. # Check installed dependencies meet requirements (pass *.txt file or list of packages)
  196. prefix = colorstr('red', 'bold', 'requirements:')
  197. check_python() # check python version
  198. if isinstance(requirements, (str, Path)): # requirements.txt file
  199. file = Path(requirements)
  200. assert file.exists(), f"{prefix} {file.resolve()} not found, check failed."
  201. requirements = [f'{x.name}{x.specifier}' for x in pkg.parse_requirements(file.open()) if x.name not in exclude]
  202. else: # list or tuple of packages
  203. requirements = [x for x in requirements if x not in exclude]
  204. n = 0 # number of packages updates
  205. for r in requirements:
  206. try:
  207. pkg.require(r)
  208. except Exception as e: # DistributionNotFound or VersionConflict if requirements not met
  209. s = f"{prefix} {r} not found and is required by YOLOv5"
  210. if install:
  211. print(f"{s}, attempting auto-update...")
  212. try:
  213. assert check_online(), f"'pip install {r}' skipped (offline)"
  214. print(check_output(f"pip install '{r}'", shell=True).decode())
  215. n += 1
  216. except Exception as e:
  217. print(f'{prefix} {e}')
  218. else:
  219. print(f'{s}. Please install and rerun your command.')
  220. if n: # if packages updated
  221. source = file.resolve() if 'file' in locals() else requirements
  222. s = f"{prefix} {n} package{'s' * (n > 1)} updated per {source}\n" \
  223. f"{prefix} ⚠️ {colorstr('bold', 'Restart runtime or rerun command for updates to take effect')}\n"
  224. print(emojis(s))
  225. def check_img_size(imgsz, s=32, floor=0):
  226. # Verify image size is a multiple of stride s in each dimension
  227. if isinstance(imgsz, int): # integer i.e. img_size=640
  228. new_size = max(make_divisible(imgsz, int(s)), floor)
  229. else: # list i.e. img_size=[640, 480]
  230. new_size = [max(make_divisible(x, int(s)), floor) for x in imgsz]
  231. if new_size != imgsz:
  232. print(f'WARNING: --img-size {imgsz} must be multiple of max stride {s}, updating to {new_size}')
  233. return new_size
  234. def check_imshow():
  235. # Check if environment supports image displays
  236. try:
  237. assert not is_docker(), 'cv2.imshow() is disabled in Docker environments'
  238. assert not is_colab(), 'cv2.imshow() is disabled in Google Colab environments'
  239. cv2.imshow('test', np.zeros((1, 1, 3)))
  240. cv2.waitKey(1)
  241. cv2.destroyAllWindows()
  242. cv2.waitKey(1)
  243. return True
  244. except Exception as e:
  245. print(f'WARNING: Environment does not support cv2.imshow() or PIL Image.show() image displays\n{e}')
  246. return False
  247. def check_suffix(file='yolov5s.pt', suffix=('.pt',), msg=''):
  248. # Check file(s) for acceptable suffix
  249. if file and suffix:
  250. if isinstance(suffix, str):
  251. suffix = [suffix]
  252. for f in file if isinstance(file, (list, tuple)) else [file]:
  253. s = Path(f).suffix.lower() # file suffix
  254. if len(s):
  255. assert s in suffix, f"{msg}{f} acceptable suffix is {suffix}"
  256. def check_yaml(file, suffix=('.yaml', '.yml')):
  257. # Search/download YAML file (if necessary) and return path, checking suffix
  258. return check_file(file, suffix)
  259. def check_file(file, suffix=''):
  260. # Search/download file (if necessary) and return path
  261. check_suffix(file, suffix) # optional
  262. file = str(file) # convert to str()
  263. if Path(file).is_file() or file == '': # exists
  264. return file
  265. elif file.startswith(('http:/', 'https:/')): # download
  266. url = str(Path(file)).replace(':/', '://') # Pathlib turns :// -> :/
  267. file = Path(urllib.parse.unquote(file).split('?')[0]).name # '%2F' to '/', split https://url.com/file.txt?auth
  268. print(f'Downloading {url} to {file}...')
  269. torch.hub.download_url_to_file(url, file)
  270. assert Path(file).exists() and Path(file).stat().st_size > 0, f'File download failed: {url}' # check
  271. return file
  272. else: # search
  273. files = []
  274. for d in 'data', 'models', 'utils': # search directories
  275. files.extend(glob.glob(str(ROOT / d / '**' / file), recursive=True)) # find file
  276. assert len(files), f'File not found: {file}' # assert file was found
  277. assert len(files) == 1, f"Multiple files match '{file}', specify exact path: {files}" # assert unique
  278. return files[0] # return file
  279. def check_dataset(data, autodownload=True):
  280. # Download and/or unzip dataset if not found locally
  281. # Usage: https://github.com/ultralytics/yolov5/releases/download/v1.0/coco128_with_yaml.zip
  282. # Download (optional)
  283. extract_dir = ''
  284. if isinstance(data, (str, Path)) and str(data).endswith('.zip'): # i.e. gs://bucket/dir/coco128.zip
  285. download(data, dir='../datasets', unzip=True, delete=False, curl=False, threads=1)
  286. data = next((Path('../datasets') / Path(data).stem).rglob('*.yaml'))
  287. extract_dir, autodownload = data.parent, False
  288. # Read yaml (optional)
  289. if isinstance(data, (str, Path)):
  290. with open(data, errors='ignore') as f:
  291. data = yaml.safe_load(f) # dictionary
  292. # Parse yaml
  293. path = extract_dir or Path(data.get('path') or '') # optional 'path' default to '.'
  294. for k in 'train', 'val', 'test':
  295. if data.get(k): # prepend path
  296. data[k] = str(path / data[k]) if isinstance(data[k], str) else [str(path / x) for x in data[k]]
  297. assert 'nc' in data, "Dataset 'nc' key missing."
  298. if 'names' not in data:
  299. data['names'] = [f'class{i}' for i in range(data['nc'])] # assign class names if missing
  300. train, val, test, s = (data.get(x) for x in ('train', 'val', 'test', 'download'))
  301. if val:
  302. val = [Path(x).resolve() for x in (val if isinstance(val, list) else [val])] # val path
  303. if not all(x.exists() for x in val):
  304. print('\nWARNING: Dataset not found, nonexistent paths: %s' % [str(x) for x in val if not x.exists()])
  305. if s and autodownload: # download script
  306. root = path.parent if 'path' in data else '..' # unzip directory i.e. '../'
  307. if s.startswith('http') and s.endswith('.zip'): # URL
  308. f = Path(s).name # filename
  309. print(f'Downloading {s} to {f}...')
  310. torch.hub.download_url_to_file(s, f)
  311. Path(root).mkdir(parents=True, exist_ok=True) # create root
  312. ZipFile(f).extractall(path=root) # unzip
  313. Path(f).unlink() # remove zip
  314. r = None # success
  315. elif s.startswith('bash '): # bash script
  316. print(f'Running {s} ...')
  317. r = os.system(s)
  318. else: # python script
  319. r = exec(s, {'yaml': data}) # return None
  320. print(f"Dataset autodownload {f'success, saved to {root}' if r in (0, None) else 'failure'}\n")
  321. else:
  322. raise Exception('Dataset not found.')
  323. return data # dictionary
  324. def url2file(url):
  325. # Convert URL to filename, i.e. https://url.com/file.txt?auth -> file.txt
  326. url = str(Path(url)).replace(':/', '://') # Pathlib turns :// -> :/
  327. file = Path(urllib.parse.unquote(url)).name.split('?')[0] # '%2F' to '/', split https://url.com/file.txt?auth
  328. return file
  329. def download(url, dir='.', unzip=True, delete=True, curl=False, threads=1):
  330. # Multi-threaded file download and unzip function, used in data.yaml for autodownload
  331. def download_one(url, dir):
  332. # Download 1 file
  333. f = dir / Path(url).name # filename
  334. if Path(url).is_file(): # exists in current path
  335. Path(url).rename(f) # move to dir
  336. elif not f.exists():
  337. print(f'Downloading {url} to {f}...')
  338. if curl:
  339. os.system(f"curl -L '{url}' -o '{f}' --retry 9 -C -") # curl download, retry and resume on fail
  340. else:
  341. torch.hub.download_url_to_file(url, f, progress=True) # torch download
  342. if unzip and f.suffix in ('.zip', '.gz'):
  343. print(f'Unzipping {f}...')
  344. if f.suffix == '.zip':
  345. ZipFile(f).extractall(path=dir) # unzip
  346. elif f.suffix == '.gz':
  347. os.system(f'tar xfz {f} --directory {f.parent}') # unzip
  348. if delete:
  349. f.unlink() # remove zip
  350. dir = Path(dir)
  351. dir.mkdir(parents=True, exist_ok=True) # make directory
  352. if threads > 1:
  353. pool = ThreadPool(threads)
  354. pool.imap(lambda x: download_one(*x), zip(url, repeat(dir))) # multi-threaded
  355. pool.close()
  356. pool.join()
  357. else:
  358. for u in [url] if isinstance(url, (str, Path)) else url:
  359. download_one(u, dir)
  360. def make_divisible(x, divisor):
  361. # Returns x evenly divisible by divisor
  362. return math.ceil(x / divisor) * divisor
  363. def clean_str(s):
  364. # Cleans a string by replacing special characters with underscore _
  365. return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s)
  366. def one_cycle(y1=0.0, y2=1.0, steps=100):
  367. # lambda function for sinusoidal ramp from y1 to y2 https://arxiv.org/pdf/1812.01187.pdf
  368. return lambda x: ((1 - math.cos(x * math.pi / steps)) / 2) * (y2 - y1) + y1
  369. def colorstr(*input):
  370. # Colors a string https://en.wikipedia.org/wiki/ANSI_escape_code, i.e. colorstr('blue', 'hello world')
  371. *args, string = input if len(input) > 1 else ('blue', 'bold', input[0]) # color arguments, string
  372. colors = {'black': '\033[30m', # basic colors
  373. 'red': '\033[31m',
  374. 'green': '\033[32m',
  375. 'yellow': '\033[33m',
  376. 'blue': '\033[34m',
  377. 'magenta': '\033[35m',
  378. 'cyan': '\033[36m',
  379. 'white': '\033[37m',
  380. 'bright_black': '\033[90m', # bright colors
  381. 'bright_red': '\033[91m',
  382. 'bright_green': '\033[92m',
  383. 'bright_yellow': '\033[93m',
  384. 'bright_blue': '\033[94m',
  385. 'bright_magenta': '\033[95m',
  386. 'bright_cyan': '\033[96m',
  387. 'bright_white': '\033[97m',
  388. 'end': '\033[0m', # misc
  389. 'bold': '\033[1m',
  390. 'underline': '\033[4m'}
  391. return ''.join(colors[x] for x in args) + f'{string}' + colors['end']
  392. def labels_to_class_weights(labels, nc=80):
  393. # Get class weights (inverse frequency) from training labels
  394. if labels[0] is None: # no labels loaded
  395. return torch.Tensor()
  396. labels = np.concatenate(labels, 0) # labels.shape = (866643, 5) for COCO
  397. classes = labels[:, 0].astype(np.int) # labels = [class xywh]
  398. weights = np.bincount(classes, minlength=nc) # occurrences per class
  399. # Prepend gridpoint count (for uCE training)
  400. # gpi = ((320 / 32 * np.array([1, 2, 4])) ** 2 * 3).sum() # gridpoints per image
  401. # weights = np.hstack([gpi * len(labels) - weights.sum() * 9, weights * 9]) ** 0.5 # prepend gridpoints to start
  402. weights[weights == 0] = 1 # replace empty bins with 1
  403. weights = 1 / weights # number of targets per class
  404. weights /= weights.sum() # normalize
  405. return torch.from_numpy(weights)
  406. def labels_to_image_weights(labels, nc=80, class_weights=np.ones(80)):
  407. # Produces image weights based on class_weights and image contents
  408. class_counts = np.array([np.bincount(x[:, 0].astype(np.int), minlength=nc) for x in labels])
  409. image_weights = (class_weights.reshape(1, nc) * class_counts).sum(1)
  410. # index = random.choices(range(n), weights=image_weights, k=1) # weight image sample
  411. return image_weights
  412. def coco80_to_coco91_class(): # converts 80-index (val2014) to 91-index (paper)
  413. # https://tech.amikelive.com/node-718/what-object-categories-labels-are-in-coco-dataset/
  414. # a = np.loadtxt('data/coco.names', dtype='str', delimiter='\n')
  415. # b = np.loadtxt('data/coco_paper.names', dtype='str', delimiter='\n')
  416. # x1 = [list(a[i] == b).index(True) + 1 for i in range(80)] # darknet to coco
  417. # x2 = [list(b[i] == a).index(True) if any(b[i] == a) else None for i in range(91)] # coco to darknet
  418. x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34,
  419. 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  420. 64, 65, 67, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90]
  421. return x
  422. def xyxy2xywh(x):
  423. # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] where xy1=top-left, xy2=bottom-right
  424. y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
  425. y[:, 0] = (x[:, 0] + x[:, 2]) / 2 # x center
  426. y[:, 1] = (x[:, 1] + x[:, 3]) / 2 # y center
  427. y[:, 2] = x[:, 2] - x[:, 0] # width
  428. y[:, 3] = x[:, 3] - x[:, 1] # height
  429. return y
  430. def xywh2xyxy(x):
  431. # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
  432. y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
  433. y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x
  434. y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y
  435. y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x
  436. y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y
  437. return y
  438. def xywhn2xyxy(x, w=640, h=640, padw=0, padh=0):
  439. # Convert nx4 boxes from [x, y, w, h] normalized to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right
  440. y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
  441. y[:, 0] = w * (x[:, 0] - x[:, 2] / 2) + padw # top left x
  442. y[:, 1] = h * (x[:, 1] - x[:, 3] / 2) + padh # top left y
  443. y[:, 2] = w * (x[:, 0] + x[:, 2] / 2) + padw # bottom right x
  444. y[:, 3] = h * (x[:, 1] + x[:, 3] / 2) + padh # bottom right y
  445. return y
  446. def xyxy2xywhn(x, w=640, h=640, clip=False, eps=0.0):
  447. # Convert nx4 boxes from [x1, y1, x2, y2] to [x, y, w, h] normalized where xy1=top-left, xy2=bottom-right
  448. if clip:
  449. clip_coords(x, (h - eps, w - eps)) # warning: inplace clip
  450. y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
  451. y[:, 0] = ((x[:, 0] + x[:, 2]) / 2) / w # x center
  452. y[:, 1] = ((x[:, 1] + x[:, 3]) / 2) / h # y center
  453. y[:, 2] = (x[:, 2] - x[:, 0]) / w # width
  454. y[:, 3] = (x[:, 3] - x[:, 1]) / h # height
  455. return y
  456. def xyn2xy(x, w=640, h=640, padw=0, padh=0):
  457. # Convert normalized segments into pixel segments, shape (n,2)
  458. y = x.clone() if isinstance(x, torch.Tensor) else np.copy(x)
  459. y[:, 0] = w * x[:, 0] + padw # top left x
  460. y[:, 1] = h * x[:, 1] + padh # top left y
  461. return y
  462. def segment2box(segment, width=640, height=640):
  463. # Convert 1 segment label to 1 box label, applying inside-image constraint, i.e. (xy1, xy2, ...) to (xyxy)
  464. x, y = segment.T # segment xy
  465. inside = (x >= 0) & (y >= 0) & (x <= width) & (y <= height)
  466. x, y, = x[inside], y[inside]
  467. return np.array([x.min(), y.min(), x.max(), y.max()]) if any(x) else np.zeros((1, 4)) # xyxy
  468. def segments2boxes(segments):
  469. # Convert segment labels to box labels, i.e. (cls, xy1, xy2, ...) to (cls, xywh)
  470. boxes = []
  471. for s in segments:
  472. x, y = s.T # segment xy
  473. boxes.append([x.min(), y.min(), x.max(), y.max()]) # cls, xyxy
  474. return xyxy2xywh(np.array(boxes)) # cls, xywh
  475. def resample_segments(segments, n=1000):
  476. # Up-sample an (n,2) segment
  477. for i, s in enumerate(segments):
  478. x = np.linspace(0, len(s) - 1, n)
  479. xp = np.arange(len(s))
  480. segments[i] = np.concatenate([np.interp(x, xp, s[:, i]) for i in range(2)]).reshape(2, -1).T # segment xy
  481. return segments
  482. def scale_coords(img1_shape, coords, img0_shape, ratio_pad=None):
  483. # Rescale coords (xyxy) from img1_shape to img0_shape
  484. if ratio_pad is None: # calculate from img0_shape
  485. gain = min(img1_shape[0] / img0_shape[0], img1_shape[1] / img0_shape[1]) # gain = old / new
  486. pad = (img1_shape[1] - img0_shape[1] * gain) / 2, (img1_shape[0] - img0_shape[0] * gain) / 2 # wh padding
  487. else:
  488. gain = ratio_pad[0][0]
  489. pad = ratio_pad[1]
  490. coords[:, [0, 2]] -= pad[0] # x padding
  491. coords[:, [1, 3]] -= pad[1] # y padding
  492. coords[:, :4] /= gain
  493. clip_coords(coords, img0_shape)
  494. return coords
  495. def clip_coords(boxes, shape):
  496. # Clip bounding xyxy bounding boxes to image shape (height, width)
  497. if isinstance(boxes, torch.Tensor): # faster individually
  498. boxes[:, 0].clamp_(0, shape[1]) # x1
  499. boxes[:, 1].clamp_(0, shape[0]) # y1
  500. boxes[:, 2].clamp_(0, shape[1]) # x2
  501. boxes[:, 3].clamp_(0, shape[0]) # y2
  502. else: # np.array (faster grouped)
  503. boxes[:, [0, 2]] = boxes[:, [0, 2]].clip(0, shape[1]) # x1, x2
  504. boxes[:, [1, 3]] = boxes[:, [1, 3]].clip(0, shape[0]) # y1, y2
  505. def non_max_suppression(prediction, conf_thres=0.25, iou_thres=0.45, classes=None, agnostic=False, multi_label=False,
  506. labels=(), max_det=300):
  507. """Runs Non-Maximum Suppression (NMS) on inference results
  508. Returns:
  509. list of detections, on (n,6) tensor per image [xyxy, conf, cls]
  510. """
  511. nc = prediction.shape[2] - 5 # number of classes
  512. xc = prediction[..., 4] > conf_thres # candidates
  513. # Checks
  514. assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0'
  515. assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0'
  516. # Settings
  517. min_wh, max_wh = 2, 4096 # (pixels) minimum and maximum box width and height
  518. max_nms = 30000 # maximum number of boxes into torchvision.ops.nms()
  519. time_limit = 10.0 # seconds to quit after
  520. redundant = True # require redundant detections
  521. multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img)
  522. merge = False # use merge-NMS
  523. t = time.time()
  524. output = [torch.zeros((0, 6), device=prediction.device)] * prediction.shape[0]
  525. for xi, x in enumerate(prediction): # image index, image inference
  526. # Apply constraints
  527. # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height
  528. x = x[xc[xi]] # confidence
  529. # Cat apriori labels if autolabelling
  530. if labels and len(labels[xi]):
  531. l = labels[xi]
  532. v = torch.zeros((len(l), nc + 5), device=x.device)
  533. v[:, :4] = l[:, 1:5] # box
  534. v[:, 4] = 1.0 # conf
  535. v[range(len(l)), l[:, 0].long() + 5] = 1.0 # cls
  536. x = torch.cat((x, v), 0)
  537. # If none remain process next image
  538. if not x.shape[0]:
  539. continue
  540. # Compute conf
  541. x[:, 5:] *= x[:, 4:5] # conf = obj_conf * cls_conf
  542. # Box (center x, center y, width, height) to (x1, y1, x2, y2)
  543. box = xywh2xyxy(x[:, :4])
  544. # Detections matrix nx6 (xyxy, conf, cls)
  545. if multi_label:
  546. i, j = (x[:, 5:] > conf_thres).nonzero(as_tuple=False).T
  547. x = torch.cat((box[i], x[i, j + 5, None], j[:, None].float()), 1)
  548. else: # best class only
  549. conf, j = x[:, 5:].max(1, keepdim=True)
  550. x = torch.cat((box, conf, j.float()), 1)[conf.view(-1) > conf_thres]
  551. # Filter by class
  552. if classes is not None:
  553. x = x[(x[:, 5:6] == torch.tensor(classes, device=x.device)).any(1)]
  554. # Apply finite constraint
  555. # if not torch.isfinite(x).all():
  556. # x = x[torch.isfinite(x).all(1)]
  557. # Check shape
  558. n = x.shape[0] # number of boxes
  559. if not n: # no boxes
  560. continue
  561. elif n > max_nms: # excess boxes
  562. x = x[x[:, 4].argsort(descending=True)[:max_nms]] # sort by confidence
  563. # Batched NMS
  564. c = x[:, 5:6] * (0 if agnostic else max_wh) # classes
  565. boxes, scores = x[:, :4] + c, x[:, 4] # boxes (offset by class), scores
  566. i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS
  567. if i.shape[0] > max_det: # limit detections
  568. i = i[:max_det]
  569. if merge and (1 < n < 3E3): # Merge NMS (boxes merged using weighted mean)
  570. # update boxes as boxes(i,4) = weights(i,n) * boxes(n,4)
  571. iou = box_iou(boxes[i], boxes) > iou_thres # iou matrix
  572. weights = iou * scores[None] # box weights
  573. x[i, :4] = torch.mm(weights, x[:, :4]).float() / weights.sum(1, keepdim=True) # merged boxes
  574. if redundant:
  575. i = i[iou.sum(1) > 1] # require redundancy
  576. output[xi] = x[i]
  577. if (time.time() - t) > time_limit:
  578. print(f'WARNING: NMS time limit {time_limit}s exceeded')
  579. break # time limit exceeded
  580. return output
  581. def strip_optimizer(f='best.pt', s=''): # from utils.general import *; strip_optimizer()
  582. # Strip optimizer from 'f' to finalize training, optionally save as 's'
  583. x = torch.load(f, map_location=torch.device('cpu'))
  584. if x.get('ema'):
  585. x['model'] = x['ema'] # replace model with ema
  586. for k in 'optimizer', 'training_results', 'wandb_id', 'ema', 'updates': # keys
  587. x[k] = None
  588. x['epoch'] = -1
  589. x['model'].half() # to FP16
  590. for p in x['model'].parameters():
  591. p.requires_grad = False
  592. torch.save(x, s or f)
  593. mb = os.path.getsize(s or f) / 1E6 # filesize
  594. print(f"Optimizer stripped from {f},{(' saved as %s,' % s) if s else ''} {mb:.1f}MB")
  595. def print_mutation(results, hyp, save_dir, bucket):
  596. evolve_csv, results_csv, evolve_yaml = save_dir / 'evolve.csv', save_dir / 'results.csv', save_dir / 'hyp_evolve.yaml'
  597. keys = ('metrics/precision', 'metrics/recall', 'metrics/mAP_0.5', 'metrics/mAP_0.5:0.95',
  598. 'val/box_loss', 'val/obj_loss', 'val/cls_loss') + tuple(hyp.keys()) # [results + hyps]
  599. keys = tuple(x.strip() for x in keys)
  600. vals = results + tuple(hyp.values())
  601. n = len(keys)
  602. # Download (optional)
  603. if bucket:
  604. url = f'gs://{bucket}/evolve.csv'
  605. if gsutil_getsize(url) > (os.path.getsize(evolve_csv) if os.path.exists(evolve_csv) else 0):
  606. os.system(f'gsutil cp {url} {save_dir}') # download evolve.csv if larger than local
  607. # Log to evolve.csv
  608. s = '' if evolve_csv.exists() else (('%20s,' * n % keys).rstrip(',') + '\n') # add header
  609. with open(evolve_csv, 'a') as f:
  610. f.write(s + ('%20.5g,' * n % vals).rstrip(',') + '\n')
  611. # Print to screen
  612. print(colorstr('evolve: ') + ', '.join(f'{x.strip():>20s}' for x in keys))
  613. print(colorstr('evolve: ') + ', '.join(f'{x:20.5g}' for x in vals), end='\n\n\n')
  614. # Save yaml
  615. with open(evolve_yaml, 'w') as f:
  616. data = pd.read_csv(evolve_csv)
  617. data = data.rename(columns=lambda x: x.strip()) # strip keys
  618. i = np.argmax(fitness(data.values[:, :7])) #
  619. f.write('# YOLOv5 Hyperparameter Evolution Results\n' +
  620. f'# Best generation: {i}\n' +
  621. f'# Last generation: {len(data)}\n' +
  622. '# ' + ', '.join(f'{x.strip():>20s}' for x in keys[:7]) + '\n' +
  623. '# ' + ', '.join(f'{x:>20.5g}' for x in data.values[i, :7]) + '\n\n')
  624. yaml.safe_dump(hyp, f, sort_keys=False)
  625. if bucket:
  626. os.system(f'gsutil cp {evolve_csv} {evolve_yaml} gs://{bucket}') # upload
  627. def apply_classifier(x, model, img, im0):
  628. # Apply a second stage classifier to yolo outputs
  629. im0 = [im0] if isinstance(im0, np.ndarray) else im0
  630. for i, d in enumerate(x): # per image
  631. if d is not None and len(d):
  632. d = d.clone()
  633. # Reshape and pad cutouts
  634. b = xyxy2xywh(d[:, :4]) # boxes
  635. b[:, 2:] = b[:, 2:].max(1)[0].unsqueeze(1) # rectangle to square
  636. b[:, 2:] = b[:, 2:] * 1.3 + 30 # pad
  637. d[:, :4] = xywh2xyxy(b).long()
  638. # Rescale boxes from img_size to im0 size
  639. scale_coords(img.shape[2:], d[:, :4], im0[i].shape)
  640. # Classes
  641. pred_cls1 = d[:, 5].long()
  642. ims = []
  643. for j, a in enumerate(d): # per item
  644. cutout = im0[i][int(a[1]):int(a[3]), int(a[0]):int(a[2])]
  645. im = cv2.resize(cutout, (224, 224)) # BGR
  646. # cv2.imwrite('example%i.jpg' % j, cutout)
  647. im = im[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to 3x416x416
  648. im = np.ascontiguousarray(im, dtype=np.float32) # uint8 to float32
  649. im /= 255 # 0 - 255 to 0.0 - 1.0
  650. ims.append(im)
  651. pred_cls2 = model(torch.Tensor(ims).to(d.device)).argmax(1) # classifier prediction
  652. x[i] = x[i][pred_cls1 == pred_cls2] # retain matching class detections
  653. return x
  654. def save_one_box(xyxy, im, file='image.jpg', gain=1.02, pad=10, square=False, BGR=False, save=True):
  655. # Save image crop as {file} with crop size multiple {gain} and {pad} pixels. Save and/or return crop
  656. xyxy = torch.tensor(xyxy).view(-1, 4)
  657. b = xyxy2xywh(xyxy) # boxes
  658. if square:
  659. b[:, 2:] = b[:, 2:].max(1)[0].unsqueeze(1) # attempt rectangle to square
  660. b[:, 2:] = b[:, 2:] * gain + pad # box wh * gain + pad
  661. xyxy = xywh2xyxy(b).long()
  662. clip_coords(xyxy, im.shape)
  663. crop = im[int(xyxy[0, 1]):int(xyxy[0, 3]), int(xyxy[0, 0]):int(xyxy[0, 2]), ::(1 if BGR else -1)]
  664. if save:
  665. cv2.imwrite(str(increment_path(file, mkdir=True).with_suffix('.jpg')), crop)
  666. return crop
  667. def increment_path(path, exist_ok=False, sep='', mkdir=False):
  668. # Increment file or directory path, i.e. runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc.
  669. path = Path(path) # os-agnostic
  670. if path.exists() and not exist_ok:
  671. suffix = path.suffix
  672. path = path.with_suffix('')
  673. dirs = glob.glob(f"{path}{sep}*") # similar paths
  674. matches = [re.search(rf"%s{sep}(\d+)" % path.stem, d) for d in dirs]
  675. i = [int(m.groups()[0]) for m in matches if m] # indices
  676. n = max(i) + 1 if i else 2 # increment number
  677. path = Path(f"{path}{sep}{n}{suffix}") # update path
  678. dir = path if path.suffix == '' else path.parent # directory
  679. if not dir.exists() and mkdir:
  680. dir.mkdir(parents=True, exist_ok=True) # make directory
  681. return path