dgenerate-ultralytics-headless 8.3.153__py3-none-any.whl → 8.3.155__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/METADATA +1 -1
- {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/RECORD +48 -48
- tests/test_python.py +1 -0
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +2 -0
- ultralytics/engine/predictor.py +1 -1
- ultralytics/engine/validator.py +0 -6
- ultralytics/models/fastsam/val.py +0 -2
- ultralytics/models/rtdetr/val.py +28 -16
- ultralytics/models/yolo/classify/val.py +26 -23
- ultralytics/models/yolo/detect/train.py +4 -7
- ultralytics/models/yolo/detect/val.py +88 -90
- ultralytics/models/yolo/obb/val.py +52 -44
- ultralytics/models/yolo/pose/train.py +1 -35
- ultralytics/models/yolo/pose/val.py +77 -176
- ultralytics/models/yolo/segment/train.py +1 -41
- ultralytics/models/yolo/segment/val.py +64 -176
- ultralytics/models/yolo/yoloe/val.py +2 -1
- ultralytics/nn/autobackend.py +2 -2
- ultralytics/nn/tasks.py +0 -1
- ultralytics/solutions/ai_gym.py +5 -5
- ultralytics/solutions/analytics.py +2 -2
- ultralytics/solutions/config.py +2 -2
- ultralytics/solutions/distance_calculation.py +1 -1
- ultralytics/solutions/heatmap.py +5 -3
- ultralytics/solutions/instance_segmentation.py +4 -2
- ultralytics/solutions/object_blurrer.py +4 -2
- ultralytics/solutions/object_counter.py +5 -5
- ultralytics/solutions/object_cropper.py +3 -2
- ultralytics/solutions/parking_management.py +9 -9
- ultralytics/solutions/queue_management.py +4 -2
- ultralytics/solutions/region_counter.py +13 -5
- ultralytics/solutions/security_alarm.py +6 -4
- ultralytics/solutions/similarity_search.py +6 -6
- ultralytics/solutions/solutions.py +9 -7
- ultralytics/solutions/speed_estimation.py +3 -2
- ultralytics/solutions/streamlit_inference.py +6 -6
- ultralytics/solutions/templates/similarity-search.html +31 -0
- ultralytics/solutions/trackzone.py +4 -2
- ultralytics/solutions/vision_eye.py +4 -2
- ultralytics/utils/callbacks/comet.py +1 -1
- ultralytics/utils/metrics.py +146 -317
- ultralytics/utils/ops.py +4 -4
- ultralytics/utils/plotting.py +31 -56
- {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/WHEEL +0 -0
- {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/top_level.txt +0 -0
@@ -47,7 +47,7 @@ class ParkingPtsSelection:
|
|
47
47
|
>>> # Use the GUI to upload an image, select parking zones, and save the data
|
48
48
|
"""
|
49
49
|
|
50
|
-
def __init__(self):
|
50
|
+
def __init__(self) -> None:
|
51
51
|
"""Initialize the ParkingPtsSelection class, setting up UI and properties for parking zone point selection."""
|
52
52
|
try: # Check if tkinter is installed
|
53
53
|
import tkinter as tk
|
@@ -99,14 +99,14 @@ class ParkingPtsSelection:
|
|
99
99
|
self.initialize_properties()
|
100
100
|
self.master.mainloop()
|
101
101
|
|
102
|
-
def initialize_properties(self):
|
102
|
+
def initialize_properties(self) -> None:
|
103
103
|
"""Initialize properties for image, canvas, bounding boxes, and dimensions."""
|
104
104
|
self.image = self.canvas_image = None
|
105
105
|
self.rg_data, self.current_box = [], []
|
106
106
|
self.imgw = self.imgh = 0
|
107
107
|
self.canvas_max_width, self.canvas_max_height = 1280, 720
|
108
108
|
|
109
|
-
def upload_image(self):
|
109
|
+
def upload_image(self) -> None:
|
110
110
|
"""Upload and display an image on the canvas, resizing it to fit within specified dimensions."""
|
111
111
|
from PIL import Image, ImageTk # Scoped import because ImageTk requires tkinter package
|
112
112
|
|
@@ -132,7 +132,7 @@ class ParkingPtsSelection:
|
|
132
132
|
|
133
133
|
self.rg_data.clear(), self.current_box.clear()
|
134
134
|
|
135
|
-
def on_canvas_click(self, event):
|
135
|
+
def on_canvas_click(self, event) -> None:
|
136
136
|
"""Handle mouse clicks to add points for bounding boxes on the canvas."""
|
137
137
|
self.current_box.append((event.x, event.y))
|
138
138
|
self.canvas.create_oval(event.x - 3, event.y - 3, event.x + 3, event.y + 3, fill="red")
|
@@ -141,12 +141,12 @@ class ParkingPtsSelection:
|
|
141
141
|
self.draw_box(self.current_box)
|
142
142
|
self.current_box.clear()
|
143
143
|
|
144
|
-
def draw_box(self, box: List[Tuple[int, int]]):
|
144
|
+
def draw_box(self, box: List[Tuple[int, int]]) -> None:
|
145
145
|
"""Draw a bounding box on the canvas using the provided coordinates."""
|
146
146
|
for i in range(4):
|
147
147
|
self.canvas.create_line(box[i], box[(i + 1) % 4], fill="blue", width=2)
|
148
148
|
|
149
|
-
def remove_last_bounding_box(self):
|
149
|
+
def remove_last_bounding_box(self) -> None:
|
150
150
|
"""Remove the last bounding box from the list and redraw the canvas."""
|
151
151
|
if not self.rg_data:
|
152
152
|
self.messagebox.showwarning("Warning", "No bounding boxes to remove.")
|
@@ -154,14 +154,14 @@ class ParkingPtsSelection:
|
|
154
154
|
self.rg_data.pop()
|
155
155
|
self.redraw_canvas()
|
156
156
|
|
157
|
-
def redraw_canvas(self):
|
157
|
+
def redraw_canvas(self) -> None:
|
158
158
|
"""Redraw the canvas with the image and all bounding boxes."""
|
159
159
|
self.canvas.delete("all")
|
160
160
|
self.canvas.create_image(0, 0, anchor=self.tk.NW, image=self.canvas_image)
|
161
161
|
for box in self.rg_data:
|
162
162
|
self.draw_box(box)
|
163
163
|
|
164
|
-
def save_to_json(self):
|
164
|
+
def save_to_json(self) -> None:
|
165
165
|
"""Save the selected parking zone points to a JSON file with scaled coordinates."""
|
166
166
|
scale_w, scale_h = self.imgw / self.canvas.winfo_width(), self.imgh / self.canvas.winfo_height()
|
167
167
|
data = [{"points": [(int(x * scale_w), int(y * scale_h)) for x, y in box]} for box in self.rg_data]
|
@@ -200,7 +200,7 @@ class ParkingManagement(BaseSolution):
|
|
200
200
|
>>> print(f"Available spaces: {parking_manager.pr_info['Available']}")
|
201
201
|
"""
|
202
202
|
|
203
|
-
def __init__(self, **kwargs: Any):
|
203
|
+
def __init__(self, **kwargs: Any) -> None:
|
204
204
|
"""Initialize the parking management system with a YOLO model and visualization settings."""
|
205
205
|
super().__init__(**kwargs)
|
206
206
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from typing import Any
|
4
|
+
|
3
5
|
from ultralytics.solutions.solutions import BaseSolution, SolutionAnnotator, SolutionResults
|
4
6
|
from ultralytics.utils.plotting import colors
|
5
7
|
|
@@ -35,7 +37,7 @@ class QueueManager(BaseSolution):
|
|
35
37
|
>>> results = queue_manager.process(im0)
|
36
38
|
"""
|
37
39
|
|
38
|
-
def __init__(self, **kwargs):
|
40
|
+
def __init__(self, **kwargs: Any) -> None:
|
39
41
|
"""Initialize the QueueManager with parameters for tracking and counting objects in a video stream."""
|
40
42
|
super().__init__(**kwargs)
|
41
43
|
self.initialize_region()
|
@@ -43,7 +45,7 @@ class QueueManager(BaseSolution):
|
|
43
45
|
self.rect_color = (255, 255, 255) # Rectangle color for visualization
|
44
46
|
self.region_length = len(self.region) # Store region length for further usage
|
45
47
|
|
46
|
-
def process(self, im0):
|
48
|
+
def process(self, im0) -> SolutionResults:
|
47
49
|
"""
|
48
50
|
Process queue management for a single frame of video.
|
49
51
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from typing import Any, List, Tuple
|
4
|
+
|
3
5
|
import numpy as np
|
4
6
|
|
5
7
|
from ultralytics.solutions.solutions import BaseSolution, SolutionAnnotator, SolutionResults
|
@@ -33,7 +35,7 @@ class RegionCounter(BaseSolution):
|
|
33
35
|
>>> print(f"Total tracks: {results.total_tracks}")
|
34
36
|
"""
|
35
37
|
|
36
|
-
def __init__(self, **kwargs):
|
38
|
+
def __init__(self, **kwargs: Any) -> None:
|
37
39
|
"""Initialize the RegionCounter for real-time object counting in user-defined regions."""
|
38
40
|
super().__init__(**kwargs)
|
39
41
|
self.region_template = {
|
@@ -47,15 +49,21 @@ class RegionCounter(BaseSolution):
|
|
47
49
|
self.region_counts = {}
|
48
50
|
self.counting_regions = []
|
49
51
|
|
50
|
-
def add_region(
|
52
|
+
def add_region(
|
53
|
+
self,
|
54
|
+
name: str,
|
55
|
+
polygon_points: List[Tuple],
|
56
|
+
region_color: Tuple[int, int, int],
|
57
|
+
text_color: Tuple[int, int, int],
|
58
|
+
) -> None:
|
51
59
|
"""
|
52
60
|
Add a new region to the counting list based on the provided template with specific attributes.
|
53
61
|
|
54
62
|
Args:
|
55
63
|
name (str): Name assigned to the new region.
|
56
64
|
polygon_points (List[Tuple]): List of (x, y) coordinates defining the region's polygon.
|
57
|
-
region_color (
|
58
|
-
text_color (
|
65
|
+
region_color (Tuple[int, int, int]): BGR color for region visualization.
|
66
|
+
text_color (Tuple[int, int, int]): BGR color for the text within the region.
|
59
67
|
"""
|
60
68
|
region = self.region_template.copy()
|
61
69
|
region.update(
|
@@ -68,7 +76,7 @@ class RegionCounter(BaseSolution):
|
|
68
76
|
)
|
69
77
|
self.counting_regions.append(region)
|
70
78
|
|
71
|
-
def process(self, im0):
|
79
|
+
def process(self, im0: np.ndarray) -> SolutionResults:
|
72
80
|
"""
|
73
81
|
Process the input frame to detect and count objects within each defined region.
|
74
82
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from typing import Any
|
4
|
+
|
3
5
|
from ultralytics.solutions.solutions import BaseSolution, SolutionAnnotator, SolutionResults
|
4
6
|
from ultralytics.utils import LOGGER
|
5
7
|
from ultralytics.utils.plotting import colors
|
@@ -32,7 +34,7 @@ class SecurityAlarm(BaseSolution):
|
|
32
34
|
>>> results = security.process(frame)
|
33
35
|
"""
|
34
36
|
|
35
|
-
def __init__(self, **kwargs):
|
37
|
+
def __init__(self, **kwargs: Any) -> None:
|
36
38
|
"""
|
37
39
|
Initialize the SecurityAlarm class with parameters for real-time object monitoring.
|
38
40
|
|
@@ -46,7 +48,7 @@ class SecurityAlarm(BaseSolution):
|
|
46
48
|
self.to_email = ""
|
47
49
|
self.from_email = ""
|
48
50
|
|
49
|
-
def authenticate(self, from_email: str, password: str, to_email: str):
|
51
|
+
def authenticate(self, from_email: str, password: str, to_email: str) -> None:
|
50
52
|
"""
|
51
53
|
Authenticate the email server for sending alert notifications.
|
52
54
|
|
@@ -69,7 +71,7 @@ class SecurityAlarm(BaseSolution):
|
|
69
71
|
self.to_email = to_email
|
70
72
|
self.from_email = from_email
|
71
73
|
|
72
|
-
def send_email(self, im0, records: int = 5):
|
74
|
+
def send_email(self, im0, records: int = 5) -> None:
|
73
75
|
"""
|
74
76
|
Send an email notification with an image attachment indicating the number of objects detected.
|
75
77
|
|
@@ -114,7 +116,7 @@ class SecurityAlarm(BaseSolution):
|
|
114
116
|
except Exception as e:
|
115
117
|
LOGGER.error(f"Failed to send email: {e}")
|
116
118
|
|
117
|
-
def process(self, im0):
|
119
|
+
def process(self, im0) -> SolutionResults:
|
118
120
|
"""
|
119
121
|
Monitor the frame, process object detections, and trigger alerts if thresholds are exceeded.
|
120
122
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
import os
|
4
4
|
from pathlib import Path
|
5
|
-
from typing import List
|
5
|
+
from typing import Any, List
|
6
6
|
|
7
7
|
import numpy as np
|
8
8
|
import torch
|
@@ -48,7 +48,7 @@ class VisualAISearch(BaseSolution):
|
|
48
48
|
>>> results = searcher.search("a cat sitting on a chair", k=10)
|
49
49
|
"""
|
50
50
|
|
51
|
-
def __init__(self, **kwargs):
|
51
|
+
def __init__(self, **kwargs: Any) -> None:
|
52
52
|
"""Initialize the VisualAISearch class with FAISS index and CLIP model."""
|
53
53
|
super().__init__(**kwargs)
|
54
54
|
check_requirements(["git+https://github.com/ultralytics/CLIP.git", "faiss-cpu"])
|
@@ -90,7 +90,7 @@ class VisualAISearch(BaseSolution):
|
|
90
90
|
with torch.no_grad():
|
91
91
|
return self.model.encode_text(tokens).cpu().numpy()
|
92
92
|
|
93
|
-
def load_or_build_index(self):
|
93
|
+
def load_or_build_index(self) -> None:
|
94
94
|
"""
|
95
95
|
Load existing FAISS index or build a new one from image features.
|
96
96
|
|
@@ -195,7 +195,7 @@ class SearchApp:
|
|
195
195
|
>>> app.run(debug=True)
|
196
196
|
"""
|
197
197
|
|
198
|
-
def __init__(self, data: str = "images", device: str = None):
|
198
|
+
def __init__(self, data: str = "images", device: str = None) -> None:
|
199
199
|
"""
|
200
200
|
Initialize the SearchApp with VisualAISearch backend.
|
201
201
|
|
@@ -217,7 +217,7 @@ class SearchApp:
|
|
217
217
|
)
|
218
218
|
self.app.add_url_rule("/", view_func=self.index, methods=["GET", "POST"])
|
219
219
|
|
220
|
-
def index(self):
|
220
|
+
def index(self) -> str:
|
221
221
|
"""Process user query and display search results in the web interface."""
|
222
222
|
results = []
|
223
223
|
if self.request.method == "POST":
|
@@ -225,6 +225,6 @@ class SearchApp:
|
|
225
225
|
results = self.searcher(query)
|
226
226
|
return self.render_template("similarity-search.html", results=results)
|
227
227
|
|
228
|
-
def run(self, debug: bool = False):
|
228
|
+
def run(self, debug: bool = False) -> None:
|
229
229
|
"""Start the Flask web application server."""
|
230
230
|
self.app.run(debug=debug)
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
import math
|
4
4
|
from collections import defaultdict
|
5
|
+
from functools import lru_cache
|
5
6
|
from typing import Any, Dict, List, Optional, Tuple
|
6
7
|
|
7
8
|
import cv2
|
@@ -69,7 +70,7 @@ class BaseSolution:
|
|
69
70
|
>>> solution.display_output(image)
|
70
71
|
"""
|
71
72
|
|
72
|
-
def __init__(self, is_cli: bool = False, **kwargs):
|
73
|
+
def __init__(self, is_cli: bool = False, **kwargs: Any) -> None:
|
73
74
|
"""
|
74
75
|
Initialize the BaseSolution class with configuration settings and YOLO model.
|
75
76
|
|
@@ -154,7 +155,7 @@ class BaseSolution:
|
|
154
155
|
name = ("" if track_id is None else f"{track_id} ") + self.names[cls]
|
155
156
|
return (f"{name} {conf:.2f}" if self.show_conf else name) if self.show_labels else None
|
156
157
|
|
157
|
-
def extract_tracks(self, im0: np.ndarray):
|
158
|
+
def extract_tracks(self, im0: np.ndarray) -> None:
|
158
159
|
"""
|
159
160
|
Apply object tracking and extract tracks from an input image or frame.
|
160
161
|
|
@@ -182,7 +183,7 @@ class BaseSolution:
|
|
182
183
|
self.LOGGER.warning("no tracks found!")
|
183
184
|
self.boxes, self.clss, self.track_ids, self.confs = [], [], [], []
|
184
185
|
|
185
|
-
def store_tracking_history(self, track_id: int, box):
|
186
|
+
def store_tracking_history(self, track_id: int, box) -> None:
|
186
187
|
"""
|
187
188
|
Store the tracking history of an object.
|
188
189
|
|
@@ -203,7 +204,7 @@ class BaseSolution:
|
|
203
204
|
if len(self.track_line) > 30:
|
204
205
|
self.track_line.pop(0)
|
205
206
|
|
206
|
-
def initialize_region(self):
|
207
|
+
def initialize_region(self) -> None:
|
207
208
|
"""Initialize the counting region and line segment based on configuration settings."""
|
208
209
|
if self.region is None:
|
209
210
|
self.region = [(10, 200), (540, 200), (540, 180), (10, 180)]
|
@@ -211,7 +212,7 @@ class BaseSolution:
|
|
211
212
|
self.Polygon(self.region) if len(self.region) >= 3 else self.LineString(self.region)
|
212
213
|
) # region or line
|
213
214
|
|
214
|
-
def display_output(self, plot_im: np.ndarray):
|
215
|
+
def display_output(self, plot_im: np.ndarray) -> None:
|
215
216
|
"""
|
216
217
|
Display the results of the processing, which could involve showing frames, printing counts, or saving results.
|
217
218
|
|
@@ -237,10 +238,10 @@ class BaseSolution:
|
|
237
238
|
cv2.destroyAllWindows() # Closes current frame window
|
238
239
|
return
|
239
240
|
|
240
|
-
def process(self, *args, **kwargs):
|
241
|
+
def process(self, *args: Any, **kwargs: Any):
|
241
242
|
"""Process method should be implemented by each Solution subclass."""
|
242
243
|
|
243
|
-
def __call__(self, *args, **kwargs):
|
244
|
+
def __call__(self, *args: Any, **kwargs: Any):
|
244
245
|
"""Allow instances to be called like a function with flexible arguments."""
|
245
246
|
with self.profilers[1]:
|
246
247
|
result = self.process(*args, **kwargs) # Call the subclass-specific process method
|
@@ -423,6 +424,7 @@ class SolutionAnnotator(Annotator):
|
|
423
424
|
text_y_offset = rect_y2
|
424
425
|
|
425
426
|
@staticmethod
|
427
|
+
@lru_cache(maxsize=256)
|
426
428
|
def estimate_pose_angle(a: List[float], b: List[float], c: List[float]) -> float:
|
427
429
|
"""
|
428
430
|
Calculate the angle between three points for workout monitoring.
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
from collections import deque
|
4
4
|
from math import sqrt
|
5
|
+
from typing import Any
|
5
6
|
|
6
7
|
from ultralytics.solutions.solutions import BaseSolution, SolutionAnnotator, SolutionResults
|
7
8
|
from ultralytics.utils.plotting import colors
|
@@ -40,7 +41,7 @@ class SpeedEstimator(BaseSolution):
|
|
40
41
|
>>> cv2.imshow("Speed Estimation", results.plot_im)
|
41
42
|
"""
|
42
43
|
|
43
|
-
def __init__(self, **kwargs):
|
44
|
+
def __init__(self, **kwargs: Any) -> None:
|
44
45
|
"""
|
45
46
|
Initialize the SpeedEstimator object with speed estimation parameters and data structures.
|
46
47
|
|
@@ -59,7 +60,7 @@ class SpeedEstimator(BaseSolution):
|
|
59
60
|
self.meter_per_pixel = self.CFG["meter_per_pixel"] # Scene scale, depends on camera details
|
60
61
|
self.max_speed = self.CFG["max_speed"] # Maximum speed adjustment
|
61
62
|
|
62
|
-
def process(self, im0):
|
63
|
+
def process(self, im0) -> SolutionResults:
|
63
64
|
"""
|
64
65
|
Process an input frame to estimate object speeds based on tracking data.
|
65
66
|
|
@@ -49,7 +49,7 @@ class Inference:
|
|
49
49
|
>>> inf.inference()
|
50
50
|
"""
|
51
51
|
|
52
|
-
def __init__(self, **kwargs: Any):
|
52
|
+
def __init__(self, **kwargs: Any) -> None:
|
53
53
|
"""
|
54
54
|
Initialize the Inference class, checking Streamlit requirements and setting up the model path.
|
55
55
|
|
@@ -77,7 +77,7 @@ class Inference:
|
|
77
77
|
|
78
78
|
LOGGER.info(f"Ultralytics Solutions: ✅ {self.temp_dict}")
|
79
79
|
|
80
|
-
def web_ui(self):
|
80
|
+
def web_ui(self) -> None:
|
81
81
|
"""Set up the Streamlit web interface with custom HTML elements."""
|
82
82
|
menu_style_cfg = """<style>MainMenu {visibility: hidden;}</style>""" # Hide main menu style
|
83
83
|
|
@@ -96,7 +96,7 @@ class Inference:
|
|
96
96
|
self.st.markdown(main_title_cfg, unsafe_allow_html=True)
|
97
97
|
self.st.markdown(sub_title_cfg, unsafe_allow_html=True)
|
98
98
|
|
99
|
-
def sidebar(self):
|
99
|
+
def sidebar(self) -> None:
|
100
100
|
"""Configure the Streamlit sidebar for model and inference settings."""
|
101
101
|
with self.st.sidebar: # Add Ultralytics LOGO
|
102
102
|
logo = "https://raw.githubusercontent.com/ultralytics/assets/main/logo/Ultralytics_Logotype_Original.svg"
|
@@ -117,7 +117,7 @@ class Inference:
|
|
117
117
|
self.org_frame = col1.empty() # Container for original frame
|
118
118
|
self.ann_frame = col2.empty() # Container for annotated frame
|
119
119
|
|
120
|
-
def source_upload(self):
|
120
|
+
def source_upload(self) -> None:
|
121
121
|
"""Handle video file uploads through the Streamlit interface."""
|
122
122
|
self.vid_file_name = ""
|
123
123
|
if self.source == "video":
|
@@ -130,7 +130,7 @@ class Inference:
|
|
130
130
|
elif self.source == "webcam":
|
131
131
|
self.vid_file_name = 0 # Use webcam index 0
|
132
132
|
|
133
|
-
def configure(self):
|
133
|
+
def configure(self) -> None:
|
134
134
|
"""Configure the model and load selected classes for inference."""
|
135
135
|
# Add dropdown menu for model selection
|
136
136
|
available_models = [x.replace("yolo", "YOLO") for x in GITHUB_ASSETS_STEMS if x.startswith("yolo11")]
|
@@ -150,7 +150,7 @@ class Inference:
|
|
150
150
|
if not isinstance(self.selected_ind, list): # Ensure selected_options is a list
|
151
151
|
self.selected_ind = list(self.selected_ind)
|
152
152
|
|
153
|
-
def inference(self):
|
153
|
+
def inference(self) -> None:
|
154
154
|
"""Perform real-time object detection inference on video or webcam feed."""
|
155
155
|
self.web_ui() # Initialize the web interface
|
156
156
|
self.sidebar() # Create the sidebar
|
@@ -126,6 +126,20 @@
|
|
126
126
|
}
|
127
127
|
</style>
|
128
128
|
</head>
|
129
|
+
<script>
|
130
|
+
function filterResults(k) {
|
131
|
+
const cards = document.querySelectorAll(".grid .card");
|
132
|
+
cards.forEach((card, idx) => {
|
133
|
+
card.style.display = idx < k ? "block" : "none";
|
134
|
+
});
|
135
|
+
const buttons = document.querySelectorAll(".topk-btn");
|
136
|
+
buttons.forEach((btn) => btn.classList.remove("active"));
|
137
|
+
event.target.classList.add("active");
|
138
|
+
}
|
139
|
+
document.addEventListener("DOMContentLoaded", () => {
|
140
|
+
filterResults(10);
|
141
|
+
});
|
142
|
+
</script>
|
129
143
|
<body>
|
130
144
|
<div style="text-align: center; margin-bottom: 1rem">
|
131
145
|
<img
|
@@ -146,6 +160,23 @@
|
|
146
160
|
required
|
147
161
|
/>
|
148
162
|
<button type="submit">Search</button>
|
163
|
+
{% if results %}
|
164
|
+
<div class="top-k-buttons">
|
165
|
+
<button type="button" class="topk-btn" onclick="filterResults(5)">
|
166
|
+
Top 5
|
167
|
+
</button>
|
168
|
+
<button
|
169
|
+
type="button"
|
170
|
+
class="topk-btn active"
|
171
|
+
onclick="filterResults(10)"
|
172
|
+
>
|
173
|
+
Top 10
|
174
|
+
</button>
|
175
|
+
<button type="button" class="topk-btn" onclick="filterResults(30)">
|
176
|
+
Top 30
|
177
|
+
</button>
|
178
|
+
</div>
|
179
|
+
{% endif %}
|
149
180
|
</form>
|
150
181
|
|
151
182
|
<!-- Search results grid -->
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from typing import Any
|
4
|
+
|
3
5
|
import cv2
|
4
6
|
import numpy as np
|
5
7
|
|
@@ -34,7 +36,7 @@ class TrackZone(BaseSolution):
|
|
34
36
|
>>> cv2.imshow("Tracked Frame", results.plot_im)
|
35
37
|
"""
|
36
38
|
|
37
|
-
def __init__(self, **kwargs):
|
39
|
+
def __init__(self, **kwargs: Any) -> None:
|
38
40
|
"""
|
39
41
|
Initialize the TrackZone class for tracking objects within a defined region in video streams.
|
40
42
|
|
@@ -46,7 +48,7 @@ class TrackZone(BaseSolution):
|
|
46
48
|
self.region = cv2.convexHull(np.array(self.region or default_region, dtype=np.int32))
|
47
49
|
self.mask = None
|
48
50
|
|
49
|
-
def process(self, im0):
|
51
|
+
def process(self, im0: np.ndarray) -> SolutionResults:
|
50
52
|
"""
|
51
53
|
Process the input frame to track objects within a defined region.
|
52
54
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
2
2
|
|
3
|
+
from typing import Any
|
4
|
+
|
3
5
|
from ultralytics.solutions.solutions import BaseSolution, SolutionAnnotator, SolutionResults
|
4
6
|
from ultralytics.utils.plotting import colors
|
5
7
|
|
@@ -24,7 +26,7 @@ class VisionEye(BaseSolution):
|
|
24
26
|
>>> print(f"Total detected instances: {results.total_tracks}")
|
25
27
|
"""
|
26
28
|
|
27
|
-
def __init__(self, **kwargs):
|
29
|
+
def __init__(self, **kwargs: Any) -> None:
|
28
30
|
"""
|
29
31
|
Initialize the VisionEye class for detecting objects and applying vision mapping.
|
30
32
|
|
@@ -35,7 +37,7 @@ class VisionEye(BaseSolution):
|
|
35
37
|
# Set the vision point where the system will view objects and draw tracks
|
36
38
|
self.vision_point = self.CFG["vision_point"]
|
37
39
|
|
38
|
-
def process(self, im0):
|
40
|
+
def process(self, im0) -> SolutionResults:
|
39
41
|
"""
|
40
42
|
Perform object detection, vision mapping, and annotation on the input image.
|
41
43
|
|
@@ -457,7 +457,7 @@ def _log_plots(experiment, trainer) -> None:
|
|
457
457
|
>>> _log_plots(experiment, trainer)
|
458
458
|
"""
|
459
459
|
plot_filenames = None
|
460
|
-
if isinstance(trainer.validator.metrics, SegmentMetrics)
|
460
|
+
if isinstance(trainer.validator.metrics, SegmentMetrics):
|
461
461
|
plot_filenames = [
|
462
462
|
trainer.save_dir / f"{prefix}{plots}.png"
|
463
463
|
for plots in EVALUATION_PLOT_NAMES
|