ultralytics 8.2.17__py3-none-any.whl → 8.2.19__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/cfg/datasets/signature.yaml +20 -0
- ultralytics/cfg/models/v9/yolov9c-seg.yaml +22 -22
- ultralytics/cfg/models/v9/yolov9c.yaml +22 -22
- ultralytics/cfg/models/v9/yolov9e-seg.yaml +34 -34
- ultralytics/cfg/models/v9/yolov9e.yaml +34 -34
- ultralytics/data/build.py +1 -1
- ultralytics/engine/exporter.py +3 -0
- 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/plotting.py +40 -42
- {ultralytics-8.2.17.dist-info → ultralytics-8.2.19.dist-info}/METADATA +1 -1
- {ultralytics-8.2.17.dist-info → ultralytics-8.2.19.dist-info}/RECORD +23 -22
- {ultralytics-8.2.17.dist-info → ultralytics-8.2.19.dist-info}/LICENSE +0 -0
- {ultralytics-8.2.17.dist-info → ultralytics-8.2.19.dist-info}/WHEEL +0 -0
- {ultralytics-8.2.17.dist-info → ultralytics-8.2.19.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.2.17.dist-info → ultralytics-8.2.19.dist-info}/top_level.txt +0 -0
|
@@ -15,55 +15,10 @@ from shapely.geometry import LineString, Point, Polygon
|
|
|
15
15
|
class ObjectCounter:
|
|
16
16
|
"""A class to manage the counting of objects in a real-time video stream based on their tracks."""
|
|
17
17
|
|
|
18
|
-
def __init__(
|
|
19
|
-
"""Initializes the Counter 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, 400), (1260, 400)]
|
|
27
|
-
self.line_dist_thresh = 15
|
|
28
|
-
self.counting_region = None
|
|
29
|
-
self.region_color = (255, 0, 255)
|
|
30
|
-
self.region_thickness = 5
|
|
31
|
-
|
|
32
|
-
# Image and annotation Information
|
|
33
|
-
self.im0 = None
|
|
34
|
-
self.tf = None
|
|
35
|
-
self.view_img = False
|
|
36
|
-
self.view_in_counts = True
|
|
37
|
-
self.view_out_counts = True
|
|
38
|
-
|
|
39
|
-
self.names = None # Classes names
|
|
40
|
-
self.annotator = None # Annotator
|
|
41
|
-
self.window_name = "Ultralytics YOLOv8 Object Counter"
|
|
42
|
-
|
|
43
|
-
# Object counting Information
|
|
44
|
-
self.in_counts = 0
|
|
45
|
-
self.out_counts = 0
|
|
46
|
-
self.count_ids = []
|
|
47
|
-
self.class_wise_count = {}
|
|
48
|
-
self.count_txt_thickness = 0
|
|
49
|
-
self.count_txt_color = (255, 255, 255)
|
|
50
|
-
self.count_bg_color = (255, 255, 255)
|
|
51
|
-
self.cls_txtdisplay_gap = 50
|
|
52
|
-
self.fontsize = 0.6
|
|
53
|
-
|
|
54
|
-
# Tracks info
|
|
55
|
-
self.track_history = defaultdict(list)
|
|
56
|
-
self.track_thickness = 2
|
|
57
|
-
self.draw_tracks = False
|
|
58
|
-
self.track_color = None
|
|
59
|
-
|
|
60
|
-
# Check if environment support imshow
|
|
61
|
-
self.env_check = check_imshow(warn=True)
|
|
62
|
-
|
|
63
|
-
def set_args(
|
|
18
|
+
def __init__(
|
|
64
19
|
self,
|
|
65
20
|
classes_names,
|
|
66
|
-
reg_pts,
|
|
21
|
+
reg_pts=None,
|
|
67
22
|
count_reg_color=(255, 0, 255),
|
|
68
23
|
count_txt_color=(0, 0, 0),
|
|
69
24
|
count_bg_color=(255, 255, 255),
|
|
@@ -79,66 +34,90 @@ class ObjectCounter:
|
|
|
79
34
|
cls_txtdisplay_gap=50,
|
|
80
35
|
):
|
|
81
36
|
"""
|
|
82
|
-
|
|
37
|
+
Initializes the ObjectCounter with various tracking and counting parameters.
|
|
83
38
|
|
|
84
39
|
Args:
|
|
40
|
+
classes_names (dict): Dictionary of class names.
|
|
41
|
+
reg_pts (list): List of points defining the counting region.
|
|
42
|
+
count_reg_color (tuple): RGB color of the counting region.
|
|
43
|
+
count_txt_color (tuple): RGB color of the count text.
|
|
44
|
+
count_bg_color (tuple): RGB color of the count text background.
|
|
85
45
|
line_thickness (int): Line thickness for bounding boxes.
|
|
46
|
+
track_thickness (int): Thickness of the track lines.
|
|
86
47
|
view_img (bool): Flag to control whether to display the video stream.
|
|
87
|
-
view_in_counts (bool): Flag to control whether to display the
|
|
88
|
-
view_out_counts (bool): Flag to control whether to display the
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
count_bg_color (RGB color): count highlighter line color
|
|
95
|
-
count_reg_color (RGB color): Color of object counting region
|
|
96
|
-
track_color (RGB color): color for tracks
|
|
97
|
-
region_thickness (int): Object counting Region thickness
|
|
98
|
-
line_dist_thresh (int): Euclidean Distance threshold for line counter
|
|
99
|
-
cls_txtdisplay_gap (int): Display gap between each class count
|
|
48
|
+
view_in_counts (bool): Flag to control whether to display the in counts on the video stream.
|
|
49
|
+
view_out_counts (bool): Flag to control whether to display the out counts on the video stream.
|
|
50
|
+
draw_tracks (bool): Flag to control whether to draw the object tracks.
|
|
51
|
+
track_color (tuple): RGB color of the tracks.
|
|
52
|
+
region_thickness (int): Thickness of the object counting region.
|
|
53
|
+
line_dist_thresh (int): Euclidean distance threshold for line counter.
|
|
54
|
+
cls_txtdisplay_gap (int): Display gap between each class count.
|
|
100
55
|
"""
|
|
56
|
+
|
|
57
|
+
# Mouse events
|
|
58
|
+
self.is_drawing = False
|
|
59
|
+
self.selected_point = None
|
|
60
|
+
|
|
61
|
+
# Region & Line Information
|
|
62
|
+
self.reg_pts = [(20, 400), (1260, 400)] if reg_pts is None else reg_pts
|
|
63
|
+
self.line_dist_thresh = line_dist_thresh
|
|
64
|
+
self.counting_region = None
|
|
65
|
+
self.region_color = count_reg_color
|
|
66
|
+
self.region_thickness = region_thickness
|
|
67
|
+
|
|
68
|
+
# Image and annotation Information
|
|
69
|
+
self.im0 = None
|
|
101
70
|
self.tf = line_thickness
|
|
102
71
|
self.view_img = view_img
|
|
103
72
|
self.view_in_counts = view_in_counts
|
|
104
73
|
self.view_out_counts = view_out_counts
|
|
74
|
+
|
|
75
|
+
self.names = classes_names # Classes names
|
|
76
|
+
self.annotator = None # Annotator
|
|
77
|
+
self.window_name = "Ultralytics YOLOv8 Object Counter"
|
|
78
|
+
|
|
79
|
+
# Object counting Information
|
|
80
|
+
self.in_counts = 0
|
|
81
|
+
self.out_counts = 0
|
|
82
|
+
self.count_ids = []
|
|
83
|
+
self.class_wise_count = {}
|
|
84
|
+
self.count_txt_thickness = 0
|
|
85
|
+
self.count_txt_color = count_txt_color
|
|
86
|
+
self.count_bg_color = count_bg_color
|
|
87
|
+
self.cls_txtdisplay_gap = cls_txtdisplay_gap
|
|
88
|
+
self.fontsize = 0.6
|
|
89
|
+
|
|
90
|
+
# Tracks info
|
|
91
|
+
self.track_history = defaultdict(list)
|
|
105
92
|
self.track_thickness = track_thickness
|
|
106
93
|
self.draw_tracks = draw_tracks
|
|
94
|
+
self.track_color = track_color
|
|
95
|
+
|
|
96
|
+
# Check if environment supports imshow
|
|
97
|
+
self.env_check = check_imshow(warn=True)
|
|
107
98
|
|
|
108
|
-
#
|
|
109
|
-
if len(reg_pts) == 2:
|
|
99
|
+
# Initialize counting region
|
|
100
|
+
if len(self.reg_pts) == 2:
|
|
110
101
|
print("Line Counter Initiated.")
|
|
111
|
-
self.reg_pts = reg_pts
|
|
112
102
|
self.counting_region = LineString(self.reg_pts)
|
|
113
|
-
elif len(reg_pts) >= 3:
|
|
103
|
+
elif len(self.reg_pts) >= 3:
|
|
114
104
|
print("Polygon Counter Initiated.")
|
|
115
|
-
self.reg_pts = reg_pts
|
|
116
105
|
self.counting_region = Polygon(self.reg_pts)
|
|
117
106
|
else:
|
|
118
107
|
print("Invalid Region points provided, region_points must be 2 for lines or >= 3 for polygons.")
|
|
119
108
|
print("Using Line Counter Now")
|
|
120
109
|
self.counting_region = LineString(self.reg_pts)
|
|
121
110
|
|
|
122
|
-
self.names = classes_names
|
|
123
|
-
self.track_color = track_color
|
|
124
|
-
self.count_txt_color = count_txt_color
|
|
125
|
-
self.count_bg_color = count_bg_color
|
|
126
|
-
self.region_color = count_reg_color
|
|
127
|
-
self.region_thickness = region_thickness
|
|
128
|
-
self.line_dist_thresh = line_dist_thresh
|
|
129
|
-
self.cls_txtdisplay_gap = cls_txtdisplay_gap
|
|
130
|
-
|
|
131
111
|
def mouse_event_for_region(self, event, x, y, flags, params):
|
|
132
112
|
"""
|
|
133
|
-
|
|
113
|
+
Handles mouse events for defining and moving the counting region in a real-time video stream.
|
|
134
114
|
|
|
135
115
|
Args:
|
|
136
116
|
event (int): The type of mouse event (e.g., cv2.EVENT_MOUSEMOVE, cv2.EVENT_LBUTTONDOWN, etc.).
|
|
137
117
|
x (int): The x-coordinate of the mouse pointer.
|
|
138
118
|
y (int): The y-coordinate of the mouse pointer.
|
|
139
|
-
flags (int): Any
|
|
140
|
-
|
|
141
|
-
params (dict): Additional parameters you may want to pass to the function.
|
|
119
|
+
flags (int): Any associated event flags (e.g., cv2.EVENT_FLAG_CTRLKEY, cv2.EVENT_FLAG_SHIFTKEY, etc.).
|
|
120
|
+
params (dict): Additional parameters for the function.
|
|
142
121
|
"""
|
|
143
122
|
if event == cv2.EVENT_LBUTTONDOWN:
|
|
144
123
|
for i, point in enumerate(self.reg_pts):
|
|
@@ -240,11 +219,11 @@ class ObjectCounter:
|
|
|
240
219
|
else:
|
|
241
220
|
labels_dict[str.capitalize(key)] = f"IN {value['IN']} OUT {value['OUT']}"
|
|
242
221
|
|
|
243
|
-
if labels_dict
|
|
222
|
+
if labels_dict:
|
|
244
223
|
self.annotator.display_analytics(self.im0, labels_dict, self.count_txt_color, self.count_bg_color, 10)
|
|
245
224
|
|
|
246
225
|
def display_frames(self):
|
|
247
|
-
"""
|
|
226
|
+
"""Displays the current frame with annotations and regions in a window."""
|
|
248
227
|
if self.env_check:
|
|
249
228
|
cv2.namedWindow(self.window_name)
|
|
250
229
|
if len(self.reg_pts) == 4: # only add mouse event If user drawn region
|
|
@@ -271,4 +250,5 @@ class ObjectCounter:
|
|
|
271
250
|
|
|
272
251
|
|
|
273
252
|
if __name__ == "__main__":
|
|
274
|
-
|
|
253
|
+
classes_names = {0: "person", 1: "car"} # example class names
|
|
254
|
+
ObjectCounter(classes_names)
|
|
@@ -8,17 +8,22 @@ from PIL import Image, ImageTk
|
|
|
8
8
|
from ultralytics.utils.checks import check_imshow, check_requirements
|
|
9
9
|
from ultralytics.utils.plotting import Annotator
|
|
10
10
|
|
|
11
|
-
check_requirements("tkinter")
|
|
12
|
-
import tkinter as tk
|
|
13
|
-
|
|
14
11
|
|
|
15
12
|
class ParkingPtsSelection:
|
|
16
13
|
def __init__(self, master):
|
|
17
|
-
"""
|
|
14
|
+
"""
|
|
15
|
+
Initializes the UI for selecting parking zone points in a tkinter window.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
master (tk.Tk): The main tkinter window object.
|
|
19
|
+
"""
|
|
20
|
+
check_requirements("tkinter")
|
|
21
|
+
import tkinter as tk
|
|
22
|
+
|
|
18
23
|
self.master = master
|
|
19
24
|
master.title("Ultralytics Parking Zones Points Selector")
|
|
20
25
|
|
|
21
|
-
#
|
|
26
|
+
# Disable window resizing
|
|
22
27
|
master.resizable(False, False)
|
|
23
28
|
|
|
24
29
|
# Setup canvas for image display
|
|
@@ -36,7 +41,6 @@ class ParkingPtsSelection:
|
|
|
36
41
|
self.image_path = None
|
|
37
42
|
self.image = None
|
|
38
43
|
self.canvas_image = None
|
|
39
|
-
self.canvas = None
|
|
40
44
|
self.bounding_boxes = []
|
|
41
45
|
self.current_box = []
|
|
42
46
|
self.img_width = 0
|
|
@@ -101,7 +105,6 @@ class ParkingPtsSelection:
|
|
|
101
105
|
Args:
|
|
102
106
|
box (list): Bounding box data
|
|
103
107
|
"""
|
|
104
|
-
|
|
105
108
|
for i in range(4):
|
|
106
109
|
x1, y1 = box[i]
|
|
107
110
|
x2, y2 = box[(i + 1) % 4]
|
|
@@ -151,6 +154,17 @@ class ParkingManagement:
|
|
|
151
154
|
available_region_color=(0, 0, 255),
|
|
152
155
|
margin=10,
|
|
153
156
|
):
|
|
157
|
+
"""
|
|
158
|
+
Initializes the parking management system with a YOLOv8 model and visualization settings.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
model_path (str): Path to the YOLOv8 model.
|
|
162
|
+
txt_color (tuple): RGB color tuple for text.
|
|
163
|
+
bg_color (tuple): RGB color tuple for background.
|
|
164
|
+
occupied_region_color (tuple): RGB color tuple for occupied regions.
|
|
165
|
+
available_region_color (tuple): RGB color tuple for available regions.
|
|
166
|
+
margin (int): Margin for text display.
|
|
167
|
+
"""
|
|
154
168
|
# Model path and initialization
|
|
155
169
|
self.model_path = model_path
|
|
156
170
|
self.model = self.load_model()
|
|
@@ -166,7 +180,7 @@ class ParkingManagement:
|
|
|
166
180
|
self.available_region_color = available_region_color
|
|
167
181
|
|
|
168
182
|
self.window_name = "Ultralytics YOLOv8 Parking Management System"
|
|
169
|
-
# Check if environment
|
|
183
|
+
# Check if environment supports imshow
|
|
170
184
|
self.env_check = check_imshow(warn=True)
|
|
171
185
|
|
|
172
186
|
def load_model(self):
|
|
@@ -184,7 +198,6 @@ class ParkingManagement:
|
|
|
184
198
|
Args:
|
|
185
199
|
json_file (str): file that have all parking slot points
|
|
186
200
|
"""
|
|
187
|
-
|
|
188
201
|
with open(json_file, "r") as json_file:
|
|
189
202
|
return json.load(json_file)
|
|
190
203
|
|
|
@@ -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)
|