ultralytics 8.2.16__py3-none-any.whl → 8.2.18__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ultralytics might be problematic. Click here for more details.
- ultralytics/__init__.py +1 -1
- ultralytics/engine/results.py +6 -4
- ultralytics/solutions/__init__.py +18 -0
- ultralytics/solutions/ai_gym.py +53 -79
- ultralytics/solutions/distance_calculation.py +66 -71
- ultralytics/solutions/heatmap.py +95 -133
- ultralytics/solutions/object_counter.py +62 -82
- ultralytics/solutions/parking_management.py +22 -9
- ultralytics/solutions/queue_management.py +63 -82
- ultralytics/solutions/speed_estimation.py +50 -68
- ultralytics/utils/__init__.py +1 -1
- ultralytics/utils/callbacks/wb.py +1 -1
- ultralytics/utils/checks.py +3 -2
- ultralytics/utils/plotting.py +40 -42
- {ultralytics-8.2.16.dist-info → ultralytics-8.2.18.dist-info}/METADATA +1 -1
- {ultralytics-8.2.16.dist-info → ultralytics-8.2.18.dist-info}/RECORD +20 -20
- {ultralytics-8.2.16.dist-info → ultralytics-8.2.18.dist-info}/LICENSE +0 -0
- {ultralytics-8.2.16.dist-info → ultralytics-8.2.18.dist-info}/WHEEL +0 -0
- {ultralytics-8.2.16.dist-info → ultralytics-8.2.18.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.2.16.dist-info → ultralytics-8.2.18.dist-info}/top_level.txt +0 -0
|
@@ -13,49 +13,12 @@ from shapely.geometry import Point, Polygon
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class QueueManager:
|
|
16
|
-
"""A class to manage the queue
|
|
16
|
+
"""A class to manage the queue in a real-time video stream based on object tracks."""
|
|
17
17
|
|
|
18
|
-
def __init__(
|
|
19
|
-
"""Initializes the queue manager with default values for various tracking and counting parameters."""
|
|
20
|
-
|
|
21
|
-
# Mouse events
|
|
22
|
-
self.is_drawing = False
|
|
23
|
-
self.selected_point = None
|
|
24
|
-
|
|
25
|
-
# Region & Line Information
|
|
26
|
-
self.reg_pts = [(20, 60), (20, 680), (1120, 680), (1120, 60)]
|
|
27
|
-
self.counting_region = None
|
|
28
|
-
self.region_color = (255, 0, 255)
|
|
29
|
-
self.region_thickness = 5
|
|
30
|
-
|
|
31
|
-
# Image and annotation Information
|
|
32
|
-
self.im0 = None
|
|
33
|
-
self.tf = None
|
|
34
|
-
self.view_img = False
|
|
35
|
-
self.view_queue_counts = True
|
|
36
|
-
self.fontsize = 0.6
|
|
37
|
-
|
|
38
|
-
self.names = None # Classes names
|
|
39
|
-
self.annotator = None # Annotator
|
|
40
|
-
self.window_name = "Ultralytics YOLOv8 Queue Manager"
|
|
41
|
-
|
|
42
|
-
# Object counting Information
|
|
43
|
-
self.counts = 0
|
|
44
|
-
self.count_txt_color = (255, 255, 255)
|
|
45
|
-
|
|
46
|
-
# Tracks info
|
|
47
|
-
self.track_history = defaultdict(list)
|
|
48
|
-
self.track_thickness = 2
|
|
49
|
-
self.draw_tracks = False
|
|
50
|
-
self.track_color = None
|
|
51
|
-
|
|
52
|
-
# Check if environment support imshow
|
|
53
|
-
self.env_check = check_imshow(warn=True)
|
|
54
|
-
|
|
55
|
-
def set_args(
|
|
18
|
+
def __init__(
|
|
56
19
|
self,
|
|
57
20
|
classes_names,
|
|
58
|
-
reg_pts,
|
|
21
|
+
reg_pts=None,
|
|
59
22
|
line_thickness=2,
|
|
60
23
|
track_thickness=2,
|
|
61
24
|
view_img=False,
|
|
@@ -68,48 +31,65 @@ class QueueManager:
|
|
|
68
31
|
fontsize=0.7,
|
|
69
32
|
):
|
|
70
33
|
"""
|
|
71
|
-
|
|
34
|
+
Initializes the QueueManager with specified parameters for tracking and counting objects.
|
|
72
35
|
|
|
73
36
|
Args:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
37
|
+
classes_names (dict): A dictionary mapping class IDs to class names.
|
|
38
|
+
reg_pts (list of tuples, optional): Points defining the counting region polygon. Defaults to a predefined
|
|
39
|
+
rectangle.
|
|
40
|
+
line_thickness (int, optional): Thickness of the annotation lines. Defaults to 2.
|
|
41
|
+
track_thickness (int, optional): Thickness of the track lines. Defaults to 2.
|
|
42
|
+
view_img (bool, optional): Whether to display the image frames. Defaults to False.
|
|
43
|
+
region_color (tuple, optional): Color of the counting region lines (BGR). Defaults to (255, 0, 255).
|
|
44
|
+
view_queue_counts (bool, optional): Whether to display the queue counts. Defaults to True.
|
|
45
|
+
draw_tracks (bool, optional): Whether to draw tracks of the objects. Defaults to False.
|
|
46
|
+
count_txt_color (tuple, optional): Color of the count text (BGR). Defaults to (255, 255, 255).
|
|
47
|
+
track_color (tuple, optional): Color of the tracks. If None, different colors will be used for different
|
|
48
|
+
tracks. Defaults to None.
|
|
49
|
+
region_thickness (int, optional): Thickness of the counting region lines. Defaults to 5.
|
|
50
|
+
fontsize (float, optional): Font size for the text annotations. Defaults to 0.7.
|
|
86
51
|
"""
|
|
52
|
+
|
|
53
|
+
# Mouse events state
|
|
54
|
+
self.is_drawing = False
|
|
55
|
+
self.selected_point = None
|
|
56
|
+
|
|
57
|
+
# Region & Line Information
|
|
58
|
+
self.reg_pts = reg_pts if reg_pts is not None else [(20, 60), (20, 680), (1120, 680), (1120, 60)]
|
|
59
|
+
self.counting_region = (
|
|
60
|
+
Polygon(self.reg_pts) if len(self.reg_pts) >= 3 else Polygon([(20, 60), (20, 680), (1120, 680), (1120, 60)])
|
|
61
|
+
)
|
|
62
|
+
self.region_color = region_color
|
|
63
|
+
self.region_thickness = region_thickness
|
|
64
|
+
|
|
65
|
+
# Image and annotation Information
|
|
66
|
+
self.im0 = None
|
|
87
67
|
self.tf = line_thickness
|
|
88
68
|
self.view_img = view_img
|
|
89
69
|
self.view_queue_counts = view_queue_counts
|
|
90
|
-
self.
|
|
91
|
-
self.draw_tracks = draw_tracks
|
|
92
|
-
self.region_color = region_color
|
|
70
|
+
self.fontsize = fontsize
|
|
93
71
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
self.counting_region = Polygon(self.reg_pts)
|
|
98
|
-
else:
|
|
99
|
-
print("Invalid region points provided...")
|
|
100
|
-
print("Using default region now....")
|
|
101
|
-
self.counting_region = Polygon(self.reg_pts)
|
|
72
|
+
self.names = classes_names # Class names
|
|
73
|
+
self.annotator = None # Annotator
|
|
74
|
+
self.window_name = "Ultralytics YOLOv8 Queue Manager"
|
|
102
75
|
|
|
103
|
-
|
|
104
|
-
self.
|
|
76
|
+
# Object counting Information
|
|
77
|
+
self.counts = 0
|
|
105
78
|
self.count_txt_color = count_txt_color
|
|
106
|
-
|
|
107
|
-
|
|
79
|
+
|
|
80
|
+
# Tracks info
|
|
81
|
+
self.track_history = defaultdict(list)
|
|
82
|
+
self.track_thickness = track_thickness
|
|
83
|
+
self.draw_tracks = draw_tracks
|
|
84
|
+
self.track_color = track_color
|
|
85
|
+
|
|
86
|
+
# Check if environment supports imshow
|
|
87
|
+
self.env_check = check_imshow(warn=True)
|
|
108
88
|
|
|
109
89
|
def extract_and_process_tracks(self, tracks):
|
|
110
90
|
"""Extracts and processes tracks for queue management in a video stream."""
|
|
111
91
|
|
|
112
|
-
#
|
|
92
|
+
# Initialize annotator and draw the queue region
|
|
113
93
|
self.annotator = Annotator(self.im0, self.tf, self.names)
|
|
114
94
|
|
|
115
95
|
if tracks[0].boxes.id is not None:
|
|
@@ -122,48 +102,48 @@ class QueueManager:
|
|
|
122
102
|
# Draw bounding box
|
|
123
103
|
self.annotator.box_label(box, label=f"{self.names[cls]}#{track_id}", color=colors(int(track_id), True))
|
|
124
104
|
|
|
125
|
-
#
|
|
105
|
+
# Update track history
|
|
126
106
|
track_line = self.track_history[track_id]
|
|
127
107
|
track_line.append((float((box[0] + box[2]) / 2), float((box[1] + box[3]) / 2)))
|
|
128
108
|
if len(track_line) > 30:
|
|
129
109
|
track_line.pop(0)
|
|
130
110
|
|
|
131
|
-
# Draw track trails
|
|
111
|
+
# Draw track trails if enabled
|
|
132
112
|
if self.draw_tracks:
|
|
133
113
|
self.annotator.draw_centroid_and_tracks(
|
|
134
114
|
track_line,
|
|
135
|
-
color=self.track_color
|
|
115
|
+
color=self.track_color or colors(int(track_id), True),
|
|
136
116
|
track_thickness=self.track_thickness,
|
|
137
117
|
)
|
|
138
118
|
|
|
139
119
|
prev_position = self.track_history[track_id][-2] if len(self.track_history[track_id]) > 1 else None
|
|
140
120
|
|
|
121
|
+
# Check if the object is inside the counting region
|
|
141
122
|
if len(self.reg_pts) >= 3:
|
|
142
123
|
is_inside = self.counting_region.contains(Point(track_line[-1]))
|
|
143
124
|
if prev_position is not None and is_inside:
|
|
144
125
|
self.counts += 1
|
|
145
126
|
|
|
146
|
-
|
|
147
|
-
|
|
127
|
+
# Display queue counts
|
|
128
|
+
label = f"Queue Counts : {str(self.counts)}"
|
|
148
129
|
if label is not None:
|
|
149
130
|
self.annotator.queue_counts_display(
|
|
150
131
|
label,
|
|
151
132
|
points=self.reg_pts,
|
|
152
133
|
region_color=self.region_color,
|
|
153
134
|
txt_color=self.count_txt_color,
|
|
154
|
-
fontsize=self.fontsize,
|
|
155
135
|
)
|
|
156
136
|
|
|
157
|
-
self.counts = 0
|
|
137
|
+
self.counts = 0 # Reset counts after displaying
|
|
158
138
|
self.display_frames()
|
|
159
139
|
|
|
160
140
|
def display_frames(self):
|
|
161
|
-
"""
|
|
141
|
+
"""Displays the current frame with annotations."""
|
|
162
142
|
if self.env_check:
|
|
163
143
|
self.annotator.draw_region(reg_pts=self.reg_pts, thickness=self.region_thickness, color=self.region_color)
|
|
164
144
|
cv2.namedWindow(self.window_name)
|
|
165
145
|
cv2.imshow(self.window_name, self.im0)
|
|
166
|
-
#
|
|
146
|
+
# Close window on 'q' key press
|
|
167
147
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
|
168
148
|
return
|
|
169
149
|
|
|
@@ -175,13 +155,14 @@ class QueueManager:
|
|
|
175
155
|
im0 (ndarray): Current frame from the video stream.
|
|
176
156
|
tracks (list): List of tracks obtained from the object tracking process.
|
|
177
157
|
"""
|
|
178
|
-
self.im0 = im0 #
|
|
179
|
-
self.extract_and_process_tracks(tracks) #
|
|
158
|
+
self.im0 = im0 # Store the current frame
|
|
159
|
+
self.extract_and_process_tracks(tracks) # Extract and process tracks
|
|
180
160
|
|
|
181
161
|
if self.view_img:
|
|
182
|
-
self.display_frames()
|
|
162
|
+
self.display_frames() # Display the frame if enabled
|
|
183
163
|
return self.im0
|
|
184
164
|
|
|
185
165
|
|
|
186
166
|
if __name__ == "__main__":
|
|
187
|
-
|
|
167
|
+
classes_names = {0: "person", 1: "car"} # example class names
|
|
168
|
+
queue_manager = QueueManager(classes_names)
|
|
@@ -11,73 +11,52 @@ from ultralytics.utils.plotting import Annotator, colors
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class SpeedEstimator:
|
|
14
|
-
"""A class to
|
|
14
|
+
"""A class to estimate the speed of objects in a real-time video stream based on their tracks."""
|
|
15
15
|
|
|
16
|
-
def __init__(self):
|
|
17
|
-
"""
|
|
16
|
+
def __init__(self, names, reg_pts=None, view_img=False, line_thickness=2, region_thickness=5, spdl_dist_thresh=10):
|
|
17
|
+
"""
|
|
18
|
+
Initializes the SpeedEstimator with the given parameters.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
Args:
|
|
21
|
+
names (dict): Dictionary of class names.
|
|
22
|
+
reg_pts (list, optional): List of region points for speed estimation. Defaults to [(20, 400), (1260, 400)].
|
|
23
|
+
view_img (bool, optional): Whether to display the image with annotations. Defaults to False.
|
|
24
|
+
line_thickness (int, optional): Thickness of the lines for drawing boxes and tracks. Defaults to 2.
|
|
25
|
+
region_thickness (int, optional): Thickness of the region lines. Defaults to 5.
|
|
26
|
+
spdl_dist_thresh (int, optional): Distance threshold for speed calculation. Defaults to 10.
|
|
27
|
+
"""
|
|
28
|
+
# Visual & image information
|
|
20
29
|
self.im0 = None
|
|
21
30
|
self.annotator = None
|
|
22
|
-
self.view_img =
|
|
31
|
+
self.view_img = view_img
|
|
23
32
|
|
|
24
33
|
# Region information
|
|
25
|
-
self.reg_pts = [(20, 400), (1260, 400)]
|
|
26
|
-
self.region_thickness =
|
|
34
|
+
self.reg_pts = reg_pts if reg_pts is not None else [(20, 400), (1260, 400)]
|
|
35
|
+
self.region_thickness = region_thickness
|
|
27
36
|
|
|
28
|
-
#
|
|
37
|
+
# Tracking information
|
|
29
38
|
self.clss = None
|
|
30
|
-
self.names =
|
|
39
|
+
self.names = names
|
|
31
40
|
self.boxes = None
|
|
32
41
|
self.trk_ids = None
|
|
33
42
|
self.trk_pts = None
|
|
34
|
-
self.line_thickness =
|
|
43
|
+
self.line_thickness = line_thickness
|
|
35
44
|
self.trk_history = defaultdict(list)
|
|
36
45
|
|
|
37
|
-
# Speed
|
|
46
|
+
# Speed estimation information
|
|
38
47
|
self.current_time = 0
|
|
39
48
|
self.dist_data = {}
|
|
40
49
|
self.trk_idslist = []
|
|
41
|
-
self.spdl_dist_thresh =
|
|
50
|
+
self.spdl_dist_thresh = spdl_dist_thresh
|
|
42
51
|
self.trk_previous_times = {}
|
|
43
52
|
self.trk_previous_points = {}
|
|
44
53
|
|
|
45
|
-
# Check if environment
|
|
54
|
+
# Check if the environment supports imshow
|
|
46
55
|
self.env_check = check_imshow(warn=True)
|
|
47
56
|
|
|
48
|
-
def set_args(
|
|
49
|
-
self,
|
|
50
|
-
reg_pts,
|
|
51
|
-
names,
|
|
52
|
-
view_img=False,
|
|
53
|
-
line_thickness=2,
|
|
54
|
-
region_thickness=5,
|
|
55
|
-
spdl_dist_thresh=10,
|
|
56
|
-
):
|
|
57
|
-
"""
|
|
58
|
-
Configures the speed estimation and display parameters.
|
|
59
|
-
|
|
60
|
-
Args:
|
|
61
|
-
reg_pts (list): Initial list of points defining the speed calculation region.
|
|
62
|
-
names (dict): object detection classes names
|
|
63
|
-
view_img (bool): Flag indicating frame display
|
|
64
|
-
line_thickness (int): Line thickness for bounding boxes.
|
|
65
|
-
region_thickness (int): Speed estimation region thickness
|
|
66
|
-
spdl_dist_thresh (int): Euclidean distance threshold for speed line
|
|
67
|
-
"""
|
|
68
|
-
if reg_pts is None:
|
|
69
|
-
print("Region points not provided, using default values")
|
|
70
|
-
else:
|
|
71
|
-
self.reg_pts = reg_pts
|
|
72
|
-
self.names = names
|
|
73
|
-
self.view_img = view_img
|
|
74
|
-
self.line_thickness = line_thickness
|
|
75
|
-
self.region_thickness = region_thickness
|
|
76
|
-
self.spdl_dist_thresh = spdl_dist_thresh
|
|
77
|
-
|
|
78
57
|
def extract_tracks(self, tracks):
|
|
79
58
|
"""
|
|
80
|
-
Extracts results from the provided data.
|
|
59
|
+
Extracts results from the provided tracking data.
|
|
81
60
|
|
|
82
61
|
Args:
|
|
83
62
|
tracks (list): List of tracks obtained from the object tracking process.
|
|
@@ -88,11 +67,14 @@ class SpeedEstimator:
|
|
|
88
67
|
|
|
89
68
|
def store_track_info(self, track_id, box):
|
|
90
69
|
"""
|
|
91
|
-
|
|
70
|
+
Stores track data.
|
|
92
71
|
|
|
93
72
|
Args:
|
|
94
|
-
track_id (int):
|
|
95
|
-
box (list):
|
|
73
|
+
track_id (int): Object track id.
|
|
74
|
+
box (list): Object bounding box data.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
(list): Updated tracking history for the given track_id.
|
|
96
78
|
"""
|
|
97
79
|
track = self.trk_history[track_id]
|
|
98
80
|
bbox_center = (float((box[0] + box[2]) / 2), float((box[1] + box[3]) / 2))
|
|
@@ -106,43 +88,39 @@ class SpeedEstimator:
|
|
|
106
88
|
|
|
107
89
|
def plot_box_and_track(self, track_id, box, cls, track):
|
|
108
90
|
"""
|
|
109
|
-
|
|
91
|
+
Plots track and bounding box.
|
|
110
92
|
|
|
111
93
|
Args:
|
|
112
|
-
track_id (int):
|
|
113
|
-
box (list):
|
|
114
|
-
cls (str):
|
|
115
|
-
track (list):
|
|
94
|
+
track_id (int): Object track id.
|
|
95
|
+
box (list): Object bounding box data.
|
|
96
|
+
cls (str): Object class name.
|
|
97
|
+
track (list): Tracking history for drawing tracks path.
|
|
116
98
|
"""
|
|
117
|
-
speed_label = f"{int(self.dist_data[track_id])}km/
|
|
99
|
+
speed_label = f"{int(self.dist_data[track_id])} km/h" if track_id in self.dist_data else self.names[int(cls)]
|
|
118
100
|
bbox_color = colors(int(track_id)) if track_id in self.dist_data else (255, 0, 255)
|
|
119
101
|
|
|
120
102
|
self.annotator.box_label(box, speed_label, bbox_color)
|
|
121
|
-
|
|
122
103
|
cv2.polylines(self.im0, [self.trk_pts], isClosed=False, color=(0, 255, 0), thickness=1)
|
|
123
104
|
cv2.circle(self.im0, (int(track[-1][0]), int(track[-1][1])), 5, bbox_color, -1)
|
|
124
105
|
|
|
125
106
|
def calculate_speed(self, trk_id, track):
|
|
126
107
|
"""
|
|
127
|
-
|
|
108
|
+
Calculates the speed of an object.
|
|
128
109
|
|
|
129
110
|
Args:
|
|
130
|
-
trk_id (int):
|
|
131
|
-
track (list):
|
|
111
|
+
trk_id (int): Object track id.
|
|
112
|
+
track (list): Tracking history for drawing tracks path.
|
|
132
113
|
"""
|
|
133
|
-
|
|
134
114
|
if not self.reg_pts[0][0] < track[-1][0] < self.reg_pts[1][0]:
|
|
135
115
|
return
|
|
136
116
|
if self.reg_pts[1][1] - self.spdl_dist_thresh < track[-1][1] < self.reg_pts[1][1] + self.spdl_dist_thresh:
|
|
137
117
|
direction = "known"
|
|
138
|
-
|
|
139
118
|
elif self.reg_pts[0][1] - self.spdl_dist_thresh < track[-1][1] < self.reg_pts[0][1] + self.spdl_dist_thresh:
|
|
140
119
|
direction = "known"
|
|
141
|
-
|
|
142
120
|
else:
|
|
143
121
|
direction = "unknown"
|
|
144
122
|
|
|
145
|
-
if self.trk_previous_times
|
|
123
|
+
if self.trk_previous_times.get(trk_id) != 0 and direction != "unknown" and trk_id not in self.trk_idslist:
|
|
146
124
|
self.trk_idslist.append(trk_id)
|
|
147
125
|
|
|
148
126
|
time_difference = time() - self.trk_previous_times[trk_id]
|
|
@@ -156,21 +134,24 @@ class SpeedEstimator:
|
|
|
156
134
|
|
|
157
135
|
def estimate_speed(self, im0, tracks, region_color=(255, 0, 0)):
|
|
158
136
|
"""
|
|
159
|
-
|
|
137
|
+
Estimates the speed of objects based on tracking data.
|
|
160
138
|
|
|
161
139
|
Args:
|
|
162
|
-
im0 (
|
|
140
|
+
im0 (ndarray): Image.
|
|
163
141
|
tracks (list): List of tracks obtained from the object tracking process.
|
|
164
|
-
region_color (tuple): Color to use when drawing regions.
|
|
142
|
+
region_color (tuple, optional): Color to use when drawing regions. Defaults to (255, 0, 0).
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
(ndarray): The image with annotated boxes and tracks.
|
|
165
146
|
"""
|
|
166
147
|
self.im0 = im0
|
|
167
148
|
if tracks[0].boxes.id is None:
|
|
168
149
|
if self.view_img and self.env_check:
|
|
169
150
|
self.display_frames()
|
|
170
151
|
return im0
|
|
171
|
-
self.extract_tracks(tracks)
|
|
172
152
|
|
|
173
|
-
self.
|
|
153
|
+
self.extract_tracks(tracks)
|
|
154
|
+
self.annotator = Annotator(self.im0, line_width=self.line_thickness)
|
|
174
155
|
self.annotator.draw_region(reg_pts=self.reg_pts, color=region_color, thickness=self.region_thickness)
|
|
175
156
|
|
|
176
157
|
for box, trk_id, cls in zip(self.boxes, self.trk_ids, self.clss):
|
|
@@ -188,11 +169,12 @@ class SpeedEstimator:
|
|
|
188
169
|
return im0
|
|
189
170
|
|
|
190
171
|
def display_frames(self):
|
|
191
|
-
"""
|
|
172
|
+
"""Displays the current frame."""
|
|
192
173
|
cv2.imshow("Ultralytics Speed Estimation", self.im0)
|
|
193
174
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
|
194
175
|
return
|
|
195
176
|
|
|
196
177
|
|
|
197
178
|
if __name__ == "__main__":
|
|
198
|
-
|
|
179
|
+
names = {0: "person", 1: "car"} # example class names
|
|
180
|
+
speed_estimator = SpeedEstimator(names)
|
ultralytics/utils/__init__.py
CHANGED
|
@@ -515,7 +515,7 @@ def is_online() -> bool:
|
|
|
515
515
|
import socket
|
|
516
516
|
|
|
517
517
|
for dns in ("1.1.1.1", "8.8.8.8"): # check Cloudflare and Google DNS
|
|
518
|
-
socket.create_connection(address=(dns, 80), timeout=
|
|
518
|
+
socket.create_connection(address=(dns, 80), timeout=2.0).close()
|
|
519
519
|
return True
|
|
520
520
|
return False
|
|
521
521
|
|
|
@@ -100,7 +100,7 @@ def _plot_curve(
|
|
|
100
100
|
|
|
101
101
|
def _log_plots(plots, step):
|
|
102
102
|
"""Logs plots from the input dictionary if they haven't been logged already at the specified step."""
|
|
103
|
-
for name, params in plots.items():
|
|
103
|
+
for name, params in plots.copy().items(): # shallow copy to prevent plots dict changing during iteration
|
|
104
104
|
timestamp = params["timestamp"]
|
|
105
105
|
if _processed_plots.get(name) != timestamp:
|
|
106
106
|
wb.run.log({name.stem: wb.Image(str(name))}, step=step)
|
ultralytics/utils/checks.py
CHANGED
|
@@ -391,7 +391,7 @@ def check_requirements(requirements=ROOT.parent / "requirements.txt", exclude=()
|
|
|
391
391
|
t = time.time()
|
|
392
392
|
assert ONLINE, "AutoUpdate skipped (offline)"
|
|
393
393
|
with Retry(times=2, delay=1): # run up to 2 times with 1-second retry delay
|
|
394
|
-
LOGGER.info(subprocess.check_output(f"pip install --no-cache {s} {cmds}", shell=True).decode())
|
|
394
|
+
LOGGER.info(subprocess.check_output(f"pip install --no-cache-dir {s} {cmds}", shell=True).decode())
|
|
395
395
|
dt = time.time() - t
|
|
396
396
|
LOGGER.info(
|
|
397
397
|
f"{prefix} AutoUpdate success ✅ {dt:.1f}s, installed {n} package{'s' * (n > 1)}: {pkgs}\n"
|
|
@@ -535,7 +535,8 @@ def check_imshow(warn=False):
|
|
|
535
535
|
"""Check if environment supports image displays."""
|
|
536
536
|
try:
|
|
537
537
|
if LINUX:
|
|
538
|
-
assert
|
|
538
|
+
assert not IS_COLAB and not IS_KAGGLE
|
|
539
|
+
assert "DISPLAY" in os.environ, "The DISPLAY environment variable isn't set."
|
|
539
540
|
cv2.imshow("test", np.zeros((8, 8, 3), dtype=np.uint8)) # show a small 8-pixel image
|
|
540
541
|
cv2.waitKey(1)
|
|
541
542
|
cv2.destroyAllWindows()
|