opsci-toolbox 0.0.5__py3-none-any.whl → 0.0.6__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.
@@ -4,7 +4,7 @@ import supervision as sv
4
4
  import cv2
5
5
  import numpy as np
6
6
 
7
- def open_image(image_path):
7
+ def open_image(image_path: str) -> Image:
8
8
  """
9
9
  Open and return an image.
10
10
 
@@ -22,32 +22,42 @@ def open_image(image_path):
22
22
  print(f"Error opening image: {e}")
23
23
  return None
24
24
 
25
- def save_image(image, output_path, name):
25
+ def save_image(image: Image, output_path: str, name: str) -> str:
26
26
  """
27
27
  Save an image to the local disk.
28
28
 
29
29
  Parameters:
30
30
  - image (Image object): The image to be saved.
31
31
  - output_path (str): The path to save the image.
32
+ - name (str): The name of the saved image file.
32
33
 
33
34
  Returns:
34
- - bool: True if saving is successful, False otherwise.
35
+ - str: The file path where the image is saved, or an error message if saving fails.
35
36
  """
36
37
  try:
37
38
  # Save the image to the specified path
38
- file_path=os.path.join(output_path, name)
39
+ file_path = os.path.join(output_path, name)
39
40
  image.save(file_path)
40
41
  return file_path
41
42
  except Exception as e:
42
43
  print(f"Error saving image: {e}")
43
- return False
44
+ return str(e)
44
45
 
45
- def convert_image_format(input_path, output_path, output_filename, output_format="JPEG"):
46
+ def convert_image_format(input_path: str, output_path: str, output_filename: str, output_format: str = "JPEG") -> str:
46
47
  """
47
- Convert an image to another image format (ex from PNG to JPEG)
48
+ Convert an image to another image format (e.g., from PNG to JPEG).
49
+
50
+ Parameters:
51
+ - input_path (str): The path to the input image file.
52
+ - output_path (str): The path to save the converted image.
53
+ - output_filename (str): The name of the converted image file.
54
+ - output_format (str): The format to which the image should be converted. Default is "JPEG".
55
+
56
+ Returns:
57
+ - str: The file path where the converted image is saved, or an error message if conversion fails.
48
58
  """
49
59
  try:
50
- file_path=os.path.join(output_path, output_filename+"."+output_format)
60
+ file_path = os.path.join(output_path, output_filename + "." + output_format)
51
61
  # Open the input image
52
62
  with Image.open(input_path) as img:
53
63
  # Convert and save the image to the desired format
@@ -55,67 +65,64 @@ def convert_image_format(input_path, output_path, output_filename, output_format
55
65
  print(f"Image converted successfully: {file_path}")
56
66
  except Exception as e:
57
67
  print(f"Error converting image: {e}")
68
+ return str(e)
58
69
 
59
70
  return file_path
60
71
 
61
- def resize_image(image, new_width, new_height):
72
+ def resize_image(image: Image, new_width: int, new_height: int) -> Image:
62
73
  """
63
74
  Resize an image to the specified width and height.
64
75
 
65
76
  Parameters:
66
- - image : PIL image
77
+ - image (PIL.Image.Image): The PIL image object to be resized.
67
78
  - new_width (int): The desired width of the resized image.
68
79
  - new_height (int): The desired height of the resized image.
69
80
 
70
81
  Returns:
71
- - Image object: The resized image.
82
+ - PIL.Image.Image: The resized image.
72
83
  """
73
84
  try:
74
- # Open the image file
75
-
85
+ # Resize the image
76
86
  resized_img = image.resize((new_width, new_height))
77
-
78
87
  return resized_img
79
88
  except Exception as e:
80
89
  print(f"Error resizing image: {e}")
81
90
  return None
82
91
 
83
- def crop_image(image, x, y, width, height):
92
+ def crop_image(image: Image, x: int, y: int, width: int, height: int) -> Image:
84
93
  """
85
94
  Crop an image based on the specified coordinates and dimensions.
86
95
 
87
96
  Parameters:
88
- - image : PIL image
97
+ - image (PIL.Image.Image): The PIL image object to be cropped.
89
98
  - x (int): The x-coordinate of the top-left corner of the cropping region.
