@camstack/addon-vision 0.1.7 → 0.1.10
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.
- package/dist/addons/animal-classifier/index.d.mts +30 -0
- package/dist/addons/animal-classifier/index.d.ts +30 -0
- package/dist/addons/animal-classifier/index.js +822 -999
- package/dist/addons/animal-classifier/index.js.map +1 -1
- package/dist/addons/animal-classifier/index.mjs +7 -242
- package/dist/addons/animal-classifier/index.mjs.map +1 -1
- package/dist/addons/audio-classification/index.d.mts +36 -0
- package/dist/addons/audio-classification/index.d.ts +36 -0
- package/dist/addons/audio-classification/index.js +378 -501
- package/dist/addons/audio-classification/index.js.map +1 -1
- package/dist/addons/audio-classification/index.mjs +4 -224
- package/dist/addons/audio-classification/index.mjs.map +1 -1
- package/dist/addons/bird-global-classifier/index.d.mts +31 -0
- package/dist/addons/bird-global-classifier/index.d.ts +31 -0
- package/dist/addons/bird-global-classifier/index.js +825 -1002
- package/dist/addons/bird-global-classifier/index.js.map +1 -1
- package/dist/addons/bird-global-classifier/index.mjs +7 -248
- package/dist/addons/bird-global-classifier/index.mjs.map +1 -1
- package/dist/addons/bird-nabirds-classifier/index.d.mts +33 -0
- package/dist/addons/bird-nabirds-classifier/index.d.ts +33 -0
- package/dist/addons/bird-nabirds-classifier/index.js +825 -1002
- package/dist/addons/bird-nabirds-classifier/index.js.map +1 -1
- package/dist/addons/bird-nabirds-classifier/index.mjs +7 -289
- package/dist/addons/bird-nabirds-classifier/index.mjs.map +1 -1
- package/dist/addons/face-detection/index.d.mts +29 -0
- package/dist/addons/face-detection/index.d.ts +29 -0
- package/dist/addons/face-detection/index.js +934 -1196
- package/dist/addons/face-detection/index.js.map +1 -1
- package/dist/addons/face-detection/index.mjs +7 -227
- package/dist/addons/face-detection/index.mjs.map +1 -1
- package/dist/addons/face-recognition/index.d.mts +29 -0
- package/dist/addons/face-recognition/index.d.ts +29 -0
- package/dist/addons/face-recognition/index.js +807 -1003
- package/dist/addons/face-recognition/index.js.map +1 -1
- package/dist/addons/face-recognition/index.mjs +6 -197
- package/dist/addons/face-recognition/index.mjs.map +1 -1
- package/dist/addons/motion-detection/index.d.mts +28 -0
- package/dist/addons/motion-detection/index.d.ts +28 -0
- package/dist/addons/motion-detection/index.js +111 -214
- package/dist/addons/motion-detection/index.js.map +1 -1
- package/dist/addons/motion-detection/index.mjs +9 -12
- package/dist/addons/motion-detection/index.mjs.map +1 -1
- package/dist/addons/object-detection/index.d.mts +31 -0
- package/dist/addons/object-detection/index.d.ts +31 -0
- package/dist/addons/object-detection/index.js +1082 -1287
- package/dist/addons/object-detection/index.js.map +1 -1
- package/dist/addons/object-detection/index.mjs +7 -373
- package/dist/addons/object-detection/index.mjs.map +1 -1
- package/dist/addons/plate-detection/index.d.mts +30 -0
- package/dist/addons/plate-detection/index.d.ts +30 -0
- package/dist/addons/plate-detection/index.js +868 -1075
- package/dist/addons/plate-detection/index.js.map +1 -1
- package/dist/addons/plate-detection/index.mjs +7 -230
- package/dist/addons/plate-detection/index.mjs.map +1 -1
- package/dist/addons/plate-recognition/index.d.mts +31 -0
- package/dist/addons/plate-recognition/index.d.ts +31 -0
- package/dist/addons/plate-recognition/index.js +505 -684
- package/dist/addons/plate-recognition/index.js.map +1 -1
- package/dist/addons/plate-recognition/index.mjs +5 -244
- package/dist/addons/plate-recognition/index.mjs.map +1 -1
- package/dist/addons/segmentation-refiner/index.d.mts +30 -0
- package/dist/addons/segmentation-refiner/index.d.ts +30 -0
- package/dist/addons/segmentation-refiner/index.js +790 -967
- package/dist/addons/segmentation-refiner/index.js.map +1 -1
- package/dist/addons/segmentation-refiner/index.mjs +17 -21
- package/dist/addons/segmentation-refiner/index.mjs.map +1 -1
- package/dist/addons/vehicle-classifier/index.d.mts +31 -0
- package/dist/addons/vehicle-classifier/index.d.ts +31 -0
- package/dist/addons/vehicle-classifier/index.js +410 -581
- package/dist/addons/vehicle-classifier/index.js.map +1 -1
- package/dist/addons/vehicle-classifier/index.mjs +16 -20
- package/dist/addons/vehicle-classifier/index.mjs.map +1 -1
- package/dist/chunk-22BHCDT5.mjs +101 -0
- package/dist/{chunk-WG66JYYW.mjs.map → chunk-22BHCDT5.mjs.map} +1 -1
- package/dist/chunk-2IOKI4ES.mjs +335 -0
- package/dist/{chunk-PIFS7AIT.mjs.map → chunk-2IOKI4ES.mjs.map} +1 -1
- package/dist/chunk-7DYHXUPZ.mjs +36 -0
- package/dist/{chunk-BS4DKYGN.mjs.map → chunk-7DYHXUPZ.mjs.map} +1 -1
- package/dist/chunk-BJTO5JO5.mjs +11 -0
- package/dist/chunk-BP7H4NFS.mjs +412 -0
- package/dist/{chunk-MGT6RUVX.mjs.map → chunk-BP7H4NFS.mjs.map} +1 -1
- package/dist/chunk-BR2FPGOX.mjs +98 -0
- package/dist/{chunk-YYDM6V2F.mjs.map → chunk-BR2FPGOX.mjs.map} +1 -1
- package/dist/chunk-D6WEHN33.mjs +276 -0
- package/dist/chunk-D6WEHN33.mjs.map +1 -0
- package/dist/chunk-DRYFGARD.mjs +289 -0
- package/dist/chunk-DRYFGARD.mjs.map +1 -0
- package/dist/chunk-DUN6XU3N.mjs +72 -0
- package/dist/{chunk-XD7WGXHZ.mjs.map → chunk-DUN6XU3N.mjs.map} +1 -1
- package/dist/chunk-ESLHNWWE.mjs +387 -0
- package/dist/chunk-ESLHNWWE.mjs.map +1 -0
- package/dist/chunk-JUQEW6ON.mjs +256 -0
- package/dist/chunk-JUQEW6ON.mjs.map +1 -0
- package/dist/chunk-KUO2BVFY.mjs +90 -0
- package/dist/{chunk-DE7I3VHO.mjs.map → chunk-KUO2BVFY.mjs.map} +1 -1
- package/dist/chunk-R5J3WAUI.mjs +645 -0
- package/dist/chunk-R5J3WAUI.mjs.map +1 -0
- package/dist/chunk-XZ6ZMXXU.mjs +39 -0
- package/dist/{chunk-K36R6HWY.mjs.map → chunk-XZ6ZMXXU.mjs.map} +1 -1
- package/dist/chunk-YPU4WTXZ.mjs +269 -0
- package/dist/chunk-YPU4WTXZ.mjs.map +1 -0
- package/dist/chunk-YUCD2TFH.mjs +242 -0
- package/dist/chunk-YUCD2TFH.mjs.map +1 -0
- package/dist/chunk-ZTJENCFC.mjs +379 -0
- package/dist/chunk-ZTJENCFC.mjs.map +1 -0
- package/dist/chunk-ZWYXXCXP.mjs +248 -0
- package/dist/chunk-ZWYXXCXP.mjs.map +1 -0
- package/dist/index.d.mts +183 -0
- package/dist/index.d.ts +183 -0
- package/dist/index.js +3930 -4449
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +250 -2698
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-2YMA6QOV.mjs +0 -193
- package/dist/chunk-2YMA6QOV.mjs.map +0 -1
- package/dist/chunk-3IIFBJCD.mjs +0 -45
- package/dist/chunk-BS4DKYGN.mjs +0 -48
- package/dist/chunk-DE7I3VHO.mjs +0 -106
- package/dist/chunk-F6D2OZ36.mjs +0 -89
- package/dist/chunk-F6D2OZ36.mjs.map +0 -1
- package/dist/chunk-GAOIFQDX.mjs +0 -59
- package/dist/chunk-GAOIFQDX.mjs.map +0 -1
- package/dist/chunk-HUIX2XVR.mjs +0 -159
- package/dist/chunk-HUIX2XVR.mjs.map +0 -1
- package/dist/chunk-K36R6HWY.mjs +0 -51
- package/dist/chunk-MBTAI3WE.mjs +0 -78
- package/dist/chunk-MBTAI3WE.mjs.map +0 -1
- package/dist/chunk-MGT6RUVX.mjs +0 -423
- package/dist/chunk-PIFS7AIT.mjs +0 -446
- package/dist/chunk-WG66JYYW.mjs +0 -116
- package/dist/chunk-XD7WGXHZ.mjs +0 -82
- package/dist/chunk-YYDM6V2F.mjs +0 -113
- package/dist/chunk-ZK7P3TZN.mjs +0 -286
- package/dist/chunk-ZK7P3TZN.mjs.map +0 -1
- /package/dist/{chunk-3IIFBJCD.mjs.map → chunk-BJTO5JO5.mjs.map} +0 -0
|
@@ -5,9 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
-
};
|
|
11
8
|
var __export = (target, all) => {
|
|
12
9
|
for (var name in all)
|
|
13
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -30,1349 +27,1147 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
27
|
));
|
|
31
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
29
|
|
|
33
|
-
// src/
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8n.mlpackage"),
|
|
61
|
-
sizeMB: 6,
|
|
62
|
-
isDirectory: true,
|
|
63
|
-
files: exports2.MLPACKAGE_FILES,
|
|
64
|
-
runtimes: ["python"]
|
|
65
|
-
},
|
|
66
|
-
openvino: {
|
|
67
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8n.xml"),
|
|
68
|
-
sizeMB: 7,
|
|
69
|
-
runtimes: ["python"]
|
|
70
|
-
},
|
|
71
|
-
tflite: {
|
|
72
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8n_float32.tflite"),
|
|
73
|
-
sizeMB: 12,
|
|
74
|
-
runtimes: ["python"]
|
|
75
|
-
}
|
|
76
|
-
}
|
|
30
|
+
// src/addons/object-detection/index.ts
|
|
31
|
+
var object_detection_exports = {};
|
|
32
|
+
__export(object_detection_exports, {
|
|
33
|
+
default: () => ObjectDetectionAddon
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(object_detection_exports);
|
|
36
|
+
|
|
37
|
+
// src/catalogs/object-detection-models.ts
|
|
38
|
+
var import_types = require("@camstack/types");
|
|
39
|
+
var HF_REPO = "camstack/camstack-models";
|
|
40
|
+
var MLPACKAGE_FILES = [
|
|
41
|
+
"Manifest.json",
|
|
42
|
+
"Data/com.apple.CoreML/model.mlmodel",
|
|
43
|
+
"Data/com.apple.CoreML/weights/weight.bin"
|
|
44
|
+
];
|
|
45
|
+
var OBJECT_DETECTION_MODELS = [
|
|
46
|
+
// ── YOLOv8 ──────────────────────────────────────────────────────
|
|
47
|
+
{
|
|
48
|
+
id: "yolov8n",
|
|
49
|
+
name: "YOLOv8 Nano",
|
|
50
|
+
description: "YOLOv8 Nano \u2014 fastest, smallest object detection model",
|
|
51
|
+
inputSize: { width: 640, height: 640 },
|
|
52
|
+
labels: import_types.COCO_80_LABELS,
|
|
53
|
+
formats: {
|
|
54
|
+
onnx: {
|
|
55
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8n.onnx"),
|
|
56
|
+
sizeMB: 12
|
|
77
57
|
},
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
formats: {
|
|
85
|
-
onnx: {
|
|
86
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8s.onnx"),
|
|
87
|
-
sizeMB: 43
|
|
88
|
-
},
|
|
89
|
-
coreml: {
|
|
90
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8s.mlpackage"),
|
|
91
|
-
sizeMB: 21,
|
|
92
|
-
isDirectory: true,
|
|
93
|
-
files: exports2.MLPACKAGE_FILES,
|
|
94
|
-
runtimes: ["python"]
|
|
95
|
-
},
|
|
96
|
-
openvino: {
|
|
97
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8s.xml"),
|
|
98
|
-
sizeMB: 22,
|
|
99
|
-
runtimes: ["python"]
|
|
100
|
-
},
|
|
101
|
-
tflite: {
|
|
102
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8s_float32.tflite"),
|
|
103
|
-
sizeMB: 43,
|
|
104
|
-
runtimes: ["python"]
|
|
105
|
-
}
|
|
106
|
-
}
|
|
58
|
+
coreml: {
|
|
59
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8n.mlpackage"),
|
|
60
|
+
sizeMB: 6,
|
|
61
|
+
isDirectory: true,
|
|
62
|
+
files: MLPACKAGE_FILES,
|
|
63
|
+
runtimes: ["python"]
|
|
107
64
|
},
|
|
108
|
-
{
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
inputSize: { width: 640, height: 640 },
|
|
113
|
-
labels: types_1.COCO_80_LABELS,
|
|
114
|
-
formats: {
|
|
115
|
-
onnx: {
|
|
116
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8s-relu.onnx"),
|
|
117
|
-
sizeMB: 43
|
|
118
|
-
}
|
|
119
|
-
}
|
|
65
|
+
openvino: {
|
|
66
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8n.xml"),
|
|
67
|
+
sizeMB: 7,
|
|
68
|
+
runtimes: ["python"]
|
|
120
69
|
},
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
},
|
|
139
|
-
openvino: {
|
|
140
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8m.xml"),
|
|
141
|
-
sizeMB: 50,
|
|
142
|
-
runtimes: ["python"]
|
|
143
|
-
},
|
|
144
|
-
tflite: {
|
|
145
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8m_float32.tflite"),
|
|
146
|
-
sizeMB: 99,
|
|
147
|
-
runtimes: ["python"]
|
|
148
|
-
}
|
|
149
|
-
}
|
|
70
|
+
tflite: {
|
|
71
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8n_float32.tflite"),
|
|
72
|
+
sizeMB: 12,
|
|
73
|
+
runtimes: ["python"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: "yolov8s",
|
|
79
|
+
name: "YOLOv8 Small",
|
|
80
|
+
description: "YOLOv8 Small \u2014 balanced speed and accuracy",
|
|
81
|
+
inputSize: { width: 640, height: 640 },
|
|
82
|
+
labels: import_types.COCO_80_LABELS,
|
|
83
|
+
formats: {
|
|
84
|
+
onnx: {
|
|
85
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8s.onnx"),
|
|
86
|
+
sizeMB: 43
|
|
150
87
|
},
|
|
151
|
-
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
formats: {
|
|
158
|
-
onnx: {
|
|
159
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8l.onnx"),
|
|
160
|
-
sizeMB: 167
|
|
161
|
-
},
|
|
162
|
-
coreml: {
|
|
163
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8l.mlpackage"),
|
|
164
|
-
sizeMB: 83,
|
|
165
|
-
isDirectory: true,
|
|
166
|
-
files: exports2.MLPACKAGE_FILES,
|
|
167
|
-
runtimes: ["python"]
|
|
168
|
-
},
|
|
169
|
-
openvino: {
|
|
170
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8l.xml"),
|
|
171
|
-
sizeMB: 84,
|
|
172
|
-
runtimes: ["python"]
|
|
173
|
-
}
|
|
174
|
-
}
|
|
88
|
+
coreml: {
|
|
89
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8s.mlpackage"),
|
|
90
|
+
sizeMB: 21,
|
|
91
|
+
isDirectory: true,
|
|
92
|
+
files: MLPACKAGE_FILES,
|
|
93
|
+
runtimes: ["python"]
|
|
175
94
|
},
|
|
176
|
-
{
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
inputSize: { width: 640, height: 640 },
|
|
181
|
-
labels: types_1.COCO_80_LABELS,
|
|
182
|
-
formats: {
|
|
183
|
-
onnx: {
|
|
184
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8x.onnx"),
|
|
185
|
-
sizeMB: 260
|
|
186
|
-
},
|
|
187
|
-
coreml: {
|
|
188
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8x.mlpackage"),
|
|
189
|
-
sizeMB: 130,
|
|
190
|
-
isDirectory: true,
|
|
191
|
-
files: exports2.MLPACKAGE_FILES,
|
|
192
|
-
runtimes: ["python"]
|
|
193
|
-
},
|
|
194
|
-
openvino: {
|
|
195
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8x.xml"),
|
|
196
|
-
sizeMB: 131,
|
|
197
|
-
runtimes: ["python"]
|
|
198
|
-
}
|
|
199
|
-
}
|
|
95
|
+
openvino: {
|
|
96
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8s.xml"),
|
|
97
|
+
sizeMB: 22,
|
|
98
|
+
runtimes: ["python"]
|
|
200
99
|
},
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
100
|
+
tflite: {
|
|
101
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8s_float32.tflite"),
|
|
102
|
+
sizeMB: 43,
|
|
103
|
+
runtimes: ["python"]
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: "yolov8s-relu",
|
|
109
|
+
name: "YOLOv8 Small ReLU",
|
|
110
|
+
description: "YOLOv8 Small with ReLU activation \u2014 better hardware compatibility",
|
|
111
|
+
inputSize: { width: 640, height: 640 },
|
|
112
|
+
labels: import_types.COCO_80_LABELS,
|
|
113
|
+
formats: {
|
|
114
|
+
onnx: {
|
|
115
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8s-relu.onnx"),
|
|
116
|
+
sizeMB: 43
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: "yolov8m",
|
|
122
|
+
name: "YOLOv8 Medium",
|
|
123
|
+
description: "YOLOv8 Medium \u2014 higher accuracy, moderate size",
|
|
124
|
+
inputSize: { width: 640, height: 640 },
|
|
125
|
+
labels: import_types.COCO_80_LABELS,
|
|
126
|
+
formats: {
|
|
127
|
+
onnx: {
|
|
128
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8m.onnx"),
|
|
129
|
+
sizeMB: 99
|
|
231
130
|
},
|
|
232
|
-
{
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
formats: {
|
|
239
|
-
onnx: {
|
|
240
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9s.onnx"),
|
|
241
|
-
sizeMB: 28
|
|
242
|
-
},
|
|
243
|
-
coreml: {
|
|
244
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9s.mlpackage"),
|
|
245
|
-
sizeMB: 14,
|
|
246
|
-
isDirectory: true,
|
|
247
|
-
files: exports2.MLPACKAGE_FILES,
|
|
248
|
-
runtimes: ["python"]
|
|
249
|
-
},
|
|
250
|
-
openvino: {
|
|
251
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9s.xml"),
|
|
252
|
-
sizeMB: 16,
|
|
253
|
-
runtimes: ["python"]
|
|
254
|
-
},
|
|
255
|
-
tflite: {
|
|
256
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9s_float32.tflite"),
|
|
257
|
-
sizeMB: 28,
|
|
258
|
-
runtimes: ["python"]
|
|
259
|
-
}
|
|
260
|
-
}
|
|
131
|
+
coreml: {
|
|
132
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8m.mlpackage"),
|
|
133
|
+
sizeMB: 49,
|
|
134
|
+
isDirectory: true,
|
|
135
|
+
files: MLPACKAGE_FILES,
|
|
136
|
+
runtimes: ["python"]
|
|
261
137
|
},
|
|
262
|
-
{
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
inputSize: { width: 640, height: 640 },
|
|
267
|
-
labels: types_1.COCO_80_LABELS,
|
|
268
|
-
formats: {
|
|
269
|
-
onnx: {
|
|
270
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9c.onnx"),
|
|
271
|
-
sizeMB: 97
|
|
272
|
-
},
|
|
273
|
-
coreml: {
|
|
274
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9c.mlpackage"),
|
|
275
|
-
sizeMB: 48,
|
|
276
|
-
isDirectory: true,
|
|
277
|
-
files: exports2.MLPACKAGE_FILES,
|
|
278
|
-
runtimes: ["python"]
|
|
279
|
-
},
|
|
280
|
-
openvino: {
|
|
281
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9c.xml"),
|
|
282
|
-
sizeMB: 49,
|
|
283
|
-
runtimes: ["python"]
|
|
284
|
-
},
|
|
285
|
-
tflite: {
|
|
286
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9c_float32.tflite"),
|
|
287
|
-
sizeMB: 97,
|
|
288
|
-
runtimes: ["python"]
|
|
289
|
-
}
|
|
290
|
-
}
|
|
138
|
+
openvino: {
|
|
139
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8m.xml"),
|
|
140
|
+
sizeMB: 50,
|
|
141
|
+
runtimes: ["python"]
|
|
291
142
|
},
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
runtimes: ["python"]
|
|
310
|
-
},
|
|
311
|
-
openvino: {
|
|
312
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11n.xml"),
|
|
313
|
-
sizeMB: 5,
|
|
314
|
-
runtimes: ["python"]
|
|
315
|
-
},
|
|
316
|
-
tflite: {
|
|
317
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11n_float32.tflite"),
|
|
318
|
-
sizeMB: 10,
|
|
319
|
-
runtimes: ["python"]
|
|
320
|
-
}
|
|
321
|
-
}
|
|
143
|
+
tflite: {
|
|
144
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/tflite/camstack-yolov8m_float32.tflite"),
|
|
145
|
+
sizeMB: 99,
|
|
146
|
+
runtimes: ["python"]
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "yolov8l",
|
|
152
|
+
name: "YOLOv8 Large",
|
|
153
|
+
description: "YOLOv8 Large \u2014 high-accuracy large model",
|
|
154
|
+
inputSize: { width: 640, height: 640 },
|
|
155
|
+
labels: import_types.COCO_80_LABELS,
|
|
156
|
+
formats: {
|
|
157
|
+
onnx: {
|
|
158
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8l.onnx"),
|
|
159
|
+
sizeMB: 167
|
|
322
160
|
},
|
|
323
|
-
{
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
formats: {
|
|
330
|
-
onnx: {
|
|
331
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11s.onnx"),
|
|
332
|
-
sizeMB: 36
|
|
333
|
-
},
|
|
334
|
-
coreml: {
|
|
335
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11s.mlpackage"),
|
|
336
|
-
sizeMB: 18,
|
|
337
|
-
isDirectory: true,
|
|
338
|
-
files: exports2.MLPACKAGE_FILES,
|
|
339
|
-
runtimes: ["python"]
|
|
340
|
-
},
|
|
341
|
-
openvino: {
|
|
342
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11s.xml"),
|
|
343
|
-
sizeMB: 18,
|
|
344
|
-
runtimes: ["python"]
|
|
345
|
-
},
|
|
346
|
-
tflite: {
|
|
347
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11s_float32.tflite"),
|
|
348
|
-
sizeMB: 36,
|
|
349
|
-
runtimes: ["python"]
|
|
350
|
-
}
|
|
351
|
-
}
|
|
161
|
+
coreml: {
|
|
162
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8l.mlpackage"),
|
|
163
|
+
sizeMB: 83,
|
|
164
|
+
isDirectory: true,
|
|
165
|
+
files: MLPACKAGE_FILES,
|
|
166
|
+
runtimes: ["python"]
|
|
352
167
|
},
|
|
353
|
-
{
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
},
|
|
371
|
-
openvino: {
|
|
372
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11m.xml"),
|
|
373
|
-
sizeMB: 39,
|
|
374
|
-
runtimes: ["python"]
|
|
375
|
-
},
|
|
376
|
-
tflite: {
|
|
377
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11m_float32.tflite"),
|
|
378
|
-
sizeMB: 77,
|
|
379
|
-
runtimes: ["python"]
|
|
380
|
-
}
|
|
381
|
-
}
|
|
168
|
+
openvino: {
|
|
169
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8l.xml"),
|
|
170
|
+
sizeMB: 84,
|
|
171
|
+
runtimes: ["python"]
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: "yolov8x",
|
|
177
|
+
name: "YOLOv8 Extra-Large",
|
|
178
|
+
description: "YOLOv8 Extra-Large \u2014 maximum accuracy",
|
|
179
|
+
inputSize: { width: 640, height: 640 },
|
|
180
|
+
labels: import_types.COCO_80_LABELS,
|
|
181
|
+
formats: {
|
|
182
|
+
onnx: {
|
|
183
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/onnx/camstack-yolov8x.onnx"),
|
|
184
|
+
sizeMB: 260
|
|
382
185
|
},
|
|
383
|
-
{
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
formats: {
|
|
390
|
-
onnx: {
|
|
391
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11l.onnx"),
|
|
392
|
-
sizeMB: 97
|
|
393
|
-
},
|
|
394
|
-
coreml: {
|
|
395
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11l.mlpackage"),
|
|
396
|
-
sizeMB: 49,
|
|
397
|
-
isDirectory: true,
|
|
398
|
-
files: exports2.MLPACKAGE_FILES,
|
|
399
|
-
runtimes: ["python"]
|
|
400
|
-
},
|
|
401
|
-
openvino: {
|
|
402
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11l.xml"),
|
|
403
|
-
sizeMB: 49,
|
|
404
|
-
runtimes: ["python"]
|
|
405
|
-
},
|
|
406
|
-
tflite: {
|
|
407
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11l_float32.tflite"),
|
|
408
|
-
sizeMB: 97,
|
|
409
|
-
runtimes: ["python"]
|
|
410
|
-
}
|
|
411
|
-
}
|
|
186
|
+
coreml: {
|
|
187
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/coreml/camstack-yolov8x.mlpackage"),
|
|
188
|
+
sizeMB: 130,
|
|
189
|
+
isDirectory: true,
|
|
190
|
+
files: MLPACKAGE_FILES,
|
|
191
|
+
runtimes: ["python"]
|
|
412
192
|
},
|
|
413
|
-
{
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
inputSize: { width: 640, height: 640 },
|
|
418
|
-
labels: types_1.COCO_80_LABELS,
|
|
419
|
-
formats: {
|
|
420
|
-
onnx: {
|
|
421
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11x.onnx"),
|
|
422
|
-
sizeMB: 218
|
|
423
|
-
},
|
|
424
|
-
coreml: {
|
|
425
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11x.mlpackage"),
|
|
426
|
-
sizeMB: 109,
|
|
427
|
-
isDirectory: true,
|
|
428
|
-
files: exports2.MLPACKAGE_FILES,
|
|
429
|
-
runtimes: ["python"]
|
|
430
|
-
},
|
|
431
|
-
openvino: {
|
|
432
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11x.xml"),
|
|
433
|
-
sizeMB: 109,
|
|
434
|
-
runtimes: ["python"]
|
|
435
|
-
},
|
|
436
|
-
tflite: {
|
|
437
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11x_float32.tflite"),
|
|
438
|
-
sizeMB: 218,
|
|
439
|
-
runtimes: ["python"]
|
|
440
|
-
}
|
|
441
|
-
}
|
|
193
|
+
openvino: {
|
|
194
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov8/openvino/camstack-yolov8x.xml"),
|
|
195
|
+
sizeMB: 131,
|
|
196
|
+
runtimes: ["python"]
|
|
442
197
|
}
|
|
443
|
-
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
exports2.SEGMENTATION_MODELS = [
|
|
457
|
-
// ── YOLO11-seg ───────────────────────────────────────────────
|
|
458
|
-
{
|
|
459
|
-
id: "yolo11n-seg",
|
|
460
|
-
name: "YOLO11 Nano Segmentation",
|
|
461
|
-
description: "YOLO11 Nano \u2014 fastest, smallest YOLO11 instance segmentation model",
|
|
462
|
-
inputSize: { width: 640, height: 640 },
|
|
463
|
-
labels: types_1.COCO_80_LABELS,
|
|
464
|
-
formats: {
|
|
465
|
-
onnx: {
|
|
466
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/onnx/camstack-yolo11n-seg.onnx"),
|
|
467
|
-
sizeMB: 11
|
|
468
|
-
},
|
|
469
|
-
coreml: {
|
|
470
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/coreml/camstack-yolo11n-seg.mlpackage"),
|
|
471
|
-
sizeMB: 6,
|
|
472
|
-
isDirectory: true,
|
|
473
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
474
|
-
runtimes: ["python"]
|
|
475
|
-
},
|
|
476
|
-
openvino: {
|
|
477
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/openvino/camstack-yolo11n-seg.xml"),
|
|
478
|
-
sizeMB: 6,
|
|
479
|
-
runtimes: ["python"]
|
|
480
|
-
}
|
|
481
|
-
}
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
// ── YOLOv9 ──────────────────────────────────────────────────────
|
|
201
|
+
{
|
|
202
|
+
id: "yolov9t",
|
|
203
|
+
name: "YOLOv9 Tiny",
|
|
204
|
+
description: "YOLOv9 Tiny \u2014 ultra-lightweight next-gen detector",
|
|
205
|
+
inputSize: { width: 640, height: 640 },
|
|
206
|
+
labels: import_types.COCO_80_LABELS,
|
|
207
|
+
formats: {
|
|
208
|
+
onnx: {
|
|
209
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9t.onnx"),
|
|
210
|
+
sizeMB: 8
|
|
482
211
|
},
|
|
483
|
-
{
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
formats: {
|
|
490
|
-
onnx: {
|
|
491
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/onnx/camstack-yolo11s-seg.onnx"),
|
|
492
|
-
sizeMB: 39
|
|
493
|
-
},
|
|
494
|
-
coreml: {
|
|
495
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/coreml/camstack-yolo11s-seg.mlpackage"),
|
|
496
|
-
sizeMB: 20,
|
|
497
|
-
isDirectory: true,
|
|
498
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
499
|
-
runtimes: ["python"]
|
|
500
|
-
},
|
|
501
|
-
openvino: {
|
|
502
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/openvino/camstack-yolo11s-seg.xml"),
|
|
503
|
-
sizeMB: 20,
|
|
504
|
-
runtimes: ["python"]
|
|
505
|
-
}
|
|
506
|
-
}
|
|
212
|
+
coreml: {
|
|
213
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9t.mlpackage"),
|
|
214
|
+
sizeMB: 4,
|
|
215
|
+
isDirectory: true,
|
|
216
|
+
files: MLPACKAGE_FILES,
|
|
217
|
+
runtimes: ["python"]
|
|
507
218
|
},
|
|
508
|
-
{
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
inputSize: { width: 640, height: 640 },
|
|
513
|
-
labels: types_1.COCO_80_LABELS,
|
|
514
|
-
formats: {
|
|
515
|
-
onnx: {
|
|
516
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/onnx/camstack-yolo11m-seg.onnx"),
|
|
517
|
-
sizeMB: 86
|
|
518
|
-
},
|
|
519
|
-
coreml: {
|
|
520
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/coreml/camstack-yolo11m-seg.mlpackage"),
|
|
521
|
-
sizeMB: 43,
|
|
522
|
-
isDirectory: true,
|
|
523
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
524
|
-
runtimes: ["python"]
|
|
525
|
-
},
|
|
526
|
-
openvino: {
|
|
527
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolo11-seg/openvino/camstack-yolo11m-seg.xml"),
|
|
528
|
-
sizeMB: 43,
|
|
529
|
-
runtimes: ["python"]
|
|
530
|
-
}
|
|
531
|
-
}
|
|
219
|
+
openvino: {
|
|
220
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9t.xml"),
|
|
221
|
+
sizeMB: 6,
|
|
222
|
+
runtimes: ["python"]
|
|
532
223
|
},
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
runtimes: ["python"]
|
|
551
|
-
},
|
|
552
|
-
openvino: {
|
|
553
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolov8-seg/openvino/camstack-yolov8n-seg.xml"),
|
|
554
|
-
sizeMB: 7,
|
|
555
|
-
runtimes: ["python"]
|
|
556
|
-
}
|
|
557
|
-
}
|
|
224
|
+
tflite: {
|
|
225
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9t_float32.tflite"),
|
|
226
|
+
sizeMB: 8,
|
|
227
|
+
runtimes: ["python"]
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: "yolov9s",
|
|
233
|
+
name: "YOLOv9 Small",
|
|
234
|
+
description: "YOLOv9 Small \u2014 improved efficiency over YOLOv8s",
|
|
235
|
+
inputSize: { width: 640, height: 640 },
|
|
236
|
+
labels: import_types.COCO_80_LABELS,
|
|
237
|
+
formats: {
|
|
238
|
+
onnx: {
|
|
239
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9s.onnx"),
|
|
240
|
+
sizeMB: 28
|
|
558
241
|
},
|
|
559
|
-
{
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
formats: {
|
|
566
|
-
onnx: {
|
|
567
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolov8-seg/onnx/camstack-yolov8s-seg.onnx"),
|
|
568
|
-
sizeMB: 45
|
|
569
|
-
},
|
|
570
|
-
coreml: {
|
|
571
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolov8-seg/coreml/camstack-yolov8s-seg.mlpackage"),
|
|
572
|
-
sizeMB: 23,
|
|
573
|
-
isDirectory: true,
|
|
574
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
575
|
-
runtimes: ["python"]
|
|
576
|
-
},
|
|
577
|
-
openvino: {
|
|
578
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolov8-seg/openvino/camstack-yolov8s-seg.xml"),
|
|
579
|
-
sizeMB: 23,
|
|
580
|
-
runtimes: ["python"]
|
|
581
|
-
}
|
|
582
|
-
}
|
|
242
|
+
coreml: {
|
|
243
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9s.mlpackage"),
|
|
244
|
+
sizeMB: 14,
|
|
245
|
+
isDirectory: true,
|
|
246
|
+
files: MLPACKAGE_FILES,
|
|
247
|
+
runtimes: ["python"]
|
|
583
248
|
},
|
|
584
|
-
{
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
sizeMB: 104
|
|
594
|
-
},
|
|
595
|
-
coreml: {
|
|
596
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolov8-seg/coreml/camstack-yolov8m-seg.mlpackage"),
|
|
597
|
-
sizeMB: 52,
|
|
598
|
-
isDirectory: true,
|
|
599
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
600
|
-
runtimes: ["python"]
|
|
601
|
-
},
|
|
602
|
-
openvino: {
|
|
603
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "segmentation/yolov8-seg/openvino/camstack-yolov8m-seg.xml"),
|
|
604
|
-
sizeMB: 53,
|
|
605
|
-
runtimes: ["python"]
|
|
606
|
-
}
|
|
607
|
-
}
|
|
249
|
+
openvino: {
|
|
250
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9s.xml"),
|
|
251
|
+
sizeMB: 16,
|
|
252
|
+
runtimes: ["python"]
|
|
253
|
+
},
|
|
254
|
+
tflite: {
|
|
255
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9s_float32.tflite"),
|
|
256
|
+
sizeMB: 28,
|
|
257
|
+
runtimes: ["python"]
|
|
608
258
|
}
|
|
609
|
-
];
|
|
610
|
-
}
|
|
611
|
-
});
|
|
612
|
-
|
|
613
|
-
// src/shared/image-utils.js
|
|
614
|
-
var require_image_utils = __commonJS({
|
|
615
|
-
"src/shared/image-utils.js"(exports2) {
|
|
616
|
-
"use strict";
|
|
617
|
-
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
618
|
-
return mod && mod.__esModule ? mod : { "default": mod };
|
|
619
|
-
};
|
|
620
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
621
|
-
exports2.jpegToRgb = jpegToRgb;
|
|
622
|
-
exports2.cropRegion = cropRegion;
|
|
623
|
-
exports2.letterbox = letterbox2;
|
|
624
|
-
exports2.resizeAndNormalize = resizeAndNormalize;
|
|
625
|
-
exports2.rgbToGrayscale = rgbToGrayscale;
|
|
626
|
-
var sharp_1 = __importDefault(require("sharp"));
|
|
627
|
-
async function jpegToRgb(jpeg) {
|
|
628
|
-
const { data, info } = await (0, sharp_1.default)(jpeg).removeAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
629
|
-
return { data, width: info.width, height: info.height };
|
|
630
259
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
float32[0 * numPixels + i] = data[srcBase] / 255;
|
|
660
|
-
float32[1 * numPixels + i] = data[srcBase + 1] / 255;
|
|
661
|
-
float32[2 * numPixels + i] = data[srcBase + 2] / 255;
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
id: "yolov9c",
|
|
263
|
+
name: "YOLOv9 C",
|
|
264
|
+
description: "YOLOv9 C \u2014 high-accuracy compact model",
|
|
265
|
+
inputSize: { width: 640, height: 640 },
|
|
266
|
+
labels: import_types.COCO_80_LABELS,
|
|
267
|
+
formats: {
|
|
268
|
+
onnx: {
|
|
269
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/onnx/camstack-yolov9c.onnx"),
|
|
270
|
+
sizeMB: 97
|
|
271
|
+
},
|
|
272
|
+
coreml: {
|
|
273
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/coreml/camstack-yolov9c.mlpackage"),
|
|
274
|
+
sizeMB: 48,
|
|
275
|
+
isDirectory: true,
|
|
276
|
+
files: MLPACKAGE_FILES,
|
|
277
|
+
runtimes: ["python"]
|
|
278
|
+
},
|
|
279
|
+
openvino: {
|
|
280
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/openvino/camstack-yolov9c.xml"),
|
|
281
|
+
sizeMB: 49,
|
|
282
|
+
runtimes: ["python"]
|
|
283
|
+
},
|
|
284
|
+
tflite: {
|
|
285
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolov9/tflite/camstack-yolov9c_float32.tflite"),
|
|
286
|
+
sizeMB: 97,
|
|
287
|
+
runtimes: ["python"]
|
|
662
288
|
}
|
|
663
|
-
return { data: float32, scale, padX, padY, originalWidth, originalHeight };
|
|
664
289
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
val = raw;
|
|
695
|
-
} else if (normalization === "imagenet") {
|
|
696
|
-
val = (raw - mean[c]) / std[c];
|
|
697
|
-
} else {
|
|
698
|
-
val = data[srcBase + c];
|
|
699
|
-
}
|
|
700
|
-
float32[i * 3 + c] = val;
|
|
701
|
-
}
|
|
702
|
-
}
|
|
290
|
+
},
|
|
291
|
+
// ── YOLO11 ────────────────────────────────────────────────────
|
|
292
|
+
{
|
|
293
|
+
id: "yolo11n",
|
|
294
|
+
name: "YOLO11 Nano",
|
|
295
|
+
description: "YOLO11 Nano \u2014 fastest, smallest YOLO11 detection model (mAP 39.5)",
|
|
296
|
+
inputSize: { width: 640, height: 640 },
|
|
297
|
+
labels: import_types.COCO_80_LABELS,
|
|
298
|
+
formats: {
|
|
299
|
+
onnx: {
|
|
300
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11n.onnx"),
|
|
301
|
+
sizeMB: 10
|
|
302
|
+
},
|
|
303
|
+
coreml: {
|
|
304
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11n.mlpackage"),
|
|
305
|
+
sizeMB: 5,
|
|
306
|
+
isDirectory: true,
|
|
307
|
+
files: MLPACKAGE_FILES,
|
|
308
|
+
runtimes: ["python"]
|
|
309
|
+
},
|
|
310
|
+
openvino: {
|
|
311
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11n.xml"),
|
|
312
|
+
sizeMB: 5,
|
|
313
|
+
runtimes: ["python"]
|
|
314
|
+
},
|
|
315
|
+
tflite: {
|
|
316
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11n_float32.tflite"),
|
|
317
|
+
sizeMB: 10,
|
|
318
|
+
runtimes: ["python"]
|
|
703
319
|
}
|
|
704
|
-
return float32;
|
|
705
320
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
id: "yolo11s",
|
|
324
|
+
name: "YOLO11 Small",
|
|
325
|
+
description: "YOLO11 Small \u2014 balanced speed and accuracy (mAP 47.0)",
|
|
326
|
+
inputSize: { width: 640, height: 640 },
|
|
327
|
+
labels: import_types.COCO_80_LABELS,
|
|
328
|
+
formats: {
|
|
329
|
+
onnx: {
|
|
330
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11s.onnx"),
|
|
331
|
+
sizeMB: 36
|
|
332
|
+
},
|
|
333
|
+
coreml: {
|
|
334
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11s.mlpackage"),
|
|
335
|
+
sizeMB: 18,
|
|
336
|
+
isDirectory: true,
|
|
337
|
+
files: MLPACKAGE_FILES,
|
|
338
|
+
runtimes: ["python"]
|
|
339
|
+
},
|
|
340
|
+
openvino: {
|
|
341
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11s.xml"),
|
|
342
|
+
sizeMB: 18,
|
|
343
|
+
runtimes: ["python"]
|
|
344
|
+
},
|
|
345
|
+
tflite: {
|
|
346
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11s_float32.tflite"),
|
|
347
|
+
sizeMB: 36,
|
|
348
|
+
runtimes: ["python"]
|
|
714
349
|
}
|
|
715
|
-
return gray;
|
|
716
350
|
}
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
const areaA = a.w * a.h;
|
|
747
|
-
const areaB = b.w * b.h;
|
|
748
|
-
const unionArea = areaA + areaB - interArea;
|
|
749
|
-
return unionArea === 0 ? 0 : interArea / unionArea;
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
id: "yolo11m",
|
|
354
|
+
name: "YOLO11 Medium",
|
|
355
|
+
description: "YOLO11 Medium \u2014 higher accuracy, moderate size (mAP 51.5)",
|
|
356
|
+
inputSize: { width: 640, height: 640 },
|
|
357
|
+
labels: import_types.COCO_80_LABELS,
|
|
358
|
+
formats: {
|
|
359
|
+
onnx: {
|
|
360
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11m.onnx"),
|
|
361
|
+
sizeMB: 77
|
|
362
|
+
},
|
|
363
|
+
coreml: {
|
|
364
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11m.mlpackage"),
|
|
365
|
+
sizeMB: 39,
|
|
366
|
+
isDirectory: true,
|
|
367
|
+
files: MLPACKAGE_FILES,
|
|
368
|
+
runtimes: ["python"]
|
|
369
|
+
},
|
|
370
|
+
openvino: {
|
|
371
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11m.xml"),
|
|
372
|
+
sizeMB: 39,
|
|
373
|
+
runtimes: ["python"]
|
|
374
|
+
},
|
|
375
|
+
tflite: {
|
|
376
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11m_float32.tflite"),
|
|
377
|
+
sizeMB: 77,
|
|
378
|
+
runtimes: ["python"]
|
|
379
|
+
}
|
|
750
380
|
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
id: "yolo11l",
|
|
384
|
+
name: "YOLO11 Large",
|
|
385
|
+
description: "YOLO11 Large \u2014 high-accuracy large model (mAP 53.4)",
|
|
386
|
+
inputSize: { width: 640, height: 640 },
|
|
387
|
+
labels: import_types.COCO_80_LABELS,
|
|
388
|
+
formats: {
|
|
389
|
+
onnx: {
|
|
390
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11l.onnx"),
|
|
391
|
+
sizeMB: 97
|
|
392
|
+
},
|
|
393
|
+
coreml: {
|
|
394
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11l.mlpackage"),
|
|
395
|
+
sizeMB: 49,
|
|
396
|
+
isDirectory: true,
|
|
397
|
+
files: MLPACKAGE_FILES,
|
|
398
|
+
runtimes: ["python"]
|
|
399
|
+
},
|
|
400
|
+
openvino: {
|
|
401
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11l.xml"),
|
|
402
|
+
sizeMB: 49,
|
|
403
|
+
runtimes: ["python"]
|
|
404
|
+
},
|
|
405
|
+
tflite: {
|
|
406
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11l_float32.tflite"),
|
|
407
|
+
sizeMB: 97,
|
|
408
|
+
runtimes: ["python"]
|
|
766
409
|
}
|
|
767
|
-
return kept;
|
|
768
410
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
id: "yolo11x",
|
|
414
|
+
name: "YOLO11 Extra-Large",
|
|
415
|
+
description: "YOLO11 Extra-Large \u2014 maximum accuracy (mAP 54.7)",
|
|
416
|
+
inputSize: { width: 640, height: 640 },
|
|
417
|
+
labels: import_types.COCO_80_LABELS,
|
|
418
|
+
formats: {
|
|
419
|
+
onnx: {
|
|
420
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/onnx/camstack-yolo11x.onnx"),
|
|
421
|
+
sizeMB: 218
|
|
422
|
+
},
|
|
423
|
+
coreml: {
|
|
424
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/coreml/camstack-yolo11x.mlpackage"),
|
|
425
|
+
sizeMB: 109,
|
|
426
|
+
isDirectory: true,
|
|
427
|
+
files: MLPACKAGE_FILES,
|
|
428
|
+
runtimes: ["python"]
|
|
429
|
+
},
|
|
430
|
+
openvino: {
|
|
431
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/openvino/camstack-yolo11x.xml"),
|
|
432
|
+
sizeMB: 109,
|
|
433
|
+
runtimes: ["python"]
|
|
434
|
+
},
|
|
435
|
+
tflite: {
|
|
436
|
+
url: (0, import_types.hfModelUrl)(HF_REPO, "objectDetection/yolo11/tflite/camstack-yolo11x_float32.tflite"),
|
|
437
|
+
sizeMB: 218,
|
|
438
|
+
runtimes: ["python"]
|
|
795
439
|
}
|
|
796
|
-
if (candidates.length === 0)
|
|
797
|
-
return [];
|
|
798
|
-
const keptIndices = nms(candidates, iouThreshold);
|
|
799
|
-
return keptIndices.map((idx) => {
|
|
800
|
-
const { bbox, score, classIdx } = candidates[idx];
|
|
801
|
-
const label = labels[classIdx] ?? String(classIdx);
|
|
802
|
-
const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale));
|
|
803
|
-
const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale));
|
|
804
|
-
const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale));
|
|
805
|
-
const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale));
|
|
806
|
-
const finalBbox = { x, y, w: x2 - x, h: y2 - y };
|
|
807
|
-
return {
|
|
808
|
-
class: label,
|
|
809
|
-
originalClass: label,
|
|
810
|
-
score,
|
|
811
|
-
bbox: finalBbox
|
|
812
|
-
};
|
|
813
|
-
});
|
|
814
440
|
}
|
|
815
441
|
}
|
|
816
|
-
|
|
442
|
+
];
|
|
817
443
|
|
|
818
|
-
// src/
|
|
819
|
-
var
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
444
|
+
// src/catalogs/segmentation-models.ts
|
|
445
|
+
var import_types2 = require("@camstack/types");
|
|
446
|
+
var HF_REPO2 = "camstack/camstack-models";
|
|
447
|
+
var SEGMENTATION_MODELS = [
|
|
448
|
+
// ── YOLO11-seg ───────────────────────────────────────────────
|
|
449
|
+
{
|
|
450
|
+
id: "yolo11n-seg",
|
|
451
|
+
name: "YOLO11 Nano Segmentation",
|
|
452
|
+
description: "YOLO11 Nano \u2014 fastest, smallest YOLO11 instance segmentation model",
|
|
453
|
+
inputSize: { width: 640, height: 640 },
|
|
454
|
+
labels: import_types2.COCO_80_LABELS,
|
|
455
|
+
formats: {
|
|
456
|
+
onnx: {
|
|
457
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/onnx/camstack-yolo11n-seg.onnx"),
|
|
458
|
+
sizeMB: 11
|
|
459
|
+
},
|
|
460
|
+
coreml: {
|
|
461
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/coreml/camstack-yolo11n-seg.mlpackage"),
|
|
462
|
+
sizeMB: 6,
|
|
463
|
+
isDirectory: true,
|
|
464
|
+
files: MLPACKAGE_FILES,
|
|
465
|
+
runtimes: ["python"]
|
|
466
|
+
},
|
|
467
|
+
openvino: {
|
|
468
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/openvino/camstack-yolo11n-seg.xml"),
|
|
469
|
+
sizeMB: 6,
|
|
470
|
+
runtimes: ["python"]
|
|
471
|
+
}
|
|
830
472
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
id: "yolo11s-seg",
|
|
476
|
+
name: "YOLO11 Small Segmentation",
|
|
477
|
+
description: "YOLO11 Small \u2014 balanced speed and accuracy for instance segmentation",
|
|
478
|
+
inputSize: { width: 640, height: 640 },
|
|
479
|
+
labels: import_types2.COCO_80_LABELS,
|
|
480
|
+
formats: {
|
|
481
|
+
onnx: {
|
|
482
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/onnx/camstack-yolo11s-seg.onnx"),
|
|
483
|
+
sizeMB: 39
|
|
484
|
+
},
|
|
485
|
+
coreml: {
|
|
486
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/coreml/camstack-yolo11s-seg.mlpackage"),
|
|
487
|
+
sizeMB: 20,
|
|
488
|
+
isDirectory: true,
|
|
489
|
+
files: MLPACKAGE_FILES,
|
|
490
|
+
runtimes: ["python"]
|
|
491
|
+
},
|
|
492
|
+
openvino: {
|
|
493
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/openvino/camstack-yolo11s-seg.xml"),
|
|
494
|
+
sizeMB: 20,
|
|
495
|
+
runtimes: ["python"]
|
|
840
496
|
}
|
|
841
|
-
return rawMask;
|
|
842
497
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
id: "yolo11m-seg",
|
|
501
|
+
name: "YOLO11 Medium Segmentation",
|
|
502
|
+
description: "YOLO11 Medium \u2014 higher accuracy instance segmentation",
|
|
503
|
+
inputSize: { width: 640, height: 640 },
|
|
504
|
+
labels: import_types2.COCO_80_LABELS,
|
|
505
|
+
formats: {
|
|
506
|
+
onnx: {
|
|
507
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/onnx/camstack-yolo11m-seg.onnx"),
|
|
508
|
+
sizeMB: 86
|
|
509
|
+
},
|
|
510
|
+
coreml: {
|
|
511
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/coreml/camstack-yolo11m-seg.mlpackage"),
|
|
512
|
+
sizeMB: 43,
|
|
513
|
+
isDirectory: true,
|
|
514
|
+
files: MLPACKAGE_FILES,
|
|
515
|
+
runtimes: ["python"]
|
|
516
|
+
},
|
|
517
|
+
openvino: {
|
|
518
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolo11-seg/openvino/camstack-yolo11m-seg.xml"),
|
|
519
|
+
sizeMB: 43,
|
|
520
|
+
runtimes: ["python"]
|
|
858
521
|
}
|
|
859
|
-
return { data, width: cropW, height: cropH };
|
|
860
522
|
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
523
|
+
},
|
|
524
|
+
// ── YOLOv8-seg — CoreML supported ─────────────────────────────
|
|
525
|
+
{
|
|
526
|
+
id: "yolov8n-seg",
|
|
527
|
+
name: "YOLOv8 Nano Segmentation",
|
|
528
|
+
description: "YOLOv8 Nano \u2014 fastest, smallest YOLOv8 instance segmentation model",
|
|
529
|
+
inputSize: { width: 640, height: 640 },
|
|
530
|
+
labels: import_types2.COCO_80_LABELS,
|
|
531
|
+
formats: {
|
|
532
|
+
onnx: {
|
|
533
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/onnx/camstack-yolov8n-seg.onnx"),
|
|
534
|
+
sizeMB: 13
|
|
535
|
+
},
|
|
536
|
+
coreml: {
|
|
537
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/coreml/camstack-yolov8n-seg.mlpackage"),
|
|
538
|
+
sizeMB: 7,
|
|
539
|
+
isDirectory: true,
|
|
540
|
+
files: MLPACKAGE_FILES,
|
|
541
|
+
runtimes: ["python"]
|
|
542
|
+
},
|
|
543
|
+
openvino: {
|
|
544
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/openvino/camstack-yolov8n-seg.xml"),
|
|
545
|
+
sizeMB: 7,
|
|
546
|
+
runtimes: ["python"]
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
id: "yolov8s-seg",
|
|
552
|
+
name: "YOLOv8 Small Segmentation",
|
|
553
|
+
description: "YOLOv8 Small \u2014 balanced speed and accuracy for instance segmentation",
|
|
554
|
+
inputSize: { width: 640, height: 640 },
|
|
555
|
+
labels: import_types2.COCO_80_LABELS,
|
|
556
|
+
formats: {
|
|
557
|
+
onnx: {
|
|
558
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/onnx/camstack-yolov8s-seg.onnx"),
|
|
559
|
+
sizeMB: 45
|
|
560
|
+
},
|
|
561
|
+
coreml: {
|
|
562
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/coreml/camstack-yolov8s-seg.mlpackage"),
|
|
563
|
+
sizeMB: 23,
|
|
564
|
+
isDirectory: true,
|
|
565
|
+
files: MLPACKAGE_FILES,
|
|
566
|
+
runtimes: ["python"]
|
|
567
|
+
},
|
|
568
|
+
openvino: {
|
|
569
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/openvino/camstack-yolov8s-seg.xml"),
|
|
570
|
+
sizeMB: 23,
|
|
571
|
+
runtimes: ["python"]
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
id: "yolov8m-seg",
|
|
577
|
+
name: "YOLOv8 Medium Segmentation",
|
|
578
|
+
description: "YOLOv8 Medium \u2014 higher accuracy instance segmentation",
|
|
579
|
+
inputSize: { width: 640, height: 640 },
|
|
580
|
+
labels: import_types2.COCO_80_LABELS,
|
|
581
|
+
formats: {
|
|
582
|
+
onnx: {
|
|
583
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/onnx/camstack-yolov8m-seg.onnx"),
|
|
584
|
+
sizeMB: 104
|
|
585
|
+
},
|
|
586
|
+
coreml: {
|
|
587
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/coreml/camstack-yolov8m-seg.mlpackage"),
|
|
588
|
+
sizeMB: 52,
|
|
589
|
+
isDirectory: true,
|
|
590
|
+
files: MLPACKAGE_FILES,
|
|
591
|
+
runtimes: ["python"]
|
|
592
|
+
},
|
|
593
|
+
openvino: {
|
|
594
|
+
url: (0, import_types2.hfModelUrl)(HF_REPO2, "segmentation/yolov8-seg/openvino/camstack-yolov8m-seg.xml"),
|
|
595
|
+
sizeMB: 53,
|
|
596
|
+
runtimes: ["python"]
|
|
894
597
|
}
|
|
895
|
-
if (candidates.length === 0)
|
|
896
|
-
return [];
|
|
897
|
-
const keptIndices = (0, yolo_js_1.nms)(candidates, iouThreshold);
|
|
898
|
-
return keptIndices.map((idx) => {
|
|
899
|
-
const { bbox, score, classIdx, coeffs } = candidates[idx];
|
|
900
|
-
const label = labels[classIdx] ?? String(classIdx);
|
|
901
|
-
const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale));
|
|
902
|
-
const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale));
|
|
903
|
-
const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale));
|
|
904
|
-
const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale));
|
|
905
|
-
const finalBbox = { x, y, w: x2 - x, h: y2 - y };
|
|
906
|
-
const rawMask = computeRawMask(coeffs, protoOutput, numMaskCoeffs, maskHeight, maskWidth);
|
|
907
|
-
const { data: maskData, width: mW, height: mH } = cropAndThresholdMask(rawMask, maskHeight, maskWidth, bbox, maskThreshold, maskScale);
|
|
908
|
-
return {
|
|
909
|
-
class: label,
|
|
910
|
-
originalClass: label,
|
|
911
|
-
score,
|
|
912
|
-
bbox: finalBbox,
|
|
913
|
-
mask: maskData,
|
|
914
|
-
maskWidth: mW,
|
|
915
|
-
maskHeight: mH
|
|
916
|
-
};
|
|
917
|
-
});
|
|
918
598
|
}
|
|
919
599
|
}
|
|
920
|
-
|
|
600
|
+
];
|
|
601
|
+
|
|
602
|
+
// src/addons/object-detection/index.ts
|
|
603
|
+
var import_types3 = require("@camstack/types");
|
|
921
604
|
|
|
922
|
-
// src/shared/
|
|
923
|
-
var
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
605
|
+
// src/shared/image-utils.ts
|
|
606
|
+
var import_sharp = __toESM(require("sharp"));
|
|
607
|
+
async function letterbox(jpeg, targetSize) {
|
|
608
|
+
const meta = await (0, import_sharp.default)(jpeg).metadata();
|
|
609
|
+
const originalWidth = meta.width ?? 0;
|
|
610
|
+
const originalHeight = meta.height ?? 0;
|
|
611
|
+
const scale = Math.min(targetSize / originalWidth, targetSize / originalHeight);
|
|
612
|
+
const scaledWidth = Math.round(originalWidth * scale);
|
|
613
|
+
const scaledHeight = Math.round(originalHeight * scale);
|
|
614
|
+
const padX = Math.floor((targetSize - scaledWidth) / 2);
|
|
615
|
+
const padY = Math.floor((targetSize - scaledHeight) / 2);
|
|
616
|
+
const { data } = await (0, import_sharp.default)(jpeg).resize(scaledWidth, scaledHeight).extend({
|
|
617
|
+
top: padY,
|
|
618
|
+
bottom: targetSize - scaledHeight - padY,
|
|
619
|
+
left: padX,
|
|
620
|
+
right: targetSize - scaledWidth - padX,
|
|
621
|
+
background: { r: 114, g: 114, b: 114 }
|
|
622
|
+
}).removeAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
623
|
+
const numPixels = targetSize * targetSize;
|
|
624
|
+
const float32 = new Float32Array(3 * numPixels);
|
|
625
|
+
for (let i = 0; i < numPixels; i++) {
|
|
626
|
+
const srcBase = i * 3;
|
|
627
|
+
float32[0 * numPixels + i] = data[srcBase] / 255;
|
|
628
|
+
float32[1 * numPixels + i] = data[srcBase + 1] / 255;
|
|
629
|
+
float32[2 * numPixels + i] = data[srcBase + 2] / 255;
|
|
630
|
+
}
|
|
631
|
+
return { data: float32, scale, padX, padY, originalWidth, originalHeight };
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// src/shared/postprocess/yolo.ts
|
|
635
|
+
function iou(a, b) {
|
|
636
|
+
const ax1 = a.x;
|
|
637
|
+
const ay1 = a.y;
|
|
638
|
+
const ax2 = a.x + a.w;
|
|
639
|
+
const ay2 = a.y + a.h;
|
|
640
|
+
const bx1 = b.x;
|
|
641
|
+
const by1 = b.y;
|
|
642
|
+
const bx2 = b.x + b.w;
|
|
643
|
+
const by2 = b.y + b.h;
|
|
644
|
+
const interX1 = Math.max(ax1, bx1);
|
|
645
|
+
const interY1 = Math.max(ay1, by1);
|
|
646
|
+
const interX2 = Math.min(ax2, bx2);
|
|
647
|
+
const interY2 = Math.min(ay2, by2);
|
|
648
|
+
const interW = Math.max(0, interX2 - interX1);
|
|
649
|
+
const interH = Math.max(0, interY2 - interY1);
|
|
650
|
+
const interArea = interW * interH;
|
|
651
|
+
if (interArea === 0) return 0;
|
|
652
|
+
const areaA = a.w * a.h;
|
|
653
|
+
const areaB = b.w * b.h;
|
|
654
|
+
const unionArea = areaA + areaB - interArea;
|
|
655
|
+
return unionArea === 0 ? 0 : interArea / unionArea;
|
|
656
|
+
}
|
|
657
|
+
function nms(boxes, iouThreshold) {
|
|
658
|
+
const indices = boxes.map((_, i) => i).sort((a, b) => boxes[b].score - boxes[a].score);
|
|
659
|
+
const kept = [];
|
|
660
|
+
const suppressed = /* @__PURE__ */ new Set();
|
|
661
|
+
for (const idx of indices) {
|
|
662
|
+
if (suppressed.has(idx)) continue;
|
|
663
|
+
kept.push(idx);
|
|
664
|
+
for (const other of indices) {
|
|
665
|
+
if (other === idx || suppressed.has(other)) continue;
|
|
666
|
+
if (iou(boxes[idx].bbox, boxes[other].bbox) > iouThreshold) {
|
|
667
|
+
suppressed.add(other);
|
|
933
668
|
}
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
};
|
|
962
|
-
})();
|
|
963
|
-
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
964
|
-
exports2.NodeInferenceEngine = void 0;
|
|
965
|
-
var path = __importStar(require("path"));
|
|
966
|
-
var BACKEND_TO_PROVIDER = {
|
|
967
|
-
cpu: "cpu",
|
|
968
|
-
coreml: "coreml",
|
|
969
|
-
cuda: "cuda",
|
|
970
|
-
tensorrt: "tensorrt",
|
|
971
|
-
dml: "dml"
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return kept;
|
|
672
|
+
}
|
|
673
|
+
function yoloPostprocess(output, numClasses, numBoxes, options) {
|
|
674
|
+
const { confidence, iouThreshold, labels, scale, padX, padY, originalWidth, originalHeight } = options;
|
|
675
|
+
const candidates = [];
|
|
676
|
+
for (let i = 0; i < numBoxes; i++) {
|
|
677
|
+
const cx = output[0 * numBoxes + i];
|
|
678
|
+
const cy = output[1 * numBoxes + i];
|
|
679
|
+
const w = output[2 * numBoxes + i];
|
|
680
|
+
const h = output[3 * numBoxes + i];
|
|
681
|
+
let bestScore = -Infinity;
|
|
682
|
+
let bestClass = 0;
|
|
683
|
+
for (let j = 0; j < numClasses; j++) {
|
|
684
|
+
const score = output[(4 + j) * numBoxes + i];
|
|
685
|
+
if (score > bestScore) {
|
|
686
|
+
bestScore = score;
|
|
687
|
+
bestClass = j;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
if (bestScore < confidence) continue;
|
|
691
|
+
const bbox = {
|
|
692
|
+
x: cx - w / 2,
|
|
693
|
+
y: cy - h / 2,
|
|
694
|
+
w,
|
|
695
|
+
h
|
|
972
696
|
};
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
697
|
+
candidates.push({ bbox, score: bestScore, classIdx: bestClass });
|
|
698
|
+
}
|
|
699
|
+
if (candidates.length === 0) return [];
|
|
700
|
+
const keptIndices = nms(candidates, iouThreshold);
|
|
701
|
+
return keptIndices.map((idx) => {
|
|
702
|
+
const { bbox, score, classIdx } = candidates[idx];
|
|
703
|
+
const label = labels[classIdx] ?? String(classIdx);
|
|
704
|
+
const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale));
|
|
705
|
+
const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale));
|
|
706
|
+
const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale));
|
|
707
|
+
const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale));
|
|
708
|
+
const finalBbox = { x, y, w: x2 - x, h: y2 - y };
|
|
709
|
+
return {
|
|
710
|
+
class: label,
|
|
711
|
+
originalClass: label,
|
|
712
|
+
score,
|
|
713
|
+
bbox: finalBbox
|
|
978
714
|
};
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// src/shared/postprocess/yolo-seg.ts
|
|
719
|
+
function sigmoid(x) {
|
|
720
|
+
return 1 / (1 + Math.exp(-x));
|
|
721
|
+
}
|
|
722
|
+
function computeRawMask(coeffs, protos, numMaskCoeffs, maskH, maskW) {
|
|
723
|
+
const maskSize = maskH * maskW;
|
|
724
|
+
const rawMask = new Float32Array(maskSize);
|
|
725
|
+
for (let px = 0; px < maskSize; px++) {
|
|
726
|
+
let val = 0;
|
|
727
|
+
for (let k = 0; k < numMaskCoeffs; k++) {
|
|
728
|
+
val += (coeffs[k] ?? 0) * (protos[k * maskSize + px] ?? 0);
|
|
729
|
+
}
|
|
730
|
+
rawMask[px] = sigmoid(val);
|
|
731
|
+
}
|
|
732
|
+
return rawMask;
|
|
733
|
+
}
|
|
734
|
+
function cropAndThresholdMask(rawMask, maskH, maskW, bbox, maskThreshold, maskScale) {
|
|
735
|
+
const cropX1 = Math.max(0, Math.floor(bbox.x * maskScale));
|
|
736
|
+
const cropY1 = Math.max(0, Math.floor(bbox.y * maskScale));
|
|
737
|
+
const cropX2 = Math.min(maskW, Math.ceil((bbox.x + bbox.w) * maskScale));
|
|
738
|
+
const cropY2 = Math.min(maskH, Math.ceil((bbox.y + bbox.h) * maskScale));
|
|
739
|
+
const cropW = Math.max(1, cropX2 - cropX1);
|
|
740
|
+
const cropH = Math.max(1, cropY2 - cropY1);
|
|
741
|
+
const data = new Uint8Array(cropW * cropH);
|
|
742
|
+
for (let row = 0; row < cropH; row++) {
|
|
743
|
+
const srcRow = cropY1 + row;
|
|
744
|
+
for (let col = 0; col < cropW; col++) {
|
|
745
|
+
const srcCol = cropX1 + col;
|
|
746
|
+
const srcIdx = srcRow * maskW + srcCol;
|
|
747
|
+
data[row * cropW + col] = (rawMask[srcIdx] ?? 0) > maskThreshold ? 255 : 0;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return { data, width: cropW, height: cropH };
|
|
751
|
+
}
|
|
752
|
+
function yoloSegPostprocess(segOutput, options) {
|
|
753
|
+
const {
|
|
754
|
+
detectionOutput,
|
|
755
|
+
protoOutput,
|
|
756
|
+
numClasses,
|
|
757
|
+
numBoxes,
|
|
758
|
+
numMaskCoeffs,
|
|
759
|
+
maskHeight,
|
|
760
|
+
maskWidth
|
|
761
|
+
} = segOutput;
|
|
762
|
+
const {
|
|
763
|
+
confidence,
|
|
764
|
+
iouThreshold,
|
|
765
|
+
labels,
|
|
766
|
+
scale,
|
|
767
|
+
padX,
|
|
768
|
+
padY,
|
|
769
|
+
originalWidth,
|
|
770
|
+
originalHeight,
|
|
771
|
+
maskThreshold = 0.5
|
|
772
|
+
} = options;
|
|
773
|
+
const yoloInputSize = 640;
|
|
774
|
+
const maskScale = maskHeight / yoloInputSize;
|
|
775
|
+
const candidates = [];
|
|
776
|
+
for (let i = 0; i < numBoxes; i++) {
|
|
777
|
+
const cx = detectionOutput[0 * numBoxes + i] ?? 0;
|
|
778
|
+
const cy = detectionOutput[1 * numBoxes + i] ?? 0;
|
|
779
|
+
const w = detectionOutput[2 * numBoxes + i] ?? 0;
|
|
780
|
+
const h = detectionOutput[3 * numBoxes + i] ?? 0;
|
|
781
|
+
let bestScore = -Infinity;
|
|
782
|
+
let bestClass = 0;
|
|
783
|
+
for (let j = 0; j < numClasses; j++) {
|
|
784
|
+
const score = detectionOutput[(4 + j) * numBoxes + i] ?? 0;
|
|
785
|
+
if (score > bestScore) {
|
|
786
|
+
bestScore = score;
|
|
787
|
+
bestClass = j;
|
|
1031
788
|
}
|
|
789
|
+
}
|
|
790
|
+
if (bestScore < confidence) continue;
|
|
791
|
+
const bbox = {
|
|
792
|
+
x: cx - w / 2,
|
|
793
|
+
y: cy - h / 2,
|
|
794
|
+
w,
|
|
795
|
+
h
|
|
1032
796
|
};
|
|
1033
|
-
|
|
797
|
+
const coeffs = new Float32Array(numMaskCoeffs);
|
|
798
|
+
for (let k = 0; k < numMaskCoeffs; k++) {
|
|
799
|
+
coeffs[k] = detectionOutput[(4 + numClasses + k) * numBoxes + i] ?? 0;
|
|
800
|
+
}
|
|
801
|
+
candidates.push({ bbox, score: bestScore, classIdx: bestClass, coeffs });
|
|
1034
802
|
}
|
|
1035
|
-
|
|
803
|
+
if (candidates.length === 0) return [];
|
|
804
|
+
const keptIndices = nms(candidates, iouThreshold);
|
|
805
|
+
return keptIndices.map((idx) => {
|
|
806
|
+
const { bbox, score, classIdx, coeffs } = candidates[idx];
|
|
807
|
+
const label = labels[classIdx] ?? String(classIdx);
|
|
808
|
+
const x = Math.max(0, Math.min(originalWidth, (bbox.x - padX) / scale));
|
|
809
|
+
const y = Math.max(0, Math.min(originalHeight, (bbox.y - padY) / scale));
|
|
810
|
+
const x2 = Math.max(0, Math.min(originalWidth, (bbox.x + bbox.w - padX) / scale));
|
|
811
|
+
const y2 = Math.max(0, Math.min(originalHeight, (bbox.y + bbox.h - padY) / scale));
|
|
812
|
+
const finalBbox = { x, y, w: x2 - x, h: y2 - y };
|
|
813
|
+
const rawMask = computeRawMask(coeffs, protoOutput, numMaskCoeffs, maskHeight, maskWidth);
|
|
814
|
+
const { data: maskData, width: mW, height: mH } = cropAndThresholdMask(
|
|
815
|
+
rawMask,
|
|
816
|
+
maskHeight,
|
|
817
|
+
maskWidth,
|
|
818
|
+
bbox,
|
|
819
|
+
maskThreshold,
|
|
820
|
+
maskScale
|
|
821
|
+
);
|
|
822
|
+
return {
|
|
823
|
+
class: label,
|
|
824
|
+
originalClass: label,
|
|
825
|
+
score,
|
|
826
|
+
bbox: finalBbox,
|
|
827
|
+
mask: maskData,
|
|
828
|
+
maskWidth: mW,
|
|
829
|
+
maskHeight: mH
|
|
830
|
+
};
|
|
831
|
+
});
|
|
832
|
+
}
|
|
1036
833
|
|
|
1037
|
-
// src/shared/
|
|
1038
|
-
var
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
async initialize() {
|
|
1072
|
-
const args = [this.scriptPath, this.modelPath, ...this.extraArgs];
|
|
1073
|
-
this.process = (0, node_child_process_1.spawn)(this.pythonPath, args, {
|
|
1074
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1075
|
-
});
|
|
1076
|
-
if (!this.process.stdout || !this.process.stdin) {
|
|
1077
|
-
throw new Error("PythonInferenceEngine: failed to create process pipes");
|
|
1078
|
-
}
|
|
1079
|
-
this.process.stderr?.on("data", (chunk) => {
|
|
1080
|
-
process.stderr.write(`[python-engine] ${chunk.toString()}`);
|
|
1081
|
-
});
|
|
1082
|
-
this.process.on("error", (err) => {
|
|
1083
|
-
this.pendingReject?.(err);
|
|
1084
|
-
this.pendingReject = null;
|
|
1085
|
-
this.pendingResolve = null;
|
|
1086
|
-
});
|
|
1087
|
-
this.process.on("exit", (code) => {
|
|
1088
|
-
if (code !== 0) {
|
|
1089
|
-
const err = new Error(`PythonInferenceEngine: process exited with code ${code}`);
|
|
1090
|
-
this.pendingReject?.(err);
|
|
1091
|
-
this.pendingReject = null;
|
|
1092
|
-
this.pendingResolve = null;
|
|
1093
|
-
}
|
|
1094
|
-
});
|
|
1095
|
-
this.process.stdout.on("data", (chunk) => {
|
|
1096
|
-
this.receiveBuffer = Buffer.concat([this.receiveBuffer, chunk]);
|
|
1097
|
-
this._tryReceive();
|
|
1098
|
-
});
|
|
1099
|
-
await new Promise((resolve, reject) => {
|
|
1100
|
-
const timeout = setTimeout(() => resolve(), 2e3);
|
|
1101
|
-
this.process?.on("error", (err) => {
|
|
1102
|
-
clearTimeout(timeout);
|
|
1103
|
-
reject(err);
|
|
1104
|
-
});
|
|
1105
|
-
this.process?.on("exit", (code) => {
|
|
1106
|
-
clearTimeout(timeout);
|
|
1107
|
-
if (code !== 0) {
|
|
1108
|
-
reject(new Error(`PythonInferenceEngine: process exited early with code ${code}`));
|
|
1109
|
-
}
|
|
1110
|
-
});
|
|
1111
|
-
});
|
|
1112
|
-
}
|
|
1113
|
-
_tryReceive() {
|
|
1114
|
-
if (this.receiveBuffer.length < 4)
|
|
1115
|
-
return;
|
|
1116
|
-
const length = this.receiveBuffer.readUInt32LE(0);
|
|
1117
|
-
if (this.receiveBuffer.length < 4 + length)
|
|
1118
|
-
return;
|
|
1119
|
-
const jsonBytes = this.receiveBuffer.subarray(4, 4 + length);
|
|
1120
|
-
this.receiveBuffer = this.receiveBuffer.subarray(4 + length);
|
|
1121
|
-
const resolve = this.pendingResolve;
|
|
1122
|
-
const reject = this.pendingReject;
|
|
1123
|
-
this.pendingResolve = null;
|
|
1124
|
-
this.pendingReject = null;
|
|
1125
|
-
if (!resolve)
|
|
1126
|
-
return;
|
|
1127
|
-
try {
|
|
1128
|
-
const parsed = JSON.parse(jsonBytes.toString("utf8"));
|
|
1129
|
-
resolve(parsed);
|
|
1130
|
-
} catch (err) {
|
|
1131
|
-
reject?.(err instanceof Error ? err : new Error(String(err)));
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
/** Send JPEG buffer, receive JSON detection results */
|
|
1135
|
-
async runJpeg(jpeg) {
|
|
1136
|
-
if (!this.process?.stdin) {
|
|
1137
|
-
throw new Error("PythonInferenceEngine: process not initialized");
|
|
1138
|
-
}
|
|
1139
|
-
return new Promise((resolve, reject) => {
|
|
1140
|
-
this.pendingResolve = resolve;
|
|
1141
|
-
this.pendingReject = reject;
|
|
1142
|
-
const lengthBuf = Buffer.allocUnsafe(4);
|
|
1143
|
-
lengthBuf.writeUInt32LE(jpeg.length, 0);
|
|
1144
|
-
this.process.stdin.write(Buffer.concat([lengthBuf, jpeg]));
|
|
1145
|
-
});
|
|
1146
|
-
}
|
|
1147
|
-
/** IInferenceEngine.run — wraps runJpeg for compatibility */
|
|
1148
|
-
async run(_input, _inputShape) {
|
|
1149
|
-
throw new Error("PythonInferenceEngine: use runJpeg() directly \u2014 this engine operates on JPEG input");
|
|
1150
|
-
}
|
|
1151
|
-
/** IInferenceEngine.runMultiOutput — not supported by Python engine (operates on JPEG input) */
|
|
1152
|
-
async runMultiOutput(_input, _inputShape) {
|
|
1153
|
-
throw new Error("PythonInferenceEngine: runMultiOutput() is not supported \u2014 this engine operates on JPEG input");
|
|
1154
|
-
}
|
|
1155
|
-
async dispose() {
|
|
1156
|
-
if (this.process) {
|
|
1157
|
-
this.process.stdin?.end();
|
|
1158
|
-
this.process.kill("SIGTERM");
|
|
1159
|
-
this.process = null;
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
834
|
+
// src/shared/engine-resolver.ts
|
|
835
|
+
var fs = __toESM(require("fs"));
|
|
836
|
+
var path2 = __toESM(require("path"));
|
|
837
|
+
|
|
838
|
+
// src/shared/node-engine.ts
|
|
839
|
+
var path = __toESM(require("path"));
|
|
840
|
+
var BACKEND_TO_PROVIDER = {
|
|
841
|
+
cpu: "cpu",
|
|
842
|
+
coreml: "coreml",
|
|
843
|
+
cuda: "cuda",
|
|
844
|
+
tensorrt: "tensorrt",
|
|
845
|
+
dml: "dml"
|
|
846
|
+
};
|
|
847
|
+
var BACKEND_TO_DEVICE = {
|
|
848
|
+
cpu: "cpu",
|
|
849
|
+
coreml: "gpu-mps",
|
|
850
|
+
cuda: "gpu-cuda",
|
|
851
|
+
tensorrt: "tensorrt"
|
|
852
|
+
};
|
|
853
|
+
var NodeInferenceEngine = class {
|
|
854
|
+
constructor(modelPath, backend) {
|
|
855
|
+
this.modelPath = modelPath;
|
|
856
|
+
this.backend = backend;
|
|
857
|
+
this.device = BACKEND_TO_DEVICE[backend] ?? "cpu";
|
|
858
|
+
}
|
|
859
|
+
runtime = "onnx";
|
|
860
|
+
device;
|
|
861
|
+
session = null;
|
|
862
|
+
async initialize() {
|
|
863
|
+
const ort = await import("onnxruntime-node");
|
|
864
|
+
const provider = BACKEND_TO_PROVIDER[this.backend] ?? "cpu";
|
|
865
|
+
const absModelPath = path.isAbsolute(this.modelPath) ? this.modelPath : path.resolve(process.cwd(), this.modelPath);
|
|
866
|
+
const sessionOptions = {
|
|
867
|
+
executionProviders: [provider]
|
|
1162
868
|
};
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
869
|
+
this.session = await ort.InferenceSession.create(absModelPath, sessionOptions);
|
|
870
|
+
}
|
|
871
|
+
async run(input, inputShape) {
|
|
872
|
+
if (!this.session) {
|
|
873
|
+
throw new Error("NodeInferenceEngine: not initialized \u2014 call initialize() first");
|
|
1168
874
|
}
|
|
875
|
+
const ort = await import("onnxruntime-node");
|
|
876
|
+
const sess = this.session;
|
|
877
|
+
const inputName = sess.inputNames[0];
|
|
878
|
+
const tensor = new ort.Tensor("float32", input, [...inputShape]);
|
|
879
|
+
const feeds = { [inputName]: tensor };
|
|
880
|
+
const results = await sess.run(feeds);
|
|
881
|
+
const outputName = sess.outputNames[0];
|
|
882
|
+
const outputTensor = results[outputName];
|
|
883
|
+
return outputTensor.data;
|
|
1169
884
|
}
|
|
1170
|
-
|
|
885
|
+
async runMultiOutput(input, inputShape) {
|
|
886
|
+
if (!this.session) {
|
|
887
|
+
throw new Error("NodeInferenceEngine: not initialized \u2014 call initialize() first");
|
|
888
|
+
}
|
|
889
|
+
const ort = await import("onnxruntime-node");
|
|
890
|
+
const sess = this.session;
|
|
891
|
+
const inputName = sess.inputNames[0];
|
|
892
|
+
const tensor = new ort.Tensor("float32", input, [...inputShape]);
|
|
893
|
+
const feeds = { [inputName]: tensor };
|
|
894
|
+
const results = await sess.run(feeds);
|
|
895
|
+
const out = {};
|
|
896
|
+
for (const name of sess.outputNames) {
|
|
897
|
+
out[name] = results[name].data;
|
|
898
|
+
}
|
|
899
|
+
return out;
|
|
900
|
+
}
|
|
901
|
+
async dispose() {
|
|
902
|
+
this.session = null;
|
|
903
|
+
}
|
|
904
|
+
};
|
|
1171
905
|
|
|
1172
|
-
// src/shared/engine
|
|
1173
|
-
var
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
906
|
+
// src/shared/python-engine.ts
|
|
907
|
+
var import_node_child_process = require("child_process");
|
|
908
|
+
var PythonInferenceEngine = class {
|
|
909
|
+
constructor(pythonPath, scriptPath, runtime, modelPath, extraArgs = []) {
|
|
910
|
+
this.pythonPath = pythonPath;
|
|
911
|
+
this.scriptPath = scriptPath;
|
|
912
|
+
this.modelPath = modelPath;
|
|
913
|
+
this.extraArgs = extraArgs;
|
|
914
|
+
this.runtime = runtime;
|
|
915
|
+
const runtimeDeviceMap = {
|
|
916
|
+
onnx: "cpu",
|
|
917
|
+
coreml: "gpu-mps",
|
|
918
|
+
pytorch: "cpu",
|
|
919
|
+
openvino: "cpu",
|
|
920
|
+
tflite: "cpu"
|
|
921
|
+
};
|
|
922
|
+
this.device = runtimeDeviceMap[runtime];
|
|
923
|
+
}
|
|
924
|
+
runtime;
|
|
925
|
+
device;
|
|
926
|
+
process = null;
|
|
927
|
+
receiveBuffer = Buffer.alloc(0);
|
|
928
|
+
pendingResolve = null;
|
|
929
|
+
pendingReject = null;
|
|
930
|
+
async initialize() {
|
|
931
|
+
const args = [this.scriptPath, this.modelPath, ...this.extraArgs];
|
|
932
|
+
this.process = (0, import_node_child_process.spawn)(this.pythonPath, args, {
|
|
933
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
934
|
+
});
|
|
935
|
+
if (!this.process.stdout || !this.process.stdin) {
|
|
936
|
+
throw new Error("PythonInferenceEngine: failed to create process pipes");
|
|
937
|
+
}
|
|
938
|
+
this.process.stderr?.on("data", (chunk) => {
|
|
939
|
+
process.stderr.write(`[python-engine] ${chunk.toString()}`);
|
|
940
|
+
});
|
|
941
|
+
this.process.on("error", (err) => {
|
|
942
|
+
this.pendingReject?.(err);
|
|
943
|
+
this.pendingReject = null;
|
|
944
|
+
this.pendingResolve = null;
|
|
945
|
+
});
|
|
946
|
+
this.process.on("exit", (code) => {
|
|
947
|
+
if (code !== 0) {
|
|
948
|
+
const err = new Error(`PythonInferenceEngine: process exited with code ${code}`);
|
|
949
|
+
this.pendingReject?.(err);
|
|
950
|
+
this.pendingReject = null;
|
|
951
|
+
this.pendingResolve = null;
|
|
1183
952
|
}
|
|
1184
|
-
Object.defineProperty(o, k2, desc);
|
|
1185
|
-
}) : (function(o, m, k, k2) {
|
|
1186
|
-
if (k2 === void 0) k2 = k;
|
|
1187
|
-
o[k2] = m[k];
|
|
1188
|
-
}));
|
|
1189
|
-
var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
1190
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
1191
|
-
}) : function(o, v) {
|
|
1192
|
-
o["default"] = v;
|
|
1193
953
|
});
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
if (
|
|
1207
|
-
|
|
954
|
+
this.process.stdout.on("data", (chunk) => {
|
|
955
|
+
this.receiveBuffer = Buffer.concat([this.receiveBuffer, chunk]);
|
|
956
|
+
this._tryReceive();
|
|
957
|
+
});
|
|
958
|
+
await new Promise((resolve2, reject) => {
|
|
959
|
+
const timeout = setTimeout(() => resolve2(), 2e3);
|
|
960
|
+
this.process?.on("error", (err) => {
|
|
961
|
+
clearTimeout(timeout);
|
|
962
|
+
reject(err);
|
|
963
|
+
});
|
|
964
|
+
this.process?.on("exit", (code) => {
|
|
965
|
+
clearTimeout(timeout);
|
|
966
|
+
if (code !== 0) {
|
|
967
|
+
reject(new Error(`PythonInferenceEngine: process exited early with code ${code}`));
|
|
1208
968
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
onnx: "onnx",
|
|
1229
|
-
coreml: "coreml",
|
|
1230
|
-
openvino: "openvino",
|
|
1231
|
-
tflite: "tflite",
|
|
1232
|
-
pytorch: "pt"
|
|
1233
|
-
};
|
|
1234
|
-
function modelFilePath(modelsDir, modelEntry, format) {
|
|
1235
|
-
const formatEntry = modelEntry.formats[format];
|
|
1236
|
-
if (!formatEntry) {
|
|
1237
|
-
throw new Error(`Model ${modelEntry.id} has no ${format} format`);
|
|
1238
|
-
}
|
|
1239
|
-
const urlParts = formatEntry.url.split("/");
|
|
1240
|
-
const filename = urlParts[urlParts.length - 1] ?? `${modelEntry.id}.${format}`;
|
|
1241
|
-
return path.join(modelsDir, filename);
|
|
969
|
+
});
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
_tryReceive() {
|
|
973
|
+
if (this.receiveBuffer.length < 4) return;
|
|
974
|
+
const length = this.receiveBuffer.readUInt32LE(0);
|
|
975
|
+
if (this.receiveBuffer.length < 4 + length) return;
|
|
976
|
+
const jsonBytes = this.receiveBuffer.subarray(4, 4 + length);
|
|
977
|
+
this.receiveBuffer = this.receiveBuffer.subarray(4 + length);
|
|
978
|
+
const resolve2 = this.pendingResolve;
|
|
979
|
+
const reject = this.pendingReject;
|
|
980
|
+
this.pendingResolve = null;
|
|
981
|
+
this.pendingReject = null;
|
|
982
|
+
if (!resolve2) return;
|
|
983
|
+
try {
|
|
984
|
+
const parsed = JSON.parse(jsonBytes.toString("utf8"));
|
|
985
|
+
resolve2(parsed);
|
|
986
|
+
} catch (err) {
|
|
987
|
+
reject?.(err instanceof Error ? err : new Error(String(err)));
|
|
1242
988
|
}
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
}
|
|
989
|
+
}
|
|
990
|
+
/** Send JPEG buffer, receive JSON detection results */
|
|
991
|
+
async runJpeg(jpeg) {
|
|
992
|
+
if (!this.process?.stdin) {
|
|
993
|
+
throw new Error("PythonInferenceEngine: process not initialized");
|
|
1249
994
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
if (!fmt) {
|
|
1276
|
-
throw new Error(`resolveEngine: unsupported runtime "${runtime}"`);
|
|
1277
|
-
}
|
|
1278
|
-
if (!modelEntry.formats[fmt]) {
|
|
1279
|
-
throw new Error(`resolveEngine: model ${modelEntry.id} has no ${fmt} format for runtime ${runtime}`);
|
|
1280
|
-
}
|
|
1281
|
-
selectedFormat = fmt;
|
|
1282
|
-
selectedBackend = runtime === "onnx" ? backend || "cpu" : runtime;
|
|
1283
|
-
}
|
|
1284
|
-
let modelPath;
|
|
1285
|
-
if (models) {
|
|
1286
|
-
modelPath = await models.ensure(modelEntry.id, selectedFormat);
|
|
1287
|
-
} else {
|
|
1288
|
-
modelPath = modelFilePath(modelsDir, modelEntry, selectedFormat);
|
|
1289
|
-
if (!modelExists(modelPath)) {
|
|
1290
|
-
throw new Error(`resolveEngine: model file not found at ${modelPath} and no model service provided`);
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
if (selectedFormat === "onnx") {
|
|
1294
|
-
const engine = new node_engine_js_1.NodeInferenceEngine(modelPath, selectedBackend);
|
|
1295
|
-
await engine.initialize();
|
|
1296
|
-
return { engine, format: selectedFormat, modelPath };
|
|
1297
|
-
}
|
|
1298
|
-
const { pythonPath } = options;
|
|
1299
|
-
const PYTHON_SCRIPT_MAP = {
|
|
1300
|
-
coreml: "coreml_inference.py",
|
|
1301
|
-
pytorch: "pytorch_inference.py",
|
|
1302
|
-
openvino: "openvino_inference.py"
|
|
1303
|
-
};
|
|
1304
|
-
const effectiveRuntime = runtime === "auto" ? selectedBackend : runtime;
|
|
1305
|
-
const scriptName = PYTHON_SCRIPT_MAP[effectiveRuntime];
|
|
1306
|
-
if (scriptName && pythonPath) {
|
|
1307
|
-
const candidates = [
|
|
1308
|
-
path.join(__dirname, "../../python", scriptName),
|
|
1309
|
-
path.join(__dirname, "../python", scriptName),
|
|
1310
|
-
path.join(__dirname, "../../../python", scriptName)
|
|
1311
|
-
];
|
|
1312
|
-
const scriptPath = candidates.find((p) => fs.existsSync(p));
|
|
1313
|
-
if (!scriptPath) {
|
|
1314
|
-
throw new Error(`resolveEngine: Python script "${scriptName}" not found. Searched:
|
|
1315
|
-
${candidates.join("\n")}`);
|
|
1316
|
-
}
|
|
1317
|
-
const inputSize = Math.max(modelEntry.inputSize.width, modelEntry.inputSize.height);
|
|
1318
|
-
const engine = new python_engine_js_1.PythonInferenceEngine(pythonPath, scriptPath, effectiveRuntime, modelPath, [
|
|
1319
|
-
`--input-size=${inputSize}`,
|
|
1320
|
-
`--confidence=0.25`
|
|
1321
|
-
]);
|
|
1322
|
-
await engine.initialize();
|
|
1323
|
-
return { engine, format: selectedFormat, modelPath };
|
|
1324
|
-
}
|
|
1325
|
-
const fallbackPath = modelFilePath(modelsDir, modelEntry, "onnx");
|
|
1326
|
-
if (modelEntry.formats["onnx"] && modelExists(fallbackPath)) {
|
|
1327
|
-
const engine = new node_engine_js_1.NodeInferenceEngine(fallbackPath, "cpu");
|
|
1328
|
-
await engine.initialize();
|
|
1329
|
-
return { engine, format: "onnx", modelPath: fallbackPath };
|
|
1330
|
-
}
|
|
1331
|
-
throw new Error(`resolveEngine: format ${selectedFormat} is not yet supported by NodeInferenceEngine, no Python runtime is available, and no ONNX fallback exists`);
|
|
995
|
+
return new Promise((resolve2, reject) => {
|
|
996
|
+
this.pendingResolve = resolve2;
|
|
997
|
+
this.pendingReject = reject;
|
|
998
|
+
const lengthBuf = Buffer.allocUnsafe(4);
|
|
999
|
+
lengthBuf.writeUInt32LE(jpeg.length, 0);
|
|
1000
|
+
this.process.stdin.write(Buffer.concat([lengthBuf, jpeg]));
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
/** IInferenceEngine.run — wraps runJpeg for compatibility */
|
|
1004
|
+
async run(_input, _inputShape) {
|
|
1005
|
+
throw new Error(
|
|
1006
|
+
"PythonInferenceEngine: use runJpeg() directly \u2014 this engine operates on JPEG input"
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
1009
|
+
/** IInferenceEngine.runMultiOutput — not supported by Python engine (operates on JPEG input) */
|
|
1010
|
+
async runMultiOutput(_input, _inputShape) {
|
|
1011
|
+
throw new Error(
|
|
1012
|
+
"PythonInferenceEngine: runMultiOutput() is not supported \u2014 this engine operates on JPEG input"
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
async dispose() {
|
|
1016
|
+
if (this.process) {
|
|
1017
|
+
this.process.stdin?.end();
|
|
1018
|
+
this.process.kill("SIGTERM");
|
|
1019
|
+
this.process = null;
|
|
1332
1020
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1021
|
+
}
|
|
1022
|
+
};
|
|
1023
|
+
|
|
1024
|
+
// src/shared/engine-resolver.ts
|
|
1025
|
+
var AUTO_BACKEND_PRIORITY = ["coreml", "cuda", "tensorrt", "cpu"];
|
|
1026
|
+
var BACKEND_TO_FORMAT = {
|
|
1027
|
+
cpu: "onnx",
|
|
1028
|
+
coreml: "onnx",
|
|
1029
|
+
cuda: "onnx",
|
|
1030
|
+
tensorrt: "onnx"
|
|
1031
|
+
};
|
|
1032
|
+
var RUNTIME_TO_FORMAT = {
|
|
1033
|
+
onnx: "onnx",
|
|
1034
|
+
coreml: "coreml",
|
|
1035
|
+
openvino: "openvino",
|
|
1036
|
+
tflite: "tflite",
|
|
1037
|
+
pytorch: "pt"
|
|
1038
|
+
};
|
|
1039
|
+
function modelFilePath(modelsDir, modelEntry, format) {
|
|
1040
|
+
const formatEntry = modelEntry.formats[format];
|
|
1041
|
+
if (!formatEntry) {
|
|
1042
|
+
throw new Error(`Model ${modelEntry.id} has no ${format} format`);
|
|
1043
|
+
}
|
|
1044
|
+
const urlParts = formatEntry.url.split("/");
|
|
1045
|
+
const filename = urlParts[urlParts.length - 1] ?? `${modelEntry.id}.${format}`;
|
|
1046
|
+
return path2.join(modelsDir, filename);
|
|
1047
|
+
}
|
|
1048
|
+
function modelExists(filePath) {
|
|
1049
|
+
try {
|
|
1050
|
+
return fs.existsSync(filePath);
|
|
1051
|
+
} catch {
|
|
1052
|
+
return false;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
async function resolveEngine(options) {
|
|
1056
|
+
const { runtime, backend, modelEntry, modelsDir, models } = options;
|
|
1057
|
+
let selectedFormat;
|
|
1058
|
+
let selectedBackend;
|
|
1059
|
+
if (runtime === "auto") {
|
|
1060
|
+
const available = await probeOnnxBackends();
|
|
1061
|
+
let chosen = null;
|
|
1062
|
+
for (const b of AUTO_BACKEND_PRIORITY) {
|
|
1063
|
+
if (!available.includes(b)) continue;
|
|
1064
|
+
const fmt = BACKEND_TO_FORMAT[b];
|
|
1065
|
+
if (!fmt) continue;
|
|
1066
|
+
if (!modelEntry.formats[fmt]) continue;
|
|
1067
|
+
chosen = { backend: b, format: fmt };
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
if (!chosen) {
|
|
1071
|
+
throw new Error(
|
|
1072
|
+
`resolveEngine: no compatible backend found for model ${modelEntry.id}. Available backends: ${available.join(", ")}`
|
|
1073
|
+
);
|
|
1074
|
+
}
|
|
1075
|
+
selectedFormat = chosen.format;
|
|
1076
|
+
selectedBackend = chosen.backend;
|
|
1077
|
+
} else {
|
|
1078
|
+
const fmt = RUNTIME_TO_FORMAT[runtime];
|
|
1079
|
+
if (!fmt) {
|
|
1080
|
+
throw new Error(`resolveEngine: unsupported runtime "${runtime}"`);
|
|
1081
|
+
}
|
|
1082
|
+
if (!modelEntry.formats[fmt]) {
|
|
1083
|
+
throw new Error(
|
|
1084
|
+
`resolveEngine: model ${modelEntry.id} has no ${fmt} format for runtime ${runtime}`
|
|
1085
|
+
);
|
|
1353
1086
|
}
|
|
1087
|
+
selectedFormat = fmt;
|
|
1088
|
+
selectedBackend = runtime === "onnx" ? backend || "cpu" : runtime;
|
|
1354
1089
|
}
|
|
1355
|
-
|
|
1090
|
+
let modelPath;
|
|
1091
|
+
if (models) {
|
|
1092
|
+
modelPath = await models.ensure(modelEntry.id, selectedFormat);
|
|
1093
|
+
} else {
|
|
1094
|
+
modelPath = modelFilePath(modelsDir, modelEntry, selectedFormat);
|
|
1095
|
+
if (!modelExists(modelPath)) {
|
|
1096
|
+
throw new Error(
|
|
1097
|
+
`resolveEngine: model file not found at ${modelPath} and no model service provided`
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
if (selectedFormat === "onnx") {
|
|
1102
|
+
const engine = new NodeInferenceEngine(modelPath, selectedBackend);
|
|
1103
|
+
await engine.initialize();
|
|
1104
|
+
return { engine, format: selectedFormat, modelPath };
|
|
1105
|
+
}
|
|
1106
|
+
const { pythonPath } = options;
|
|
1107
|
+
const PYTHON_SCRIPT_MAP = {
|
|
1108
|
+
coreml: "coreml_inference.py",
|
|
1109
|
+
pytorch: "pytorch_inference.py",
|
|
1110
|
+
openvino: "openvino_inference.py"
|
|
1111
|
+
};
|
|
1112
|
+
const effectiveRuntime = runtime === "auto" ? selectedBackend : runtime;
|
|
1113
|
+
const scriptName = PYTHON_SCRIPT_MAP[effectiveRuntime];
|
|
1114
|
+
if (scriptName && pythonPath) {
|
|
1115
|
+
const candidates = [
|
|
1116
|
+
path2.join(__dirname, "../../python", scriptName),
|
|
1117
|
+
path2.join(__dirname, "../python", scriptName),
|
|
1118
|
+
path2.join(__dirname, "../../../python", scriptName)
|
|
1119
|
+
];
|
|
1120
|
+
const scriptPath = candidates.find((p) => fs.existsSync(p));
|
|
1121
|
+
if (!scriptPath) {
|
|
1122
|
+
throw new Error(
|
|
1123
|
+
`resolveEngine: Python script "${scriptName}" not found. Searched:
|
|
1124
|
+
${candidates.join("\n")}`
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
const inputSize = Math.max(modelEntry.inputSize.width, modelEntry.inputSize.height);
|
|
1128
|
+
const engine = new PythonInferenceEngine(pythonPath, scriptPath, effectiveRuntime, modelPath, [
|
|
1129
|
+
`--input-size=${inputSize}`,
|
|
1130
|
+
`--confidence=0.25`
|
|
1131
|
+
]);
|
|
1132
|
+
await engine.initialize();
|
|
1133
|
+
return { engine, format: selectedFormat, modelPath };
|
|
1134
|
+
}
|
|
1135
|
+
const fallbackPath = modelFilePath(modelsDir, modelEntry, "onnx");
|
|
1136
|
+
if (modelEntry.formats["onnx"] && modelExists(fallbackPath)) {
|
|
1137
|
+
const engine = new NodeInferenceEngine(fallbackPath, "cpu");
|
|
1138
|
+
await engine.initialize();
|
|
1139
|
+
return { engine, format: "onnx", modelPath: fallbackPath };
|
|
1140
|
+
}
|
|
1141
|
+
throw new Error(
|
|
1142
|
+
`resolveEngine: format ${selectedFormat} is not yet supported by NodeInferenceEngine, no Python runtime is available, and no ONNX fallback exists`
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1145
|
+
async function probeOnnxBackends() {
|
|
1146
|
+
const available = ["cpu"];
|
|
1147
|
+
try {
|
|
1148
|
+
const ort = await import("onnxruntime-node");
|
|
1149
|
+
const providers = ort.env?.webgl?.disabled !== void 0 ? ort.InferenceSession?.getAvailableProviders?.() ?? [] : [];
|
|
1150
|
+
for (const p of providers) {
|
|
1151
|
+
const normalized = p.toLowerCase().replace("executionprovider", "");
|
|
1152
|
+
if (normalized === "coreml") available.push("coreml");
|
|
1153
|
+
else if (normalized === "cuda") available.push("cuda");
|
|
1154
|
+
else if (normalized === "tensorrt") available.push("tensorrt");
|
|
1155
|
+
}
|
|
1156
|
+
} catch {
|
|
1157
|
+
}
|
|
1158
|
+
if (process.platform === "darwin" && !available.includes("coreml")) {
|
|
1159
|
+
available.push("coreml");
|
|
1160
|
+
}
|
|
1161
|
+
return [...new Set(available)];
|
|
1162
|
+
}
|
|
1356
1163
|
|
|
1357
1164
|
// src/addons/object-detection/index.ts
|
|
1358
|
-
var object_detection_exports = {};
|
|
1359
|
-
__export(object_detection_exports, {
|
|
1360
|
-
default: () => ObjectDetectionAddon
|
|
1361
|
-
});
|
|
1362
|
-
module.exports = __toCommonJS(object_detection_exports);
|
|
1363
|
-
var import_object_detection_models = __toESM(require_object_detection_models());
|
|
1364
|
-
var import_segmentation_models = __toESM(require_segmentation_models());
|
|
1365
|
-
var import_types = require("@camstack/types");
|
|
1366
|
-
var import_image_utils = __toESM(require_image_utils());
|
|
1367
|
-
var import_yolo = __toESM(require_yolo());
|
|
1368
|
-
var import_yolo_seg = __toESM(require_yolo_seg());
|
|
1369
|
-
var import_engine_resolver = __toESM(require_engine_resolver());
|
|
1370
1165
|
function isSegModel(modelId) {
|
|
1371
1166
|
return modelId.includes("-seg");
|
|
1372
1167
|
}
|
|
1373
1168
|
var ALL_DETECTION_MODELS = [
|
|
1374
|
-
...
|
|
1375
|
-
...
|
|
1169
|
+
...OBJECT_DETECTION_MODELS,
|
|
1170
|
+
...SEGMENTATION_MODELS
|
|
1376
1171
|
];
|
|
1377
1172
|
function applyClassMap(detections, classMap) {
|
|
1378
1173
|
return detections.filter((d) => classMap.mapping[d.class] !== void 0).map((d) => ({
|
|
@@ -1489,7 +1284,7 @@ var ObjectDetectionAddon = class {
|
|
|
1489
1284
|
const result = await this.engine.runJpeg(frame.data);
|
|
1490
1285
|
const rawDets = result.detections ?? [];
|
|
1491
1286
|
const detections2 = rawDets.map((d) => ({
|
|
1492
|
-
class: this.classMapMode === "all" ? d.className :
|
|
1287
|
+
class: this.classMapMode === "all" ? d.className : import_types3.COCO_TO_MACRO.mapping[d.className] ?? d.className,
|
|
1493
1288
|
originalClass: d.className,
|
|
1494
1289
|
score: d.score,
|
|
1495
1290
|
bbox: {
|
|
@@ -1498,7 +1293,7 @@ var ObjectDetectionAddon = class {
|
|
|
1498
1293
|
w: (d.bbox[2] - d.bbox[0]) * frame.width,
|
|
1499
1294
|
h: (d.bbox[3] - d.bbox[1]) * frame.height
|
|
1500
1295
|
}
|
|
1501
|
-
})).filter((d) => this.classMapMode === "all" ||
|
|
1296
|
+
})).filter((d) => this.classMapMode === "all" || import_types3.COCO_TO_MACRO.mapping[d.originalClass] !== void 0);
|
|
1502
1297
|
return {
|
|
1503
1298
|
detections: detections2,
|
|
1504
1299
|
inferenceMs: result.inferenceMs ?? Date.now() - start,
|
|
@@ -1507,7 +1302,7 @@ var ObjectDetectionAddon = class {
|
|
|
1507
1302
|
}
|
|
1508
1303
|
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
1509
1304
|
const targetSize = Math.max(inputW, inputH);
|
|
1510
|
-
const lb = await
|
|
1305
|
+
const lb = await letterbox(frame.data, targetSize);
|
|
1511
1306
|
const numClasses = this.modelEntry.labels.length;
|
|
1512
1307
|
const labels = this.modelEntry.labels.map((l) => l.id);
|
|
1513
1308
|
const postprocessOpts = {
|
|
@@ -1535,7 +1330,7 @@ var ObjectDetectionAddon = class {
|
|
|
1535
1330
|
const numBoxes = detectionOutput.length / (4 + numClasses + numMaskCoeffs);
|
|
1536
1331
|
const maskHeight = 160;
|
|
1537
1332
|
const maskWidth = 160;
|
|
1538
|
-
rawDetections =
|
|
1333
|
+
rawDetections = yoloSegPostprocess(
|
|
1539
1334
|
{
|
|
1540
1335
|
detectionOutput,
|
|
1541
1336
|
protoOutput,
|
|
@@ -1550,9 +1345,9 @@ var ObjectDetectionAddon = class {
|
|
|
1550
1345
|
} else {
|
|
1551
1346
|
const output = await this.engine.run(lb.data, [1, 3, targetSize, targetSize]);
|
|
1552
1347
|
const numBoxes = output.length / (4 + numClasses);
|
|
1553
|
-
rawDetections =
|
|
1348
|
+
rawDetections = yoloPostprocess(output, numClasses, numBoxes, postprocessOpts);
|
|
1554
1349
|
}
|
|
1555
|
-
const detections = this.classMapMode === "all" ? rawDetections : applyClassMap(rawDetections,
|
|
1350
|
+
const detections = this.classMapMode === "all" ? rawDetections : applyClassMap(rawDetections, import_types3.COCO_TO_MACRO);
|
|
1556
1351
|
return {
|
|
1557
1352
|
detections,
|
|
1558
1353
|
inferenceMs: Date.now() - start,
|
|
@@ -1583,7 +1378,7 @@ var ObjectDetectionAddon = class {
|
|
|
1583
1378
|
}
|
|
1584
1379
|
}
|
|
1585
1380
|
}
|
|
1586
|
-
const resolved = await
|
|
1381
|
+
const resolved = await resolveEngine({
|
|
1587
1382
|
runtime,
|
|
1588
1383
|
backend,
|
|
1589
1384
|
modelEntry: entry,
|
|
@@ -1693,7 +1488,7 @@ var ObjectDetectionAddon = class {
|
|
|
1693
1488
|
};
|
|
1694
1489
|
}
|
|
1695
1490
|
getClassMap() {
|
|
1696
|
-
return
|
|
1491
|
+
return import_types3.COCO_TO_MACRO;
|
|
1697
1492
|
}
|
|
1698
1493
|
getModelCatalog() {
|
|
1699
1494
|
return [...ALL_DETECTION_MODELS];
|
|
@@ -1702,7 +1497,7 @@ var ObjectDetectionAddon = class {
|
|
|
1702
1497
|
return [];
|
|
1703
1498
|
}
|
|
1704
1499
|
getActiveLabels() {
|
|
1705
|
-
return this.classMapMode === "all" ?
|
|
1500
|
+
return this.classMapMode === "all" ? import_types3.COCO_80_LABELS : import_types3.MACRO_LABELS;
|
|
1706
1501
|
}
|
|
1707
1502
|
async probe() {
|
|
1708
1503
|
return {
|