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.

@@ -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 management in real-time video stream based on their tracks."""
16
+ """A class to manage the queue in a real-time video stream based on object tracks."""
17
17
 
18
- def __init__(self):
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
- Configures the Counter's image, bounding box line thickness, and counting region points.
34
+ Initializes the QueueManager with specified parameters for tracking and counting objects.
72
35
 
73
36
  Args:
74
- line_thickness (int): Line thickness for bounding boxes.
75
- view_img (bool): Flag to control whether to display the video stream.
76
- view_queue_counts (bool): Flag to control whether to display the counts on video stream.
77
- reg_pts (list): Initial list of points defining the counting region.
78
- classes_names (dict): Classes names
79
- region_color (RGB color): Color of queue region
80
- track_thickness (int): Track thickness
81
- draw_tracks (Bool): draw tracks
82
- count_txt_color (RGB color): count text color value
83
- track_color (RGB color): color for tracks
84
- region_thickness (int): Object counting Region thickness
85
- fontsize (float): Text display font size
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.track_thickness = track_thickness
91
- self.draw_tracks = draw_tracks
92
- self.region_color = region_color
70
+ self.fontsize = fontsize
93
71
 
94
- if len(reg_pts) >= 3:
95
- print("Queue region initiated...")
96
- self.reg_pts = reg_pts
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
- self.names = classes_names
104
- self.track_color = track_color
76
+ # Object counting Information
77
+ self.counts = 0
105
78
  self.count_txt_color = count_txt_color
106
- self.region_thickness = region_thickness
107
- self.fontsize = fontsize
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
- # Annotator Init and queue region drawing
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
- # Draw Tracks
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 if self.track_color else colors(int(track_id), True),
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
- label = "Queue Counts : " + str(self.counts)
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
- """Display frame."""
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
- # Break Window
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 # store image
179
- self.extract_and_process_tracks(tracks) # draw region even if no objects
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
- QueueManager()
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 estimation speed of objects in real-time video stream based on their tracks."""
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
- """Initializes the speed-estimator class with default values for Visual, Image, track and speed parameters."""
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
- # Visual & im0 information
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 = False
31
+ self.view_img = view_img
23
32
 
24
33
  # Region information
25
- self.reg_pts = [(20, 400), (1260, 400)]
26
- self.region_thickness = 3
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
- # Predict/track information
37
+ # Tracking information
29
38
  self.clss = None
30
- self.names = None
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 = 2
43
+ self.line_thickness = line_thickness
35
44
  self.trk_history = defaultdict(list)
36
45
 
37
- # Speed estimator information
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 = 10
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 support imshow
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
- Store track data.
70
+ Stores track data.
92
71
 
93
72
  Args:
94
- track_id (int): object track id.
95
- box (list): object bounding box data
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
- Plot track and bounding box.
91
+ Plots track and bounding box.
110
92
 
111
93
  Args:
112
- track_id (int): object track id.
113
- box (list): object bounding box data
114
- cls (str): object class name
115
- track (list): tracking history for tracks path drawing
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/ph" if track_id in self.dist_data else self.names[int(cls)]
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
- Calculation of object speed.
108
+ Calculates the speed of an object.
128
109
 
129
110
  Args:
130
- trk_id (int): object track id.
131
- track (list): tracking history for tracks path drawing
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[trk_id] != 0 and direction != "unknown" and trk_id not in self.trk_idslist:
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
- Calculate object based on tracking data.
137
+ Estimates the speed of objects based on tracking data.
160
138
 
161
139
  Args:
162
- im0 (nd array): Image
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.annotator = Annotator(self.im0, line_width=2)
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
- """Display frame."""
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
- SpeedEstimator()
179
+ names = {0: "person", 1: "car"} # example class names
180
+ speed_estimator = SpeedEstimator(names)
@@ -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=1.0).close()
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)
@@ -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 "DISPLAY" in os.environ and not IS_DOCKER and not IS_COLAB and not IS_KAGGLE
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()