From 75b67336786d666f3dc8c7866ada7521a9ade040 Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Wed, 16 Oct 2024 17:23:23 +0500 Subject: [PATCH 01/40] Fix `self.type` variable name in Analytics solution (#16965) Co-authored-by: Glenn Jocher --- ultralytics/solutions/analytics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ultralytics/solutions/analytics.py b/ultralytics/solutions/analytics.py index 38489827af..6c2f27db03 100644 --- a/ultralytics/solutions/analytics.py +++ b/ultralytics/solutions/analytics.py @@ -48,7 +48,7 @@ class Analytics(BaseSolution): self.canvas = FigureCanvas(self.fig) # Set common axis properties self.ax.set_facecolor(self.bg_color) self.color_mapping = {} - self.ax.axis("equal") if type == "pie" else None # Ensure pie chart is circular + self.ax.axis("equal") if self.type == "pie" else None # Ensure pie chart is circular def process_data(self, im0, frame_number): """ From 03a1f58e03f2211dccc221a755b98d2de9ea09ae Mon Sep 17 00:00:00 2001 From: Laughing <61612323+Laughing-q@users.noreply.github.com> Date: Wed, 16 Oct 2024 20:24:28 +0800 Subject: [PATCH 02/40] `ultralytics 8.3.14` update TensorRT `dynamic` inference (#16953) Co-authored-by: Glenn Jocher --- ultralytics/__init__.py | 2 +- ultralytics/cfg/__init__.py | 1 - ultralytics/nn/autobackend.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 06ee07e308..99cfc59deb 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.13" +__version__ = "8.3.14" import os diff --git a/ultralytics/cfg/__init__.py b/ultralytics/cfg/__init__.py index c8d8f44f02..e73610aaf5 100644 --- a/ultralytics/cfg/__init__.py +++ b/ultralytics/cfg/__init__.py @@ -1,6 +1,5 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -import contextlib import shutil import subprocess import sys diff --git a/ultralytics/nn/autobackend.py b/ultralytics/nn/autobackend.py index 12977f0184..3d9fbe24a7 100644 --- a/ultralytics/nn/autobackend.py +++ b/ultralytics/nn/autobackend.py @@ -501,7 +501,7 @@ class AutoBackend(nn.Module): # TensorRT elif self.engine: - if self.dynamic or im.shape != self.bindings["images"].shape: + if self.dynamic and im.shape != self.bindings["images"].shape: if self.is_trt10: self.context.set_input_shape("images", im.shape) self.bindings["images"] = self.bindings["images"]._replace(shape=im.shape) From 822e5a5e70b120d852e278a35a41de32ad7d7f12 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 16 Oct 2024 17:53:12 +0200 Subject: [PATCH 03/40] Update publish.yml (#16967) --- .github/workflows/publish.yml | 42 ++--------------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e82aecc5a0..024eb8567d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -41,49 +41,11 @@ jobs: shell: python run: | import os - import requests - import toml - - # Load version and package name from pyproject.toml - pyproject = toml.load('pyproject.toml') - package_name = pyproject['project']['name'] - local_version = pyproject['project'].get('version', 'dynamic') - - # If version is dynamic, extract it from the specified file - if local_version == 'dynamic': - version_attr = pyproject['tool']['setuptools']['dynamic']['version']['attr'] - module_path, attr_name = version_attr.rsplit('.', 1) - with open(f"{module_path.replace('.', '/')}/__init__.py") as f: - local_version = next(line.split('=')[1].strip().strip("'\"") for line in f if line.startswith(attr_name)) - - print(f"Local Version: {local_version}") - - # Get online version from PyPI - response = requests.get(f"https://pypi.org/pypi/{package_name}/json") - online_version = response.json()['info']['version'] if response.status_code == 200 else None - print(f"Online Version: {online_version or 'Not Found'}") - - # Determine if a new version should be published - publish = False - if online_version: - local_ver = tuple(map(int, local_version.split('.'))) - online_ver = tuple(map(int, online_version.split('.'))) - major_diff = local_ver[0] - online_ver[0] - minor_diff = local_ver[1] - online_ver[1] - patch_diff = local_ver[2] - online_ver[2] - - publish = ( - (major_diff == 0 and minor_diff == 0 and 0 < patch_diff <= 2) or - (major_diff == 0 and minor_diff == 1 and local_ver[2] == 0) or - (major_diff == 1 and local_ver[1] == 0 and local_ver[2] == 0) - ) - else: - publish = True # First release - + from actions.utils import check_pypi_version + local_version, online_version, publish = check_pypi_version() os.system(f'echo "increment={publish}" >> $GITHUB_OUTPUT') os.system(f'echo "current_tag=v{local_version}" >> $GITHUB_OUTPUT') os.system(f'echo "previous_tag=v{online_version}" >> $GITHUB_OUTPUT') - if publish: print('Ready to publish new version to PyPI โœ….') id: check_pypi From 3bf47c248a495a08b78b93f378bc8c8b02bb090d Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 16 Oct 2024 18:55:17 +0200 Subject: [PATCH 04/40] Expand Docs CI table with `mkdocs`, `thop`, `actions`, `handbook` (#16970) Co-authored-by: UltralyticsAssistant --- docs/en/help/CI.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/en/help/CI.md b/docs/en/help/CI.md index c63d678eb8..0f6b4c3a40 100644 --- a/docs/en/help/CI.md +++ b/docs/en/help/CI.md @@ -22,14 +22,18 @@ Here's a brief description of our CI actions: Below is the table showing the status of these CI tests for our main repositories: -| Repository | CI | Docker Deployment | Broken Links | CodeQL | PyPI and Docs Publishing | -| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [yolov3](https://github.com/ultralytics/yolov3) | [![YOLOv3 CI](https://github.com/ultralytics/yolov3/actions/workflows/ci-testing.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/ci-testing.yml) | [![Publish Docker Images](https://github.com/ultralytics/yolov3/actions/workflows/docker.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/docker.yml) | [![Check Broken links](https://github.com/ultralytics/yolov3/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/yolov3/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/codeql-analysis.yml) | | -| [yolov5](https://github.com/ultralytics/yolov5) | [![YOLOv5 CI](https://github.com/ultralytics/yolov5/actions/workflows/ci-testing.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/ci-testing.yml) | [![Publish Docker Images](https://github.com/ultralytics/yolov5/actions/workflows/docker.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/docker.yml) | [![Check Broken links](https://github.com/ultralytics/yolov5/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/yolov5/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/codeql-analysis.yml) | | -| [ultralytics](https://github.com/ultralytics/ultralytics) | [![ultralytics CI](https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml) | [![Publish Docker Images](https://github.com/ultralytics/ultralytics/actions/workflows/docker.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/docker.yaml) | [![Check Broken links](https://github.com/ultralytics/ultralytics/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml) | [![Publish to PyPI and Deploy Docs](https://github.com/ultralytics/ultralytics/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/publish.yml) | -| [hub-sdk](https://github.com/ultralytics/hub-sdk) | [![HUB-SDK CI](https://github.com/ultralytics/hub-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/ci.yml) | | [![Check Broken links](https://github.com/ultralytics/hub-sdk/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/hub-sdk/actions/workflows/codeql.yaml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/codeql.yaml) | [![Publish to PyPI](https://github.com/ultralytics/hub-sdk/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/publish.yml) | -| [hub](https://github.com/ultralytics/hub) | [![HUB CI](https://github.com/ultralytics/hub/actions/workflows/ci.yaml/badge.svg)](https://github.com/ultralytics/hub/actions/workflows/ci.yaml) | | [![Check Broken links](https://github.com/ultralytics/hub/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/hub/actions/workflows/links.yml) | | | -| [docs](https://github.com/ultralytics/docs) | | | [![Check Broken links](https://github.com/ultralytics/docs/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/links.yml)[![Check Domains](https://github.com/ultralytics/docs/actions/workflows/check_domains.yml/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/check_domains.yml) | | [![pages-build-deployment](https://github.com/ultralytics/docs/actions/workflows/pages/pages-build-deployment/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/pages/pages-build-deployment) | +| Repository | CI | Docker Deployment | Broken Links | CodeQL | PyPI and Docs Publishing | +| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [yolov3](https://github.com/ultralytics/yolov3) | [![YOLOv3 CI](https://github.com/ultralytics/yolov3/actions/workflows/ci-testing.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/ci-testing.yml) | [![Publish Docker Images](https://github.com/ultralytics/yolov3/actions/workflows/docker.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/docker.yml) | [![Check Broken links](https://github.com/ultralytics/yolov3/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/yolov3/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ultralytics/yolov3/actions/workflows/codeql-analysis.yml) | | +| [yolov5](https://github.com/ultralytics/yolov5) | [![YOLOv5 CI](https://github.com/ultralytics/yolov5/actions/workflows/ci-testing.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/ci-testing.yml) | [![Publish Docker Images](https://github.com/ultralytics/yolov5/actions/workflows/docker.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/docker.yml) | [![Check Broken links](https://github.com/ultralytics/yolov5/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/yolov5/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ultralytics/yolov5/actions/workflows/codeql-analysis.yml) | | +| [ultralytics](https://github.com/ultralytics/ultralytics) | [![ultralytics CI](https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/ci.yaml) | [![Publish Docker Images](https://github.com/ultralytics/ultralytics/actions/workflows/docker.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/docker.yaml) | [![Check Broken links](https://github.com/ultralytics/ultralytics/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/codeql.yaml) | [![Publish to PyPI and Deploy Docs](https://github.com/ultralytics/ultralytics/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/ultralytics/actions/workflows/publish.yml) | +| [hub-sdk](https://github.com/ultralytics/hub-sdk) | [![HUB-SDK CI](https://github.com/ultralytics/hub-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/ci.yml) | | [![Check Broken links](https://github.com/ultralytics/hub-sdk/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/links.yml) | [![CodeQL](https://github.com/ultralytics/hub-sdk/actions/workflows/codeql.yaml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/codeql.yaml) | [![Publish to PyPI](https://github.com/ultralytics/hub-sdk/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/hub-sdk/actions/workflows/publish.yml) | +| [hub](https://github.com/ultralytics/hub) | [![HUB CI](https://github.com/ultralytics/hub/actions/workflows/ci.yaml/badge.svg)](https://github.com/ultralytics/hub/actions/workflows/ci.yaml) | | [![Check Broken links](https://github.com/ultralytics/hub/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/hub/actions/workflows/links.yml) | | | +| [mkdocs](https://github.com/ultralytics/mkdocs) | [![Ultralytics Actions](https://github.com/ultralytics/mkdocs/actions/workflows/format.yml/badge.svg)](https://github.com/ultralytics/mkdocs/actions/workflows/format.yml) | | | [![CodeQL](https://github.com/ultralytics/mkdocs/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/ultralytics/mkdocs/actions/workflows/github-code-scanning/codeql) | [![Publish to PyPI](https://github.com/ultralytics/mkdocs/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/mkdocs/actions/workflows/publish.yml) | +| [thop](https://github.com/ultralytics/thop) | [![Ultralytics Actions](https://github.com/ultralytics/thop/actions/workflows/format.yml/badge.svg)](https://github.com/ultralytics/thop/actions/workflows/format.yml) | | | [![CodeQL](https://github.com/ultralytics/thop/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/ultralytics/thop/actions/workflows/github-code-scanning/codeql) | [![Publish to PyPI](https://github.com/ultralytics/thop/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/mkdocs/actions/workflows/publish.yml) | +| [actions](https://github.com/ultralytics/mkdocs) | [![Ultralytics Actions](https://github.com/ultralytics/actions/actions/workflows/format.yml/badge.svg)](https://github.com/ultralytics/actions/actions/workflows/format.yml) | | | [![CodeQL](https://github.com/ultralytics/actions/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/ultralytics/actions/actions/workflows/github-code-scanning/codeql) | [![Publish to PyPI](https://github.com/ultralytics/actions/actions/workflows/publish.yml/badge.svg)](https://github.com/ultralytics/actions/actions/workflows/publish.yml) | +| [docs](https://github.com/ultralytics/docs) | [![Ultralytics Actions](https://github.com/ultralytics/docs/actions/workflows/format.yml/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/format.yml) | | [![Check Broken links](https://github.com/ultralytics/docs/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/links.yml)[![Check Domains](https://github.com/ultralytics/docs/actions/workflows/check_domains.yml/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/check_domains.yml) | | [![pages-build-deployment](https://github.com/ultralytics/docs/actions/workflows/pages/pages-build-deployment/badge.svg)](https://github.com/ultralytics/docs/actions/workflows/pages/pages-build-deployment) | +| [handbook](https://github.com/ultralytics/handbook) | [![Ultralytics Actions](https://github.com/ultralytics/handbook/actions/workflows/format.yml/badge.svg)](https://github.com/ultralytics/handbook/actions/workflows/format.yml) | | [![Check Broken links](https://github.com/ultralytics/handbook/actions/workflows/links.yml/badge.svg)](https://github.com/ultralytics/handbook/actions/workflows/links.yml) | | [![pages-build-deployment](https://github.com/ultralytics/handbook/actions/workflows/pages/pages-build-deployment/badge.svg)](https://github.com/ultralytics/handbook/actions/workflows/pages/pages-build-deployment) | Each badge shows the status of the last run of the corresponding CI test on the `main` branch of the respective repository. If a test fails, the badge will display a "failing" status, and if it passes, it will display a "passing" status. From 3484daa1b56723c1c97ea6020050dbbcdbab8ec0 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 16 Oct 2024 19:14:38 +0200 Subject: [PATCH 05/40] Fix broken Tencent AI link (#16971) --- docs/en/models/yolo-world.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/models/yolo-world.md b/docs/en/models/yolo-world.md index 96a6e0b606..a9ea22a780 100644 --- a/docs/en/models/yolo-world.md +++ b/docs/en/models/yolo-world.md @@ -320,7 +320,7 @@ This approach provides a powerful means of customizing state-of-the-art object d ## Citations and Acknowledgements -We extend our gratitude to the [Tencent AILab Computer Vision Center](https://ai.tencent.com/) for their pioneering work in real-time open-vocabulary object detection with YOLO-World: +We extend our gratitude to the [Tencent AILab Computer Vision Center](https://www.tencent.com/) for their pioneering work in real-time open-vocabulary object detection with YOLO-World: !!! quote "" From 3204a2a6a71e4506dd978fc21804838fa9d8c56b Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Thu, 17 Oct 2024 02:48:28 +0200 Subject: [PATCH 06/40] Remove `onnxslim==0.1.34` pin (#16974) --- ultralytics/engine/exporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ultralytics/engine/exporter.py b/ultralytics/engine/exporter.py index dab9c69e60..b42f8e97cf 100644 --- a/ultralytics/engine/exporter.py +++ b/ultralytics/engine/exporter.py @@ -398,7 +398,7 @@ class Exporter: """YOLO ONNX export.""" requirements = ["onnx>=1.12.0"] if self.args.simplify: - requirements += ["onnxslim==0.1.34", "onnxruntime" + ("-gpu" if torch.cuda.is_available() else "")] + requirements += ["onnxslim", "onnxruntime" + ("-gpu" if torch.cuda.is_available() else "")] check_requirements(requirements) import onnx # noqa From 984201969a1ef5cb9e4725539c19a7e3924eba38 Mon Sep 17 00:00:00 2001 From: Jan Knobloch <116908874+jk4e@users.noreply.github.com> Date: Thu, 17 Oct 2024 02:48:56 +0200 Subject: [PATCH 07/40] Update `utralytics/solutions` docstrings to match new YOLO11 (#16975) Co-authored-by: Glenn Jocher --- ultralytics/solutions/ai_gym.py | 2 +- ultralytics/solutions/parking_management.py | 6 +++--- ultralytics/solutions/streamlit_inference.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ultralytics/solutions/ai_gym.py b/ultralytics/solutions/ai_gym.py index 26f22d7032..02345749c6 100644 --- a/ultralytics/solutions/ai_gym.py +++ b/ultralytics/solutions/ai_gym.py @@ -31,7 +31,7 @@ class AIGym(BaseSolution): def monitor(self, im0): """ - Monitor the workouts using Ultralytics YOLOv8 Pose Model: https://docs.ultralytics.com/tasks/pose/. + Monitor the workouts using Ultralytics YOLO Pose Model: https://docs.ultralytics.com/tasks/pose/. Args: im0 (ndarray): The input image that will be used for processing diff --git a/ultralytics/solutions/parking_management.py b/ultralytics/solutions/parking_management.py index ef58ad6274..3a1cd21972 100644 --- a/ultralytics/solutions/parking_management.py +++ b/ultralytics/solutions/parking_management.py @@ -143,7 +143,7 @@ class ParkingPtsSelection: class ParkingManagement: - """Manages parking occupancy and availability using YOLOv8 for real-time monitoring and visualization.""" + """Manages parking occupancy and availability using YOLO model for real-time monitoring and visualization.""" def __init__( self, @@ -153,10 +153,10 @@ class ParkingManagement: available_region_color=(0, 255, 0), # available region color ): """ - Initializes the parking management system with a YOLOv8 model and visualization settings. + Initializes the parking management system with a YOLO model and visualization settings. Args: - model (str): Path to the YOLOv8 model. + model (str): Path to the YOLO model. json_file (str): file that have all parking slot points data occupied_region_color (tuple): RGB color tuple for occupied regions. available_region_color (tuple): RGB color tuple for available regions. diff --git a/ultralytics/solutions/streamlit_inference.py b/ultralytics/solutions/streamlit_inference.py index ea85cffba3..f38cceb3ce 100644 --- a/ultralytics/solutions/streamlit_inference.py +++ b/ultralytics/solutions/streamlit_inference.py @@ -11,7 +11,7 @@ from ultralytics.utils.downloads import GITHUB_ASSETS_STEMS def inference(model=None): - """Runs real-time object detection on video input using Ultralytics YOLOv8 in a Streamlit application.""" + """Runs real-time object detection on video input using Ultralytics YOLO11 in a Streamlit application.""" check_requirements("streamlit>=1.29.0") # scope imports for faster ultralytics package load speeds import streamlit as st From 1aebe6ffed51713cc94bb448dc76baa361ddf31d Mon Sep 17 00:00:00 2001 From: Jan Knobloch <116908874+jk4e@users.noreply.github.com> Date: Thu, 17 Oct 2024 02:49:27 +0200 Subject: [PATCH 08/40] Fix display of links in yolov5 docs (#16973) Co-authored-by: Glenn Jocher --- docs/en/yolov5/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/yolov5/index.md b/docs/en/yolov5/index.md index 17be5e24a0..ec52007485 100644 --- a/docs/en/yolov5/index.md +++ b/docs/en/yolov5/index.md @@ -22,11 +22,11 @@ keywords: YOLOv5, Ultralytics, object detection, computer vision, deep learning,

-Welcome to the Ultralytics' YOLOv5๐Ÿš€ Documentation! YOLOv5, the fifth iteration of the revolutionary "You Only Look Once" [object detection](https://www.ultralytics.com/glossary/object-detection) model, is designed to deliver high-speed, high-accuracy results in real-time. +Welcome to the Ultralytics' YOLOv5๐Ÿš€ Documentation! YOLOv5, the fifth iteration of the revolutionary "You Only Look Once" object detection model, is designed to deliver high-speed, high-accuracy results in real-time.

-Built on PyTorch, this powerful [deep learning](https://www.ultralytics.com/glossary/deep-learning-dl) framework has garnered immense popularity for its versatility, ease of use, and high performance. Our documentation guides you through the installation process, explains the architectural nuances of the model, showcases various use-cases, and provides a series of detailed tutorials. These resources will help you harness the full potential of YOLOv5 for your [computer vision](https://www.ultralytics.com/glossary/computer-vision-cv) projects. Let's get started! +Built on PyTorch, this powerful deep learning framework has garnered immense popularity for its versatility, ease of use, and high performance. Our documentation guides you through the installation process, explains the architectural nuances of the model, showcases various use-cases, and provides a series of detailed tutorials. These resources will help you harness the full potential of YOLOv5 for your computer vision projects. Let's get started! From ccda7ff973cfae1c6d8ece8d7ecce34d2917988d Mon Sep 17 00:00:00 2001 From: Olivier Jolly Date: Thu, 17 Oct 2024 02:53:14 +0200 Subject: [PATCH 09/40] Fix Triton inference without explicit metadata (#16938) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- ultralytics/nn/autobackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ultralytics/nn/autobackend.py b/ultralytics/nn/autobackend.py index 3d9fbe24a7..7d4dbb8cb4 100644 --- a/ultralytics/nn/autobackend.py +++ b/ultralytics/nn/autobackend.py @@ -126,7 +126,7 @@ class AutoBackend(nn.Module): fp16 &= pt or jit or onnx or xml or engine or nn_module or triton # FP16 nhwc = coreml or saved_model or pb or tflite or edgetpu # BHWC formats (vs torch BCWH) stride = 32 # default stride - model, metadata = None, None + model, metadata, task = None, None, None # Set device cuda = torch.cuda.is_available() and device.type != "cpu" # use CUDA From 22ebd44f62791cfd4de2a24de15ce05a13c1447a Mon Sep 17 00:00:00 2001 From: Kirill Lalayants <91465467+lalayants@users.noreply.github.com> Date: Thu, 17 Oct 2024 03:57:01 +0300 Subject: [PATCH 10/40] `ultralytics 8.3.15` new TPU device-selection ability (#16576) Co-authored-by: UltralyticsAssistant Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Co-authored-by: Skillnoob <78843978+Skillnoob@users.noreply.github.com> Co-authored-by: Laughing <61612323+Laughing-q@users.noreply.github.com> Co-authored-by: Glenn Jocher --- .../guides/coral-edge-tpu-on-raspberry-pi.md | 51 ++++++++++++------- ultralytics/__init__.py | 2 +- ultralytics/nn/autobackend.py | 8 ++- ultralytics/utils/torch_utils.py | 2 +- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md b/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md index 5f6fceb781..e2d2a03f45 100644 --- a/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md +++ b/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md @@ -85,7 +85,7 @@ After installing the runtime, you need to plug in your Coral Edge TPU into a USB To use the Edge TPU, you need to convert your model into a compatible format. It is recommended that you run export on Google Colab, x86_64 Linux machine, using the official [Ultralytics Docker container](docker-quickstart.md), or using [Ultralytics HUB](../hub/quickstart.md), since the Edge TPU compiler is not available on ARM. See the [Export Mode](../modes/export.md) for the available arguments. -!!! note "Exporting the model" +!!! example "Exporting the model" === "Python" @@ -105,13 +105,27 @@ To use the Edge TPU, you need to convert your model into a compatible format. It yolo export model=path/to/model.pt format=edgetpu # Export an official model or custom model ``` -The exported model will be saved in the `_saved_model/` folder with the name `_full_integer_quant_edgetpu.tflite`. +The exported model will be saved in the `_saved_model/` folder with the name `_full_integer_quant_edgetpu.tflite`. It is important that your model ends with the suffix `_edgetpu.tflite`, otherwise ultralytics doesn't know that you're using a Edge TPU model. ## Running the model -After exporting your model, you can run inference with it using the following code: +Before you can actually run the model, you will need to install the correct libraries. -!!! note "Running the model" +If `tensorflow` is installed, uninstall tensorflow with the following command: + +```bash +pip uninstall tensorflow tensorflow-aarch64 +``` + +Then install/update `tflite-runtime`: + +```bash +pip install -U tflite-runtime +``` + +Now you can run inference using the following code: + +!!! example "Running the model" === "Python" @@ -119,7 +133,7 @@ After exporting your model, you can run inference with it using the following co from ultralytics import YOLO # Load a model - model = YOLO("path/to/edgetpu_model.tflite") # Load an official model or custom model + model = YOLO("path/to/_full_integer_quant_edgetpu.tflite") # Load an official model or custom model # Run Prediction model.predict("path/to/source.png") @@ -128,27 +142,30 @@ After exporting your model, you can run inference with it using the following co === "CLI" ```bash - yolo predict model=path/to/edgetpu_model.tflite source=path/to/source.png # Load an official model or custom model + yolo predict model=path/to/_full_integer_quant_edgetpu.tflite source=path/to/source.png # Load an official model or custom model ``` Find comprehensive information on the [Predict](../modes/predict.md) page for full prediction mode details. -???+ warning "Important" +!!! note "Inference with multiple Edge TPUs" - You should run the model using `tflite-runtime` and not `tensorflow`. - If `tensorflow` is installed, uninstall tensorflow with the following command: + If you have multiple Edge TPUs you can use the following code to select a specific TPU. - ```bash - pip uninstall tensorflow tensorflow-aarch64 - ``` + === "Python" + + ```python + from ultralytics import YOLO - Then install/update `tflite-runtime`: + # Load a model + model = YOLO("path/to/_full_integer_quant_edgetpu.tflite") # Load an official model or custom model - ``` - pip install -U tflite-runtime - ``` + # Run Prediction + model.predict("path/to/source.png") # Inference defaults to the first TPU + + model.predict("path/to/source.png", device="tpu:0") # Select the first TPU - If you want a `tflite-runtime` wheel for `tensorflow` 2.15.0 download it from [here](https://github.com/feranick/TFlite-builds/releases) and install it using `pip` or your package manager of choice. + model.predict("path/to/source.png", device="tpu:1") # Select the second TPU + ``` ## FAQ diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 99cfc59deb..d83c00a02b 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.14" +__version__ = "8.3.15" import os diff --git a/ultralytics/nn/autobackend.py b/ultralytics/nn/autobackend.py index 7d4dbb8cb4..9a8678f184 100644 --- a/ultralytics/nn/autobackend.py +++ b/ultralytics/nn/autobackend.py @@ -336,11 +336,15 @@ class AutoBackend(nn.Module): Interpreter, load_delegate = tf.lite.Interpreter, tf.lite.experimental.load_delegate if edgetpu: # TF Edge TPU https://coral.ai/software/#edgetpu-runtime - LOGGER.info(f"Loading {w} for TensorFlow Lite Edge TPU inference...") + device = device[3:] if str(device).startswith("tpu") else ":0" + LOGGER.info(f"Loading {w} on device {device[1:]} for TensorFlow Lite Edge TPU inference...") delegate = {"Linux": "libedgetpu.so.1", "Darwin": "libedgetpu.1.dylib", "Windows": "edgetpu.dll"}[ platform.system() ] - interpreter = Interpreter(model_path=w, experimental_delegates=[load_delegate(delegate)]) + interpreter = Interpreter( + model_path=w, + experimental_delegates=[load_delegate(delegate, options={"device": device})], + ) else: # TFLite LOGGER.info(f"Loading {w} for TensorFlow Lite inference...") interpreter = Interpreter(model_path=w) # load TFLite model diff --git a/ultralytics/utils/torch_utils.py b/ultralytics/utils/torch_utils.py index 0143b933d8..0dbc728e23 100644 --- a/ultralytics/utils/torch_utils.py +++ b/ultralytics/utils/torch_utils.py @@ -163,7 +163,7 @@ def select_device(device="", batch=0, newline=False, verbose=True): Note: Sets the 'CUDA_VISIBLE_DEVICES' environment variable for specifying which GPUs to use. """ - if isinstance(device, torch.device): + if isinstance(device, torch.device) or str(device).startswith("tpu"): return device s = f"Ultralytics {__version__} ๐Ÿš€ Python-{PYTHON_VERSION} torch-{torch.__version__} " From 1c650ab04cb682999c45dbe224fc3df5ecb921a6 Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Thu, 17 Oct 2024 21:51:52 +0500 Subject: [PATCH 11/40] Update `parking-management` solution (#16990) Co-authored-by: UltralyticsAssistant --- docs/en/guides/parking-management.md | 10 +- ultralytics/cfg/solutions/default.yaml | 1 + ultralytics/solutions/parking_management.py | 270 ++++++++------------ 3 files changed, 105 insertions(+), 176 deletions(-) diff --git a/docs/en/guides/parking-management.md b/docs/en/guides/parking-management.md index 6cf07e4847..b6140181ae 100644 --- a/docs/en/guides/parking-management.md +++ b/docs/en/guides/parking-management.md @@ -102,12 +102,10 @@ Parking management with [Ultralytics YOLO11](https://github.com/ultralytics/ultr ### Optional Arguments `ParkingManagement` -| Name | Type | Default | Description | -| ------------------------ | ------- | ------------- | -------------------------------------------------------------- | -| `model` | `str` | `None` | Path to the YOLO11 model. | -| `json_file` | `str` | `None` | Path to the JSON file, that have all parking coordinates data. | -| `occupied_region_color` | `tuple` | `(0, 0, 255)` | RGB color for occupied regions. | -| `available_region_color` | `tuple` | `(0, 255, 0)` | RGB color for available regions. | +| Name | Type | Default | Description | +| ----------- | ----- | ------- | -------------------------------------------------------------- | +| `model` | `str` | `None` | Path to the YOLO11 model. | +| `json_file` | `str` | `None` | Path to the JSON file, that have all parking coordinates data. | ### Arguments `model.track` diff --git a/ultralytics/cfg/solutions/default.yaml b/ultralytics/cfg/solutions/default.yaml index e4e1b845a0..a353fd2a21 100644 --- a/ultralytics/cfg/solutions/default.yaml +++ b/ultralytics/cfg/solutions/default.yaml @@ -15,3 +15,4 @@ down_angle: 90 # Workouts down_angle for counts, 90 is default value. You can ch kpts: [6, 8, 10] # Keypoints for workouts monitoring, i.e. If you want to consider keypoints for pushups that have mostly values of [6, 8, 10]. colormap: # Colormap for heatmap, Only OPENCV supported colormaps can be used. By default COLORMAP_PARULA will be used for visualization. analytics_type: "line" # Analytics type i.e "line", "pie", "bar" or "area" charts. By default, "line" analytics will be used for processing. +json_file: # parking system regions file path. diff --git a/ultralytics/solutions/parking_management.py b/ultralytics/solutions/parking_management.py index 3a1cd21972..e7afda8598 100644 --- a/ultralytics/solutions/parking_management.py +++ b/ultralytics/solutions/parking_management.py @@ -4,8 +4,9 @@ import json import cv2 import numpy as np +from PIL import Image, ImageTk -from ultralytics.utils.checks import check_imshow, check_requirements +from ultralytics.solutions.solutions import LOGGER, BaseSolution, check_requirements from ultralytics.utils.plotting import Annotator @@ -13,229 +14,158 @@ class ParkingPtsSelection: """Class for selecting and managing parking zone points on images using a Tkinter-based UI.""" def __init__(self): - """Initializes the UI for selecting parking zone points in a tkinter window.""" + """Class initialization method.""" check_requirements("tkinter") + import tkinter as tk + from tkinter import filedialog, messagebox - import tkinter as tk # scope for multi-environment compatibility + self.tk, self.filedialog, self.messagebox = tk, filedialog, messagebox + self.setup_ui() + self.initialize_properties() + self.master.mainloop() - self.tk = tk - self.master = tk.Tk() + def setup_ui(self): + """Sets up the Tkinter UI components.""" + self.master = self.tk.Tk() self.master.title("Ultralytics Parking Zones Points Selector") - - # Disable window resizing self.master.resizable(False, False) - # Setup canvas for image display + # Canvas for image display self.canvas = self.tk.Canvas(self.master, bg="white") + self.canvas.pack(side=self.tk.BOTTOM) - # Setup buttons + # Button frame with buttons button_frame = self.tk.Frame(self.master) button_frame.pack(side=self.tk.TOP) - - self.tk.Button(button_frame, text="Upload Image", command=self.upload_image).grid(row=0, column=0) - self.tk.Button(button_frame, text="Remove Last BBox", command=self.remove_last_bounding_box).grid( - row=0, column=1 - ) - self.tk.Button(button_frame, text="Save", command=self.save_to_json).grid(row=0, column=2) - - # Initialize properties - self.image_path = None - self.image = None - self.canvas_image = None - self.rg_data = [] # region coordinates - self.current_box = [] - self.imgw = 0 # image width - self.imgh = 0 # image height - - # Constants - self.canvas_max_width = 1280 - self.canvas_max_height = 720 - - self.master.mainloop() + for text, cmd in [ + ("Upload Image", self.upload_image), + ("Remove Last BBox", self.remove_last_bounding_box), + ("Save", self.save_to_json), + ]: + self.tk.Button(button_frame, text=text, command=cmd).pack(side=self.tk.LEFT) + + def initialize_properties(self): + """Initialize the necessary properties.""" + self.image = self.canvas_image = None + self.rg_data, self.current_box = [], [] + self.imgw = self.imgh = 0 + self.canvas_max_width, self.canvas_max_height = 1280, 720 def upload_image(self): - """Upload an image and resize it to fit canvas.""" - from tkinter import filedialog - - from PIL import Image, ImageTk # scope because ImageTk requires tkinter package - - self.image_path = filedialog.askopenfilename(filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")]) - if not self.image_path: + """Uploads an image, resizes it to fit the canvas, and displays it.""" + self.image = Image.open(self.filedialog.askopenfilename(filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])) + if not self.image: return - self.image = Image.open(self.image_path) self.imgw, self.imgh = self.image.size - - # Calculate the aspect ratio and resize image aspect_ratio = self.imgw / self.imgh - if aspect_ratio > 1: - # Landscape orientation - canvas_width = min(self.canvas_max_width, self.imgw) - canvas_height = int(canvas_width / aspect_ratio) - else: - # Portrait orientation - canvas_height = min(self.canvas_max_height, self.imgh) - canvas_width = int(canvas_height * aspect_ratio) - - # Check if canvas is already initialized - if self.canvas: - self.canvas.destroy() # Destroy previous canvas - - self.canvas = self.tk.Canvas(self.master, bg="white", width=canvas_width, height=canvas_height) - resized_image = self.image.resize((canvas_width, canvas_height), Image.LANCZOS) - self.canvas_image = ImageTk.PhotoImage(resized_image) - self.canvas.create_image(0, 0, anchor=self.tk.NW, image=self.canvas_image) + canvas_width = ( + min(self.canvas_max_width, self.imgw) if aspect_ratio > 1 else int(self.canvas_max_height * aspect_ratio) + ) + canvas_height = ( + min(self.canvas_max_height, self.imgh) if aspect_ratio <= 1 else int(canvas_width / aspect_ratio) + ) - self.canvas.pack(side=self.tk.BOTTOM) - self.canvas.bind("", self.on_canvas_click) + self.canvas.config(width=canvas_width, height=canvas_height) + self.display_image(canvas_width, canvas_height) + self.rg_data.clear(), self.current_box.clear() - # Reset bounding boxes and current box - self.rg_data = [] - self.current_box = [] + def display_image(self, width, height): + """Displays the resized image on the canvas.""" + self.canvas_image = ImageTk.PhotoImage(self.image.resize((width, height), Image.LANCZOS)) + self.canvas.create_image(0, 0, anchor=self.tk.NW, image=self.canvas_image) + self.canvas.bind("", self.on_canvas_click) def on_canvas_click(self, event): - """Handle mouse clicks on canvas to create points for bounding boxes.""" + """Handles mouse clicks to add points for bounding boxes.""" self.current_box.append((event.x, event.y)) self.canvas.create_oval(event.x - 3, event.y - 3, event.x + 3, event.y + 3, fill="red") - if len(self.current_box) == 4: - self.rg_data.append(self.current_box) - [ - self.canvas.create_line(self.current_box[i], self.current_box[(i + 1) % 4], fill="blue", width=2) - for i in range(4) - ] - self.current_box = [] + self.rg_data.append(self.current_box.copy()) + self.draw_box(self.current_box) + self.current_box.clear() - def remove_last_bounding_box(self): - """Remove the last drawn bounding box from canvas.""" - from tkinter import messagebox # scope for multi-environment compatibility + def draw_box(self, box): + """Draws a bounding box on the canvas.""" + for i in range(4): + self.canvas.create_line(box[i], box[(i + 1) % 4], fill="blue", width=2) - if self.rg_data: - self.rg_data.pop() # Remove the last bounding box - self.canvas.delete("all") # Clear the canvas - self.canvas.create_image(0, 0, anchor=self.tk.NW, image=self.canvas_image) # Redraw the image + def remove_last_bounding_box(self): + """Removes the last bounding box and redraws the canvas.""" + if not self.rg_data: + self.messagebox.showwarning("Warning", "No bounding boxes to remove.") + return + self.rg_data.pop() + self.redraw_canvas() - # Redraw all bounding boxes - for box in self.rg_data: - [self.canvas.create_line(box[i], box[(i + 1) % 4], fill="blue", width=2) for i in range(4)] - messagebox.showinfo("Success", "Last bounding box removed.") - else: - messagebox.showwarning("Warning", "No bounding boxes to remove.") + def redraw_canvas(self): + """Redraws the canvas with the image and all bounding boxes.""" + self.canvas.delete("all") + self.canvas.create_image(0, 0, anchor=self.tk.NW, image=self.canvas_image) + for box in self.rg_data: + self.draw_box(box) def save_to_json(self): - """Saves rescaled bounding boxes to 'bounding_boxes.json' based on image-to-canvas size ratio.""" - from tkinter import messagebox # scope for multi-environment compatibility - - rg_data = [] # regions data - for box in self.rg_data: - rs_box = [ - ( - int(x * self.imgw / self.canvas.winfo_width()), # width scaling - int(y * self.imgh / self.canvas.winfo_height()), # height scaling - ) - for x, y in box - ] - rg_data.append({"points": rs_box}) + """Saves the bounding boxes to a JSON file.""" + scale_w, scale_h = self.imgw / self.canvas.winfo_width(), self.imgh / self.canvas.winfo_height() + data = [{"points": [(int(x * scale_w), int(y * scale_h)) for x, y in box]} for box in self.rg_data] with open("bounding_boxes.json", "w") as f: - json.dump(rg_data, f, indent=4) - - messagebox.showinfo("Success", "Bounding boxes saved to bounding_boxes.json") + json.dump(data, f, indent=4) + self.messagebox.showinfo("Success", "Bounding boxes saved to bounding_boxes.json") -class ParkingManagement: +class ParkingManagement(BaseSolution): """Manages parking occupancy and availability using YOLO model for real-time monitoring and visualization.""" - def __init__( - self, - model, # Ultralytics YOLO model file path - json_file, # Parking management annotation file created from Parking Annotator - occupied_region_color=(0, 0, 255), # occupied region color - available_region_color=(0, 255, 0), # available region color - ): - """ - Initializes the parking management system with a YOLO model and visualization settings. + def __init__(self, **kwargs): + """Initializes the parking management system with a YOLO model and visualization settings.""" + super().__init__(**kwargs) - Args: - model (str): Path to the YOLO model. - json_file (str): file that have all parking slot points data - occupied_region_color (tuple): RGB color tuple for occupied regions. - available_region_color (tuple): RGB color tuple for available regions. - """ - # Model initialization - from ultralytics import YOLO + self.json_file = self.CFG["json_file"] # Load JSON data + if self.json_file is None: + LOGGER.warning("โŒ json_file argument missing. Parking region details required.") + raise ValueError("โŒ Json file path can not be empty") - self.model = YOLO(model) - - # Load JSON data - with open(json_file) as f: - self.json_data = json.load(f) + with open(self.json_file) as f: + self.json = json.load(f) self.pr_info = {"Occupancy": 0, "Available": 0} # dictionary for parking information - self.occ = occupied_region_color - self.arc = available_region_color - - self.env_check = check_imshow(warn=True) # check if environment supports imshow + self.arc = (0, 0, 255) # available region color + self.occ = (0, 255, 0) # occupied region color + self.dc = (255, 0, 189) # centroid color for each box def process_data(self, im0): """ Process the model data for parking lot management. Args: - im0 (ndarray): inference image + im0 (ndarray): inference image. """ - results = self.model.track(im0, persist=True, show=False) # object tracking + self.extract_tracks(im0) # extract tracks from im0 + es, fs = len(self.json), 0 # empty slots, filled slots + annotator = Annotator(im0, self.line_width) # init annotator - es, fs = len(self.json_data), 0 # empty slots, filled slots - annotator = Annotator(im0) # init annotator - - # extract tracks data - if results[0].boxes.id is None: - self.display_frames(im0) - return im0 - - boxes = results[0].boxes.xyxy.cpu().tolist() - clss = results[0].boxes.cls.cpu().tolist() - - for region in self.json_data: + for region in self.json: # Convert points to a NumPy array with the correct dtype and reshape properly pts_array = np.array(region["points"], dtype=np.int32).reshape((-1, 1, 2)) rg_occupied = False # occupied region initialization - for box, cls in zip(boxes, clss): - xc = int((box[0] + box[2]) / 2) - yc = int((box[1] + box[3]) / 2) - annotator.display_objects_labels( - im0, self.model.names[int(cls)], (104, 31, 17), (255, 255, 255), xc, yc, 10 - ) + for box, cls in zip(self.boxes, self.clss): + xc, yc = int((box[0] + box[2]) / 2), int((box[1] + box[3]) / 2) dist = cv2.pointPolygonTest(pts_array, (xc, yc), False) if dist >= 0: + # cv2.circle(im0, (xc, yc), radius=self.line_width * 4, color=self.dc, thickness=-1) + annotator.display_objects_labels( + im0, self.model.names[int(cls)], (104, 31, 17), (255, 255, 255), xc, yc, 10 + ) rg_occupied = True break - if rg_occupied: - fs += 1 - es -= 1 - + fs, es = (fs + 1, es - 1) if rg_occupied else (fs, es) # Plotting regions - color = self.occ if rg_occupied else self.arc - cv2.polylines(im0, [pts_array], isClosed=True, color=color, thickness=2) + cv2.polylines(im0, [pts_array], isClosed=True, color=self.occ if rg_occupied else self.arc, thickness=2) - self.pr_info["Occupancy"] = fs - self.pr_info["Available"] = es + self.pr_info["Occupancy"], self.pr_info["Available"] = fs, es annotator.display_analytics(im0, self.pr_info, (104, 31, 17), (255, 255, 255), 10) - - self.display_frames(im0) - return im0 - - def display_frames(self, im0): - """ - Display frame. - - Args: - im0 (ndarray): inference image - """ - if self.env_check: - cv2.imshow("Ultralytics Parking Manager", im0) - # Break Window - if cv2.waitKey(1) & 0xFF == ord("q"): - return + self.display_output(im0) # display output with base class function + return im0 # return output image for more usage From ae312a118ad775b17d88ff88edc20bd12c252c19 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Thu, 17 Oct 2024 18:55:00 +0200 Subject: [PATCH 12/40] Update Integrations table (#16994) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- README.md | 14 +++++++------- README.zh-CN.md | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index cce98e50b0..608a860e7a 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ See YOLO [Python Docs](https://docs.ultralytics.com/usage/python/) for more exam YOLO11 [Detect](https://docs.ultralytics.com/tasks/detect/), [Segment](https://docs.ultralytics.com/tasks/segment/) and [Pose](https://docs.ultralytics.com/tasks/pose/) models pretrained on the [COCO](https://docs.ultralytics.com/datasets/detect/coco/) dataset are available here, as well as YOLO11 [Classify](https://docs.ultralytics.com/tasks/classify/) models pretrained on the [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) dataset. [Track](https://docs.ultralytics.com/modes/track/) mode is available for all Detect, Segment and Pose models. -Ultralytics YOLO supported tasks +Ultralytics YOLO supported tasks All [Models](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models) download automatically from the latest Ultralytics [release](https://github.com/ultralytics/assets/releases) on first use. @@ -207,7 +207,7 @@ See [OBB Docs](https://docs.ultralytics.com/tasks/obb/) for usage examples with ##
Integrations
-Our key integrations with leading AI platforms extend the functionality of Ultralytics' offerings, enhancing tasks like dataset labeling, training, visualization, and model management. Discover how Ultralytics, in collaboration with [Roboflow](https://roboflow.com/?ref=ultralytics), ClearML, [Comet](https://bit.ly/yolov8-readme-comet), Neural Magic and [OpenVINO](https://docs.ultralytics.com/integrations/openvino/), can optimize your AI workflow. +Our key integrations with leading AI platforms extend the functionality of Ultralytics' offerings, enhancing tasks like dataset labeling, training, visualization, and model management. Discover how Ultralytics, in collaboration with [W&B](https://docs.wandb.ai/guides/integrations/ultralytics/), [Comet](https://bit.ly/yolov8-readme-comet), [Roboflow](https://roboflow.com/?ref=ultralytics) and [OpenVINO](https://docs.ultralytics.com/integrations/openvino/), can optimize your AI workflow.
@@ -217,10 +217,10 @@ Our key integrations with leading AI platforms extend the functionality of Ultra
- Roboflow logo + Ultralytics HUB logo space - ClearML logo + ClearML logo space Comet ML logo @@ -229,9 +229,9 @@ Our key integrations with leading AI platforms extend the functionality of Ultra NeuralMagic logo
-| Roboflow | ClearML โญ NEW | Comet โญ NEW | Neural Magic โญ NEW | -| :--------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | -| Label and export your custom datasets directly to YOLO11 for training with [Roboflow](https://roboflow.com/?ref=ultralytics) | Automatically track, visualize and even remotely train YOLO11 using [ClearML](https://clear.ml/) (open-source!) | Free forever, [Comet](https://bit.ly/yolov5-readme-comet) lets you save YOLO11 models, resume training, and interactively visualize and debug predictions | Run YOLO11 inference up to 6x faster with [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) | +| Ultralytics HUB ๐Ÿš€ | W&B | Comet โญ NEW | Neural Magic | +| :----------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | +| Streamline YOLO workflows: Label, train, and deploy effortlessly with [Ultralytics HUB](https://ultralytics.com/hub). Try now! | Track experiments, hyperparameters, and results with [Weights & Biases](https://docs.wandb.ai/guides/integrations/ultralytics/) | Free forever, [Comet](https://bit.ly/yolov5-readme-comet) lets you save YOLO11 models, resume training, and interactively visualize and debug predictions | Run YOLO11 inference up to 6x faster with [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) | ##
Ultralytics HUB
diff --git a/README.zh-CN.md b/README.zh-CN.md index ca49bb8ad1..4edd13a8ed 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -116,7 +116,7 @@ path = model.export(format="onnx") # ่ฟ”ๅ›žๅฏผๅ‡บๆจกๅž‹็š„่ทฏๅพ„ YOLO11 [ๆฃ€ๆต‹](https://docs.ultralytics.com/tasks/detect/)ใ€[ๅˆ†ๅ‰ฒ](https://docs.ultralytics.com/tasks/segment/) ๅ’Œ [ๅงฟๆ€](https://docs.ultralytics.com/tasks/pose/) ๆจกๅž‹ๅœจ [COCO](https://docs.ultralytics.com/datasets/detect/coco/) ๆ•ฐๆฎ้›†ไธŠ่ฟ›่กŒ้ข„่ฎญ็ปƒ๏ผŒ่ฟ™ไบ›ๆจกๅž‹ๅฏๅœจๆญคๅค„่Žทๅพ—๏ผŒๆญคๅค–่ฟ˜ๆœ‰ๅœจ [ImageNet](https://docs.ultralytics.com/datasets/classify/imagenet/) ๆ•ฐๆฎ้›†ไธŠ้ข„่ฎญ็ปƒ็š„ YOLO11 [ๅˆ†็ฑป](https://docs.ultralytics.com/tasks/classify/) ๆจกๅž‹ใ€‚ๆ‰€ๆœ‰ๆฃ€ๆต‹ใ€ๅˆ†ๅ‰ฒๅ’Œๅงฟๆ€ๆจกๅž‹ๅ‡ๆ”ฏๆŒ [่ทŸ่ธช](https://docs.ultralytics.com/modes/track/) ๆจกๅผใ€‚ -Ultralytics YOLO supported tasks +Ultralytics YOLO supported tasks ๆ‰€ๆœ‰[ๆจกๅž‹](https://github.com/ultralytics/ultralytics/tree/main/ultralytics/cfg/models)ๅœจ้ฆ–ๆฌกไฝฟ็”จๆ—ถ่‡ชๅŠจไปŽๆœ€ๆ–ฐ็š„ Ultralytics [ๅ‘ๅธƒ](https://github.com/ultralytics/assets/releases)ไธ‹่ฝฝใ€‚ @@ -207,7 +207,7 @@ YOLO11 [ๆฃ€ๆต‹](https://docs.ultralytics.com/tasks/detect/)ใ€[ๅˆ†ๅ‰ฒ](https://d ##
้›†ๆˆ
-ๆˆ‘ไปฌไธŽ้ข†ๅ…ˆ็š„ AI ๅนณๅฐ็š„ๅ…ณ้”ฎ้›†ๆˆๆ‰ฉๅฑ•ไบ† Ultralytics ไบงๅ“็š„ๅŠŸ่ƒฝ๏ผŒๅขžๅผบไบ†ๆ•ฐๆฎ้›†ๆ ‡่ฎฐใ€่ฎญ็ปƒใ€ๅฏ่ง†ๅŒ–ๅ’Œๆจกๅž‹็ฎก็†็ญ‰ไปปๅŠก็š„่ƒฝๅŠ›ใ€‚ไบ†่งฃ Ultralytics ๅฆ‚ไฝ•ไธŽ [Roboflow](https://roboflow.com/?ref=ultralytics)ใ€ClearMLใ€[Comet](https://bit.ly/yolov8-readme-comet)ใ€Neural Magic ๅ’Œ [OpenVINO](https://docs.ultralytics.com/integrations/openvino/) ๅˆไฝœ๏ผŒไผ˜ๅŒ–ๆ‚จ็š„ AI ๅทฅไฝœๆต็จ‹ใ€‚ +ๆˆ‘ไปฌไธŽ้ข†ๅ…ˆ็š„ AI ๅนณๅฐ็š„ๅ…ณ้”ฎ้›†ๆˆๆ‰ฉๅฑ•ไบ† Ultralytics ไบงๅ“็š„ๅŠŸ่ƒฝ๏ผŒๆๅ‡ไบ†ๆ•ฐๆฎ้›†ๆ ‡ๆณจใ€่ฎญ็ปƒใ€ๅฏ่ง†ๅŒ–ๅ’Œๆจกๅž‹็ฎก็†็ญ‰ไปปๅŠกใ€‚ๆŽข็ดข Ultralytics ๅฆ‚ไฝ•้€š่ฟ‡ไธŽ [W&B](https://docs.wandb.ai/guides/integrations/ultralytics/)ใ€[Comet](https://bit.ly/yolov8-readme-comet)ใ€[Roboflow](https://roboflow.com/?ref=ultralytics) ๅ’Œ [OpenVINO](https://docs.ultralytics.com/integrations/openvino/) ็š„ๅˆไฝœ๏ผŒไผ˜ๅŒ–ๆ‚จ็š„ AI ๅทฅไฝœๆต็จ‹ใ€‚
@@ -217,10 +217,10 @@ YOLO11 [ๆฃ€ๆต‹](https://docs.ultralytics.com/tasks/detect/)ใ€[ๅˆ†ๅ‰ฒ](https://d
- Roboflow logo + Ultralytics HUB logo space - ClearML logo + W&B logo space Comet ML logo @@ -229,9 +229,9 @@ YOLO11 [ๆฃ€ๆต‹](https://docs.ultralytics.com/tasks/detect/)ใ€[ๅˆ†ๅ‰ฒ](https://d NeuralMagic logo
-| Roboflow | ClearML โญ NEW | Comet โญ NEW | Neural Magic โญ NEW | -| :--------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | -| Label and export your custom datasets directly to YOLO11 for training with [Roboflow](https://roboflow.com/?ref=ultralytics) | Automatically track, visualize and even remotely train YOLO11 using [ClearML](https://clear.ml/) (open-source!) | Free forever, [Comet](https://bit.ly/yolov5-readme-comet) lets you save YOLO11 models, resume training, and interactively visualize and debug predictions | Run YOLO11 inference up to 6x faster with [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) | +| Ultralytics HUB ๐Ÿš€ | W&B | Comet โญ ๅ…จๆ–ฐ | Neural Magic | +| :------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: | +| ็ฎ€ๅŒ– YOLO ๅทฅไฝœๆต็จ‹๏ผš้€š่ฟ‡ [Ultralytics HUB](https://ultralytics.com/hub) ่ฝปๆพๆ ‡ๆณจใ€่ฎญ็ปƒๅ’Œ้ƒจ็ฝฒใ€‚็ซ‹ๅณ่ฏ•็”จ๏ผ | ไฝฟ็”จ [Weights & Biases](https://docs.wandb.ai/guides/integrations/ultralytics/) ่ทŸ่ธชๅฎž้ชŒใ€่ถ…ๅ‚ๆ•ฐๅ’Œ็ป“ๆžœ | ๆฐธไน…ๅ…่ดน๏ผŒ[Comet](https://bit.ly/yolov5-readme-comet) ๅ…่ฎธๆ‚จไฟๅญ˜ YOLO11 ๆจกๅž‹ใ€ๆขๅค่ฎญ็ปƒ๏ผŒๅนถไบคไบ’ๅผๅœฐๅฏ่ง†ๅŒ–ๅ’Œ่ฐƒ่ฏ•้ข„ๆต‹็ป“ๆžœ | ไฝฟ็”จ [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) ่ฟ่กŒ YOLO11 ๆŽจ็†๏ผŒ้€Ÿๅบฆๆๅ‡่‡ณ 6 ๅ€ | ##
Ultralytics HUB
From 520ac7b5c20659e29deab4226eaaa6fad2f7e884 Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Thu, 17 Oct 2024 22:58:25 +0500 Subject: [PATCH 13/40] Docker tkinter fix (#16995) Co-authored-by: UltralyticsAssistant --- ultralytics/solutions/parking_management.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ultralytics/solutions/parking_management.py b/ultralytics/solutions/parking_management.py index e7afda8598..33beb80bff 100644 --- a/ultralytics/solutions/parking_management.py +++ b/ultralytics/solutions/parking_management.py @@ -4,7 +4,6 @@ import json import cv2 import numpy as np -from PIL import Image, ImageTk from ultralytics.solutions.solutions import LOGGER, BaseSolution, check_requirements from ultralytics.utils.plotting import Annotator @@ -37,6 +36,7 @@ class ParkingPtsSelection: # Button frame with buttons button_frame = self.tk.Frame(self.master) button_frame.pack(side=self.tk.TOP) + for text, cmd in [ ("Upload Image", self.upload_image), ("Remove Last BBox", self.remove_last_bounding_box), @@ -53,6 +53,8 @@ class ParkingPtsSelection: def upload_image(self): """Uploads an image, resizes it to fit the canvas, and displays it.""" + from PIL import Image, ImageTk # scope because ImageTk requires tkinter package + self.image = Image.open(self.filedialog.askopenfilename(filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])) if not self.image: return @@ -67,15 +69,12 @@ class ParkingPtsSelection: ) self.canvas.config(width=canvas_width, height=canvas_height) - self.display_image(canvas_width, canvas_height) - self.rg_data.clear(), self.current_box.clear() - - def display_image(self, width, height): - """Displays the resized image on the canvas.""" - self.canvas_image = ImageTk.PhotoImage(self.image.resize((width, height), Image.LANCZOS)) + self.canvas_image = ImageTk.PhotoImage(self.image.resize((canvas_width, canvas_height), Image.LANCZOS)) self.canvas.create_image(0, 0, anchor=self.tk.NW, image=self.canvas_image) self.canvas.bind("", self.on_canvas_click) + self.rg_data.clear(), self.current_box.clear() + def on_canvas_click(self, event): """Handles mouse clicks to add points for bounding boxes.""" self.current_box.append((event.x, event.y)) From ea326c0a4fd0f7dca46e317ef29cd2b8172dca88 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Thu, 17 Oct 2024 20:03:10 +0200 Subject: [PATCH 14/40] Update README links (#16996) --- README.md | 4 ++-- README.zh-CN.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 608a860e7a..291977d609 100644 --- a/README.md +++ b/README.md @@ -216,10 +216,10 @@ Our key integrations with leading AI platforms extend the functionality of Ultra
- + Ultralytics HUB logo space - + ClearML logo space diff --git a/README.zh-CN.md b/README.zh-CN.md index 4edd13a8ed..ae2ded2ea9 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -216,10 +216,10 @@ YOLO11 [ๆฃ€ๆต‹](https://docs.ultralytics.com/tasks/detect/)ใ€[ๅˆ†ๅ‰ฒ](https://d
- + Ultralytics HUB logo space - + W&B logo space From ef28f1078c691e84569ee74ec3f3e0177a041347 Mon Sep 17 00:00:00 2001 From: Francesco Mattioli Date: Fri, 18 Oct 2024 12:37:02 +0200 Subject: [PATCH 15/40] Fixed build docs regex security (#17012) --- docs/build_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build_docs.py b/docs/build_docs.py index 483a2dd051..281a85f513 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -199,7 +199,7 @@ def convert_plaintext_links_to_html(content): for text_node in paragraph.find_all(string=True, recursive=False): if text_node.parent.name not in {"a", "code"}: # Ignore links and code blocks new_text = re.sub( - r'(https?://[^\s()<>]+(?:\.[^\s()<>]+)+)(?\1', str(text_node), ) From 8d7d1fe39047a9016645a1c8ae410e70cfa7d9a4 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Fri, 18 Oct 2024 13:54:45 +0200 Subject: [PATCH 16/40] `ultralytics 8.3.16` PyTorch 2.5.0 support (#16998) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant Co-authored-by: RizwanMunawar Co-authored-by: Muhammad Rizwan Munawar --- .github/workflows/publish.yml | 2 +- docs/mkdocs_github_authors.yaml | 3 + mkdocs.yml | 1 + pyproject.toml | 2 +- tests/test_solutions.py | 36 +++--- ultralytics/__init__.py | 2 +- ultralytics/data/split_dota.py | 6 +- ultralytics/solutions/ai_gym.py | 52 +++++++-- ultralytics/solutions/analytics.py | 77 +++++++++++-- ultralytics/solutions/distance_calculation.py | 60 ++++++++-- ultralytics/solutions/heatmap.py | 64 ++++++++--- ultralytics/solutions/object_counter.py | 104 ++++++++++++++---- ultralytics/solutions/parking_management.py | 90 +++++++++++++-- ultralytics/solutions/queue_management.py | 67 +++++++++-- ultralytics/solutions/solutions.py | 95 ++++++++++++---- ultralytics/solutions/speed_estimation.py | 48 ++++++-- ultralytics/solutions/streamlit_inference.py | 5 +- 17 files changed, 570 insertions(+), 144 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 024eb8567d..1ec1b9a93c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: name: Publish runs-on: ubuntu-latest permissions: - id-token: write # for PyPI trusted publishing + id-token: write # for PyPI trusted publishing steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/docs/mkdocs_github_authors.yaml b/docs/mkdocs_github_authors.yaml index 0e0423c248..2e20921385 100644 --- a/docs/mkdocs_github_authors.yaml +++ b/docs/mkdocs_github_authors.yaml @@ -76,6 +76,9 @@ 79740115+0xSynapse@users.noreply.github.com: avatar: https://avatars.githubusercontent.com/u/79740115?v=4 username: 0xSynapse +91465467+lalayants@users.noreply.github.com: + avatar: https://avatars.githubusercontent.com/u/91465467?v=4 + username: lalayants Francesco.mttl@gmail.com: avatar: https://avatars.githubusercontent.com/u/3855193?v=4 username: ambitious-octopus diff --git a/mkdocs.yml b/mkdocs.yml index 771084066f..f5298dc474 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -555,6 +555,7 @@ nav: - utils: reference/nn/modules/utils.md - tasks: reference/nn/tasks.md - solutions: + - solutions: reference/solutions/solutions.md - ai_gym: reference/solutions/ai_gym.md - analytics: reference/solutions/analytics.md - distance_calculation: reference/solutions/distance_calculation.md diff --git a/pyproject.toml b/pyproject.toml index 3fb80e62af..f6cb23204a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ build-backend = "setuptools.build_meta" [project] name = "ultralytics" dynamic = ["version"] -description = "Ultralytics YOLO for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification." +description = "Ultralytics YOLO ๐Ÿš€ for SOTA object detection, multi-object tracking, instance segmentation, pose estimation and image classification." readme = "README.md" requires-python = ">=3.8" license = { "text" = "AGPL-3.0" } diff --git a/tests/test_solutions.py b/tests/test_solutions.py index d3ba2d5fc2..e01da6d818 100644 --- a/tests/test_solutions.py +++ b/tests/test_solutions.py @@ -17,10 +17,15 @@ def test_major_solutions(): cap = cv2.VideoCapture("solutions_ci_demo.mp4") assert cap.isOpened(), "Error reading video file" region_points = [(20, 400), (1080, 404), (1080, 360), (20, 360)] - counter = solutions.ObjectCounter(region=region_points, model="yolo11n.pt", show=False) - heatmap = solutions.Heatmap(colormap=cv2.COLORMAP_PARULA, model="yolo11n.pt", show=False) - speed = solutions.SpeedEstimator(region=region_points, model="yolo11n.pt", show=False) - queue = solutions.QueueManager(region=region_points, model="yolo11n.pt", show=False) + counter = solutions.ObjectCounter(region=region_points, model="yolo11n.pt", show=False) # Test object counter + heatmap = solutions.Heatmap(colormap=cv2.COLORMAP_PARULA, model="yolo11n.pt", show=False) # Test heatmaps + speed = solutions.SpeedEstimator(region=region_points, model="yolo11n.pt", show=False) # Test queue manager + queue = solutions.QueueManager(region=region_points, model="yolo11n.pt", show=False) # Test speed estimation + line_analytics = solutions.Analytics(analytics_type="line", model="yolo11n.pt", show=False) # line analytics + pie_analytics = solutions.Analytics(analytics_type="pie", model="yolo11n.pt", show=False) # line analytics + bar_analytics = solutions.Analytics(analytics_type="bar", model="yolo11n.pt", show=False) # line analytics + area_analytics = solutions.Analytics(analytics_type="area", model="yolo11n.pt", show=False) # line analytics + frame_count = 0 # Required for analytics while cap.isOpened(): success, im0 = cap.read() if not success: @@ -30,24 +35,23 @@ def test_major_solutions(): _ = heatmap.generate_heatmap(original_im0.copy()) _ = speed.estimate_speed(original_im0.copy()) _ = queue.process_queue(original_im0.copy()) + _ = line_analytics.process_data(original_im0.copy(), frame_count) + _ = pie_analytics.process_data(original_im0.copy(), frame_count) + _ = bar_analytics.process_data(original_im0.copy(), frame_count) + _ = area_analytics.process_data(original_im0.copy(), frame_count) cap.release() - cv2.destroyAllWindows() - -@pytest.mark.slow -def test_aigym(): - """Test the workouts monitoring solution.""" + # Test workouts monitoring safe_download(url=WORKOUTS_SOLUTION_DEMO) - cap = cv2.VideoCapture("solution_ci_pose_demo.mp4") - assert cap.isOpened(), "Error reading video file" - gym = solutions.AIGym(line_width=2, kpts=[5, 11, 13]) - while cap.isOpened(): - success, im0 = cap.read() + cap1 = cv2.VideoCapture("solution_ci_pose_demo.mp4") + assert cap1.isOpened(), "Error reading video file" + gym = solutions.AIGym(line_width=2, kpts=[5, 11, 13], show=False) + while cap1.isOpened(): + success, im0 = cap1.read() if not success: break _ = gym.monitor(im0) - cap.release() - cv2.destroyAllWindows() + cap1.release() @pytest.mark.slow diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index d83c00a02b..9c0a6f3943 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.15" +__version__ = "8.3.16" import os diff --git a/ultralytics/data/split_dota.py b/ultralytics/data/split_dota.py index f9acffe9bb..b745b3662c 100644 --- a/ultralytics/data/split_dota.py +++ b/ultralytics/data/split_dota.py @@ -13,9 +13,6 @@ from tqdm import tqdm from ultralytics.data.utils import exif_size, img2label_paths from ultralytics.utils.checks import check_requirements -check_requirements("shapely") -from shapely.geometry import Polygon - def bbox_iof(polygon1, bbox2, eps=1e-6): """ @@ -33,6 +30,9 @@ def bbox_iof(polygon1, bbox2, eps=1e-6): Polygon format: [x1, y1, x2, y2, x3, y3, x4, y4]. Bounding box format: [x_min, y_min, x_max, y_max]. """ + check_requirements("shapely") + from shapely.geometry import Polygon + polygon1 = polygon1.reshape(-1, 4, 2) lt_point = np.min(polygon1, axis=-2) # left-top rb_point = np.max(polygon1, axis=-2) # right-bottom diff --git a/ultralytics/solutions/ai_gym.py b/ultralytics/solutions/ai_gym.py index 02345749c6..0d131bd9d6 100644 --- a/ultralytics/solutions/ai_gym.py +++ b/ultralytics/solutions/ai_gym.py @@ -1,16 +1,40 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -from ultralytics.solutions.solutions import BaseSolution # Import a parent class +from ultralytics.solutions.solutions import BaseSolution from ultralytics.utils.plotting import Annotator class AIGym(BaseSolution): - """A class to manage the gym steps of people in a real-time video stream based on their poses.""" + """ + A class to manage gym steps of people in a real-time video stream based on their poses. + + This class extends BaseSolution to monitor workouts using YOLO pose estimation models. It tracks and counts + repetitions of exercises based on predefined angle thresholds for up and down positions. + + Attributes: + count (List[int]): Repetition counts for each detected person. + angle (List[float]): Current angle of the tracked body part for each person. + stage (List[str]): Current exercise stage ('up', 'down', or '-') for each person. + initial_stage (str | None): Initial stage of the exercise. + up_angle (float): Angle threshold for considering the 'up' position of an exercise. + down_angle (float): Angle threshold for considering the 'down' position of an exercise. + kpts (List[int]): Indices of keypoints used for angle calculation. + lw (int): Line width for drawing annotations. + annotator (Annotator): Object for drawing annotations on the image. + + Methods: + monitor: Processes a frame to detect poses, calculate angles, and count repetitions. + + Examples: + >>> gym = AIGym(model="yolov8n-pose.pt") + >>> image = cv2.imread("gym_scene.jpg") + >>> processed_image = gym.monitor(image) + >>> cv2.imshow("Processed Image", processed_image) + >>> cv2.waitKey(0) + """ def __init__(self, **kwargs): - """Initialization function for AiGYM class, a child class of BaseSolution class, can be used for workouts - monitoring. - """ + """Initializes AIGym for workout monitoring using pose estimation and predefined angles.""" # Check if the model name ends with '-pose' if "model" in kwargs and "-pose" not in kwargs["model"]: kwargs["model"] = "yolo11n-pose.pt" @@ -31,12 +55,22 @@ class AIGym(BaseSolution): def monitor(self, im0): """ - Monitor the workouts using Ultralytics YOLO Pose Model: https://docs.ultralytics.com/tasks/pose/. + Monitors workouts using Ultralytics YOLO Pose Model. + + This function processes an input image to track and analyze human poses for workout monitoring. It uses + the YOLO Pose model to detect keypoints, estimate angles, and count repetitions based on predefined + angle thresholds. Args: - im0 (ndarray): The input image that will be used for processing - Returns - im0 (ndarray): The processed image for more usage + im0 (ndarray): Input image for processing. + + Returns: + (ndarray): Processed image with annotations for workout monitoring. + + Examples: + >>> gym = AIGym() + >>> image = cv2.imread("workout.jpg") + >>> processed_image = gym.monitor(image) """ # Extract tracks tracks = self.model.track(source=im0, persist=True, classes=self.CFG["classes"])[0] diff --git a/ultralytics/solutions/analytics.py b/ultralytics/solutions/analytics.py index 6c2f27db03..aed7beed94 100644 --- a/ultralytics/solutions/analytics.py +++ b/ultralytics/solutions/analytics.py @@ -12,10 +12,41 @@ from ultralytics.solutions.solutions import BaseSolution # Import a parent clas class Analytics(BaseSolution): - """A class to create and update various types of charts (line, bar, pie, area) for visual analytics.""" + """ + A class for creating and updating various types of charts for visual analytics. + + This class extends BaseSolution to provide functionality for generating line, bar, pie, and area charts + based on object detection and tracking data. + + Attributes: + type (str): The type of analytics chart to generate ('line', 'bar', 'pie', or 'area'). + x_label (str): Label for the x-axis. + y_label (str): Label for the y-axis. + bg_color (str): Background color of the chart frame. + fg_color (str): Foreground color of the chart frame. + title (str): Title of the chart window. + max_points (int): Maximum number of data points to display on the chart. + fontsize (int): Font size for text display. + color_cycle (cycle): Cyclic iterator for chart colors. + total_counts (int): Total count of detected objects (used for line charts). + clswise_count (Dict[str, int]): Dictionary for class-wise object counts. + fig (Figure): Matplotlib figure object for the chart. + ax (Axes): Matplotlib axes object for the chart. + canvas (FigureCanvas): Canvas for rendering the chart. + + Methods: + process_data: Processes image data and updates the chart. + update_graph: Updates the chart with new data points. + + Examples: + >>> analytics = Analytics(analytics_type="line") + >>> frame = cv2.imread("image.jpg") + >>> processed_frame = analytics.process_data(frame, frame_number=1) + >>> cv2.imshow("Analytics", processed_frame) + """ def __init__(self, **kwargs): - """Initialize the Analytics class with various chart types.""" + """Initialize Analytics class with various chart types for visual data representation.""" super().__init__(**kwargs) self.type = self.CFG["analytics_type"] # extract type of analytics @@ -31,8 +62,8 @@ class Analytics(BaseSolution): figsize = (19.2, 10.8) # Set output image size 1920 * 1080 self.color_cycle = cycle(["#DD00BA", "#042AFF", "#FF4447", "#7D24FF", "#BD00FF"]) - self.total_counts = 0 # count variable for storing total counts i.e for line - self.clswise_count = {} # dictionary for classwise counts + self.total_counts = 0 # count variable for storing total counts i.e. for line + self.clswise_count = {} # dictionary for class-wise counts # Ensure line and area chart if self.type in {"line", "area"}: @@ -48,15 +79,28 @@ class Analytics(BaseSolution): self.canvas = FigureCanvas(self.fig) # Set common axis properties self.ax.set_facecolor(self.bg_color) self.color_mapping = {} - self.ax.axis("equal") if self.type == "pie" else None # Ensure pie chart is circular + + if self.type == "pie": # Ensure pie chart is circular + self.ax.axis("equal") def process_data(self, im0, frame_number): """ - Process the image data, run object tracking. + Processes image data and runs object tracking to update analytics charts. Args: - im0 (ndarray): Input image for processing. - frame_number (int): Video frame # for plotting the data. + im0 (np.ndarray): Input image for processing. + frame_number (int): Video frame number for plotting the data. + + Returns: + (np.ndarray): Processed image with updated analytics chart. + + Raises: + ModuleNotFoundError: If an unsupported chart type is specified. + + Examples: + >>> analytics = Analytics(analytics_type="line") + >>> frame = np.zeros((480, 640, 3), dtype=np.uint8) + >>> processed_frame = analytics.process_data(frame, frame_number=1) """ self.extract_tracks(im0) # Extract tracks @@ -79,13 +123,22 @@ class Analytics(BaseSolution): def update_graph(self, frame_number, count_dict=None, plot="line"): """ - Update the graph (line or area) with new data for single or multiple classes. + Updates the graph with new data for single or multiple classes. Args: frame_number (int): The current frame number. - count_dict (dict, optional): Dictionary with class names as keys and counts as values for multiple classes. - If None, updates a single line graph. - plot (str): Type of the plot i.e. line, bar or area. + count_dict (Dict[str, int] | None): Dictionary with class names as keys and counts as values for multiple + classes. If None, updates a single line graph. + plot (str): Type of the plot. Options are 'line', 'bar', 'pie', or 'area'. + + Returns: + (np.ndarray): Updated image containing the graph. + + Examples: + >>> analytics = Analytics() + >>> frame_number = 10 + >>> count_dict = {"person": 5, "car": 3} + >>> updated_image = analytics.update_graph(frame_number, count_dict, plot="bar") """ if count_dict is None: # Single line update diff --git a/ultralytics/solutions/distance_calculation.py b/ultralytics/solutions/distance_calculation.py index 773b6086da..608aa97d7e 100644 --- a/ultralytics/solutions/distance_calculation.py +++ b/ultralytics/solutions/distance_calculation.py @@ -4,15 +4,41 @@ import math import cv2 -from ultralytics.solutions.solutions import BaseSolution # Import a parent class +from ultralytics.solutions.solutions import BaseSolution from ultralytics.utils.plotting import Annotator, colors class DistanceCalculation(BaseSolution): - """A class to calculate distance between two objects in a real-time video stream based on their tracks.""" + """ + A class to calculate distance between two objects in a real-time video stream based on their tracks. + + This class extends BaseSolution to provide functionality for selecting objects and calculating the distance + between them in a video stream using YOLO object detection and tracking. + + Attributes: + left_mouse_count (int): Counter for left mouse button clicks. + selected_boxes (Dict[int, List[float]]): Dictionary to store selected bounding boxes and their track IDs. + annotator (Annotator): An instance of the Annotator class for drawing on the image. + boxes (List[List[float]]): List of bounding boxes for detected objects. + track_ids (List[int]): List of track IDs for detected objects. + clss (List[int]): List of class indices for detected objects. + names (List[str]): List of class names that the model can detect. + centroids (List[List[int]]): List to store centroids of selected bounding boxes. + + Methods: + mouse_event_for_distance: Handles mouse events for selecting objects in the video stream. + calculate: Processes video frames and calculates the distance between selected objects. + + Examples: + >>> distance_calc = DistanceCalculation() + >>> frame = cv2.imread("frame.jpg") + >>> processed_frame = distance_calc.calculate(frame) + >>> cv2.imshow("Distance Calculation", processed_frame) + >>> cv2.waitKey(0) + """ def __init__(self, **kwargs): - """Initializes the DistanceCalculation class with the given parameters.""" + """Initializes the DistanceCalculation class for measuring object distances in video streams.""" super().__init__(**kwargs) # Mouse event information @@ -21,14 +47,18 @@ class DistanceCalculation(BaseSolution): def mouse_event_for_distance(self, event, x, y, flags, param): """ - Handles mouse events to select regions in a real-time video stream. + Handles mouse events to select regions in a real-time video stream for distance calculation. Args: - event (int): Type of mouse event (e.g., cv2.EVENT_MOUSEMOVE, cv2.EVENT_LBUTTONDOWN, etc.). + event (int): Type of mouse event (e.g., cv2.EVENT_MOUSEMOVE, cv2.EVENT_LBUTTONDOWN). x (int): X-coordinate of the mouse pointer. y (int): Y-coordinate of the mouse pointer. - flags (int): Flags associated with the event (e.g., cv2.EVENT_FLAG_CTRLKEY, cv2.EVENT_FLAG_SHIFTKEY, etc.). - param (dict): Additional parameters passed to the function. + flags (int): Flags associated with the event (e.g., cv2.EVENT_FLAG_CTRLKEY, cv2.EVENT_FLAG_SHIFTKEY). + param (Dict): Additional parameters passed to the function. + + Examples: + >>> # Assuming 'dc' is an instance of DistanceCalculation + >>> cv2.setMouseCallback("window_name", dc.mouse_event_for_distance) """ if event == cv2.EVENT_LBUTTONDOWN: self.left_mouse_count += 1 @@ -43,13 +73,23 @@ class DistanceCalculation(BaseSolution): def calculate(self, im0): """ - Processes the video frame and calculates the distance between two bounding boxes. + Processes a video frame and calculates the distance between two selected bounding boxes. + + This method extracts tracks from the input frame, annotates bounding boxes, and calculates the distance + between two user-selected objects if they have been chosen. Args: - im0 (ndarray): The image frame. + im0 (numpy.ndarray): The input image frame to process. Returns: - (ndarray): The processed image frame. + (numpy.ndarray): The processed image frame with annotations and distance calculations. + + Examples: + >>> import numpy as np + >>> from ultralytics.solutions import DistanceCalculation + >>> dc = DistanceCalculation() + >>> frame = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8) + >>> processed_frame = dc.calculate(frame) """ self.annotator = Annotator(im0, line_width=self.line_width) # Initialize annotator self.extract_tracks(im0) # Extract tracks diff --git a/ultralytics/solutions/heatmap.py b/ultralytics/solutions/heatmap.py index d7dcf71cff..39352a9bd7 100644 --- a/ultralytics/solutions/heatmap.py +++ b/ultralytics/solutions/heatmap.py @@ -3,15 +3,40 @@ import cv2 import numpy as np -from ultralytics.solutions.object_counter import ObjectCounter # Import object counter class +from ultralytics.solutions.object_counter import ObjectCounter from ultralytics.utils.plotting import Annotator class Heatmap(ObjectCounter): - """A class to draw heatmaps in real-time video stream based on their tracks.""" + """ + A class to draw heatmaps in real-time video streams based on object tracks. + + This class extends the ObjectCounter class to generate and visualize heatmaps of object movements in video + streams. It uses tracked object positions to create a cumulative heatmap effect over time. + + Attributes: + initialized (bool): Flag indicating whether the heatmap has been initialized. + colormap (int): OpenCV colormap used for heatmap visualization. + heatmap (np.ndarray): Array storing the cumulative heatmap data. + annotator (Annotator): Object for drawing annotations on the image. + + Methods: + heatmap_effect: Calculates and updates the heatmap effect for a given bounding box. + generate_heatmap: Generates and applies the heatmap effect to each frame. + + Examples: + >>> from ultralytics.solutions import Heatmap + >>> heatmap = Heatmap(model="yolov8n.pt", colormap=cv2.COLORMAP_JET) + >>> results = heatmap("path/to/video.mp4") + >>> for result in results: + ... print(result.speed) # Print inference speed + ... cv2.imshow("Heatmap", result.plot()) + ... if cv2.waitKey(1) & 0xFF == ord("q"): + ... break + """ def __init__(self, **kwargs): - """Initializes function for heatmap class with default values.""" + """Initializes the Heatmap class for real-time video stream heatmap generation based on object tracks.""" super().__init__(**kwargs) self.initialized = False # bool variable for heatmap initialization @@ -23,10 +48,15 @@ class Heatmap(ObjectCounter): def heatmap_effect(self, box): """ - Efficient calculation of heatmap area and effect location for applying colormap. + Efficiently calculates heatmap area and effect location for applying colormap. Args: - box (list): Bounding Box coordinates data [x0, y0, x1, y1] + box (List[float]): Bounding box coordinates [x0, y0, x1, y1]. + + Examples: + >>> heatmap = Heatmap() + >>> box = [100, 100, 200, 200] + >>> heatmap.heatmap_effect(box) """ x0, y0, x1, y1 = map(int, box) radius_squared = (min(x1 - x0, y1 - y0) // 2) ** 2 @@ -48,9 +78,15 @@ class Heatmap(ObjectCounter): Generate heatmap for each frame using Ultralytics. Args: - im0 (ndarray): Input image array for processing + im0 (np.ndarray): Input image array for processing. + Returns: - im0 (ndarray): Processed image for further usage + (np.ndarray): Processed image with heatmap overlay and object counts (if region is specified). + + Examples: + >>> heatmap = Heatmap() + >>> im0 = cv2.imread("image.jpg") + >>> result = heatmap.generate_heatmap(im0) """ if not self.initialized: self.heatmap = np.zeros_like(im0, dtype=np.float32) * 0.99 @@ -70,16 +106,17 @@ class Heatmap(ObjectCounter): self.store_classwise_counts(cls) # store classwise counts in dict # Store tracking previous position and perform object counting - prev_position = self.track_history[track_id][-2] if len(self.track_history[track_id]) > 1 else None + prev_position = None + if len(self.track_history[track_id]) > 1: + prev_position = self.track_history[track_id][-2] self.count_objects(self.track_line, box, track_id, prev_position, cls) # Perform object counting - self.display_counts(im0) if self.region is not None else None # Display the counts on the frame + if self.region is not None: + self.display_counts(im0) # Display the counts on the frame # Normalize, apply colormap to heatmap and combine with original image - im0 = ( - im0 - if self.track_data.id is None - else cv2.addWeighted( + if self.track_data.id is not None: + im0 = cv2.addWeighted( im0, 0.5, cv2.applyColorMap( @@ -88,7 +125,6 @@ class Heatmap(ObjectCounter): 0.5, 0, ) - ) self.display_output(im0) # display output with base class function return im0 # return output image for more usage diff --git a/ultralytics/solutions/object_counter.py b/ultralytics/solutions/object_counter.py index d576746421..6374920734 100644 --- a/ultralytics/solutions/object_counter.py +++ b/ultralytics/solutions/object_counter.py @@ -1,18 +1,40 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -from shapely.geometry import LineString, Point - -from ultralytics.solutions.solutions import BaseSolution # Import a parent class +from ultralytics.solutions.solutions import BaseSolution from ultralytics.utils.plotting import Annotator, colors class ObjectCounter(BaseSolution): - """A class to manage the counting of objects in a real-time video stream based on their tracks.""" + """ + A class to manage the counting of objects in a real-time video stream based on their tracks. + + This class extends the BaseSolution class and provides functionality for counting objects moving in and out of a + specified region in a video stream. It supports both polygonal and linear regions for counting. + + Attributes: + in_count (int): Counter for objects moving inward. + out_count (int): Counter for objects moving outward. + counted_ids (List[int]): List of IDs of objects that have been counted. + classwise_counts (Dict[str, Dict[str, int]]): Dictionary for counts, categorized by object class. + region_initialized (bool): Flag indicating whether the counting region has been initialized. + show_in (bool): Flag to control display of inward count. + show_out (bool): Flag to control display of outward count. + + Methods: + count_objects: Counts objects within a polygonal or linear region. + store_classwise_counts: Initializes class-wise counts if not already present. + display_counts: Displays object counts on the frame. + count: Processes input data (frames or object tracks) and updates counts. + + Examples: + >>> counter = ObjectCounter() + >>> frame = cv2.imread("frame.jpg") + >>> processed_frame = counter.count(frame) + >>> print(f"Inward count: {counter.in_count}, Outward count: {counter.out_count}") + """ def __init__(self, **kwargs): - """Initialization function for Count class, a child class of BaseSolution class, can be used for counting the - objects. - """ + """Initializes the ObjectCounter class for real-time object counting in video streams.""" super().__init__(**kwargs) self.in_count = 0 # Counter for objects moving inward @@ -26,14 +48,23 @@ class ObjectCounter(BaseSolution): def count_objects(self, track_line, box, track_id, prev_position, cls): """ - Helper function to count objects within a polygonal region. + Counts objects within a polygonal or linear region based on their tracks. Args: - track_line (dict): last 30 frame track record - box (list): Bounding box data for specific track in current frame - track_id (int): track ID of the object - prev_position (tuple): last frame position coordinates of the track - cls (int): Class index for classwise count updates + track_line (Dict): Last 30 frame track record for the object. + box (List[float]): Bounding box coordinates [x1, y1, x2, y2] for the specific track in the current frame. + track_id (int): Unique identifier for the tracked object. + prev_position (Tuple[float, float]): Last frame position coordinates (x, y) of the track. + cls (int): Class index for classwise count updates. + + Examples: + >>> counter = ObjectCounter() + >>> track_line = {1: [100, 200], 2: [110, 210], 3: [120, 220]} + >>> box = [130, 230, 150, 250] + >>> track_id = 1 + >>> prev_position = (120, 220) + >>> cls = 0 + >>> counter.count_objects(track_line, box, track_id, prev_position, cls) """ if prev_position is None or track_id in self.counted_ids: return @@ -42,7 +73,7 @@ class ObjectCounter(BaseSolution): dx = (box[0] - prev_position[0]) * (centroid.x - prev_position[0]) dy = (box[1] - prev_position[1]) * (centroid.y - prev_position[1]) - if len(self.region) >= 3 and self.r_s.contains(Point(track_line[-1])): + if len(self.region) >= 3 and self.r_s.contains(self.Point(track_line[-1])): self.counted_ids.append(track_id) # For polygon region if dx > 0: @@ -52,7 +83,7 @@ class ObjectCounter(BaseSolution): self.out_count += 1 self.classwise_counts[self.names[cls]]["OUT"] += 1 - elif len(self.region) < 3 and LineString([prev_position, box[:2]]).intersects(self.l_s): + elif len(self.region) < 3 and self.LineString([prev_position, box[:2]]).intersects(self.r_s): self.counted_ids.append(track_id) # For linear region if dx > 0 and dy > 0: @@ -64,20 +95,34 @@ class ObjectCounter(BaseSolution): def store_classwise_counts(self, cls): """ - Initialize class-wise counts if not already present. + Initialize class-wise counts for a specific object class if not already present. Args: - cls (int): Class index for classwise count updates + cls (int): Class index for classwise count updates. + + This method ensures that the 'classwise_counts' dictionary contains an entry for the specified class, + initializing 'IN' and 'OUT' counts to zero if the class is not already present. + + Examples: + >>> counter = ObjectCounter() + >>> counter.store_classwise_counts(0) # Initialize counts for class index 0 + >>> print(counter.classwise_counts) + {'person': {'IN': 0, 'OUT': 0}} """ if self.names[cls] not in self.classwise_counts: self.classwise_counts[self.names[cls]] = {"IN": 0, "OUT": 0} def display_counts(self, im0): """ - Helper function to display object counts on the frame. + Displays object counts on the input image or frame. Args: - im0 (ndarray): The input image or frame + im0 (numpy.ndarray): The input image or frame to display counts on. + + Examples: + >>> counter = ObjectCounter() + >>> frame = cv2.imread("image.jpg") + >>> counter.display_counts(frame) """ labels_dict = { str.capitalize(key): f"{'IN ' + str(value['IN']) if self.show_in else ''} " @@ -91,12 +136,21 @@ class ObjectCounter(BaseSolution): def count(self, im0): """ - Processes input data (frames or object tracks) and updates counts. + Processes input data (frames or object tracks) and updates object counts. + + This method initializes the counting region, extracts tracks, draws bounding boxes and regions, updates + object counts, and displays the results on the input image. Args: - im0 (ndarray): The input image that will be used for processing - Returns - im0 (ndarray): The processed image for more usage + im0 (numpy.ndarray): The input image or frame to be processed. + + Returns: + (numpy.ndarray): The processed image with annotations and count information. + + Examples: + >>> counter = ObjectCounter() + >>> frame = cv2.imread("path/to/image.jpg") + >>> processed_frame = counter.count(frame) """ if not self.region_initialized: self.initialize_region() @@ -122,7 +176,9 @@ class ObjectCounter(BaseSolution): ) # store previous position of track for object counting - prev_position = self.track_history[track_id][-2] if len(self.track_history[track_id]) > 1 else None + prev_position = None + if len(self.track_history[track_id]) > 1: + prev_position = self.track_history[track_id][-2] self.count_objects(self.track_line, box, track_id, prev_position, cls) # Perform object counting self.display_counts(im0) # Display the counts on the frame diff --git a/ultralytics/solutions/parking_management.py b/ultralytics/solutions/parking_management.py index 33beb80bff..fa815938ab 100644 --- a/ultralytics/solutions/parking_management.py +++ b/ultralytics/solutions/parking_management.py @@ -10,10 +10,44 @@ from ultralytics.utils.plotting import Annotator class ParkingPtsSelection: - """Class for selecting and managing parking zone points on images using a Tkinter-based UI.""" + """ + A class for selecting and managing parking zone points on images using a Tkinter-based UI. + + This class provides functionality to upload an image, select points to define parking zones, and save the + selected points to a JSON file. It uses Tkinter for the graphical user interface. + + Attributes: + tk (module): The Tkinter module for GUI operations. + filedialog (module): Tkinter's filedialog module for file selection operations. + messagebox (module): Tkinter's messagebox module for displaying message boxes. + master (tk.Tk): The main Tkinter window. + canvas (tk.Canvas): The canvas widget for displaying the image and drawing bounding boxes. + image (PIL.Image.Image): The uploaded image. + canvas_image (ImageTk.PhotoImage): The image displayed on the canvas. + rg_data (List[List[Tuple[int, int]]]): List of bounding boxes, each defined by 4 points. + current_box (List[Tuple[int, int]]): Temporary storage for the points of the current bounding box. + imgw (int): Original width of the uploaded image. + imgh (int): Original height of the uploaded image. + canvas_max_width (int): Maximum width of the canvas. + canvas_max_height (int): Maximum height of the canvas. + + Methods: + setup_ui: Sets up the Tkinter UI components. + initialize_properties: Initializes the necessary properties. + upload_image: Uploads an image, resizes it to fit the canvas, and displays it. + on_canvas_click: Handles mouse clicks to add points for bounding boxes. + draw_box: Draws a bounding box on the canvas. + remove_last_bounding_box: Removes the last bounding box and redraws the canvas. + redraw_canvas: Redraws the canvas with the image and all bounding boxes. + save_to_json: Saves the bounding boxes to a JSON file. + + Examples: + >>> parking_selector = ParkingPtsSelection() + >>> # Use the GUI to upload an image, select parking zones, and save the data + """ def __init__(self): - """Class initialization method.""" + """Initializes the ParkingPtsSelection class, setting up UI and properties for parking zone point selection.""" check_requirements("tkinter") import tkinter as tk from tkinter import filedialog, messagebox @@ -24,7 +58,7 @@ class ParkingPtsSelection: self.master.mainloop() def setup_ui(self): - """Sets up the Tkinter UI components.""" + """Sets up the Tkinter UI components for the parking zone points selection interface.""" self.master = self.tk.Tk() self.master.title("Ultralytics Parking Zones Points Selector") self.master.resizable(False, False) @@ -45,14 +79,14 @@ class ParkingPtsSelection: self.tk.Button(button_frame, text=text, command=cmd).pack(side=self.tk.LEFT) def initialize_properties(self): - """Initialize the necessary properties.""" + """Initialize properties for image, canvas, bounding boxes, and dimensions.""" self.image = self.canvas_image = None self.rg_data, self.current_box = [], [] self.imgw = self.imgh = 0 self.canvas_max_width, self.canvas_max_height = 1280, 720 def upload_image(self): - """Uploads an image, resizes it to fit the canvas, and displays it.""" + """Uploads and displays an image on the canvas, resizing it to fit within specified dimensions.""" from PIL import Image, ImageTk # scope because ImageTk requires tkinter package self.image = Image.open(self.filedialog.askopenfilename(filetypes=[("Image Files", "*.png;*.jpg;*.jpeg")])) @@ -76,7 +110,7 @@ class ParkingPtsSelection: self.rg_data.clear(), self.current_box.clear() def on_canvas_click(self, event): - """Handles mouse clicks to add points for bounding boxes.""" + """Handles mouse clicks to add points for bounding boxes on the canvas.""" self.current_box.append((event.x, event.y)) self.canvas.create_oval(event.x - 3, event.y - 3, event.x + 3, event.y + 3, fill="red") if len(self.current_box) == 4: @@ -85,12 +119,12 @@ class ParkingPtsSelection: self.current_box.clear() def draw_box(self, box): - """Draws a bounding box on the canvas.""" + """Draws a bounding box on the canvas using the provided coordinates.""" for i in range(4): self.canvas.create_line(box[i], box[(i + 1) % 4], fill="blue", width=2) def remove_last_bounding_box(self): - """Removes the last bounding box and redraws the canvas.""" + """Removes the last bounding box from the list and redraws the canvas.""" if not self.rg_data: self.messagebox.showwarning("Warning", "No bounding boxes to remove.") return @@ -105,7 +139,7 @@ class ParkingPtsSelection: self.draw_box(box) def save_to_json(self): - """Saves the bounding boxes to a JSON file.""" + """Saves the selected parking zone points to a JSON file with scaled coordinates.""" scale_w, scale_h = self.imgw / self.canvas.winfo_width(), self.imgh / self.canvas.winfo_height() data = [{"points": [(int(x * scale_w), int(y * scale_h)) for x, y in box]} for box in self.rg_data] with open("bounding_boxes.json", "w") as f: @@ -114,7 +148,30 @@ class ParkingPtsSelection: class ParkingManagement(BaseSolution): - """Manages parking occupancy and availability using YOLO model for real-time monitoring and visualization.""" + """ + Manages parking occupancy and availability using YOLO model for real-time monitoring and visualization. + + This class extends BaseSolution to provide functionality for parking lot management, including detection of + occupied spaces, visualization of parking regions, and display of occupancy statistics. + + Attributes: + json_file (str): Path to the JSON file containing parking region details. + json (List[Dict]): Loaded JSON data containing parking region information. + pr_info (Dict[str, int]): Dictionary storing parking information (Occupancy and Available spaces). + arc (Tuple[int, int, int]): RGB color tuple for available region visualization. + occ (Tuple[int, int, int]): RGB color tuple for occupied region visualization. + dc (Tuple[int, int, int]): RGB color tuple for centroid visualization of detected objects. + + Methods: + process_data: Processes model data for parking lot management and visualization. + + Examples: + >>> from ultralytics.solutions import ParkingManagement + >>> parking_manager = ParkingManagement(model="yolov8n.pt", json_file="parking_regions.json") + >>> results = parking_manager(source="parking_lot_video.mp4") + >>> print(f"Occupied spaces: {parking_manager.pr_info['Occupancy']}") + >>> print(f"Available spaces: {parking_manager.pr_info['Available']}") + """ def __init__(self, **kwargs): """Initializes the parking management system with a YOLO model and visualization settings.""" @@ -136,10 +193,19 @@ class ParkingManagement(BaseSolution): def process_data(self, im0): """ - Process the model data for parking lot management. + Processes the model data for parking lot management. + + This function analyzes the input image, extracts tracks, and determines the occupancy status of parking + regions defined in the JSON file. It annotates the image with occupied and available parking spots, + and updates the parking information. Args: - im0 (ndarray): inference image. + im0 (np.ndarray): The input inference image. + + Examples: + >>> parking_manager = ParkingManagement(json_file="parking_regions.json") + >>> image = cv2.imread("parking_lot.jpg") + >>> parking_manager.process_data(image) """ self.extract_tracks(im0) # extract tracks from im0 es, fs = len(self.json), 0 # empty slots, filled slots diff --git a/ultralytics/solutions/queue_management.py b/ultralytics/solutions/queue_management.py index 287f337dc5..ca0acb14f8 100644 --- a/ultralytics/solutions/queue_management.py +++ b/ultralytics/solutions/queue_management.py @@ -1,16 +1,40 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -from shapely.geometry import Point - -from ultralytics.solutions.solutions import BaseSolution # Import a parent class +from ultralytics.solutions.solutions import BaseSolution from ultralytics.utils.plotting import Annotator, colors class QueueManager(BaseSolution): - """A class to manage the queue in a real-time video stream based on object tracks.""" + """ + Manages queue counting in real-time video streams based on object tracks. + + This class extends BaseSolution to provide functionality for tracking and counting objects within a specified + region in video frames. + + Attributes: + counts (int): The current count of objects in the queue. + rect_color (Tuple[int, int, int]): RGB color tuple for drawing the queue region rectangle. + region_length (int): The number of points defining the queue region. + annotator (Annotator): An instance of the Annotator class for drawing on frames. + track_line (List[Tuple[int, int]]): List of track line coordinates. + track_history (Dict[int, List[Tuple[int, int]]]): Dictionary storing tracking history for each object. + + Methods: + initialize_region: Initializes the queue region. + process_queue: Processes a single frame for queue management. + extract_tracks: Extracts object tracks from the current frame. + store_tracking_history: Stores the tracking history for an object. + display_output: Displays the processed output. + + Examples: + >>> queue_manager = QueueManager(source="video.mp4", region=[100, 100, 200, 200, 300, 300]) + >>> for frame in video_stream: + ... processed_frame = queue_manager.process_queue(frame) + ... cv2.imshow("Queue Management", processed_frame) + """ def __init__(self, **kwargs): - """Initializes the QueueManager with specified parameters for tracking and counting objects.""" + """Initializes the QueueManager with parameters for tracking and counting objects in a video stream.""" super().__init__(**kwargs) self.initialize_region() self.counts = 0 # Queue counts Information @@ -19,12 +43,31 @@ class QueueManager(BaseSolution): def process_queue(self, im0): """ - Main function to start the queue management process. + Processes the queue management for a single frame of video. Args: - im0 (ndarray): The input image that will be used for processing - Returns - im0 (ndarray): The processed image for more usage + im0 (numpy.ndarray): Input image for processing, typically a frame from a video stream. + + Returns: + (numpy.ndarray): Processed image with annotations, bounding boxes, and queue counts. + + This method performs the following steps: + 1. Resets the queue count for the current frame. + 2. Initializes an Annotator object for drawing on the image. + 3. Extracts tracks from the image. + 4. Draws the counting region on the image. + 5. For each detected object: + - Draws bounding boxes and labels. + - Stores tracking history. + - Draws centroids and tracks. + - Checks if the object is inside the counting region and updates the count. + 6. Displays the queue count on the image. + 7. Displays the processed output. + + Examples: + >>> queue_manager = QueueManager() + >>> frame = cv2.imread("frame.jpg") + >>> processed_frame = queue_manager.process_queue(frame) """ self.counts = 0 # Reset counts every frame self.annotator = Annotator(im0, line_width=self.line_width) # Initialize annotator @@ -48,8 +91,10 @@ class QueueManager(BaseSolution): track_history = self.track_history.get(track_id, []) # store previous position of track and check if the object is inside the counting region - prev_position = track_history[-2] if len(track_history) > 1 else None - if self.region_length >= 3 and prev_position and self.r_s.contains(Point(self.track_line[-1])): + prev_position = None + if len(track_history) > 1: + prev_position = track_history[-2] + if self.region_length >= 3 and prev_position and self.r_s.contains(self.Point(self.track_line[-1])): self.counts += 1 # Display queue counts diff --git a/ultralytics/solutions/solutions.py b/ultralytics/solutions/solutions.py index 71a92becfd..1af0c0ba09 100644 --- a/ultralytics/solutions/solutions.py +++ b/ultralytics/solutions/solutions.py @@ -9,21 +9,51 @@ from ultralytics import YOLO from ultralytics.utils import LOGGER, yaml_load from ultralytics.utils.checks import check_imshow, check_requirements -check_requirements("shapely>=2.0.0") -from shapely.geometry import LineString, Polygon - DEFAULT_SOL_CFG_PATH = Path(__file__).resolve().parents[1] / "cfg/solutions/default.yaml" class BaseSolution: - """A class to manage all the Ultralytics Solutions: https://docs.ultralytics.com/solutions/.""" + """ + A base class for managing Ultralytics Solutions. + + This class provides core functionality for various Ultralytics Solutions, including model loading, object tracking, + and region initialization. + + Attributes: + LineString (shapely.geometry.LineString): Class for creating line string geometries. + Polygon (shapely.geometry.Polygon): Class for creating polygon geometries. + Point (shapely.geometry.Point): Class for creating point geometries. + CFG (Dict): Configuration dictionary loaded from a YAML file and updated with kwargs. + region (List[Tuple[int, int]]): List of coordinate tuples defining a region of interest. + line_width (int): Width of lines used in visualizations. + model (ultralytics.YOLO): Loaded YOLO model instance. + names (Dict[int, str]): Dictionary mapping class indices to class names. + env_check (bool): Flag indicating whether the environment supports image display. + track_history (collections.defaultdict): Dictionary to store tracking history for each object. + + Methods: + extract_tracks: Apply object tracking and extract tracks from an input image. + store_tracking_history: Store object tracking history for a given track ID and bounding box. + initialize_region: Initialize the counting region and line segment based on configuration. + display_output: Display the results of processing, including showing frames or saving results. + + Examples: + >>> solution = BaseSolution(model="yolov8n.pt", region=[(0, 0), (100, 0), (100, 100), (0, 100)]) + >>> solution.initialize_region() + >>> image = cv2.imread("image.jpg") + >>> solution.extract_tracks(image) + >>> solution.display_output(image) + """ def __init__(self, **kwargs): - """ - Base initializer for all solutions. + """Initializes the BaseSolution class with configuration settings and YOLO model for Ultralytics solutions.""" + check_requirements("shapely>=2.0.0") + from shapely.geometry import LineString, Point, Polygon + + self.LineString = LineString + self.Polygon = Polygon + self.Point = Point - Child classes should call this with necessary parameters. - """ # Load config and update with args self.CFG = yaml_load(DEFAULT_SOL_CFG_PATH) self.CFG.update(kwargs) @@ -42,10 +72,15 @@ class BaseSolution: def extract_tracks(self, im0): """ - Apply object tracking and extract tracks. + Applies object tracking and extracts tracks from an input image or frame. Args: - im0 (ndarray): The input image or frame + im0 (ndarray): The input image or frame. + + Examples: + >>> solution = BaseSolution() + >>> frame = cv2.imread("path/to/image.jpg") + >>> solution.extract_tracks(frame) """ self.tracks = self.model.track(source=im0, persist=True, classes=self.CFG["classes"]) @@ -62,11 +97,18 @@ class BaseSolution: def store_tracking_history(self, track_id, box): """ - Store object tracking history. + Stores the tracking history of an object. + + This method updates the tracking history for a given object by appending the center point of its + bounding box to the track line. It maintains a maximum of 30 points in the tracking history. Args: - track_id (int): The track ID of the object - box (list): Bounding box coordinates of the object + track_id (int): The unique identifier for the tracked object. + box (List[float]): The bounding box coordinates of the object in the format [x1, y1, x2, y2]. + + Examples: + >>> solution = BaseSolution() + >>> solution.store_tracking_history(1, [100, 200, 300, 400]) """ # Store tracking history self.track_line = self.track_history[track_id] @@ -75,19 +117,32 @@ class BaseSolution: self.track_line.pop(0) def initialize_region(self): - """Initialize the counting region and line segment based on config.""" - self.region = [(20, 400), (1080, 404), (1080, 360), (20, 360)] if self.region is None else self.region - self.r_s = Polygon(self.region) if len(self.region) >= 3 else LineString(self.region) # region segment - self.l_s = LineString( - [(self.region[0][0], self.region[0][1]), (self.region[1][0], self.region[1][1])] - ) # line segment + """Initialize the counting region and line segment based on configuration settings.""" + if self.region is None: + self.region = [(20, 400), (1080, 404), (1080, 360), (20, 360)] + self.r_s = ( + self.Polygon(self.region) if len(self.region) >= 3 else self.LineString(self.region) + ) # region or line def display_output(self, im0): """ Display the results of the processing, which could involve showing frames, printing counts, or saving results. + This method is responsible for visualizing the output of the object detection and tracking process. It displays + the processed frame with annotations, and allows for user interaction to close the display. + Args: - im0 (ndarray): The input image or frame + im0 (numpy.ndarray): The input image or frame that has been processed and annotated. + + Examples: + >>> solution = BaseSolution() + >>> frame = cv2.imread("path/to/image.jpg") + >>> solution.display_output(frame) + + Notes: + - This method will only display output if the 'show' configuration is set to True and the environment + supports image display. + - The display can be closed by pressing the 'q' key. """ if self.CFG.get("show") and self.env_check: cv2.imshow("Ultralytics Solutions", im0) diff --git a/ultralytics/solutions/speed_estimation.py b/ultralytics/solutions/speed_estimation.py index decd159b55..0c4bc5f057 100644 --- a/ultralytics/solutions/speed_estimation.py +++ b/ultralytics/solutions/speed_estimation.py @@ -4,15 +4,43 @@ from time import time import numpy as np -from ultralytics.solutions.solutions import BaseSolution, LineString +from ultralytics.solutions.solutions import BaseSolution from ultralytics.utils.plotting import Annotator, colors class SpeedEstimator(BaseSolution): - """A class to estimate the speed of objects in a real-time video stream based on their tracks.""" + """ + A class to estimate the speed of objects in a real-time video stream based on their tracks. + + This class extends the BaseSolution class and provides functionality for estimating object speeds using + tracking data in video streams. + + Attributes: + spd (Dict[int, float]): Dictionary storing speed data for tracked objects. + trkd_ids (List[int]): List of tracked object IDs that have already been speed-estimated. + trk_pt (Dict[int, float]): Dictionary storing previous timestamps for tracked objects. + trk_pp (Dict[int, Tuple[float, float]]): Dictionary storing previous positions for tracked objects. + annotator (Annotator): Annotator object for drawing on images. + region (List[Tuple[int, int]]): List of points defining the speed estimation region. + track_line (List[Tuple[float, float]]): List of points representing the object's track. + r_s (LineString): LineString object representing the speed estimation region. + + Methods: + initialize_region: Initializes the speed estimation region. + estimate_speed: Estimates the speed of objects based on tracking data. + store_tracking_history: Stores the tracking history for an object. + extract_tracks: Extracts tracks from the current frame. + display_output: Displays the output with annotations. + + Examples: + >>> estimator = SpeedEstimator() + >>> frame = cv2.imread("frame.jpg") + >>> processed_frame = estimator.estimate_speed(frame) + >>> cv2.imshow("Speed Estimation", processed_frame) + """ def __init__(self, **kwargs): - """Initializes the SpeedEstimator with the given parameters.""" + """Initializes the SpeedEstimator object with speed estimation parameters and data structures.""" super().__init__(**kwargs) self.initialize_region() # Initialize speed region @@ -27,9 +55,15 @@ class SpeedEstimator(BaseSolution): Estimates the speed of objects based on tracking data. Args: - im0 (ndarray): The input image that will be used for processing - Returns - im0 (ndarray): The processed image for more usage + im0 (np.ndarray): Input image for processing. Shape is typically (H, W, C) for RGB images. + + Returns: + (np.ndarray): Processed image with speed estimations and annotations. + + Examples: + >>> estimator = SpeedEstimator() + >>> image = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8) + >>> processed_image = estimator.estimate_speed(image) """ self.annotator = Annotator(im0, line_width=self.line_width) # Initialize annotator self.extract_tracks(im0) # Extract tracks @@ -56,7 +90,7 @@ class SpeedEstimator(BaseSolution): ) # Calculate object speed and direction based on region intersection - if LineString([self.trk_pp[track_id], self.track_line[-1]]).intersects(self.l_s): + if self.LineString([self.trk_pp[track_id], self.track_line[-1]]).intersects(self.r_s): direction = "known" else: direction = "unknown" diff --git a/ultralytics/solutions/streamlit_inference.py b/ultralytics/solutions/streamlit_inference.py index f38cceb3ce..dcae3add76 100644 --- a/ultralytics/solutions/streamlit_inference.py +++ b/ultralytics/solutions/streamlit_inference.py @@ -11,7 +11,7 @@ from ultralytics.utils.downloads import GITHUB_ASSETS_STEMS def inference(model=None): - """Runs real-time object detection on video input using Ultralytics YOLO11 in a Streamlit application.""" + """Performs real-time object detection on video input using YOLO in a Streamlit web application.""" check_requirements("streamlit>=1.29.0") # scope imports for faster ultralytics package load speeds import streamlit as st @@ -108,7 +108,7 @@ def inference(model=None): st.warning("Failed to read frame from webcam. Please make sure the webcam is connected properly.") break - prev_time = time.time() + prev_time = time.time() # Store initial time for FPS calculation # Store model predictions if enable_trk == "Yes": @@ -120,7 +120,6 @@ def inference(model=None): # Calculate model FPS curr_time = time.time() fps = 1 / (curr_time - prev_time) - prev_time = curr_time # display frame org_frame.image(frame, channels="BGR") From 899fb0495e2ad05a6a1b0a34909e25e0a8f6b032 Mon Sep 17 00:00:00 2001 From: Laughing <61612323+Laughing-q@users.noreply.github.com> Date: Sat, 19 Oct 2024 02:49:21 +0800 Subject: [PATCH 17/40] Backward compatibility support for legacy models (#17010) Co-authored-by: Glenn Jocher --- ultralytics/nn/modules/head.py | 17 +++++++++++------ ultralytics/nn/tasks.py | 9 +++++++-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ultralytics/nn/modules/head.py b/ultralytics/nn/modules/head.py index 60911e779f..4bc1fa25e7 100644 --- a/ultralytics/nn/modules/head.py +++ b/ultralytics/nn/modules/head.py @@ -28,6 +28,7 @@ class Detect(nn.Module): shape = None anchors = torch.empty(0) # init strides = torch.empty(0) # init + legacy = False # backward compatibility for v3/v5/v8/v9 models def __init__(self, nc=80, ch=()): """Initializes the YOLO detection layer with specified number of classes and channels.""" @@ -41,13 +42,17 @@ class Detect(nn.Module): self.cv2 = nn.ModuleList( nn.Sequential(Conv(x, c2, 3), Conv(c2, c2, 3), nn.Conv2d(c2, 4 * self.reg_max, 1)) for x in ch ) - self.cv3 = nn.ModuleList( - nn.Sequential( - nn.Sequential(DWConv(x, x, 3), Conv(x, c3, 1)), - nn.Sequential(DWConv(c3, c3, 3), Conv(c3, c3, 1)), - nn.Conv2d(c3, self.nc, 1), + self.cv3 = ( + nn.ModuleList(nn.Sequential(Conv(x, c3, 3), Conv(c3, c3, 3), nn.Conv2d(c3, self.nc, 1)) for x in ch) + if self.legacy + else nn.ModuleList( + nn.Sequential( + nn.Sequential(DWConv(x, x, 3), Conv(x, c3, 1)), + nn.Sequential(DWConv(c3, c3, 3), Conv(c3, c3, 1)), + nn.Conv2d(c3, self.nc, 1), + ) + for x in ch ) - for x in ch ) self.dfl = DFL(self.reg_max) if self.reg_max > 1 else nn.Identity() diff --git a/ultralytics/nn/tasks.py b/ultralytics/nn/tasks.py index 12de1cfbf6..1e69a8f25c 100644 --- a/ultralytics/nn/tasks.py +++ b/ultralytics/nn/tasks.py @@ -936,6 +936,7 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3) import ast # Args + legacy = True # backward compatibility for v3/v5/v8/v9 models max_channels = float("inf") nc, act, scales = (d.get(x) for x in ("nc", "activation", "scales")) depth, width, kpt_shape = (d.get(x, 1.0) for x in ("depth_multiple", "width_multiple", "kpt_shape")) @@ -1027,8 +1028,10 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3) }: args.insert(2, n) # number of repeats n = 1 - if m is C3k2 and scale in "mlx": # for M/L/X sizes - args[3] = True + if m is C3k2: # for M/L/X sizes + legacy = False + if scale in "mlx": + args[3] = True elif m is AIFI: args = [ch[f], *args] elif m in {HGStem, HGBlock}: @@ -1047,6 +1050,8 @@ def parse_model(d, ch, verbose=True): # model_dict, input_channels(3) args.append([ch[x] for x in f]) if m is Segment: args[2] = make_divisible(min(args[2], max_channels) * width, 8) + if m in {Detect, Segment, Pose, OBB}: + m.legacy = legacy elif m is RTDETRDecoder: # special case, channels arg must be passed in index 1 args.insert(1, [ch[x] for x in f]) elif m is CBLinear: From 9f8cf111c47781024f4cb592d751aaff35d4b08a Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Fri, 18 Oct 2024 20:55:53 +0200 Subject: [PATCH 18/40] `ultralytics 8.3.17` accept spaces in CLI args (#16641) Co-authored-by: UltralyticsAssistant Co-authored-by: RizwanMunawar Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> --- ultralytics/__init__.py | 2 +- ultralytics/cfg/__init__.py | 54 +++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 9c0a6f3943..10688a9a2f 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.16" +__version__ = "8.3.17" import os diff --git a/ultralytics/cfg/__init__.py b/ultralytics/cfg/__init__.py index e73610aaf5..4cdb123d81 100644 --- a/ultralytics/cfg/__init__.py +++ b/ultralytics/cfg/__init__.py @@ -438,34 +438,60 @@ def check_dict_alignment(base: Dict, custom: Dict, e=None): def merge_equals_args(args: List[str]) -> List[str]: """ - Merges arguments around isolated '=' in a list of strings, handling three cases: - 1. ['arg', '=', 'val'] becomes ['arg=val'], - 2. ['arg=', 'val'] becomes ['arg=val'], - 3. ['arg', '=val'] becomes ['arg=val']. + Merges arguments around isolated '=' in a list of strings and joins fragments with brackets. + + This function handles the following cases: + 1. ['arg', '=', 'val'] becomes ['arg=val'] + 2. ['arg=', 'val'] becomes ['arg=val'] + 3. ['arg', '=val'] becomes ['arg=val'] + 4. Joins fragments with brackets, e.g., ['imgsz=[3,', '640,', '640]'] becomes ['imgsz=[3,640,640]'] Args: - args (List[str]): A list of strings where each element represents an argument. + args (List[str]): A list of strings where each element represents an argument or fragment. Returns: - (List[str]): A list of strings where the arguments around isolated '=' are merged. + List[str]: A list of strings where the arguments around isolated '=' are merged and fragments with brackets are joined. Examples: - >>> args = ["arg1", "=", "value", "arg2=", "value2", "arg3", "=value3"] - >>> merge_equals_args(args) - ['arg1=value', 'arg2=value2', 'arg3=value3'] + >>> args = ["arg1", "=", "value", "arg2=", "value2", "arg3", "=value3", "imgsz=[3,", "640,", "640]"] + >>> merge_and_join_args(args) + ['arg1=value', 'arg2=value2', 'arg3=value3', 'imgsz=[3,640,640]'] """ new_args = [] - for i, arg in enumerate(args): + current = "" + depth = 0 + + i = 0 + while i < len(args): + arg = args[i] + + # Handle equals sign merging if arg == "=" and 0 < i < len(args) - 1: # merge ['arg', '=', 'val'] new_args[-1] += f"={args[i + 1]}" - del args[i + 1] + i += 2 + continue elif arg.endswith("=") and i < len(args) - 1 and "=" not in args[i + 1]: # merge ['arg=', 'val'] new_args.append(f"{arg}{args[i + 1]}") - del args[i + 1] + i += 2 + continue elif arg.startswith("=") and i > 0: # merge ['arg', '=val'] new_args[-1] += arg - else: - new_args.append(arg) + i += 1 + continue + + # Handle bracket joining + depth += arg.count("[") - arg.count("]") + current += arg + if depth == 0: + new_args.append(current) + current = "" + + i += 1 + + # Append any remaining current string + if current: + new_args.append(current) + return new_args From b5f1a70974a7eb38b9670125700ddd40d18d66e5 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sat, 19 Oct 2024 00:41:13 +0200 Subject: [PATCH 19/40] Update YOLO login (#17022) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- ultralytics/cfg/__init__.py | 2 +- ultralytics/hub/__init__.py | 6 +++--- ultralytics/hub/auth.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ultralytics/cfg/__init__.py b/ultralytics/cfg/__init__.py index 4cdb123d81..153ab27e38 100644 --- a/ultralytics/cfg/__init__.py +++ b/ultralytics/cfg/__init__.py @@ -508,7 +508,7 @@ def handle_yolo_hub(args: List[str]) -> None: Examples: ```bash - yolo hub login YOUR_API_KEY + yolo login YOUR_API_KEY ``` Notes: diff --git a/ultralytics/hub/__init__.py b/ultralytics/hub/__init__.py index 9c9c9dfa16..5b1fc9faeb 100644 --- a/ultralytics/hub/__init__.py +++ b/ultralytics/hub/__init__.py @@ -63,13 +63,13 @@ def login(api_key: str = None, save=True) -> bool: return True else: # Failed to authenticate with HUB - LOGGER.info(f"{PREFIX}Get API key from {api_key_url} and then run 'yolo hub login API_KEY'") + LOGGER.info(f"{PREFIX}Get API key from {api_key_url} and then run 'yolo login API_KEY'") return False def logout(): """ - Log out of Ultralytics HUB by removing the API key from the settings file. To log in again, use 'yolo hub login'. + Log out of Ultralytics HUB by removing the API key from the settings file. To log in again, use 'yolo login'. Example: ```python @@ -79,7 +79,7 @@ def logout(): ``` """ SETTINGS["api_key"] = "" - LOGGER.info(f"{PREFIX}logged out โœ…. To log in again, use 'yolo hub login'.") + LOGGER.info(f"{PREFIX}logged out โœ…. To log in again, use 'yolo login'.") def reset_model(model_id=""): diff --git a/ultralytics/hub/auth.py b/ultralytics/hub/auth.py index 3c7c6d3d25..a12215bb20 100644 --- a/ultralytics/hub/auth.py +++ b/ultralytics/hub/auth.py @@ -68,7 +68,7 @@ class Auth: if verbose: LOGGER.info(f"{PREFIX}New authentication successful โœ…") elif verbose: - LOGGER.info(f"{PREFIX}Get API key from {API_KEY_URL} and then run 'yolo hub login API_KEY'") + LOGGER.info(f"{PREFIX}Get API key from {API_KEY_URL} and then run 'yolo login API_KEY'") def request_api_key(self, max_attempts=3): """ From 92cc8b8b52fc7122848d2d5472b79841135f902d Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sat, 19 Oct 2024 01:19:45 +0200 Subject: [PATCH 20/40] `ultralytics 8.3.18` fix `is_jupyter()` to `globals()` (#17023) --- ultralytics/__init__.py | 2 +- ultralytics/utils/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 10688a9a2f..0887cf9050 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.17" +__version__ = "8.3.18" import os diff --git a/ultralytics/utils/__init__.py b/ultralytics/utils/__init__.py index 6e19188ca8..05a4f464b7 100644 --- a/ultralytics/utils/__init__.py +++ b/ultralytics/utils/__init__.py @@ -571,7 +571,7 @@ def is_jupyter(): Returns: (bool): True if running inside a Jupyter Notebook, False otherwise. """ - return "get_ipython" in locals() + return "get_ipython" in globals() def is_docker() -> bool: From 31b357b8a791798cb4110abf597aedb3c042778b Mon Sep 17 00:00:00 2001 From: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Date: Sat, 19 Oct 2024 13:46:45 +0200 Subject: [PATCH 21/40] Revert "Fixed build docs regex security" (#17027) --- docs/build_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build_docs.py b/docs/build_docs.py index 281a85f513..483a2dd051 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -199,7 +199,7 @@ def convert_plaintext_links_to_html(content): for text_node in paragraph.find_all(string=True, recursive=False): if text_node.parent.name not in {"a", "code"}: # Ignore links and code blocks new_text = re.sub( - r'\b(https?://(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(?:/[a-zA-Z0-9\-._~:/?#[\]@!$&\'()*+,;=%]*)?)(?]+(?:\.[^\s()<>]+)+)(?\1', str(text_node), ) From 99f729a4e453151a14ad975012b0877ce42c07a0 Mon Sep 17 00:00:00 2001 From: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Date: Sat, 19 Oct 2024 18:20:57 +0200 Subject: [PATCH 22/40] Ultralytics Refactor https://ultralytics.com/actions (#17031) Signed-off-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- .github/workflows/format.yml | 2 +- README.md | 8 +++--- README.zh-CN.md | 8 +++--- docs/build_docs.py | 2 +- docs/en/datasets/explorer/explorer.ipynb | 2 +- .../guides/coral-edge-tpu-on-raspberry-pi.md | 2 +- docs/en/guides/model-training-tips.md | 2 +- docs/en/guides/steps-of-a-cv-project.md | 6 +---- docs/en/index.md | 2 +- docs/en/integrations/kaggle.md | 6 ++--- .../environments/aws_quickstart_tutorial.md | 2 +- .../docker_image_quickstart_tutorial.md | 2 +- docs/en/yolov5/index.md | 4 +-- .../tutorials/hyperparameter_evolution.md | 2 +- docs/en/yolov5/tutorials/model_ensembling.md | 2 +- docs/en/yolov5/tutorials/model_export.md | 2 +- .../tutorials/model_pruning_and_sparsity.md | 2 +- .../en/yolov5/tutorials/multi_gpu_training.md | 2 +- .../tutorials/pytorch_hub_model_loading.md | 2 +- .../roboflow_datasets_integration.md | 4 +-- .../tutorials/test_time_augmentation.md | 2 +- docs/en/yolov5/tutorials/train_custom_data.md | 6 ++--- .../transfer_learning_with_frozen_layers.md | 2 +- docs/overrides/partials/source-file.html | 26 ------------------- examples/heatmaps.ipynb | 2 +- examples/object_counting.ipynb | 2 +- examples/object_tracking.ipynb | 2 +- examples/tutorial.ipynb | 2 +- ultralytics/cfg/datasets/coco128-seg.yaml | 2 +- ultralytics/cfg/datasets/coco128.yaml | 2 +- 30 files changed, 41 insertions(+), 71 deletions(-) delete mode 100644 docs/overrides/partials/source-file.html diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index f1e6ba908e..acd2865658 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -49,7 +49,7 @@ jobs: YOLO may be run in any of the following up-to-date verified environments (with all dependencies including [CUDA](https://developer.nvidia.com/cuda)/[CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/) and [PyTorch](https://pytorch.org/) preinstalled): - - **Notebooks** with free GPU: Run on Gradient Open In Colab Open In Kaggle + - **Notebooks** with free GPU: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud** Deep Learning VM. See [GCP Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/google_cloud_quickstart_tutorial/) - **Amazon** Deep Learning AMI. See [AWS Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/aws_quickstart_tutorial/) - **Docker Image**. See [Docker Quickstart Guide](https://docs.ultralytics.com/yolov5/environments/docker_image_quickstart_tutorial/) Docker Pulls diff --git a/README.md b/README.md index 291977d609..39fd7bacaf 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@
Run Ultralytics on Gradient Open Ultralytics In Colab - Open Ultralytics In Kaggle + Open Ultralytics In Kaggle

@@ -229,9 +229,9 @@ Our key integrations with leading AI platforms extend the functionality of Ultra NeuralMagic logo
-| Ultralytics HUB ๐Ÿš€ | W&B | Comet โญ NEW | Neural Magic | -| :----------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | -| Streamline YOLO workflows: Label, train, and deploy effortlessly with [Ultralytics HUB](https://ultralytics.com/hub). Try now! | Track experiments, hyperparameters, and results with [Weights & Biases](https://docs.wandb.ai/guides/integrations/ultralytics/) | Free forever, [Comet](https://bit.ly/yolov5-readme-comet) lets you save YOLO11 models, resume training, and interactively visualize and debug predictions | Run YOLO11 inference up to 6x faster with [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) | +| Ultralytics HUB ๐Ÿš€ | W&B | Comet โญ NEW | Neural Magic | +| :--------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | +| Streamline YOLO workflows: Label, train, and deploy effortlessly with [Ultralytics HUB](https://www.ultralytics.com/hub). Try now! | Track experiments, hyperparameters, and results with [Weights & Biases](https://docs.wandb.ai/guides/integrations/ultralytics/) | Free forever, [Comet](https://bit.ly/yolov5-readme-comet) lets you save YOLO11 models, resume training, and interactively visualize and debug predictions | Run YOLO11 inference up to 6x faster with [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) | ##
Ultralytics HUB
diff --git a/README.zh-CN.md b/README.zh-CN.md index ae2ded2ea9..ac87d1bd4c 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -16,7 +16,7 @@
Run Ultralytics on Gradient Open Ultralytics In Colab - Open Ultralytics In Kaggle + Open Ultralytics In Kaggle
@@ -229,9 +229,9 @@ YOLO11 [ๆฃ€ๆต‹](https://docs.ultralytics.com/tasks/detect/)ใ€[ๅˆ†ๅ‰ฒ](https://d NeuralMagic logo -| Ultralytics HUB ๐Ÿš€ | W&B | Comet โญ ๅ…จๆ–ฐ | Neural Magic | -| :------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: | -| ็ฎ€ๅŒ– YOLO ๅทฅไฝœๆต็จ‹๏ผš้€š่ฟ‡ [Ultralytics HUB](https://ultralytics.com/hub) ่ฝปๆพๆ ‡ๆณจใ€่ฎญ็ปƒๅ’Œ้ƒจ็ฝฒใ€‚็ซ‹ๅณ่ฏ•็”จ๏ผ | ไฝฟ็”จ [Weights & Biases](https://docs.wandb.ai/guides/integrations/ultralytics/) ่ทŸ่ธชๅฎž้ชŒใ€่ถ…ๅ‚ๆ•ฐๅ’Œ็ป“ๆžœ | ๆฐธไน…ๅ…่ดน๏ผŒ[Comet](https://bit.ly/yolov5-readme-comet) ๅ…่ฎธๆ‚จไฟๅญ˜ YOLO11 ๆจกๅž‹ใ€ๆขๅค่ฎญ็ปƒ๏ผŒๅนถไบคไบ’ๅผๅœฐๅฏ่ง†ๅŒ–ๅ’Œ่ฐƒ่ฏ•้ข„ๆต‹็ป“ๆžœ | ไฝฟ็”จ [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) ่ฟ่กŒ YOLO11 ๆŽจ็†๏ผŒ้€Ÿๅบฆๆๅ‡่‡ณ 6 ๅ€ | +| Ultralytics HUB ๐Ÿš€ | W&B | Comet โญ ๅ…จๆ–ฐ | Neural Magic | +| :----------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: | +| ็ฎ€ๅŒ– YOLO ๅทฅไฝœๆต็จ‹๏ผš้€š่ฟ‡ [Ultralytics HUB](https://www.ultralytics.com/hub) ่ฝปๆพๆ ‡ๆณจใ€่ฎญ็ปƒๅ’Œ้ƒจ็ฝฒใ€‚็ซ‹ๅณ่ฏ•็”จ๏ผ | ไฝฟ็”จ [Weights & Biases](https://docs.wandb.ai/guides/integrations/ultralytics/) ่ทŸ่ธชๅฎž้ชŒใ€่ถ…ๅ‚ๆ•ฐๅ’Œ็ป“ๆžœ | ๆฐธไน…ๅ…่ดน๏ผŒ[Comet](https://bit.ly/yolov5-readme-comet) ๅ…่ฎธๆ‚จไฟๅญ˜ YOLO11 ๆจกๅž‹ใ€ๆขๅค่ฎญ็ปƒ๏ผŒๅนถไบคไบ’ๅผๅœฐๅฏ่ง†ๅŒ–ๅ’Œ่ฐƒ่ฏ•้ข„ๆต‹็ป“ๆžœ | ไฝฟ็”จ [Neural Magic DeepSparse](https://bit.ly/yolov5-neuralmagic) ่ฟ่กŒ YOLO11 ๆŽจ็†๏ผŒ้€Ÿๅบฆๆๅ‡่‡ณ 6 ๅ€ | ##
Ultralytics HUB
diff --git a/docs/build_docs.py b/docs/build_docs.py index 483a2dd051..82e4d6d323 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -199,7 +199,7 @@ def convert_plaintext_links_to_html(content): for text_node in paragraph.find_all(string=True, recursive=False): if text_node.parent.name not in {"a", "code"}: # Ignore links and code blocks new_text = re.sub( - r'(https?://[^\s()<>]+(?:\.[^\s()<>]+)+)(?]+)", r'\1', str(text_node), ) diff --git a/docs/en/datasets/explorer/explorer.ipynb b/docs/en/datasets/explorer/explorer.ipynb index 42da7a61e3..7349a08276 100644 --- a/docs/en/datasets/explorer/explorer.ipynb +++ b/docs/en/datasets/explorer/explorer.ipynb @@ -17,7 +17,7 @@ "\n", " \"Run\n", " \"Open\n", - " \"Open\n", + " \"Open\n", "\n", "Welcome to the Ultralytics Explorer API notebook! This notebook serves as the starting point for exploring the various resources available to help you get started with using Ultralytics to explore your datasets using with the power of semantic search. You can utilities out of the box that allow you to examine specific types of labels using vector search or even SQL queries.\n", "\n", diff --git a/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md b/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md index e2d2a03f45..8715483872 100644 --- a/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md +++ b/docs/en/guides/coral-edge-tpu-on-raspberry-pi.md @@ -27,7 +27,7 @@ The Coral Edge TPU is a compact device that adds an Edge TPU coprocessor to your ## Boost Raspberry Pi Model Performance with Coral Edge TPU -Many people want to run their models on an embedded or mobile device such as a Raspberry Pi, since they are very power efficient and can be used in many different applications. However, the inference performance on these devices is usually poor even when using formats like [onnx](../integrations/onnx.md) or [openvino](../integrations/openvino.md). The Coral Edge TPU is a great solution to this problem, since it can be used with a Raspberry Pi and accelerate inference performance greatly. +Many people want to run their models on an embedded or mobile device such as a Raspberry Pi, since they are very power efficient and can be used in many different applications. However, the inference performance on these devices is usually poor even when using formats like [ONNX](../integrations/onnx.md) or [OpenVINO](../integrations/openvino.md). The Coral Edge TPU is a great solution to this problem, since it can be used with a Raspberry Pi and accelerate inference performance greatly. ## Edge TPU on Raspberry Pi with TensorFlow Lite (New)โญ diff --git a/docs/en/guides/model-training-tips.md b/docs/en/guides/model-training-tips.md index e7e3904811..b0eada0df0 100644 --- a/docs/en/guides/model-training-tips.md +++ b/docs/en/guides/model-training-tips.md @@ -18,7 +18,7 @@ One of the most important steps when working on a [computer vision project](./st allowfullscreen>
- Watch: Model Training Tips | How to Handle Large Datasets | Batch Size, GPU Utilization and [Mixed Precision](https://www.ultralytics.com/glossary/mixed-precision) + Watch: Model Training Tips | How to Handle Large Datasets | Batch Size, GPU Utilization and Mixed Precision

So, what is [model training](../modes/train.md)? Model training is the process of teaching your model to recognize visual patterns and make predictions based on your data. It directly impacts the performance and accuracy of your application. In this guide, we'll cover best practices, optimization techniques, and troubleshooting tips to help you train your computer vision models effectively. diff --git a/docs/en/guides/steps-of-a-cv-project.md b/docs/en/guides/steps-of-a-cv-project.md index ca067547da..72676d72a5 100644 --- a/docs/en/guides/steps-of-a-cv-project.md +++ b/docs/en/guides/steps-of-a-cv-project.md @@ -18,15 +18,11 @@ Computer vision is a subfield of [artificial intelligence](https://www.ultralyti allowfullscreen>
- Watch: How to Do [Computer Vision](https://www.ultralytics.com/glossary/computer-vision-cv) Projects | A Step-by-Step Guide + Watch: How to Do Computer Vision Projects | A Step-by-Step Guide

Computer vision techniques like [object detection](../tasks/detect.md), [image classification](../tasks/classify.md), and [instance segmentation](../tasks/segment.md) can be applied across various industries, from [autonomous driving](https://www.ultralytics.com/solutions/ai-in-self-driving) to [medical imaging](https://www.ultralytics.com/solutions/ai-in-healthcare) to gain valuable insights. -

- Overview of computer vision techniques -

- Working on your own computer vision projects is a great way to understand and learn more about computer vision. However, a computer vision project can consist of many steps, and it might seem confusing at first. By the end of this guide, you'll be familiar with the steps involved in a computer vision project. We'll walk through everything from the beginning to the end of a project, explaining why each part is important. Let's get started and make your computer vision project a success! ## An Overview of a Computer Vision Project diff --git a/docs/en/index.md b/docs/en/index.md index 5f861f7fed..f796e4b483 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -28,7 +28,7 @@ keywords: Ultralytics, YOLO, YOLO11, object detection, image segmentation, deep
Run on Gradient Open In Colab -Open In Kaggle +Open In Kaggle Introducing [Ultralytics](https://www.ultralytics.com/) [YOLO11](https://github.com/ultralytics/ultralytics), the latest version of the acclaimed real-time object detection and image segmentation model. YOLO11 is built on cutting-edge advancements in [deep learning](https://www.ultralytics.com/glossary/deep-learning-dl) and [computer vision](https://www.ultralytics.com/glossary/computer-vision-cv), offering unparalleled performance in terms of speed and [accuracy](https://www.ultralytics.com/glossary/accuracy). Its streamlined design makes it suitable for various applications and easily adaptable to different hardware platforms, from edge devices to cloud APIs. diff --git a/docs/en/integrations/kaggle.md b/docs/en/integrations/kaggle.md index 2e2c00cac6..920c5dbc84 100644 --- a/docs/en/integrations/kaggle.md +++ b/docs/en/integrations/kaggle.md @@ -20,7 +20,7 @@ With more than [10 million users](https://www.kaggle.com/discussions/general/332 Training YOLO11 models on Kaggle is simple and efficient, thanks to the platform's access to powerful GPUs. -To get started, access the [Kaggle YOLO11 Notebook](https://www.kaggle.com/code/ultralytics/yolov8). Kaggle's environment comes with pre-installed libraries like [TensorFlow](https://www.ultralytics.com/glossary/tensorflow) and [PyTorch](https://www.ultralytics.com/glossary/pytorch), making the setup process hassle-free. +To get started, access the [Kaggle YOLO11 Notebook](https://www.kaggle.com/code/glennjocherultralytics/yolo11). Kaggle's environment comes with pre-installed libraries like [TensorFlow](https://www.ultralytics.com/glossary/tensorflow) and [PyTorch](https://www.ultralytics.com/glossary/pytorch), making the setup process hassle-free. ![What is the kaggle integration with respect to YOLO11?](https://github.com/ultralytics/docs/releases/download/0/kaggle-integration-yolov8.avif) @@ -28,7 +28,7 @@ Once you sign in to your Kaggle account, you can click on the option to copy and ![Using kaggle for machine learning model training with a GPU](https://github.com/ultralytics/docs/releases/download/0/using-kaggle-for-machine-learning-model-training-with-a-gpu.avif) -On the [official YOLO11 Kaggle notebook page](https://www.kaggle.com/code/ultralytics/yolov8), if you click on the three dots in the upper right-hand corner, you'll notice more options will pop up. +On the [official YOLO11 Kaggle notebook page](https://www.kaggle.com/code/glennjocherultralytics/yolo11), if you click on the three dots in the upper right-hand corner, you'll notice more options will pop up. ![Overview of Options From the Official YOLO11 Kaggle Notebook Page](https://github.com/ultralytics/docs/releases/download/0/overview-options-yolov8-kaggle-notebook.avif) @@ -95,7 +95,7 @@ Interested in more YOLO11 integrations? Check out the[ Ultralytics integration g ### How do I train a YOLO11 model on Kaggle? -Training a YOLO11 model on Kaggle is straightforward. First, access the [Kaggle YOLO11 Notebook](https://www.kaggle.com/ultralytics/yolov8). Sign in to your Kaggle account, copy and edit the notebook, and select a GPU under the accelerator settings. Run the notebook cells to start training. For more detailed steps, refer to our [YOLO11 Model Training guide](../modes/train.md). +Training a YOLO11 model on Kaggle is straightforward. First, access the [Kaggle YOLO11 Notebook](https://www.kaggle.com/code/glennjocherultralytics/yolo11). Sign in to your Kaggle account, copy and edit the notebook, and select a GPU under the accelerator settings. Run the notebook cells to start training. For more detailed steps, refer to our [YOLO11 Model Training guide](../modes/train.md). ### What are the benefits of using Kaggle for YOLO11 model training? diff --git a/docs/en/yolov5/environments/aws_quickstart_tutorial.md b/docs/en/yolov5/environments/aws_quickstart_tutorial.md index 0e5daf2fe9..387817dcc9 100644 --- a/docs/en/yolov5/environments/aws_quickstart_tutorial.md +++ b/docs/en/yolov5/environments/aws_quickstart_tutorial.md @@ -8,7 +8,7 @@ keywords: YOLOv5, AWS, Deep Learning, Machine Learning, AWS EC2, YOLOv5 setup, D Setting up a high-performance deep learning environment can be daunting for newcomers, but fear not! ๐Ÿ› ๏ธ With this guide, we'll walk you through the process of getting YOLOv5 up and running on an AWS Deep Learning instance. By leveraging the power of Amazon Web Services (AWS), even those new to [machine learning](https://www.ultralytics.com/glossary/machine-learning-ml) can get started quickly and cost-effectively. The AWS platform's scalability is perfect for both experimentation and production deployment. -Other quickstart options for YOLOv5 include our [Colab Notebook](https://colab.research.google.com/github/ultralytics/yolov5/blob/master/tutorial.ipynb) Open In Colab Open In Kaggle, [GCP Deep Learning VM](./google_cloud_quickstart_tutorial.md), and our Docker image at [Docker Hub](https://hub.docker.com/r/ultralytics/yolov5) Docker Pulls. +Other quickstart options for YOLOv5 include our [Colab Notebook](https://colab.research.google.com/github/ultralytics/yolov5/blob/master/tutorial.ipynb) Open In Colab Open In Kaggle, [GCP Deep Learning VM](./google_cloud_quickstart_tutorial.md), and our Docker image at [Docker Hub](https://hub.docker.com/r/ultralytics/yolov5) Docker Pulls. ## Step 1: AWS Console Sign-In diff --git a/docs/en/yolov5/environments/docker_image_quickstart_tutorial.md b/docs/en/yolov5/environments/docker_image_quickstart_tutorial.md index 023f24c505..9063949bc4 100644 --- a/docs/en/yolov5/environments/docker_image_quickstart_tutorial.md +++ b/docs/en/yolov5/environments/docker_image_quickstart_tutorial.md @@ -8,7 +8,7 @@ keywords: YOLOv5, Docker, Ultralytics, setup, guide, tutorial, machine learning, This tutorial will guide you through the process of setting up and running YOLOv5 in a Docker container. -You can also explore other quickstart options for YOLOv5, such as our [Colab Notebook](https://colab.research.google.com/github/ultralytics/yolov5/blob/master/tutorial.ipynb) Open In Colab Open In Kaggle, [GCP Deep Learning VM](./google_cloud_quickstart_tutorial.md), and [Amazon AWS](./aws_quickstart_tutorial.md). +You can also explore other quickstart options for YOLOv5, such as our [Colab Notebook](https://colab.research.google.com/github/ultralytics/yolov5/blob/master/tutorial.ipynb) Open In Colab Open In Kaggle, [GCP Deep Learning VM](./google_cloud_quickstart_tutorial.md), and [Amazon AWS](./aws_quickstart_tutorial.md). ## Prerequisites diff --git a/docs/en/yolov5/index.md b/docs/en/yolov5/index.md index ec52007485..0e0712997b 100644 --- a/docs/en/yolov5/index.md +++ b/docs/en/yolov5/index.md @@ -18,7 +18,7 @@ keywords: YOLOv5, Ultralytics, object detection, computer vision, deep learning,
Run on Gradient Open In Colab -Open In Kaggle +Open In Kaggle

@@ -54,7 +54,7 @@ Here's a compilation of comprehensive tutorials that will guide you through diff Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/hyperparameter_evolution.md b/docs/en/yolov5/tutorials/hyperparameter_evolution.md index 3db460b126..9dff4ba3d7 100644 --- a/docs/en/yolov5/tutorials/hyperparameter_evolution.md +++ b/docs/en/yolov5/tutorials/hyperparameter_evolution.md @@ -153,7 +153,7 @@ We recommend a minimum of 300 generations of evolution for best results. Note th Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/model_ensembling.md b/docs/en/yolov5/tutorials/model_ensembling.md index 814c896921..cc76cc0cda 100644 --- a/docs/en/yolov5/tutorials/model_ensembling.md +++ b/docs/en/yolov5/tutorials/model_ensembling.md @@ -134,7 +134,7 @@ Done. (0.223s) Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/model_export.md b/docs/en/yolov5/tutorials/model_export.md index e5f0c73007..a3a945c1e1 100644 --- a/docs/en/yolov5/tutorials/model_export.md +++ b/docs/en/yolov5/tutorials/model_export.md @@ -234,7 +234,7 @@ YOLOv5 OpenVINO C++ inference examples: Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/model_pruning_and_sparsity.md b/docs/en/yolov5/tutorials/model_pruning_and_sparsity.md index 8bda8772e1..0adfb32c8a 100644 --- a/docs/en/yolov5/tutorials/model_pruning_and_sparsity.md +++ b/docs/en/yolov5/tutorials/model_pruning_and_sparsity.md @@ -97,7 +97,7 @@ In the results we can observe that we have achieved a **sparsity of 30%** in our Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/multi_gpu_training.md b/docs/en/yolov5/tutorials/multi_gpu_training.md index 53f3a1c1fd..d61fab8327 100644 --- a/docs/en/yolov5/tutorials/multi_gpu_training.md +++ b/docs/en/yolov5/tutorials/multi_gpu_training.md @@ -173,7 +173,7 @@ If you went through all the above, feel free to raise an Issue by giving as much Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/pytorch_hub_model_loading.md b/docs/en/yolov5/tutorials/pytorch_hub_model_loading.md index 27e26f144f..0f464adf89 100644 --- a/docs/en/yolov5/tutorials/pytorch_hub_model_loading.md +++ b/docs/en/yolov5/tutorials/pytorch_hub_model_loading.md @@ -361,7 +361,7 @@ model = torch.hub.load("ultralytics/yolov5", "custom", path="yolov5s_paddle_mode Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/roboflow_datasets_integration.md b/docs/en/yolov5/tutorials/roboflow_datasets_integration.md index 55728f21e7..a6f700694c 100644 --- a/docs/en/yolov5/tutorials/roboflow_datasets_integration.md +++ b/docs/en/yolov5/tutorials/roboflow_datasets_integration.md @@ -60,7 +60,7 @@ The real world is messy and your model will invariably encounter situations your Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) @@ -102,4 +102,4 @@ Active learning is a machine learning strategy that iteratively improves a model ### How can I use Ultralytics environments for training YOLOv5 models on different platforms? -Ultralytics provides ready-to-use environments with pre-installed dependencies like CUDA, CUDNN, Python, and [PyTorch](https://www.ultralytics.com/glossary/pytorch), making it easier to kickstart your training projects. These environments are available on various platforms such as Google Cloud, AWS, Azure, and Docker. You can also access free GPU notebooks via [Paperspace](https://bit.ly/yolov5-paperspace-notebook), [Google Colab](https://colab.research.google.com/github/ultralytics/yolov5/blob/master/tutorial.ipynb), and [Kaggle](https://www.kaggle.com/ultralytics/yolov5). For specific setup instructions, visit the [Supported Environments](#supported-environments) section of the documentation. +Ultralytics provides ready-to-use environments with pre-installed dependencies like CUDA, CUDNN, Python, and [PyTorch](https://www.ultralytics.com/glossary/pytorch), making it easier to kickstart your training projects. These environments are available on various platforms such as Google Cloud, AWS, Azure, and Docker. You can also access free GPU notebooks via [Paperspace](https://bit.ly/yolov5-paperspace-notebook), [Google Colab](https://colab.research.google.com/github/ultralytics/yolov5/blob/master/tutorial.ipynb), and [Kaggle](https://www.kaggle.com/models/ultralytics/yolov5). For specific setup instructions, visit the [Supported Environments](#supported-environments) section of the documentation. diff --git a/docs/en/yolov5/tutorials/test_time_augmentation.md b/docs/en/yolov5/tutorials/test_time_augmentation.md index 336ad3f79b..30c53b7230 100644 --- a/docs/en/yolov5/tutorials/test_time_augmentation.md +++ b/docs/en/yolov5/tutorials/test_time_augmentation.md @@ -151,7 +151,7 @@ You can customize the TTA ops applied in the YOLOv5 `forward_augment()` method [ Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/train_custom_data.md b/docs/en/yolov5/tutorials/train_custom_data.md index 8b465c5239..c6f9d6f269 100644 --- a/docs/en/yolov5/tutorials/train_custom_data.md +++ b/docs/en/yolov5/tutorials/train_custom_data.md @@ -77,7 +77,7 @@ Export in `YOLOv5 Pytorch` format, then copy the snippet into your training scri ### 2.1 Create `dataset.yaml` -[COCO128](https://www.kaggle.com/ultralytics/coco128) is an example small tutorial dataset composed of the first 128 images in [COCO](https://cocodataset.org/) train2017. These same 128 images are used for both training and validation to verify our training pipeline is capable of [overfitting](https://www.ultralytics.com/glossary/overfitting). [data/coco128.yaml](https://github.com/ultralytics/yolov5/blob/master/data/coco128.yaml), shown below, is the dataset config file that defines 1) the dataset root directory `path` and relative paths to `train` / `val` / `test` image directories (or `*.txt` files with image paths) and 2) a class `names` dictionary: +[COCO128](https://www.kaggle.com/datasets/ultralytics/coco128) is an example small tutorial dataset composed of the first 128 images in [COCO](https://cocodataset.org/) train2017. These same 128 images are used for both training and validation to verify our training pipeline is capable of [overfitting](https://www.ultralytics.com/glossary/overfitting). [data/coco128.yaml](https://github.com/ultralytics/yolov5/blob/master/data/coco128.yaml), shown below, is the dataset config file that defines 1) the dataset root directory `path` and relative paths to `train` / `val` / `test` image directories (or `*.txt` files with image paths) and 2) a class `names` dictionary: ```yaml # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..] @@ -145,7 +145,7 @@ python train.py --img 640 --epochs 3 --data coco128.yaml --weights yolov5s.pt ๐Ÿ’ก Always train from a local dataset. Mounted or network drives like Google Drive will be very slow. -All training results are saved to `runs/train/` with incrementing run directories, i.e. `runs/train/exp2`, `runs/train/exp3` etc. For more details see the Training section of our tutorial notebook. Open In Colab Open In Kaggle +All training results are saved to `runs/train/` with incrementing run directories, i.e. `runs/train/exp2`, `runs/train/exp3` etc. For more details see the Training section of our tutorial notebook. Open In Colab Open In Kaggle ## 5. Visualize @@ -211,7 +211,7 @@ Once your model is trained you can use your best checkpoint `best.pt` to: Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/en/yolov5/tutorials/transfer_learning_with_frozen_layers.md b/docs/en/yolov5/tutorials/transfer_learning_with_frozen_layers.md index 9e689ad3eb..9a37ace165 100644 --- a/docs/en/yolov5/tutorials/transfer_learning_with_frozen_layers.md +++ b/docs/en/yolov5/tutorials/transfer_learning_with_frozen_layers.md @@ -141,7 +141,7 @@ Interestingly, the more modules are frozen the less GPU memory is required to tr Ultralytics provides a range of ready-to-use environments, each pre-installed with essential dependencies such as [CUDA](https://developer.nvidia.com/cuda-zone), [CUDNN](https://developer.nvidia.com/cudnn), [Python](https://www.python.org/), and [PyTorch](https://pytorch.org/), to kickstart your projects. -- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle +- **Free GPU Notebooks**: Run on Gradient Open In Colab Open In Kaggle - **Google Cloud**: [GCP Quickstart Guide](../environments/google_cloud_quickstart_tutorial.md) - **Amazon**: [AWS Quickstart Guide](../environments/aws_quickstart_tutorial.md) - **Azure**: [AzureML Quickstart Guide](../environments/azureml_quickstart_tutorial.md) diff --git a/docs/overrides/partials/source-file.html b/docs/overrides/partials/source-file.html deleted file mode 100644 index 84e2ab1f7d..0000000000 --- a/docs/overrides/partials/source-file.html +++ /dev/null @@ -1,26 +0,0 @@ -{% import "partials/language.html" as lang with context %} - - - -
-
- - - - {% if page.meta.git_revision_date_localized %} - ๐Ÿ“… {{ lang.t("source.file.date.updated") }}: - {{ page.meta.git_revision_date_localized }} - {% if page.meta.git_creation_date_localized %} -
- ๐ŸŽ‚ {{ lang.t("source.file.date.created") }}: - {{ page.meta.git_creation_date_localized }} - {% endif %} - - - {% elif page.meta.revision_date %} - ๐Ÿ“… {{ lang.t("source.file.date.updated") }}: - {{ page.meta.revision_date }} - {% endif %} -
-
diff --git a/examples/heatmaps.ipynb b/examples/heatmaps.ipynb index 6ebf179b21..11ffdc9058 100644 --- a/examples/heatmaps.ipynb +++ b/examples/heatmaps.ipynb @@ -16,7 +16,7 @@ " \"Ultralytics\n", " \"Run\n", " \"Open\n", - " \"Open\n", + " \"Open\n", " \"Discord\"\n", "\n", "Welcome to the Ultralytics YOLO11 ๐Ÿš€ notebook! YOLO11 is the latest version of the YOLO (You Only Look Once) AI models developed by Ultralytics. This notebook serves as the starting point for exploring the various resources available to help you get started with YOLO11 and understand its features and capabilities.\n", diff --git a/examples/object_counting.ipynb b/examples/object_counting.ipynb index 8356d592d2..572f1033a1 100644 --- a/examples/object_counting.ipynb +++ b/examples/object_counting.ipynb @@ -16,7 +16,7 @@ " \"Ultralytics\n", " \"Run\n", " \"Open\n", - " \"Open\n", + " \"Open\n", " \"Discord\"\n", "\n", "Welcome to the Ultralytics YOLO11 ๐Ÿš€ notebook! YOLO11 is the latest version of the YOLO (You Only Look Once) AI models developed by Ultralytics. This notebook serves as the starting point for exploring the various resources available to help you get started with YOLO11 and understand its features and capabilities.\n", diff --git a/examples/object_tracking.ipynb b/examples/object_tracking.ipynb index 53ca6b253c..7691fce9cd 100644 --- a/examples/object_tracking.ipynb +++ b/examples/object_tracking.ipynb @@ -16,7 +16,7 @@ " \"Ultralytics\n", " \"Run\n", " \"Open\n", - " \"Open\n", + " \"Open\n", " \"Discord\"\n", "\n", "Welcome to the Ultralytics YOLO11 ๐Ÿš€ notebook! YOLO11 is the latest version of the YOLO (You Only Look Once) AI models developed by Ultralytics. This notebook serves as the starting point for exploring the various resources available to help you get started with YOLO11 and understand its features and capabilities.\n", diff --git a/examples/tutorial.ipynb b/examples/tutorial.ipynb index c52b03c990..98c659b864 100644 --- a/examples/tutorial.ipynb +++ b/examples/tutorial.ipynb @@ -30,7 +30,7 @@ " \"Ultralytics\n", " \"Run\n", " \"Open\n", - " \"Open\n", + " \"Open\n", "\n", " \"Discord\"\n", " \"Ultralytics\n", diff --git a/ultralytics/cfg/datasets/coco128-seg.yaml b/ultralytics/cfg/datasets/coco128-seg.yaml index dcd961c6e5..c8349cee66 100644 --- a/ultralytics/cfg/datasets/coco128-seg.yaml +++ b/ultralytics/cfg/datasets/coco128-seg.yaml @@ -1,5 +1,5 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -# COCO128-seg dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics +# COCO128-seg dataset https://www.kaggle.com/datasets/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics # Documentation: https://docs.ultralytics.com/datasets/segment/coco/ # Example usage: yolo train data=coco128.yaml # parent diff --git a/ultralytics/cfg/datasets/coco128.yaml b/ultralytics/cfg/datasets/coco128.yaml index 1b515592f2..a085f5e9a6 100644 --- a/ultralytics/cfg/datasets/coco128.yaml +++ b/ultralytics/cfg/datasets/coco128.yaml @@ -1,5 +1,5 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -# COCO128 dataset https://www.kaggle.com/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics +# COCO128 dataset https://www.kaggle.com/datasets/ultralytics/coco128 (first 128 images from COCO train2017) by Ultralytics # Documentation: https://docs.ultralytics.com/datasets/detect/coco/ # Example usage: yolo train data=coco128.yaml # parent From e107611294327fa0645ac54d1f48ab0d42917064 Mon Sep 17 00:00:00 2001 From: Paula Derrenger <107626595+pderrenger@users.noreply.github.com> Date: Sat, 19 Oct 2024 21:27:03 +0200 Subject: [PATCH 23/40] Fix build_docs regex for trailing URL periods (#17036) Co-authored-by: Glenn Jocher --- docs/build_docs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/build_docs.py b/docs/build_docs.py index 82e4d6d323..f685fdddd9 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -199,11 +199,11 @@ def convert_plaintext_links_to_html(content): for text_node in paragraph.find_all(string=True, recursive=False): if text_node.parent.name not in {"a", "code"}: # Ignore links and code blocks new_text = re.sub( - r"(https?://[^\s()<>]+)", + r"(https?://[^\s()<>]*[^\s()<>.,:;!?])", r'\1', str(text_node), ) - if " Date: Sat, 19 Oct 2024 23:43:12 +0200 Subject: [PATCH 24/40] Fix MNIST link (#17038) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- docs/build_docs.py | 3 ++- docs/en/datasets/classify/mnist.md | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/build_docs.py b/docs/build_docs.py index f685fdddd9..1744aefffa 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -199,11 +199,12 @@ def convert_plaintext_links_to_html(content): for text_node in paragraph.find_all(string=True, recursive=False): if text_node.parent.name not in {"a", "code"}: # Ignore links and code blocks new_text = re.sub( - r"(https?://[^\s()<>]*[^\s()<>.,:;!?])", + r"(https?://[^\s()<>]*[^\s()<>.,:;!?\'\"])", r'\1', str(text_node), ) if " Date: Sun, 20 Oct 2024 00:54:30 +0200 Subject: [PATCH 25/40] Improve Docs publish.yml workflow dispatch (#17039) --- .github/workflows/docs.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5c8baafc0a..37e99b618d 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -20,6 +20,11 @@ on: pull_request: branches: [main] workflow_dispatch: + inputs: + publish_docs: + description: 'Publish live to https://docs.ultralytics.com' + default: 'true' + type: boolean jobs: Docs: @@ -80,7 +85,7 @@ jobs: echo "No changes to commit" fi - name: Publish Docs to https://docs.ultralytics.com - if: github.event_name == 'push' + if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish_docs == 'true') run: | git clone https://github.com/ultralytics/docs.git docs-repo cd docs-repo From 2c8f31c9c0a6a7c307d93041909b1fc46c64dd9b Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sun, 20 Oct 2024 03:12:23 +0200 Subject: [PATCH 26/40] Update extra.js (#17040) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- .github/workflows/docs.yml | 6 +- docs/build_docs.py | 33 ++++++- docs/overrides/javascript/extra.js | 135 +++++++++++++------------- docs/overrides/javascript/giscus.js | 63 ++++++++++++ docs/overrides/partials/comments.html | 48 +-------- docs/overrides/stylesheets/style.css | 14 +-- mkdocs.yml | 2 + 7 files changed, 175 insertions(+), 126 deletions(-) create mode 100644 docs/overrides/javascript/giscus.js diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 37e99b618d..360feead0c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -22,8 +22,8 @@ on: workflow_dispatch: inputs: publish_docs: - description: 'Publish live to https://docs.ultralytics.com' - default: 'true' + description: "Publish live to https://docs.ultralytics.com" + default: "true" type: boolean jobs: @@ -48,7 +48,7 @@ jobs: python-version: "3.x" cache: "pip" # caching pip dependencies - name: Install Dependencies - run: pip install ruff black tqdm mkdocs-material "mkdocstrings[python]" mkdocs-jupyter mkdocs-redirects mkdocs-ultralytics-plugin mkdocs-macros-plugin + run: pip install ruff black tqdm minify-html mkdocs-material "mkdocstrings[python]" mkdocs-jupyter mkdocs-redirects mkdocs-ultralytics-plugin mkdocs-macros-plugin - name: Ruff fixes continue-on-error: true run: ruff check --fix --unsafe-fixes --select D --ignore=D100,D104,D203,D205,D212,D213,D401,D406,D407,D413 . diff --git a/docs/build_docs.py b/docs/build_docs.py index 1744aefffa..7bf0575f44 100644 --- a/docs/build_docs.py +++ b/docs/build_docs.py @@ -238,8 +238,36 @@ def remove_macros(): print(f"Removed {len(macros_indices)} URLs containing '/macros/' from {sitemap}") +def minify_html_files(): + """Minifies all HTML files in the site directory and prints reduction stats.""" + try: + from minify_html import minify # pip install minify-html + except ImportError: + return + + total_original_size = 0 + total_minified_size = 0 + for html_file in tqdm(SITE.rglob("*.html"), desc="Minifying HTML files"): + with open(html_file, encoding="utf-8") as f: + content = f.read() + + original_size = len(content) + minified_content = minify(content) + minified_size = len(minified_content) + + total_original_size += original_size + total_minified_size += minified_size + + with open(html_file, "w", encoding="utf-8") as f: + f.write(minified_content) + + total_reduction = total_original_size - total_minified_size + total_percent_reduction = (total_reduction / total_original_size) * 100 + print(f"Minify HTML reduction: {total_percent_reduction:.2f}% " f"({total_reduction / 1024:.2f} KB saved)") + + def main(): - """Builds docs, updates titles and edit links, and prints local server command.""" + """Builds docs, updates titles and edit links, minifies HTML, and prints local server command.""" prepare_docs_markdown() # Build the main documentation @@ -251,6 +279,9 @@ def main(): # Update docs HTML pages update_docs_html() + # Minify HTML files + minify_html_files() + # Show command to serve built website print('Docs built correctly โœ…\nServe site at http://localhost:8000 with "python -m http.server --directory site"') diff --git a/docs/overrides/javascript/extra.js b/docs/overrides/javascript/extra.js index b106acdfe0..5029ff4893 100644 --- a/docs/overrides/javascript/extra.js +++ b/docs/overrides/javascript/extra.js @@ -1,71 +1,68 @@ -// Function that applies light/dark theme based on the user's preference -const applyAutoTheme = () => { - // Determine the user's preferred color scheme - const prefersLight = window.matchMedia("(prefers-color-scheme: light)").matches; - const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; +// Apply theme based on user preference +const applyTheme = (isDark) => { + document.body.setAttribute( + "data-md-color-scheme", + isDark ? "slate" : "default", + ); + document.body.setAttribute( + "data-md-color-primary", + isDark ? "black" : "indigo", + ); +}; + +// Check and apply auto theme +const checkAutoTheme = () => { + const supportedLangCodes = [ + "en", + "zh", + "ko", + "ja", + "ru", + "de", + "fr", + "es", + "pt", + "it", + "tr", + "vi", + "ar", + ]; + const langCode = window.location.pathname.split("/")[1]; + const localStorageKey = `${supportedLangCodes.includes(langCode) ? `/${langCode}` : ""}/.__palette`; + const palette = JSON.parse(localStorage.getItem(localStorageKey) || "{}"); - // Apply the appropriate attributes based on the user's preference - if (prefersLight) { - document.body.setAttribute("data-md-color-scheme", "default"); - document.body.setAttribute("data-md-color-primary", "indigo"); - } else if (prefersDark) { - document.body.setAttribute("data-md-color-scheme", "slate"); - document.body.setAttribute("data-md-color-primary", "black"); + if (palette.index === 0) { + applyTheme(window.matchMedia("(prefers-color-scheme: dark)").matches); } }; -// Function that checks and applies light/dark theme based on the user's preference (if auto theme is enabled) -function checkAutoTheme() { - // Array of supported language codes -> each language has its own palette (stored in local storage) - const supportedLangCodes = ["en", "zh", "ko", "ja", "ru", "de", "fr", "es", "pt", "it", "tr", "vi", "nl"]; - // Get the URL path - const path = window.location.pathname; - // Extract the language code from the URL (assuming it's in the format /xx/...) - const langCode = path.split("/")[1]; - // Check if the extracted language code is in the supported languages - const isValidLangCode = supportedLangCodes.includes(langCode); - // Construct the local storage key based on the language code if valid, otherwise default to the root key - const localStorageKey = isValidLangCode ? `/${langCode}/.__palette` : "/.__palette"; - // Retrieve the palette from local storage using the constructed key - const palette = localStorage.getItem(localStorageKey); - if (palette) { - // Check if the palette's index is 0 (auto theme) - const paletteObj = JSON.parse(palette); - if (paletteObj && paletteObj.index === 0) { - applyAutoTheme(); - } - } -} +// Event listeners for theme changes +const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)"); +mediaQueryList.addListener(checkAutoTheme); -// Run function when the script loads +// Initial theme check checkAutoTheme(); -// Re-run the function when the user's preference changes (when the user changes their system theme) -window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", checkAutoTheme); -window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", checkAutoTheme); - -// Re-run the function when the palette changes (e.g. user switched from dark theme to auto theme) -// ! We can't use window.addEventListener("storage", checkAutoTheme) because it will NOT be triggered on the current tab -// ! So we have to use the following workaround: -// Get the palette input for auto theme -var autoThemeInput = document.getElementById("__palette_1"); -if (autoThemeInput) { - // Add a click event listener to the input - autoThemeInput.addEventListener("click", function () { - // Check if the auto theme is selected - if (autoThemeInput.checked) { - // Re-run the function after a short delay (to ensure that the palette has been updated) - setTimeout(applyAutoTheme); - } +// Auto theme input listener +document.addEventListener("DOMContentLoaded", () => { + const autoThemeInput = document.getElementById("__palette_1"); + autoThemeInput?.addEventListener("click", () => { + if (autoThemeInput.checked) setTimeout(checkAutoTheme); }); -} +}); -// Add iframe navigation -window.onhashchange = function() { - window.parent.postMessage({ - type: 'navigation', - hash: window.location.pathname + window.location.search + window.location.hash - }, '*'); +// Iframe navigation +window.onhashchange = () => { + window.parent.postMessage( + { + type: "navigation", + hash: + window.location.pathname + + window.location.search + + window.location.hash, + }, + "*", + ); }; // Add Inkeep button @@ -112,35 +109,35 @@ document.addEventListener("DOMContentLoaded", () => { }, aiChatSettings: { chatSubjectName: "Ultralytics", - botAvatarSrcUrl: "https://storage.googleapis.com/organization-image-assets/ultralytics-botAvatarSrcUrl-1727908259285.png", - botAvatarDarkSrcUrl: "https://storage.googleapis.com/organization-image-assets/ultralytics-botAvatarDarkSrcUrl-1727908258478.png", + botAvatarSrcUrl: + "https://storage.googleapis.com/organization-image-assets/ultralytics-botAvatarSrcUrl-1729379860806.svg", quickQuestions: [ "What's new in Ultralytics YOLO11?", "How can I get started with Ultralytics HUB?", - "How does Ultralytics Enterprise Licensing work?" + "How does Ultralytics Enterprise Licensing work?", ], getHelpCallToActions: [ { name: "Ask on Ultralytics GitHub", url: "https://github.com/ultralytics/ultralytics", icon: { - builtIn: "FaGithub" - } + builtIn: "FaGithub", + }, }, { name: "Ask on Ultralytics Discourse", url: "https://community.ultralytics.com/", icon: { - builtIn: "FaDiscourse" - } + builtIn: "FaDiscourse", + }, }, { name: "Ask on Ultralytics Discord", url: "https://discord.com/invite/ultralytics", icon: { - builtIn: "FaDiscord" - } - } + builtIn: "FaDiscord", + }, + }, ], }, }, diff --git a/docs/overrides/javascript/giscus.js b/docs/overrides/javascript/giscus.js new file mode 100644 index 0000000000..327e16ae74 --- /dev/null +++ b/docs/overrides/javascript/giscus.js @@ -0,0 +1,63 @@ +// Giscus functionality +function loadGiscus() { + const script = document.createElement("script"); + script.src = "https://giscus.app/client.js"; + script.setAttribute("data-repo", "ultralytics/ultralytics"); + script.setAttribute("data-repo-id", "R_kgDOH-jzvQ"); + script.setAttribute("data-category", "Docs"); + script.setAttribute("data-category-id", "DIC_kwDOH-jzvc4CWLkL"); + script.setAttribute("data-mapping", "pathname"); + script.setAttribute("data-strict", "1"); + script.setAttribute("data-reactions-enabled", "1"); + script.setAttribute("data-emit-metadata", "0"); + script.setAttribute("data-input-position", "top"); + script.setAttribute("data-theme", "preferred_color_scheme"); + script.setAttribute("data-lang", "en"); + script.setAttribute("data-loading", "lazy"); + script.setAttribute("crossorigin", "anonymous"); + script.setAttribute("async", ""); + + const giscusContainer = document.getElementById("giscus-container"); + if (giscusContainer) { + giscusContainer.appendChild(script); + + // Synchronize Giscus theme with palette + var palette = __md_get("__palette"); + if (palette && typeof palette.color === "object") { + var theme = palette.color.scheme === "slate" ? "dark" : "light"; + script.setAttribute("data-theme", theme); + } + + // Register event handlers for theme changes + var ref = document.querySelector("[data-md-component=palette]"); + if (ref) { + ref.addEventListener("change", function () { + var palette = __md_get("__palette"); + if (palette && typeof palette.color === "object") { + var theme = palette.color.scheme === "slate" ? "dark" : "light"; + + // Instruct Giscus to change theme + var frame = document.querySelector(".giscus-frame"); + if (frame) { + frame.contentWindow.postMessage( + { giscus: { setConfig: { theme } } }, + "https://giscus.app", + ); + } + } + }); + } + } +} + +// MkDocs specific: Load Giscus when the page content is fully loaded +document.addEventListener("DOMContentLoaded", function () { + var observer = new MutationObserver(function (mutations) { + if (document.getElementById("giscus-container")) { + loadGiscus(); + observer.disconnect(); + } + }); + + observer.observe(document.body, { childList: true, subtree: true }); +}); diff --git a/docs/overrides/partials/comments.html b/docs/overrides/partials/comments.html index a99f4f814b..fdfce5d651 100644 --- a/docs/overrides/partials/comments.html +++ b/docs/overrides/partials/comments.html @@ -1,51 +1,7 @@ {% if page.meta.comments %}

{{ lang.t("meta.comments") }}

- - + +
- - {% endif %} diff --git a/docs/overrides/stylesheets/style.css b/docs/overrides/stylesheets/style.css index a5bdcc56ab..d10582db41 100644 --- a/docs/overrides/stylesheets/style.css +++ b/docs/overrides/stylesheets/style.css @@ -76,7 +76,6 @@ div.highlight { .banner-wrapper { justify-content: space-between; gap: 16px; - padding: 16px; } @@ -121,7 +120,6 @@ div.highlight { .banner-wrapper > .banner-button-wrapper, .banner-wrapper > .banner-button-wrapper > .banner-button-wrapper { padding: 2px; - background-color: rgba(222, 255, 56, 0.2); } @@ -131,13 +129,10 @@ div.highlight { .banner-wrapper > .banner-button-wrapper > .banner-button-wrapper > button { cursor: pointer; - min-width: 132px; padding: 10px; - font-weight: 500; color: #111f68; - background-color: rgb(222, 255, 56); } @@ -156,13 +151,11 @@ div.highlight { .banner-wrapper { gap: 32px; - padding: 12px; } .banner-wrapper > .banner-content-wrapper { gap: 24px; - margin: 0 auto; } } @@ -217,6 +210,13 @@ div.highlight { height: 50px; border-radius: 50%; margin-right: 3px; + background-color: #f0f0f0; /* Placeholder color */ + opacity: 0; /* Start fully transparent */ + transition: opacity 0.3s ease-in-out; +} + +.author-link .hover-item[src] { + opacity: 1; /* Fade in when src is set (image loaded) */ } .hover-item:hover { diff --git a/mkdocs.yml b/mkdocs.yml index f5298dc474..17a72c2e2f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -96,8 +96,10 @@ extra: # version: extra_css: - stylesheets/style.css + extra_javascript: - javascript/extra.js + - javascript/giscus.js markdown_extensions: - admonition From 0535db9885327d4ff2e7a7f41e6b8dad4a3a6abf Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Sun, 20 Oct 2024 04:00:25 +0200 Subject: [PATCH 27/40] Fix Giscus load after navigation (#17042) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- docs/overrides/javascript/giscus.js | 89 +++++++++++++++++------------ 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/docs/overrides/javascript/giscus.js b/docs/overrides/javascript/giscus.js index 327e16ae74..a64e297342 100644 --- a/docs/overrides/javascript/giscus.js +++ b/docs/overrides/javascript/giscus.js @@ -1,5 +1,8 @@ // Giscus functionality function loadGiscus() { + const giscusContainer = document.getElementById("giscus-container"); + if (!giscusContainer || giscusContainer.querySelector("script")) return; + const script = document.createElement("script"); script.src = "https://giscus.app/client.js"; script.setAttribute("data-repo", "ultralytics/ultralytics"); @@ -17,47 +20,61 @@ function loadGiscus() { script.setAttribute("crossorigin", "anonymous"); script.setAttribute("async", ""); + giscusContainer.appendChild(script); + + // Synchronize Giscus theme with palette + var palette = __md_get("__palette"); + if (palette && typeof palette.color === "object") { + var theme = palette.color.scheme === "slate" ? "dark" : "light"; + script.setAttribute("data-theme", theme); + } + + // Register event handlers for theme changes + var ref = document.querySelector("[data-md-component=palette]"); + if (ref) { + ref.addEventListener("change", function () { + var palette = __md_get("__palette"); + if (palette && typeof palette.color === "object") { + var theme = palette.color.scheme === "slate" ? "dark" : "light"; + + // Instruct Giscus to change theme + var frame = document.querySelector(".giscus-frame"); + if (frame) { + frame.contentWindow.postMessage( + { giscus: { setConfig: { theme } } }, + "https://giscus.app", + ); + } + } + }); + } +} + +// Use Intersection Observer to load Giscus when the container is visible +function setupGiscusLoader() { const giscusContainer = document.getElementById("giscus-container"); + if (giscusContainer) { - giscusContainer.appendChild(script); - - // Synchronize Giscus theme with palette - var palette = __md_get("__palette"); - if (palette && typeof palette.color === "object") { - var theme = palette.color.scheme === "slate" ? "dark" : "light"; - script.setAttribute("data-theme", theme); - } - - // Register event handlers for theme changes - var ref = document.querySelector("[data-md-component=palette]"); - if (ref) { - ref.addEventListener("change", function () { - var palette = __md_get("__palette"); - if (palette && typeof palette.color === "object") { - var theme = palette.color.scheme === "slate" ? "dark" : "light"; - - // Instruct Giscus to change theme - var frame = document.querySelector(".giscus-frame"); - if (frame) { - frame.contentWindow.postMessage( - { giscus: { setConfig: { theme } } }, - "https://giscus.app", - ); - } + const observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + loadGiscus(); + observer.unobserve(entry.target); } }); - } + }, { threshold: 0.1 }); // Trigger when 10% of the element is visible + + observer.observe(giscusContainer); } } -// MkDocs specific: Load Giscus when the page content is fully loaded -document.addEventListener("DOMContentLoaded", function () { - var observer = new MutationObserver(function (mutations) { - if (document.getElementById("giscus-container")) { - loadGiscus(); - observer.disconnect(); - } +// Hook into MkDocs' navigation system +if (typeof document$ !== "undefined") { + document$.subscribe(() => { + // This function is called on every page load/change + setupGiscusLoader(); }); - - observer.observe(document.body, { childList: true, subtree: true }); -}); +} else { + console.warn("MkDocs document$ not found. Falling back to DOMContentLoaded."); + document.addEventListener("DOMContentLoaded", setupGiscusLoader); +} From b9747791df927bbc06192cd177e9180ca334ec99 Mon Sep 17 00:00:00 2001 From: Mohammed Yasin <32206511+Y-T-G@users.noreply.github.com> Date: Tue, 22 Oct 2024 02:51:36 +0800 Subject: [PATCH 28/40] Remove YOLO11n message from AMP logs (#17075) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- ultralytics/utils/checks.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ultralytics/utils/checks.py b/ultralytics/utils/checks.py index c483e31366..60faef2c4b 100644 --- a/ultralytics/utils/checks.py +++ b/ultralytics/utils/checks.py @@ -688,7 +688,7 @@ def check_amp(model): im = ASSETS / "bus.jpg" # image to check prefix = colorstr("AMP: ") - LOGGER.info(f"{prefix}running Automatic Mixed Precision (AMP) checks with YOLO11n...") + LOGGER.info(f"{prefix}running Automatic Mixed Precision (AMP) checks...") warning_msg = "Setting 'amp=True'. If you experience zero-mAP or NaN losses you can disable AMP with amp=False." try: from ultralytics import YOLO @@ -696,11 +696,13 @@ def check_amp(model): assert amp_allclose(YOLO("yolo11n.pt"), im) LOGGER.info(f"{prefix}checks passed โœ…") except ConnectionError: - LOGGER.warning(f"{prefix}checks skipped โš ๏ธ, offline and unable to download YOLO11n. {warning_msg}") + LOGGER.warning( + f"{prefix}checks skipped โš ๏ธ. " f"Offline and unable to download YOLO11n for AMP checks. {warning_msg}" + ) except (AttributeError, ModuleNotFoundError): LOGGER.warning( f"{prefix}checks skipped โš ๏ธ. " - f"Unable to load YOLO11n due to possible Ultralytics package modifications. {warning_msg}" + f"Unable to load YOLO11n for AMP checks due to possible Ultralytics package modifications. {warning_msg}" ) except AssertionError: LOGGER.warning( From 71624018e25e7267dbf1a295253e519551978d1b Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Mon, 21 Oct 2024 23:56:57 +0500 Subject: [PATCH 29/40] Update notebooks (#17065) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- examples/heatmaps.ipynb | 17 +++++------------ examples/object_counting.ipynb | 22 ++++++---------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/examples/heatmaps.ipynb b/examples/heatmaps.ipynb index 11ffdc9058..c674ad4800 100644 --- a/examples/heatmaps.ipynb +++ b/examples/heatmaps.ipynb @@ -96,10 +96,7 @@ "source": [ "import cv2\n", "\n", - "from ultralytics import YOLO, solutions\n", - "\n", - "# Load YOLO model\n", - "model = YOLO(\"yolo11n.pt\")\n", + "from ultralytics import solutions\n", "\n", "# Open video file\n", "cap = cv2.VideoCapture(\"path/to/video/file.mp4\")\n", @@ -113,10 +110,9 @@ "\n", "# Initialize heatmap object\n", "heatmap_obj = solutions.Heatmap(\n", - " colormap=cv2.COLORMAP_PARULA,\n", - " view_img=True,\n", - " shape=\"circle\",\n", - " names=model.names,\n", + " colormap=cv2.COLORMAP_PARULA, # Color of the heatmap\n", + " show=True, # Display the image during processing\n", + " model=yolo11n.pt, # Ultralytics YOLO11 model file\n", ")\n", "\n", "while cap.isOpened():\n", @@ -125,11 +121,8 @@ " print(\"Video frame is empty or video processing has been successfully completed.\")\n", " break\n", "\n", - " # Perform tracking on the current frame\n", - " tracks = model.track(im0, persist=True, show=False)\n", - "\n", " # Generate heatmap on the frame\n", - " im0 = heatmap_obj.generate_heatmap(im0, tracks)\n", + " im0 = heatmap_obj.generate_heatmap(im0)\n", "\n", " # Write the frame to the output video\n", " video_writer.write(im0)\n", diff --git a/examples/object_counting.ipynb b/examples/object_counting.ipynb index 572f1033a1..50168f262e 100644 --- a/examples/object_counting.ipynb +++ b/examples/object_counting.ipynb @@ -104,10 +104,7 @@ "source": [ "import cv2\n", "\n", - "from ultralytics import YOLO, solutions\n", - "\n", - "# Load the pre-trained YOLO11 model\n", - "model = YOLO(\"yolo11n.pt\")\n", + "from ultralytics import solutions\n", "\n", "# Open the video file\n", "cap = cv2.VideoCapture(\"path/to/video/file.mp4\")\n", @@ -119,19 +116,15 @@ "# Define points for a line or region of interest in the video frame\n", "line_points = [(20, 400), (1080, 400)] # Line coordinates\n", "\n", - "# Specify classes to count, for example: person (0) and car (2)\n", - "classes_to_count = [0, 2] # Class IDs for person and car\n", - "\n", "# Initialize the video writer to save the output video\n", "video_writer = cv2.VideoWriter(\"object_counting_output.avi\", cv2.VideoWriter_fourcc(*\"mp4v\"), fps, (w, h))\n", "\n", "# Initialize the Object Counter with visualization options and other parameters\n", "counter = solutions.ObjectCounter(\n", - " view_img=True, # Display the image during processing\n", - " reg_pts=line_points, # Region of interest points\n", - " names=model.names, # Class names from the YOLO model\n", - " draw_tracks=True, # Draw tracking lines for objects\n", - " line_thickness=2, # Thickness of the lines drawn\n", + " show=True, # Display the image during processing\n", + " region=line_points, # Region of interest points\n", + " model=yolo11n.pt, # Ultralytics YOLO11 model file\n", + " line_width=2, # Thickness of the lines and bounding boxes\n", ")\n", "\n", "# Process video frames in a loop\n", @@ -141,11 +134,8 @@ " print(\"Video frame is empty or video processing has been successfully completed.\")\n", " break\n", "\n", - " # Perform object tracking on the current frame, filtering by specified classes\n", - " tracks = model.track(im0, persist=True, show=False, classes=classes_to_count)\n", - "\n", " # Use the Object Counter to count objects in the frame and get the annotated image\n", - " im0 = counter.start_counting(im0, tracks)\n", + " im0 = counter.count(im0)\n", "\n", " # Write the annotated frame to the output video\n", " video_writer.write(im0)\n", From 767aa1caccc732d9aef8d67814e52491732f66c8 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Tue, 22 Oct 2024 01:34:44 +0200 Subject: [PATCH 30/40] `ultralytics 8.3.19` TensorRT 10.5.0 support (#17076) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- docker/Dockerfile | 4 ++-- ultralytics/__init__.py | 2 +- ultralytics/engine/exporter.py | 4 ++-- ultralytics/nn/autobackend.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 37b0640752..c6b8ac3269 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -41,8 +41,8 @@ ADD https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n.pt . # Install pip packages RUN python3 -m pip install --upgrade pip wheel -# Pin TensorRT-cu12==10.1.0 to avoid 10.2.0 bug https://github.com/ultralytics/ultralytics/pull/14239 (note -cu12 must be used) -RUN pip install -e ".[export]" "tensorrt-cu12==10.1.0" "albumentations>=1.4.6" comet pycocotools +# Note -cu12 must be used with tensorrt) +RUN pip install -e ".[export]" tensorrt-cu12 "albumentations>=1.4.6" comet pycocotools # Run exports to AutoInstall packages # Edge TPU export fails the first time so is run twice here diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 0887cf9050..49cd5efd37 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.18" +__version__ = "8.3.19" import os diff --git a/ultralytics/engine/exporter.py b/ultralytics/engine/exporter.py index b42f8e97cf..b25b837fd1 100644 --- a/ultralytics/engine/exporter.py +++ b/ultralytics/engine/exporter.py @@ -691,10 +691,10 @@ class Exporter: import tensorrt as trt # noqa except ImportError: if LINUX: - check_requirements("tensorrt>7.0.0,<=10.1.0") + check_requirements("tensorrt>7.0.0,!=10.1.0") import tensorrt as trt # noqa check_version(trt.__version__, ">=7.0.0", hard=True) - check_version(trt.__version__, "<=10.1.0", msg="https://github.com/ultralytics/ultralytics/pull/14239") + check_version(trt.__version__, "!=10.1.0", msg="https://github.com/ultralytics/ultralytics/pull/14239") # Setup and checks LOGGER.info(f"\n{prefix} starting export with TensorRT {trt.__version__}...") diff --git a/ultralytics/nn/autobackend.py b/ultralytics/nn/autobackend.py index 9a8678f184..0dcbb12f96 100644 --- a/ultralytics/nn/autobackend.py +++ b/ultralytics/nn/autobackend.py @@ -226,10 +226,10 @@ class AutoBackend(nn.Module): import tensorrt as trt # noqa https://developer.nvidia.com/nvidia-tensorrt-download except ImportError: if LINUX: - check_requirements("tensorrt>7.0.0,<=10.1.0") + check_requirements("tensorrt>7.0.0,!=10.1.0") import tensorrt as trt # noqa check_version(trt.__version__, ">=7.0.0", hard=True) - check_version(trt.__version__, "<=10.1.0", msg="https://github.com/ultralytics/ultralytics/pull/14239") + check_version(trt.__version__, "!=10.1.0", msg="https://github.com/ultralytics/ultralytics/pull/14239") if device.type == "cpu": device = torch.device("cuda:0") Binding = namedtuple("Binding", ("name", "dtype", "shape", "data", "ptr")) From 036b515fba88854b06cecda9b981f1b129f3ad2e Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Tue, 22 Oct 2024 18:27:10 +0200 Subject: [PATCH 31/40] Dockerfile FROM pytorch/pytorch:2.5.0-cuda12.4-cudnn9-runtime (#17094) --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c6b8ac3269..931326f891 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,7 +3,7 @@ # Image is CUDA-optimized for YOLO11 single/multi-GPU training and inference # Start FROM PyTorch image https://hub.docker.com/r/pytorch/pytorch or nvcr.io/nvidia/pytorch:23.03-py3 -FROM pytorch/pytorch:2.4.1-cuda12.1-cudnn9-runtime +FROM pytorch/pytorch:2.5.0-cuda12.4-cudnn9-runtime # Set environment variables # Avoid DDP error "MKL_THREADING_LAYER=INTEL is incompatible with libgomp.so.1 library" https://github.com/pytorch/pytorch/issues/37377 From 901b68aa5c8d5bf334660be11a2228aa76c520ed Mon Sep 17 00:00:00 2001 From: Mohammed Yasin <32206511+Y-T-G@users.noreply.github.com> Date: Wed, 23 Oct 2024 00:27:55 +0800 Subject: [PATCH 32/40] Add Open Images Dataset V7 pretrained model usage examples (#17090) Co-authored-by: Glenn Jocher --- docs/en/datasets/detect/open-images-v7.md | 29 +++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/docs/en/datasets/detect/open-images-v7.md b/docs/en/datasets/detect/open-images-v7.md index 7083a6354c..1751a2d0a4 100644 --- a/docs/en/datasets/detect/open-images-v7.md +++ b/docs/en/datasets/detect/open-images-v7.md @@ -29,6 +29,35 @@ keywords: Open Images V7, Google dataset, computer vision, YOLO11 models, object | [YOLOv8l](https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8l-oiv7.pt) | 640 | 34.9 | 596.9 | 2.43 | 44.1 | 167.4 | | [YOLOv8x](https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8x-oiv7.pt) | 640 | 36.3 | 860.6 | 3.56 | 68.7 | 260.6 | +You can use these pretrained for inference or fine-tuning as follows. + +!!! example "Pretrained Model Usage Example" + + === "Python" + + ```python + from ultralytics import YOLO + + # Load an Open Images Dataset V7 pretrained YOLOv8n model + model = YOLO("yolov8n-oiv7.pt") + + # Run prediction + results = model.predict(source="image.jpg") + + # Start training from the pretrained checkpoint + results = model.train(data="coco8.yaml", epochs=100, imgsz=640) + ``` + + === "CLI" + + ```bash + # Predict using an Open Images Dataset V7 pretrained model + yolo detect predict source=image.jpg model=yolov8n-oiv7.pt + + # Start training from an Open Images Dataset V7 pretrained checkpoint + yolo detect train data=coco8.yaml model=yolov8n-oiv7.pt epochs=100 imgsz=640 + ``` + ![Open Images V7 classes visual](https://github.com/ultralytics/docs/releases/download/0/open-images-v7-classes-visual.avif) ## Key Features From f4d8f7765a490f3920e2d14c592a2967e347f185 Mon Sep 17 00:00:00 2001 From: Anzhc <133806049+Anzhc@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:30:20 +0300 Subject: [PATCH 33/40] `ultralytics 8.3.20` W&B `plots=False` logging fix (#17088) Co-authored-by: Glenn Jocher --- ultralytics/__init__.py | 2 +- ultralytics/utils/callbacks/wb.py | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 49cd5efd37..09e2fde550 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.19" +__version__ = "8.3.20" import os diff --git a/ultralytics/utils/callbacks/wb.py b/ultralytics/utils/callbacks/wb.py index 7b6d00cfc3..b82b8d85ec 100644 --- a/ultralytics/utils/callbacks/wb.py +++ b/ultralytics/utils/callbacks/wb.py @@ -137,17 +137,19 @@ def on_train_end(trainer): if trainer.best.exists(): art.add_file(trainer.best) wb.run.log_artifact(art, aliases=["best"]) - for curve_name, curve_values in zip(trainer.validator.metrics.curves, trainer.validator.metrics.curves_results): - x, y, x_title, y_title = curve_values - _plot_curve( - x, - y, - names=list(trainer.validator.metrics.names.values()), - id=f"curves/{curve_name}", - title=curve_name, - x_title=x_title, - y_title=y_title, - ) + # Check if we actually have plots to save + if trainer.args.plots: + for curve_name, curve_values in zip(trainer.validator.metrics.curves, trainer.validator.metrics.curves_results): + x, y, x_title, y_title = curve_values + _plot_curve( + x, + y, + names=list(trainer.validator.metrics.names.values()), + id=f"curves/{curve_name}", + title=curve_name, + x_title=x_title, + y_title=y_title, + ) wb.run.finish() # required or run continues on dashboard From 357bd373ba290c6d1b26743ae5e4b49ca4e817c4 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Tue, 22 Oct 2024 19:31:55 +0200 Subject: [PATCH 34/40] Update YOLO11 comparison plots (#17097) Signed-off-by: UltralyticsAssistant Co-authored-by: UltralyticsAssistant --- README.md | 2 +- README.zh-CN.md | 2 +- docs/en/models/index.md | 2 +- docs/en/models/yolo11.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 39fd7bacaf..c70ed6a41b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ We hope that the resources here will help you get the most out of YOLO. Please b To request an Enterprise License please complete the form at [Ultralytics Licensing](https://www.ultralytics.com/license). -YOLO11 performance plots
+YOLO11 performance plots
Ultralytics GitHub diff --git a/README.zh-CN.md b/README.zh-CN.md index ac87d1bd4c..53cb7e05d6 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -26,7 +26,7 @@ ๆƒณ็”ณ่ฏทไผไธš่ฎธๅฏ่ฏ๏ผŒ่ฏทๅฎŒๆˆ [Ultralytics Licensing](https://www.ultralytics.com/license) ไธŠ็š„่กจๅ•ใ€‚ -YOLO11 performance plots +YOLO11 performance plots
Ultralytics GitHub diff --git a/docs/en/models/index.md b/docs/en/models/index.md index 5e9d07f3d5..c0f4fd333d 100644 --- a/docs/en/models/index.md +++ b/docs/en/models/index.md @@ -8,7 +8,7 @@ keywords: Ultralytics, supported models, YOLOv3, YOLOv4, YOLOv5, YOLOv6, YOLOv7, Welcome to Ultralytics' model documentation! We offer support for a wide range of models, each tailored to specific tasks like [object detection](../tasks/detect.md), [instance segmentation](../tasks/segment.md), [image classification](../tasks/classify.md), [pose estimation](../tasks/pose.md), and [multi-object tracking](../modes/track.md). If you're interested in contributing your model architecture to Ultralytics, check out our [Contributing Guide](../help/contributing.md). -![Ultralytics YOLO11 Comparison Plots](https://github.com/user-attachments/assets/a311a4ed-bbf2-43b5-8012-5f183a28a845) +![Ultralytics YOLO11 Comparison Plots](https://raw.githubusercontent.com/ultralytics/assets/refs/heads/main/yolo/performance-comparison.png) ## Featured Models diff --git a/docs/en/models/yolo11.md b/docs/en/models/yolo11.md index 0c755147ab..8baf2dd725 100644 --- a/docs/en/models/yolo11.md +++ b/docs/en/models/yolo11.md @@ -10,7 +10,7 @@ keywords: YOLO11, state-of-the-art object detection, YOLO series, Ultralytics, c YOLO11 is the latest iteration in the [Ultralytics](https://www.ultralytics.com/) YOLO series of real-time object detectors, redefining what's possible with cutting-edge [accuracy](https://www.ultralytics.com/glossary/accuracy), speed, and efficiency. Building upon the impressive advancements of previous YOLO versions, YOLO11 introduces significant improvements in architecture and training methods, making it a versatile choice for a wide range of [computer vision](https://www.ultralytics.com/glossary/computer-vision-cv) tasks. -![Ultralytics YOLO11 Comparison Plots](https://github.com/user-attachments/assets/a311a4ed-bbf2-43b5-8012-5f183a28a845) +![Ultralytics YOLO11 Comparison Plots](hhttps://raw.githubusercontent.com/ultralytics/assets/refs/heads/main/yolo/performance-comparison.png)


From 6ebbe17bd82498140e5001ef8d39dfc023163a5d Mon Sep 17 00:00:00 2001 From: Muhammad Rizwan Munawar Date: Tue, 22 Oct 2024 22:50:08 +0500 Subject: [PATCH 35/40] Add YOLO publication notice in Docs (#17095) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- docs/en/models/yolo11.md | 6 +++++- docs/en/models/yolov5.md | 6 +++++- docs/en/models/yolov8.md | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/en/models/yolo11.md b/docs/en/models/yolo11.md index 8baf2dd725..fe9115f2ed 100644 --- a/docs/en/models/yolo11.md +++ b/docs/en/models/yolo11.md @@ -8,9 +8,13 @@ keywords: YOLO11, state-of-the-art object detection, YOLO series, Ultralytics, c ## Overview +!!! tip "Ultralytics YOLO11 Publication" + + Ultralytics has not published a formal research paper for YOLO11 due to the rapidly evolving nature of the models. We focus on advancing the technology and making it easier to use, rather than producing static documentation. For the most up-to-date information on YOLO architecture, features, and usage, please refer to our [GitHub repository](https://github.com/ultralytics/ultralytics) and [documentation](https://docs.ultralytics.com). + YOLO11 is the latest iteration in the [Ultralytics](https://www.ultralytics.com/) YOLO series of real-time object detectors, redefining what's possible with cutting-edge [accuracy](https://www.ultralytics.com/glossary/accuracy), speed, and efficiency. Building upon the impressive advancements of previous YOLO versions, YOLO11 introduces significant improvements in architecture and training methods, making it a versatile choice for a wide range of [computer vision](https://www.ultralytics.com/glossary/computer-vision-cv) tasks. -![Ultralytics YOLO11 Comparison Plots](hhttps://raw.githubusercontent.com/ultralytics/assets/refs/heads/main/yolo/performance-comparison.png) +![Ultralytics YOLO11 Comparison Plots](https://raw.githubusercontent.com/ultralytics/assets/refs/heads/main/yolo/performance-comparison.png)


diff --git a/docs/en/models/yolov5.md b/docs/en/models/yolov5.md index 8ff1c36ec0..91c562a44e 100644 --- a/docs/en/models/yolov5.md +++ b/docs/en/models/yolov5.md @@ -4,7 +4,11 @@ description: Explore YOLOv5u, an advanced object detection model with optimized keywords: YOLOv5, YOLOv5u, object detection, Ultralytics, anchor-free, pre-trained models, accuracy, speed, real-time detection --- -# YOLOv5 +# Ultralytics YOLOv5 + +!!! tip "Ultralytics YOLOv5 Publication" + + Ultralytics has not published a formal research paper for YOLOv5 due to the rapidly evolving nature of the models. We focus on advancing the technology and making it easier to use, rather than producing static documentation. For the most up-to-date information on YOLO architecture, features, and usage, please refer to our [GitHub repository](https://github.com/ultralytics/ultralytics) and [documentation](https://docs.ultralytics.com). ## Overview diff --git a/docs/en/models/yolov8.md b/docs/en/models/yolov8.md index 036cd305a1..c8e4397d15 100644 --- a/docs/en/models/yolov8.md +++ b/docs/en/models/yolov8.md @@ -6,6 +6,10 @@ keywords: YOLOv8, real-time object detection, YOLO series, Ultralytics, computer # Ultralytics YOLOv8 +!!! tip "Ultralytics YOLOv8 Publication" + + Ultralytics has not published a formal research paper for YOLOv8 due to the rapidly evolving nature of the models. We focus on advancing the technology and making it easier to use, rather than producing static documentation. For the most up-to-date information on YOLO architecture, features, and usage, please refer to our [GitHub repository](https://github.com/ultralytics/ultralytics) and [documentation](https://docs.ultralytics.com). + ## Overview YOLOv8 is the latest iteration in the YOLO series of real-time object detectors, offering cutting-edge performance in terms of accuracy and speed. Building upon the advancements of previous YOLO versions, YOLOv8 introduces new features and optimizations that make it an ideal choice for various [object detection](https://www.ultralytics.com/glossary/object-detection) tasks in a wide range of applications. From 797f2374618a231c82d82f3e572635ad776af3b1 Mon Sep 17 00:00:00 2001 From: Mohammed Yasin <32206511+Y-T-G@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:09:21 +0800 Subject: [PATCH 36/40] Add `project` and `name` args to docs for predict and val task (#17114) Co-authored-by: UltralyticsAssistant --- docs/en/macros/predict-args.md | 2 ++ docs/en/macros/validation-args.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/en/macros/predict-args.md b/docs/en/macros/predict-args.md index 35c285afe0..091e692a69 100644 --- a/docs/en/macros/predict-args.md +++ b/docs/en/macros/predict-args.md @@ -15,3 +15,5 @@ | `classes` | `list[int]` | `None` | Filters predictions to a set of class IDs. Only detections belonging to the specified classes will be returned. Useful for focusing on relevant objects in multi-class detection tasks. | | `retina_masks` | `bool` | `False` | Uses high-resolution segmentation masks if available in the model. This can enhance mask quality for segmentation tasks, providing finer detail. | | `embed` | `list[int]` | `None` | Specifies the layers from which to extract feature vectors or [embeddings](https://www.ultralytics.com/glossary/embeddings). Useful for downstream tasks like clustering or similarity search. | +| `project` | `str` | `None` | Name of the project directory where prediction outputs are saved if `save` is enabled. | +| `name` | `str` | `None` | Name of the prediction run. Used for creating a subdirectory within the project folder, where prediction outputs are stored if `save` is enabled. | diff --git a/docs/en/macros/validation-args.md b/docs/en/macros/validation-args.md index 5c709f7bfc..5eeea81f49 100644 --- a/docs/en/macros/validation-args.md +++ b/docs/en/macros/validation-args.md @@ -14,3 +14,5 @@ | `plots` | `bool` | `False` | When set to `True`, generates and saves plots of predictions versus ground truth for visual evaluation of the model's performance. | | `rect` | `bool` | `False` | If `True`, uses rectangular inference for batching, reducing padding and potentially increasing speed and efficiency. | | `split` | `str` | `val` | Determines the dataset split to use for validation (`val`, `test`, or `train`). Allows flexibility in choosing the data segment for performance evaluation. | +| `project` | `str` | `None` | Name of the project directory where validation outputs are saved. | +| `name` | `str` | `None` | Name of the validation run. Used for creating a subdirectory within the project folder, where valdiation logs and outputs are stored. | From d7eef9f330dfafa43fb9f1ca5b6d3ceb7fd51296 Mon Sep 17 00:00:00 2001 From: Iaroslav Omelianenko Date: Wed, 23 Oct 2024 19:55:42 +0300 Subject: [PATCH 37/40] Comet integration fix (#17099) Co-authored-by: UltralyticsAssistant Co-authored-by: Glenn Jocher --- ultralytics/utils/callbacks/comet.py | 43 +++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/ultralytics/utils/callbacks/comet.py b/ultralytics/utils/callbacks/comet.py index 3a217c3f25..3fae97f917 100644 --- a/ultralytics/utils/callbacks/comet.py +++ b/ultralytics/utils/callbacks/comet.py @@ -1,6 +1,7 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license from ultralytics.utils import LOGGER, RANK, SETTINGS, TESTS_RUNNING, ops +from ultralytics.utils.metrics import ClassifyMetrics, DetMetrics, OBBMetrics, PoseMetrics, SegmentMetrics try: assert not TESTS_RUNNING # do not log pytest @@ -16,8 +17,11 @@ try: COMET_SUPPORTED_TASKS = ["detect"] # Names of plots created by Ultralytics that are logged to Comet - EVALUATION_PLOT_NAMES = "F1_curve", "P_curve", "R_curve", "PR_curve", "confusion_matrix" + CONFUSION_MATRIX_PLOT_NAMES = "confusion_matrix", "confusion_matrix_normalized" + EVALUATION_PLOT_NAMES = "F1_curve", "P_curve", "R_curve", "PR_curve" LABEL_PLOT_NAMES = "labels", "labels_correlogram" + SEGMENT_METRICS_PLOT_PREFIX = "Box", "Mask" + POSE_METRICS_PLOT_PREFIX = "Box", "Pose" _comet_image_prediction_count = 0 @@ -86,7 +90,7 @@ def _create_experiment(args): "max_image_predictions": _get_max_image_predictions_to_log(), } ) - experiment.log_other("Created from", "yolov8") + experiment.log_other("Created from", "ultralytics") except Exception as e: LOGGER.warning(f"WARNING โš ๏ธ Comet installed but not initialized correctly, not logging this run. {e}") @@ -274,11 +278,31 @@ def _log_image_predictions(experiment, validator, curr_step): def _log_plots(experiment, trainer): """Logs evaluation plots and label plots for the experiment.""" - plot_filenames = [trainer.save_dir / f"{plots}.png" for plots in EVALUATION_PLOT_NAMES] - _log_images(experiment, plot_filenames, None) - - label_plot_filenames = [trainer.save_dir / f"{labels}.jpg" for labels in LABEL_PLOT_NAMES] - _log_images(experiment, label_plot_filenames, None) + plot_filenames = None + if isinstance(trainer.validator.metrics, SegmentMetrics) and trainer.validator.metrics.task == "segment": + plot_filenames = [ + trainer.save_dir / f"{prefix}{plots}.png" + for plots in EVALUATION_PLOT_NAMES + for prefix in SEGMENT_METRICS_PLOT_PREFIX + ] + elif isinstance(trainer.validator.metrics, PoseMetrics): + plot_filenames = [ + trainer.save_dir / f"{prefix}{plots}.png" + for plots in EVALUATION_PLOT_NAMES + for prefix in POSE_METRICS_PLOT_PREFIX + ] + elif isinstance(trainer.validator.metrics, DetMetrics) or isinstance(trainer.validator.metrics, OBBMetrics): + plot_filenames = [trainer.save_dir / f"{plots}.png" for plots in EVALUATION_PLOT_NAMES] + + if plot_filenames is not None: + _log_images(experiment, plot_filenames, None) + + confusion_matrix_filenames = [trainer.save_dir / f"{plots}.png" for plots in CONFUSION_MATRIX_PLOT_NAMES] + _log_images(experiment, confusion_matrix_filenames, None) + + if not isinstance(trainer.validator.metrics, ClassifyMetrics): + label_plot_filenames = [trainer.save_dir / f"{labels}.jpg" for labels in LABEL_PLOT_NAMES] + _log_images(experiment, label_plot_filenames, None) def _log_model(experiment, trainer): @@ -307,9 +331,6 @@ def on_train_epoch_end(trainer): experiment.log_metrics(trainer.label_loss_items(trainer.tloss, prefix="train"), step=curr_step, epoch=curr_epoch) - if curr_epoch == 1: - _log_images(experiment, trainer.save_dir.glob("train_batch*.jpg"), curr_step) - def on_fit_epoch_end(trainer): """Logs model assets at the end of each epoch.""" @@ -356,6 +377,8 @@ def on_train_end(trainer): _log_confusion_matrix(experiment, trainer, curr_step, curr_epoch) _log_image_predictions(experiment, trainer.validator, curr_step) + _log_images(experiment, trainer.save_dir.glob("train_batch*.jpg"), curr_step) + _log_images(experiment, trainer.save_dir.glob("val_batch*.jpg"), curr_step) experiment.end() global _comet_image_prediction_count From b8fbee3a975dee918ea3ce9369847246500327e9 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Wed, 23 Oct 2024 18:57:42 +0200 Subject: [PATCH 38/40] Update datasets index.md (#17098) --- docs/en/datasets/index.md | 2 +- mkdocs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/datasets/index.md b/docs/en/datasets/index.md index 9d7a10ed7e..4b6bd6c968 100644 --- a/docs/en/datasets/index.md +++ b/docs/en/datasets/index.md @@ -46,7 +46,7 @@ Create [embeddings](https://www.ultralytics.com/glossary/embeddings) for your da - [VisDrone](detect/visdrone.md): A dataset containing object detection and multi-object tracking data from drone-captured imagery with over 10K images and video sequences. - [VOC](detect/voc.md): The Pascal Visual Object Classes (VOC) dataset for object detection and segmentation with 20 object classes and over 11K images. - [xView](detect/xview.md): A dataset for object detection in overhead imagery with 60 object categories and over 1 million annotated objects. -- [Roboflow 100](detect/roboflow-100.md): A diverse object detection benchmark with 100 datasets spanning seven imagery domains for comprehensive model evaluation. +- [RF100](detect/roboflow-100.md): A diverse object detection benchmark with 100 datasets spanning seven imagery domains for comprehensive model evaluation. - [Brain-tumor](detect/brain-tumor.md): A dataset for detecting brain tumors includes MRI or CT scan images with details on tumor presence, location, and characteristics. - [African-wildlife](detect/african-wildlife.md): A dataset featuring images of African wildlife, including buffalo, elephant, rhino, and zebras. - [Signature](detect/signature.md): A dataset featuring images of various documents with annotated signatures, supporting document verification and fraud detection research. diff --git a/mkdocs.yml b/mkdocs.yml index 17a72c2e2f..a7157ec942 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -274,7 +274,7 @@ nav: - VisDrone: datasets/detect/visdrone.md - VOC: datasets/detect/voc.md - xView: datasets/detect/xview.md - - Roboflow 100: datasets/detect/roboflow-100.md + - RF100: datasets/detect/roboflow-100.md - Brain-tumor: datasets/detect/brain-tumor.md - African-wildlife: datasets/detect/african-wildlife.md - Signature: datasets/detect/signature.md From 8f0a94409fb2f6320b2d42db9feb4dea7ec40ac1 Mon Sep 17 00:00:00 2001 From: Justin Davis Date: Wed, 23 Oct 2024 11:00:15 -0600 Subject: [PATCH 39/40] `ultralytics 8.3.21` NVIDIA DLA export support (#16449) Co-authored-by: UltralyticsAssistant Co-authored-by: Ultralytics Assistant <135830346+UltralyticsAssistant@users.noreply.github.com> Co-authored-by: Lakshantha Dissanayake Co-authored-by: Lakshantha Co-authored-by: Laughing <61612323+Laughing-q@users.noreply.github.com> Co-authored-by: Glenn Jocher Co-authored-by: Laughing-q <1185102784@qq.com> --- docs/en/guides/nvidia-jetson.md | 45 +++++++++++++++++++++++++++++++-- docs/en/macros/export-args.md | 1 + ultralytics/__init__.py | 2 +- ultralytics/engine/exporter.py | 23 +++++++++++++++-- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/docs/en/guides/nvidia-jetson.md b/docs/en/guides/nvidia-jetson.md index f352c76b8c..16793288a2 100644 --- a/docs/en/guides/nvidia-jetson.md +++ b/docs/en/guides/nvidia-jetson.md @@ -240,7 +240,7 @@ pip install onnxruntime_gpu-1.17.0-cp38-cp38-linux_aarch64.whl Out of all the model export formats supported by Ultralytics, TensorRT delivers the best inference performance when working with NVIDIA Jetson devices and our recommendation is to use TensorRT with Jetson. We also have a detailed document on TensorRT [here](../integrations/tensorrt.md). -## Convert Model to TensorRT and Run Inference +### Convert Model to TensorRT and Run Inference The YOLOv8n model in PyTorch format is converted to TensorRT to run inference with the exported model. @@ -254,7 +254,7 @@ The YOLOv8n model in PyTorch format is converted to TensorRT to run inference wi # Load a YOLOv8n PyTorch model model = YOLO("yolov8n.pt") - # Export the model + # Export the model to TensorRT model.export(format="engine") # creates 'yolov8n.engine' # Load the exported TensorRT model @@ -274,6 +274,47 @@ The YOLOv8n model in PyTorch format is converted to TensorRT to run inference wi yolo predict model=yolov8n.engine source='https://ultralytics.com/images/bus.jpg' ``` +### Use NVIDIA Deep Learning Accelerator (DLA) + +[NVIDIA Deep Learning Accelerator (DLA)](https://developer.nvidia.com/deep-learning-accelerator) is a specialized hardware component built into NVIDIA Jetson devices that optimizes deep learning inference for energy efficiency and performance. By offloading tasks from the GPU (freeing it up for more intensive processes), DLA enables models to run with lower power consumption while maintaining high throughput, ideal for embedded systems and real-time AI applications. + +The following Jetson devices are equipped with DLA hardware: + +- Jetson Orin NX 16GB +- Jetson AGX Orin Series +- Jetson AGX Xavier Series +- Jetson Xavier NX Series + +!!! example + + === "Python" + + ```python + from ultralytics import YOLO + + # Load a YOLOv8n PyTorch model + model = YOLO("yolov8n.pt") + + # Export the model to TensorRT with DLA enabled (only works with FP16 or INT8) + model.export(format="engine", device="dla:0", half=True) # dla:0 or dla:1 corresponds to the DLA cores + + # Load the exported TensorRT model + trt_model = YOLO("yolov8n.engine") + + # Run inference + results = trt_model("https://ultralytics.com/images/bus.jpg") + ``` + + === "CLI" + + ```bash + # Export a YOLOv8n PyTorch model to TensorRT format with DLA enabled (only works with FP16 or INT8) + yolo export model=yolov8n.pt format=engine device="dla:0" half=True # dla:0 or dla:1 corresponds to the DLA cores + + # Run inference with the exported model on the DLA + yolo predict model=yolov8n.engine source='https://ultralytics.com/images/bus.jpg' + ``` + !!! note Visit the [Export page](../modes/export.md#arguments) to access additional arguments when exporting models to different model formats diff --git a/docs/en/macros/export-args.md b/docs/en/macros/export-args.md index 99dd5f4d0a..242090d7c6 100644 --- a/docs/en/macros/export-args.md +++ b/docs/en/macros/export-args.md @@ -12,3 +12,4 @@ | `workspace` | `float` | `4.0` | Sets the maximum workspace size in GiB for TensorRT optimizations, balancing memory usage and performance. | | `nms` | `bool` | `False` | Adds Non-Maximum Suppression (NMS) to the CoreML export, essential for accurate and efficient detection post-processing. | | `batch` | `int` | `1` | Specifies export model batch inference size or the max number of images the exported model will process concurrently in `predict` mode. | +| `device` | `str` | `None` | Specifies the device for exporting: GPU (`device=0`), CPU (`device=cpu`), MPS for Apple silicon (`device=mps`) or DLA for NVIDIA Jetson (`device=dla:0` or `device=dla:1`). | diff --git a/ultralytics/__init__.py b/ultralytics/__init__.py index 09e2fde550..ac22fe8620 100644 --- a/ultralytics/__init__.py +++ b/ultralytics/__init__.py @@ -1,6 +1,6 @@ # Ultralytics YOLO ๐Ÿš€, AGPL-3.0 license -__version__ = "8.3.20" +__version__ = "8.3.21" import os diff --git a/ultralytics/engine/exporter.py b/ultralytics/engine/exporter.py index b25b837fd1..da2e746cbe 100644 --- a/ultralytics/engine/exporter.py +++ b/ultralytics/engine/exporter.py @@ -194,6 +194,11 @@ class Exporter: is_tf_format = any((saved_model, pb, tflite, edgetpu, tfjs)) # Device + dla = None + if fmt == "engine" and "dla" in self.args.device: + dla = self.args.device.split(":")[-1] + assert dla in {"0", "1"}, f"Expected self.args.device='dla:0' or 'dla:1, but got {self.args.device}." + self.args.device = "0" if fmt == "engine" and self.args.device is None: LOGGER.warning("WARNING โš ๏ธ TensorRT requires GPU export, automatically assigning device=0") self.args.device = "0" @@ -309,7 +314,7 @@ class Exporter: if jit or ncnn: # TorchScript f[0], _ = self.export_torchscript() if engine: # TensorRT required before ONNX - f[1], _ = self.export_engine() + f[1], _ = self.export_engine(dla=dla) if onnx: # ONNX f[2], _ = self.export_onnx() if xml: # OpenVINO @@ -682,7 +687,7 @@ class Exporter: return f, ct_model @try_export - def export_engine(self, prefix=colorstr("TensorRT:")): + def export_engine(self, dla=None, prefix=colorstr("TensorRT:")): """YOLO TensorRT export https://developer.nvidia.com/tensorrt.""" assert self.im.device.type != "cpu", "export running on CPU but must be on GPU, i.e. use 'device=0'" f_onnx, _ = self.export_onnx() # run before TRT import https://github.com/ultralytics/ultralytics/issues/7016 @@ -717,6 +722,20 @@ class Exporter: network = builder.create_network(flag) half = builder.platform_has_fast_fp16 and self.args.half int8 = builder.platform_has_fast_int8 and self.args.int8 + + # Optionally switch to DLA if enabled + if dla is not None: + if not IS_JETSON: + raise ValueError("DLA is only available on NVIDIA Jetson devices") + LOGGER.info(f"{prefix} enabling DLA on core {dla}...") + if not self.args.half and not self.args.int8: + raise ValueError( + "DLA requires either 'half=True' (FP16) or 'int8=True' (INT8) to be enabled. Please enable one of them and try again." + ) + config.default_device_type = trt.DeviceType.DLA + config.DLA_core = int(dla) + config.set_flag(trt.BuilderFlag.GPU_FALLBACK) + # Read ONNX file parser = trt.OnnxParser(network, logger) if not parser.parse_from_file(f_onnx): From be40a45ec32d9173ff42b4bdb00dbfe5a8c7a838 Mon Sep 17 00:00:00 2001 From: Laughing <61612323+Laughing-q@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:58:10 +0800 Subject: [PATCH 40/40] Fix DLA export when device=None (#17128) Co-authored-by: UltralyticsAssistant --- ultralytics/engine/exporter.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ultralytics/engine/exporter.py b/ultralytics/engine/exporter.py index da2e746cbe..6d403a2afb 100644 --- a/ultralytics/engine/exporter.py +++ b/ultralytics/engine/exporter.py @@ -195,13 +195,12 @@ class Exporter: # Device dla = None - if fmt == "engine" and "dla" in self.args.device: - dla = self.args.device.split(":")[-1] - assert dla in {"0", "1"}, f"Expected self.args.device='dla:0' or 'dla:1, but got {self.args.device}." - self.args.device = "0" if fmt == "engine" and self.args.device is None: LOGGER.warning("WARNING โš ๏ธ TensorRT requires GPU export, automatically assigning device=0") self.args.device = "0" + if fmt == "engine" and "dla" in str(self.args.device): # convert int/list to str first + dla = self.args.device.split(":")[-1] + assert dla in {"0", "1"}, f"Expected self.args.device='dla:0' or 'dla:1, but got {self.args.device}." self.device = select_device("cpu" if self.args.device is None else self.args.device) # Checks