vidformer 0.9.0__py3-none-any.whl → 0.10.0__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.
- vidformer/__init__.py +1397 -3
- vidformer/cv2/__init__.py +858 -1
- vidformer/supervision/__init__.py +529 -0
- {vidformer-0.9.0.dist-info → vidformer-0.10.0.dist-info}/METADATA +7 -5
- vidformer-0.10.0.dist-info/RECORD +6 -0
- vidformer/cv2/vf_cv2.py +0 -810
- vidformer/igni/__init__.py +0 -1
- vidformer/igni/vf_igni.py +0 -285
- vidformer/vf.py +0 -1112
- vidformer-0.9.0.dist-info/RECORD +0 -9
- {vidformer-0.9.0.dist-info → vidformer-0.10.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,529 @@
|
|
1
|
+
"""
|
2
|
+
vidformer.supervision is the [supervision](https://supervision.roboflow.com/) frontend for [vidformer](https://github.com/ixlab/vidformer).
|
3
|
+
"""
|
4
|
+
|
5
|
+
import vidformer.cv2 as vf_cv2
|
6
|
+
|
7
|
+
import supervision as _sv
|
8
|
+
import numpy as np
|
9
|
+
from supervision import Color, ColorPalette, ColorLookup, Detections
|
10
|
+
from supervision.annotators.utils import resolve_color, resolve_text_background_xyxy
|
11
|
+
from supervision.detection.utils import spread_out_boxes
|
12
|
+
from supervision.config import CLASS_NAME_DATA_FIELD
|
13
|
+
from math import sqrt
|
14
|
+
from supervision.geometry.core import Position
|
15
|
+
|
16
|
+
CV2_FONT = vf_cv2.FONT_HERSHEY_SIMPLEX
|
17
|
+
|
18
|
+
|
19
|
+
class BoxAnnotator:
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
color=ColorPalette.DEFAULT,
|
23
|
+
thickness=2,
|
24
|
+
color_lookup=ColorLookup.CLASS,
|
25
|
+
):
|
26
|
+
self.color = color
|
27
|
+
self.thickness = thickness
|
28
|
+
self.color_lookup = color_lookup
|
29
|
+
|
30
|
+
def annotate(
|
31
|
+
self,
|
32
|
+
scene: vf_cv2.Frame,
|
33
|
+
detections: Detections,
|
34
|
+
custom_color_lookup=None,
|
35
|
+
):
|
36
|
+
for detection_idx in range(len(detections)):
|
37
|
+
x1, y1, x2, y2 = detections.xyxy[detection_idx].astype(int)
|
38
|
+
color = resolve_color(
|
39
|
+
color=self.color,
|
40
|
+
detections=detections,
|
41
|
+
detection_idx=detection_idx,
|
42
|
+
color_lookup=(
|
43
|
+
self.color_lookup
|
44
|
+
if custom_color_lookup is None
|
45
|
+
else custom_color_lookup
|
46
|
+
),
|
47
|
+
)
|
48
|
+
vf_cv2.rectangle(
|
49
|
+
img=scene,
|
50
|
+
pt1=(x1, y1),
|
51
|
+
pt2=(x2, y2),
|
52
|
+
color=color.as_rgb(),
|
53
|
+
thickness=self.thickness,
|
54
|
+
)
|
55
|
+
return scene
|
56
|
+
|
57
|
+
|
58
|
+
class RoundBoxAnnotator:
|
59
|
+
def __init__(
|
60
|
+
self,
|
61
|
+
color=ColorPalette.DEFAULT,
|
62
|
+
thickness: int = 2,
|
63
|
+
color_lookup: ColorLookup = ColorLookup.CLASS,
|
64
|
+
roundness: float = 0.6,
|
65
|
+
):
|
66
|
+
self.color = color
|
67
|
+
self.thickness = thickness
|
68
|
+
self.color_lookup = color_lookup
|
69
|
+
if not 0 < roundness <= 1.0:
|
70
|
+
raise ValueError("roundness attribute must be float between (0, 1.0]")
|
71
|
+
self.roundness = roundness
|
72
|
+
|
73
|
+
def annotate(
|
74
|
+
self,
|
75
|
+
scene: vf_cv2.Frame,
|
76
|
+
detections: _sv.Detections,
|
77
|
+
custom_color_lookup=None,
|
78
|
+
):
|
79
|
+
for detection_idx in range(len(detections)):
|
80
|
+
x1, y1, x2, y2 = detections.xyxy[detection_idx].astype(int)
|
81
|
+
color = resolve_color(
|
82
|
+
color=self.color,
|
83
|
+
detections=detections,
|
84
|
+
detection_idx=detection_idx,
|
85
|
+
color_lookup=(
|
86
|
+
self.color_lookup
|
87
|
+
if custom_color_lookup is None
|
88
|
+
else custom_color_lookup
|
89
|
+
),
|
90
|
+
)
|
91
|
+
radius = (
|
92
|
+
int((x2 - x1) // 2 * self.roundness)
|
93
|
+
if abs(x1 - x2) < abs(y1 - y2)
|
94
|
+
else int((y2 - y1) // 2 * self.roundness)
|
95
|
+
)
|
96
|
+
circle_coordinates = [
|
97
|
+
((x1 + radius), (y1 + radius)),
|
98
|
+
((x2 - radius), (y1 + radius)),
|
99
|
+
((x2 - radius), (y2 - radius)),
|
100
|
+
((x1 + radius), (y2 - radius)),
|
101
|
+
]
|
102
|
+
line_coordinates = [
|
103
|
+
((x1 + radius, y1), (x2 - radius, y1)),
|
104
|
+
((x2, y1 + radius), (x2, y2 - radius)),
|
105
|
+
((x1 + radius, y2), (x2 - radius, y2)),
|
106
|
+
((x1, y1 + radius), (x1, y2 - radius)),
|
107
|
+
]
|
108
|
+
start_angles = (180, 270, 0, 90)
|
109
|
+
end_angles = (270, 360, 90, 180)
|
110
|
+
for center_coordinates, line, start_angle, end_angle in zip(
|
111
|
+
circle_coordinates, line_coordinates, start_angles, end_angles
|
112
|
+
):
|
113
|
+
vf_cv2.ellipse(
|
114
|
+
img=scene,
|
115
|
+
center=center_coordinates,
|
116
|
+
axes=(radius, radius),
|
117
|
+
angle=0,
|
118
|
+
startAngle=start_angle,
|
119
|
+
endAngle=end_angle,
|
120
|
+
color=color.as_rgb(),
|
121
|
+
thickness=self.thickness,
|
122
|
+
)
|
123
|
+
vf_cv2.line(
|
124
|
+
img=scene,
|
125
|
+
pt1=line[0],
|
126
|
+
pt2=line[1],
|
127
|
+
color=color.as_rgb(),
|
128
|
+
thickness=self.thickness,
|
129
|
+
)
|
130
|
+
return scene
|
131
|
+
|
132
|
+
|
133
|
+
class BoxCornerAnnotator:
|
134
|
+
def __init__(
|
135
|
+
self,
|
136
|
+
color=ColorPalette.DEFAULT,
|
137
|
+
thickness=4,
|
138
|
+
corner_length=15,
|
139
|
+
color_lookup=ColorLookup.CLASS,
|
140
|
+
):
|
141
|
+
self.color = color
|
142
|
+
self.thickness: int = thickness
|
143
|
+
self.corner_length: int = corner_length
|
144
|
+
self.color_lookup: ColorLookup = color_lookup
|
145
|
+
|
146
|
+
def annotate(
|
147
|
+
self,
|
148
|
+
scene: vf_cv2.Frame,
|
149
|
+
detections: Detections,
|
150
|
+
custom_color_lookup=None,
|
151
|
+
):
|
152
|
+
for detection_idx in range(len(detections)):
|
153
|
+
x1, y1, x2, y2 = detections.xyxy[detection_idx].astype(int)
|
154
|
+
color = resolve_color(
|
155
|
+
color=self.color,
|
156
|
+
detections=detections,
|
157
|
+
detection_idx=detection_idx,
|
158
|
+
color_lookup=(
|
159
|
+
self.color_lookup
|
160
|
+
if custom_color_lookup is None
|
161
|
+
else custom_color_lookup
|
162
|
+
),
|
163
|
+
)
|
164
|
+
corners = [(x1, y1), (x2, y1), (x1, y2), (x2, y2)]
|
165
|
+
for x, y in corners:
|
166
|
+
x_end = x + self.corner_length if x == x1 else x - self.corner_length
|
167
|
+
vf_cv2.line(
|
168
|
+
scene, (x, y), (x_end, y), color.as_rgb(), thickness=self.thickness
|
169
|
+
)
|
170
|
+
|
171
|
+
y_end = y + self.corner_length if y == y1 else y - self.corner_length
|
172
|
+
vf_cv2.line(
|
173
|
+
scene, (x, y), (x, y_end), color.as_rgb(), thickness=self.thickness
|
174
|
+
)
|
175
|
+
return scene
|
176
|
+
|
177
|
+
|
178
|
+
class ColorAnnotator:
|
179
|
+
def __init__(
|
180
|
+
self,
|
181
|
+
color=ColorPalette.DEFAULT,
|
182
|
+
opacity: float = 0.5,
|
183
|
+
color_lookup: ColorLookup = ColorLookup.CLASS,
|
184
|
+
):
|
185
|
+
self.color = color
|
186
|
+
self.color_lookup: ColorLookup = color_lookup
|
187
|
+
self.opacity = opacity
|
188
|
+
|
189
|
+
def annotate(
|
190
|
+
self,
|
191
|
+
scene: vf_cv2.Frame,
|
192
|
+
detections: Detections,
|
193
|
+
custom_color_lookup=None,
|
194
|
+
):
|
195
|
+
scene_with_boxes = scene.copy()
|
196
|
+
for detection_idx in range(len(detections)):
|
197
|
+
x1, y1, x2, y2 = detections.xyxy[detection_idx].astype(int)
|
198
|
+
color = resolve_color(
|
199
|
+
color=self.color,
|
200
|
+
detections=detections,
|
201
|
+
detection_idx=detection_idx,
|
202
|
+
color_lookup=(
|
203
|
+
self.color_lookup
|
204
|
+
if custom_color_lookup is None
|
205
|
+
else custom_color_lookup
|
206
|
+
),
|
207
|
+
)
|
208
|
+
vf_cv2.rectangle(
|
209
|
+
img=scene_with_boxes,
|
210
|
+
pt1=(x1, y1),
|
211
|
+
pt2=(x2, y2),
|
212
|
+
color=color.as_rgb(),
|
213
|
+
thickness=-1,
|
214
|
+
)
|
215
|
+
|
216
|
+
vf_cv2.addWeighted(
|
217
|
+
scene_with_boxes, self.opacity, scene, 1 - self.opacity, gamma=0, dst=scene
|
218
|
+
)
|
219
|
+
return scene
|
220
|
+
|
221
|
+
|
222
|
+
class CircleAnnotator:
|
223
|
+
def __init__(
|
224
|
+
self,
|
225
|
+
color=ColorPalette.DEFAULT,
|
226
|
+
thickness: int = 2,
|
227
|
+
color_lookup: ColorLookup = ColorLookup.CLASS,
|
228
|
+
):
|
229
|
+
self.color = color
|
230
|
+
self.thickness: int = thickness
|
231
|
+
self.color_lookup: ColorLookup = color_lookup
|
232
|
+
|
233
|
+
def annotate(
|
234
|
+
self,
|
235
|
+
scene: vf_cv2.Frame,
|
236
|
+
detections: Detections,
|
237
|
+
custom_color_lookup=None,
|
238
|
+
):
|
239
|
+
for detection_idx in range(len(detections)):
|
240
|
+
x1, y1, x2, y2 = detections.xyxy[detection_idx].astype(int)
|
241
|
+
center = ((x1 + x2) // 2, (y1 + y2) // 2)
|
242
|
+
distance = sqrt((x1 - center[0]) ** 2 + (y1 - center[1]) ** 2)
|
243
|
+
color = resolve_color(
|
244
|
+
color=self.color,
|
245
|
+
detections=detections,
|
246
|
+
detection_idx=detection_idx,
|
247
|
+
color_lookup=(
|
248
|
+
self.color_lookup
|
249
|
+
if custom_color_lookup is None
|
250
|
+
else custom_color_lookup
|
251
|
+
),
|
252
|
+
)
|
253
|
+
vf_cv2.circle(
|
254
|
+
img=scene,
|
255
|
+
center=center,
|
256
|
+
radius=int(distance),
|
257
|
+
color=color.as_rgb(),
|
258
|
+
thickness=self.thickness,
|
259
|
+
)
|
260
|
+
|
261
|
+
return scene
|
262
|
+
|
263
|
+
|
264
|
+
class DotAnnotator:
|
265
|
+
def __init__(
|
266
|
+
self,
|
267
|
+
color=ColorPalette.DEFAULT,
|
268
|
+
radius: int = 4,
|
269
|
+
position: Position = Position.CENTER,
|
270
|
+
color_lookup: ColorLookup = ColorLookup.CLASS,
|
271
|
+
outline_thickness: int = 0,
|
272
|
+
outline_color=Color.BLACK,
|
273
|
+
):
|
274
|
+
|
275
|
+
self.color = color
|
276
|
+
self.radius: int = radius
|
277
|
+
self.position: Position = position
|
278
|
+
self.color_lookup: ColorLookup = color_lookup
|
279
|
+
self.outline_thickness = outline_thickness
|
280
|
+
self.outline_color = outline_color
|
281
|
+
|
282
|
+
def annotate(
|
283
|
+
self,
|
284
|
+
scene: vf_cv2.Frame,
|
285
|
+
detections: Detections,
|
286
|
+
custom_color_lookup=None,
|
287
|
+
):
|
288
|
+
xy = detections.get_anchors_coordinates(anchor=self.position)
|
289
|
+
for detection_idx in range(len(detections)):
|
290
|
+
color = resolve_color(
|
291
|
+
color=self.color,
|
292
|
+
detections=detections,
|
293
|
+
detection_idx=detection_idx,
|
294
|
+
color_lookup=(
|
295
|
+
self.color_lookup
|
296
|
+
if custom_color_lookup is None
|
297
|
+
else custom_color_lookup
|
298
|
+
),
|
299
|
+
)
|
300
|
+
center = (int(xy[detection_idx, 0]), int(xy[detection_idx, 1]))
|
301
|
+
|
302
|
+
vf_cv2.circle(scene, center, self.radius, color.as_rgb(), -1)
|
303
|
+
if self.outline_thickness:
|
304
|
+
outline_color = resolve_color(
|
305
|
+
color=self.outline_color,
|
306
|
+
detections=detections,
|
307
|
+
detection_idx=detection_idx,
|
308
|
+
color_lookup=(
|
309
|
+
self.color_lookup
|
310
|
+
if custom_color_lookup is None
|
311
|
+
else custom_color_lookup
|
312
|
+
),
|
313
|
+
)
|
314
|
+
vf_cv2.circle(
|
315
|
+
scene,
|
316
|
+
center,
|
317
|
+
self.radius,
|
318
|
+
outline_color.as_rgb(),
|
319
|
+
self.outline_thickness,
|
320
|
+
)
|
321
|
+
return scene
|
322
|
+
|
323
|
+
|
324
|
+
class LabelAnnotator:
|
325
|
+
def __init__(
|
326
|
+
self,
|
327
|
+
color=ColorPalette.DEFAULT,
|
328
|
+
text_color=Color.WHITE,
|
329
|
+
text_scale: float = 0.5,
|
330
|
+
text_thickness: int = 1,
|
331
|
+
text_padding: int = 10,
|
332
|
+
text_position: Position = Position.TOP_LEFT,
|
333
|
+
color_lookup: ColorLookup = ColorLookup.CLASS,
|
334
|
+
border_radius: int = 0,
|
335
|
+
smart_position: bool = False,
|
336
|
+
):
|
337
|
+
self.border_radius: int = border_radius
|
338
|
+
self.color = color
|
339
|
+
self.text_color = text_color
|
340
|
+
self.text_scale: float = text_scale
|
341
|
+
self.text_thickness: int = text_thickness
|
342
|
+
self.text_padding: int = text_padding
|
343
|
+
self.text_anchor: Position = text_position
|
344
|
+
self.color_lookup: ColorLookup = color_lookup
|
345
|
+
self.smart_position = smart_position
|
346
|
+
|
347
|
+
def annotate(
|
348
|
+
self,
|
349
|
+
scene,
|
350
|
+
detections: Detections,
|
351
|
+
labels,
|
352
|
+
custom_color_lookup=None,
|
353
|
+
):
|
354
|
+
self._validate_labels(labels, detections)
|
355
|
+
|
356
|
+
labels = self._get_labels_text(detections, labels)
|
357
|
+
label_properties = self._get_label_properties(detections, labels)
|
358
|
+
|
359
|
+
if self.smart_position:
|
360
|
+
xyxy = label_properties[:, :4]
|
361
|
+
xyxy = spread_out_boxes(xyxy)
|
362
|
+
label_properties[:, :4] = xyxy
|
363
|
+
|
364
|
+
self._draw_labels(
|
365
|
+
scene=scene,
|
366
|
+
labels=labels,
|
367
|
+
label_properties=label_properties,
|
368
|
+
detections=detections,
|
369
|
+
custom_color_lookup=custom_color_lookup,
|
370
|
+
)
|
371
|
+
|
372
|
+
return scene
|
373
|
+
|
374
|
+
def _validate_labels(self, labels, detections: Detections):
|
375
|
+
if labels is not None and len(labels) != len(detections):
|
376
|
+
raise ValueError(
|
377
|
+
f"The number of labels ({len(labels)}) does not match the "
|
378
|
+
f"number of detections ({len(detections)}). Each detection "
|
379
|
+
f"should have exactly 1 label."
|
380
|
+
)
|
381
|
+
|
382
|
+
def _get_label_properties(
|
383
|
+
self,
|
384
|
+
detections: Detections,
|
385
|
+
labels,
|
386
|
+
):
|
387
|
+
label_properties = []
|
388
|
+
anchors_coordinates = detections.get_anchors_coordinates(
|
389
|
+
anchor=self.text_anchor
|
390
|
+
).astype(int)
|
391
|
+
|
392
|
+
for label, center_coords in zip(labels, anchors_coordinates):
|
393
|
+
(text_w, text_h) = vf_cv2.getTextSize(
|
394
|
+
text=label,
|
395
|
+
fontFace=CV2_FONT,
|
396
|
+
fontScale=self.text_scale,
|
397
|
+
thickness=self.text_thickness,
|
398
|
+
)[0]
|
399
|
+
|
400
|
+
width_padded = text_w + 2 * self.text_padding
|
401
|
+
height_padded = text_h + 2 * self.text_padding
|
402
|
+
|
403
|
+
text_background_xyxy = resolve_text_background_xyxy(
|
404
|
+
center_coordinates=tuple(center_coords),
|
405
|
+
text_wh=(width_padded, height_padded),
|
406
|
+
position=self.text_anchor,
|
407
|
+
)
|
408
|
+
|
409
|
+
label_properties.append(
|
410
|
+
[
|
411
|
+
*text_background_xyxy,
|
412
|
+
text_h,
|
413
|
+
]
|
414
|
+
)
|
415
|
+
|
416
|
+
return np.array(label_properties).reshape(-1, 5)
|
417
|
+
|
418
|
+
@staticmethod
|
419
|
+
def _get_labels_text(detections: Detections, custom_labels):
|
420
|
+
if custom_labels is not None:
|
421
|
+
return custom_labels
|
422
|
+
|
423
|
+
labels = []
|
424
|
+
for idx in range(len(detections)):
|
425
|
+
if CLASS_NAME_DATA_FIELD in detections.data:
|
426
|
+
labels.append(detections.data[CLASS_NAME_DATA_FIELD][idx])
|
427
|
+
elif detections.class_id is not None:
|
428
|
+
labels.append(str(detections.class_id[idx]))
|
429
|
+
else:
|
430
|
+
labels.append(str(idx))
|
431
|
+
return labels
|
432
|
+
|
433
|
+
def _draw_labels(
|
434
|
+
self,
|
435
|
+
scene,
|
436
|
+
labels,
|
437
|
+
label_properties,
|
438
|
+
detections,
|
439
|
+
custom_color_lookup,
|
440
|
+
) -> None:
|
441
|
+
assert len(labels) == len(label_properties) == len(detections), (
|
442
|
+
f"Number of label properties ({len(label_properties)}), "
|
443
|
+
f"labels ({len(labels)}) and detections ({len(detections)}) "
|
444
|
+
"do not match."
|
445
|
+
)
|
446
|
+
|
447
|
+
color_lookup = (
|
448
|
+
custom_color_lookup
|
449
|
+
if custom_color_lookup is not None
|
450
|
+
else self.color_lookup
|
451
|
+
)
|
452
|
+
|
453
|
+
for idx, label_property in enumerate(label_properties):
|
454
|
+
background_color = resolve_color(
|
455
|
+
color=self.color,
|
456
|
+
detections=detections,
|
457
|
+
detection_idx=idx,
|
458
|
+
color_lookup=color_lookup,
|
459
|
+
)
|
460
|
+
text_color = resolve_color(
|
461
|
+
color=self.text_color,
|
462
|
+
detections=detections,
|
463
|
+
detection_idx=idx,
|
464
|
+
color_lookup=color_lookup,
|
465
|
+
)
|
466
|
+
|
467
|
+
box_xyxy = label_property[:4]
|
468
|
+
text_height_padded = label_property[4]
|
469
|
+
self.draw_rounded_rectangle(
|
470
|
+
scene=scene,
|
471
|
+
xyxy=box_xyxy,
|
472
|
+
color=background_color.as_rgb(),
|
473
|
+
border_radius=self.border_radius,
|
474
|
+
)
|
475
|
+
|
476
|
+
text_x = box_xyxy[0] + self.text_padding
|
477
|
+
text_y = box_xyxy[1] + self.text_padding + text_height_padded
|
478
|
+
vf_cv2.putText(
|
479
|
+
img=scene,
|
480
|
+
text=labels[idx],
|
481
|
+
org=(text_x, text_y),
|
482
|
+
fontFace=CV2_FONT,
|
483
|
+
fontScale=self.text_scale,
|
484
|
+
color=text_color.as_rgb(),
|
485
|
+
thickness=self.text_thickness,
|
486
|
+
lineType=vf_cv2.LINE_AA,
|
487
|
+
)
|
488
|
+
|
489
|
+
@staticmethod
|
490
|
+
def draw_rounded_rectangle(
|
491
|
+
scene: np.ndarray,
|
492
|
+
xyxy,
|
493
|
+
color,
|
494
|
+
border_radius: int,
|
495
|
+
) -> np.ndarray:
|
496
|
+
x1, y1, x2, y2 = xyxy
|
497
|
+
width = x2 - x1
|
498
|
+
height = y2 - y1
|
499
|
+
|
500
|
+
border_radius = min(border_radius, min(width, height) // 2)
|
501
|
+
|
502
|
+
rectangle_coordinates = [
|
503
|
+
((x1 + border_radius, y1), (x2 - border_radius, y2)),
|
504
|
+
((x1, y1 + border_radius), (x2, y2 - border_radius)),
|
505
|
+
]
|
506
|
+
circle_centers = [
|
507
|
+
(x1 + border_radius, y1 + border_radius),
|
508
|
+
(x2 - border_radius, y1 + border_radius),
|
509
|
+
(x1 + border_radius, y2 - border_radius),
|
510
|
+
(x2 - border_radius, y2 - border_radius),
|
511
|
+
]
|
512
|
+
|
513
|
+
for coordinates in rectangle_coordinates:
|
514
|
+
vf_cv2.rectangle(
|
515
|
+
img=scene,
|
516
|
+
pt1=coordinates[0],
|
517
|
+
pt2=coordinates[1],
|
518
|
+
color=color,
|
519
|
+
thickness=-1,
|
520
|
+
)
|
521
|
+
for center in circle_centers:
|
522
|
+
vf_cv2.circle(
|
523
|
+
img=scene,
|
524
|
+
center=center,
|
525
|
+
radius=border_radius,
|
526
|
+
color=color,
|
527
|
+
thickness=-1,
|
528
|
+
)
|
529
|
+
return scene
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: vidformer
|
3
|
-
Version: 0.
|
4
|
-
Summary:
|
3
|
+
Version: 0.10.0
|
4
|
+
Summary: vidformer-py is a Python 🐍 interface for [vidformer](https://github.com/ixlab/vidformer).
|
5
5
|
Author-email: Dominik Winecki <dominikwinecki@gmail.com>
|
6
6
|
Requires-Python: >=3.8
|
7
7
|
Description-Content-Type: text/markdown
|
@@ -19,13 +19,15 @@ Project-URL: Issues, https://github.com/ixlab/vidformer/issues
|
|
19
19
|
[](https://pypi.org/project/vidformer/)
|
20
20
|
[](https://github.com/ixlab/vidformer/blob/main/LICENSE)
|
21
21
|
|
22
|
-
vidformer-py is a Python 🐍
|
22
|
+
vidformer-py is a Python 🐍 frontend for [vidformer](https://github.com/ixlab/vidformer).
|
23
|
+
It has an API compatability layer with OpenCV cv2, as well as some [supervision](https://github.com/roboflow/supervision) annotators.
|
23
24
|
Our [getting started guide](https://ixlab.github.io/vidformer/getting-started.html) explains how to use it.
|
24
25
|
|
25
26
|
**Quick links:**
|
26
27
|
* [📦 PyPI](https://pypi.org/project/vidformer/)
|
27
|
-
* [📘 Documentation - vidformer-py](https://ixlab.github.io/vidformer/vidformer-py/)
|
28
|
-
* [📘 Documentation - vidformer.cv2](https://ixlab.github.io/vidformer/vidformer-py
|
28
|
+
* [📘 Documentation - vidformer-py](https://ixlab.github.io/vidformer/vidformer-py/pdoc/)
|
29
|
+
* [📘 Documentation - vidformer.cv2](https://ixlab.github.io/vidformer/vidformer-py/pdoc/vidformer/cv2.html)
|
30
|
+
* [📘 Documentation - vidformer.supervision](https://ixlab.github.io/vidformer/vidformer-py/pdoc/vidformer/supervision.html)
|
29
31
|
* [🧑💻 Source Code](https://github.com/ixlab/vidformer/tree/main/vidformer-py/)
|
30
32
|
|
31
33
|
**Publish:**
|
@@ -0,0 +1,6 @@
|
|
1
|
+
vidformer/__init__.py,sha256=qpWcttHsW1wnaGx5__qJqaT-m5VF7yMiHCxdm10Fjek,44916
|
2
|
+
vidformer/cv2/__init__.py,sha256=DGm5NB4FGCHxPVez-yO748DjocKruxn4QBqqThgskWI,25555
|
3
|
+
vidformer/supervision/__init__.py,sha256=T2QJ3gKtUSoKOlxAf06TG4fD9IgIDuBpiVOBKVk3qAw,17150
|
4
|
+
vidformer-0.10.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
5
|
+
vidformer-0.10.0.dist-info/METADATA,sha256=f_aUIFbQUoVJuYTKtqexwyN5uzWRoS2Fvd2dHZ_EGbo,1800
|
6
|
+
vidformer-0.10.0.dist-info/RECORD,,
|