90
99
  - y (int): The y-coordinate of the top-left corner of the cropping region.
91
100
  - width (int): The width of the cropping region.
92
101
  - height (int): The height of the cropping region.
93
102
 
94
103
  Returns:
95
- - Image object: The cropped image.
104
+ - PIL.Image.Image: The cropped image.
96
105
  """
97
106
  try:
98
107
  # Crop the image
99
108
  cropped_img = image.crop((x, y, x + width, y + height))
100
-
101
109
  return cropped_img
102
110
  except Exception as e:
103
111
  print(f"Error cropping image: {e}")
104
112
  return None
105
113
 
106
- def flip_image(image, direction='horizontal'):
114
+ def flip_image(image: Image, direction: str = 'horizontal') -> Image:
107
115
  """
108
116
  Flip an image horizontally or vertically.
109
117
 
110
118
  Parameters:
111
- - image : PIL image
112
- - direction (str): The direction of the flip ('horizontal' or 'vertical').
119
+ - image (PIL.Image.Image): The PIL image object to be flipped.
120
+ - direction (str): The direction of the flip ('horizontal' or 'vertical'). Default is 'horizontal'.
113
121
 
114
122
  Returns:
115
- - Image object: The flipped image.
123
+ - PIL.Image.Image: The flipped image.
116
124
  """
117
125
  try:
118
-
119
126
  # Flip the image
120
127
  if direction == 'horizontal':
121
128
  flipped_img = image.transpose(Image.FLIP_LEFT_RIGHT)
@@ -130,145 +137,214 @@ def flip_image(image, direction='horizontal'):
130
137
  print(f"Error flipping image: {e}")
131
138
  return None
132
139
 
133
-
134
- def rotate_image(image, angle):
140
+ def rotate_image(image: Image, angle: float) -> Image:
135
141
  """
136
142
  Rotate an image by the given angle (in degrees).
137
143
 
138
144
  Parameters:
139
- - image : PIL image
145
+ - image (PIL.Image.Image): The PIL image object to be rotated.
140
146
  - angle (float): The angle by which to rotate the image (in degrees).
141
147
 
142
148
  Returns:
143
- - Image object: The rotated image.
149
+ - PIL.Image.Image: The rotated image.
144
150
  """
145
151
  try:
146
-
147
152
  # Rotate the image
148
153
  rotated_img = image.rotate(angle)
149
-
150
154
  return rotated_img
151
155
  except Exception as e:
152
156
  print(f"Error rotating image: {e}")
153
157
  return None
154
158
 
155
- def convert_to_grayscale(image):
159
+ def convert_to_grayscale(image: Image) -> Image:
156
160
  """
157
161
  Convert a color image to grayscale.
158
162
 
159
163
  Parameters:
160
- - image : PIL image
164
+ - image (PIL.Image.Image): The PIL image object to be converted.
161
165
 
162
166
  Returns:
163
- - Image object: The grayscale image.
167
+ - PIL.Image.Image: The grayscale image.
164
168
  """
165
169
  try:
166
-
167
170
  # Convert the image to grayscale
168
171
  grayscale_img = image.convert("L")
169
-
170
172
  return grayscale_img
171
173
  except Exception as e:
172
174
  print(f"Error converting image to grayscale: {e}")
173
175
  return None
174
-
175
- def PIL_get_image_size(image):
176
+
177
+ def PIL_get_image_size(image: Image) -> tuple:
176
178
  """
177
- Get PILLOW image size
179
+ Get PILLOW image size.
180
+
181
+ Parameters:
182
+ - image (PIL.Image.Image): The PIL image object.
183
+
184
+ Returns:
185
+ - tuple: A tuple containing the width and height of the image.
178
186
  """
179
187
  width, height = image.size
180
- return width, height
188
+ return width, height
181
189
 
182
- def cv_get_image_size(image):
190
+ def cv_get_image_size(image) -> tuple:
183
191
  """
184
- Get cv2 image size
192
+ Get cv2 image size.
193
+
194
+ Parameters:
195
+ - image: The cv2 image array.
196
+
197
+ Returns:
198
+ - tuple: A tuple containing the width and height of the image.
185
199
  """
186
200
  height, width, _ = image.shape
187
201
  return width, height
188
202
 
189
- def convert_PIL_to_cv(image):
203
+ def convert_PIL_to_cv(image: Image) -> np.ndarray:
190
204
  """
