@camstack/addon-vision 0.1.0

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 (109) hide show
  1. package/dist/addons/animal-classifier/index.d.mts +25 -0
  2. package/dist/addons/animal-classifier/index.d.ts +25 -0
  3. package/dist/addons/animal-classifier/index.js +652 -0
  4. package/dist/addons/animal-classifier/index.js.map +1 -0
  5. package/dist/addons/animal-classifier/index.mjs +10 -0
  6. package/dist/addons/animal-classifier/index.mjs.map +1 -0
  7. package/dist/addons/audio-classification/index.d.mts +31 -0
  8. package/dist/addons/audio-classification/index.d.ts +31 -0
  9. package/dist/addons/audio-classification/index.js +572 -0
  10. package/dist/addons/audio-classification/index.js.map +1 -0
  11. package/dist/addons/audio-classification/index.mjs +8 -0
  12. package/dist/addons/audio-classification/index.mjs.map +1 -0
  13. package/dist/addons/bird-global-classifier/index.d.mts +26 -0
  14. package/dist/addons/bird-global-classifier/index.d.ts +26 -0
  15. package/dist/addons/bird-global-classifier/index.js +658 -0
  16. package/dist/addons/bird-global-classifier/index.js.map +1 -0
  17. package/dist/addons/bird-global-classifier/index.mjs +10 -0
  18. package/dist/addons/bird-global-classifier/index.mjs.map +1 -0
  19. package/dist/addons/bird-nabirds-classifier/index.d.mts +28 -0
  20. package/dist/addons/bird-nabirds-classifier/index.d.ts +28 -0
  21. package/dist/addons/bird-nabirds-classifier/index.js +700 -0
  22. package/dist/addons/bird-nabirds-classifier/index.js.map +1 -0
  23. package/dist/addons/bird-nabirds-classifier/index.mjs +10 -0
  24. package/dist/addons/bird-nabirds-classifier/index.mjs.map +1 -0
  25. package/dist/addons/camera-native-detection/index.d.mts +32 -0
  26. package/dist/addons/camera-native-detection/index.d.ts +32 -0
  27. package/dist/addons/camera-native-detection/index.js +99 -0
  28. package/dist/addons/camera-native-detection/index.js.map +1 -0
  29. package/dist/addons/camera-native-detection/index.mjs +7 -0
  30. package/dist/addons/camera-native-detection/index.mjs.map +1 -0
  31. package/dist/addons/face-detection/index.d.mts +24 -0
  32. package/dist/addons/face-detection/index.d.ts +24 -0
  33. package/dist/addons/face-detection/index.js +720 -0
  34. package/dist/addons/face-detection/index.js.map +1 -0
  35. package/dist/addons/face-detection/index.mjs +10 -0
  36. package/dist/addons/face-detection/index.mjs.map +1 -0
  37. package/dist/addons/face-recognition/index.d.mts +24 -0
  38. package/dist/addons/face-recognition/index.d.ts +24 -0
  39. package/dist/addons/face-recognition/index.js +603 -0
  40. package/dist/addons/face-recognition/index.js.map +1 -0
  41. package/dist/addons/face-recognition/index.mjs +9 -0
  42. package/dist/addons/face-recognition/index.mjs.map +1 -0
  43. package/dist/addons/motion-detection/index.d.mts +26 -0
  44. package/dist/addons/motion-detection/index.d.ts +26 -0
  45. package/dist/addons/motion-detection/index.js +273 -0
  46. package/dist/addons/motion-detection/index.js.map +1 -0
  47. package/dist/addons/motion-detection/index.mjs +8 -0
  48. package/dist/addons/motion-detection/index.mjs.map +1 -0
  49. package/dist/addons/object-detection/index.d.mts +26 -0
  50. package/dist/addons/object-detection/index.d.ts +26 -0
  51. package/dist/addons/object-detection/index.js +1214 -0
  52. package/dist/addons/object-detection/index.js.map +1 -0
  53. package/dist/addons/object-detection/index.mjs +10 -0
  54. package/dist/addons/object-detection/index.mjs.map +1 -0
  55. package/dist/addons/plate-detection/index.d.mts +25 -0
  56. package/dist/addons/plate-detection/index.d.ts +25 -0
  57. package/dist/addons/plate-detection/index.js +646 -0
  58. package/dist/addons/plate-detection/index.js.map +1 -0
  59. package/dist/addons/plate-detection/index.mjs +10 -0
  60. package/dist/addons/plate-detection/index.mjs.map +1 -0
  61. package/dist/addons/plate-recognition/index.d.mts +25 -0
  62. package/dist/addons/plate-recognition/index.d.ts +25 -0
  63. package/dist/addons/plate-recognition/index.js +648 -0
  64. package/dist/addons/plate-recognition/index.js.map +1 -0
  65. package/dist/addons/plate-recognition/index.mjs +9 -0
  66. package/dist/addons/plate-recognition/index.mjs.map +1 -0
  67. package/dist/chunk-3MQFUDRU.mjs +260 -0
  68. package/dist/chunk-3MQFUDRU.mjs.map +1 -0
  69. package/dist/chunk-5AIQSN32.mjs +227 -0
  70. package/dist/chunk-5AIQSN32.mjs.map +1 -0
  71. package/dist/chunk-5JJZGKL7.mjs +186 -0
  72. package/dist/chunk-5JJZGKL7.mjs.map +1 -0
  73. package/dist/chunk-6OR5TE7A.mjs +101 -0
  74. package/dist/chunk-6OR5TE7A.mjs.map +1 -0
  75. package/dist/chunk-AYBFB7ID.mjs +763 -0
  76. package/dist/chunk-AYBFB7ID.mjs.map +1 -0
  77. package/dist/chunk-B3R66MPF.mjs +219 -0
  78. package/dist/chunk-B3R66MPF.mjs.map +1 -0
  79. package/dist/chunk-DTOAB2CE.mjs +79 -0
  80. package/dist/chunk-DTOAB2CE.mjs.map +1 -0
  81. package/dist/chunk-ISOIDU4U.mjs +54 -0
  82. package/dist/chunk-ISOIDU4U.mjs.map +1 -0
  83. package/dist/chunk-J4WRYHHY.mjs +212 -0
  84. package/dist/chunk-J4WRYHHY.mjs.map +1 -0
  85. package/dist/chunk-KUO2BVFY.mjs +90 -0
  86. package/dist/chunk-KUO2BVFY.mjs.map +1 -0
  87. package/dist/chunk-LPI42WL6.mjs +324 -0
  88. package/dist/chunk-LPI42WL6.mjs.map +1 -0
  89. package/dist/chunk-MEVASN3P.mjs +305 -0
  90. package/dist/chunk-MEVASN3P.mjs.map +1 -0
  91. package/dist/chunk-PDSHDDPV.mjs +255 -0
  92. package/dist/chunk-PDSHDDPV.mjs.map +1 -0
  93. package/dist/chunk-Q3SQOYG6.mjs +218 -0
  94. package/dist/chunk-Q3SQOYG6.mjs.map +1 -0
  95. package/dist/chunk-QIMDG34B.mjs +229 -0
  96. package/dist/chunk-QIMDG34B.mjs.map +1 -0
  97. package/dist/index.d.mts +171 -0
  98. package/dist/index.d.ts +171 -0
  99. package/dist/index.js +3463 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/index.mjs +111 -0
  102. package/dist/index.mjs.map +1 -0
  103. package/package.json +49 -0
  104. package/python/__pycache__/coreml_inference.cpython-313.pyc +0 -0
  105. package/python/__pycache__/openvino_inference.cpython-313.pyc +0 -0
  106. package/python/__pycache__/pytorch_inference.cpython-313.pyc +0 -0
  107. package/python/coreml_inference.py +319 -0
  108. package/python/openvino_inference.py +247 -0
  109. package/python/pytorch_inference.py +255 -0
