Skip to content

Commit 752818e

Browse files
authored
Merge pull request roboflow#1790 from roboflow/feature/support_for_qwen_2_5_vl
support for converting Qwen2.5-VL into sv.Detections
2 parents dc449c4 + 2e38e89 commit 752818e

File tree

14 files changed

+584
-322
lines changed

14 files changed

+584
-322
lines changed

docs/how_to/track_objects.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ it will be modified to include tracking, labeling, and trace annotations.
5555
from ultralytics import YOLO
5656

5757
model = YOLO("yolov8n.pt")
58-
box_annotator = sv.BoundingBoxAnnotator()
58+
box_annotator = sv.BoxAnnotator()
5959

6060
def callback(frame: np.ndarray, _: int) -> np.ndarray:
6161
results = model(frame)[0]
@@ -77,7 +77,7 @@ it will be modified to include tracking, labeling, and trace annotations.
7777
from inference.models.utils import get_roboflow_model
7878

7979
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
80-
box_annotator = sv.BoundingBoxAnnotator()
80+
box_annotator = sv.BoxAnnotator()
8181

8282
def callback(frame: np.ndarray, _: int) -> np.ndarray:
8383
results = model.infer(frame)[0]
@@ -112,7 +112,7 @@ enabling the continuous following of the object's motion path across different f
112112

113113
model = YOLO("yolov8n.pt")
114114
tracker = sv.ByteTrack()
115-
box_annotator = sv.BoundingBoxAnnotator()
115+
box_annotator = sv.BoxAnnotator()
116116

117117
def callback(frame: np.ndarray, _: int) -> np.ndarray:
118118
results = model(frame)[0]
@@ -136,7 +136,7 @@ enabling the continuous following of the object's motion path across different f
136136

137137
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
138138
tracker = sv.ByteTrack()
139-
box_annotator = sv.BoundingBoxAnnotator()
139+
box_annotator = sv.BoxAnnotator()
140140

141141
def callback(frame: np.ndarray, _: int) -> np.ndarray:
142142
results = model.infer(frame)[0]
@@ -168,7 +168,7 @@ offering a clear visual representation of each object's class and unique identif
168168

169169
model = YOLO("yolov8n.pt")
170170
tracker = sv.ByteTrack()
171-
box_annotator = sv.BoundingBoxAnnotator()
171+
box_annotator = sv.BoxAnnotator()
172172
label_annotator = sv.LabelAnnotator()
173173

174174
def callback(frame: np.ndarray, _: int) -> np.ndarray:
@@ -203,7 +203,7 @@ offering a clear visual representation of each object's class and unique identif
203203

204204
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
205205
tracker = sv.ByteTrack()
206-
box_annotator = sv.BoundingBoxAnnotator()
206+
box_annotator = sv.BoxAnnotator()
207207
label_annotator = sv.LabelAnnotator()
208208

209209
def callback(frame: np.ndarray, _: int) -> np.ndarray:
@@ -250,7 +250,7 @@ movement patterns and interactions between objects in the video.
250250

251251
model = YOLO("yolov8n.pt")
252252
tracker = sv.ByteTrack()
253-
box_annotator = sv.BoundingBoxAnnotator()
253+
box_annotator = sv.BoxAnnotator()
254254
label_annotator = sv.LabelAnnotator()
255255
trace_annotator = sv.TraceAnnotator()
256256

@@ -288,7 +288,7 @@ movement patterns and interactions between objects in the video.
288288

289289
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
290290
tracker = sv.ByteTrack()
291-
box_annotator = sv.BoundingBoxAnnotator()
291+
box_annotator = sv.BoxAnnotator()
292292
label_annotator = sv.LabelAnnotator()
293293
trace_annotator = sv.TraceAnnotator()
294294

examples/count_people_in_zone/inference_example.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ def load_zones_config(file_path: str) -> List[np.ndarray]:
3535

3636
def initiate_annotators(
3737
polygons: List[np.ndarray], resolution_wh: Tuple[int, int]
38-
) -> Tuple[
39-
List[sv.PolygonZone], List[sv.PolygonZoneAnnotator], List[sv.BoundingBoxAnnotator]
40-
]:
38+
) -> Tuple[List[sv.PolygonZone], List[sv.PolygonZoneAnnotator], List[sv.BoxAnnotator]]:
4139
line_thickness = sv.calculate_optimal_line_thickness(resolution_wh=resolution_wh)
4240
text_scale = sv.calculate_optimal_text_scale(resolution_wh=resolution_wh)
4341