191
- Convert an image from Pillow to CV2
205
+ Convert an image from Pillow to CV2.
206
+
207
+ Parameters:
208
+ - image (PIL.Image.Image): The PIL image object.
209
+
210
+ Returns:
211
+ - numpy.ndarray: The converted cv2 image array.
192
212
  """
193
213
  numpy_array = np.array(image)
194
214
  cv2_image = cv2.cvtColor(numpy_array, cv2.COLOR_RGB2BGR)
195
215
  return cv2_image
196
216
 
197
- def convert_cv2_to_pil(cv2_image):
217
+ def convert_cv2_to_pil(cv2_image: np.ndarray) -> Image:
198
218
  """
199
- Convert an image from CV2 to Pillow
219
+ Convert an image from OpenCV format (BGR) to Pillow format (RGB).
220
+
221
+ Args:
222
+ cv2_image (np.ndarray): The input image in OpenCV format (BGR).
223
+
224
+ Returns:
225
+ Image.Image: The converted image in Pillow format (RGB).
200
226
  """
201
- # Convert the cv2 image to RGB format
227
+ # Convert the OpenCV image from BGR to RGB format
202
228
  rgb_image = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB)
203
229
 
204
- # Create a PIL Image from the RGB image
230
+ # Create a Pillow Image from the RGB image
205
231
  pil_image = Image.fromarray(rgb_image)
206
232
 
207
233
  return pil_image
208
234
 
209
- def compress_image(image, output_path, name, quality):
235
+ def compress_image(image: Image, output_path: str, name: str, quality: int) -> str:
210
236
  """
211
237
  Compress an image with a specified quality level.
212
238
 
213
- Parameters:
214
- - image object
215
- - output_path (str): The path to save the compressed image.
216
- - name of the file
217
- - quality (int): The quality level for compression (0 to 100, higher is better).
239
+ Args:
240
+ image (Image.Image): The image object to be compressed.
241
+ output_path (str): The directory path where the compressed image will be saved.
242
+ name (str): The name of the compressed image file.
243
+ quality (int): The quality level for compression (0 to 100, higher is better).
218
244
 
219
245
  Returns:
220
- - file_path
246
+ str: The file path of the compressed image, or an empty string if an error occurred.
221
247
  """
222
248
  try:
223
- # Open the image file
224
- file_path=os.path.join(output_path, name)
249
+ # Create the file path by joining the output path and file name
250
+ file_path = os.path.join(output_path, name)
251
+
252
+ # Save the image with the specified quality
225
253
  image.save(file_path, quality=quality)
226
-
254
+
227
255
  return file_path
228
256
  except Exception as e:
229
257
  print(f"Error compressing image: {e}")
230
- return False
258
+ return ""
231
259
 
232
260
 
233
- def cv2_read_image(path):
261
+ def cv2_read_image(path: str) -> np.ndarray:
234
262
  """
235
- Read an image file
263
+ Read an image file using OpenCV.
264
+
265
+ Args:
266
+ path (str): The file path to the image.
267
+
268
+ Returns:
269
+ np.ndarray: The image read by OpenCV as a NumPy array.
236
270
  """
271
+ # Read the image from the given path
237
272
  image = cv2.imread(path)
238
273
  return image
239
274
 
240
- def cv2_write_image(image, path, name):
275
+ def cv2_write_image(image: np.ndarray, path: str, name: str) -> str:
241
276
  """
242
- Write an image file
277
+ Write an image to a file using OpenCV.
278
+
279
+ Args:
280
+ image (np.ndarray): The image to be saved.
281
+ path (str): The directory path where the image will be saved.
282
+ name (str): The name of the image file.
283
+
284
+ Returns:
285
+ str: The file path of the saved image.
243
286
  """
244
- file_path=os.path.join(path, name)
287
+ # Create the file path by joining the directory path and file name
288
+ file_path = os.path.join(path, name)
289
+
290
+ # Write the image to the specified file path
245
291
  cv2.imwrite(file_path, image)
292
+
246
293
  return file_path
247
294
 
248
- def cv2_crop_image(image, xmin, ymin, xmax, ymax):
295
+ def cv2_crop_image(image: np.ndarray, xmin: int, ymin: int, xmax: int, ymax: int) -> np.ndarray:
249
296
  """