@@ -0,0 +1,763 @@
1
+ import {
2
+ nms,
3
+ yoloPostprocess
4
+ } from "./chunk-KUO2BVFY.mjs";
5
+ import {
6
+ letterbox
7
+ } from "./chunk-6OR5TE7A.mjs";
8
+ import {
9
+ resolveEngine
10
+ } from "./chunk-LPI42WL6.mjs";
11
+
12
+ // src/catalogs/object-detection-models.ts
13
+ import { hfModelUrl, COCO_80_LABELS } from "@camstack/types";
14
+ var HF_REPO = "camstack/camstack-models";
15
+ var OBJECT_DETECTION_MODELS = [
16
+ {
17
+ id: "yolov8n",
18
+ name: "YOLOv8 Nano",
19
+ description: "YOLOv8 Nano \u2014 fastest, smallest object detection model",
20
+ inputSize: { width: 640, height: 640 },
21
+ labels: COCO_80_LABELS,
22
+ formats: {
23
+ onnx: {
24
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8n.onnx"),
25
+ sizeMB: 12
26
+ },
27
+ coreml: {
28
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8n.mlpackage"),
29
+ sizeMB: 6
30
+ },
31
+ openvino: {
32
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8n.xml"),
33
+ sizeMB: 7
34
+ },
35
+ tflite: {
36
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8n_float32.tflite"),
37
+ sizeMB: 12
38
+ }
39
+ }
40
+ },
41
+ {
42
+ id: "yolov8s",
43
+ name: "YOLOv8 Small",
44
+ description: "YOLOv8 Small \u2014 balanced speed and accuracy",
45
+ inputSize: { width: 640, height: 640 },
46
+ labels: COCO_80_LABELS,
47
+ formats: {
48
+ onnx: {
49
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8s.onnx"),
50
+ sizeMB: 43
51
+ },
52
+ coreml: {
53
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8s.mlpackage"),
54
+ sizeMB: 21
55
+ },
56
+ openvino: {
57
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8s.xml"),
58
+ sizeMB: 22
59
+ },
60
+ tflite: {
61
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8s_float32.tflite"),
62
+ sizeMB: 43
63
+ }
64
+ }
65
+ },
66
+ {
67
+ id: "yolov8m",
68
+ name: "YOLOv8 Medium",
69
+ description: "YOLOv8 Medium \u2014 higher accuracy, moderate size",
70
+ inputSize: { width: 640, height: 640 },
71
+ labels: COCO_80_LABELS,
72
+ formats: {
73
+ onnx: {
74
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8m.onnx"),
75
+ sizeMB: 99
76
+ },
77
+ coreml: {
78
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8m.mlpackage"),
79
+ sizeMB: 49
80
+ },
81
+ openvino: {
82
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8m.xml"),
83
+ sizeMB: 50
84
+ },
85
+ tflite: {
86
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8m_float32.tflite"),
87
+ sizeMB: 99
88
+ }
89
+ }
90
+ },
91
+ {
92
+ id: "yolov9t",
93
+ name: "YOLOv9 Tiny",
94
+ description: "YOLOv9 Tiny \u2014 ultra-lightweight next-gen detector",
95
+ inputSize: { width: 640, height: 640 },
96
+ labels: COCO_80_LABELS,
97
+ formats: {
98
+ onnx: {
99
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9t.onnx"),
100
+ sizeMB: 8
101
+ },
102
+ coreml: {
103
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9t.mlpackage"),
104
+ sizeMB: 4
105
+ },
106
+ openvino: {
107
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9t.xml"),
108
+ sizeMB: 6
109
+ },
110
+ tflite: {
111
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9t_float32.tflite"),
112
+ sizeMB: 8
113
+ }
114
+ }
115
+ },
116
+ {
117
+ id: "yolov9s",
118
+ name: "YOLOv9 Small",
119
+ description: "YOLOv9 Small \u2014 improved efficiency over YOLOv8s",
120
+ inputSize: { width: 640, height: 640 },
121
+ labels: COCO_80_LABELS,
122
+ formats: {
123
+ onnx: {
124
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9s.onnx"),
125
+ sizeMB: 28
126
+ },
127
+ coreml: {
128
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9s.mlpackage"),
129
+ sizeMB: 14
130
+ },
131
+ openvino: {
132
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9s.xml"),
133
+ sizeMB: 16
134
+ },
135
+ tflite: {
136
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9s_float32.tflite"),
137
+ sizeMB: 28
138
+ }
139
+ }
140
+ },
141
+ {
142
+ id: "yolov9c",
143
+ name: "YOLOv9 C",
144
+ description: "YOLOv9 C \u2014 high-accuracy compact model",
145
+ inputSize: { width: 640, height: 640 },
146
+ labels: COCO_80_LABELS,
147
+ formats: {
148
+ onnx: {
149
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9c.onnx"),
150
+ sizeMB: 97
151
+ },
152
+ coreml: {
153
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9c.mlpackage"),
154
+ sizeMB: 48
155
+ },
156
+ openvino: {
157
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9c.xml"),
158
+ sizeMB: 49
159
+ },
160
+ tflite: {
161
+ url: hfModelUrl(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9c_float32.tflite"),
162
+ sizeMB: 97
163
+ }
164
+ }
165
+ },
166
+ // YOLO11 — no CoreML (coremltools incompatible)
167
+ {
168
+ id: "yolo11n",
169
+ name: "YOLO11 Nano",
170
+ description: "YOLO11 Nano \u2014 fastest, smallest YOLO11 detection model",
171
+ inputSize: { width: 640, height: 640 },
172
+ labels: COCO_80_LABELS,
173
+ formats: {
174
+ onnx: {
175
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11n.onnx"),
176
+ sizeMB: 10
177
+ },
178
+ openvino: {
179
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11n.xml"),
180
+ sizeMB: 5.4
181
+ },
182
+ tflite: {
183
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11n_float32.tflite"),
184
+ sizeMB: 10
185
+ }
186
+ }
187
+ },
188
+ {
189
+ id: "yolo11s",
190
+ name: "YOLO11 Small",
191
+ description: "YOLO11 Small \u2014 balanced speed and accuracy",
192
+ inputSize: { width: 640, height: 640 },
193
+ labels: COCO_80_LABELS,
194
+ formats: {
195
+ onnx: {
196
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11s.onnx"),
197
+ sizeMB: 36
198
+ },
199
+ openvino: {
200
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11s.xml"),
201
+ sizeMB: 18
202
+ },
203
+ tflite: {
204
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11s_float32.tflite"),
205
+ sizeMB: 36
206
+ }
207
+ }
208
+ },
209
+ {
210
+ id: "yolo11m",
211
+ name: "YOLO11 Medium",
212
+ description: "YOLO11 Medium \u2014 higher accuracy, moderate size",
213
+ inputSize: { width: 640, height: 640 },
214
+ labels: COCO_80_LABELS,
215
+ formats: {
216
+ onnx: {
217
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11m.onnx"),
218
+ sizeMB: 77
219
+ },
220
+ openvino: {
221
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11m.xml"),
222
+ sizeMB: 39
223
+ },
224
+ tflite: {
225
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11m_float32.tflite"),
226
+ sizeMB: 77
227
+ }
228
+ }
229
+ },
230
+ {
231
+ id: "yolo11l",
232
+ name: "YOLO11 Large",
233
+ description: "YOLO11 Large \u2014 high-accuracy large model",
234
+ inputSize: { width: 640, height: 640 },
235
+ labels: COCO_80_LABELS,
236
+ formats: {
237
+ onnx: {
238
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11l.onnx"),
239
+ sizeMB: 97
240
+ },
241
+ openvino: {
242
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11l.xml"),
243
+ sizeMB: 49
244
+ },
245
+ tflite: {
246
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11l_float32.tflite"),
247
+ sizeMB: 97
248
+ }
249
+ }
250
+ },
251
+ {
252
+ id: "yolo11x",
253
+ name: "YOLO11 Extra-Large",
254
+ description: "YOLO11 Extra-Large \u2014 maximum accuracy",
255
+ inputSize: { width: 640, height: 640 },
256
+ labels: COCO_80_LABELS,
257
+ formats: {
258
+ onnx: {
259
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11x.onnx"),
260
+ sizeMB: 218
261
+ },
262
+ openvino: {
263
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11x.xml"),
264
+ sizeMB: 109
265
+ },
266
+ tflite: {
267
+ url: hfModelUrl(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11x_float32.tflite"),
268
+ sizeMB: 218
269
+ }
270
+ }
271
+ }
272
+ ];
273
+
274
+ // src/catalogs/segmentation-models.ts
275
+ import { hfModelUrl as hfModelUrl2, COCO_80_LABELS as COCO_80_LABELS2 } from "@camstack/types";
276
+ var HF_REPO2 = "camstack/camstack-models";
277
+ var SEGMENTATION_MODELS = [
278
+ // YOLO11-seg — no CoreML (coremltools incompatible)
279
+ {
280
+ id: "yolo11n-seg",
281
+ name: "YOLO11 Nano Segmentation",
282
+ description: "YOLO11 Nano \u2014 fastest, smallest YOLO11 instance segmentation model",
283
+ inputSize: { width: 640, height: 640 },
284
+ labels: COCO_80_LABELS2,
285
+ formats: {
286
+ onnx: {
287
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolo11-seg/onnx/camstack-yolo11n-seg.onnx"),
288
+ sizeMB: 11
289
+ },
290
+ openvino: {
291
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolo11-seg/openvino/camstack-yolo11n-seg.xml"),
292
+ sizeMB: 6
293
+ }
294
+ }
295
+ },
296
+ {
297
+ id: "yolo11s-seg",
298
+ name: "YOLO11 Small Segmentation",
299
+ description: "YOLO11 Small \u2014 balanced speed and accuracy for instance segmentation",
300
+ inputSize: { width: 640, height: 640 },
301
+ labels: COCO_80_LABELS2,
302
+ formats: {
303
+ onnx: {
304
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolo11-seg/onnx/camstack-yolo11s-seg.onnx"),
305
+ sizeMB: 39
306
+ },
307
+ openvino: {
308
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolo11-seg/openvino/camstack-yolo11s-seg.xml"),
309
+ sizeMB: 20
310
+ }
311
+ }
312
+ },
313
+ {
314
+ id: "yolo11m-seg",
315
+ name: "YOLO11 Medium Segmentation",
316
+ description: "YOLO11 Medium \u2014 higher accuracy instance segmentation",
317
+ inputSize: { width: 640, height: 640 },
318
+ labels: COCO_80_LABELS2,
319
+ formats: {
320
+ onnx: {
321
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolo11-seg/onnx/camstack-yolo11m-seg.onnx"),
322
+ sizeMB: 86
323
+ },
324
+ openvino: {
325
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolo11-seg/openvino/camstack-yolo11m-seg.xml"),
326
+ sizeMB: 43
327
+ }
328
+ }
329
+ },
330
+ // YOLOv8-seg — CoreML available
331
+ {
332
+ id: "yolov8n-seg",
333
+ name: "YOLOv8 Nano Segmentation",
334
+ description: "YOLOv8 Nano \u2014 fastest, smallest YOLOv8 instance segmentation model",
335
+ inputSize: { width: 640, height: 640 },
336
+ labels: COCO_80_LABELS2,
337
+ formats: {
338
+ onnx: {
339
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/onnx/camstack-yolov8n-seg.onnx"),
340
+ sizeMB: 13
341
+ },
342
+ coreml: {
343
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/coreml/camstack-yolov8n-seg.mlpackage"),
344
+ sizeMB: 7
345
+ },
346
+ openvino: {
347
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/openvino/camstack-yolov8n-seg.xml"),
348
+ sizeMB: 7
349
+ }
350
+ }
351
+ },
352
+ {
353
+ id: "yolov8s-seg",
354
+ name: "YOLOv8 Small Segmentation",
355
+ description: "YOLOv8 Small \u2014 balanced speed and accuracy for instance segmentation",
356
+ inputSize: { width: 640, height: 640 },
357
+ labels: COCO_80_LABELS2,
358
+ formats: {
359
+ onnx: {
360
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/onnx/camstack-yolov8s-seg.onnx"),
361
+ sizeMB: 45
362
+ },
363
+ coreml: {
364
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/coreml/camstack-yolov8s-seg.mlpackage"),
365
+ sizeMB: 23
366
+ },
367
+ openvino: {
368
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/openvino/camstack-yolov8s-seg.xml"),
369
+ sizeMB: 23
370
+ }
371
+ }
372
+ },
373
+ {
374
+ id: "yolov8m-seg",
375
+ name: "YOLOv8 Medium Segmentation",
376
+ description: "YOLOv8 Medium \u2014 higher accuracy instance segmentation",
377
+ inputSize: { width: 640, height: 640 },
378
+ labels: COCO_80_LABELS2,
379
+ formats: {
380
+ onnx: {
381
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/onnx/camstack-yolov8m-seg.onnx"),
382
+ sizeMB: 104
383
+ },
384
+ coreml: {
385
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/coreml/camstack-yolov8m-seg.mlpackage"),
386
+ sizeMB: 52
387
+ },
388
+ openvino: {
389
+ url: hfModelUrl2(HF_REPO2, "segmentation/yolov8-seg/openvino/camstack-yolov8m-seg.xml"),
390
+ sizeMB: 53
391
+ }
392
+ }
393
+ }
394
+ ];
395
+
396
+ // src/addons/object-detection/index.ts
397
+ import { COCO_TO_MACRO, MACRO_LABELS, COCO_80_LABELS as COCO_80_LABELS3 } from "@camstack/types";
398
+
399
+ // src/shared/postprocess/yolo-seg.ts
400
+ function sigmoid(x) {
401
+ return 1 / (1 + Math.exp(-x));
402
+ }
403
+ function computeRawMask(coeffs, protos, numMaskCoeffs, maskH, maskW) {
404
+ const maskSize = maskH * maskW;
405
+ const rawMask = new Float32Array(maskSize);
406
+ for (let px = 0; px < maskSize; px++) {
407
+ let val = 0;
408
+ for (let k = 0; k < numMaskCoeffs; k++) {
409
+ val += (coeffs[k] ?? 0) * (protos[k * maskSize + px] ?? 0);
410
+ }
411
+ rawMask[px] = sigmoid(val);
412
+ }
413
+ return rawMask;
414
+ }
415
+ function cropAndThresholdMask(rawMask, maskH, maskW, bbox, maskThreshold, maskScale) {
416
+ const cropX1 = Math.max(0, Math.floor(bbox.x * maskScale));
417
+ const cropY1 = Math.max(0, Math.floor(bbox.y * maskScale));
418
+ const cropX2 = Math.min(maskW, Math.ceil((bbox.x + bbox.w) * maskScale));
419
+ const cropY2 = Math.min(maskH, Math.ceil((bbox.y + bbox.h) * maskScale));
420
+ const cropW = Math.max(1, cropX2 - cropX1);
421
+ const cropH = Math.max(1, cropY2 - cropY1);
422
+ const data = new Uint8Array(cropW * cropH);
423
+ for (let row = 0; row < cropH; row++) {
424
+ const srcRow = cropY1 + row;
425
+ for (let col = 0; col < cropW; col++) {
426
+ const srcCol = cropX1 + col;
427
+ const srcIdx = srcRow * maskW + srcCol;
428
+ data[row * cropW + col] = (rawMask[srcIdx] ?? 0) > maskThreshold ? 255 : 0;
429
+ }
430
+ }
431
+ return { data, width: cropW, height: cropH };
432
+ }
433
+ function yoloSegPostprocess(segOutput, options) {
434
+ const {
435
+ detectionOutput,
436
+ protoOutput,
437
+ numClasses,
438
+ numBoxes,
439
+ numMaskCoeffs,
440
+ maskHeight,
441
+ maskWidth
442
+ } = segOutput;
443
+ const {
444
+ confidence,
445
+ iouThreshold,
446
+ labels,
447
+ scale,
448
+ padX,
449
+ padY,
450
+ originalWidth,
451
+ originalHeight,
452
+ maskThreshold = 0.5
453
+ } = options;
454
+ const yoloInputSize = 640;
455
+ const maskScale = maskHeight / yoloInputSize;
456
+ const candidates = [];
457
+ for (let i = 0; i < numBoxes; i++) {
458
+ const cx = detectionOutput[0 * numBoxes + i] ?? 0;
459
+ const cy = detectionOutput[1 * numBoxes + i] ?? 0;
460
+ const w = detectionOutput[2 * numBoxes + i] ?? 0;
461
+ const h = detectionOutput[3 * numBoxes + i] ?? 0;
462
+ let bestScore = -Infinity;
463
+ let bestClass = 0;
464
+ for (let j = 0; j < numClasses; j++) {
465
+ const score = detectionOutput[(4 + j) * numBoxes + i] ?? 0;
466
+ if (score > bestScore) {
467
+ bestScore = score;
468
+ bestClass = j;
469
+ }
470
+ }
471
+ if (bestScore < confidence) continue;
472
+ const bbox = {
473
+ x: cx - w / 2,
474
+ y: cy - h / 2,
475
+ w,
476
+ h
477
+ };
478
+ const coeffs = new Float32Array(numMaskCoeffs);
479
+ for (let k = 0; k < numMaskCoeffs; k++) {
480
+ coeffs[k] = detectionOutput[(4 + numClasses + k) * numBoxes + i] ?? 0;
481
+ }
482
+ candidates.push({ bbox, score: bestScore, classIdx: bestClass, coeffs });
483
+ }
484
+ if (candidates.length === 0) return [];
485
+ const keptIndices = nms(candidates, iouThreshold);
486
+ return keptIndices.map((idx) => {
487
+ const { bbox, score, classIdx, coeffs } = candidates[idx];
488
+ const label = labels[classIdx] ?? String(classIdx);
489
+ const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale));
490
+ const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale));
491
+ const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale));
492
+ const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale));
493
+ const finalBbox = { x, y, w: x2 - x, h: y2 - y };
494
+ const rawMask = computeRawMask(coeffs, protoOutput, numMaskCoeffs, maskHeight, maskWidth);
495
+ const { data: maskData, width: mW, height: mH } = cropAndThresholdMask(
496
+ rawMask,
497
+ maskHeight,
498
+ maskWidth,
499
+ bbox,
500
+ maskThreshold,
501
+ maskScale
502
+ );
503
+ return {
504
+ class: label,
505
+ originalClass: label,
506
+ score,
507
+ bbox: finalBbox,
508
+ mask: maskData,
509
+ maskWidth: mW,
510
+ maskHeight: mH
511
+ };
512
+ });
513
+ }
514
+
515
+ // src/addons/object-detection/index.ts
516
+ function isSegModel(modelId) {
517
+ return modelId.includes("-seg");
518
+ }
519
+ var ALL_DETECTION_MODELS = [
520
+ ...OBJECT_DETECTION_MODELS,
521
+ ...SEGMENTATION_MODELS
522
+ ];
523
+ function applyClassMap(detections, classMap) {
524
+ return detections.filter((d) => classMap.mapping[d.class] !== void 0).map((d) => ({
525
+ ...d,
526
+ originalClass: d.class,
527
+ class: classMap.mapping[d.class]
528
+ }));
529
+ }
530
+ var ObjectDetectionAddon = class {
531
+ id = "object-detection";
532
+ slot = "detector";
533
+ inputClasses = null;
534
+ outputClasses = ["person", "vehicle", "animal"];
535
+ slotPriority = 0;
536
+ manifest = {
537
+ id: "object-detection",
538
+ name: "Object Detection",
539
+ version: "0.1.0",
540
+ description: "YOLO-based object detection \u2014 detects persons, vehicles, and animals",
541
+ packageName: "@camstack/addon-vision",
542
+ slot: "detector",
543
+ inputClasses: void 0,
544
+ outputClasses: ["person", "vehicle", "animal"],
545
+ supportsCustomModels: true,
546
+ mayRequirePython: false,
547
+ defaultConfig: {
548
+ modelId: "yolov8n",
549
+ runtime: "auto",
550
+ backend: "cpu",
551
+ confidence: 0.5,
552
+ iouThreshold: 0.45,
553
+ classMapMode: "macro"
554
+ }
555
+ };
556
+ engine;
557
+ modelEntry;
558
+ confidence = 0.5;
559
+ iouThreshold = 0.45;
560
+ classMapMode = "macro";
561
+ async initialize(ctx) {
562
+ const cfg = ctx.addonConfig;
563
+ const modelId = cfg["modelId"] ?? "yolov8n";
564
+ const runtime = cfg["runtime"] ?? "auto";
565
+ const backend = cfg["backend"] ?? "cpu";
566
+ this.confidence = cfg["confidence"] ?? 0.5;
567
+ this.iouThreshold = cfg["iouThreshold"] ?? 0.45;
568
+ this.classMapMode = cfg["classMapMode"] ?? "macro";
569
+ const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId);
570
+ if (!entry) {
571
+ throw new Error(`ObjectDetectionAddon: unknown modelId "${modelId}"`);
572
+ }
573
+ this.modelEntry = entry;
574
+ const resolved = await resolveEngine({
575
+ runtime,
576
+ backend,
577
+ modelEntry: entry,
578
+ modelsDir: ctx.locationPaths.models
579
+ });
580
+ this.engine = resolved.engine;
581
+ }
582
+ async detect(frame) {
583
+ const start = Date.now();
584
+ const { width: inputW, height: inputH } = this.modelEntry.inputSize;
585
+ const targetSize = Math.max(inputW, inputH);
586
+ const lb = await letterbox(frame.data, targetSize);
587
+ const numClasses = this.modelEntry.labels.length;
588
+ const labels = this.modelEntry.labels.map((l) => l.id);
589
+ const postprocessOpts = {
590
+ confidence: this.confidence,
591
+ iouThreshold: this.iouThreshold,
592
+ labels,
593
+ scale: lb.scale,
594
+ padX: lb.padX,
595
+ padY: lb.padY,
596
+ originalWidth: lb.originalWidth,
597
+ originalHeight: lb.originalHeight
598
+ };
599
+ let rawDetections;
600
+ if (isSegModel(this.modelEntry.id)) {
601
+ const outputs = await this.engine.runMultiOutput(lb.data, [1, 3, targetSize, targetSize]);
602
+ const outputNames = Object.keys(outputs);
603
+ if (outputNames.length < 2) {
604
+ throw new Error(
605
+ `ObjectDetectionAddon: seg model "${this.modelEntry.id}" returned ${outputNames.length} output(s); expected 2`
606
+ );
607
+ }
608
+ const detectionOutput = outputs[outputNames[0]];
609
+ const protoOutput = outputs[outputNames[1]];
610
+ const numMaskCoeffs = 32;
611
+ const numBoxes = detectionOutput.length / (4 + numClasses + numMaskCoeffs);
612
+ const maskHeight = 160;
613
+ const maskWidth = 160;
614
+ rawDetections = yoloSegPostprocess(
615
+ {
616
+ detectionOutput,
617
+ protoOutput,
618
+ numClasses,
619
+ numBoxes,
620
+ numMaskCoeffs,
621
+ maskHeight,
622
+ maskWidth
623
+ },
624
+ postprocessOpts
625
+ );
626
+ } else {
627
+ const output = await this.engine.run(lb.data, [1, 3, targetSize, targetSize]);
628
+ const numBoxes = output.length / (4 + numClasses);
629
+ rawDetections = yoloPostprocess(output, numClasses, numBoxes, postprocessOpts);
630
+ }
631
+ const detections = this.classMapMode === "all" ? rawDetections : applyClassMap(rawDetections, COCO_TO_MACRO);
632
+ return {
633
+ detections,
634
+ inferenceMs: Date.now() - start,
635
+ modelId: this.modelEntry.id
636
+ };
637
+ }
638
+ async shutdown() {
639
+ await this.engine?.dispose();
640
+ }
641
+ getConfigSchema() {
642
+ return {
643
+ sections: [
644
+ {
645
+ id: "model",
646
+ title: "Model",
647
+ columns: 2,
648
+ fields: [
649
+ {
650
+ key: "modelId",
651
+ label: "Model",
652
+ type: "model-selector",
653
+ catalog: [...ALL_DETECTION_MODELS],
654
+ allowCustom: true,
655
+ allowConversion: true,
656
+ acceptFormats: ["onnx", "coreml", "openvino", "tflite"],
657
+ requiredMetadata: ["inputSize", "labels", "outputFormat"],
658
+ outputFormatHint: "yolo"
659
+ }
660
+ ]
661
+ },
662
+ {
663
+ id: "runtime",
664
+ title: "Runtime",
665
+ columns: 2,
666
+ fields: [
667
+ {
668
+ key: "runtime",
669
+ label: "Runtime",
670
+ type: "select",
671
+ options: [
672
+ { value: "auto", label: "Auto (recommended)" },
673
+ { value: "onnx", label: "ONNX Runtime" },
674
+ { value: "coreml", label: "CoreML (Apple)" },
675
+ { value: "openvino", label: "OpenVINO (Intel)" }
676
+ ]
677
+ },
678
+ {
679
+ key: "backend",
680
+ label: "Backend",
681
+ type: "select",
682
+ dependsOn: { runtime: "onnx" },
683
+ options: [
684
+ { value: "cpu", label: "CPU" },
685
+ { value: "coreml", label: "CoreML" },
686
+ { value: "cuda", label: "CUDA (NVIDIA)" },
687
+ { value: "tensorrt", label: "TensorRT (NVIDIA)" }
688
+ ]
689
+ }
690
+ ]
691
+ },
692
+ {
693
+ id: "thresholds",
694
+ title: "Detection Thresholds",
695
+ columns: 2,
696
+ fields: [
697
+ {
698
+ key: "confidence",
699
+ label: "Confidence Threshold",
700
+ type: "slider",
701
+ min: 0.1,
702
+ max: 1,
703
+ step: 0.05,
704
+ default: 0.5
705
+ },
706
+ {
707
+ key: "iouThreshold",
708
+ label: "IoU Threshold (NMS)",
709
+ type: "slider",
710
+ min: 0.1,
711
+ max: 1,
712
+ step: 0.05,
713
+ default: 0.45
714
+ }
715
+ ]
716
+ },
717
+ {
718
+ id: "classmap",
719
+ title: "Class Mapping",
720
+ columns: 1,
721
+ fields: [
722
+ {
723
+ key: "classMapMode",
724
+ label: "Output classes",
725
+ type: "select",
726
+ options: [
727
+ { value: "macro", label: "Macro (person / vehicle / animal)" },
728
+ { value: "all", label: "All COCO classes (80)" }
729
+ ]
730
+ }
731
+ ]
732
+ }
733
+ ]
734
+ };
735
+ }
736
+ getClassMap() {
737
+ return COCO_TO_MACRO;
738
+ }
739
+ getModelCatalog() {
740
+ return [...ALL_DETECTION_MODELS];
741
+ }
742
+ getAvailableModels() {
743
+ return [];
744
+ }
745
+ getActiveLabels() {
746
+ return this.classMapMode === "all" ? COCO_80_LABELS3 : MACRO_LABELS;
747
+ }
748
+ async probe() {
749
+ return {
750
+ available: true,
751
+ runtime: this.engine?.runtime ?? "onnx",
752
+ device: this.engine?.device ?? "cpu",
753
+ capabilities: ["fp32"]
754
+ };
755
+ }
756
+ };
757
+
758
+ export {
759
+ OBJECT_DETECTION_MODELS,
760
+ SEGMENTATION_MODELS,
761
+ ObjectDetectionAddon
762
+ };
763
+ //# sourceMappingURL=chunk-AYBFB7ID.mjs.map