@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
package/dist/index.mjs
CHANGED
|
@@ -1,2730 +1,282 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
BirdGlobalClassifierAddon
|
|
3
|
+
} from "./chunk-ZWYXXCXP.mjs";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
BirdNABirdsClassifierAddon
|
|
6
|
+
} from "./chunk-DRYFGARD.mjs";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
AnimalClassifierAddon
|
|
9
|
+
} from "./chunk-YUCD2TFH.mjs";
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
ANIMAL_TYPE_MODELS,
|
|
12
|
+
BIRD_NABIRDS_MODELS,
|
|
13
|
+
BIRD_SPECIES_MODELS
|
|
14
|
+
} from "./chunk-DUN6XU3N.mjs";
|
|
13
15
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} from "./chunk-ZK7P3TZN.mjs";
|
|
16
|
+
VEHICLE_TYPE_MODELS
|
|
17
|
+
} from "./chunk-XZ6ZMXXU.mjs";
|
|
17
18
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from "./chunk-2YMA6QOV.mjs";
|
|
19
|
+
SEGMENTATION_REFINER_MODELS
|
|
20
|
+
} from "./chunk-7DYHXUPZ.mjs";
|
|
21
21
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
} from "./chunk-F6D2OZ36.mjs";
|
|
22
|
+
detectMotion
|
|
23
|
+
} from "./chunk-BR2FPGOX.mjs";
|
|
25
24
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
ObjectDetectionAddon,
|
|
26
|
+
SEGMENTATION_MODELS
|
|
27
|
+
} from "./chunk-R5J3WAUI.mjs";
|
|
28
28
|
import {
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
FACE_DETECTION_MODELS,
|
|
30
|
+
FaceDetectionAddon,
|
|
31
|
+
scrfdPostprocess
|
|
32
|
+
} from "./chunk-ESLHNWWE.mjs";
|
|
31
33
|
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
FACE_RECOGNITION_MODELS,
|
|
35
|
+
FaceRecognitionAddon,
|
|
36
|
+
cosineSimilarity,
|
|
37
|
+
l2Normalize
|
|
38
|
+
} from "./chunk-JUQEW6ON.mjs";
|
|
34
39
|
import {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} from "./chunk-
|
|
40
|
+
PLATE_DETECTION_MODELS,
|
|
41
|
+
PlateDetectionAddon
|
|
42
|
+
} from "./chunk-YPU4WTXZ.mjs";
|
|
38
43
|
import {
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
iou,
|
|
45
|
+
nms,
|
|
46
|
+
yoloPostprocess
|
|
47
|
+
} from "./chunk-KUO2BVFY.mjs";
|
|
41
48
|
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
} from "./chunk-
|
|
49
|
+
MLPACKAGE_FILES,
|
|
50
|
+
OBJECT_DETECTION_MODELS
|
|
51
|
+
} from "./chunk-BP7H4NFS.mjs";
|
|
45
52
|
import {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
} from "./chunk-
|
|
53
|
+
PLATE_RECOGNITION_MODELS,
|
|
54
|
+
PlateRecognitionAddon,
|
|
55
|
+
ctcDecode
|
|
56
|
+
} from "./chunk-ZTJENCFC.mjs";
|
|
50
57
|
import {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
} from "./chunk-
|
|
58
|
+
cropRegion,
|
|
59
|
+
jpegToRgb,
|
|
60
|
+
letterbox,
|
|
61
|
+
resizeAndNormalize,
|
|
62
|
+
rgbToGrayscale
|
|
63
|
+
} from "./chunk-22BHCDT5.mjs";
|
|
64
|
+
import {
|
|
65
|
+
AUDIO_CLASSIFICATION_MODELS,
|
|
66
|
+
AudioClassificationAddon,
|
|
67
|
+
yamnetPostprocess
|
|
68
|
+
} from "./chunk-D6WEHN33.mjs";
|
|
69
|
+
import {
|
|
70
|
+
NodeInferenceEngine,
|
|
71
|
+
PythonInferenceEngine,
|
|
72
|
+
probeOnnxBackends,
|
|
73
|
+
resolveEngine
|
|
74
|
+
} from "./chunk-2IOKI4ES.mjs";
|
|
75
|
+
import "./chunk-BJTO5JO5.mjs";
|
|
57
76
|
|
|
58
|
-
// src/catalogs/general-ocr-models.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
labels: OCR_TEXT_LABELS,
|
|
77
|
-
formats: {
|
|
78
|
-
onnx: {
|
|
79
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/onnx/camstack-doctr-det-db-mobilenet-v3.onnx"),
|
|
80
|
-
sizeMB: 15
|
|
81
|
-
},
|
|
82
|
-
coreml: {
|
|
83
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/coreml/camstack-doctr-det-db-mobilenet-v3.mlpackage"),
|
|
84
|
-
sizeMB: 8,
|
|
85
|
-
isDirectory: true,
|
|
86
|
-
files: [
|
|
87
|
-
"Manifest.json",
|
|
88
|
-
"Data/com.apple.CoreML/model.mlmodel",
|
|
89
|
-
"Data/com.apple.CoreML/weights/weight.bin"
|
|
90
|
-
],
|
|
91
|
-
runtimes: ["python"]
|
|
92
|
-
},
|
|
93
|
-
openvino: {
|
|
94
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/openvino/camstack-doctr-det-db-mobilenet-v3.xml"),
|
|
95
|
-
sizeMB: 8,
|
|
96
|
-
runtimes: ["python"]
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
id: "doctr-rec-crnn-mobilenet",
|
|
102
|
-
name: "docTR Recognition CRNN MobileNet",
|
|
103
|
-
description: "docTR CRNN MobileNet V3 \u2014 lightweight text recognition for detected regions",
|
|
104
|
-
inputSize: { width: 128, height: 32 },
|
|
105
|
-
labels: OCR_TEXT_LABELS,
|
|
106
|
-
formats: {
|
|
107
|
-
onnx: {
|
|
108
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/onnx/camstack-doctr-rec-crnn-mobilenet-v3.onnx"),
|
|
109
|
-
sizeMB: 5
|
|
110
|
-
},
|
|
111
|
-
coreml: {
|
|
112
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/coreml/camstack-doctr-rec-crnn-mobilenet-v3.mlpackage"),
|
|
113
|
-
sizeMB: 3,
|
|
114
|
-
isDirectory: true,
|
|
115
|
-
files: [
|
|
116
|
-
"Manifest.json",
|
|
117
|
-
"Data/com.apple.CoreML/model.mlmodel",
|
|
118
|
-
"Data/com.apple.CoreML/weights/weight.bin"
|
|
119
|
-
],
|
|
120
|
-
runtimes: ["python"]
|
|
121
|
-
},
|
|
122
|
-
openvino: {
|
|
123
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/openvino/camstack-doctr-rec-crnn-mobilenet-v3.xml"),
|
|
124
|
-
sizeMB: 3,
|
|
125
|
-
runtimes: ["python"]
|
|
126
|
-
}
|
|
127
|
-
}
|
|
77
|
+
// src/catalogs/general-ocr-models.ts
|
|
78
|
+
import { hfModelUrl } from "@camstack/types";
|
|
79
|
+
var HF_REPO = "camstack/camstack-models";
|
|
80
|
+
var OCR_TEXT_LABELS = [
|
|
81
|
+
{ id: "text", name: "Scene Text" }
|
|
82
|
+
];
|
|
83
|
+
var GENERAL_OCR_MODELS = [
|
|
84
|
+
// ── OnnxTR / docTR — lightweight general scene text recognition ──
|
|
85
|
+
{
|
|
86
|
+
id: "doctr-det-db-mobilenet",
|
|
87
|
+
name: "docTR Detection MobileNet",
|
|
88
|
+
description: "docTR DBNet MobileNet V3 \u2014 lightweight text region detection for scene text",
|
|
89
|
+
inputSize: { width: 1024, height: 1024 },
|
|
90
|
+
labels: OCR_TEXT_LABELS,
|
|
91
|
+
formats: {
|
|
92
|
+
onnx: {
|
|
93
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/onnx/camstack-doctr-det-db-mobilenet-v3.onnx"),
|
|
94
|
+
sizeMB: 15
|
|
128
95
|
},
|
|
129
|
-
{
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
},
|
|
140
|
-
coreml: {
|
|
141
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/coreml/camstack-doctr-rec-parseq.mlpackage"),
|
|
142
|
-
sizeMB: 13,
|
|
143
|
-
isDirectory: true,
|
|
144
|
-
files: [
|
|
145
|
-
"Manifest.json",
|
|
146
|
-
"Data/com.apple.CoreML/model.mlmodel",
|
|
147
|
-
"Data/com.apple.CoreML/weights/weight.bin"
|
|
148
|
-
],
|
|
149
|
-
runtimes: ["python"]
|
|
150
|
-
},
|
|
151
|
-
openvino: {
|
|
152
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/doctr/openvino/camstack-doctr-rec-parseq.xml"),
|
|
153
|
-
sizeMB: 13,
|
|
154
|
-
runtimes: ["python"]
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
// ── PaddleOCR PP-OCRv5 Mobile — general-purpose text detection + recognition ──
|
|
159
|
-
{
|
|
160
|
-
id: "ppocr-v5-det-mobile",
|
|
161
|
-
name: "PP-OCRv5 Detection Mobile",
|
|
162
|
-
description: "PP-OCRv5 mobile text detection \u2014 optimized for edge, 100+ languages",
|
|
163
|
-
inputSize: { width: 640, height: 640 },
|
|
164
|
-
labels: OCR_TEXT_LABELS,
|
|
165
|
-
formats: {
|
|
166
|
-
onnx: {
|
|
167
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-det-mobile.onnx"),
|
|
168
|
-
sizeMB: 6
|
|
169
|
-
},
|
|
170
|
-
coreml: {
|
|
171
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-det-mobile.mlpackage"),
|
|
172
|
-
sizeMB: 3,
|
|
173
|
-
isDirectory: true,
|
|
174
|
-
files: [
|
|
175
|
-
"Manifest.json",
|
|
176
|
-
"Data/com.apple.CoreML/model.mlmodel",
|
|
177
|
-
"Data/com.apple.CoreML/weights/weight.bin"
|
|
178
|
-
],
|
|
179
|
-
runtimes: ["python"]
|
|
180
|
-
},
|
|
181
|
-
openvino: {
|
|
182
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-det-mobile.xml"),
|
|
183
|
-
sizeMB: 3,
|
|
184
|
-
runtimes: ["python"]
|
|
185
|
-
}
|
|
186
|
-
}
|
|
96
|
+
coreml: {
|
|
97
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/coreml/camstack-doctr-det-db-mobilenet-v3.mlpackage"),
|
|
98
|
+
sizeMB: 8,
|
|
99
|
+
isDirectory: true,
|
|
100
|
+
files: [
|
|
101
|
+
"Manifest.json",
|
|
102
|
+
"Data/com.apple.CoreML/model.mlmodel",
|
|
103
|
+
"Data/com.apple.CoreML/weights/weight.bin"
|
|
104
|
+
],
|
|
105
|
+
runtimes: ["python"]
|
|
187
106
|
},
|
|
188
|
-
{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
inputSize: { width: 320, height: 48 },
|
|
193
|
-
labels: OCR_TEXT_LABELS,
|
|
194
|
-
formats: {
|
|
195
|
-
onnx: {
|
|
196
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-rec-mobile.onnx"),
|
|
197
|
-
sizeMB: 8
|
|
198
|
-
},
|
|
199
|
-
coreml: {
|
|
200
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-rec-mobile.mlpackage"),
|
|
201
|
-
sizeMB: 4,
|
|
202
|
-
isDirectory: true,
|
|
203
|
-
files: [
|
|
204
|
-
"Manifest.json",
|
|
205
|
-
"Data/com.apple.CoreML/model.mlmodel",
|
|
206
|
-
"Data/com.apple.CoreML/weights/weight.bin"
|
|
207
|
-
],
|
|
208
|
-
runtimes: ["python"]
|
|
209
|
-
},
|
|
210
|
-
openvino: {
|
|
211
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-rec-mobile.xml"),
|
|
212
|
-
sizeMB: 4,
|
|
213
|
-
runtimes: ["python"]
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
extraFiles: [
|
|
217
|
-
{
|
|
218
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "generalOcr/ppocr-v5/camstack-ppocr-v5-keys.txt"),
|
|
219
|
-
filename: "camstack-ppocr-v5-keys.txt",
|
|
220
|
-
sizeMB: 0.1
|
|
221
|
-
}
|
|
222
|
-
]
|
|
223
|
-
}
|
|
224
|
-
];
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
// src/catalogs/index.js
|
|
229
|
-
var require_catalogs = __commonJS({
|
|
230
|
-
"src/catalogs/index.js"(exports) {
|
|
231
|
-
"use strict";
|
|
232
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
233
|
-
if (k2 === void 0) k2 = k;
|
|
234
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
235
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
236
|
-
desc = { enumerable: true, get: function() {
|
|
237
|
-
return m[k];
|
|
238
|
-
} };
|
|
239
|
-
}
|
|
240
|
-
Object.defineProperty(o, k2, desc);
|
|
241
|
-
}) : (function(o, m, k, k2) {
|
|
242
|
-
if (k2 === void 0) k2 = k;
|
|
243
|
-
o[k2] = m[k];
|
|
244
|
-
}));
|
|
245
|
-
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
|
|
246
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
|
|
247
|
-
};
|
|
248
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
249
|
-
__exportStar(require_object_detection_models(), exports);
|
|
250
|
-
__exportStar(require_face_detection_models(), exports);
|
|
251
|
-
__exportStar(require_face_recognition_models(), exports);
|
|
252
|
-
__exportStar(require_plate_detection_models(), exports);
|
|
253
|
-
__exportStar(require_plate_recognition_models(), exports);
|
|
254
|
-
__exportStar(require_general_ocr_models(), exports);
|
|
255
|
-
__exportStar(require_audio_classification_models(), exports);
|
|
256
|
-
__exportStar(require_segmentation_models(), exports);
|
|
257
|
-
__exportStar(require_animal_classification_models(), exports);
|
|
258
|
-
__exportStar(require_vehicle_classification_models(), exports);
|
|
259
|
-
__exportStar(require_segmentation_refiner_models(), exports);
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
// src/addons/object-detection/index.js
|
|
264
|
-
var require_object_detection = __commonJS({
|
|
265
|
-
"src/addons/object-detection/index.js"(exports) {
|
|
266
|
-
"use strict";
|
|
267
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
268
|
-
if (k2 === void 0) k2 = k;
|
|
269
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
270
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
271
|
-
desc = { enumerable: true, get: function() {
|
|
272
|
-
return m[k];
|
|
273
|
-
} };
|
|
274
|
-
}
|
|
275
|
-
Object.defineProperty(o, k2, desc);
|
|
276
|
-
}) : (function(o, m, k, k2) {
|
|
277
|
-
if (k2 === void 0) k2 = k;
|
|
278
|
-
o[k2] = m[k];
|
|
279
|
-
}));
|
|
280
|
-
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
281
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
282
|
-
}) : function(o, v) {
|
|
283
|
-
o["default"] = v;
|
|
284
|
-
});
|
|
285
|
-
var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
|
|
286
|
-
var ownKeys = function(o) {
|
|
287
|
-
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
288
|
-
var ar = [];
|
|
289
|
-
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
290
|
-
return ar;
|
|
291
|
-
};
|
|
292
|
-
return ownKeys(o);
|
|
293
|
-
};
|
|
294
|
-
return function(mod) {
|
|
295
|
-
if (mod && mod.__esModule) return mod;
|
|
296
|
-
var result = {};
|
|
297
|
-
if (mod != null) {
|
|
298
|
-
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
299
|
-
}
|
|
300
|
-
__setModuleDefault(result, mod);
|
|
301
|
-
return result;
|
|
302
|
-
};
|
|
303
|
-
})();
|
|
304
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
305
|
-
var object_detection_models_js_1 = require_object_detection_models();
|
|
306
|
-
var segmentation_models_js_1 = require_segmentation_models();
|
|
307
|
-
var types_1 = __require("@camstack/types");
|
|
308
|
-
var image_utils_js_1 = require_image_utils();
|
|
309
|
-
var yolo_js_1 = require_yolo();
|
|
310
|
-
var yolo_seg_js_1 = require_yolo_seg();
|
|
311
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
312
|
-
function isSegModel(modelId) {
|
|
313
|
-
return modelId.includes("-seg");
|
|
314
|
-
}
|
|
315
|
-
var ALL_DETECTION_MODELS = [
|
|
316
|
-
...object_detection_models_js_1.OBJECT_DETECTION_MODELS,
|
|
317
|
-
...segmentation_models_js_1.SEGMENTATION_MODELS
|
|
318
|
-
];
|
|
319
|
-
function applyClassMap(detections, classMap) {
|
|
320
|
-
return detections.filter((d) => classMap.mapping[d.class] !== void 0).map((d) => ({
|
|
321
|
-
...d,
|
|
322
|
-
originalClass: d.class,
|
|
323
|
-
class: classMap.mapping[d.class]
|
|
324
|
-
}));
|
|
325
|
-
}
|
|
326
|
-
var RAM_ESTIMATES = {
|
|
327
|
-
"yolov8n": 80,
|
|
328
|
-
"yolov8s": 150,
|
|
329
|
-
"yolov8s-relu": 150,
|
|
330
|
-
"yolov8m": 300,
|
|
331
|
-
"yolov8l": 500,
|
|
332
|
-
"yolov8x": 800,
|
|
333
|
-
"yolov9t": 60,
|
|
334
|
-
"yolov9s": 120,
|
|
335
|
-
"yolov9c": 300,
|
|
336
|
-
"yolo11n": 70,
|
|
337
|
-
"yolo11s": 130,
|
|
338
|
-
"yolo11m": 280,
|
|
339
|
-
"yolo11l": 450,
|
|
340
|
-
"yolo11x": 750,
|
|
341
|
-
"yolo11n-seg": 84,
|
|
342
|
-
"yolo11s-seg": 156,
|
|
343
|
-
"yolo11m-seg": 336,
|
|
344
|
-
"yolov8n-seg": 96,
|
|
345
|
-
"yolov8s-seg": 180,
|
|
346
|
-
"yolov8m-seg": 360
|
|
347
|
-
};
|
|
348
|
-
var ACCURACY_SCORES = {
|
|
349
|
-
"yolov8n": 55,
|
|
350
|
-
"yolov8s": 70,
|
|
351
|
-
"yolov8s-relu": 68,
|
|
352
|
-
"yolov8m": 82,
|
|
353
|
-
"yolov8l": 88,
|
|
354
|
-
"yolov8x": 92,
|
|
355
|
-
"yolov9t": 58,
|
|
356
|
-
"yolov9s": 73,
|
|
357
|
-
"yolov9c": 86,
|
|
358
|
-
"yolo11n": 62,
|
|
359
|
-
"yolo11s": 78,
|
|
360
|
-
"yolo11m": 88,
|
|
361
|
-
"yolo11l": 93,
|
|
362
|
-
"yolo11x": 97,
|
|
363
|
-
"yolo11n-seg": 62,
|
|
364
|
-
"yolo11s-seg": 78,
|
|
365
|
-
"yolo11m-seg": 88,
|
|
366
|
-
"yolov8n-seg": 55,
|
|
367
|
-
"yolov8s-seg": 70,
|
|
368
|
-
"yolov8m-seg": 82
|
|
369
|
-
};
|
|
370
|
-
var ObjectDetectionAddon = class {
|
|
371
|
-
id = "object-detection";
|
|
372
|
-
slot = "detector";
|
|
373
|
-
inputClasses = null;
|
|
374
|
-
outputClasses = ["person", "vehicle", "animal"];
|
|
375
|
-
slotPriority = 0;
|
|
376
|
-
manifest = {
|
|
377
|
-
id: "object-detection",
|
|
378
|
-
name: "Object Detection",
|
|
379
|
-
version: "0.1.0",
|
|
380
|
-
description: "YOLO-based object detection \u2014 detects persons, vehicles, and animals",
|
|
381
|
-
slot: "detector",
|
|
382
|
-
inputClasses: void 0,
|
|
383
|
-
outputClasses: ["person", "vehicle", "animal"],
|
|
384
|
-
supportsCustomModels: true,
|
|
385
|
-
mayRequirePython: false,
|
|
386
|
-
defaultConfig: {
|
|
387
|
-
modelId: "yolo11n",
|
|
388
|
-
runtime: "node",
|
|
389
|
-
backend: "cpu",
|
|
390
|
-
confidence: 0.5,
|
|
391
|
-
iouThreshold: 0.45,
|
|
392
|
-
classMapMode: "macro"
|
|
393
|
-
}
|
|
394
|
-
};
|
|
395
|
-
engine = null;
|
|
396
|
-
modelEntry;
|
|
397
|
-
confidence = 0.5;
|
|
398
|
-
iouThreshold = 0.45;
|
|
399
|
-
classMapMode = "macro";
|
|
400
|
-
resolvedConfig = null;
|
|
401
|
-
ctx = null;
|
|
402
|
-
getModelRequirements() {
|
|
403
|
-
return ALL_DETECTION_MODELS.map((m) => ({
|
|
404
|
-
modelId: m.id,
|
|
405
|
-
name: m.name,
|
|
406
|
-
minRAM_MB: RAM_ESTIMATES[m.id] ?? 100,
|
|
407
|
-
accuracyScore: ACCURACY_SCORES[m.id] ?? 60,
|
|
408
|
-
formats: Object.keys(m.formats)
|
|
409
|
-
}));
|
|
410
|
-
}
|
|
411
|
-
configure(config) {
|
|
412
|
-
this.resolvedConfig = config;
|
|
413
|
-
}
|
|
414
|
-
async initialize(ctx) {
|
|
415
|
-
this.ctx = ctx;
|
|
416
|
-
const cfg = ctx.addonConfig;
|
|
417
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "yolo11n";
|
|
418
|
-
this.confidence = cfg["confidence"] ?? 0.5;
|
|
419
|
-
this.iouThreshold = cfg["iouThreshold"] ?? 0.45;
|
|
420
|
-
this.classMapMode = cfg["classMapMode"] ?? "macro";
|
|
421
|
-
const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId);
|
|
422
|
-
if (!entry) {
|
|
423
|
-
throw new Error(`ObjectDetectionAddon: unknown modelId "${modelId}"`);
|
|
424
|
-
}
|
|
425
|
-
this.modelEntry = entry;
|
|
426
|
-
}
|
|
427
|
-
async detect(frame) {
|
|
428
|
-
if (!this.engine)
|
|
429
|
-
await this.ensureEngine();
|
|
430
|
-
const start = Date.now();
|
|
431
|
-
if ("runJpeg" in this.engine && typeof this.engine.runJpeg === "function") {
|
|
432
|
-
const result = await this.engine.runJpeg(frame.data);
|
|
433
|
-
const rawDets = result.detections ?? [];
|
|
434
|
-
const detections2 = rawDets.map((d) => ({
|
|
435
|
-
class: this.classMapMode === "all" ? d.className : types_1.COCO_TO_MACRO.mapping[d.className] ?? d.className,
|
|
436
|
-
originalClass: d.className,
|
|
437
|
-
score: d.score,
|
|
438
|
-
bbox: {
|
|
439
|
-
x: d.bbox[0] * frame.width,
|
|
440
|
-
y: d.bbox[1] * frame.height,
|
|
441
|
-
w: (d.bbox[2] - d.bbox[0]) * frame.width,
|
|
442
|
-
h: (d.bbox[3] - d.bbox[1]) * frame.height
|
|
443
|
-
}
|
|
444
|
-
})).filter((d) => this.classMapMode === "all" || types_1.COCO_TO_MACRO.mapping[d.originalClass] !== void 0);
|
|
445
|
-
return {
|
|
446
|
-
detections: detections2,
|
|
447
|
-
inferenceMs: result.inferenceMs ?? Date.now() - start,
|
|
448
|
-
modelId: this.modelEntry.id
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
452
|
-
const targetSize = Math.max(inputW, inputH);
|
|
453
|
-
const lb = await (0, image_utils_js_1.letterbox)(frame.data, targetSize);
|
|
454
|
-
const numClasses = this.modelEntry.labels.length;
|
|
455
|
-
const labels = this.modelEntry.labels.map((l) => l.id);
|
|
456
|
-
const postprocessOpts = {
|
|
457
|
-
confidence: this.confidence,
|
|
458
|
-
iouThreshold: this.iouThreshold,
|
|
459
|
-
labels,
|
|
460
|
-
scale: lb.scale,
|
|
461
|
-
padX: lb.padX,
|
|
462
|
-
padY: lb.padY,
|
|
463
|
-
originalWidth: lb.originalWidth,
|
|
464
|
-
originalHeight: lb.originalHeight
|
|
465
|
-
};
|
|
466
|
-
let rawDetections;
|
|
467
|
-
if (isSegModel(this.modelEntry.id)) {
|
|
468
|
-
const outputs = await this.engine.runMultiOutput(lb.data, [1, 3, targetSize, targetSize]);
|
|
469
|
-
const outputNames = Object.keys(outputs);
|
|
470
|
-
if (outputNames.length < 2) {
|
|
471
|
-
throw new Error(`ObjectDetectionAddon: seg model "${this.modelEntry.id}" returned ${outputNames.length} output(s); expected 2`);
|
|
472
|
-
}
|
|
473
|
-
const detectionOutput = outputs[outputNames[0]];
|
|
474
|
-
const protoOutput = outputs[outputNames[1]];
|
|
475
|
-
const numMaskCoeffs = 32;
|
|
476
|
-
const numBoxes = detectionOutput.length / (4 + numClasses + numMaskCoeffs);
|
|
477
|
-
const maskHeight = 160;
|
|
478
|
-
const maskWidth = 160;
|
|
479
|
-
rawDetections = (0, yolo_seg_js_1.yoloSegPostprocess)({
|
|
480
|
-
detectionOutput,
|
|
481
|
-
protoOutput,
|
|
482
|
-
numClasses,
|
|
483
|
-
numBoxes,
|
|
484
|
-
numMaskCoeffs,
|
|
485
|
-
maskHeight,
|
|
486
|
-
maskWidth
|
|
487
|
-
}, postprocessOpts);
|
|
488
|
-
} else {
|
|
489
|
-
const output = await this.engine.run(lb.data, [1, 3, targetSize, targetSize]);
|
|
490
|
-
const numBoxes = output.length / (4 + numClasses);
|
|
491
|
-
rawDetections = (0, yolo_js_1.yoloPostprocess)(output, numClasses, numBoxes, postprocessOpts);
|
|
492
|
-
}
|
|
493
|
-
const detections = this.classMapMode === "all" ? rawDetections : applyClassMap(rawDetections, types_1.COCO_TO_MACRO);
|
|
494
|
-
return {
|
|
495
|
-
detections,
|
|
496
|
-
inferenceMs: Date.now() - start,
|
|
497
|
-
modelId: this.modelEntry.id
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
async ensureEngine() {
|
|
501
|
-
const config = this.resolvedConfig;
|
|
502
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
503
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
504
|
-
const backend = config?.backend ?? "cpu";
|
|
505
|
-
const format = config?.format ?? "onnx";
|
|
506
|
-
const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
507
|
-
this.modelEntry = entry;
|
|
508
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
509
|
-
if (this.ctx.models) {
|
|
510
|
-
await this.ctx.models.ensure(modelId, format);
|
|
511
|
-
}
|
|
512
|
-
let pythonPath;
|
|
513
|
-
if (config?.runtime === "python") {
|
|
514
|
-
for (const cmd of ["python3", "python"]) {
|
|
515
|
-
try {
|
|
516
|
-
const { execSync } = await Promise.resolve().then(() => __importStar(__require("child_process")));
|
|
517
|
-
execSync(`${cmd} --version`, { timeout: 3e3, stdio: "ignore" });
|
|
518
|
-
pythonPath = cmd;
|
|
519
|
-
break;
|
|
520
|
-
} catch {
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
525
|
-
runtime,
|
|
526
|
-
backend,
|
|
527
|
-
modelEntry: entry,
|
|
528
|
-
modelsDir,
|
|
529
|
-
pythonPath,
|
|
530
|
-
models: this.ctx.models
|
|
531
|
-
});
|
|
532
|
-
this.engine = resolved.engine;
|
|
533
|
-
}
|
|
534
|
-
async shutdown() {
|
|
535
|
-
await this.engine?.dispose();
|
|
536
|
-
}
|
|
537
|
-
getConfigSchema() {
|
|
538
|
-
return {
|
|
539
|
-
sections: [
|
|
540
|
-
{
|
|
541
|
-
id: "model",
|
|
542
|
-
title: "Model",
|
|
543
|
-
columns: 1,
|
|
544
|
-
fields: [
|
|
545
|
-
{
|
|
546
|
-
key: "modelId",
|
|
547
|
-
label: "Model",
|
|
548
|
-
type: "model-selector",
|
|
549
|
-
catalog: [...ALL_DETECTION_MODELS],
|
|
550
|
-
allowCustom: true,
|
|
551
|
-
allowConversion: true,
|
|
552
|
-
acceptFormats: ["onnx", "coreml", "openvino", "tflite"],
|
|
553
|
-
requiredMetadata: ["inputSize", "labels", "outputFormat"],
|
|
554
|
-
outputFormatHint: "yolo"
|
|
555
|
-
}
|
|
556
|
-
]
|
|
557
|
-
},
|
|
558
|
-
{
|
|
559
|
-
id: "runtime",
|
|
560
|
-
title: "Runtime",
|
|
561
|
-
columns: 2,
|
|
562
|
-
fields: [
|
|
563
|
-
{
|
|
564
|
-
key: "runtime",
|
|
565
|
-
label: "Runtime",
|
|
566
|
-
type: "select",
|
|
567
|
-
options: [
|
|
568
|
-
{ value: "auto", label: "Auto" },
|
|
569
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
570
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
571
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
572
|
-
]
|
|
573
|
-
},
|
|
574
|
-
{
|
|
575
|
-
key: "backend",
|
|
576
|
-
label: "Backend",
|
|
577
|
-
type: "select",
|
|
578
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
579
|
-
options: [
|
|
580
|
-
{ value: "auto", label: "Auto" },
|
|
581
|
-
{ value: "cpu", label: "CPU" },
|
|
582
|
-
{ value: "coreml", label: "CoreML" },
|
|
583
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" },
|
|
584
|
-
{ value: "tensorrt", label: "TensorRT (NVIDIA)" }
|
|
585
|
-
]
|
|
586
|
-
}
|
|
587
|
-
]
|
|
588
|
-
},
|
|
589
|
-
{
|
|
590
|
-
id: "thresholds",
|
|
591
|
-
title: "Detection Thresholds",
|
|
592
|
-
columns: 2,
|
|
593
|
-
fields: [
|
|
594
|
-
{
|
|
595
|
-
key: "confidence",
|
|
596
|
-
label: "Confidence Threshold",
|
|
597
|
-
type: "slider",
|
|
598
|
-
min: 0.1,
|
|
599
|
-
max: 1,
|
|
600
|
-
step: 0.05,
|
|
601
|
-
default: 0.5
|
|
602
|
-
},
|
|
603
|
-
{
|
|
604
|
-
key: "iouThreshold",
|
|
605
|
-
label: "IoU Threshold (NMS)",
|
|
606
|
-
type: "slider",
|
|
607
|
-
min: 0.1,
|
|
608
|
-
max: 1,
|
|
609
|
-
step: 0.05,
|
|
610
|
-
default: 0.45
|
|
611
|
-
}
|
|
612
|
-
]
|
|
613
|
-
},
|
|
614
|
-
{
|
|
615
|
-
id: "classmap",
|
|
616
|
-
title: "Class Mapping",
|
|
617
|
-
columns: 1,
|
|
618
|
-
fields: [
|
|
619
|
-
{
|
|
620
|
-
key: "classMapMode",
|
|
621
|
-
label: "Output classes",
|
|
622
|
-
type: "select",
|
|
623
|
-
options: [
|
|
624
|
-
{ value: "macro", label: "Macro (person / vehicle / animal)" },
|
|
625
|
-
{ value: "all", label: "All COCO classes (80)" }
|
|
626
|
-
]
|
|
627
|
-
}
|
|
628
|
-
]
|
|
629
|
-
}
|
|
630
|
-
]
|
|
631
|
-
};
|
|
632
|
-
}
|
|
633
|
-
getClassMap() {
|
|
634
|
-
return types_1.COCO_TO_MACRO;
|
|
635
|
-
}
|
|
636
|
-
getModelCatalog() {
|
|
637
|
-
return [...ALL_DETECTION_MODELS];
|
|
638
|
-
}
|
|
639
|
-
getAvailableModels() {
|
|
640
|
-
return [];
|
|
641
|
-
}
|
|
642
|
-
getActiveLabels() {
|
|
643
|
-
return this.classMapMode === "all" ? types_1.COCO_80_LABELS : types_1.MACRO_LABELS;
|
|
644
|
-
}
|
|
645
|
-
async probe() {
|
|
646
|
-
return {
|
|
647
|
-
available: true,
|
|
648
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
649
|
-
device: this.engine?.device ?? "cpu",
|
|
650
|
-
capabilities: ["fp32"]
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
};
|
|
654
|
-
exports.default = ObjectDetectionAddon;
|
|
655
|
-
}
|
|
656
|
-
});
|
|
657
|
-
|
|
658
|
-
// src/addons/face-detection/index.js
|
|
659
|
-
var require_face_detection = __commonJS({
|
|
660
|
-
"src/addons/face-detection/index.js"(exports) {
|
|
661
|
-
"use strict";
|
|
662
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
663
|
-
var face_detection_models_js_1 = require_face_detection_models();
|
|
664
|
-
var image_utils_js_1 = require_image_utils();
|
|
665
|
-
var scrfd_js_1 = require_scrfd();
|
|
666
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
667
|
-
var FACE_LABEL = { id: "face", name: "Face" };
|
|
668
|
-
var FACE_LABELS = [FACE_LABEL];
|
|
669
|
-
var FACE_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
670
|
-
var RAM_ESTIMATES = {
|
|
671
|
-
"scrfd-500m": 50,
|
|
672
|
-
"scrfd-2.5g": 80,
|
|
673
|
-
"scrfd-10g": 200
|
|
674
|
-
};
|
|
675
|
-
var ACCURACY_SCORES = {
|
|
676
|
-
"scrfd-500m": 70,
|
|
677
|
-
"scrfd-2.5g": 82,
|
|
678
|
-
"scrfd-10g": 92
|
|
679
|
-
};
|
|
680
|
-
var FaceDetectionAddon = class {
|
|
681
|
-
id = "face-detection";
|
|
682
|
-
slot = "cropper";
|
|
683
|
-
inputClasses = ["person"];
|
|
684
|
-
outputClasses = ["face"];
|
|
685
|
-
slotPriority = 0;
|
|
686
|
-
manifest = {
|
|
687
|
-
id: "face-detection",
|
|
688
|
-
name: "Face Detection",
|
|
689
|
-
version: "0.1.0",
|
|
690
|
-
description: "SCRFD-based face detector \u2014 crops face regions from person detections",
|
|
691
|
-
slot: "cropper",
|
|
692
|
-
inputClasses: ["person"],
|
|
693
|
-
outputClasses: ["face"],
|
|
694
|
-
supportsCustomModels: false,
|
|
695
|
-
mayRequirePython: false,
|
|
696
|
-
defaultConfig: {
|
|
697
|
-
modelId: "scrfd-500m",
|
|
698
|
-
runtime: "node",
|
|
699
|
-
backend: "cpu",
|
|
700
|
-
confidence: 0.5
|
|
701
|
-
}
|
|
702
|
-
};
|
|
703
|
-
engine = null;
|
|
704
|
-
modelEntry;
|
|
705
|
-
confidence = 0.5;
|
|
706
|
-
resolvedConfig = null;
|
|
707
|
-
ctx = null;
|
|
708
|
-
getModelRequirements() {
|
|
709
|
-
return face_detection_models_js_1.FACE_DETECTION_MODELS.map((m) => ({
|
|
710
|
-
modelId: m.id,
|
|
711
|
-
name: m.name,
|
|
712
|
-
minRAM_MB: RAM_ESTIMATES[m.id] ?? 50,
|
|
713
|
-
accuracyScore: ACCURACY_SCORES[m.id] ?? 70,
|
|
714
|
-
formats: Object.keys(m.formats)
|
|
715
|
-
}));
|
|
716
|
-
}
|
|
717
|
-
configure(config) {
|
|
718
|
-
this.resolvedConfig = config;
|
|
719
|
-
}
|
|
720
|
-
async initialize(ctx) {
|
|
721
|
-
this.ctx = ctx;
|
|
722
|
-
const cfg = ctx.addonConfig;
|
|
723
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "scrfd-500m";
|
|
724
|
-
this.confidence = cfg["confidence"] ?? 0.5;
|
|
725
|
-
const entry = face_detection_models_js_1.FACE_DETECTION_MODELS.find((m) => m.id === modelId);
|
|
726
|
-
if (!entry) {
|
|
727
|
-
throw new Error(`FaceDetectionAddon: unknown modelId "${modelId}"`);
|
|
728
|
-
}
|
|
729
|
-
this.modelEntry = entry;
|
|
730
|
-
}
|
|
731
|
-
async crop(input) {
|
|
732
|
-
if (!this.engine)
|
|
733
|
-
await this.ensureEngine();
|
|
734
|
-
const start = Date.now();
|
|
735
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
736
|
-
const targetSize = Math.max(inputW, inputH);
|
|
737
|
-
const personCrop = await (0, image_utils_js_1.cropRegion)(input.frame.data, input.roi);
|
|
738
|
-
const lb = await (0, image_utils_js_1.letterbox)(personCrop, targetSize);
|
|
739
|
-
const engineWithMulti = this.engine;
|
|
740
|
-
let outputs;
|
|
741
|
-
if (typeof engineWithMulti.runMultiOutput === "function") {
|
|
742
|
-
outputs = await engineWithMulti.runMultiOutput(lb.data, [1, 3, targetSize, targetSize]);
|
|
743
|
-
} else {
|
|
744
|
-
const single = await this.engine.run(lb.data, [1, 3, targetSize, targetSize]);
|
|
745
|
-
outputs = { output0: single };
|
|
746
|
-
}
|
|
747
|
-
const crops = (0, scrfd_js_1.scrfdPostprocess)(outputs, this.confidence, targetSize, lb.originalWidth, lb.originalHeight);
|
|
748
|
-
return {
|
|
749
|
-
crops,
|
|
750
|
-
inferenceMs: Date.now() - start,
|
|
751
|
-
modelId: this.modelEntry.id
|
|
752
|
-
};
|
|
753
|
-
}
|
|
754
|
-
async ensureEngine() {
|
|
755
|
-
const config = this.resolvedConfig;
|
|
756
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
757
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
758
|
-
const backend = config?.backend ?? "cpu";
|
|
759
|
-
const format = config?.format ?? "onnx";
|
|
760
|
-
const entry = face_detection_models_js_1.FACE_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
761
|
-
this.modelEntry = entry;
|
|
762
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
763
|
-
if (this.ctx.models) {
|
|
764
|
-
await this.ctx.models.ensure(modelId, format);
|
|
765
|
-
}
|
|
766
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
767
|
-
runtime,
|
|
768
|
-
backend,
|
|
769
|
-
modelEntry: entry,
|
|
770
|
-
modelsDir,
|
|
771
|
-
models: this.ctx.models
|
|
772
|
-
});
|
|
773
|
-
this.engine = resolved.engine;
|
|
774
|
-
}
|
|
775
|
-
async shutdown() {
|
|
776
|
-
await this.engine?.dispose();
|
|
777
|
-
}
|
|
778
|
-
getConfigSchema() {
|
|
779
|
-
return {
|
|
780
|
-
sections: [
|
|
781
|
-
{
|
|
782
|
-
id: "model",
|
|
783
|
-
title: "Model",
|
|
784
|
-
columns: 1,
|
|
785
|
-
fields: [
|
|
786
|
-
{
|
|
787
|
-
key: "modelId",
|
|
788
|
-
label: "Model",
|
|
789
|
-
type: "model-selector",
|
|
790
|
-
catalog: [...face_detection_models_js_1.FACE_DETECTION_MODELS],
|
|
791
|
-
allowCustom: false,
|
|
792
|
-
allowConversion: false,
|
|
793
|
-
acceptFormats: ["onnx", "coreml", "openvino"],
|
|
794
|
-
requiredMetadata: ["inputSize", "labels", "outputFormat"],
|
|
795
|
-
outputFormatHint: "ssd"
|
|
796
|
-
}
|
|
797
|
-
]
|
|
798
|
-
},
|
|
799
|
-
{
|
|
800
|
-
id: "runtime",
|
|
801
|
-
title: "Runtime",
|
|
802
|
-
columns: 2,
|
|
803
|
-
fields: [
|
|
804
|
-
{
|
|
805
|
-
key: "runtime",
|
|
806
|
-
label: "Runtime",
|
|
807
|
-
type: "select",
|
|
808
|
-
options: [
|
|
809
|
-
{ value: "auto", label: "Auto" },
|
|
810
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
811
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
812
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
813
|
-
]
|
|
814
|
-
},
|
|
815
|
-
{
|
|
816
|
-
key: "backend",
|
|
817
|
-
label: "Backend",
|
|
818
|
-
type: "select",
|
|
819
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
820
|
-
options: [
|
|
821
|
-
{ value: "auto", label: "Auto" },
|
|
822
|
-
{ value: "cpu", label: "CPU" },
|
|
823
|
-
{ value: "coreml", label: "CoreML" },
|
|
824
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
825
|
-
]
|
|
826
|
-
}
|
|
827
|
-
]
|
|
828
|
-
},
|
|
829
|
-
{
|
|
830
|
-
id: "thresholds",
|
|
831
|
-
title: "Detection Thresholds",
|
|
832
|
-
columns: 1,
|
|
833
|
-
fields: [
|
|
834
|
-
{
|
|
835
|
-
key: "confidence",
|
|
836
|
-
label: "Confidence Threshold",
|
|
837
|
-
type: "slider",
|
|
838
|
-
min: 0.1,
|
|
839
|
-
max: 1,
|
|
840
|
-
step: 0.05,
|
|
841
|
-
default: 0.5
|
|
842
|
-
}
|
|
843
|
-
]
|
|
844
|
-
}
|
|
845
|
-
]
|
|
846
|
-
};
|
|
847
|
-
}
|
|
848
|
-
getClassMap() {
|
|
849
|
-
return FACE_CLASS_MAP;
|
|
107
|
+
openvino: {
|
|
108
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/openvino/camstack-doctr-det-db-mobilenet-v3.xml"),
|
|
109
|
+
sizeMB: 8,
|
|
110
|
+
runtimes: ["python"]
|
|
850
111
|
}
|
|
851
|
-
getModelCatalog() {
|
|
852
|
-
return [...face_detection_models_js_1.FACE_DETECTION_MODELS];
|
|
853
|
-
}
|
|
854
|
-
getAvailableModels() {
|
|
855
|
-
return [];
|
|
856
|
-
}
|
|
857
|
-
getActiveLabels() {
|
|
858
|
-
return FACE_LABELS;
|
|
859
|
-
}
|
|
860
|
-
async probe() {
|
|
861
|
-
return {
|
|
862
|
-
available: true,
|
|
863
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
864
|
-
device: this.engine?.device ?? "cpu",
|
|
865
|
-
capabilities: ["fp32"]
|
|
866
|
-
};
|
|
867
|
-
}
|
|
868
|
-
};
|
|
869
|
-
exports.default = FaceDetectionAddon;
|
|
870
|
-
}
|
|
871
|
-
});
|
|
872
|
-
|
|
873
|
-
// src/addons/face-recognition/index.js
|
|
874
|
-
var require_face_recognition = __commonJS({
|
|
875
|
-
"src/addons/face-recognition/index.js"(exports) {
|
|
876
|
-
"use strict";
|
|
877
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
878
|
-
var face_recognition_models_js_1 = require_face_recognition_models();
|
|
879
|
-
var image_utils_js_1 = require_image_utils();
|
|
880
|
-
var arcface_js_1 = require_arcface();
|
|
881
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
882
|
-
var IDENTITY_LABEL = { id: "identity", name: "Identity" };
|
|
883
|
-
var IDENTITY_LABELS = [IDENTITY_LABEL];
|
|
884
|
-
var FACE_REC_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
885
|
-
var REQUIRED_STEPS = [
|
|
886
|
-
{ slot: "cropper", outputClasses: ["face"], description: "Requires a face detector" }
|
|
887
|
-
];
|
|
888
|
-
var FaceRecognitionAddon = class {
|
|
889
|
-
id = "face-recognition";
|
|
890
|
-
slot = "classifier";
|
|
891
|
-
inputClasses = ["face"];
|
|
892
|
-
outputClasses = ["identity:*"];
|
|
893
|
-
slotPriority = 0;
|
|
894
|
-
requiredSteps = REQUIRED_STEPS;
|
|
895
|
-
manifest = {
|
|
896
|
-
id: "face-recognition",
|
|
897
|
-
name: "Face Recognition",
|
|
898
|
-
version: "0.1.0",
|
|
899
|
-
description: "ArcFace-based face recognition \u2014 produces 512-d identity embeddings",
|
|
900
|
-
slot: "classifier",
|
|
901
|
-
labelOutputType: "face",
|
|
902
|
-
inputClasses: ["face"],
|
|
903
|
-
outputClasses: ["identity:*"],
|
|
904
|
-
requiredSteps: REQUIRED_STEPS,
|
|
905
|
-
supportsCustomModels: false,
|
|
906
|
-
mayRequirePython: false,
|
|
907
|
-
defaultConfig: {
|
|
908
|
-
modelId: "arcface-r100",
|
|
909
|
-
runtime: "node",
|
|
910
|
-
backend: "cpu"
|
|
911
|
-
}
|
|
912
|
-
};
|
|
913
|
-
engine = null;
|
|
914
|
-
modelEntry;
|
|
915
|
-
resolvedConfig = null;
|
|
916
|
-
ctx = null;
|
|
917
|
-
getModelRequirements() {
|
|
918
|
-
return face_recognition_models_js_1.FACE_RECOGNITION_MODELS.map((m) => ({
|
|
919
|
-
modelId: m.id,
|
|
920
|
-
name: m.name,
|
|
921
|
-
minRAM_MB: 400,
|
|
922
|
-
accuracyScore: 90,
|
|
923
|
-
formats: Object.keys(m.formats)
|
|
924
|
-
}));
|
|
925
|
-
}
|
|
926
|
-
configure(config) {
|
|
927
|
-
this.resolvedConfig = config;
|
|
928
|
-
}
|
|
929
|
-
async initialize(ctx) {
|
|
930
|
-
this.ctx = ctx;
|
|
931
|
-
const cfg = ctx.addonConfig;
|
|
932
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "arcface-r100";
|
|
933
|
-
const entry = face_recognition_models_js_1.FACE_RECOGNITION_MODELS.find((m) => m.id === modelId);
|
|
934
|
-
if (!entry) {
|
|
935
|
-
throw new Error(`FaceRecognitionAddon: unknown modelId "${modelId}"`);
|
|
936
|
-
}
|
|
937
|
-
this.modelEntry = entry;
|
|
938
|
-
}
|
|
939
|
-
async classify(input) {
|
|
940
|
-
if (!this.engine)
|
|
941
|
-
await this.ensureEngine();
|
|
942
|
-
const start = Date.now();
|
|
943
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
944
|
-
const faceCrop = await (0, image_utils_js_1.cropRegion)(input.frame.data, input.roi);
|
|
945
|
-
const layout = this.modelEntry.inputLayout ?? "nhwc";
|
|
946
|
-
const normalization = this.modelEntry.inputNormalization ?? "zero-one";
|
|
947
|
-
const normalized = await (0, image_utils_js_1.resizeAndNormalize)(faceCrop, inputW, inputH, normalization, layout);
|
|
948
|
-
const rawEmbedding = await this.engine.run(normalized, [1, inputH, inputW, 3]);
|
|
949
|
-
const embedding = (0, arcface_js_1.l2Normalize)(rawEmbedding);
|
|
950
|
-
return {
|
|
951
|
-
classifications: [
|
|
952
|
-
{
|
|
953
|
-
class: "identity",
|
|
954
|
-
score: 1,
|
|
955
|
-
embedding
|
|
956
|
-
}
|
|
957
|
-
],
|
|
958
|
-
inferenceMs: Date.now() - start,
|
|
959
|
-
modelId: this.modelEntry.id
|
|
960
|
-
};
|
|
961
|
-
}
|
|
962
|
-
async ensureEngine() {
|
|
963
|
-
const config = this.resolvedConfig;
|
|
964
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
965
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
966
|
-
const backend = config?.backend ?? "cpu";
|
|
967
|
-
const format = config?.format ?? "onnx";
|
|
968
|
-
const entry = face_recognition_models_js_1.FACE_RECOGNITION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
969
|
-
this.modelEntry = entry;
|
|
970
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
971
|
-
if (this.ctx.models) {
|
|
972
|
-
await this.ctx.models.ensure(modelId, format);
|
|
973
|
-
}
|
|
974
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
975
|
-
runtime,
|
|
976
|
-
backend,
|
|
977
|
-
modelEntry: entry,
|
|
978
|
-
modelsDir,
|
|
979
|
-
models: this.ctx.models
|
|
980
|
-
});
|
|
981
|
-
this.engine = resolved.engine;
|
|
982
|
-
}
|
|
983
|
-
async shutdown() {
|
|
984
|
-
await this.engine?.dispose();
|
|
985
|
-
}
|
|
986
|
-
getConfigSchema() {
|
|
987
|
-
return {
|
|
988
|
-
sections: [
|
|
989
|
-
{
|
|
990
|
-
id: "model",
|
|
991
|
-
title: "Model",
|
|
992
|
-
columns: 1,
|
|
993
|
-
fields: [
|
|
994
|
-
{
|
|
995
|
-
key: "modelId",
|
|
996
|
-
label: "Model",
|
|
997
|
-
type: "model-selector",
|
|
998
|
-
catalog: [...face_recognition_models_js_1.FACE_RECOGNITION_MODELS],
|
|
999
|
-
allowCustom: false,
|
|
1000
|
-
allowConversion: false,
|
|
1001
|
-
acceptFormats: ["onnx", "coreml", "openvino"],
|
|
1002
|
-
requiredMetadata: ["inputSize", "labels", "outputFormat"],
|
|
1003
|
-
outputFormatHint: "embedding"
|
|
1004
|
-
}
|
|
1005
|
-
]
|
|
1006
|
-
},
|
|
1007
|
-
{
|
|
1008
|
-
id: "runtime",
|
|
1009
|
-
title: "Runtime",
|
|
1010
|
-
columns: 2,
|
|
1011
|
-
fields: [
|
|
1012
|
-
{
|
|
1013
|
-
key: "runtime",
|
|
1014
|
-
label: "Runtime",
|
|
1015
|
-
type: "select",
|
|
1016
|
-
options: [
|
|
1017
|
-
{ value: "auto", label: "Auto" },
|
|
1018
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
1019
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
1020
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
1021
|
-
]
|
|
1022
|
-
},
|
|
1023
|
-
{
|
|
1024
|
-
key: "backend",
|
|
1025
|
-
label: "Backend",
|
|
1026
|
-
type: "select",
|
|
1027
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
1028
|
-
options: [
|
|
1029
|
-
{ value: "auto", label: "Auto" },
|
|
1030
|
-
{ value: "cpu", label: "CPU" },
|
|
1031
|
-
{ value: "coreml", label: "CoreML" },
|
|
1032
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
1033
|
-
]
|
|
1034
|
-
}
|
|
1035
|
-
]
|
|
1036
|
-
}
|
|
1037
|
-
]
|
|
1038
|
-
};
|
|
1039
|
-
}
|
|
1040
|
-
getClassMap() {
|
|
1041
|
-
return FACE_REC_CLASS_MAP;
|
|
1042
|
-
}
|
|
1043
|
-
getModelCatalog() {
|
|
1044
|
-
return [...face_recognition_models_js_1.FACE_RECOGNITION_MODELS];
|
|
1045
|
-
}
|
|
1046
|
-
getAvailableModels() {
|
|
1047
|
-
return [];
|
|
1048
|
-
}
|
|
1049
|
-
getActiveLabels() {
|
|
1050
|
-
return IDENTITY_LABELS;
|
|
1051
|
-
}
|
|
1052
|
-
async probe() {
|
|
1053
|
-
return {
|
|
1054
|
-
available: true,
|
|
1055
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
1056
|
-
device: this.engine?.device ?? "cpu",
|
|
1057
|
-
capabilities: ["fp32"]
|
|
1058
|
-
};
|
|
1059
|
-
}
|
|
1060
|
-
};
|
|
1061
|
-
exports.default = FaceRecognitionAddon;
|
|
1062
|
-
}
|
|
1063
|
-
});
|
|
1064
|
-
|
|
1065
|
-
// src/addons/plate-detection/index.js
|
|
1066
|
-
var require_plate_detection = __commonJS({
|
|
1067
|
-
"src/addons/plate-detection/index.js"(exports) {
|
|
1068
|
-
"use strict";
|
|
1069
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1070
|
-
var plate_detection_models_js_1 = require_plate_detection_models();
|
|
1071
|
-
var image_utils_js_1 = require_image_utils();
|
|
1072
|
-
var yolo_js_1 = require_yolo();
|
|
1073
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
1074
|
-
var PLATE_LABEL = { id: "plate", name: "License Plate" };
|
|
1075
|
-
var PLATE_LABELS = [PLATE_LABEL];
|
|
1076
|
-
var PLATE_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
1077
|
-
var PlateDetectionAddon = class {
|
|
1078
|
-
id = "plate-detection";
|
|
1079
|
-
slot = "cropper";
|
|
1080
|
-
inputClasses = ["vehicle"];
|
|
1081
|
-
outputClasses = ["plate"];
|
|
1082
|
-
slotPriority = 0;
|
|
1083
|
-
manifest = {
|
|
1084
|
-
id: "plate-detection",
|
|
1085
|
-
name: "License Plate Detection",
|
|
1086
|
-
version: "0.1.0",
|
|
1087
|
-
description: "YOLO-based license plate detector \u2014 crops plate regions from vehicle detections",
|
|
1088
|
-
slot: "cropper",
|
|
1089
|
-
inputClasses: ["vehicle"],
|
|
1090
|
-
outputClasses: ["plate"],
|
|
1091
|
-
supportsCustomModels: false,
|
|
1092
|
-
mayRequirePython: false,
|
|
1093
|
-
defaultConfig: {
|
|
1094
|
-
modelId: "yolov8n-plate",
|
|
1095
|
-
runtime: "node",
|
|
1096
|
-
backend: "cpu",
|
|
1097
|
-
confidence: 0.5,
|
|
1098
|
-
iouThreshold: 0.45
|
|
1099
|
-
}
|
|
1100
|
-
};
|
|
1101
|
-
engine = null;
|
|
1102
|
-
modelEntry;
|
|
1103
|
-
confidence = 0.5;
|
|
1104
|
-
iouThreshold = 0.45;
|
|
1105
|
-
resolvedConfig = null;
|
|
1106
|
-
ctx = null;
|
|
1107
|
-
getModelRequirements() {
|
|
1108
|
-
return plate_detection_models_js_1.PLATE_DETECTION_MODELS.map((m) => ({
|
|
1109
|
-
modelId: m.id,
|
|
1110
|
-
name: m.name,
|
|
1111
|
-
minRAM_MB: 80,
|
|
1112
|
-
accuracyScore: 60,
|
|
1113
|
-
formats: Object.keys(m.formats)
|
|
1114
|
-
}));
|
|
1115
|
-
}
|
|
1116
|
-
configure(config) {
|
|
1117
|
-
this.resolvedConfig = config;
|
|
1118
|
-
}
|
|
1119
|
-
async initialize(ctx) {
|
|
1120
|
-
this.ctx = ctx;
|
|
1121
|
-
const cfg = ctx.addonConfig;
|
|
1122
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "yolov8n-plate";
|
|
1123
|
-
this.confidence = cfg["confidence"] ?? 0.5;
|
|
1124
|
-
this.iouThreshold = cfg["iouThreshold"] ?? 0.45;
|
|
1125
|
-
const entry = plate_detection_models_js_1.PLATE_DETECTION_MODELS.find((m) => m.id === modelId);
|
|
1126
|
-
if (!entry) {
|
|
1127
|
-
throw new Error(`PlateDetectionAddon: unknown modelId "${modelId}"`);
|
|
1128
|
-
}
|
|
1129
|
-
this.modelEntry = entry;
|
|
1130
|
-
}
|
|
1131
|
-
async crop(input) {
|
|
1132
|
-
if (!this.engine)
|
|
1133
|
-
await this.ensureEngine();
|
|
1134
|
-
const start = Date.now();
|
|
1135
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
1136
|
-
const targetSize = Math.max(inputW, inputH);
|
|
1137
|
-
const vehicleCrop = await (0, image_utils_js_1.cropRegion)(input.frame.data, input.roi);
|
|
1138
|
-
const lb = await (0, image_utils_js_1.letterbox)(vehicleCrop, targetSize);
|
|
1139
|
-
const output = await this.engine.run(lb.data, [1, 3, targetSize, targetSize]);
|
|
1140
|
-
const numClasses = this.modelEntry.labels.length;
|
|
1141
|
-
const numBoxes = output.length / (4 + numClasses);
|
|
1142
|
-
const labels = this.modelEntry.labels.map((l) => l.id);
|
|
1143
|
-
const plates = (0, yolo_js_1.yoloPostprocess)(output, numClasses, numBoxes, {
|
|
1144
|
-
confidence: this.confidence,
|
|
1145
|
-
iouThreshold: this.iouThreshold,
|
|
1146
|
-
labels,
|
|
1147
|
-
scale: lb.scale,
|
|
1148
|
-
padX: lb.padX,
|
|
1149
|
-
padY: lb.padY,
|
|
1150
|
-
originalWidth: lb.originalWidth,
|
|
1151
|
-
originalHeight: lb.originalHeight
|
|
1152
|
-
});
|
|
1153
|
-
const crops = plates.map((p) => ({ ...p, class: "plate", originalClass: p.originalClass }));
|
|
1154
|
-
return {
|
|
1155
|
-
crops,
|
|
1156
|
-
inferenceMs: Date.now() - start,
|
|
1157
|
-
modelId: this.modelEntry.id
|
|
1158
|
-
};
|
|
1159
|
-
}
|
|
1160
|
-
async ensureEngine() {
|
|
1161
|
-
const config = this.resolvedConfig;
|
|
1162
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
1163
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
1164
|
-
const backend = config?.backend ?? "cpu";
|
|
1165
|
-
const format = config?.format ?? "onnx";
|
|
1166
|
-
const entry = plate_detection_models_js_1.PLATE_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
1167
|
-
this.modelEntry = entry;
|
|
1168
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
1169
|
-
if (this.ctx.models) {
|
|
1170
|
-
await this.ctx.models.ensure(modelId, format);
|
|
1171
|
-
}
|
|
1172
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
1173
|
-
runtime,
|
|
1174
|
-
backend,
|
|
1175
|
-
modelEntry: entry,
|
|
1176
|
-
modelsDir,
|
|
1177
|
-
models: this.ctx.models
|
|
1178
|
-
});
|
|
1179
|
-
this.engine = resolved.engine;
|
|
1180
|
-
}
|
|
1181
|
-
async shutdown() {
|
|
1182
|
-
await this.engine?.dispose();
|
|
1183
|
-
}
|
|
1184
|
-
getConfigSchema() {
|
|
1185
|
-
return {
|
|
1186
|
-
sections: [
|
|
1187
|
-
{
|
|
1188
|
-
id: "model",
|
|
1189
|
-
title: "Model",
|
|
1190
|
-
columns: 1,
|
|
1191
|
-
fields: [
|
|
1192
|
-
{
|
|
1193
|
-
key: "modelId",
|
|
1194
|
-
label: "Model",
|
|
1195
|
-
type: "model-selector",
|
|
1196
|
-
catalog: [...plate_detection_models_js_1.PLATE_DETECTION_MODELS],
|
|
1197
|
-
allowCustom: false,
|
|
1198
|
-
allowConversion: false,
|
|
1199
|
-
acceptFormats: ["onnx", "coreml", "openvino"],
|
|
1200
|
-
requiredMetadata: ["inputSize", "labels", "outputFormat"],
|
|
1201
|
-
outputFormatHint: "yolo"
|
|
1202
|
-
}
|
|
1203
|
-
]
|
|
1204
|
-
},
|
|
1205
|
-
{
|
|
1206
|
-
id: "runtime",
|
|
1207
|
-
title: "Runtime",
|
|
1208
|
-
columns: 2,
|
|
1209
|
-
fields: [
|
|
1210
|
-
{
|
|
1211
|
-
key: "runtime",
|
|
1212
|
-
label: "Runtime",
|
|
1213
|
-
type: "select",
|
|
1214
|
-
options: [
|
|
1215
|
-
{ value: "auto", label: "Auto" },
|
|
1216
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
1217
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
1218
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
1219
|
-
]
|
|
1220
|
-
},
|
|
1221
|
-
{
|
|
1222
|
-
key: "backend",
|
|
1223
|
-
label: "Backend",
|
|
1224
|
-
type: "select",
|
|
1225
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
1226
|
-
options: [
|
|
1227
|
-
{ value: "auto", label: "Auto" },
|
|
1228
|
-
{ value: "cpu", label: "CPU" },
|
|
1229
|
-
{ value: "coreml", label: "CoreML" },
|
|
1230
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
1231
|
-
]
|
|
1232
|
-
}
|
|
1233
|
-
]
|
|
1234
|
-
},
|
|
1235
|
-
{
|
|
1236
|
-
id: "thresholds",
|
|
1237
|
-
title: "Detection Thresholds",
|
|
1238
|
-
columns: 2,
|
|
1239
|
-
fields: [
|
|
1240
|
-
{
|
|
1241
|
-
key: "confidence",
|
|
1242
|
-
label: "Confidence Threshold",
|
|
1243
|
-
type: "slider",
|
|
1244
|
-
min: 0.1,
|
|
1245
|
-
max: 1,
|
|
1246
|
-
step: 0.05,
|
|
1247
|
-
default: 0.5
|
|
1248
|
-
},
|
|
1249
|
-
{
|
|
1250
|
-
key: "iouThreshold",
|
|
1251
|
-
label: "IoU Threshold (NMS)",
|
|
1252
|
-
type: "slider",
|
|
1253
|
-
min: 0.1,
|
|
1254
|
-
max: 1,
|
|
1255
|
-
step: 0.05,
|
|
1256
|
-
default: 0.45
|
|
1257
|
-
}
|
|
1258
|
-
]
|
|
1259
|
-
}
|
|
1260
|
-
]
|
|
1261
|
-
};
|
|
1262
|
-
}
|
|
1263
|
-
getClassMap() {
|
|
1264
|
-
return PLATE_CLASS_MAP;
|
|
1265
|
-
}
|
|
1266
|
-
getModelCatalog() {
|
|
1267
|
-
return [...plate_detection_models_js_1.PLATE_DETECTION_MODELS];
|
|
1268
|
-
}
|
|
1269
|
-
getAvailableModels() {
|
|
1270
|
-
return [];
|
|
1271
|
-
}
|
|
1272
|
-
getActiveLabels() {
|
|
1273
|
-
return PLATE_LABELS;
|
|
1274
|
-
}
|
|
1275
|
-
async probe() {
|
|
1276
|
-
return {
|
|
1277
|
-
available: true,
|
|
1278
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
1279
|
-
device: this.engine?.device ?? "cpu",
|
|
1280
|
-
capabilities: ["fp32"]
|
|
1281
|
-
};
|
|
1282
|
-
}
|
|
1283
|
-
};
|
|
1284
|
-
exports.default = PlateDetectionAddon;
|
|
1285
|
-
}
|
|
1286
|
-
});
|
|
1287
|
-
|
|
1288
|
-
// src/addons/plate-recognition/index.js
|
|
1289
|
-
var require_plate_recognition = __commonJS({
|
|
1290
|
-
"src/addons/plate-recognition/index.js"(exports) {
|
|
1291
|
-
"use strict";
|
|
1292
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
1293
|
-
if (k2 === void 0) k2 = k;
|
|
1294
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
1295
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
1296
|
-
desc = { enumerable: true, get: function() {
|
|
1297
|
-
return m[k];
|
|
1298
|
-
} };
|
|
1299
|
-
}
|
|
1300
|
-
Object.defineProperty(o, k2, desc);
|
|
1301
|
-
}) : (function(o, m, k, k2) {
|
|
1302
|
-
if (k2 === void 0) k2 = k;
|
|
1303
|
-
o[k2] = m[k];
|
|
1304
|
-
}));
|
|
1305
|
-
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
1306
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
1307
|
-
}) : function(o, v) {
|
|
1308
|
-
o["default"] = v;
|
|
1309
|
-
});
|
|
1310
|
-
var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
|
|
1311
|
-
var ownKeys = function(o) {
|
|
1312
|
-
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
1313
|
-
var ar = [];
|
|
1314
|
-
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
1315
|
-
return ar;
|
|
1316
|
-
};
|
|
1317
|
-
return ownKeys(o);
|
|
1318
|
-
};
|
|
1319
|
-
return function(mod) {
|
|
1320
|
-
if (mod && mod.__esModule) return mod;
|
|
1321
|
-
var result = {};
|
|
1322
|
-
if (mod != null) {
|
|
1323
|
-
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
1324
|
-
}
|
|
1325
|
-
__setModuleDefault(result, mod);
|
|
1326
|
-
return result;
|
|
1327
|
-
};
|
|
1328
|
-
})();
|
|
1329
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1330
|
-
var plate_recognition_models_js_1 = require_plate_recognition_models();
|
|
1331
|
-
var image_utils_js_1 = require_image_utils();
|
|
1332
|
-
var paddleocr_js_1 = require_paddleocr();
|
|
1333
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
1334
|
-
var PLATE_TEXT_LABEL = { id: "plate-text", name: "Plate Text" };
|
|
1335
|
-
var PLATE_TEXT_LABELS = [PLATE_TEXT_LABEL];
|
|
1336
|
-
var PLATE_REC_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
1337
|
-
var fs = __importStar(__require("fs"));
|
|
1338
|
-
var path = __importStar(__require("path"));
|
|
1339
|
-
function loadCharset(modelsDir, modelId) {
|
|
1340
|
-
const dictNames = [
|
|
1341
|
-
`camstack-${modelId}-dict.txt`,
|
|
1342
|
-
`camstack-paddleocr-latin-dict.txt`,
|
|
1343
|
-
`camstack-paddleocr-en-dict.txt`,
|
|
1344
|
-
`camstack-crnn-mobilenet-charset.txt`
|
|
1345
|
-
];
|
|
1346
|
-
for (const name of dictNames) {
|
|
1347
|
-
const dictPath = path.join(modelsDir, name);
|
|
1348
|
-
if (fs.existsSync(dictPath)) {
|
|
1349
|
-
const lines = fs.readFileSync(dictPath, "utf-8").split("\n").filter((l) => l.length > 0);
|
|
1350
|
-
return ["", ...lines, " "];
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
throw new Error(`PlateRecognitionAddon: dict.txt not found in ${modelsDir}`);
|
|
1354
112
|
}
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
}
|
|
1383
|
-
};
|
|
1384
|
-
engine = null;
|
|
1385
|
-
modelEntry;
|
|
1386
|
-
minConfidence = 0.5;
|
|
1387
|
-
charset = [];
|
|
1388
|
-
resolvedConfig = null;
|
|
1389
|
-
ctx = null;
|
|
1390
|
-
getModelRequirements() {
|
|
1391
|
-
const scores = {
|
|
1392
|
-
"paddleocr-latin": { ram: 100, accuracy: 80 },
|
|
1393
|
-
"paddleocr-en": { ram: 100, accuracy: 80 }
|
|
1394
|
-
};
|
|
1395
|
-
return plate_recognition_models_js_1.PLATE_RECOGNITION_MODELS.map((m) => ({
|
|
1396
|
-
modelId: m.id,
|
|
1397
|
-
name: m.name,
|
|
1398
|
-
minRAM_MB: scores[m.id]?.ram ?? 100,
|
|
1399
|
-
accuracyScore: scores[m.id]?.accuracy ?? 75,
|
|
1400
|
-
formats: Object.keys(m.formats)
|
|
1401
|
-
}));
|
|
1402
|
-
}
|
|
1403
|
-
configure(config) {
|
|
1404
|
-
this.resolvedConfig = config;
|
|
1405
|
-
}
|
|
1406
|
-
async initialize(ctx) {
|
|
1407
|
-
this.ctx = ctx;
|
|
1408
|
-
const cfg = ctx.addonConfig;
|
|
1409
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "paddleocr-latin";
|
|
1410
|
-
this.minConfidence = cfg["minConfidence"] ?? 0.5;
|
|
1411
|
-
const entry = plate_recognition_models_js_1.PLATE_RECOGNITION_MODELS.find((m) => m.id === modelId);
|
|
1412
|
-
if (!entry) {
|
|
1413
|
-
throw new Error(`PlateRecognitionAddon: unknown modelId "${modelId}"`);
|
|
1414
|
-
}
|
|
1415
|
-
this.modelEntry = entry;
|
|
1416
|
-
}
|
|
1417
|
-
async classify(input) {
|
|
1418
|
-
if (!this.engine)
|
|
1419
|
-
await this.ensureEngine();
|
|
1420
|
-
const start = Date.now();
|
|
1421
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
1422
|
-
console.log(`[plate-recognition] ROI: x=${input.roi?.x}, y=${input.roi?.y}, w=${input.roi?.w}, h=${input.roi?.h}, frameSize=${input.frame?.data?.length}`);
|
|
1423
|
-
const plateCrop = await (0, image_utils_js_1.cropRegion)(input.frame.data, input.roi);
|
|
1424
|
-
console.log(`[plate-recognition] Crop size: ${plateCrop.length} bytes`);
|
|
1425
|
-
try {
|
|
1426
|
-
__require("fs").writeFileSync("/tmp/plate-recognition-crop.jpg", plateCrop);
|
|
1427
|
-
} catch {
|
|
1428
|
-
}
|
|
1429
|
-
const normalized = await (0, image_utils_js_1.resizeAndNormalize)(plateCrop, inputW, inputH, "zero-one", "nchw");
|
|
1430
|
-
const output = await this.engine.run(normalized, [1, 3, inputH, inputW]);
|
|
1431
|
-
const numChars = this.charset.length;
|
|
1432
|
-
const seqLen = output.length / numChars;
|
|
1433
|
-
const { text, confidence } = (0, paddleocr_js_1.ctcDecode)(output, seqLen, numChars, this.charset);
|
|
1434
|
-
return {
|
|
1435
|
-
classifications: [
|
|
1436
|
-
{
|
|
1437
|
-
class: "plate-text",
|
|
1438
|
-
score: confidence,
|
|
1439
|
-
text: text.trim() || "(unreadable)"
|
|
1440
|
-
}
|
|
1441
|
-
],
|
|
1442
|
-
inferenceMs: Date.now() - start,
|
|
1443
|
-
modelId: this.modelEntry.id
|
|
1444
|
-
};
|
|
1445
|
-
}
|
|
1446
|
-
async ensureEngine() {
|
|
1447
|
-
const config = this.resolvedConfig;
|
|
1448
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
1449
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
1450
|
-
const backend = config?.backend ?? "cpu";
|
|
1451
|
-
const format = config?.format ?? "onnx";
|
|
1452
|
-
const entry = plate_recognition_models_js_1.PLATE_RECOGNITION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
1453
|
-
this.modelEntry = entry;
|
|
1454
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
1455
|
-
if (this.ctx.models) {
|
|
1456
|
-
await this.ctx.models.ensure(modelId, format);
|
|
1457
|
-
}
|
|
1458
|
-
this.charset = loadCharset(modelsDir, modelId);
|
|
1459
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
1460
|
-
runtime,
|
|
1461
|
-
backend,
|
|
1462
|
-
modelEntry: entry,
|
|
1463
|
-
modelsDir,
|
|
1464
|
-
models: this.ctx.models
|
|
1465
|
-
});
|
|
1466
|
-
this.engine = resolved.engine;
|
|
1467
|
-
}
|
|
1468
|
-
async shutdown() {
|
|
1469
|
-
await this.engine?.dispose();
|
|
1470
|
-
}
|
|
1471
|
-
getConfigSchema() {
|
|
1472
|
-
return {
|
|
1473
|
-
sections: [
|
|
1474
|
-
{
|
|
1475
|
-
id: "model",
|
|
1476
|
-
title: "Model",
|
|
1477
|
-
columns: 1,
|
|
1478
|
-
fields: [
|
|
1479
|
-
{
|
|
1480
|
-
key: "modelId",
|
|
1481
|
-
label: "Model",
|
|
1482
|
-
type: "model-selector",
|
|
1483
|
-
catalog: [...plate_recognition_models_js_1.PLATE_RECOGNITION_MODELS],
|
|
1484
|
-
allowCustom: false,
|
|
1485
|
-
allowConversion: false,
|
|
1486
|
-
acceptFormats: ["onnx", "openvino"],
|
|
1487
|
-
requiredMetadata: ["inputSize", "labels", "outputFormat"],
|
|
1488
|
-
outputFormatHint: "ocr"
|
|
1489
|
-
}
|
|
1490
|
-
]
|
|
1491
|
-
},
|
|
1492
|
-
{
|
|
1493
|
-
id: "runtime",
|
|
1494
|
-
title: "Runtime",
|
|
1495
|
-
columns: 2,
|
|
1496
|
-
fields: [
|
|
1497
|
-
{
|
|
1498
|
-
key: "runtime",
|
|
1499
|
-
label: "Runtime",
|
|
1500
|
-
type: "select",
|
|
1501
|
-
options: [
|
|
1502
|
-
{ value: "auto", label: "Auto" },
|
|
1503
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
1504
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
1505
|
-
]
|
|
1506
|
-
},
|
|
1507
|
-
{
|
|
1508
|
-
key: "backend",
|
|
1509
|
-
label: "Backend",
|
|
1510
|
-
type: "select",
|
|
1511
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
1512
|
-
options: [
|
|
1513
|
-
{ value: "auto", label: "Auto" },
|
|
1514
|
-
{ value: "cpu", label: "CPU" },
|
|
1515
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
1516
|
-
]
|
|
1517
|
-
}
|
|
1518
|
-
]
|
|
1519
|
-
},
|
|
1520
|
-
{
|
|
1521
|
-
id: "thresholds",
|
|
1522
|
-
title: "Recognition Settings",
|
|
1523
|
-
columns: 1,
|
|
1524
|
-
fields: [
|
|
1525
|
-
{
|
|
1526
|
-
key: "minConfidence",
|
|
1527
|
-
label: "Minimum Confidence",
|
|
1528
|
-
type: "slider",
|
|
1529
|
-
min: 0.1,
|
|
1530
|
-
max: 1,
|
|
1531
|
-
step: 0.05,
|
|
1532
|
-
default: 0.5
|
|
1533
|
-
}
|
|
1534
|
-
]
|
|
1535
|
-
}
|
|
1536
|
-
]
|
|
1537
|
-
};
|
|
1538
|
-
}
|
|
1539
|
-
getClassMap() {
|
|
1540
|
-
return PLATE_REC_CLASS_MAP;
|
|
1541
|
-
}
|
|
1542
|
-
getModelCatalog() {
|
|
1543
|
-
return [...plate_recognition_models_js_1.PLATE_RECOGNITION_MODELS];
|
|
1544
|
-
}
|
|
1545
|
-
getAvailableModels() {
|
|
1546
|
-
return [];
|
|
1547
|
-
}
|
|
1548
|
-
getActiveLabels() {
|
|
1549
|
-
return PLATE_TEXT_LABELS;
|
|
1550
|
-
}
|
|
1551
|
-
async probe() {
|
|
1552
|
-
return {
|
|
1553
|
-
available: true,
|
|
1554
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
1555
|
-
device: this.engine?.device ?? "cpu",
|
|
1556
|
-
capabilities: ["fp32"]
|
|
1557
|
-
};
|
|
1558
|
-
}
|
|
1559
|
-
};
|
|
1560
|
-
exports.default = PlateRecognitionAddon;
|
|
1561
|
-
}
|
|
1562
|
-
});
|
|
1563
|
-
|
|
1564
|
-
// src/addons/audio-classification/index.js
|
|
1565
|
-
var require_audio_classification = __commonJS({
|
|
1566
|
-
"src/addons/audio-classification/index.js"(exports) {
|
|
1567
|
-
"use strict";
|
|
1568
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1569
|
-
var audio_classification_models_js_1 = require_audio_classification_models();
|
|
1570
|
-
var yamnet_js_1 = require_yamnet();
|
|
1571
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
1572
|
-
var YAMNET_NUM_CLASSES = 521;
|
|
1573
|
-
var AUDIO_EVENT_LABEL = { id: "audio-event", name: "Audio Event" };
|
|
1574
|
-
var AUDIO_LABELS = [AUDIO_EVENT_LABEL];
|
|
1575
|
-
var AUDIO_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
1576
|
-
var AudioClassificationAddon = class {
|
|
1577
|
-
id = "audio-classification";
|
|
1578
|
-
slot = "classifier";
|
|
1579
|
-
inputClasses = null;
|
|
1580
|
-
outputClasses = ["audio-event:*"];
|
|
1581
|
-
slotPriority = 0;
|
|
1582
|
-
manifest = {
|
|
1583
|
-
id: "audio-classification",
|
|
1584
|
-
name: "Audio Classification",
|
|
1585
|
-
version: "0.1.0",
|
|
1586
|
-
description: "YAMNet-based audio event classification from audio waveform",
|
|
1587
|
-
slot: "classifier",
|
|
1588
|
-
labelOutputType: "classification",
|
|
1589
|
-
inputClasses: void 0,
|
|
1590
|
-
outputClasses: ["audio-event:*"],
|
|
1591
|
-
supportsCustomModels: false,
|
|
1592
|
-
mayRequirePython: false,
|
|
1593
|
-
defaultConfig: {
|
|
1594
|
-
modelId: "yamnet",
|
|
1595
|
-
runtime: "node",
|
|
1596
|
-
backend: "cpu",
|
|
1597
|
-
minScore: 0.3
|
|
1598
|
-
}
|
|
1599
|
-
};
|
|
1600
|
-
engine = null;
|
|
1601
|
-
modelEntry;
|
|
1602
|
-
minScore = 0.3;
|
|
1603
|
-
resolvedConfig = null;
|
|
1604
|
-
ctx = null;
|
|
1605
|
-
getModelRequirements() {
|
|
1606
|
-
return audio_classification_models_js_1.AUDIO_CLASSIFICATION_MODELS.map((m) => ({
|
|
1607
|
-
modelId: m.id,
|
|
1608
|
-
name: m.name,
|
|
1609
|
-
minRAM_MB: 100,
|
|
1610
|
-
accuracyScore: 80,
|
|
1611
|
-
formats: Object.keys(m.formats)
|
|
1612
|
-
}));
|
|
1613
|
-
}
|
|
1614
|
-
configure(config) {
|
|
1615
|
-
this.resolvedConfig = config;
|
|
1616
|
-
}
|
|
1617
|
-
async initialize(ctx) {
|
|
1618
|
-
this.ctx = ctx;
|
|
1619
|
-
const cfg = ctx.addonConfig;
|
|
1620
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "yamnet";
|
|
1621
|
-
this.minScore = cfg["minScore"] ?? 0.3;
|
|
1622
|
-
const entry = audio_classification_models_js_1.AUDIO_CLASSIFICATION_MODELS.find((m) => m.id === modelId);
|
|
1623
|
-
if (!entry) {
|
|
1624
|
-
throw new Error(`AudioClassificationAddon: unknown modelId "${modelId}"`);
|
|
1625
|
-
}
|
|
1626
|
-
this.modelEntry = entry;
|
|
1627
|
-
}
|
|
1628
|
-
/**
|
|
1629
|
-
* classify() receives a CropInput but internally treats input.frame.data as raw audio context.
|
|
1630
|
-
* For audio, the actual audio chunk data should be stored in frame.data as a Float32Array
|
|
1631
|
-
* serialized into a Buffer (little-endian float32 samples at 16 kHz).
|
|
1632
|
-
*
|
|
1633
|
-
* The CropInput.roi is not used for audio — it is ignored.
|
|
1634
|
-
*/
|
|
1635
|
-
async classify(input) {
|
|
1636
|
-
if (!this.engine)
|
|
1637
|
-
await this.ensureEngine();
|
|
1638
|
-
const start = Date.now();
|
|
1639
|
-
const buf = input.frame.data;
|
|
1640
|
-
const numSamples = Math.floor(buf.length / 4);
|
|
1641
|
-
const audioData = new Float32Array(numSamples);
|
|
1642
|
-
for (let i = 0; i < numSamples; i++) {
|
|
1643
|
-
audioData[i] = buf.readFloatLE(i * 4);
|
|
1644
|
-
}
|
|
1645
|
-
const output = await this.engine.run(audioData, [numSamples]);
|
|
1646
|
-
const numFrames = output.length / YAMNET_NUM_CLASSES;
|
|
1647
|
-
const classNames = this.modelEntry.labels.map((l) => l.id);
|
|
1648
|
-
while (classNames.length < YAMNET_NUM_CLASSES) {
|
|
1649
|
-
classNames.push(`class_${classNames.length}`);
|
|
1650
|
-
}
|
|
1651
|
-
const results = (0, yamnet_js_1.yamnetPostprocess)(output, Math.round(numFrames), YAMNET_NUM_CLASSES, classNames, this.minScore);
|
|
1652
|
-
const classifications = results.map((r) => ({
|
|
1653
|
-
class: `audio-event:${r.className}`,
|
|
1654
|
-
score: r.score
|
|
1655
|
-
}));
|
|
1656
|
-
return {
|
|
1657
|
-
classifications,
|
|
1658
|
-
inferenceMs: Date.now() - start,
|
|
1659
|
-
modelId: this.modelEntry.id
|
|
1660
|
-
};
|
|
1661
|
-
}
|
|
1662
|
-
async ensureEngine() {
|
|
1663
|
-
const config = this.resolvedConfig;
|
|
1664
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
1665
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
1666
|
-
const backend = config?.backend ?? "cpu";
|
|
1667
|
-
const format = config?.format ?? "onnx";
|
|
1668
|
-
const entry = audio_classification_models_js_1.AUDIO_CLASSIFICATION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
1669
|
-
this.modelEntry = entry;
|
|
1670
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
1671
|
-
if (this.ctx.models) {
|
|
1672
|
-
await this.ctx.models.ensure(modelId, format);
|
|
1673
|
-
}
|
|
1674
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
1675
|
-
runtime,
|
|
1676
|
-
backend,
|
|
1677
|
-
modelEntry: entry,
|
|
1678
|
-
modelsDir,
|
|
1679
|
-
models: this.ctx.models
|
|
1680
|
-
});
|
|
1681
|
-
this.engine = resolved.engine;
|
|
1682
|
-
}
|
|
1683
|
-
async shutdown() {
|
|
1684
|
-
await this.engine?.dispose();
|
|
1685
|
-
}
|
|
1686
|
-
getConfigSchema() {
|
|
1687
|
-
return {
|
|
1688
|
-
sections: [
|
|
1689
|
-
{
|
|
1690
|
-
id: "model",
|
|
1691
|
-
title: "Model",
|
|
1692
|
-
columns: 1,
|
|
1693
|
-
fields: [
|
|
1694
|
-
{
|
|
1695
|
-
key: "modelId",
|
|
1696
|
-
label: "Model",
|
|
1697
|
-
type: "model-selector",
|
|
1698
|
-
catalog: [...audio_classification_models_js_1.AUDIO_CLASSIFICATION_MODELS],
|
|
1699
|
-
allowCustom: false,
|
|
1700
|
-
allowConversion: false,
|
|
1701
|
-
acceptFormats: ["onnx", "openvino"],
|
|
1702
|
-
requiredMetadata: ["inputSize", "labels", "outputFormat"],
|
|
1703
|
-
outputFormatHint: "classification"
|
|
1704
|
-
}
|
|
1705
|
-
]
|
|
1706
|
-
},
|
|
1707
|
-
{
|
|
1708
|
-
id: "runtime",
|
|
1709
|
-
title: "Runtime",
|
|
1710
|
-
columns: 2,
|
|
1711
|
-
fields: [
|
|
1712
|
-
{
|
|
1713
|
-
key: "runtime",
|
|
1714
|
-
label: "Runtime",
|
|
1715
|
-
type: "select",
|
|
1716
|
-
options: [
|
|
1717
|
-
{ value: "auto", label: "Auto" },
|
|
1718
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
1719
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
1720
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
1721
|
-
]
|
|
1722
|
-
},
|
|
1723
|
-
{
|
|
1724
|
-
key: "backend",
|
|
1725
|
-
label: "Backend",
|
|
1726
|
-
type: "select",
|
|
1727
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
1728
|
-
options: [
|
|
1729
|
-
{ value: "auto", label: "Auto" },
|
|
1730
|
-
{ value: "cpu", label: "CPU" },
|
|
1731
|
-
{ value: "coreml", label: "CoreML" },
|
|
1732
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
1733
|
-
]
|
|
1734
|
-
}
|
|
1735
|
-
]
|
|
1736
|
-
},
|
|
1737
|
-
{
|
|
1738
|
-
id: "thresholds",
|
|
1739
|
-
title: "Classification Settings",
|
|
1740
|
-
columns: 1,
|
|
1741
|
-
fields: [
|
|
1742
|
-
{
|
|
1743
|
-
key: "minScore",
|
|
1744
|
-
label: "Minimum Score",
|
|
1745
|
-
type: "slider",
|
|
1746
|
-
min: 0.05,
|
|
1747
|
-
max: 1,
|
|
1748
|
-
step: 0.05,
|
|
1749
|
-
default: 0.3
|
|
1750
|
-
}
|
|
1751
|
-
]
|
|
1752
|
-
}
|
|
1753
|
-
]
|
|
1754
|
-
};
|
|
1755
|
-
}
|
|
1756
|
-
getClassMap() {
|
|
1757
|
-
return AUDIO_CLASS_MAP;
|
|
1758
|
-
}
|
|
1759
|
-
getModelCatalog() {
|
|
1760
|
-
return [...audio_classification_models_js_1.AUDIO_CLASSIFICATION_MODELS];
|
|
1761
|
-
}
|
|
1762
|
-
getAvailableModels() {
|
|
1763
|
-
return [];
|
|
1764
|
-
}
|
|
1765
|
-
getActiveLabels() {
|
|
1766
|
-
return AUDIO_LABELS;
|
|
1767
|
-
}
|
|
1768
|
-
async probe() {
|
|
1769
|
-
return {
|
|
1770
|
-
available: true,
|
|
1771
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
1772
|
-
device: this.engine?.device ?? "cpu",
|
|
1773
|
-
capabilities: ["fp32"]
|
|
1774
|
-
};
|
|
1775
|
-
}
|
|
1776
|
-
};
|
|
1777
|
-
exports.default = AudioClassificationAddon;
|
|
1778
|
-
}
|
|
1779
|
-
});
|
|
1780
|
-
|
|
1781
|
-
// src/addons/bird-global-classifier/index.js
|
|
1782
|
-
var require_bird_global_classifier = __commonJS({
|
|
1783
|
-
"src/addons/bird-global-classifier/index.js"(exports) {
|
|
1784
|
-
"use strict";
|
|
1785
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
1786
|
-
if (k2 === void 0) k2 = k;
|
|
1787
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
1788
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
1789
|
-
desc = { enumerable: true, get: function() {
|
|
1790
|
-
return m[k];
|
|
1791
|
-
} };
|
|
1792
|
-
}
|
|
1793
|
-
Object.defineProperty(o, k2, desc);
|
|
1794
|
-
}) : (function(o, m, k, k2) {
|
|
1795
|
-
if (k2 === void 0) k2 = k;
|
|
1796
|
-
o[k2] = m[k];
|
|
1797
|
-
}));
|
|
1798
|
-
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
1799
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
1800
|
-
}) : function(o, v) {
|
|
1801
|
-
o["default"] = v;
|
|
1802
|
-
});
|
|
1803
|
-
var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
|
|
1804
|
-
var ownKeys = function(o) {
|
|
1805
|
-
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
1806
|
-
var ar = [];
|
|
1807
|
-
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
1808
|
-
return ar;
|
|
1809
|
-
};
|
|
1810
|
-
return ownKeys(o);
|
|
1811
|
-
};
|
|
1812
|
-
return function(mod) {
|
|
1813
|
-
if (mod && mod.__esModule) return mod;
|
|
1814
|
-
var result = {};
|
|
1815
|
-
if (mod != null) {
|
|
1816
|
-
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
1817
|
-
}
|
|
1818
|
-
__setModuleDefault(result, mod);
|
|
1819
|
-
return result;
|
|
1820
|
-
};
|
|
1821
|
-
})();
|
|
1822
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1823
|
-
var animal_classification_models_js_1 = require_animal_classification_models();
|
|
1824
|
-
var image_utils_js_1 = require_image_utils();
|
|
1825
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
1826
|
-
var fs = __importStar(__require("fs"));
|
|
1827
|
-
var path = __importStar(__require("path"));
|
|
1828
|
-
var SPECIES_LABEL = { id: "species", name: "Bird Species" };
|
|
1829
|
-
var SPECIES_LABELS = [SPECIES_LABEL];
|
|
1830
|
-
var BIRD_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
1831
|
-
function loadLabels(modelsDir, modelId) {
|
|
1832
|
-
const labelNames = [
|
|
1833
|
-
`camstack-${modelId}-labels.json`,
|
|
1834
|
-
`camstack-bird-species-525-labels.json`
|
|
1835
|
-
];
|
|
1836
|
-
for (const name of labelNames) {
|
|
1837
|
-
const labelPath = path.join(modelsDir, name);
|
|
1838
|
-
if (fs.existsSync(labelPath)) {
|
|
1839
|
-
const raw = fs.readFileSync(labelPath, "utf-8");
|
|
1840
|
-
return JSON.parse(raw);
|
|
1841
|
-
}
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: "doctr-rec-crnn-mobilenet",
|
|
116
|
+
name: "docTR Recognition CRNN MobileNet",
|
|
117
|
+
description: "docTR CRNN MobileNet V3 \u2014 lightweight text recognition for detected regions",
|
|
118
|
+
inputSize: { width: 128, height: 32 },
|
|
119
|
+
labels: OCR_TEXT_LABELS,
|
|
120
|
+
formats: {
|
|
121
|
+
onnx: {
|
|
122
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/onnx/camstack-doctr-rec-crnn-mobilenet-v3.onnx"),
|
|
123
|
+
sizeMB: 5
|
|
124
|
+
},
|
|
125
|
+
coreml: {
|
|
126
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/coreml/camstack-doctr-rec-crnn-mobilenet-v3.mlpackage"),
|
|
127
|
+
sizeMB: 3,
|
|
128
|
+
isDirectory: true,
|
|
129
|
+
files: [
|
|
130
|
+
"Manifest.json",
|
|
131
|
+
"Data/com.apple.CoreML/model.mlmodel",
|
|
132
|
+
"Data/com.apple.CoreML/weights/weight.bin"
|
|
133
|
+
],
|
|
134
|
+
runtimes: ["python"]
|
|
135
|
+
},
|
|
136
|
+
openvino: {
|
|
137
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/openvino/camstack-doctr-rec-crnn-mobilenet-v3.xml"),
|
|
138
|
+
sizeMB: 3,
|
|
139
|
+
runtimes: ["python"]
|
|
1842
140
|
}
|
|
1843
|
-
throw new Error(`BirdGlobalClassifierAddon: labels JSON not found in ${modelsDir}`);
|
|
1844
141
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
}
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
backend: "cpu",
|
|
1873
|
-
minConfidence: 0.3
|
|
1874
|
-
}
|
|
1875
|
-
};
|
|
1876
|
-
engine = null;
|
|
1877
|
-
modelEntry;
|
|
1878
|
-
labels = [];
|
|
1879
|
-
minConfidence = 0.3;
|
|
1880
|
-
resolvedConfig = null;
|
|
1881
|
-
ctx = null;
|
|
1882
|
-
getModelRequirements() {
|
|
1883
|
-
return animal_classification_models_js_1.BIRD_SPECIES_MODELS.map((m) => ({
|
|
1884
|
-
modelId: m.id,
|
|
1885
|
-
name: m.name,
|
|
1886
|
-
minRAM_MB: 120,
|
|
1887
|
-
accuracyScore: 80,
|
|
1888
|
-
formats: Object.keys(m.formats)
|
|
1889
|
-
}));
|
|
1890
|
-
}
|
|
1891
|
-
configure(config) {
|
|
1892
|
-
this.resolvedConfig = config;
|
|
1893
|
-
}
|
|
1894
|
-
async initialize(ctx) {
|
|
1895
|
-
this.ctx = ctx;
|
|
1896
|
-
const cfg = ctx.addonConfig;
|
|
1897
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "bird-species-525";
|
|
1898
|
-
this.minConfidence = cfg["minConfidence"] ?? 0.3;
|
|
1899
|
-
const entry = animal_classification_models_js_1.BIRD_SPECIES_MODELS.find((m) => m.id === modelId);
|
|
1900
|
-
if (!entry) {
|
|
1901
|
-
throw new Error(`BirdGlobalClassifierAddon: unknown modelId "${modelId}"`);
|
|
1902
|
-
}
|
|
1903
|
-
this.modelEntry = entry;
|
|
1904
|
-
}
|
|
1905
|
-
async classify(input) {
|
|
1906
|
-
if (!this.engine)
|
|
1907
|
-
await this.ensureEngine();
|
|
1908
|
-
const start = Date.now();
|
|
1909
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
1910
|
-
const animalCrop = await (0, image_utils_js_1.cropRegion)(input.frame.data, input.roi);
|
|
1911
|
-
const normalized = await (0, image_utils_js_1.resizeAndNormalize)(animalCrop, inputW, inputH, "imagenet", "nchw");
|
|
1912
|
-
const rawOutput = await this.engine.run(normalized, [1, 3, inputH, inputW]);
|
|
1913
|
-
const probs = softmax(rawOutput);
|
|
1914
|
-
let maxIdx = 0;
|
|
1915
|
-
let maxScore = probs[0] ?? 0;
|
|
1916
|
-
for (let i = 1; i < probs.length; i++) {
|
|
1917
|
-
const score = probs[i] ?? 0;
|
|
1918
|
-
if (score > maxScore) {
|
|
1919
|
-
maxScore = score;
|
|
1920
|
-
maxIdx = i;
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
if (maxScore < this.minConfidence) {
|
|
1924
|
-
return {
|
|
1925
|
-
classifications: [],
|
|
1926
|
-
inferenceMs: Date.now() - start,
|
|
1927
|
-
modelId: this.modelEntry.id
|
|
1928
|
-
};
|
|
1929
|
-
}
|
|
1930
|
-
const label = this.labels[maxIdx] ?? `species_${maxIdx}`;
|
|
1931
|
-
return {
|
|
1932
|
-
classifications: [
|
|
1933
|
-
{
|
|
1934
|
-
class: label,
|
|
1935
|
-
score: maxScore
|
|
1936
|
-
}
|
|
1937
|
-
],
|
|
1938
|
-
inferenceMs: Date.now() - start,
|
|
1939
|
-
modelId: this.modelEntry.id
|
|
1940
|
-
};
|
|
1941
|
-
}
|
|
1942
|
-
async ensureEngine() {
|
|
1943
|
-
const config = this.resolvedConfig;
|
|
1944
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
1945
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
1946
|
-
const backend = config?.backend ?? "cpu";
|
|
1947
|
-
const format = config?.format ?? "onnx";
|
|
1948
|
-
const entry = animal_classification_models_js_1.BIRD_SPECIES_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
1949
|
-
this.modelEntry = entry;
|
|
1950
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
1951
|
-
if (this.ctx.models) {
|
|
1952
|
-
await this.ctx.models.ensure(modelId, format);
|
|
1953
|
-
}
|
|
1954
|
-
this.labels = loadLabels(modelsDir, modelId);
|
|
1955
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
1956
|
-
runtime,
|
|
1957
|
-
backend,
|
|
1958
|
-
modelEntry: entry,
|
|
1959
|
-
modelsDir,
|
|
1960
|
-
models: this.ctx.models
|
|
1961
|
-
});
|
|
1962
|
-
this.engine = resolved.engine;
|
|
1963
|
-
}
|
|
1964
|
-
async shutdown() {
|
|
1965
|
-
await this.engine?.dispose();
|
|
1966
|
-
}
|
|
1967
|
-
getConfigSchema() {
|
|
1968
|
-
return {
|
|
1969
|
-
sections: [
|
|
1970
|
-
{
|
|
1971
|
-
id: "model",
|
|
1972
|
-
title: "Model",
|
|
1973
|
-
columns: 1,
|
|
1974
|
-
fields: [
|
|
1975
|
-
{
|
|
1976
|
-
key: "modelId",
|
|
1977
|
-
label: "Model",
|
|
1978
|
-
type: "model-selector",
|
|
1979
|
-
catalog: [...animal_classification_models_js_1.BIRD_SPECIES_MODELS],
|
|
1980
|
-
allowCustom: false,
|
|
1981
|
-
allowConversion: false,
|
|
1982
|
-
acceptFormats: ["onnx", "coreml", "openvino"],
|
|
1983
|
-
requiredMetadata: ["inputSize", "labels"],
|
|
1984
|
-
outputFormatHint: "classification"
|
|
1985
|
-
}
|
|
1986
|
-
]
|
|
1987
|
-
},
|
|
1988
|
-
{
|
|
1989
|
-
id: "runtime",
|
|
1990
|
-
title: "Runtime",
|
|
1991
|
-
columns: 2,
|
|
1992
|
-
fields: [
|
|
1993
|
-
{
|
|
1994
|
-
key: "runtime",
|
|
1995
|
-
label: "Runtime",
|
|
1996
|
-
type: "select",
|
|
1997
|
-
options: [
|
|
1998
|
-
{ value: "auto", label: "Auto" },
|
|
1999
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
2000
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
2001
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
2002
|
-
]
|
|
2003
|
-
},
|
|
2004
|
-
{
|
|
2005
|
-
key: "backend",
|
|
2006
|
-
label: "Backend",
|
|
2007
|
-
type: "select",
|
|
2008
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
2009
|
-
options: [
|
|
2010
|
-
{ value: "auto", label: "Auto" },
|
|
2011
|
-
{ value: "cpu", label: "CPU" },
|
|
2012
|
-
{ value: "coreml", label: "CoreML" },
|
|
2013
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
2014
|
-
]
|
|
2015
|
-
}
|
|
2016
|
-
]
|
|
2017
|
-
},
|
|
2018
|
-
{
|
|
2019
|
-
id: "thresholds",
|
|
2020
|
-
title: "Classification Settings",
|
|
2021
|
-
columns: 1,
|
|
2022
|
-
fields: [
|
|
2023
|
-
{
|
|
2024
|
-
key: "minConfidence",
|
|
2025
|
-
label: "Minimum Confidence",
|
|
2026
|
-
type: "slider",
|
|
2027
|
-
min: 0.05,
|
|
2028
|
-
max: 1,
|
|
2029
|
-
step: 0.05,
|
|
2030
|
-
default: 0.3
|
|
2031
|
-
}
|
|
2032
|
-
]
|
|
2033
|
-
}
|
|
2034
|
-
]
|
|
2035
|
-
};
|
|
2036
|
-
}
|
|
2037
|
-
getClassMap() {
|
|
2038
|
-
return BIRD_CLASS_MAP;
|
|
2039
|
-
}
|
|
2040
|
-
getModelCatalog() {
|
|
2041
|
-
return [...animal_classification_models_js_1.BIRD_SPECIES_MODELS];
|
|
2042
|
-
}
|
|
2043
|
-
getAvailableModels() {
|
|
2044
|
-
return [];
|
|
2045
|
-
}
|
|
2046
|
-
getActiveLabels() {
|
|
2047
|
-
return SPECIES_LABELS;
|
|
2048
|
-
}
|
|
2049
|
-
async probe() {
|
|
2050
|
-
return {
|
|
2051
|
-
available: true,
|
|
2052
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
2053
|
-
device: this.engine?.device ?? "cpu",
|
|
2054
|
-
capabilities: ["fp32"]
|
|
2055
|
-
};
|
|
2056
|
-
}
|
|
2057
|
-
};
|
|
2058
|
-
exports.default = BirdGlobalClassifierAddon;
|
|
2059
|
-
}
|
|
2060
|
-
});
|
|
2061
|
-
|
|
2062
|
-
// src/addons/bird-nabirds-classifier/index.js
|
|
2063
|
-
var require_bird_nabirds_classifier = __commonJS({
|
|
2064
|
-
"src/addons/bird-nabirds-classifier/index.js"(exports) {
|
|
2065
|
-
"use strict";
|
|
2066
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
2067
|
-
if (k2 === void 0) k2 = k;
|
|
2068
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
2069
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
2070
|
-
desc = { enumerable: true, get: function() {
|
|
2071
|
-
return m[k];
|
|
2072
|
-
} };
|
|
2073
|
-
}
|
|
2074
|
-
Object.defineProperty(o, k2, desc);
|
|
2075
|
-
}) : (function(o, m, k, k2) {
|
|
2076
|
-
if (k2 === void 0) k2 = k;
|
|
2077
|
-
o[k2] = m[k];
|
|
2078
|
-
}));
|
|
2079
|
-
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
2080
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
2081
|
-
}) : function(o, v) {
|
|
2082
|
-
o["default"] = v;
|
|
2083
|
-
});
|
|
2084
|
-
var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
|
|
2085
|
-
var ownKeys = function(o) {
|
|
2086
|
-
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
2087
|
-
var ar = [];
|
|
2088
|
-
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
2089
|
-
return ar;
|
|
2090
|
-
};
|
|
2091
|
-
return ownKeys(o);
|
|
2092
|
-
};
|
|
2093
|
-
return function(mod) {
|
|
2094
|
-
if (mod && mod.__esModule) return mod;
|
|
2095
|
-
var result = {};
|
|
2096
|
-
if (mod != null) {
|
|
2097
|
-
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
2098
|
-
}
|
|
2099
|
-
__setModuleDefault(result, mod);
|
|
2100
|
-
return result;
|
|
2101
|
-
};
|
|
2102
|
-
})();
|
|
2103
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2104
|
-
var animal_classification_models_js_1 = require_animal_classification_models();
|
|
2105
|
-
var image_utils_js_1 = require_image_utils();
|
|
2106
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
2107
|
-
var fs = __importStar(__require("fs"));
|
|
2108
|
-
var path = __importStar(__require("path"));
|
|
2109
|
-
var SPECIES_LABEL = { id: "species", name: "Bird Species" };
|
|
2110
|
-
var SPECIES_LABELS = [SPECIES_LABEL];
|
|
2111
|
-
var BIRD_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
2112
|
-
function loadLabels(modelsDir, modelId) {
|
|
2113
|
-
const labelNames = [
|
|
2114
|
-
`camstack-${modelId}-labels.json`,
|
|
2115
|
-
`camstack-bird-nabirds-404-labels.json`
|
|
2116
|
-
];
|
|
2117
|
-
for (const name of labelNames) {
|
|
2118
|
-
const labelPath = path.join(modelsDir, name);
|
|
2119
|
-
if (fs.existsSync(labelPath)) {
|
|
2120
|
-
const raw = fs.readFileSync(labelPath, "utf-8");
|
|
2121
|
-
return JSON.parse(raw);
|
|
2122
|
-
}
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: "doctr-rec-parseq",
|
|
145
|
+
name: "docTR Recognition PARSeq",
|
|
146
|
+
description: "docTR PARSeq \u2014 high-accuracy scene text recognition (top ICDAR scores)",
|
|
147
|
+
inputSize: { width: 128, height: 32 },
|
|
148
|
+
labels: OCR_TEXT_LABELS,
|
|
149
|
+
formats: {
|
|
150
|
+
onnx: {
|
|
151
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/onnx/camstack-doctr-rec-parseq.onnx"),
|
|
152
|
+
sizeMB: 25
|
|
153
|
+
},
|
|
154
|
+
coreml: {
|
|
155
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/coreml/camstack-doctr-rec-parseq.mlpackage"),
|
|
156
|
+
sizeMB: 13,
|
|
157
|
+
isDirectory: true,
|
|
158
|
+
files: [
|
|
159
|
+
"Manifest.json",
|
|
160
|
+
"Data/com.apple.CoreML/model.mlmodel",
|
|
161
|
+
"Data/com.apple.CoreML/weights/weight.bin"
|
|
162
|
+
],
|
|
163
|
+
runtimes: ["python"]
|
|
164
|
+
},
|
|
165
|
+
openvino: {
|
|
166
|
+
url: hfModelUrl(HF_REPO, "generalOcr/doctr/openvino/camstack-doctr-rec-parseq.xml"),
|
|
167
|
+
sizeMB: 13,
|
|
168
|
+
runtimes: ["python"]
|
|
2123
169
|
}
|
|
2124
|
-
throw new Error(`BirdNABirdsClassifierAddon: labels JSON not found in ${modelsDir}`);
|
|
2125
|
-
}
|
|
2126
|
-
function softmax(logits) {
|
|
2127
|
-
const max = logits.reduce((a, b) => Math.max(a, b), -Infinity);
|
|
2128
|
-
const exps = logits.map((v) => Math.exp(v - max));
|
|
2129
|
-
const sum = exps.reduce((a, b) => a + b, 0);
|
|
2130
|
-
return exps.map((v) => v / sum);
|
|
2131
170
|
}
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
minConfidence = 0.3;
|
|
2161
|
-
allowedSpecies;
|
|
2162
|
-
resolvedConfig = null;
|
|
2163
|
-
ctx = null;
|
|
2164
|
-
getModelRequirements() {
|
|
2165
|
-
return animal_classification_models_js_1.BIRD_NABIRDS_MODELS.map((m) => ({
|
|
2166
|
-
modelId: m.id,
|
|
2167
|
-
name: m.name,
|
|
2168
|
-
minRAM_MB: 300,
|
|
2169
|
-
accuracyScore: 80,
|
|
2170
|
-
formats: Object.keys(m.formats)
|
|
2171
|
-
}));
|
|
2172
|
-
}
|
|
2173
|
-
configure(config) {
|
|
2174
|
-
this.resolvedConfig = config;
|
|
2175
|
-
}
|
|
2176
|
-
async initialize(ctx) {
|
|
2177
|
-
this.ctx = ctx;
|
|
2178
|
-
const cfg = ctx.addonConfig;
|
|
2179
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "bird-nabirds-404";
|
|
2180
|
-
this.minConfidence = cfg["minConfidence"] ?? 0.3;
|
|
2181
|
-
this.allowedSpecies = cfg["allowedSpecies"];
|
|
2182
|
-
const entry = animal_classification_models_js_1.BIRD_NABIRDS_MODELS.find((m) => m.id === modelId);
|
|
2183
|
-
if (!entry) {
|
|
2184
|
-
throw new Error(`BirdNABirdsClassifierAddon: unknown modelId "${modelId}"`);
|
|
2185
|
-
}
|
|
2186
|
-
this.modelEntry = entry;
|
|
2187
|
-
}
|
|
2188
|
-
applyRegionFilter(scores, labels) {
|
|
2189
|
-
if (!this.allowedSpecies || this.allowedSpecies.length === 0)
|
|
2190
|
-
return;
|
|
2191
|
-
const allowedSet = new Set(this.allowedSpecies.map((s) => s.toLowerCase()));
|
|
2192
|
-
for (let i = 0; i < scores.length; i++) {
|
|
2193
|
-
if (!allowedSet.has(labels[i].toLowerCase())) {
|
|
2194
|
-
scores[i] = 0;
|
|
2195
|
-
}
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
async classify(input) {
|
|
2199
|
-
if (!this.engine)
|
|
2200
|
-
await this.ensureEngine();
|
|
2201
|
-
const start = Date.now();
|
|
2202
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
2203
|
-
const animalCrop = await (0, image_utils_js_1.cropRegion)(input.frame.data, input.roi);
|
|
2204
|
-
const normalized = await (0, image_utils_js_1.resizeAndNormalize)(animalCrop, inputW, inputH, "imagenet", "nchw");
|
|
2205
|
-
const rawOutput = await this.engine.run(normalized, [1, 3, inputH, inputW]);
|
|
2206
|
-
const probs = softmax(rawOutput);
|
|
2207
|
-
this.applyRegionFilter(probs, this.labels);
|
|
2208
|
-
const filteredSum = probs.reduce((a, b) => a + b, 0);
|
|
2209
|
-
if (filteredSum > 0) {
|
|
2210
|
-
for (let i = 0; i < probs.length; i++) {
|
|
2211
|
-
probs[i] = (probs[i] ?? 0) / filteredSum;
|
|
2212
|
-
}
|
|
2213
|
-
}
|
|
2214
|
-
let maxIdx = 0;
|
|
2215
|
-
let maxScore = probs[0] ?? 0;
|
|
2216
|
-
for (let i = 1; i < probs.length; i++) {
|
|
2217
|
-
const score = probs[i] ?? 0;
|
|
2218
|
-
if (score > maxScore) {
|
|
2219
|
-
maxScore = score;
|
|
2220
|
-
maxIdx = i;
|
|
2221
|
-
}
|
|
2222
|
-
}
|
|
2223
|
-
if (maxScore < this.minConfidence) {
|
|
2224
|
-
return {
|
|
2225
|
-
classifications: [],
|
|
2226
|
-
inferenceMs: Date.now() - start,
|
|
2227
|
-
modelId: this.modelEntry.id
|
|
2228
|
-
};
|
|
2229
|
-
}
|
|
2230
|
-
const label = this.labels[maxIdx] ?? `species_${maxIdx}`;
|
|
2231
|
-
return {
|
|
2232
|
-
classifications: [
|
|
2233
|
-
{
|
|
2234
|
-
class: label,
|
|
2235
|
-
score: maxScore
|
|
2236
|
-
}
|
|
2237
|
-
],
|
|
2238
|
-
inferenceMs: Date.now() - start,
|
|
2239
|
-
modelId: this.modelEntry.id
|
|
2240
|
-
};
|
|
2241
|
-
}
|
|
2242
|
-
async ensureEngine() {
|
|
2243
|
-
const config = this.resolvedConfig;
|
|
2244
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
2245
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
2246
|
-
const backend = config?.backend ?? "cpu";
|
|
2247
|
-
const format = config?.format ?? "onnx";
|
|
2248
|
-
const entry = animal_classification_models_js_1.BIRD_NABIRDS_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
2249
|
-
this.modelEntry = entry;
|
|
2250
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
2251
|
-
if (this.ctx.models) {
|
|
2252
|
-
await this.ctx.models.ensure(modelId, format);
|
|
2253
|
-
}
|
|
2254
|
-
this.labels = loadLabels(modelsDir, modelId);
|
|
2255
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
2256
|
-
runtime,
|
|
2257
|
-
backend,
|
|
2258
|
-
modelEntry: entry,
|
|
2259
|
-
modelsDir,
|
|
2260
|
-
models: this.ctx.models
|
|
2261
|
-
});
|
|
2262
|
-
this.engine = resolved.engine;
|
|
2263
|
-
}
|
|
2264
|
-
async shutdown() {
|
|
2265
|
-
await this.engine?.dispose();
|
|
2266
|
-
}
|
|
2267
|
-
getConfigSchema() {
|
|
2268
|
-
return {
|
|
2269
|
-
sections: [
|
|
2270
|
-
{
|
|
2271
|
-
id: "model",
|
|
2272
|
-
title: "Model",
|
|
2273
|
-
columns: 1,
|
|
2274
|
-
fields: [
|
|
2275
|
-
{
|
|
2276
|
-
key: "modelId",
|
|
2277
|
-
label: "Model",
|
|
2278
|
-
type: "model-selector",
|
|
2279
|
-
catalog: [...animal_classification_models_js_1.BIRD_NABIRDS_MODELS],
|
|
2280
|
-
allowCustom: false,
|
|
2281
|
-
allowConversion: false,
|
|
2282
|
-
acceptFormats: ["onnx", "coreml", "openvino"],
|
|
2283
|
-
requiredMetadata: ["inputSize", "labels"],
|
|
2284
|
-
outputFormatHint: "classification"
|
|
2285
|
-
}
|
|
2286
|
-
]
|
|
2287
|
-
},
|
|
2288
|
-
{
|
|
2289
|
-
id: "runtime",
|
|
2290
|
-
title: "Runtime",
|
|
2291
|
-
columns: 2,
|
|
2292
|
-
fields: [
|
|
2293
|
-
{
|
|
2294
|
-
key: "runtime",
|
|
2295
|
-
label: "Runtime",
|
|
2296
|
-
type: "select",
|
|
2297
|
-
options: [
|
|
2298
|
-
{ value: "auto", label: "Auto" },
|
|
2299
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
2300
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
2301
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
2302
|
-
]
|
|
2303
|
-
},
|
|
2304
|
-
{
|
|
2305
|
-
key: "backend",
|
|
2306
|
-
label: "Backend",
|
|
2307
|
-
type: "select",
|
|
2308
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
2309
|
-
options: [
|
|
2310
|
-
{ value: "auto", label: "Auto" },
|
|
2311
|
-
{ value: "cpu", label: "CPU" },
|
|
2312
|
-
{ value: "coreml", label: "CoreML" },
|
|
2313
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
2314
|
-
]
|
|
2315
|
-
}
|
|
2316
|
-
]
|
|
2317
|
-
},
|
|
2318
|
-
{
|
|
2319
|
-
id: "thresholds",
|
|
2320
|
-
title: "Classification Settings",
|
|
2321
|
-
columns: 1,
|
|
2322
|
-
fields: [
|
|
2323
|
-
{
|
|
2324
|
-
key: "minConfidence",
|
|
2325
|
-
label: "Minimum Confidence",
|
|
2326
|
-
type: "slider",
|
|
2327
|
-
min: 0.05,
|
|
2328
|
-
max: 1,
|
|
2329
|
-
step: 0.05,
|
|
2330
|
-
default: 0.3
|
|
2331
|
-
}
|
|
2332
|
-
]
|
|
2333
|
-
},
|
|
2334
|
-
{
|
|
2335
|
-
id: "region",
|
|
2336
|
-
title: "Regional Filter",
|
|
2337
|
-
columns: 1,
|
|
2338
|
-
fields: [
|
|
2339
|
-
{
|
|
2340
|
-
key: "regionFilter",
|
|
2341
|
-
label: "Region Preset",
|
|
2342
|
-
type: "select",
|
|
2343
|
-
options: [
|
|
2344
|
-
{ value: "", label: "None (all 404 species)" },
|
|
2345
|
-
{ value: "north-america-east", label: "North America \u2014 Eastern" },
|
|
2346
|
-
{ value: "north-america-west", label: "North America \u2014 Western" },
|
|
2347
|
-
{ value: "north-america-south", label: "North America \u2014 Southern" }
|
|
2348
|
-
]
|
|
2349
|
-
},
|
|
2350
|
-
{
|
|
2351
|
-
key: "allowedSpecies",
|
|
2352
|
-
label: "Custom Allowed Species (comma-separated)",
|
|
2353
|
-
type: "text"
|
|
2354
|
-
}
|
|
2355
|
-
]
|
|
2356
|
-
}
|
|
2357
|
-
]
|
|
2358
|
-
};
|
|
2359
|
-
}
|
|
2360
|
-
getClassMap() {
|
|
2361
|
-
return BIRD_CLASS_MAP;
|
|
2362
|
-
}
|
|
2363
|
-
getModelCatalog() {
|
|
2364
|
-
return [...animal_classification_models_js_1.BIRD_NABIRDS_MODELS];
|
|
2365
|
-
}
|
|
2366
|
-
getAvailableModels() {
|
|
2367
|
-
return [];
|
|
2368
|
-
}
|
|
2369
|
-
getActiveLabels() {
|
|
2370
|
-
return SPECIES_LABELS;
|
|
2371
|
-
}
|
|
2372
|
-
async probe() {
|
|
2373
|
-
return {
|
|
2374
|
-
available: true,
|
|
2375
|
-
runtime: this.engine?.runtime ?? "onnx",
|
|
2376
|
-
device: this.engine?.device ?? "cpu",
|
|
2377
|
-
capabilities: ["fp32"]
|
|
2378
|
-
};
|
|
171
|
+
},
|
|
172
|
+
// ── PaddleOCR PP-OCRv5 Mobile — general-purpose text detection + recognition ──
|
|
173
|
+
{
|
|
174
|
+
id: "ppocr-v5-det-mobile",
|
|
175
|
+
name: "PP-OCRv5 Detection Mobile",
|
|
176
|
+
description: "PP-OCRv5 mobile text detection \u2014 optimized for edge, 100+ languages",
|
|
177
|
+
inputSize: { width: 640, height: 640 },
|
|
178
|
+
labels: OCR_TEXT_LABELS,
|
|
179
|
+
formats: {
|
|
180
|
+
onnx: {
|
|
181
|
+
url: hfModelUrl(HF_REPO, "generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-det-mobile.onnx"),
|
|
182
|
+
sizeMB: 6
|
|
183
|
+
},
|
|
184
|
+
coreml: {
|
|
185
|
+
url: hfModelUrl(HF_REPO, "generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-det-mobile.mlpackage"),
|
|
186
|
+
sizeMB: 3,
|
|
187
|
+
isDirectory: true,
|
|
188
|
+
files: [
|
|
189
|
+
"Manifest.json",
|
|
190
|
+
"Data/com.apple.CoreML/model.mlmodel",
|
|
191
|
+
"Data/com.apple.CoreML/weights/weight.bin"
|
|
192
|
+
],
|
|
193
|
+
runtimes: ["python"]
|
|
194
|
+
},
|
|
195
|
+
openvino: {
|
|
196
|
+
url: hfModelUrl(HF_REPO, "generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-det-mobile.xml"),
|
|
197
|
+
sizeMB: 3,
|
|
198
|
+
runtimes: ["python"]
|
|
2379
199
|
}
|
|
2380
|
-
};
|
|
2381
|
-
exports.default = BirdNABirdsClassifierAddon;
|
|
2382
|
-
}
|
|
2383
|
-
});
|
|
2384
|
-
|
|
2385
|
-
// src/addons/animal-classifier/index.js
|
|
2386
|
-
var require_animal_classifier = __commonJS({
|
|
2387
|
-
"src/addons/animal-classifier/index.js"(exports) {
|
|
2388
|
-
"use strict";
|
|
2389
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2390
|
-
var animal_classification_models_js_1 = require_animal_classification_models();
|
|
2391
|
-
var image_utils_js_1 = require_image_utils();
|
|
2392
|
-
var engine_resolver_js_1 = require_engine_resolver();
|
|
2393
|
-
var ANIMAL_TYPE_LABEL = { id: "animal-type", name: "Animal Type" };
|
|
2394
|
-
var ANIMAL_TYPE_LABELS = [ANIMAL_TYPE_LABEL];
|
|
2395
|
-
var ANIMAL_CLASS_MAP = { mapping: {}, preserveOriginal: true };
|
|
2396
|
-
var ANIMAL_10_CLASSES = [
|
|
2397
|
-
"cat",
|
|
2398
|
-
"cow",
|
|
2399
|
-
"dog",
|
|
2400
|
-
"dolphin",
|
|
2401
|
-
"eagle",
|
|
2402
|
-
"giant panda",
|
|
2403
|
-
"horse",
|
|
2404
|
-
"monkey",
|
|
2405
|
-
"sheep",
|
|
2406
|
-
"spider"
|
|
2407
|
-
];
|
|
2408
|
-
function softmax(logits) {
|
|
2409
|
-
const max = logits.reduce((a, b) => Math.max(a, b), -Infinity);
|
|
2410
|
-
const exps = logits.map((v) => Math.exp(v - max));
|
|
2411
|
-
const sum = exps.reduce((a, b) => a + b, 0);
|
|
2412
|
-
return exps.map((v) => v / sum);
|
|
2413
200
|
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
minConfidence = 0.3;
|
|
2442
|
-
resolvedConfig = null;
|
|
2443
|
-
ctx = null;
|
|
2444
|
-
getModelRequirements() {
|
|
2445
|
-
return animal_classification_models_js_1.ANIMAL_TYPE_MODELS.map((m) => ({
|
|
2446
|
-
modelId: m.id,
|
|
2447
|
-
name: m.name,
|
|
2448
|
-
minRAM_MB: 800,
|
|
2449
|
-
accuracyScore: 75,
|
|
2450
|
-
formats: Object.keys(m.formats)
|
|
2451
|
-
}));
|
|
2452
|
-
}
|
|
2453
|
-
configure(config) {
|
|
2454
|
-
this.resolvedConfig = config;
|
|
2455
|
-
}
|
|
2456
|
-
async initialize(ctx) {
|
|
2457
|
-
this.ctx = ctx;
|
|
2458
|
-
const cfg = ctx.addonConfig;
|
|
2459
|
-
const modelId = cfg["modelId"] ?? this.resolvedConfig?.modelId ?? "animals-10";
|
|
2460
|
-
this.minConfidence = cfg["minConfidence"] ?? 0.3;
|
|
2461
|
-
const entry = animal_classification_models_js_1.ANIMAL_TYPE_MODELS.find((m) => m.id === modelId);
|
|
2462
|
-
if (!entry) {
|
|
2463
|
-
throw new Error(`AnimalClassifierAddon: unknown modelId "${modelId}"`);
|
|
2464
|
-
}
|
|
2465
|
-
this.modelEntry = entry;
|
|
2466
|
-
}
|
|
2467
|
-
async classify(input) {
|
|
2468
|
-
if (!this.engine)
|
|
2469
|
-
await this.ensureEngine();
|
|
2470
|
-
const start = Date.now();
|
|
2471
|
-
const { width: inputW, height: inputH } = this.modelEntry.inputSize;
|
|
2472
|
-
const animalCrop = await (0, image_utils_js_1.cropRegion)(input.frame.data, input.roi);
|
|
2473
|
-
const normalized = await (0, image_utils_js_1.resizeAndNormalize)(animalCrop, inputW, inputH, "imagenet", "nchw");
|
|
2474
|
-
const rawOutput = await this.engine.run(normalized, [1, 3, inputH, inputW]);
|
|
2475
|
-
const probs = softmax(rawOutput);
|
|
2476
|
-
let maxIdx = 0;
|
|
2477
|
-
let maxScore = probs[0] ?? 0;
|
|
2478
|
-
for (let i = 1; i < probs.length; i++) {
|
|
2479
|
-
const score = probs[i] ?? 0;
|
|
2480
|
-
if (score > maxScore) {
|
|
2481
|
-
maxScore = score;
|
|
2482
|
-
maxIdx = i;
|
|
2483
|
-
}
|
|
2484
|
-
}
|
|
2485
|
-
if (maxScore < this.minConfidence) {
|
|
2486
|
-
return {
|
|
2487
|
-
classifications: [],
|
|
2488
|
-
inferenceMs: Date.now() - start,
|
|
2489
|
-
modelId: this.modelEntry.id
|
|
2490
|
-
};
|
|
2491
|
-
}
|
|
2492
|
-
const label = ANIMAL_10_CLASSES[maxIdx] ?? `animal_${maxIdx}`;
|
|
2493
|
-
return {
|
|
2494
|
-
classifications: [
|
|
2495
|
-
{
|
|
2496
|
-
class: label,
|
|
2497
|
-
score: maxScore
|
|
2498
|
-
}
|
|
2499
|
-
],
|
|
2500
|
-
inferenceMs: Date.now() - start,
|
|
2501
|
-
modelId: this.modelEntry.id
|
|
2502
|
-
};
|
|
2503
|
-
}
|
|
2504
|
-
async ensureEngine() {
|
|
2505
|
-
const config = this.resolvedConfig;
|
|
2506
|
-
const modelId = config?.modelId ?? this.modelEntry.id;
|
|
2507
|
-
const runtime = config?.runtime === "python" ? "coreml" : config?.runtime === "node" ? "onnx" : "auto";
|
|
2508
|
-
const backend = config?.backend ?? "cpu";
|
|
2509
|
-
const format = config?.format ?? "onnx";
|
|
2510
|
-
const entry = animal_classification_models_js_1.ANIMAL_TYPE_MODELS.find((m) => m.id === modelId) ?? this.modelEntry;
|
|
2511
|
-
this.modelEntry = entry;
|
|
2512
|
-
const modelsDir = this.ctx.models?.getModelsDir() ?? this.ctx.locationPaths.models;
|
|
2513
|
-
if (this.ctx.models) {
|
|
2514
|
-
await this.ctx.models.ensure(modelId, format);
|
|
2515
|
-
}
|
|
2516
|
-
const resolved = await (0, engine_resolver_js_1.resolveEngine)({
|
|
2517
|
-
runtime,
|
|
2518
|
-
backend,
|
|
2519
|
-
modelEntry: entry,
|
|
2520
|
-
modelsDir,
|
|
2521
|
-
models: this.ctx.models
|
|
2522
|
-
});
|
|
2523
|
-
this.engine = resolved.engine;
|
|
2524
|
-
}
|
|
2525
|
-
async shutdown() {
|
|
2526
|
-
await this.engine?.dispose();
|
|
2527
|
-
}
|
|
2528
|
-
getConfigSchema() {
|
|
2529
|
-
return {
|
|
2530
|
-
sections: [
|
|
2531
|
-
{
|
|
2532
|
-
id: "model",
|
|
2533
|
-
title: "Model",
|
|
2534
|
-
columns: 1,
|
|
2535
|
-
fields: [
|
|
2536
|
-
{
|
|
2537
|
-
key: "modelId",
|
|
2538
|
-
label: "Model",
|
|
2539
|
-
type: "model-selector",
|
|
2540
|
-
catalog: [...animal_classification_models_js_1.ANIMAL_TYPE_MODELS],
|
|
2541
|
-
allowCustom: false,
|
|
2542
|
-
allowConversion: false,
|
|
2543
|
-
acceptFormats: ["onnx", "coreml", "openvino"],
|
|
2544
|
-
requiredMetadata: ["inputSize", "labels"],
|
|
2545
|
-
outputFormatHint: "classification"
|
|
2546
|
-
}
|
|
2547
|
-
]
|
|
2548
|
-
},
|
|
2549
|
-
{
|
|
2550
|
-
id: "runtime",
|
|
2551
|
-
title: "Runtime",
|
|
2552
|
-
columns: 2,
|
|
2553
|
-
fields: [
|
|
2554
|
-
{
|
|
2555
|
-
key: "runtime",
|
|
2556
|
-
label: "Runtime",
|
|
2557
|
-
type: "select",
|
|
2558
|
-
options: [
|
|
2559
|
-
{ value: "auto", label: "Auto" },
|
|
2560
|
-
{ value: "onnx", label: "ONNX Runtime" },
|
|
2561
|
-
{ value: "coreml", label: "CoreML (Apple)" },
|
|
2562
|
-
{ value: "openvino", label: "OpenVINO (Intel)" }
|
|
2563
|
-
]
|
|
2564
|
-
},
|
|
2565
|
-
{
|
|
2566
|
-
key: "backend",
|
|
2567
|
-
label: "Backend",
|
|
2568
|
-
type: "select",
|
|
2569
|
-
showWhen: { field: "runtime", equals: "onnx" },
|
|
2570
|
-
options: [
|
|
2571
|
-
{ value: "auto", label: "Auto" },
|
|
2572
|
-
{ value: "cpu", label: "CPU" },
|
|
2573
|
-
{ value: "coreml", label: "CoreML" },
|
|
2574
|
-
{ value: "cuda", label: "CUDA (NVIDIA)" }
|
|
2575
|
-
]
|
|
2576
|
-
}
|
|
2577
|
-
]
|
|
2578
|
-
},
|
|
2579
|
-
{
|
|
2580
|
-
id: "thresholds",
|
|
2581
|
-
title: "Classification Settings",
|
|
2582
|
-
columns: 1,
|
|
2583
|
-
fields: [
|
|
2584
|
-
{
|
|
2585
|
-
key: "minConfidence",
|
|
2586
|
-
label: "Minimum Confidence",
|
|
2587
|
-
type: "slider",
|
|
2588
|
-
min: 0.05,
|
|
2589
|
-
max: 1,
|
|
2590
|
-
step: 0.05,
|
|
2591
|
-
default: 0.3
|
|
2592
|
-
}
|
|
2593
|
-
]
|
|
2594
|
-
}
|
|
2595
|
-
]
|
|
2596
|
-
};
|
|
2597
|
-
}
|
|
2598
|
-
getClassMap() {
|
|
2599
|
-
return ANIMAL_CLASS_MAP;
|
|
2600
|
-
}
|
|
2601
|
-
getModelCatalog() {
|
|
2602
|
-
return [...animal_classification_models_js_1.ANIMAL_TYPE_MODELS];
|
|
2603
|
-
}
|
|
2604
|
-
getAvailableModels() {
|
|
2605
|
-
return [];
|
|
2606
|
-
}
|
|
2607
|
-
getActiveLabels() {
|
|
2608
|
-
return ANIMAL_TYPE_LABELS;
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: "ppocr-v5-rec-mobile",
|
|
204
|
+
name: "PP-OCRv5 Recognition Mobile",
|
|
205
|
+
description: "PP-OCRv5 mobile text recognition \u2014 100+ languages, CTC decoding",
|
|
206
|
+
inputSize: { width: 320, height: 48 },
|
|
207
|
+
labels: OCR_TEXT_LABELS,
|
|
208
|
+
formats: {
|
|
209
|
+
onnx: {
|
|
210
|
+
url: hfModelUrl(HF_REPO, "generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-rec-mobile.onnx"),
|
|
211
|
+
sizeMB: 8
|
|
212
|
+
},
|
|
213
|
+
coreml: {
|
|
214
|
+
url: hfModelUrl(HF_REPO, "generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-rec-mobile.mlpackage"),
|
|
215
|
+
sizeMB: 4,
|
|
216
|
+
isDirectory: true,
|
|
217
|
+
files: [
|
|
218
|
+
"Manifest.json",
|
|
219
|
+
"Data/com.apple.CoreML/model.mlmodel",
|
|
220
|
+
"Data/com.apple.CoreML/weights/weight.bin"
|
|
221
|
+
],
|
|
222
|
+
runtimes: ["python"]
|
|
223
|
+
},
|
|
224
|
+
openvino: {
|
|
225
|
+
url: hfModelUrl(HF_REPO, "generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-rec-mobile.xml"),
|
|
226
|
+
sizeMB: 4,
|
|
227
|
+
runtimes: ["python"]
|
|
2609
228
|
}
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
};
|
|
229
|
+
},
|
|
230
|
+
extraFiles: [
|
|
231
|
+
{
|
|
232
|
+
url: hfModelUrl(HF_REPO, "generalOcr/ppocr-v5/camstack-ppocr-v5-keys.txt"),
|
|
233
|
+
filename: "camstack-ppocr-v5-keys.txt",
|
|
234
|
+
sizeMB: 0.1
|
|
2617
235
|
}
|
|
2618
|
-
|
|
2619
|
-
exports.default = AnimalClassifierAddon;
|
|
236
|
+
]
|
|
2620
237
|
}
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
// src/index.ts
|
|
2624
|
-
var src_exports = {};
|
|
2625
|
-
__export(src_exports, {
|
|
2626
|
-
AnimalClassifierAddon: () => import_animal_classifier.default,
|
|
2627
|
-
AudioClassificationAddon: () => import_audio_classification.default,
|
|
2628
|
-
BirdGlobalClassifierAddon: () => import_bird_global_classifier.default,
|
|
2629
|
-
BirdNABirdsClassifierAddon: () => import_bird_nabirds_classifier.default,
|
|
2630
|
-
FaceDetectionAddon: () => import_face_detection.default,
|
|
2631
|
-
FaceRecognitionAddon: () => import_face_recognition.default,
|
|
2632
|
-
NodeInferenceEngine: () => import_node_engine.NodeInferenceEngine,
|
|
2633
|
-
ObjectDetectionAddon: () => import_object_detection.default,
|
|
2634
|
-
PlateDetectionAddon: () => import_plate_detection.default,
|
|
2635
|
-
PlateRecognitionAddon: () => import_plate_recognition.default,
|
|
2636
|
-
PythonInferenceEngine: () => import_python_engine.PythonInferenceEngine,
|
|
2637
|
-
cosineSimilarity: () => import_arcface.cosineSimilarity,
|
|
2638
|
-
cropRegion: () => import_image_utils.cropRegion,
|
|
2639
|
-
ctcDecode: () => import_paddleocr.ctcDecode,
|
|
2640
|
-
detectMotion: () => import_frame_diff.detectMotion,
|
|
2641
|
-
iou: () => import_yolo.iou,
|
|
2642
|
-
jpegToRgb: () => import_image_utils.jpegToRgb,
|
|
2643
|
-
l2Normalize: () => import_arcface.l2Normalize,
|
|
2644
|
-
letterbox: () => import_image_utils.letterbox,
|
|
2645
|
-
nms: () => import_yolo.nms,
|
|
2646
|
-
probeOnnxBackends: () => import_engine_resolver.probeOnnxBackends,
|
|
2647
|
-
resizeAndNormalize: () => import_image_utils.resizeAndNormalize,
|
|
2648
|
-
resolveEngine: () => import_engine_resolver.resolveEngine,
|
|
2649
|
-
rgbToGrayscale: () => import_image_utils.rgbToGrayscale,
|
|
2650
|
-
scrfdPostprocess: () => import_scrfd.scrfdPostprocess,
|
|
2651
|
-
yamnetPostprocess: () => import_yamnet.yamnetPostprocess,
|
|
2652
|
-
yoloPostprocess: () => import_yolo.yoloPostprocess
|
|
2653
|
-
});
|
|
2654
|
-
var import_image_utils = __toESM(require_image_utils());
|
|
2655
|
-
var import_yolo = __toESM(require_yolo());
|
|
2656
|
-
var import_scrfd = __toESM(require_scrfd());
|
|
2657
|
-
var import_arcface = __toESM(require_arcface());
|
|
2658
|
-
var import_paddleocr = __toESM(require_paddleocr());
|
|
2659
|
-
var import_yamnet = __toESM(require_yamnet());
|
|
2660
|
-
var import_node_engine = __toESM(require_node_engine());
|
|
2661
|
-
var import_python_engine = __toESM(require_python_engine());
|
|
2662
|
-
var import_engine_resolver = __toESM(require_engine_resolver());
|
|
2663
|
-
var import_frame_diff = __toESM(require_frame_diff());
|
|
2664
|
-
__reExport(src_exports, __toESM(require_catalogs()));
|
|
2665
|
-
var import_object_detection = __toESM(require_object_detection());
|
|
2666
|
-
var import_face_detection = __toESM(require_face_detection());
|
|
2667
|
-
var import_face_recognition = __toESM(require_face_recognition());
|
|
2668
|
-
var import_plate_detection = __toESM(require_plate_detection());
|
|
2669
|
-
var import_plate_recognition = __toESM(require_plate_recognition());
|
|
2670
|
-
var import_audio_classification = __toESM(require_audio_classification());
|
|
2671
|
-
var import_bird_global_classifier = __toESM(require_bird_global_classifier());
|
|
2672
|
-
var import_bird_nabirds_classifier = __toESM(require_bird_nabirds_classifier());
|
|
2673
|
-
var import_animal_classifier = __toESM(require_animal_classifier());
|
|
2674
|
-
var export_AnimalClassifierAddon = import_animal_classifier.default;
|
|
2675
|
-
var export_AudioClassificationAddon = import_audio_classification.default;
|
|
2676
|
-
var export_BirdGlobalClassifierAddon = import_bird_global_classifier.default;
|
|
2677
|
-
var export_BirdNABirdsClassifierAddon = import_bird_nabirds_classifier.default;
|
|
2678
|
-
var export_FaceDetectionAddon = import_face_detection.default;
|
|
2679
|
-
var export_FaceRecognitionAddon = import_face_recognition.default;
|
|
2680
|
-
var export_NodeInferenceEngine = import_node_engine.NodeInferenceEngine;
|
|
2681
|
-
var export_ObjectDetectionAddon = import_object_detection.default;
|
|
2682
|
-
var export_PlateDetectionAddon = import_plate_detection.default;
|
|
2683
|
-
var export_PlateRecognitionAddon = import_plate_recognition.default;
|
|
2684
|
-
var export_PythonInferenceEngine = import_python_engine.PythonInferenceEngine;
|
|
2685
|
-
var export_cosineSimilarity = import_arcface.cosineSimilarity;
|
|
2686
|
-
var export_cropRegion = import_image_utils.cropRegion;
|
|
2687
|
-
var export_ctcDecode = import_paddleocr.ctcDecode;
|
|
2688
|
-
var export_detectMotion = import_frame_diff.detectMotion;
|
|
2689
|
-
var export_iou = import_yolo.iou;
|
|
2690
|
-
var export_jpegToRgb = import_image_utils.jpegToRgb;
|
|
2691
|
-
var export_l2Normalize = import_arcface.l2Normalize;
|
|
2692
|
-
var export_letterbox = import_image_utils.letterbox;
|
|
2693
|
-
var export_nms = import_yolo.nms;
|
|
2694
|
-
var export_probeOnnxBackends = import_engine_resolver.probeOnnxBackends;
|
|
2695
|
-
var export_resizeAndNormalize = import_image_utils.resizeAndNormalize;
|
|
2696
|
-
var export_resolveEngine = import_engine_resolver.resolveEngine;
|
|
2697
|
-
var export_rgbToGrayscale = import_image_utils.rgbToGrayscale;
|
|
2698
|
-
var export_scrfdPostprocess = import_scrfd.scrfdPostprocess;
|
|
2699
|
-
var export_yamnetPostprocess = import_yamnet.yamnetPostprocess;
|
|
2700
|
-
var export_yoloPostprocess = import_yolo.yoloPostprocess;
|
|
238
|
+
];
|
|
2701
239
|
export {
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
240
|
+
ANIMAL_TYPE_MODELS,
|
|
241
|
+
AUDIO_CLASSIFICATION_MODELS,
|
|
242
|
+
AnimalClassifierAddon,
|
|
243
|
+
AudioClassificationAddon,
|
|
244
|
+
BIRD_NABIRDS_MODELS,
|
|
245
|
+
BIRD_SPECIES_MODELS,
|
|
246
|
+
BirdGlobalClassifierAddon,
|
|
247
|
+
BirdNABirdsClassifierAddon,
|
|
248
|
+
FACE_DETECTION_MODELS,
|
|
249
|
+
FACE_RECOGNITION_MODELS,
|
|
250
|
+
FaceDetectionAddon,
|
|
251
|
+
FaceRecognitionAddon,
|
|
252
|
+
GENERAL_OCR_MODELS,
|
|
253
|
+
MLPACKAGE_FILES,
|
|
254
|
+
NodeInferenceEngine,
|
|
255
|
+
OBJECT_DETECTION_MODELS,
|
|
256
|
+
ObjectDetectionAddon,
|
|
257
|
+
PLATE_DETECTION_MODELS,
|
|
258
|
+
PLATE_RECOGNITION_MODELS,
|
|
259
|
+
PlateDetectionAddon,
|
|
260
|
+
PlateRecognitionAddon,
|
|
261
|
+
PythonInferenceEngine,
|
|
262
|
+
SEGMENTATION_MODELS,
|
|
263
|
+
SEGMENTATION_REFINER_MODELS,
|
|
264
|
+
VEHICLE_TYPE_MODELS,
|
|
265
|
+
cosineSimilarity,
|
|
266
|
+
cropRegion,
|
|
267
|
+
ctcDecode,
|
|
268
|
+
detectMotion,
|
|
269
|
+
iou,
|
|
270
|
+
jpegToRgb,
|
|
271
|
+
l2Normalize,
|
|
272
|
+
letterbox,
|
|
273
|
+
nms,
|
|
274
|
+
probeOnnxBackends,
|
|
275
|
+
resizeAndNormalize,
|
|
276
|
+
resolveEngine,
|
|
277
|
+
rgbToGrayscale,
|
|
278
|
+
scrfdPostprocess,
|
|
279
|
+
yamnetPostprocess,
|
|
280
|
+
yoloPostprocess
|
|
2729
281
|
};
|
|
2730
282
|
//# sourceMappingURL=index.mjs.map
|