250
- Crop image by coordinates
297
+ Crop an image by specified coordinates.
298
+
299
+ Args:
300
+ image (np.ndarray): The input image to be cropped.
301
+ xmin (int): The minimum x-coordinate (left).
302
+ ymin (int): The minimum y-coordinate (top).
303
+ xmax (int): The maximum x-coordinate (right).
304
+ ymax (int): The maximum y-coordinate (bottom).
305
+
306
+ Returns:
307
+ np.ndarray: The cropped image.
251
308
  """
252
- cropped_img=image[ymin:ymax, xmin:xmax]
309
+ # Crop the image using the provided coordinates
310
+ cropped_img = image[ymin:ymax, xmin:xmax]
253
311
  return cropped_img
254
312
 
255
- def cv2_flip(image, direction='horizontal'):
313
+ def cv2_flip(image: np.ndarray, direction: str = 'horizontal') -> np.ndarray:
256
314
  """
257
- Flip an image using CV2
315
+ Flip an image either horizontally or vertically using OpenCV.
316
+
317
+ Args:
318
+ image (np.ndarray): The input image to be flipped.
319
+ direction (str): The direction to flip the image, either 'horizontal' or 'vertical'.
320
+ Default is 'horizontal'.
321
+
322
+ Returns:
323
+ np.ndarray: The flipped image.
324
+
325
+ Raises:
326
+ ValueError: If the direction is neither 'horizontal' nor 'vertical'.
258
327
  """
259
- if direction=='horizontal':
328
+ if direction == 'horizontal':
260
329
  flipped_image = cv2.flip(image, 1)
261
- elif direction=='vertical':
330
+ elif direction == 'vertical':
262
331
  flipped_image = cv2.flip(image, 0)
263
332
  else:
264
- print("error - direction should be horizontal or vertical")
333
+ raise ValueError("Direction should be 'horizontal' or 'vertical'")
334
+
265
335
  return flipped_image
266
336
 
267
- def cv2_rotate_image(image, angle):
268
- """
269
- Rotate an image using CV2
337
+ def cv2_rotate_image(image: np.ndarray, angle: float) -> np.ndarray:
270
338
  """
339
+ Rotate an image by a specified angle using OpenCV.
340
+
341
+ Args:
342
+ image (np.ndarray): The input image to be rotated.
343
+ angle (float): The angle by which to rotate the image (in degrees).
271
344
 
345
+ Returns:
346
+ np.ndarray: The rotated image.
347
+ """
272
348
  # Get the height and width of the image
273
349
  height, width = image.shape[:2]
274
350
 
@@ -280,28 +356,57 @@ def cv2_rotate_image(image, angle):
280
356
 
281
357
  return rotated_image
282
358
 
283
- def cv2_convert_to_grayscale(image):
284
- """
285
- Convert an image to grayscale using CV2
359
+ def cv2_convert_to_grayscale(image: np.ndarray) -> np.ndarray:
286
360
  """
361
+ Convert an image to grayscale using OpenCV.
287
362
 
363
+ Args:
364
+ image (np.ndarray): The input image to be converted.
365
+
366
+ Returns:
367
+ np.ndarray: The grayscale image.
368
+ """
288
369
  # Convert the image to grayscale
289
370
  grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
290
371
 
291
372
  return grayscale_image
292
373
 
293
- def draw_circle(image, x, y, size=5, color=(255, 0, 0)):
374
+ def draw_circle(image: np.ndarray, x: int, y: int, size: int = 5, color: tuple = (255, 0, 0)) -> np.ndarray:
294
375
  """
