dgenerate-ultralytics-headless 8.3.153__py3-none-any.whl → 8.3.155__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.
Files changed (48) hide show
  1. {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/METADATA +1 -1
  2. {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/RECORD +48 -48
  3. tests/test_python.py +1 -0
  4. ultralytics/__init__.py +1 -1
  5. ultralytics/cfg/__init__.py +2 -0
  6. ultralytics/engine/predictor.py +1 -1
  7. ultralytics/engine/validator.py +0 -6
  8. ultralytics/models/fastsam/val.py +0 -2
  9. ultralytics/models/rtdetr/val.py +28 -16
  10. ultralytics/models/yolo/classify/val.py +26 -23
  11. ultralytics/models/yolo/detect/train.py +4 -7
  12. ultralytics/models/yolo/detect/val.py +88 -90
  13. ultralytics/models/yolo/obb/val.py +52 -44
  14. ultralytics/models/yolo/pose/train.py +1 -35
  15. ultralytics/models/yolo/pose/val.py +77 -176
  16. ultralytics/models/yolo/segment/train.py +1 -41
  17. ultralytics/models/yolo/segment/val.py +64 -176
  18. ultralytics/models/yolo/yoloe/val.py +2 -1
  19. ultralytics/nn/autobackend.py +2 -2
  20. ultralytics/nn/tasks.py +0 -1
  21. ultralytics/solutions/ai_gym.py +5 -5
  22. ultralytics/solutions/analytics.py +2 -2
  23. ultralytics/solutions/config.py +2 -2
  24. ultralytics/solutions/distance_calculation.py +1 -1
  25. ultralytics/solutions/heatmap.py +5 -3
  26. ultralytics/solutions/instance_segmentation.py +4 -2
  27. ultralytics/solutions/object_blurrer.py +4 -2
  28. ultralytics/solutions/object_counter.py +5 -5
  29. ultralytics/solutions/object_cropper.py +3 -2
  30. ultralytics/solutions/parking_management.py +9 -9
  31. ultralytics/solutions/queue_management.py +4 -2
  32. ultralytics/solutions/region_counter.py +13 -5
  33. ultralytics/solutions/security_alarm.py +6 -4
  34. ultralytics/solutions/similarity_search.py +6 -6
  35. ultralytics/solutions/solutions.py +9 -7
  36. ultralytics/solutions/speed_estimation.py +3 -2
  37. ultralytics/solutions/streamlit_inference.py +6 -6
  38. ultralytics/solutions/templates/similarity-search.html +31 -0
  39. ultralytics/solutions/trackzone.py +4 -2
  40. ultralytics/solutions/vision_eye.py +4 -2
  41. ultralytics/utils/callbacks/comet.py +1 -1
  42. ultralytics/utils/metrics.py +146 -317
  43. ultralytics/utils/ops.py +4 -4
  44. ultralytics/utils/plotting.py +31 -56
  45. {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/WHEEL +0 -0
  46. {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/entry_points.txt +0 -0
  47. {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/licenses/LICENSE +0 -0
  48. {dgenerate_ultralytics_headless-8.3.153.dist-info → dgenerate_ultralytics_headless-8.3.155.dist-info}/top_level.txt +0 -0
ultralytics/utils/ops.py CHANGED
@@ -255,7 +255,7 @@ def non_max_suppression(
255
255
 
256
256
  bs = prediction.shape[0] # batch size (BCN, i.e. 1,84,6300)
257
257
  nc = nc or (prediction.shape[1] - 4) # number of classes
258
- nm = prediction.shape[1] - nc - 4 # number of masks
258
+ extra = prediction.shape[1] - nc - 4 # number of extra info
259
259
  mi = 4 + nc # mask start index
260
260
  xc = prediction[:, 4:mi].amax(1) > conf_thres # candidates
261
261
  xinds = torch.stack([torch.arange(len(i), device=prediction.device) for i in xc])[..., None] # to track idxs
@@ -273,7 +273,7 @@ def non_max_suppression(
273
273
  prediction = torch.cat((xywh2xyxy(prediction[..., :4]), prediction[..., 4:]), dim=-1) # xywh to xyxy
274
274
 
275
275
  t = time.time()
276
- output = [torch.zeros((0, 6 + nm), device=prediction.device)] * bs
276
+ output = [torch.zeros((0, 6 + extra), device=prediction.device)] * bs
277
277
  keepi = [torch.zeros((0, 1), device=prediction.device)] * bs # to store the kept idxs
278
278
  for xi, (x, xk) in enumerate(zip(prediction, xinds)): # image index, (preds, preds indices)
279
279
  # Apply constraints
@@ -284,7 +284,7 @@ def non_max_suppression(
284
284
  # Cat apriori labels if autolabelling
285
285
  if labels and len(labels[xi]) and not rotated:
286
286
  lb = labels[xi]
287
- v = torch.zeros((len(lb), nc + nm + 4), device=x.device)
287
+ v = torch.zeros((len(lb), nc + extra + 4), device=x.device)
288
288
  v[:, :4] = xywh2xyxy(lb[:, 1:5]) # box
289
289
  v[range(len(lb)), lb[:, 0].long() + 4] = 1.0 # cls
290
290
  x = torch.cat((x, v), 0)
@@ -294,7 +294,7 @@ def non_max_suppression(
294
294
  continue
295
295
 
296
296
  # Detections matrix nx6 (xyxy, conf, cls)
297
- box, cls, mask = x.split((4, nc, nm), 1)
297
+ box, cls, mask = x.split((4, nc, extra), 1)
298
298
 
299
299
  if multi_label:
300
300
  i, j = torch.where(cls > conf_thres)
@@ -3,7 +3,7 @@
3
3
  import math
4
4
  import warnings
5
5
  from pathlib import Path
6
- from typing import Callable, Dict, List, Optional, Union
6
+ from typing import Any, Callable, Dict, List, Optional, Union
7
7
 
8
8
  import cv2
9
9
  import numpy as np
@@ -678,13 +678,8 @@ def save_one_box(
678
678
 
679
679
  @threaded
680
680
  def plot_images(
681
- images: Union[torch.Tensor, np.ndarray],
682
- batch_idx: Union[torch.Tensor, np.ndarray],
683
- cls: Union[torch.Tensor, np.ndarray],
684
- bboxes: Union[torch.Tensor, np.ndarray] = np.zeros(0, dtype=np.float32),
685
- confs: Optional[Union[torch.Tensor, np.ndarray]] = None,
686
- masks: Union[torch.Tensor, np.ndarray] = np.zeros(0, dtype=np.uint8),
687
- kpts: Union[torch.Tensor, np.ndarray] = np.zeros((0, 51), dtype=np.float32),
681
+ labels: Dict[str, Any],
682
+ images: Union[torch.Tensor, np.ndarray] = np.zeros((0, 3, 640, 640), dtype=np.float32),
688
683
  paths: Optional[List[str]] = None,
689
684
  fname: str = "images.jpg",
690
685
  names: Optional[Dict[int, str]] = None,
@@ -698,21 +693,16 @@ def plot_images(
698
693
  Plot image grid with labels, bounding boxes, masks, and keypoints.
699
694
 
700
695
  Args:
701
- images: Batch of images to plot. Shape: (batch_size, channels, height, width).
702
- batch_idx: Batch indices for each detection. Shape: (num_detections,).
703
- cls: Class labels for each detection. Shape: (num_detections,).
704
- bboxes: Bounding boxes for each detection. Shape: (num_detections, 4) or (num_detections, 5) for rotated boxes.
705
- confs: Confidence scores for each detection. Shape: (num_detections,).
706
- masks: Instance segmentation masks. Shape: (num_detections, height, width) or (1, height, width).
707
- kpts: Keypoints for each detection. Shape: (num_detections, 51).
708
- paths: List of file paths for each image in the batch.
709
- fname: Output filename for the plotted image grid.
710
- names: Dictionary mapping class indices to class names.
711
- on_plot: Optional callback function to be called after saving the plot.
712
- max_size: Maximum size of the output image grid.
713
- max_subplots: Maximum number of subplots in the image grid.
714
- save: Whether to save the plotted image grid to a file.
715
- conf_thres: Confidence threshold for displaying detections.
696
+ labels (Dict[str, Any]): Dictionary containing detection data with keys like 'cls', 'bboxes', 'conf', 'masks', 'keypoints', 'batch_idx', 'img'.
697
+ images (Union[torch.Tensor, np.ndarray]): Batch of images to plot. Shape: (batch_size, channels, height, width).
698
+ paths (Optional[List[str]]): List of file paths for each image in the batch.
699
+ fname (str): Output filename for the plotted image grid.
700
+ names (Optional[Dict[int, str]]): Dictionary mapping class indices to class names.
701
+ on_plot (Optional[Callable]): Optional callback function to be called after saving the plot.
702
+ max_size (int): Maximum size of the output image grid.
703
+ max_subplots (int): Maximum number of subplots in the image grid.
704
+ save (bool): Whether to save the plotted image grid to a file.
705
+ conf_thres (float): Confidence threshold for displaying detections.
716
706
 
717
707
  Returns:
718
708
  (np.ndarray): Plotted image grid as a numpy array if save is False, None otherwise.
@@ -721,18 +711,24 @@ def plot_images(
721
711
  This function supports both tensor and numpy array inputs. It will automatically
722
712
  convert tensor inputs to numpy arrays for processing.
723
713
  """
724
- if isinstance(images, torch.Tensor):
714
+ for k in {"cls", "bboxes", "conf", "masks", "keypoints", "batch_idx", "images"}:
715
+ if k not in labels:
716
+ continue
717
+ if k == "cls" and labels[k].ndim == 2:
718
+ labels[k] = labels[k].squeeze(1) # squeeze if shape is (n, 1)
719
+ if isinstance(labels[k], torch.Tensor):
720
+ labels[k] = labels[k].cpu().numpy()
721
+
722
+ cls = labels.get("cls", np.zeros(0, dtype=np.int64))
723
+ batch_idx = labels.get("batch_idx", np.zeros(cls.shape, dtype=np.int64))
724
+ bboxes = labels.get("bboxes", np.zeros(0, dtype=np.float32))
725
+ confs = labels.get("conf", None)
726
+ masks = labels.get("masks", np.zeros(0, dtype=np.uint8))
727
+ kpts = labels.get("keypoints", np.zeros(0, dtype=np.float32))
728
+ images = labels.get("img", images) # default to input images
729
+
730
+ if len(images) and isinstance(images, torch.Tensor):
725
731
  images = images.cpu().float().numpy()
726
- if isinstance(cls, torch.Tensor):
727
- cls = cls.cpu().numpy()
728
- if isinstance(bboxes, torch.Tensor):
729
- bboxes = bboxes.cpu().numpy()
730
- if isinstance(masks, torch.Tensor):
731
- masks = masks.cpu().numpy().astype(int)
732
- if isinstance(kpts, torch.Tensor):
733
- kpts = kpts.cpu().numpy()
734
- if isinstance(batch_idx, torch.Tensor):
735
- batch_idx = batch_idx.cpu().numpy()
736
732
  if images.shape[1] > 3:
737
733
  images = images[:, :3] # crop multispectral images to first 3 channels
738
734
 
@@ -781,6 +777,7 @@ def plot_images(
781
777
  boxes[..., 0] += x
782
778
  boxes[..., 1] += y
783
779
  is_obb = boxes.shape[-1] == 5 # xywhr
780
+ # TODO: this transformation might be unnecessary
784
781
  boxes = ops.xywhr2xyxyxyxy(boxes) if is_obb else ops.xywh2xyxy(boxes)
785
782
  for j, box in enumerate(boxes.astype(np.int64).tolist()):
786
783
  c = classes[j]
@@ -1004,28 +1001,6 @@ def plot_tune_results(csv_file: str = "tune_results.csv"):
1004
1001
  _save_one_file(csv_file.with_name("tune_fitness.png"))
1005
1002
 
1006
1003
 
1007
- def output_to_target(output, max_det: int = 300):
1008
- """Convert model output to target format [batch_id, class_id, x, y, w, h, conf] for plotting."""
1009
- targets = []
1010
- for i, o in enumerate(output):
1011
- box, conf, cls = o[:max_det, :6].cpu().split((4, 1, 1), 1)
1012
- j = torch.full((conf.shape[0], 1), i)
1013
- targets.append(torch.cat((j, cls, ops.xyxy2xywh(box), conf), 1))
1014
- targets = torch.cat(targets, 0).numpy()
1015
- return targets[:, 0], targets[:, 1], targets[:, 2:-1], targets[:, -1]
1016
-
1017
-
1018
- def output_to_rotated_target(output, max_det: int = 300):
1019
- """Convert model output to target format [batch_id, class_id, x, y, w, h, conf] for plotting."""
1020
- targets = []
1021
- for i, o in enumerate(output):
1022
- box, conf, cls, angle = o[:max_det].cpu().split((4, 1, 1, 1), 1)
1023
- j = torch.full((conf.shape[0], 1), i)
1024
- targets.append(torch.cat((j, cls, box, angle, conf), 1))
1025
- targets = torch.cat(targets, 0).numpy()
1026
- return targets[:, 0], targets[:, 1], targets[:, 2:-1], targets[:, -1]
1027
-
1028
-
1029
1004
  def feature_visualization(x, module_type: str, stage: int, n: int = 32, save_dir: Path = Path("runs/detect/exp")):
1030
1005
  """
1031
1006
  Visualize feature maps of a given model module during inference.