@@ -54,7 +52,7 @@ def initiate_annotators(
5452
text_thickness=line_thickness * 2,
5553
text_scale=text_scale * 2,
5654
)
57-
box_annotator = sv.BoundingBoxAnnotator(
55+
box_annotator = sv.BoxAnnotator(
5856
color=COLORS.by_idx(index), thickness=line_thickness
5957
)
6058
zones.append(zone)
@@ -97,7 +95,7 @@ def annotate(
9795
frame: np.ndarray,
9896
zones: List[sv.PolygonZone],
9997
zone_annotators: List[sv.PolygonZoneAnnotator],
100-
box_annotators: List[sv.BoundingBoxAnnotator],
98+
box_annotators: List[sv.BoxAnnotator],
10199
detections: sv.Detections,
102100
) -> np.ndarray:
103101
"""
@@ -108,7 +106,7 @@ def annotate(
108106
zones (List[sv.PolygonZone]): A list of polygon zones used for detection.
109107
zone_annotators (List[sv.PolygonZoneAnnotator]): A list of annotators for
110108
drawing zone annotations.
111-
box_annotators (List[sv.BoundingBoxAnnotator]): A list of annotators for
109+
box_annotators (List[sv.BoxAnnotator]): A list of annotators for
112110
drawing box annotations.
113111
detections (sv.Detections): Detections to be used for annotation.
114112

examples/count_people_in_zone/ultralytics_example.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ def load_zones_config(file_path: str) -> List[np.ndarray]:
3333

3434
def initiate_annotators(
3535
polygons: List[np.ndarray], resolution_wh: Tuple[int, int]
36-
) -> Tuple[
37-
List[sv.PolygonZone], List[sv.PolygonZoneAnnotator], List[sv.BoundingBoxAnnotator]
38-
]:
36+
) -> Tuple[List[sv.PolygonZone], List[sv.PolygonZoneAnnotator], List[sv.BoxAnnotator]]:
3937
line_thickness = sv.calculate_optimal_line_thickness(resolution_wh=resolution_wh)
4038
text_scale = sv.calculate_optimal_text_scale(resolution_wh=resolution_wh)
4139

@@ -52,7 +50,7 @@ def initiate_annotators(
5250
text_thickness=line_thickness * 2,
5351
text_scale=text_scale * 2,
5452
)
55-
box_annotator = sv.BoundingBoxAnnotator(
53+
box_annotator = sv.BoxAnnotator(
5654
color=COLORS.by_idx(index), thickness=line_thickness
5755
)
5856
zones.append(zone)
@@ -94,7 +92,7 @@ def annotate(
9492
frame: np.ndarray,
9593
zones: List[sv.PolygonZone],
9694
zone_annotators: List[sv.PolygonZoneAnnotator],
97-
box_annotators: List[sv.BoundingBoxAnnotator],
95+
box_annotators: List[sv.BoxAnnotator],
9896
detections: sv.Detections,
9997
) -> np.ndarray:
10098
"""
@@ -105,7 +103,7 @@ def annotate(
105103
zones (List[sv.PolygonZone]): A list of polygon zones used for detection.
106104
zone_annotators (List[sv.PolygonZoneAnnotator]): A list of annotators for
107105
drawing zone annotations.
108-
box_annotators (List[sv.BoundingBoxAnnotator]): A list of annotators for
106+
box_annotators (List[sv.BoxAnnotator]): A list of annotators for
109107
drawing box annotations.
110108
detections (sv.Detections): Detections to be used for annotation.
111109

examples/tracking/inference_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def process_video(
1818
model = get_roboflow_model(model_id=model_id, api_key=roboflow_api_key)
1919

2020
tracker = sv.ByteTrack()
21-
box_annotator = sv.BoundingBoxAnnotator()
21+
box_annotator = sv.BoxAnnotator()
2222
label_annotator = sv.LabelAnnotator()
2323
frame_generator = sv.get_video_frames_generator(source_path=source_video_path)
2424
video_info = sv.VideoInfo.from_video_path(video_path=source_video_path)

examples/tracking/ultralytics_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def process_video(
1616
model = YOLO(source_weights_path)
1717

1818
tracker = sv.ByteTrack()
19-
box_annotator = sv.BoundingBoxAnnotator()
19+
box_annotator = sv.BoxAnnotator()
2020
label_annotator = sv.LabelAnnotator()
2121
frame_generator = sv.get_video_frames_generator(source_path=source_video_path)
2222
video_info = sv.VideoInfo.from_video_path(video_path=source_video_path)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "supervision"
33
description = "A set of easy-to-use utils that will come in handy in any Computer Vision project"
44
license = { text = "MIT" }
5-
version = "0.26.0rc3"
5+
version = "0.26.0rc4"
66
readme = "README.md"
77
requires-python = ">=3.8"
88
authors = [

supervision/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from supervision.annotators.core import (
1010
BackgroundOverlayAnnotator,
1111
BlurAnnotator,
12-
BoundingBoxAnnotator,
1312
BoxAnnotator,
1413
BoxCornerAnnotator,
1514
CircleAnnotator,
@@ -46,7 +45,6 @@
4645
LineZoneAnnotator,
4746
LineZoneAnnotatorMulticlass,
4847
)
49-
from supervision.detection.lmm import LMM
5048
from supervision.detection.overlap_filter import (
5149
OverlapFilter,
5250
box_non_max_merge,
@@ -80,6 +78,7 @@
8078
xyxy_to_polygons,
8179
xyxy_to_xywh,
8280
)
81+
from supervision.detection.vlm import LMM, VLM
8382
from supervision.draw.color import Color, ColorPalette
8483
from supervision.draw.utils import (
8584
calculate_optimal_line_thickness,
@@ -127,7 +126,6 @@
127126
"BackgroundOverlayAnnotator",
128127
"BaseDataset",
129128
"BlurAnnotator",
130-
"BoundingBoxAnnotator",
131129
"BoxAnnotator",
132130
"BoxCornerAnnotator",
133131
"ByteTrack",

supervision/annotators/core.py

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
overlay_image,
3737
scale_image,
3838
)
39-
from supervision.utils.internal import deprecated
4039

4140
CV2_FONT = cv2.FONT_HERSHEY_SIMPLEX
4241

@@ -124,92 +123,6 @@ def annotate(
124123
return scene
125124

126125

127-
@deprecated(
128-
"`BoundingBoxAnnotator` is deprecated and has been renamed to `BoxAnnotator`."
129-
" `BoundingBoxAnnotator` will be removed in supervision-0.26.0."
130-
)
131-
class BoundingBoxAnnotator(BaseAnnotator):
132-
"""
133-
A class for drawing bounding boxes on an image using provided detections.
134-
"""
135-
136-
def __init__(
137-
self,
138-
color: Union[Color, ColorPalette] = ColorPalette.DEFAULT,
139-
thickness: int = 2,
140-
color_lookup: ColorLookup = ColorLookup.CLASS,
141-
):
142-
"""
143-
Args:
144-
color (Union[Color, ColorPalette]): The color or color palette to use for
145-
annotating detections.
146-
thickness (int): Thickness of the bounding box lines.
147-
color_lookup (ColorLookup): Strategy for mapping colors to annotations.
148-
Options are `INDEX`, `CLASS`, `TRACK`.
149-
"""
150-
self.color: Union[Color, ColorPalette] = color
151-
self.thickness: int = thickness
152-
self.color_lookup: ColorLookup = color_lookup
153-
154-
@ensure_cv2_image_for_annotation
155-
def annotate(
156-
self,
157-
scene: ImageType,
158-
detections: Detections,
159-
custom_color_lookup: Optional[np.ndarray] = None,
160-
) -> ImageType:
161-
"""
162-
Annotates the given scene with bounding boxes based on the provided detections.
163-
164-
Args:
165-
scene (ImageType): The image where bounding boxes will be drawn. `ImageType`
166-
is a flexible type, accepting either `numpy.ndarray` or `PIL.Image.Image`.
167-
detections (Detections): Object detections to annotate.
168-
custom_color_lookup (Optional[np.ndarray]): Custom color lookup array.
169-
Allows to override the default color mapping strategy.
170-
171-
Returns:
172-
The annotated image, matching the type of `scene` (`numpy.ndarray`
173-
or `PIL.Image.Image`)
174-
175-
Example:
176-
```python
177-
import supervision as sv
178-
179-
image = ...
180-
detections = sv.Detections(...)
181-
182-
bounding_box_annotator = sv.BoundingBoxAnnotator()
183-
annotated_frame = bounding_box_annotator.annotate(
184-
scene=image.copy(),
185-
detections=detections
186-
)
187-
```
188-
189-
![bounding-box-annotator-example](https://media.roboflow.com/
190-
supervision-annotator-examples/bounding-box-annotator-example-purple.png)
191-
"""
192-
assert isinstance(scene, np.ndarray)
193-
for detection_idx in range(len(detections)):
194-
x1, y1, x2, y2 = detections.xyxy[detection_idx].astype(int)
195-
color = resolve_color(
196-
color=self.color,
197-
detections=detections,
198-
detection_idx=detection_idx,
199-
color_lookup=self.color_lookup
200-
if custom_color_lookup is None
201-
else custom_color_lookup,
202-
)
203-
cv2.rectangle(
204-
img=scene,
205-
pt1=(x1, y1),
206-
pt2=(x2, y2),
207-
color=color.as_bgr(),
208-
thickness=self.thickness,
209-
)
210-
return scene
211-
212-
213126
class OrientedBoxAnnotator(BaseAnnotator):
214127
"""
215128
A class for drawing oriented bounding boxes on an image using provided detections.

supervision/dataset/core.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -705,28 +705,6 @@ def __init__(
705705
"a list of paths `List[str]` instead."
706706
)
707707

708-
@property
709-
@deprecated(
710-
"`DetectionDataset.images` property is deprecated and will be removed in "
711-
"`supervision-0.26.0`. Iterate with `for path, image, annotation in dataset:` "
712-
"instead."
713-
)
714-
def images(self) -> Dict[str, np.ndarray]:
715-
"""
716-
Load all images to memory and return them as a dictionary.
717-
718-
!!! warning
719-
720-
Only use this when you need all images at once.
721-
It is much more memory-efficient to initialize dataset with
722-
image paths and use `for path, image, annotation in dataset:`.
723-
"""
724-
if self._images_in_memory:
725-
return self._images_in_memory
726-
727-
images = {image_path: cv2.imread(image_path) for image_path in self.image_paths}
728-
return images
729-
730708
def _get_image(self, image_path: str) -> np.ndarray:
731709
"""Assumes that image is in dataset"""
732710
if self._images_in_memory:

0 commit comments

Comments
 (0)