295
- Draw a circle on a CV2 image
376
+ Draw a circle on an OpenCV image.
377
+
378
+ Args:
379
+ image (np.ndarray): The input image on which to draw the circle.
380
+ x (int): The x-coordinate of the center of the circle.
381
+ y (int): The y-coordinate of the center of the circle.
382
+ size (int, optional): The radius of the circle. Default is 5.
383
+ color (tuple, optional): The color of the circle in RGB format. Default is red (255, 0, 0).
384
+
385
+ Returns:
386
+ np.ndarray: The image with the circle drawn on it.
296
387
  """
388
+ # Convert the image from BGR to RGB color space
297
389
  image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
298
- image_with_circle=cv2.circle(image_rgb, (x,y), size, color, -1)
390
+
391
+ # Draw the circle on the RGB image
392
+ image_with_circle = cv2.circle(image_rgb, (x, y), size, color, -1)
393
+
299
394
  return image_with_circle
300
395
 
301
396
 
302
- def apply_mask(image, mask, color_mask=[255, 255, 255], reverse=True, transparency=1.0):
397
+ def apply_mask(image: np.ndarray, mask: np.ndarray, color_mask: list = [255, 255, 255], reverse: bool = True, transparency: float = 1.0) -> np.ndarray:
303
398
  """
304
- Apply a transparent color mask on an image
399
+ Apply a transparent color mask on an image.
400
+
401
+ Args:
402
+ image (np.ndarray): The input image to which the mask will be applied.
403
+ mask (np.ndarray): The binary mask indicating where to apply the color mask.
404
+ color_mask (list, optional): The RGB color to use for the mask. Default is white [255, 255, 255].
405
+ reverse (bool, optional): If True, apply the color mask where the mask is False; otherwise, apply where True. Default is True.
406
+ transparency (float, optional): The transparency level of the color mask (0.0 to 1.0). Default is 1.0 (opaque).
407
+
408
+ Returns:
409
+ np.ndarray: The image with the color mask applied.
305
410
  """
306
411
  # Validate transparency value
307
412
  transparency = max(0.0, min(1.0, transparency))
@@ -315,53 +420,84 @@ def apply_mask(image, mask, color_mask=[255, 255, 255], reverse=True, transparen
315
420
  # Set the alpha channel of the color_mask
316
421
  color_mask_with_alpha = color_mask + [alpha]
317
422
 
318
- # Create a mask for the region where the color_mask will be applied
319
- region_mask = np.stack([mask] * 3, axis=-1)
423
+ # Ensure the mask is a binary mask with the same dimensions as the image
424
+ if mask.ndim == 2:
425
+ mask = mask[:, :, np.newaxis]
320
426
 
321
427
  if reverse:
322
- # Set the color_mask with alpha where the mask is False
323
- masked_image[~region_mask] = color_mask_with_alpha
428
+ # Apply the color mask where the mask is False
429
+ masked_image[mask == 0] = color_mask_with_alpha
324
430
  else:
325
- # Set the color_mask with alpha where the mask is True
326
- masked_image[region_mask] = color_mask_with_alpha
431
+ # Apply the color mask where the mask is True
432
+ masked_image[mask != 0] = color_mask_with_alpha
327
433
 
328
434
  return masked_image
329
435
 
330
-
331
- def transform_coordinates_CV_to_YOLO(left, top, width, height):
436
+ def transform_coordinates_CV_to_YOLO(left: float, top: float, width: float, height: float) -> tuple:
332
437
  """
333
- Transform MS Custom Vision annotation format to YOLO
438
+ Transform MS Custom Vision annotation format to YOLO format.
439
+
440
+ Args:
441
+ left (float): The x-coordinate of the top-left corner of the bounding box.
442
+ top (float): The y-coordinate of the top-left corner of the bounding box.
443
+ width (float): The width of the bounding box.
444
+ height (float): The height of the bounding box.
445
+
446
+ Returns:
447
+ tuple: A tuple containing the transformed coordinates in YOLO format (center_x, center_y, width, height).
334
448
  """
449
+ # Calculate the center coordinates
450
+ center_x = left + (width / 2)
451
+ center_y = top + (height / 2)
335
452
 
336
- center_x = left + (width/2)
337
- center_y = top + (height/2)
338
453
  return (center_x, center_y, width, height)
339
454
 
340
455
 
341
- def transform_coordinates_PascalVOC_to_YOLO(xmin, ymin, xmax, ymax, width, height):
456
+ def transform_coordinates_PascalVOC_to_YOLO(xmin: float, ymin: float, xmax: float, ymax: float, width: float, height: float) -> tuple:
342
457
  """
