dgenerate-ultralytics-headless 8.3.137__py3-none-any.whl → 8.3.224__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 (215) hide show
  1. {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/METADATA +41 -34
  2. dgenerate_ultralytics_headless-8.3.224.dist-info/RECORD +285 -0
  3. {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/WHEEL +1 -1
  4. tests/__init__.py +7 -6
  5. tests/conftest.py +15 -39
  6. tests/test_cli.py +17 -17
  7. tests/test_cuda.py +17 -8
  8. tests/test_engine.py +36 -10
  9. tests/test_exports.py +98 -37
  10. tests/test_integrations.py +12 -15
  11. tests/test_python.py +126 -82
  12. tests/test_solutions.py +319 -135
  13. ultralytics/__init__.py +27 -9
  14. ultralytics/cfg/__init__.py +83 -87
  15. ultralytics/cfg/datasets/Argoverse.yaml +4 -4
  16. ultralytics/cfg/datasets/DOTAv1.5.yaml +2 -2
  17. ultralytics/cfg/datasets/DOTAv1.yaml +2 -2
  18. ultralytics/cfg/datasets/GlobalWheat2020.yaml +2 -2
  19. ultralytics/cfg/datasets/HomeObjects-3K.yaml +4 -5
  20. ultralytics/cfg/datasets/ImageNet.yaml +3 -3
  21. ultralytics/cfg/datasets/Objects365.yaml +24 -20
  22. ultralytics/cfg/datasets/SKU-110K.yaml +9 -9
  23. ultralytics/cfg/datasets/VOC.yaml +10 -13
  24. ultralytics/cfg/datasets/VisDrone.yaml +43 -33
  25. ultralytics/cfg/datasets/african-wildlife.yaml +5 -5
  26. ultralytics/cfg/datasets/brain-tumor.yaml +4 -5
  27. ultralytics/cfg/datasets/carparts-seg.yaml +5 -5
  28. ultralytics/cfg/datasets/coco-pose.yaml +26 -4
  29. ultralytics/cfg/datasets/coco.yaml +4 -4
  30. ultralytics/cfg/datasets/coco128-seg.yaml +2 -2
  31. ultralytics/cfg/datasets/coco128.yaml +2 -2
  32. ultralytics/cfg/datasets/coco8-grayscale.yaml +103 -0
  33. ultralytics/cfg/datasets/coco8-multispectral.yaml +2 -2
  34. ultralytics/cfg/datasets/coco8-pose.yaml +23 -2
  35. ultralytics/cfg/datasets/coco8-seg.yaml +2 -2
  36. ultralytics/cfg/datasets/coco8.yaml +2 -2
  37. ultralytics/cfg/datasets/construction-ppe.yaml +32 -0
  38. ultralytics/cfg/datasets/crack-seg.yaml +5 -5
  39. ultralytics/cfg/datasets/dog-pose.yaml +32 -4
  40. ultralytics/cfg/datasets/dota8-multispectral.yaml +2 -2
  41. ultralytics/cfg/datasets/dota8.yaml +2 -2
  42. ultralytics/cfg/datasets/hand-keypoints.yaml +29 -4
  43. ultralytics/cfg/datasets/lvis.yaml +9 -9
  44. ultralytics/cfg/datasets/medical-pills.yaml +4 -5
  45. ultralytics/cfg/datasets/open-images-v7.yaml +7 -10
  46. ultralytics/cfg/datasets/package-seg.yaml +5 -5
  47. ultralytics/cfg/datasets/signature.yaml +4 -4
  48. ultralytics/cfg/datasets/tiger-pose.yaml +20 -4
  49. ultralytics/cfg/datasets/xView.yaml +5 -5
  50. ultralytics/cfg/default.yaml +96 -93
  51. ultralytics/cfg/trackers/botsort.yaml +16 -17
  52. ultralytics/cfg/trackers/bytetrack.yaml +9 -11
  53. ultralytics/data/__init__.py +4 -4
  54. ultralytics/data/annotator.py +12 -12
  55. ultralytics/data/augment.py +531 -564
  56. ultralytics/data/base.py +76 -81
  57. ultralytics/data/build.py +206 -42
  58. ultralytics/data/converter.py +179 -78
  59. ultralytics/data/dataset.py +121 -121
  60. ultralytics/data/loaders.py +114 -91
  61. ultralytics/data/split.py +28 -15
  62. ultralytics/data/split_dota.py +67 -48
  63. ultralytics/data/utils.py +110 -89
  64. ultralytics/engine/exporter.py +422 -460
  65. ultralytics/engine/model.py +224 -252
  66. ultralytics/engine/predictor.py +94 -89
  67. ultralytics/engine/results.py +345 -595
  68. ultralytics/engine/trainer.py +231 -134
  69. ultralytics/engine/tuner.py +279 -73
  70. ultralytics/engine/validator.py +53 -46
  71. ultralytics/hub/__init__.py +26 -28
  72. ultralytics/hub/auth.py +30 -16
  73. ultralytics/hub/google/__init__.py +34 -36
  74. ultralytics/hub/session.py +53 -77
  75. ultralytics/hub/utils.py +23 -109
  76. ultralytics/models/__init__.py +1 -1
  77. ultralytics/models/fastsam/__init__.py +1 -1
  78. ultralytics/models/fastsam/model.py +36 -18
  79. ultralytics/models/fastsam/predict.py +33 -44
  80. ultralytics/models/fastsam/utils.py +4 -5
  81. ultralytics/models/fastsam/val.py +12 -14
  82. ultralytics/models/nas/__init__.py +1 -1
  83. ultralytics/models/nas/model.py +16 -20
  84. ultralytics/models/nas/predict.py +12 -14
  85. ultralytics/models/nas/val.py +4 -5
  86. ultralytics/models/rtdetr/__init__.py +1 -1
  87. ultralytics/models/rtdetr/model.py +9 -9
  88. ultralytics/models/rtdetr/predict.py +22 -17
  89. ultralytics/models/rtdetr/train.py +20 -16
  90. ultralytics/models/rtdetr/val.py +79 -59
  91. ultralytics/models/sam/__init__.py +8 -2
  92. ultralytics/models/sam/amg.py +53 -38
  93. ultralytics/models/sam/build.py +29 -31
  94. ultralytics/models/sam/model.py +33 -38
  95. ultralytics/models/sam/modules/blocks.py +159 -182
  96. ultralytics/models/sam/modules/decoders.py +38 -47
  97. ultralytics/models/sam/modules/encoders.py +114 -133
  98. ultralytics/models/sam/modules/memory_attention.py +38 -31
  99. ultralytics/models/sam/modules/sam.py +114 -93
  100. ultralytics/models/sam/modules/tiny_encoder.py +268 -291
  101. ultralytics/models/sam/modules/transformer.py +59 -66
  102. ultralytics/models/sam/modules/utils.py +55 -72
  103. ultralytics/models/sam/predict.py +745 -341
  104. ultralytics/models/utils/loss.py +118 -107
  105. ultralytics/models/utils/ops.py +118 -71
  106. ultralytics/models/yolo/__init__.py +1 -1
  107. ultralytics/models/yolo/classify/predict.py +28 -26
  108. ultralytics/models/yolo/classify/train.py +50 -81
  109. ultralytics/models/yolo/classify/val.py +68 -61
  110. ultralytics/models/yolo/detect/predict.py +12 -15
  111. ultralytics/models/yolo/detect/train.py +56 -46
  112. ultralytics/models/yolo/detect/val.py +279 -223
  113. ultralytics/models/yolo/model.py +167 -86
  114. ultralytics/models/yolo/obb/predict.py +7 -11
  115. ultralytics/models/yolo/obb/train.py +23 -25
  116. ultralytics/models/yolo/obb/val.py +107 -99
  117. ultralytics/models/yolo/pose/__init__.py +1 -1
  118. ultralytics/models/yolo/pose/predict.py +12 -14
  119. ultralytics/models/yolo/pose/train.py +31 -69
  120. ultralytics/models/yolo/pose/val.py +119 -254
  121. ultralytics/models/yolo/segment/predict.py +21 -25
  122. ultralytics/models/yolo/segment/train.py +12 -66
  123. ultralytics/models/yolo/segment/val.py +126 -305
  124. ultralytics/models/yolo/world/train.py +53 -45
  125. ultralytics/models/yolo/world/train_world.py +51 -32
  126. ultralytics/models/yolo/yoloe/__init__.py +7 -7
  127. ultralytics/models/yolo/yoloe/predict.py +30 -37
  128. ultralytics/models/yolo/yoloe/train.py +89 -71
  129. ultralytics/models/yolo/yoloe/train_seg.py +15 -17
  130. ultralytics/models/yolo/yoloe/val.py +56 -41
  131. ultralytics/nn/__init__.py +9 -11
  132. ultralytics/nn/autobackend.py +179 -107
  133. ultralytics/nn/modules/__init__.py +67 -67
  134. ultralytics/nn/modules/activation.py +8 -7
  135. ultralytics/nn/modules/block.py +302 -323
  136. ultralytics/nn/modules/conv.py +61 -104
  137. ultralytics/nn/modules/head.py +488 -186
  138. ultralytics/nn/modules/transformer.py +183 -123
  139. ultralytics/nn/modules/utils.py +15 -20
  140. ultralytics/nn/tasks.py +327 -203
  141. ultralytics/nn/text_model.py +81 -65
  142. ultralytics/py.typed +1 -0
  143. ultralytics/solutions/__init__.py +12 -12
  144. ultralytics/solutions/ai_gym.py +19 -27
  145. ultralytics/solutions/analytics.py +36 -26
  146. ultralytics/solutions/config.py +29 -28
  147. ultralytics/solutions/distance_calculation.py +23 -24
  148. ultralytics/solutions/heatmap.py +17 -19
  149. ultralytics/solutions/instance_segmentation.py +21 -19
  150. ultralytics/solutions/object_blurrer.py +16 -17
  151. ultralytics/solutions/object_counter.py +48 -53
  152. ultralytics/solutions/object_cropper.py +22 -16
  153. ultralytics/solutions/parking_management.py +61 -58
  154. ultralytics/solutions/queue_management.py +19 -19
  155. ultralytics/solutions/region_counter.py +63 -50
  156. ultralytics/solutions/security_alarm.py +22 -25
  157. ultralytics/solutions/similarity_search.py +107 -60
  158. ultralytics/solutions/solutions.py +343 -262
  159. ultralytics/solutions/speed_estimation.py +35 -31
  160. ultralytics/solutions/streamlit_inference.py +104 -40
  161. ultralytics/solutions/templates/similarity-search.html +31 -24
  162. ultralytics/solutions/trackzone.py +24 -24
  163. ultralytics/solutions/vision_eye.py +11 -12
  164. ultralytics/trackers/__init__.py +1 -1
  165. ultralytics/trackers/basetrack.py +18 -27
  166. ultralytics/trackers/bot_sort.py +48 -39
  167. ultralytics/trackers/byte_tracker.py +94 -94
  168. ultralytics/trackers/track.py +7 -16
  169. ultralytics/trackers/utils/gmc.py +37 -69
  170. ultralytics/trackers/utils/kalman_filter.py +68 -76
  171. ultralytics/trackers/utils/matching.py +13 -17
  172. ultralytics/utils/__init__.py +251 -275
  173. ultralytics/utils/autobatch.py +19 -7
  174. ultralytics/utils/autodevice.py +68 -38
  175. ultralytics/utils/benchmarks.py +169 -130
  176. ultralytics/utils/callbacks/base.py +12 -13
  177. ultralytics/utils/callbacks/clearml.py +14 -15
  178. ultralytics/utils/callbacks/comet.py +139 -66
  179. ultralytics/utils/callbacks/dvc.py +19 -27
  180. ultralytics/utils/callbacks/hub.py +8 -6
  181. ultralytics/utils/callbacks/mlflow.py +6 -10
  182. ultralytics/utils/callbacks/neptune.py +11 -19
  183. ultralytics/utils/callbacks/platform.py +73 -0
  184. ultralytics/utils/callbacks/raytune.py +3 -4
  185. ultralytics/utils/callbacks/tensorboard.py +9 -12
  186. ultralytics/utils/callbacks/wb.py +33 -30
  187. ultralytics/utils/checks.py +163 -114
  188. ultralytics/utils/cpu.py +89 -0
  189. ultralytics/utils/dist.py +24 -20
  190. ultralytics/utils/downloads.py +176 -146
  191. ultralytics/utils/errors.py +11 -13
  192. ultralytics/utils/events.py +113 -0
  193. ultralytics/utils/export/__init__.py +7 -0
  194. ultralytics/utils/{export.py → export/engine.py} +81 -63
  195. ultralytics/utils/export/imx.py +294 -0
  196. ultralytics/utils/export/tensorflow.py +217 -0
  197. ultralytics/utils/files.py +33 -36
  198. ultralytics/utils/git.py +137 -0
  199. ultralytics/utils/instance.py +105 -120
  200. ultralytics/utils/logger.py +404 -0
  201. ultralytics/utils/loss.py +99 -61
  202. ultralytics/utils/metrics.py +649 -478
  203. ultralytics/utils/nms.py +337 -0
  204. ultralytics/utils/ops.py +263 -451
  205. ultralytics/utils/patches.py +70 -31
  206. ultralytics/utils/plotting.py +253 -223
  207. ultralytics/utils/tal.py +48 -61
  208. ultralytics/utils/torch_utils.py +244 -251
  209. ultralytics/utils/tqdm.py +438 -0
  210. ultralytics/utils/triton.py +22 -23
  211. ultralytics/utils/tuner.py +11 -10
  212. dgenerate_ultralytics_headless-8.3.137.dist-info/RECORD +0 -272
  213. {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/entry_points.txt +0 -0
  214. {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/licenses/LICENSE +0 -0
  215. {dgenerate_ultralytics_headless-8.3.137.dist-info → dgenerate_ultralytics_headless-8.3.224.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,10 @@
1
1
  # Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from collections import abc
4
6
  from itertools import repeat
5
7
  from numbers import Number
6
- from typing import List
7
8
 
8
9
  import numpy as np
9
10
 
@@ -11,7 +12,7 @@ from .ops import ltwh2xywh, ltwh2xyxy, resample_segments, xywh2ltwh, xywh2xyxy,
11
12
 
12
13
 
13
14
  def _ntuple(n):
14
- """From PyTorch internals."""
15
+ """Create a function that converts input to n-tuple by repeating singleton values."""
15
16
 
16
17
  def parse(x):
17
18
  """Parse input to return n-tuple by repeating singleton values n times."""
@@ -32,23 +33,34 @@ __all__ = ("Bboxes", "Instances") # tuple or list
32
33
 
33
34
 
34
35
  class Bboxes:
35
- """
36
- A class for handling bounding boxes.
36
+ """A class for handling bounding boxes in multiple formats.
37
37
 
38
- The class supports various bounding box formats like 'xyxy', 'xywh', and 'ltwh'.
39
- Bounding box data should be provided in numpy arrays.
38
+ The class supports various bounding box formats like 'xyxy', 'xywh', and 'ltwh' and provides methods for format
39
+ conversion, scaling, and area calculation. Bounding box data should be provided as numpy arrays.
40
40
 
41
41
  Attributes:
42
42
  bboxes (np.ndarray): The bounding boxes stored in a 2D numpy array with shape (N, 4).
43
43
  format (str): The format of the bounding boxes ('xyxy', 'xywh', or 'ltwh').
44
44
 
45
- Note:
45
+ Methods:
46
+ convert: Convert bounding box format from one type to another.
47
+ areas: Calculate the area of bounding boxes.
48
+ mul: Multiply bounding box coordinates by scale factor(s).
49
+ add: Add offset to bounding box coordinates.
50
+ concatenate: Concatenate multiple Bboxes objects.
51
+
52
+ Examples:
53
+ Create bounding boxes in YOLO format
54
+ >>> bboxes = Bboxes(np.array([[100, 50, 150, 100]]), format="xywh")
55
+ >>> bboxes.convert("xyxy")
56
+ >>> print(bboxes.areas())
57
+
58
+ Notes:
46
59
  This class does not handle normalization or denormalization of bounding boxes.
47
60
  """
48
61
 
49
- def __init__(self, bboxes, format="xyxy") -> None:
50
- """
51
- Initialize the Bboxes class with bounding box data in a specified format.
62
+ def __init__(self, bboxes: np.ndarray, format: str = "xyxy") -> None:
63
+ """Initialize the Bboxes class with bounding box data in a specified format.
52
64
 
53
65
  Args:
54
66
  bboxes (np.ndarray): Array of bounding boxes with shape (N, 4) or (4,).
@@ -60,11 +72,9 @@ class Bboxes:
60
72
  assert bboxes.shape[1] == 4
61
73
  self.bboxes = bboxes
62
74
  self.format = format
63
- # self.normalized = normalized
64
75
 
65
- def convert(self, format):
66
- """
67
- Convert bounding box format from one type to another.
76
+ def convert(self, format: str) -> None:
77
+ """Convert bounding box format from one type to another.
68
78
 
69
79
  Args:
70
80
  format (str): Target format for conversion, one of 'xyxy', 'xywh', or 'ltwh'.
@@ -81,37 +91,20 @@ class Bboxes:
81
91
  self.bboxes = func(self.bboxes)
82
92
  self.format = format
83
93
 
84
- def areas(self):
85
- """Return box areas."""
94
+ def areas(self) -> np.ndarray:
95
+ """Calculate the area of bounding boxes."""
86
96
  return (
87
97
  (self.bboxes[:, 2] - self.bboxes[:, 0]) * (self.bboxes[:, 3] - self.bboxes[:, 1]) # format xyxy
88
98
  if self.format == "xyxy"
89
99
  else self.bboxes[:, 3] * self.bboxes[:, 2] # format xywh or ltwh
90
100
  )
91
101
 
92
- # def denormalize(self, w, h):
93
- # if not self.normalized:
94
- # return
95
- # assert (self.bboxes <= 1.0).all()
96
- # self.bboxes[:, 0::2] *= w
97
- # self.bboxes[:, 1::2] *= h
98
- # self.normalized = False
99
- #
100
- # def normalize(self, w, h):
101
- # if self.normalized:
102
- # return
103
- # assert (self.bboxes > 1.0).any()
104
- # self.bboxes[:, 0::2] /= w
105
- # self.bboxes[:, 1::2] /= h
106
- # self.normalized = True
107
-
108
- def mul(self, scale):
109
- """
110
- Multiply bounding box coordinates by scale factor(s).
102
+ def mul(self, scale: int | tuple | list) -> None:
103
+ """Multiply bounding box coordinates by scale factor(s).
111
104
 
112
105
  Args:
113
- scale (int | tuple | list): Scale factor(s) for four coordinates.
114
- If int, the same scale is applied to all coordinates.
106
+ scale (int | tuple | list): Scale factor(s) for four coordinates. If int, the same scale is applied to all
107
+ coordinates.
115
108
  """
116
109
  if isinstance(scale, Number):
117
110
  scale = to_4tuple(scale)
@@ -122,13 +115,12 @@ class Bboxes:
122
115
  self.bboxes[:, 2] *= scale[2]
123
116
  self.bboxes[:, 3] *= scale[3]
124
117
 
125
- def add(self, offset):
126
- """
127
- Add offset to bounding box coordinates.
118
+ def add(self, offset: int | tuple | list) -> None:
119
+ """Add offset to bounding box coordinates.
128
120
 
129
121
  Args:
130
- offset (int | tuple | list): Offset(s) for four coordinates.
131
- If int, the same offset is applied to all coordinates.
122
+ offset (int | tuple | list): Offset(s) for four coordinates. If int, the same offset is applied to all
123
+ coordinates.
132
124
  """
133
125
  if isinstance(offset, Number):
134
126
  offset = to_4tuple(offset)
@@ -139,23 +131,22 @@ class Bboxes:
139
131
  self.bboxes[:, 2] += offset[2]
140
132
  self.bboxes[:, 3] += offset[3]
141
133
 
142
- def __len__(self):
143
- """Return the number of boxes."""
134
+ def __len__(self) -> int:
135
+ """Return the number of bounding boxes."""
144
136
  return len(self.bboxes)
145
137
 
146
138
  @classmethod
147
- def concatenate(cls, boxes_list: List["Bboxes"], axis=0) -> "Bboxes":
148
- """
149
- Concatenate a list of Bboxes objects into a single Bboxes object.
139
+ def concatenate(cls, boxes_list: list[Bboxes], axis: int = 0) -> Bboxes:
140
+ """Concatenate a list of Bboxes objects into a single Bboxes object.
150
141
 
151
142
  Args:
152
- boxes_list (List[Bboxes]): A list of Bboxes objects to concatenate.
143
+ boxes_list (list[Bboxes]): A list of Bboxes objects to concatenate.
153
144
  axis (int, optional): The axis along which to concatenate the bounding boxes.
154
145
 
155
146
  Returns:
156
147
  (Bboxes): A new Bboxes object containing the concatenated bounding boxes.
157
148
 
158
- Note:
149
+ Notes:
159
150
  The input should be a list or tuple of Bboxes objects.
160
151
  """
161
152
  assert isinstance(boxes_list, (list, tuple))
@@ -167,23 +158,18 @@ class Bboxes:
167
158
  return boxes_list[0]
168
159
  return cls(np.concatenate([b.bboxes for b in boxes_list], axis=axis))
169
160
 
170
- def __getitem__(self, index) -> "Bboxes":
171
- """
172
- Retrieve a specific bounding box or a set of bounding boxes using indexing.
161
+ def __getitem__(self, index: int | np.ndarray | slice) -> Bboxes:
162
+ """Retrieve a specific bounding box or a set of bounding boxes using indexing.
173
163
 
174
164
  Args:
175
- index (int | slice | np.ndarray): The index, slice, or boolean array to select
176
- the desired bounding boxes.
165
+ index (int | slice | np.ndarray): The index, slice, or boolean array to select the desired bounding boxes.
177
166
 
178
167
  Returns:
179
168
  (Bboxes): A new Bboxes object containing the selected bounding boxes.
180
169
 
181
- Raises:
182
- AssertionError: If the indexed bounding boxes do not form a 2-dimensional matrix.
183
-
184
- Note:
185
- When using boolean indexing, make sure to provide a boolean array with the same
186
- length as the number of bounding boxes.
170
+ Notes:
171
+ When using boolean indexing, make sure to provide a boolean array with the same length as the number of
172
+ bounding boxes.
187
173
  """
188
174
  if isinstance(index, int):
189
175
  return Bboxes(self.bboxes[index].reshape(1, -1))
@@ -193,8 +179,11 @@ class Bboxes:
193
179
 
194
180
 
195
181
  class Instances:
196
- """
197
- Container for bounding boxes, segments, and keypoints of detected objects in an image.
182
+ """Container for bounding boxes, segments, and keypoints of detected objects in an image.
183
+
184
+ This class provides a unified interface for handling different types of object annotations including bounding boxes,
185
+ segmentation masks, and keypoints. It supports various operations like scaling, normalization, clipping, and format
186
+ conversion.
198
187
 
199
188
  Attributes:
200
189
  _bboxes (Bboxes): Internal object for handling bounding box operations.
@@ -216,6 +205,7 @@ class Instances:
216
205
  concatenate: Concatenate multiple Instances objects.
217
206
 
218
207
  Examples:
208
+ Create instances with bounding boxes and segments
219
209
  >>> instances = Instances(
220
210
  ... bboxes=np.array([[10, 10, 30, 30], [20, 20, 40, 40]]),
221
211
  ... segments=[np.array([[5, 5], [10, 10]]), np.array([[15, 15], [20, 20]])],
@@ -223,25 +213,30 @@ class Instances:
223
213
  ... )
224
214
  """
225
215
 
226
- def __init__(self, bboxes, segments=None, keypoints=None, bbox_format="xywh", normalized=True) -> None:
227
- """
228
- Initialize the object with bounding boxes, segments, and keypoints.
216
+ def __init__(
217
+ self,
218
+ bboxes: np.ndarray,
219
+ segments: np.ndarray = None,
220
+ keypoints: np.ndarray = None,
221
+ bbox_format: str = "xywh",
222
+ normalized: bool = True,
223
+ ) -> None:
224
+ """Initialize the Instances object with bounding boxes, segments, and keypoints.
229
225
 
230
226
  Args:
231
- bboxes (np.ndarray): Bounding boxes, shape (N, 4).
232
- segments (List | np.ndarray, optional): Segmentation masks.
233
- keypoints (np.ndarray, optional): Keypoints, shape (N, 17, 3) in format (x, y, visible).
234
- bbox_format (str, optional): Format of bboxes.
235
- normalized (bool, optional): Whether the coordinates are normalized.
227
+ bboxes (np.ndarray): Bounding boxes with shape (N, 4).
228
+ segments (np.ndarray, optional): Segmentation masks.
229
+ keypoints (np.ndarray, optional): Keypoints with shape (N, 17, 3) in format (x, y, visible).
230
+ bbox_format (str): Format of bboxes.
231
+ normalized (bool): Whether the coordinates are normalized.
236
232
  """
237
233
  self._bboxes = Bboxes(bboxes=bboxes, format=bbox_format)
238
234
  self.keypoints = keypoints
239
235
  self.normalized = normalized
240
236
  self.segments = segments
241
237
 
242
- def convert_bbox(self, format):
243
- """
244
- Convert bounding box format.
238
+ def convert_bbox(self, format: str) -> None:
239
+ """Convert bounding box format.
245
240
 
246
241
  Args:
247
242
  format (str): Target format for conversion, one of 'xyxy', 'xywh', or 'ltwh'.
@@ -249,13 +244,12 @@ class Instances:
249
244
  self._bboxes.convert(format=format)
250
245
 
251
246
  @property
252
- def bbox_areas(self):
247
+ def bbox_areas(self) -> np.ndarray:
253
248
  """Calculate the area of bounding boxes."""
254
249
  return self._bboxes.areas()
255
250
 
256
- def scale(self, scale_w, scale_h, bbox_only=False):
257
- """
258
- Scale coordinates by given factors.
251
+ def scale(self, scale_w: float, scale_h: float, bbox_only: bool = False):
252
+ """Scale coordinates by given factors.
259
253
 
260
254
  Args:
261
255
  scale_w (float): Scale factor for width.
@@ -271,9 +265,8 @@ class Instances:
271
265
  self.keypoints[..., 0] *= scale_w
272
266
  self.keypoints[..., 1] *= scale_h
273
267
 
274
- def denormalize(self, w, h):
275
- """
276
- Convert normalized coordinates to absolute coordinates.
268
+ def denormalize(self, w: int, h: int) -> None:
269
+ """Convert normalized coordinates to absolute coordinates.
277
270
 
278
271
  Args:
279
272
  w (int): Image width.
@@ -289,9 +282,8 @@ class Instances:
289
282
  self.keypoints[..., 1] *= h
290
283
  self.normalized = False
291
284
 
292
- def normalize(self, w, h):
293
- """
294
- Convert absolute coordinates to normalized coordinates.
285
+ def normalize(self, w: int, h: int) -> None:
286
+ """Convert absolute coordinates to normalized coordinates.
295
287
 
296
288
  Args:
297
289
  w (int): Image width.
@@ -307,9 +299,8 @@ class Instances:
307
299
  self.keypoints[..., 1] /= h
308
300
  self.normalized = True
309
301
 
310
- def add_padding(self, padw, padh):
311
- """
312
- Add padding to coordinates.
302
+ def add_padding(self, padw: int, padh: int) -> None:
303
+ """Add padding to coordinates.
313
304
 
314
305
  Args:
315
306
  padw (int): Padding width.
@@ -323,9 +314,8 @@ class Instances:
323
314
  self.keypoints[..., 0] += padw
324
315
  self.keypoints[..., 1] += padh
325
316
 
326
- def __getitem__(self, index) -> "Instances":
327
- """
328
- Retrieve a specific instance or a set of instances using indexing.
317
+ def __getitem__(self, index: int | np.ndarray | slice) -> Instances:
318
+ """Retrieve a specific instance or a set of instances using indexing.
329
319
 
330
320
  Args:
331
321
  index (int | slice | np.ndarray): The index, slice, or boolean array to select the desired instances.
@@ -333,9 +323,9 @@ class Instances:
333
323
  Returns:
334
324
  (Instances): A new Instances object containing the selected boxes, segments, and keypoints if present.
335
325
 
336
- Note:
337
- When using boolean indexing, make sure to provide a boolean array with the same
338
- length as the number of instances.
326
+ Notes:
327
+ When using boolean indexing, make sure to provide a boolean array with the same length as the number of
328
+ instances.
339
329
  """
340
330
  segments = self.segments[index] if len(self.segments) else self.segments
341
331
  keypoints = self.keypoints[index] if self.keypoints is not None else None
@@ -349,9 +339,8 @@ class Instances:
349
339
  normalized=self.normalized,
350
340
  )
351
341
 
352
- def flipud(self, h):
353
- """
354
- Flip coordinates vertically.
342
+ def flipud(self, h: int) -> None:
343
+ """Flip coordinates vertically.
355
344
 
356
345
  Args:
357
346
  h (int): Image height.
@@ -367,9 +356,8 @@ class Instances:
367
356
  if self.keypoints is not None:
368
357
  self.keypoints[..., 1] = h - self.keypoints[..., 1]
369
358
 
370
- def fliplr(self, w):
371
- """
372
- Flip coordinates horizontally.
359
+ def fliplr(self, w: int) -> None:
360
+ """Flip coordinates horizontally.
373
361
 
374
362
  Args:
375
363
  w (int): Image width.
@@ -385,9 +373,8 @@ class Instances:
385
373
  if self.keypoints is not None:
386
374
  self.keypoints[..., 0] = w - self.keypoints[..., 0]
387
375
 
388
- def clip(self, w, h):
389
- """
390
- Clip coordinates to stay within image boundaries.
376
+ def clip(self, w: int, h: int) -> None:
377
+ """Clip coordinates to stay within image boundaries.
391
378
 
392
379
  Args:
393
380
  w (int): Image width.
@@ -409,10 +396,11 @@ class Instances:
409
396
  | (self.keypoints[..., 1] < 0)
410
397
  | (self.keypoints[..., 1] > h)
411
398
  ] = 0.0
399
+ self.keypoints[..., 0] = self.keypoints[..., 0].clip(0, w)
400
+ self.keypoints[..., 1] = self.keypoints[..., 1].clip(0, h)
412
401
 
413
- def remove_zero_area_boxes(self):
414
- """
415
- Remove zero-area boxes, i.e. after clipping some boxes may have zero width or height.
402
+ def remove_zero_area_boxes(self) -> np.ndarray:
403
+ """Remove zero-area boxes, i.e. after clipping some boxes may have zero width or height.
416
404
 
417
405
  Returns:
418
406
  (np.ndarray): Boolean array indicating which boxes were kept.
@@ -426,9 +414,8 @@ class Instances:
426
414
  self.keypoints = self.keypoints[good]
427
415
  return good
428
416
 
429
- def update(self, bboxes, segments=None, keypoints=None):
430
- """
431
- Update instance variables.
417
+ def update(self, bboxes: np.ndarray, segments: np.ndarray = None, keypoints: np.ndarray = None):
418
+ """Update instance variables.
432
419
 
433
420
  Args:
434
421
  bboxes (np.ndarray): New bounding boxes.
@@ -441,27 +428,25 @@ class Instances:
441
428
  if keypoints is not None:
442
429
  self.keypoints = keypoints
443
430
 
444
- def __len__(self):
445
- """Return the length of the instance list."""
431
+ def __len__(self) -> int:
432
+ """Return the number of instances."""
446
433
  return len(self.bboxes)
447
434
 
448
435
  @classmethod
449
- def concatenate(cls, instances_list: List["Instances"], axis=0) -> "Instances":
450
- """
451
- Concatenate a list of Instances objects into a single Instances object.
436
+ def concatenate(cls, instances_list: list[Instances], axis=0) -> Instances:
437
+ """Concatenate a list of Instances objects into a single Instances object.
452
438
 
453
439
  Args:
454
- instances_list (List[Instances]): A list of Instances objects to concatenate.
440
+ instances_list (list[Instances]): A list of Instances objects to concatenate.
455
441
  axis (int, optional): The axis along which the arrays will be concatenated.
456
442
 
457
443
  Returns:
458
- (Instances): A new Instances object containing the concatenated bounding boxes,
459
- segments, and keypoints if present.
444
+ (Instances): A new Instances object containing the concatenated bounding boxes, segments, and keypoints if
445
+ present.
460
446
 
461
- Note:
462
- The `Instances` objects in the list should have the same properties, such as
463
- the format of the bounding boxes, whether keypoints are present, and if the
464
- coordinates are normalized.
447
+ Notes:
448
+ The `Instances` objects in the list should have the same properties, such as the format of the bounding
449
+ boxes, whether keypoints are present, and if the coordinates are normalized.
465
450
  """
466
451
  assert isinstance(instances_list, (list, tuple))
467
452
  if not instances_list:
@@ -494,6 +479,6 @@ class Instances:
494
479
  return cls(cat_boxes, cat_segments, cat_keypoints, bbox_format, normalized)
495
480
 
496
481
  @property
497
- def bboxes(self):
482
+ def bboxes(self) -> np.ndarray:
498
483
  """Return bounding boxes."""
499
484
  return self._bboxes.bboxes