dgenerate-ultralytics-headless 8.3.214__py3-none-any.whl → 8.4.7__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.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/METADATA +64 -74
- dgenerate_ultralytics_headless-8.4.7.dist-info/RECORD +311 -0
- {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/WHEEL +1 -1
- tests/__init__.py +7 -9
- tests/conftest.py +8 -15
- tests/test_cli.py +1 -1
- tests/test_cuda.py +13 -10
- tests/test_engine.py +9 -9
- tests/test_exports.py +65 -13
- tests/test_integrations.py +13 -13
- tests/test_python.py +125 -69
- tests/test_solutions.py +161 -152
- ultralytics/__init__.py +1 -1
- ultralytics/cfg/__init__.py +86 -92
- ultralytics/cfg/datasets/Argoverse.yaml +7 -6
- ultralytics/cfg/datasets/DOTAv1.5.yaml +1 -1
- ultralytics/cfg/datasets/DOTAv1.yaml +1 -1
- ultralytics/cfg/datasets/ImageNet.yaml +1 -1
- ultralytics/cfg/datasets/TT100K.yaml +346 -0
- ultralytics/cfg/datasets/VOC.yaml +15 -16
- ultralytics/cfg/datasets/african-wildlife.yaml +1 -1
- ultralytics/cfg/datasets/coco-pose.yaml +21 -0
- ultralytics/cfg/datasets/coco12-formats.yaml +101 -0
- ultralytics/cfg/datasets/coco128-seg.yaml +1 -1
- ultralytics/cfg/datasets/coco8-pose.yaml +21 -0
- ultralytics/cfg/datasets/dog-pose.yaml +28 -0
- ultralytics/cfg/datasets/dota8-multispectral.yaml +1 -1
- ultralytics/cfg/datasets/dota8.yaml +2 -2
- ultralytics/cfg/datasets/hand-keypoints.yaml +26 -2
- ultralytics/cfg/datasets/kitti.yaml +27 -0
- ultralytics/cfg/datasets/lvis.yaml +5 -5
- ultralytics/cfg/datasets/open-images-v7.yaml +1 -1
- ultralytics/cfg/datasets/tiger-pose.yaml +16 -0
- ultralytics/cfg/datasets/xView.yaml +16 -16
- ultralytics/cfg/default.yaml +4 -2
- ultralytics/cfg/models/11/yolo11-pose.yaml +1 -1
- ultralytics/cfg/models/11/yoloe-11-seg.yaml +2 -2
- ultralytics/cfg/models/11/yoloe-11.yaml +2 -2
- ultralytics/cfg/models/26/yolo26-cls.yaml +33 -0
- ultralytics/cfg/models/26/yolo26-obb.yaml +52 -0
- ultralytics/cfg/models/26/yolo26-p2.yaml +60 -0
- ultralytics/cfg/models/26/yolo26-p6.yaml +62 -0
- ultralytics/cfg/models/26/yolo26-pose.yaml +53 -0
- ultralytics/cfg/models/26/yolo26-seg.yaml +52 -0
- ultralytics/cfg/models/26/yolo26.yaml +52 -0
- ultralytics/cfg/models/26/yoloe-26-seg.yaml +53 -0
- ultralytics/cfg/models/26/yoloe-26.yaml +53 -0
- ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +1 -1
- ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +1 -1
- ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +1 -1
- ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +1 -1
- ultralytics/cfg/models/v10/yolov10b.yaml +2 -2
- ultralytics/cfg/models/v10/yolov10l.yaml +2 -2
- ultralytics/cfg/models/v10/yolov10m.yaml +2 -2
- ultralytics/cfg/models/v10/yolov10n.yaml +2 -2
- ultralytics/cfg/models/v10/yolov10s.yaml +2 -2
- ultralytics/cfg/models/v10/yolov10x.yaml +2 -2
- ultralytics/cfg/models/v3/yolov3-tiny.yaml +1 -1
- ultralytics/cfg/models/v6/yolov6.yaml +1 -1
- ultralytics/cfg/models/v8/yoloe-v8-seg.yaml +9 -6
- ultralytics/cfg/models/v8/yoloe-v8.yaml +9 -6
- ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +2 -2
- ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +2 -2
- ultralytics/cfg/models/v8/yolov8-ghost.yaml +2 -2
- ultralytics/cfg/models/v8/yolov8-obb.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-p2.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-world.yaml +1 -1
- ultralytics/cfg/models/v8/yolov8-worldv2.yaml +6 -6
- ultralytics/cfg/models/v9/yolov9s.yaml +1 -1
- ultralytics/data/__init__.py +4 -4
- ultralytics/data/annotator.py +5 -6
- ultralytics/data/augment.py +300 -475
- ultralytics/data/base.py +18 -26
- ultralytics/data/build.py +147 -25
- ultralytics/data/converter.py +108 -87
- ultralytics/data/dataset.py +47 -75
- ultralytics/data/loaders.py +42 -49
- ultralytics/data/split.py +5 -6
- ultralytics/data/split_dota.py +8 -15
- ultralytics/data/utils.py +36 -45
- ultralytics/engine/exporter.py +351 -263
- ultralytics/engine/model.py +186 -225
- ultralytics/engine/predictor.py +45 -54
- ultralytics/engine/results.py +198 -325
- ultralytics/engine/trainer.py +165 -106
- ultralytics/engine/tuner.py +41 -43
- ultralytics/engine/validator.py +55 -38
- ultralytics/hub/__init__.py +16 -19
- ultralytics/hub/auth.py +6 -12
- ultralytics/hub/google/__init__.py +7 -10
- ultralytics/hub/session.py +15 -25
- ultralytics/hub/utils.py +5 -8
- ultralytics/models/__init__.py +1 -1
- ultralytics/models/fastsam/__init__.py +1 -1
- ultralytics/models/fastsam/model.py +8 -10
- ultralytics/models/fastsam/predict.py +18 -30
- ultralytics/models/fastsam/utils.py +1 -2
- ultralytics/models/fastsam/val.py +5 -7
- ultralytics/models/nas/__init__.py +1 -1
- ultralytics/models/nas/model.py +5 -8
- ultralytics/models/nas/predict.py +7 -9
- ultralytics/models/nas/val.py +1 -2
- ultralytics/models/rtdetr/__init__.py +1 -1
- ultralytics/models/rtdetr/model.py +5 -8
- ultralytics/models/rtdetr/predict.py +15 -19
- ultralytics/models/rtdetr/train.py +10 -13
- ultralytics/models/rtdetr/val.py +21 -23
- ultralytics/models/sam/__init__.py +15 -2
- ultralytics/models/sam/amg.py +14 -20
- ultralytics/models/sam/build.py +26 -19
- ultralytics/models/sam/build_sam3.py +377 -0
- ultralytics/models/sam/model.py +29 -32
- ultralytics/models/sam/modules/blocks.py +83 -144
- ultralytics/models/sam/modules/decoders.py +19 -37
- ultralytics/models/sam/modules/encoders.py +44 -101
- ultralytics/models/sam/modules/memory_attention.py +16 -30
- ultralytics/models/sam/modules/sam.py +200 -73
- ultralytics/models/sam/modules/tiny_encoder.py +64 -83
- ultralytics/models/sam/modules/transformer.py +18 -28
- ultralytics/models/sam/modules/utils.py +174 -50
- ultralytics/models/sam/predict.py +2248 -350
- ultralytics/models/sam/sam3/__init__.py +3 -0
- ultralytics/models/sam/sam3/decoder.py +546 -0
- ultralytics/models/sam/sam3/encoder.py +529 -0
- ultralytics/models/sam/sam3/geometry_encoders.py +415 -0
- ultralytics/models/sam/sam3/maskformer_segmentation.py +286 -0
- ultralytics/models/sam/sam3/model_misc.py +199 -0
- ultralytics/models/sam/sam3/necks.py +129 -0
- ultralytics/models/sam/sam3/sam3_image.py +339 -0
- ultralytics/models/sam/sam3/text_encoder_ve.py +307 -0
- ultralytics/models/sam/sam3/vitdet.py +547 -0
- ultralytics/models/sam/sam3/vl_combiner.py +160 -0
- ultralytics/models/utils/loss.py +14 -26
- ultralytics/models/utils/ops.py +13 -17
- ultralytics/models/yolo/__init__.py +1 -1
- ultralytics/models/yolo/classify/predict.py +10 -13
- ultralytics/models/yolo/classify/train.py +12 -33
- ultralytics/models/yolo/classify/val.py +30 -29
- ultralytics/models/yolo/detect/predict.py +9 -12
- ultralytics/models/yolo/detect/train.py +17 -23
- ultralytics/models/yolo/detect/val.py +77 -59
- ultralytics/models/yolo/model.py +43 -60
- ultralytics/models/yolo/obb/predict.py +7 -16
- ultralytics/models/yolo/obb/train.py +14 -17
- ultralytics/models/yolo/obb/val.py +40 -37
- ultralytics/models/yolo/pose/__init__.py +1 -1
- ultralytics/models/yolo/pose/predict.py +7 -22
- ultralytics/models/yolo/pose/train.py +13 -16
- ultralytics/models/yolo/pose/val.py +39 -58
- ultralytics/models/yolo/segment/predict.py +17 -21
- ultralytics/models/yolo/segment/train.py +7 -10
- ultralytics/models/yolo/segment/val.py +95 -47
- ultralytics/models/yolo/world/train.py +8 -14
- ultralytics/models/yolo/world/train_world.py +11 -34
- ultralytics/models/yolo/yoloe/__init__.py +7 -7
- ultralytics/models/yolo/yoloe/predict.py +16 -23
- ultralytics/models/yolo/yoloe/train.py +36 -44
- ultralytics/models/yolo/yoloe/train_seg.py +11 -11
- ultralytics/models/yolo/yoloe/val.py +15 -20
- ultralytics/nn/__init__.py +7 -7
- ultralytics/nn/autobackend.py +159 -85
- ultralytics/nn/modules/__init__.py +68 -60
- ultralytics/nn/modules/activation.py +4 -6
- ultralytics/nn/modules/block.py +260 -224
- ultralytics/nn/modules/conv.py +52 -97
- ultralytics/nn/modules/head.py +831 -299
- ultralytics/nn/modules/transformer.py +76 -88
- ultralytics/nn/modules/utils.py +16 -21
- ultralytics/nn/tasks.py +180 -195
- ultralytics/nn/text_model.py +45 -69
- ultralytics/optim/__init__.py +5 -0
- ultralytics/optim/muon.py +338 -0
- ultralytics/solutions/__init__.py +12 -12
- ultralytics/solutions/ai_gym.py +13 -19
- ultralytics/solutions/analytics.py +15 -16
- ultralytics/solutions/config.py +6 -7
- ultralytics/solutions/distance_calculation.py +10 -13
- ultralytics/solutions/heatmap.py +8 -14
- ultralytics/solutions/instance_segmentation.py +6 -9
- ultralytics/solutions/object_blurrer.py +7 -10
- ultralytics/solutions/object_counter.py +12 -19
- ultralytics/solutions/object_cropper.py +8 -14
- ultralytics/solutions/parking_management.py +34 -32
- ultralytics/solutions/queue_management.py +10 -12
- ultralytics/solutions/region_counter.py +9 -12
- ultralytics/solutions/security_alarm.py +15 -20
- ultralytics/solutions/similarity_search.py +10 -15
- ultralytics/solutions/solutions.py +77 -76
- ultralytics/solutions/speed_estimation.py +7 -10
- ultralytics/solutions/streamlit_inference.py +2 -4
- ultralytics/solutions/templates/similarity-search.html +7 -18
- ultralytics/solutions/trackzone.py +7 -10
- ultralytics/solutions/vision_eye.py +5 -8
- ultralytics/trackers/__init__.py +1 -1
- ultralytics/trackers/basetrack.py +3 -5
- ultralytics/trackers/bot_sort.py +10 -27
- ultralytics/trackers/byte_tracker.py +21 -37
- ultralytics/trackers/track.py +4 -7
- ultralytics/trackers/utils/gmc.py +11 -22
- ultralytics/trackers/utils/kalman_filter.py +37 -48
- ultralytics/trackers/utils/matching.py +12 -15
- ultralytics/utils/__init__.py +124 -124
- ultralytics/utils/autobatch.py +2 -4
- ultralytics/utils/autodevice.py +17 -18
- ultralytics/utils/benchmarks.py +57 -71
- ultralytics/utils/callbacks/base.py +8 -10
- ultralytics/utils/callbacks/clearml.py +5 -13
- ultralytics/utils/callbacks/comet.py +32 -46
- ultralytics/utils/callbacks/dvc.py +13 -18
- ultralytics/utils/callbacks/mlflow.py +4 -5
- ultralytics/utils/callbacks/neptune.py +7 -15
- ultralytics/utils/callbacks/platform.py +423 -38
- ultralytics/utils/callbacks/raytune.py +3 -4
- ultralytics/utils/callbacks/tensorboard.py +25 -31
- ultralytics/utils/callbacks/wb.py +16 -14
- ultralytics/utils/checks.py +127 -85
- ultralytics/utils/cpu.py +3 -8
- ultralytics/utils/dist.py +9 -12
- ultralytics/utils/downloads.py +25 -33
- ultralytics/utils/errors.py +6 -14
- ultralytics/utils/events.py +2 -4
- ultralytics/utils/export/__init__.py +4 -236
- ultralytics/utils/export/engine.py +246 -0
- ultralytics/utils/export/imx.py +117 -63
- ultralytics/utils/export/tensorflow.py +231 -0
- ultralytics/utils/files.py +26 -30
- ultralytics/utils/git.py +9 -11
- ultralytics/utils/instance.py +30 -51
- ultralytics/utils/logger.py +212 -114
- ultralytics/utils/loss.py +601 -215
- ultralytics/utils/metrics.py +128 -156
- ultralytics/utils/nms.py +13 -16
- ultralytics/utils/ops.py +117 -166
- ultralytics/utils/patches.py +75 -21
- ultralytics/utils/plotting.py +75 -80
- ultralytics/utils/tal.py +125 -59
- ultralytics/utils/torch_utils.py +53 -79
- ultralytics/utils/tqdm.py +24 -21
- ultralytics/utils/triton.py +13 -19
- ultralytics/utils/tuner.py +19 -10
- dgenerate_ultralytics_headless-8.3.214.dist-info/RECORD +0 -283
- {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/entry_points.txt +0 -0
- {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/licenses/LICENSE +0 -0
- {dgenerate_ultralytics_headless-8.3.214.dist-info → dgenerate_ultralytics_headless-8.4.7.dist-info}/top_level.txt +0 -0
|
@@ -14,11 +14,10 @@ from ultralytics.utils.checks import check_imshow
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class ParkingPtsSelection:
|
|
17
|
-
"""
|
|
18
|
-
A class for selecting and managing parking zone points on images using a Tkinter-based UI.
|
|
17
|
+
"""A class for selecting and managing parking zone points on images using a Tkinter-based UI.
|
|
19
18
|
|
|
20
|
-
This class provides functionality to upload an image, select points to define parking zones, and save the
|
|
21
|
-
|
|
19
|
+
This class provides functionality to upload an image, select points to define parking zones, and save the selected
|
|
20
|
+
points to a JSON file. It uses Tkinter for the graphical user interface.
|
|
22
21
|
|
|
23
22
|
Attributes:
|
|
24
23
|
tk (module): The Tkinter module for GUI operations.
|
|
@@ -93,7 +92,7 @@ class ParkingPtsSelection:
|
|
|
93
92
|
|
|
94
93
|
for text, cmd in [
|
|
95
94
|
("Upload Image", self.upload_image),
|
|
96
|
-
("Remove Last
|
|
95
|
+
("Remove Last Bounding Box", self.remove_last_bounding_box),
|
|
97
96
|
("Save", self.save_to_json),
|
|
98
97
|
]:
|
|
99
98
|
self.tk.Button(button_frame, text=text, command=cmd).pack(side=self.tk.LEFT)
|
|
@@ -178,26 +177,25 @@ class ParkingPtsSelection:
|
|
|
178
177
|
|
|
179
178
|
|
|
180
179
|
class ParkingManagement(BaseSolution):
|
|
181
|
-
"""
|
|
182
|
-
Manages parking occupancy and availability using YOLO model for real-time monitoring and visualization.
|
|
180
|
+
"""Manages parking occupancy and availability using YOLO model for real-time monitoring and visualization.
|
|
183
181
|
|
|
184
|
-
This class extends BaseSolution to provide functionality for parking lot management, including detection of
|
|
185
|
-
|
|
182
|
+
This class extends BaseSolution to provide functionality for parking lot management, including detection of occupied
|
|
183
|
+
spaces, visualization of parking regions, and display of occupancy statistics.
|
|
186
184
|
|
|
187
185
|
Attributes:
|
|
188
186
|
json_file (str): Path to the JSON file containing parking region details.
|
|
189
187
|
json (list[dict]): Loaded JSON data containing parking region information.
|
|
190
188
|
pr_info (dict[str, int]): Dictionary storing parking information (Occupancy and Available spaces).
|
|
191
|
-
arc (tuple[int, int, int]):
|
|
192
|
-
occ (tuple[int, int, int]):
|
|
193
|
-
dc (tuple[int, int, int]):
|
|
189
|
+
arc (tuple[int, int, int]): BGR color tuple for available region visualization.
|
|
190
|
+
occ (tuple[int, int, int]): BGR color tuple for occupied region visualization.
|
|
191
|
+
dc (tuple[int, int, int]): BGR color tuple for centroid visualization of detected objects.
|
|
194
192
|
|
|
195
193
|
Methods:
|
|
196
194
|
process: Process the input image for parking lot management and visualization.
|
|
197
195
|
|
|
198
196
|
Examples:
|
|
199
197
|
>>> from ultralytics.solutions import ParkingManagement
|
|
200
|
-
>>> parking_manager = ParkingManagement(model="
|
|
198
|
+
>>> parking_manager = ParkingManagement(model="yolo26n.pt", json_file="parking_regions.json")
|
|
201
199
|
>>> print(f"Occupied spaces: {parking_manager.pr_info['Occupancy']}")
|
|
202
200
|
>>> print(f"Available spaces: {parking_manager.pr_info['Available']}")
|
|
203
201
|
"""
|
|
@@ -207,11 +205,11 @@ class ParkingManagement(BaseSolution):
|
|
|
207
205
|
super().__init__(**kwargs)
|
|
208
206
|
|
|
209
207
|
self.json_file = self.CFG["json_file"] # Load parking regions JSON data
|
|
210
|
-
if self.json_file
|
|
211
|
-
LOGGER.warning("json_file
|
|
212
|
-
raise ValueError("❌
|
|
208
|
+
if not self.json_file:
|
|
209
|
+
LOGGER.warning("ParkingManagement requires `json_file` with parking region coordinates.")
|
|
210
|
+
raise ValueError("❌ JSON file path cannot be empty.")
|
|
213
211
|
|
|
214
|
-
with open(self.json_file) as f:
|
|
212
|
+
with open(self.json_file, encoding="utf-8") as f:
|
|
215
213
|
self.json = json.load(f)
|
|
216
214
|
|
|
217
215
|
self.pr_info = {"Occupancy": 0, "Available": 0} # Dictionary for parking information
|
|
@@ -221,19 +219,19 @@ class ParkingManagement(BaseSolution):
|
|
|
221
219
|
self.dc = (255, 0, 189) # Centroid color for each box
|
|
222
220
|
|
|
223
221
|
def process(self, im0: np.ndarray) -> SolutionResults:
|
|
224
|
-
"""
|
|
225
|
-
Process the input image for parking lot management and visualization.
|
|
222
|
+
"""Process the input image for parking lot management and visualization.
|
|
226
223
|
|
|
227
|
-
This function analyzes the input image, extracts tracks, and determines the occupancy status of parking
|
|
228
|
-
|
|
229
|
-
|
|
224
|
+
This function analyzes the input image, extracts tracks, and determines the occupancy status of parking regions
|
|
225
|
+
defined in the JSON file. It annotates the image with occupied and available parking spots, and updates the
|
|
226
|
+
parking information.
|
|
230
227
|
|
|
231
228
|
Args:
|
|
232
229
|
im0 (np.ndarray): The input inference image.
|
|
233
230
|
|
|
234
231
|
Returns:
|
|
235
232
|
(SolutionResults): Contains processed image `plot_im`, 'filled_slots' (number of occupied parking slots),
|
|
236
|
-
'available_slots' (number of available parking slots), and 'total_tracks' (total number of
|
|
233
|
+
'available_slots' (number of available parking slots), and 'total_tracks' (total number of
|
|
234
|
+
tracked objects).
|
|
237
235
|
|
|
238
236
|
Examples:
|
|
239
237
|
>>> parking_manager = ParkingManagement(json_file="parking_regions.json")
|
|
@@ -241,28 +239,32 @@ class ParkingManagement(BaseSolution):
|
|
|
241
239
|
>>> results = parking_manager.process(image)
|
|
242
240
|
"""
|
|
243
241
|
self.extract_tracks(im0) # Extract tracks from im0
|
|
244
|
-
|
|
242
|
+
available_slots, occupied_slots = len(self.json), 0
|
|
245
243
|
annotator = SolutionAnnotator(im0, self.line_width) # Initialize annotator
|
|
246
244
|
|
|
247
245
|
for region in self.json:
|
|
248
246
|
# Convert points to a NumPy array with the correct dtype and reshape properly
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
region_polygon = np.array(region["points"], dtype=np.int32).reshape((-1, 1, 2))
|
|
248
|
+
region_occupied = False
|
|
251
249
|
for box, cls in zip(self.boxes, self.clss):
|
|
252
250
|
xc, yc = int((box[0] + box[2]) / 2), int((box[1] + box[3]) / 2)
|
|
253
|
-
|
|
254
|
-
if
|
|
251
|
+
inside_distance = cv2.pointPolygonTest(region_polygon, (xc, yc), False)
|
|
252
|
+
if inside_distance >= 0:
|
|
255
253
|
# cv2.circle(im0, (xc, yc), radius=self.line_width * 4, color=self.dc, thickness=-1)
|
|
256
254
|
annotator.display_objects_labels(
|
|
257
255
|
im0, self.model.names[int(cls)], (104, 31, 17), (255, 255, 255), xc, yc, 10
|
|
258
256
|
)
|
|
259
|
-
|
|
257
|
+
region_occupied = True
|
|
260
258
|
break
|
|
261
|
-
|
|
259
|
+
if region_occupied:
|
|
260
|
+
occupied_slots += 1
|
|
261
|
+
available_slots -= 1
|
|
262
262
|
# Plot regions
|
|
263
|
-
cv2.polylines(
|
|
263
|
+
cv2.polylines(
|
|
264
|
+
im0, [region_polygon], isClosed=True, color=self.occ if region_occupied else self.arc, thickness=2
|
|
265
|
+
)
|
|
264
266
|
|
|
265
|
-
self.pr_info["Occupancy"], self.pr_info["Available"] =
|
|
267
|
+
self.pr_info["Occupancy"], self.pr_info["Available"] = occupied_slots, available_slots
|
|
266
268
|
|
|
267
269
|
annotator.display_analytics(im0, self.pr_info, (104, 31, 17), (255, 255, 255), 10)
|
|
268
270
|
|
|
@@ -7,15 +7,14 @@ from ultralytics.utils.plotting import colors
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class QueueManager(BaseSolution):
|
|
10
|
-
"""
|
|
11
|
-
Manages queue counting in real-time video streams based on object tracks.
|
|
10
|
+
"""Manages queue counting in real-time video streams based on object tracks.
|
|
12
11
|
|
|
13
|
-
This class extends BaseSolution to provide functionality for tracking and counting objects within a specified
|
|
14
|
-
|
|
12
|
+
This class extends BaseSolution to provide functionality for tracking and counting objects within a specified region
|
|
13
|
+
in video frames.
|
|
15
14
|
|
|
16
15
|
Attributes:
|
|
17
16
|
counts (int): The current count of objects in the queue.
|
|
18
|
-
rect_color (tuple[int, int, int]):
|
|
17
|
+
rect_color (tuple[int, int, int]): BGR color tuple for drawing the queue region rectangle.
|
|
19
18
|
region_length (int): The number of points defining the queue region.
|
|
20
19
|
track_line (list[tuple[int, int]]): List of track line coordinates.
|
|
21
20
|
track_history (dict[int, list[tuple[int, int]]]): Dictionary storing tracking history for each object.
|
|
@@ -31,10 +30,10 @@ class QueueManager(BaseSolution):
|
|
|
31
30
|
>>> cap = cv2.VideoCapture("path/to/video.mp4")
|
|
32
31
|
>>> queue_manager = QueueManager(region=[100, 100, 200, 200, 300, 300])
|
|
33
32
|
>>> while cap.isOpened():
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
... success, im0 = cap.read()
|
|
34
|
+
... if not success:
|
|
35
|
+
... break
|
|
36
|
+
... results = queue_manager.process(im0)
|
|
38
37
|
"""
|
|
39
38
|
|
|
40
39
|
def __init__(self, **kwargs: Any) -> None:
|
|
@@ -46,8 +45,7 @@ class QueueManager(BaseSolution):
|
|
|
46
45
|
self.region_length = len(self.region) # Store region length for further usage
|
|
47
46
|
|
|
48
47
|
def process(self, im0) -> SolutionResults:
|
|
49
|
-
"""
|
|
50
|
-
Process queue management for a single frame of video.
|
|
48
|
+
"""Process queue management for a single frame of video.
|
|
51
49
|
|
|
52
50
|
Args:
|
|
53
51
|
im0 (np.ndarray): Input image for processing, typically a frame from a video stream.
|
|
@@ -83,7 +81,7 @@ class QueueManager(BaseSolution):
|
|
|
83
81
|
|
|
84
82
|
# Display queue counts
|
|
85
83
|
annotator.queue_counts_display(
|
|
86
|
-
f"Queue Counts : {
|
|
84
|
+
f"Queue Counts : {self.counts}",
|
|
87
85
|
points=self.region,
|
|
88
86
|
region_color=self.rect_color,
|
|
89
87
|
txt_color=(104, 31, 17),
|
|
@@ -11,8 +11,7 @@ from ultralytics.utils.plotting import colors
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class RegionCounter(BaseSolution):
|
|
14
|
-
"""
|
|
15
|
-
A class for real-time counting of objects within user-defined regions in a video stream.
|
|
14
|
+
"""A class for real-time counting of objects within user-defined regions in a video stream.
|
|
16
15
|
|
|
17
16
|
This class inherits from `BaseSolution` and provides functionality to define polygonal regions in a video frame,
|
|
18
17
|
track objects, and count those objects that pass through each defined region. Useful for applications requiring
|
|
@@ -21,8 +20,8 @@ class RegionCounter(BaseSolution):
|
|
|
21
20
|
Attributes:
|
|
22
21
|
region_template (dict): Template for creating new counting regions with default attributes including name,
|
|
23
22
|
polygon coordinates, and display colors.
|
|
24
|
-
counting_regions (list): List storing all defined regions, where each entry is based on `region_template`
|
|
25
|
-
|
|
23
|
+
counting_regions (list): List storing all defined regions, where each entry is based on `region_template` and
|
|
24
|
+
includes specific region settings like name, coordinates, and color.
|
|
26
25
|
region_counts (dict): Dictionary storing the count of objects for each named region.
|
|
27
26
|
|
|
28
27
|
Methods:
|
|
@@ -59,8 +58,7 @@ class RegionCounter(BaseSolution):
|
|
|
59
58
|
region_color: tuple[int, int, int],
|
|
60
59
|
text_color: tuple[int, int, int],
|
|
61
60
|
) -> dict[str, Any]:
|
|
62
|
-
"""
|
|
63
|
-
Add a new region to the counting list based on the provided template with specific attributes.
|
|
61
|
+
"""Add a new region to the counting list based on the provided template with specific attributes.
|
|
64
62
|
|
|
65
63
|
Args:
|
|
66
64
|
name (str): Name assigned to the new region.
|
|
@@ -69,7 +67,7 @@ class RegionCounter(BaseSolution):
|
|
|
69
67
|
text_color (tuple[int, int, int]): BGR color for the text within the region.
|
|
70
68
|
|
|
71
69
|
Returns:
|
|
72
|
-
(dict[str,
|
|
70
|
+
(dict[str, Any]): Region information including name, polygon, and display colors.
|
|
73
71
|
"""
|
|
74
72
|
region = self.region_template.copy()
|
|
75
73
|
region.update(
|
|
@@ -84,7 +82,7 @@ class RegionCounter(BaseSolution):
|
|
|
84
82
|
return region
|
|
85
83
|
|
|
86
84
|
def initialize_regions(self):
|
|
87
|
-
"""Initialize regions only once."""
|
|
85
|
+
"""Initialize regions from `self.region` only once."""
|
|
88
86
|
if self.region is None:
|
|
89
87
|
self.initialize_region()
|
|
90
88
|
if not isinstance(self.region, dict): # Ensure self.region is initialized and structured as a dictionary
|
|
@@ -94,15 +92,14 @@ class RegionCounter(BaseSolution):
|
|
|
94
92
|
region["prepared_polygon"] = self.prep(region["polygon"])
|
|
95
93
|
|
|
96
94
|
def process(self, im0: np.ndarray) -> SolutionResults:
|
|
97
|
-
"""
|
|
98
|
-
Process the input frame to detect and count objects within each defined region.
|
|
95
|
+
"""Process the input frame to detect and count objects within each defined region.
|
|
99
96
|
|
|
100
97
|
Args:
|
|
101
98
|
im0 (np.ndarray): Input image frame where objects and regions are annotated.
|
|
102
99
|
|
|
103
100
|
Returns:
|
|
104
|
-
(SolutionResults): Contains processed image `plot_im`, 'total_tracks' (int, total number of tracked
|
|
105
|
-
and 'region_counts' (dict, counts of objects per region).
|
|
101
|
+
(SolutionResults): Contains processed image `plot_im`, 'total_tracks' (int, total number of tracked
|
|
102
|
+
objects), and 'region_counts' (dict, counts of objects per region).
|
|
106
103
|
"""
|
|
107
104
|
self.extract_tracks(im0)
|
|
108
105
|
annotator = SolutionAnnotator(im0, line_width=self.line_width)
|
|
@@ -8,8 +8,7 @@ from ultralytics.utils.plotting import colors
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class SecurityAlarm(BaseSolution):
|
|
11
|
-
"""
|
|
12
|
-
A class to manage security alarm functionalities for real-time monitoring.
|
|
11
|
+
"""A class to manage security alarm functionalities for real-time monitoring.
|
|
13
12
|
|
|
14
13
|
This class extends the BaseSolution class and provides features to monitor objects in a frame, send email
|
|
15
14
|
notifications when specific thresholds are exceeded for total detections, and annotate the output frame for
|
|
@@ -35,8 +34,7 @@ class SecurityAlarm(BaseSolution):
|
|
|
35
34
|
"""
|
|
36
35
|
|
|
37
36
|
def __init__(self, **kwargs: Any) -> None:
|
|
38
|
-
"""
|
|
39
|
-
Initialize the SecurityAlarm class with parameters for real-time object monitoring.
|
|
37
|
+
"""Initialize the SecurityAlarm class with parameters for real-time object monitoring.
|
|
40
38
|
|
|
41
39
|
Args:
|
|
42
40
|
**kwargs (Any): Additional keyword arguments passed to the parent class.
|
|
@@ -49,16 +47,15 @@ class SecurityAlarm(BaseSolution):
|
|
|
49
47
|
self.from_email = ""
|
|
50
48
|
|
|
51
49
|
def authenticate(self, from_email: str, password: str, to_email: str) -> None:
|
|
52
|
-
"""
|
|
53
|
-
|
|
50
|
+
"""Authenticate the email server for sending alert notifications.
|
|
51
|
+
|
|
52
|
+
This method initializes a secure connection with the SMTP server and logs in using the provided credentials.
|
|
54
53
|
|
|
55
54
|
Args:
|
|
56
55
|
from_email (str): Sender's email address.
|
|
57
56
|
password (str): Password for the sender's email account.
|
|
58
57
|
to_email (str): Recipient's email address.
|
|
59
58
|
|
|
60
|
-
This method initializes a secure connection with the SMTP server and logs in using the provided credentials.
|
|
61
|
-
|
|
62
59
|
Examples:
|
|
63
60
|
>>> alarm = SecurityAlarm()
|
|
64
61
|
>>> alarm.authenticate("sender@example.com", "password123", "recipient@example.com")
|
|
@@ -72,16 +69,15 @@ class SecurityAlarm(BaseSolution):
|
|
|
72
69
|
self.from_email = from_email
|
|
73
70
|
|
|
74
71
|
def send_email(self, im0, records: int = 5) -> None:
|
|
75
|
-
"""
|
|
76
|
-
|
|
72
|
+
"""Send an email notification with an image attachment indicating the number of objects detected.
|
|
73
|
+
|
|
74
|
+
This method encodes the input image, composes the email message with details about the detection, and sends it
|
|
75
|
+
to the specified recipient.
|
|
77
76
|
|
|
78
77
|
Args:
|
|
79
78
|
im0 (np.ndarray): The input image or frame to be attached to the email.
|
|
80
79
|
records (int, optional): The number of detected objects to be included in the email message.
|
|
81
80
|
|
|
82
|
-
This method encodes the input image, composes the email message with details about the detection, and sends it
|
|
83
|
-
to the specified recipient.
|
|
84
|
-
|
|
85
81
|
Examples:
|
|
86
82
|
>>> alarm = SecurityAlarm()
|
|
87
83
|
>>> frame = cv2.imread("path/to/image.jpg")
|
|
@@ -102,7 +98,7 @@ class SecurityAlarm(BaseSolution):
|
|
|
102
98
|
message["Subject"] = "Security Alert"
|
|
103
99
|
|
|
104
100
|
# Add the text message body
|
|
105
|
-
message_body = f"Ultralytics
|
|
101
|
+
message_body = f"Ultralytics alert: {records} object(s) detected."
|
|
106
102
|
message.attach(MIMEText(message_body))
|
|
107
103
|
|
|
108
104
|
# Attach the image
|
|
@@ -117,8 +113,11 @@ class SecurityAlarm(BaseSolution):
|
|
|
117
113
|
LOGGER.error(f"Failed to send email: {e}")
|
|
118
114
|
|
|
119
115
|
def process(self, im0) -> SolutionResults:
|
|
120
|
-
"""
|
|
121
|
-
|
|
116
|
+
"""Monitor the frame, process object detections, and trigger alerts if thresholds are exceeded.
|
|
117
|
+
|
|
118
|
+
This method processes the input frame, extracts detections, annotates the frame with bounding boxes, and sends
|
|
119
|
+
an email notification if the number of detected objects surpasses the specified threshold and an alert has not
|
|
120
|
+
already been sent.
|
|
122
121
|
|
|
123
122
|
Args:
|
|
124
123
|
im0 (np.ndarray): The input image or frame to be processed and annotated.
|
|
@@ -127,10 +126,6 @@ class SecurityAlarm(BaseSolution):
|
|
|
127
126
|
(SolutionResults): Contains processed image `plot_im`, 'total_tracks' (total number of tracked objects) and
|
|
128
127
|
'email_sent' (whether an email alert was triggered).
|
|
129
128
|
|
|
130
|
-
This method processes the input frame, extracts detections, annotates the frame with bounding boxes, and sends
|
|
131
|
-
an email notification if the number of detected objects surpasses the specified threshold and an alert has not
|
|
132
|
-
already been sent.
|
|
133
|
-
|
|
134
129
|
Examples:
|
|
135
130
|
>>> alarm = SecurityAlarm()
|
|
136
131
|
>>> frame = cv2.imread("path/to/image.jpg")
|
|
@@ -18,8 +18,7 @@ os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" # Avoid OpenMP conflict on some sys
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class VisualAISearch:
|
|
21
|
-
"""
|
|
22
|
-
A semantic image search system that leverages OpenCLIP for generating high-quality image and text embeddings and
|
|
21
|
+
"""A semantic image search system that leverages OpenCLIP for generating high-quality image and text embeddings and
|
|
23
22
|
FAISS for fast similarity-based retrieval.
|
|
24
23
|
|
|
25
24
|
This class aligns image and text embeddings in a shared semantic space, enabling users to search large collections
|
|
@@ -78,15 +77,14 @@ class VisualAISearch:
|
|
|
78
77
|
|
|
79
78
|
def extract_image_feature(self, path: Path) -> np.ndarray:
|
|
80
79
|
"""Extract CLIP image embedding from the given image path."""
|
|
81
|
-
return self.model.encode_image(Image.open(path)).cpu().numpy()
|
|
80
|
+
return self.model.encode_image(Image.open(path)).detach().cpu().numpy()
|
|
82
81
|
|
|
83
82
|
def extract_text_feature(self, text: str) -> np.ndarray:
|
|
84
83
|
"""Extract CLIP text embedding from the given text query."""
|
|
85
|
-
return self.model.encode_text(self.model.tokenize([text])).cpu().numpy()
|
|
84
|
+
return self.model.encode_text(self.model.tokenize([text])).detach().cpu().numpy()
|
|
86
85
|
|
|
87
86
|
def load_or_build_index(self) -> None:
|
|
88
|
-
"""
|
|
89
|
-
Load existing FAISS index or build a new one from image features.
|
|
87
|
+
"""Load existing FAISS index or build a new one from image features.
|
|
90
88
|
|
|
91
89
|
Checks if FAISS index and image paths exist on disk. If found, loads them directly. Otherwise, builds a new
|
|
92
90
|
index by extracting features from all images in the data directory, normalizes the features, and saves both the
|
|
@@ -130,8 +128,7 @@ class VisualAISearch:
|
|
|
130
128
|
LOGGER.info(f"Indexed {len(self.image_paths)} images.")
|
|
131
129
|
|
|
132
130
|
def search(self, query: str, k: int = 30, similarity_thresh: float = 0.1) -> list[str]:
|
|
133
|
-
"""
|
|
134
|
-
Return top-k semantically similar images to the given query.
|
|
131
|
+
"""Return top-k semantically similar images to the given query.
|
|
135
132
|
|
|
136
133
|
Args:
|
|
137
134
|
query (str): Natural language text query to search for.
|
|
@@ -167,11 +164,10 @@ class VisualAISearch:
|
|
|
167
164
|
|
|
168
165
|
|
|
169
166
|
class SearchApp:
|
|
170
|
-
"""
|
|
171
|
-
A Flask-based web interface for semantic image search with natural language queries.
|
|
167
|
+
"""A Flask-based web interface for semantic image search with natural language queries.
|
|
172
168
|
|
|
173
|
-
This class provides a clean, responsive frontend that enables users to input natural language queries and
|
|
174
|
-
|
|
169
|
+
This class provides a clean, responsive frontend that enables users to input natural language queries and instantly
|
|
170
|
+
view the most relevant images retrieved from the indexed database.
|
|
175
171
|
|
|
176
172
|
Attributes:
|
|
177
173
|
render_template: Flask template rendering function.
|
|
@@ -189,9 +185,8 @@ class SearchApp:
|
|
|
189
185
|
>>> app.run(debug=True)
|
|
190
186
|
"""
|
|
191
187
|
|
|
192
|
-
def __init__(self, data: str = "images", device: str = None) -> None:
|
|
193
|
-
"""
|
|
194
|
-
Initialize the SearchApp with VisualAISearch backend.
|
|
188
|
+
def __init__(self, data: str = "images", device: str | None = None) -> None:
|
|
189
|
+
"""Initialize the SearchApp with VisualAISearch backend.
|
|
195
190
|
|
|
196
191
|
Args:
|
|
197
192
|
data (str, optional): Path to directory containing images to index and search.
|