343
- Transform PascalVOC coordinates to YOLO
458
+ Transform PascalVOC coordinates to YOLO format.
459
+
460
+ Args:
461
+ xmin (float): The minimum x-coordinate (left boundary) of the bounding box.
462
+ ymin (float): The minimum y-coordinate (top boundary) of the bounding box.
463
+ xmax (float): The maximum x-coordinate (right boundary) of the bounding box.
464
+ ymax (float): The maximum y-coordinate (bottom boundary) of the bounding box.
465
+ width (float): The width of the image.
466
+ height (float): The height of the image.
467
+
468
+ Returns:
469
+ tuple: A tuple containing the transformed coordinates in YOLO format (x_center, y_center, box_width, box_height).
344
470
  """
471
+ # Calculate the center x-coordinate of the bounding box in YOLO format
345
472
  x_center = ((xmax + xmin) / 2) / width
473
+
474
+ # Calculate the center y-coordinate of the bounding box in YOLO format
346
475
  y_center = ((ymax + ymin) / 2) / height
476
+
477
+ # Calculate the width of the bounding box in YOLO format
347
478
  box_width = (xmax - xmin) / width
479
+
480
+ # Calculate the height of the bounding box in YOLO format
348
481
  box_height = (ymax - ymin) / height
482
+
349
483
  return (x_center, y_center, box_width, box_height)
350
484
 
351
485
 
352
- def transform_coordinates_YOLO_to_PascalVOC(center_x, center_y, width, height, image_width, image_height):
486
+ def transform_coordinates_YOLO_to_PascalVOC(center_x: float, center_y: float, width: float, height: float, image_width: int, image_height: int) -> tuple:
353
487
  """
354
488
  Convert YOLO coordinates to Pascal VOC format.
355
489
 
356
- Parameters:
357
- - YOLO format coordinates center_x, center_y, width, height
358
- - image_width (int): Width of the image
359
- - image_height (int): Height of the image
490
+ Args:
491
+ center_x (float): The x-coordinate of the center of the bounding box (YOLO format).
492
+ center_y (float): The y-coordinate of the center of the bounding box (YOLO format).
493
+ width (float): The width of the bounding box (YOLO format).
494
+ height (float): The height of the bounding box (YOLO format).
495
+ image_width (int): The width of the image.
496
+ image_height (int): The height of the image.
360
497
 
361
498
  Returns:
362
- - tuple: Pascal VOC coordinates (xmin, ymin, xmax, ymax)
499
+ tuple: Pascal VOC coordinates (xmin, ymin, xmax, ymax).
363
500
  """
364
-
365
501
  # Convert YOLO coordinates to absolute coordinates
366
502
  abs_x = int(center_x * image_width)
367
503
  abs_y = int(center_y * image_height)
@@ -377,58 +513,97 @@ def transform_coordinates_YOLO_to_PascalVOC(center_x, center_y, width, height, i
377
513
  return xmin, ymin, xmax, ymax
378
514
 
379
515
 
380
-
381
- def sv_detections_ultralytics(results):
516
+ def sv_detections_ultralytics(results) -> sv.Detections:
382
517
  """
383
- Loads detections from results
518
+ Load detections from Ultralytics results.
519
+
520
+ Args:
521
+ results: The results object from Ultralytics containing detection data.
522
+
523
+ Returns:
524
+ sv.Detections: An object containing the loaded detections.
384
525
  """
385
526
  detections = sv.Detections.from_ultralytics(results)
386
527
  return detections
387
528
 
388
- def sv_convert_mask_to_box(masks):
529
+ def sv_convert_mask_to_box(masks) -> sv.Detections:
389
530
  """
390
- Convert mask coordinates to boxes
531
+ Convert mask coordinates to bounding boxes.
532
+
533
+ Args:
534
+ masks: The mask data from which to derive bounding boxes.
535
+
536
+ Returns:
537
+ sv.Detections: An object containing the bounding boxes and original masks.
391
538
  """
392
539
  detections = sv.Detections(
393
- xyxy=sv.mask_to_xyxy(masks=masks),
394
- mask=masks
540
+ xyxy=sv.mask_to_xyxy(masks=masks),
541
+ mask=masks
395
542
  )
396
543
  return detections
397
544
 
398
-
399
- def sv_annotate_image_bbox(image, detections):
545
+ def sv_annotate_image_bbox(image: np.ndarray, detections: sv.Detections) -> np.ndarray:
400
546
  """
