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