401
- Draw a bounding box
547
+ Draw bounding boxes on an image.
548
+
549
+ Args:
550
+ image (np.ndarray): The input image on which to draw the bounding boxes.
551
+ detections (sv.Detections): The detections containing bounding box information.
552
+
553
+ Returns:
554
+ np.ndarray: The annotated image with bounding boxes drawn.
402
555
  """
403
556
  bounding_box_annotator = sv.BoundingBoxAnnotator()
404
557
  annotated_image = bounding_box_annotator.annotate(scene=image, detections=detections)
405
558
  return annotated_image
406
559
 
407
-
408
- def sv_annotate_image_mask(image, detections):
560
+ def sv_annotate_image_mask(image: np.ndarray, detections: sv.Detections) -> np.ndarray:
409
561
  """
410
- Draw a mask area on an image
562
+ Draw mask areas on an image.
563
+
564
+ Args:
565
+ image (np.ndarray): The input image on which to draw the mask areas.
566
+ detections (sv.Detections): The detections containing mask information.
567
+
568
+ Returns:
569
+ np.ndarray: The annotated image with mask areas drawn.
411
570
  """
412
571
  mask_annotator = sv.MaskAnnotator()
413
572
  annotated_image = mask_annotator.annotate(scene=image, detections=detections)
414
573
  return annotated_image
415
574
 
416
- def sv_annotate_image_label(image, detections, model, color=sv.Color.ROBOFLOW, text_color=sv.Color.WHITE, text_position=sv.Position.TOP_CENTER):
417
- """
418
- Draw a label rectangle on detections
419
- """
420
- # possible values for colors : https://supervision.roboflow.com/latest/draw/color/#supervision.draw.color.Color
421
- # Possible positions for text relative to the detection = "CENTER" / "CENTER_LEFT" / "CENTER_RIGHT" / "TOP_CENTER"
422
- # "TOP_LEFT" / "TOP_RIGHT" / "BOTTOM_LEFT" / "BOTTOM_CENTER" / "BOTTOM_RIGHT" / "CENTER_OF_MASS"
575
+ def sv_annotate_image_label(
576
+ image: np.ndarray,
577
+ detections: sv.Detections,
578
+ model,
579
+ color: sv.Color = sv.Color.ROBOFLOW,
580
+ text_color: sv.Color = sv.Color.WHITE,
581
+ text_position: sv.Position = sv.Position.TOP_CENTER
582
+ ) -> np.ndarray:
583
+ """
584
+ Draw label rectangles on detections.
585
+
586
+ Args:
587
+ image (np.ndarray): The input image on which to draw the labels.
588
+ detections (sv.Detections): The detections containing information about the detected objects.
589
+ model: The model object containing the class names.
590
+ color (sv.Color, optional): The color for the label rectangles. Defaults to sv.Color.ROBOFLOW.
591
+ text_color (sv.Color, optional): The color for the text. Defaults to sv.Color.WHITE.
592
+ text_position (sv.Position, optional): The position of the text relative to the detection. Defaults to sv.Position.TOP_CENTER.
423
593
 
594
+ Returns:
595
+ np.ndarray: The annotated image with label rectangles drawn.
596
+ """
597
+ # Instantiate the LabelAnnotator with the specified colors and text position
424
598
  label_annotator = sv.LabelAnnotator(color=color, text_color=text_color, text_position=text_position)
425
599
 
600
+ # Extract the class names for each detected object
426
601
  labels = [
427
602
  model.model.names[class_id]
428
- for class_id
429
- in detections.class_id
603
+ for class_id in detections.class_id
430
604
  ]
431
605
 
606
+ # Annotate the image with the labels
432
607
  annotated_image = label_annotator.annotate(scene=image, detections=detections, labels=labels)
433
608
 
434
609
  return annotated_image