@camstack/addon-pipeline 1.1.54 → 1.1.56
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/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +159 -1471
- package/dist/detection-pipeline/index.mjs +139 -1451
- package/dist/{dist-BbaoC680.js → dist-ClE6_i0p.js} +1000 -40
- package/dist/{dist-CEcTeu1h.mjs → dist-CrjLGrkj.mjs} +1000 -40
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +777 -27
- package/dist/pipeline-runner/index.mjs +777 -28
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.mjs +1 -1
- package/dist/{remote-source-plane-CNCqC_XG.mjs → remote-source-plane-B28iGi7h.mjs} +1 -1
- package/dist/{remote-source-plane-vN45KFSm.js → remote-source-plane-BAqEHSgm.js} +1 -1
- package/dist/session-decode/decode-worker-child.js +227 -6
- package/dist/session-decode/decode-worker-child.mjs +227 -6
- package/dist/step-definitions-C9kUXgC7.js +1514 -0
- package/dist/step-definitions-dCghpdRo.mjs +1479 -0
- package/dist/stream-broker/_stub.js +79 -79
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-HS0tc6Sa.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-D4xH4Tm-.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D2z_vRMH.mjs +26 -0
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B_v5r5ya.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-TWCUWhCm.mjs} +2 -2
- package/dist/stream-broker/{hostInit-DgohfEDA.mjs → hostInit-Di9WUNlQ.mjs} +3 -3
- package/dist/stream-broker/index.js +60 -3
- package/dist/stream-broker/index.mjs +60 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-DGIt_waM.mjs → worker-protocol-CyVJTZEO.mjs} +1 -0
- package/dist/{worker-protocol-DkL6GDxe.js → worker-protocol-PP4jKHHJ.js} +1 -0
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-CA2Hd6xx.js → MaskShapeCanvas-DI4BY7W2-Ca93F1js.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-DUN1VeC7.js → MotionZonesSettings-NcxxQN8r-CDqgb-WA.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BqZIAU5s.js → PrivacyMaskSettings-APgPLF7p-BlxPhY_w.js} +1 -1
- package/embed-dist/assets/index-B23riUw8.js +81 -0
- package/embed-dist/assets/index-Bmpl9O1K.css +2 -0
- package/embed-dist/index.html +2 -2
- package/package.json +1 -1
- package/python/inference_pool.py +11 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B3gTdHEh.mjs +0 -26
- package/embed-dist/assets/index-CC06JBcl.css +0 -2
- package/embed-dist/assets/index-CMkYypxB.js +0 -81
|
@@ -3,7 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-D6vf50IK.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-ClE6_i0p.js");
|
|
7
|
+
const require_step_definitions = require("../step-definitions-C9kUXgC7.js");
|
|
7
8
|
const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
|
|
8
9
|
const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BLXzxpRB.js");
|
|
9
10
|
let _camstack_shm_ring = require("@camstack/shm-ring");
|
|
@@ -298,1437 +299,6 @@ function projectNodeEngine(store, nodeId) {
|
|
|
298
299
|
return out;
|
|
299
300
|
}
|
|
300
301
|
//#endregion
|
|
301
|
-
//#region src/detection-pipeline/registry/model-catalogs.ts
|
|
302
|
-
var HF_REPO = "camstack/camstack-models";
|
|
303
|
-
var HF_SCRYPTED = "scrypted/plugin-models";
|
|
304
|
-
var hf = (path) => require_dist.hfModelUrl(HF_REPO, path);
|
|
305
|
-
var hfScrypted = (path) => require_dist.hfModelUrl(HF_SCRYPTED, path);
|
|
306
|
-
/**
|
|
307
|
-
* Build an OpenVINO format entry (always python runtime).
|
|
308
|
-
*
|
|
309
|
-
* OpenVINO IR is a two-file bundle: a `.xml` topology + a sibling `.bin`
|
|
310
|
-
* weights file with the same basename. We declare the `.bin` in `files` so
|
|
311
|
-
* the (format-agnostic) downloader fetches it alongside the `.xml` — without
|
|
312
|
-
* the weights, OpenVINO compile fails with "Empty weights data in bin file".
|
|
313
|
-
* A plain `.onnx` run through the OpenVINO runtime (e.g. yamnet) has no
|
|
314
|
-
* sibling, so none is added.
|
|
315
|
-
*/
|
|
316
|
-
var ovFormat = (url, sizeMB) => {
|
|
317
|
-
const base = url.split("/").pop() ?? "";
|
|
318
|
-
const files = base.endsWith(".xml") ? [base.replace(/\.xml$/, ".bin")] : void 0;
|
|
319
|
-
return {
|
|
320
|
-
url,
|
|
321
|
-
sizeMB,
|
|
322
|
-
runtimes: ["python"],
|
|
323
|
-
...files ? { files } : {}
|
|
324
|
-
};
|
|
325
|
-
};
|
|
326
|
-
/**
|
|
327
|
-
* Build a precision-variant catalog entry (OpenVINO-only) derived from a base
|
|
328
|
-
* detection model. fp16 halves the weights (Intel iGPU/NPU sweet spot); int8 is
|
|
329
|
-
* NNCF post-training-quantized (~4× smaller, fastest on CPU/iGPU at a small
|
|
330
|
-
* accuracy cost). The IRs live next to the base `.xml` on HF as
|
|
331
|
-
* `camstack-<id>-<precision>.xml`. Lets an operator scale the model to the node
|
|
332
|
-
* (e.g. yolo26x-int8 on a 265K, yolo26n-int8 on an N100).
|
|
333
|
-
*/
|
|
334
|
-
var ovPrecisionVariant = (baseId, ovDir, baseName, precision, sizeMB, legacy = false) => ({
|
|
335
|
-
id: `${baseId}-${precision}`,
|
|
336
|
-
name: `${baseName} (${precision.toUpperCase()})`,
|
|
337
|
-
description: `${baseName} — OpenVINO ${precision.toUpperCase()} variant for Intel iGPU/NPU; scale by hardware`,
|
|
338
|
-
inputSize: {
|
|
339
|
-
width: 640,
|
|
340
|
-
height: 640
|
|
341
|
-
},
|
|
342
|
-
labels: [],
|
|
343
|
-
preprocessMode: "letterbox",
|
|
344
|
-
formats: { openvino: ovFormat(hf(`${ovDir}/camstack-${baseId}-${precision}.xml`), sizeMB) },
|
|
345
|
-
...legacy ? { legacy: true } : {},
|
|
346
|
-
...precision === "int8" ? { group: {
|
|
347
|
-
family: baseId.slice(0, -1),
|
|
348
|
-
tier: baseId.slice(-1),
|
|
349
|
-
precision: "int8"
|
|
350
|
-
} } : {}
|
|
351
|
-
});
|
|
352
|
-
var MLPACKAGE_FILES = [
|
|
353
|
-
"Manifest.json",
|
|
354
|
-
"Data/com.apple.CoreML/model.mlmodel",
|
|
355
|
-
"Data/com.apple.CoreML/weights/weight.bin"
|
|
356
|
-
];
|
|
357
|
-
var YOLO26_TIER_NAME = {
|
|
358
|
-
n: "Nano",
|
|
359
|
-
s: "Small",
|
|
360
|
-
m: "Medium",
|
|
361
|
-
l: "Large"
|
|
362
|
-
};
|
|
363
|
-
/**
|
|
364
|
-
* Reduced-input YOLO26 variants (2026-07-11). A lower square input (320 / 256)
|
|
365
|
-
* is the biggest, cheapest latency lever measured across every runtime — Mac
|
|
366
|
-
* ANE, Intel Ultra NPU, and especially the N100 — at a small-object accuracy
|
|
367
|
-
* cost. Each resolution ships a base (fp32) entry (onnx + coreml + openvino)
|
|
368
|
-
* grouped under `{family, tier, resolution}`, plus an OpenVINO INT8 entry (best
|
|
369
|
-
* on Intel/N100) grouped with `precision:'int8'`. The grouped selector surfaces
|
|
370
|
-
* `resolution` as a variant axis alongside precision.
|
|
371
|
-
*/
|
|
372
|
-
var yolo26Reduced = (tier, res, sizes) => {
|
|
373
|
-
const name = YOLO26_TIER_NAME[tier] ?? tier.toUpperCase();
|
|
374
|
-
return [{
|
|
375
|
-
id: `yolo26${tier}-${res}`,
|
|
376
|
-
group: {
|
|
377
|
-
family: "yolo26",
|
|
378
|
-
tier,
|
|
379
|
-
resolution: res
|
|
380
|
-
},
|
|
381
|
-
name: `YOLO26 ${name} @${res}`,
|
|
382
|
-
description: `YOLO26 ${name}, reduced ${res}×${res} input — faster on ANE / hub NPU / N100 at a small-object accuracy cost`,
|
|
383
|
-
inputSize: {
|
|
384
|
-
width: res,
|
|
385
|
-
height: res
|
|
386
|
-
},
|
|
387
|
-
labels: [],
|
|
388
|
-
preprocessMode: "letterbox",
|
|
389
|
-
formats: {
|
|
390
|
-
onnx: {
|
|
391
|
-
url: hf(`objectDetection/yolo26/onnx/camstack-yolo26${tier}-${res}.onnx`),
|
|
392
|
-
sizeMB: sizes.onnx
|
|
393
|
-
},
|
|
394
|
-
coreml: {
|
|
395
|
-
url: hf(`objectDetection/yolo26/coreml/camstack-yolo26${tier}-${res}.mlpackage`),
|
|
396
|
-
sizeMB: sizes.coreml,
|
|
397
|
-
isDirectory: true,
|
|
398
|
-
files: [...MLPACKAGE_FILES],
|
|
399
|
-
runtimes: ["python"]
|
|
400
|
-
},
|
|
401
|
-
openvino: ovFormat(hf(`objectDetection/yolo26/openvino/camstack-yolo26${tier}-${res}.xml`), sizes.ovFp32)
|
|
402
|
-
}
|
|
403
|
-
}, {
|
|
404
|
-
id: `yolo26${tier}-${res}-int8`,
|
|
405
|
-
group: {
|
|
406
|
-
family: "yolo26",
|
|
407
|
-
tier,
|
|
408
|
-
precision: "int8",
|
|
409
|
-
resolution: res
|
|
410
|
-
},
|
|
411
|
-
name: `YOLO26 ${name} @${res} (INT8)`,
|
|
412
|
-
description: `YOLO26 ${name} @${res} — OpenVINO INT8 for Intel iGPU/CPU; the N100's fastest config`,
|
|
413
|
-
inputSize: {
|
|
414
|
-
width: res,
|
|
415
|
-
height: res
|
|
416
|
-
},
|
|
417
|
-
labels: [],
|
|
418
|
-
preprocessMode: "letterbox",
|
|
419
|
-
formats: { openvino: ovFormat(hf(`objectDetection/yolo26/openvino/camstack-yolo26${tier}-${res}-int8.xml`), sizes.ovInt8) }
|
|
420
|
-
}];
|
|
421
|
-
};
|
|
422
|
-
var OBJECT_DETECTION_MODELS = [
|
|
423
|
-
{
|
|
424
|
-
id: "yolov9t",
|
|
425
|
-
legacy: true,
|
|
426
|
-
name: "YOLOv9 Tiny",
|
|
427
|
-
description: "YOLOv9 Tiny — ultra-lightweight next-gen detector",
|
|
428
|
-
inputSize: {
|
|
429
|
-
width: 640,
|
|
430
|
-
height: 640
|
|
431
|
-
},
|
|
432
|
-
labels: [],
|
|
433
|
-
preprocessMode: "letterbox",
|
|
434
|
-
formats: {
|
|
435
|
-
onnx: {
|
|
436
|
-
url: hf("objectDetection/yolov9/onnx/camstack-yolov9t.onnx"),
|
|
437
|
-
sizeMB: 8
|
|
438
|
-
},
|
|
439
|
-
coreml: {
|
|
440
|
-
url: hf("objectDetection/yolov9/coreml/camstack-yolov9t.mlpackage"),
|
|
441
|
-
sizeMB: 4,
|
|
442
|
-
isDirectory: true,
|
|
443
|
-
files: [...MLPACKAGE_FILES],
|
|
444
|
-
runtimes: ["python"]
|
|
445
|
-
},
|
|
446
|
-
openvino: ovFormat(hf("objectDetection/yolov9/openvino/camstack-yolov9t.xml"), 6)
|
|
447
|
-
}
|
|
448
|
-
},
|
|
449
|
-
{
|
|
450
|
-
id: "yolov9s",
|
|
451
|
-
legacy: true,
|
|
452
|
-
name: "YOLOv9 Small",
|
|
453
|
-
description: "YOLOv9 Small — improved efficiency over YOLOv8s",
|
|
454
|
-
inputSize: {
|
|
455
|
-
width: 640,
|
|
456
|
-
height: 640
|
|
457
|
-
},
|
|
458
|
-
labels: [],
|
|
459
|
-
preprocessMode: "letterbox",
|
|
460
|
-
formats: {
|
|
461
|
-
onnx: {
|
|
462
|
-
url: hf("objectDetection/yolov9/onnx/camstack-yolov9s.onnx"),
|
|
463
|
-
sizeMB: 28
|
|
464
|
-
},
|
|
465
|
-
coreml: {
|
|
466
|
-
url: hf("objectDetection/yolov9/coreml/camstack-yolov9s.mlpackage"),
|
|
467
|
-
sizeMB: 14,
|
|
468
|
-
isDirectory: true,
|
|
469
|
-
files: [...MLPACKAGE_FILES],
|
|
470
|
-
runtimes: ["python"]
|
|
471
|
-
},
|
|
472
|
-
openvino: ovFormat(hf("objectDetection/yolov9/openvino/camstack-yolov9s.xml"), 16)
|
|
473
|
-
}
|
|
474
|
-
},
|
|
475
|
-
{
|
|
476
|
-
id: "yolov9c",
|
|
477
|
-
legacy: true,
|
|
478
|
-
name: "YOLOv9 C",
|
|
479
|
-
description: "YOLOv9 C — high-accuracy compact model",
|
|
480
|
-
inputSize: {
|
|
481
|
-
width: 640,
|
|
482
|
-
height: 640
|
|
483
|
-
},
|
|
484
|
-
labels: [],
|
|
485
|
-
preprocessMode: "letterbox",
|
|
486
|
-
formats: {
|
|
487
|
-
onnx: {
|
|
488
|
-
url: hf("objectDetection/yolov9/onnx/camstack-yolov9c.onnx"),
|
|
489
|
-
sizeMB: 97
|
|
490
|
-
},
|
|
491
|
-
coreml: {
|
|
492
|
-
url: hf("objectDetection/yolov9/coreml/camstack-yolov9c.mlpackage"),
|
|
493
|
-
sizeMB: 48,
|
|
494
|
-
isDirectory: true,
|
|
495
|
-
files: [...MLPACKAGE_FILES],
|
|
496
|
-
runtimes: ["python"]
|
|
497
|
-
},
|
|
498
|
-
openvino: ovFormat(hf("objectDetection/yolov9/openvino/camstack-yolov9c.xml"), 49)
|
|
499
|
-
}
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
id: "yolo26n",
|
|
503
|
-
group: {
|
|
504
|
-
family: "yolo26",
|
|
505
|
-
tier: "n"
|
|
506
|
-
},
|
|
507
|
-
name: "YOLO26 Nano",
|
|
508
|
-
description: "YOLO26 Nano — latest generation ultra-lightweight detector with attention mechanism",
|
|
509
|
-
inputSize: {
|
|
510
|
-
width: 640,
|
|
511
|
-
height: 640
|
|
512
|
-
},
|
|
513
|
-
labels: [],
|
|
514
|
-
preprocessMode: "letterbox",
|
|
515
|
-
formats: {
|
|
516
|
-
onnx: {
|
|
517
|
-
url: hf("objectDetection/yolo26/onnx/camstack-yolo26n.onnx"),
|
|
518
|
-
sizeMB: 10
|
|
519
|
-
},
|
|
520
|
-
coreml: {
|
|
521
|
-
url: hf("objectDetection/yolo26/coreml/camstack-yolo26n.mlpackage"),
|
|
522
|
-
sizeMB: 5,
|
|
523
|
-
isDirectory: true,
|
|
524
|
-
files: [...MLPACKAGE_FILES],
|
|
525
|
-
runtimes: ["python"]
|
|
526
|
-
},
|
|
527
|
-
openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26n.xml"), 9)
|
|
528
|
-
}
|
|
529
|
-
},
|
|
530
|
-
{
|
|
531
|
-
id: "yolo26s",
|
|
532
|
-
group: {
|
|
533
|
-
family: "yolo26",
|
|
534
|
-
tier: "s"
|
|
535
|
-
},
|
|
536
|
-
name: "YOLO26 Small",
|
|
537
|
-
description: "YOLO26 Small — balanced speed/accuracy with attention-based architecture",
|
|
538
|
-
inputSize: {
|
|
539
|
-
width: 640,
|
|
540
|
-
height: 640
|
|
541
|
-
},
|
|
542
|
-
labels: [],
|
|
543
|
-
preprocessMode: "letterbox",
|
|
544
|
-
formats: {
|
|
545
|
-
onnx: {
|
|
546
|
-
url: hf("objectDetection/yolo26/onnx/camstack-yolo26s.onnx"),
|
|
547
|
-
sizeMB: 37
|
|
548
|
-
},
|
|
549
|
-
coreml: {
|
|
550
|
-
url: hf("objectDetection/yolo26/coreml/camstack-yolo26s.mlpackage"),
|
|
551
|
-
sizeMB: 18,
|
|
552
|
-
isDirectory: true,
|
|
553
|
-
files: [...MLPACKAGE_FILES],
|
|
554
|
-
runtimes: ["python"]
|
|
555
|
-
},
|
|
556
|
-
openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26s.xml"), 36)
|
|
557
|
-
}
|
|
558
|
-
},
|
|
559
|
-
{
|
|
560
|
-
id: "yolo26m",
|
|
561
|
-
group: {
|
|
562
|
-
family: "yolo26",
|
|
563
|
-
tier: "m"
|
|
564
|
-
},
|
|
565
|
-
name: "YOLO26 Medium",
|
|
566
|
-
description: "YOLO26 Medium — high accuracy general-purpose detector",
|
|
567
|
-
inputSize: {
|
|
568
|
-
width: 640,
|
|
569
|
-
height: 640
|
|
570
|
-
},
|
|
571
|
-
labels: [],
|
|
572
|
-
preprocessMode: "letterbox",
|
|
573
|
-
formats: {
|
|
574
|
-
onnx: {
|
|
575
|
-
url: hf("objectDetection/yolo26/onnx/camstack-yolo26m.onnx"),
|
|
576
|
-
sizeMB: 78
|
|
577
|
-
},
|
|
578
|
-
coreml: {
|
|
579
|
-
url: hf("objectDetection/yolo26/coreml/camstack-yolo26m.mlpackage"),
|
|
580
|
-
sizeMB: 39,
|
|
581
|
-
isDirectory: true,
|
|
582
|
-
files: [...MLPACKAGE_FILES],
|
|
583
|
-
runtimes: ["python"]
|
|
584
|
-
},
|
|
585
|
-
openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26m.xml"), 78)
|
|
586
|
-
}
|
|
587
|
-
},
|
|
588
|
-
{
|
|
589
|
-
id: "yolo26l",
|
|
590
|
-
group: {
|
|
591
|
-
family: "yolo26",
|
|
592
|
-
tier: "l"
|
|
593
|
-
},
|
|
594
|
-
name: "YOLO26 Large",
|
|
595
|
-
description: "YOLO26 Large — maximum accuracy for demanding deployments",
|
|
596
|
-
inputSize: {
|
|
597
|
-
width: 640,
|
|
598
|
-
height: 640
|
|
599
|
-
},
|
|
600
|
-
labels: [],
|
|
601
|
-
preprocessMode: "letterbox",
|
|
602
|
-
formats: {
|
|
603
|
-
onnx: {
|
|
604
|
-
url: hf("objectDetection/yolo26/onnx/camstack-yolo26l.onnx"),
|
|
605
|
-
sizeMB: 95
|
|
606
|
-
},
|
|
607
|
-
coreml: {
|
|
608
|
-
url: hf("objectDetection/yolo26/coreml/camstack-yolo26l.mlpackage"),
|
|
609
|
-
sizeMB: 48,
|
|
610
|
-
isDirectory: true,
|
|
611
|
-
files: [...MLPACKAGE_FILES],
|
|
612
|
-
runtimes: ["python"]
|
|
613
|
-
},
|
|
614
|
-
openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26l.xml"), 95)
|
|
615
|
-
}
|
|
616
|
-
},
|
|
617
|
-
{
|
|
618
|
-
id: "yolo26x",
|
|
619
|
-
legacy: true,
|
|
620
|
-
name: "YOLO26 XLarge",
|
|
621
|
-
description: "YOLO26 XLarge — highest accuracy, attention-based architecture",
|
|
622
|
-
inputSize: {
|
|
623
|
-
width: 640,
|
|
624
|
-
height: 640
|
|
625
|
-
},
|
|
626
|
-
labels: [],
|
|
627
|
-
preprocessMode: "letterbox",
|
|
628
|
-
formats: {
|
|
629
|
-
onnx: {
|
|
630
|
-
url: hf("objectDetection/yolo26/onnx/camstack-yolo26x.onnx"),
|
|
631
|
-
sizeMB: 213
|
|
632
|
-
},
|
|
633
|
-
coreml: {
|
|
634
|
-
url: hf("objectDetection/yolo26/coreml/camstack-yolo26x.mlpackage"),
|
|
635
|
-
sizeMB: 107,
|
|
636
|
-
isDirectory: true,
|
|
637
|
-
files: [...MLPACKAGE_FILES],
|
|
638
|
-
runtimes: ["python"]
|
|
639
|
-
},
|
|
640
|
-
openvino: ovFormat(hf("objectDetection/yolo26/openvino/camstack-yolo26x.xml"), 213)
|
|
641
|
-
}
|
|
642
|
-
},
|
|
643
|
-
{
|
|
644
|
-
id: "scrypted-yolov9t-relu",
|
|
645
|
-
legacy: true,
|
|
646
|
-
name: "YOLOv9 Tiny ReLU",
|
|
647
|
-
description: "YOLOv9t ReLU — optimized for int8 quantization",
|
|
648
|
-
inputSize: {
|
|
649
|
-
width: 320,
|
|
650
|
-
height: 320
|
|
651
|
-
},
|
|
652
|
-
labels: [],
|
|
653
|
-
preprocessMode: "letterbox",
|
|
654
|
-
formats: {
|
|
655
|
-
onnx: {
|
|
656
|
-
url: hfScrypted("onnx/scrypted_yolov9t_relu/scrypted_yolov9t_relu.onnx"),
|
|
657
|
-
sizeMB: 8.1
|
|
658
|
-
},
|
|
659
|
-
coreml: {
|
|
660
|
-
url: hfScrypted("coreml/scrypted_yolov9t_relu/scrypted_yolov9t_relu.mlpackage"),
|
|
661
|
-
sizeMB: 4,
|
|
662
|
-
isDirectory: true,
|
|
663
|
-
files: [...MLPACKAGE_FILES],
|
|
664
|
-
runtimes: ["python"]
|
|
665
|
-
},
|
|
666
|
-
openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9t_relu.xml"), 6)
|
|
667
|
-
}
|
|
668
|
-
},
|
|
669
|
-
{
|
|
670
|
-
id: "scrypted-yolov9s-relu",
|
|
671
|
-
legacy: true,
|
|
672
|
-
name: "YOLOv9 Small ReLU",
|
|
673
|
-
description: "YOLOv9s ReLU — improved efficiency, int8 ready",
|
|
674
|
-
inputSize: {
|
|
675
|
-
width: 320,
|
|
676
|
-
height: 320
|
|
677
|
-
},
|
|
678
|
-
labels: [],
|
|
679
|
-
preprocessMode: "letterbox",
|
|
680
|
-
formats: {
|
|
681
|
-
onnx: {
|
|
682
|
-
url: hfScrypted("onnx/scrypted_yolov9s_relu/scrypted_yolov9s_relu.onnx"),
|
|
683
|
-
sizeMB: 27.9
|
|
684
|
-
},
|
|
685
|
-
coreml: {
|
|
686
|
-
url: hfScrypted("coreml/scrypted_yolov9s_relu/scrypted_yolov9s_relu.mlpackage"),
|
|
687
|
-
sizeMB: 14,
|
|
688
|
-
isDirectory: true,
|
|
689
|
-
files: [...MLPACKAGE_FILES],
|
|
690
|
-
runtimes: ["python"]
|
|
691
|
-
},
|
|
692
|
-
openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9s_relu.xml"), 16)
|
|
693
|
-
}
|
|
694
|
-
},
|
|
695
|
-
{
|
|
696
|
-
id: "scrypted-yolov9c-relu",
|
|
697
|
-
legacy: true,
|
|
698
|
-
name: "YOLOv9 C ReLU",
|
|
699
|
-
description: "YOLOv9c ReLU — high-accuracy, int8 ready",
|
|
700
|
-
inputSize: {
|
|
701
|
-
width: 320,
|
|
702
|
-
height: 320
|
|
703
|
-
},
|
|
704
|
-
labels: [],
|
|
705
|
-
preprocessMode: "letterbox",
|
|
706
|
-
formats: {
|
|
707
|
-
onnx: {
|
|
708
|
-
url: hfScrypted("onnx/scrypted_yolov9c_relu/scrypted_yolov9c_relu.onnx"),
|
|
709
|
-
sizeMB: 96.9
|
|
710
|
-
},
|
|
711
|
-
coreml: {
|
|
712
|
-
url: hfScrypted("coreml/scrypted_yolov9c_relu/scrypted_yolov9c_relu.mlpackage"),
|
|
713
|
-
sizeMB: 48,
|
|
714
|
-
isDirectory: true,
|
|
715
|
-
files: [...MLPACKAGE_FILES],
|
|
716
|
-
runtimes: ["python"]
|
|
717
|
-
},
|
|
718
|
-
openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9c_relu.xml"), 49)
|
|
719
|
-
}
|
|
720
|
-
},
|
|
721
|
-
{
|
|
722
|
-
id: "scrypted-yolov9m-relu",
|
|
723
|
-
legacy: true,
|
|
724
|
-
name: "YOLOv9 M ReLU",
|
|
725
|
-
description: "YOLOv9m ReLU — medium, int8 ready",
|
|
726
|
-
inputSize: {
|
|
727
|
-
width: 320,
|
|
728
|
-
height: 320
|
|
729
|
-
},
|
|
730
|
-
labels: [],
|
|
731
|
-
preprocessMode: "letterbox",
|
|
732
|
-
formats: {
|
|
733
|
-
onnx: {
|
|
734
|
-
url: hfScrypted("onnx/scrypted_yolov9m_relu/scrypted_yolov9m_relu.onnx"),
|
|
735
|
-
sizeMB: 76.6
|
|
736
|
-
},
|
|
737
|
-
coreml: {
|
|
738
|
-
url: hfScrypted("coreml/scrypted_yolov9m_relu/scrypted_yolov9m_relu.mlpackage"),
|
|
739
|
-
sizeMB: 38,
|
|
740
|
-
isDirectory: true,
|
|
741
|
-
files: [...MLPACKAGE_FILES],
|
|
742
|
-
runtimes: ["python"]
|
|
743
|
-
},
|
|
744
|
-
openvino: ovFormat(hf("objectDetection/scrypted-yolov9-relu/openvino/scrypted_yolov9m_relu.xml"), 38)
|
|
745
|
-
}
|
|
746
|
-
},
|
|
747
|
-
ovPrecisionVariant("yolov9t", "objectDetection/yolov9/openvino", "YOLOv9 Tiny", "fp16", 5, true),
|
|
748
|
-
ovPrecisionVariant("yolov9t", "objectDetection/yolov9/openvino", "YOLOv9 Tiny", "int8", 3, true),
|
|
749
|
-
ovPrecisionVariant("yolov9s", "objectDetection/yolov9/openvino", "YOLOv9 Small", "fp16", 15, true),
|
|
750
|
-
ovPrecisionVariant("yolov9s", "objectDetection/yolov9/openvino", "YOLOv9 Small", "int8", 8, true),
|
|
751
|
-
ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "fp16", 5, true),
|
|
752
|
-
ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "int8", 3),
|
|
753
|
-
ovPrecisionVariant("yolo26s", "objectDetection/yolo26/openvino", "YOLO26 Small", "fp16", 19, true),
|
|
754
|
-
ovPrecisionVariant("yolo26s", "objectDetection/yolo26/openvino", "YOLO26 Small", "int8", 10),
|
|
755
|
-
ovPrecisionVariant("yolo26m", "objectDetection/yolo26/openvino", "YOLO26 Medium", "fp16", 41, true),
|
|
756
|
-
ovPrecisionVariant("yolo26m", "objectDetection/yolo26/openvino", "YOLO26 Medium", "int8", 21),
|
|
757
|
-
ovPrecisionVariant("yolo26l", "objectDetection/yolo26/openvino", "YOLO26 Large", "fp16", 50, true),
|
|
758
|
-
ovPrecisionVariant("yolo26l", "objectDetection/yolo26/openvino", "YOLO26 Large", "int8", 25),
|
|
759
|
-
...yolo26Reduced("n", 320, {
|
|
760
|
-
onnx: 10.47,
|
|
761
|
-
coreml: 5.05,
|
|
762
|
-
ovFp32: 10.05,
|
|
763
|
-
ovInt8: 3.29
|
|
764
|
-
}),
|
|
765
|
-
...yolo26Reduced("n", 256, {
|
|
766
|
-
onnx: 10.47,
|
|
767
|
-
coreml: 5.05,
|
|
768
|
-
ovFp32: 10.05,
|
|
769
|
-
ovInt8: 3.29
|
|
770
|
-
}),
|
|
771
|
-
...yolo26Reduced("s", 320, {
|
|
772
|
-
onnx: 38.82,
|
|
773
|
-
coreml: 19.23,
|
|
774
|
-
ovFp32: 38.4,
|
|
775
|
-
ovInt8: 10.43
|
|
776
|
-
}),
|
|
777
|
-
...yolo26Reduced("s", 256, {
|
|
778
|
-
onnx: 38.82,
|
|
779
|
-
coreml: 19.23,
|
|
780
|
-
ovFp32: 38.4,
|
|
781
|
-
ovInt8: 10.43
|
|
782
|
-
}),
|
|
783
|
-
...yolo26Reduced("m", 320, {
|
|
784
|
-
onnx: 83.31,
|
|
785
|
-
coreml: 41.07,
|
|
786
|
-
ovFp32: 82.09,
|
|
787
|
-
ovInt8: 21.47
|
|
788
|
-
}),
|
|
789
|
-
...yolo26Reduced("m", 256, {
|
|
790
|
-
onnx: 83.31,
|
|
791
|
-
coreml: 41.07,
|
|
792
|
-
ovFp32: 82.09,
|
|
793
|
-
ovInt8: 21.47
|
|
794
|
-
}),
|
|
795
|
-
...yolo26Reduced("l", 320, {
|
|
796
|
-
onnx: 101.74,
|
|
797
|
-
coreml: 49.97,
|
|
798
|
-
ovFp32: 99.85,
|
|
799
|
-
ovInt8: 26.31
|
|
800
|
-
}),
|
|
801
|
-
...yolo26Reduced("l", 256, {
|
|
802
|
-
onnx: 101.74,
|
|
803
|
-
coreml: 49.97,
|
|
804
|
-
ovFp32: 99.85,
|
|
805
|
-
ovInt8: 26.31
|
|
806
|
-
}),
|
|
807
|
-
ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "fp16", 112, true),
|
|
808
|
-
ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "int8", 56, true)
|
|
809
|
-
];
|
|
810
|
-
var FACE_DETECTION_MODELS = [{
|
|
811
|
-
id: "scrfd-2.5g",
|
|
812
|
-
name: "SCRFD 2.5G",
|
|
813
|
-
description: "SCRFD 2.5G — balanced face detection model",
|
|
814
|
-
inputSize: {
|
|
815
|
-
width: 640,
|
|
816
|
-
height: 640
|
|
817
|
-
},
|
|
818
|
-
labels: [{
|
|
819
|
-
id: "face",
|
|
820
|
-
name: "Face"
|
|
821
|
-
}],
|
|
822
|
-
preprocessMode: "letterbox",
|
|
823
|
-
formats: {
|
|
824
|
-
onnx: {
|
|
825
|
-
url: hf("faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx"),
|
|
826
|
-
sizeMB: 3.1
|
|
827
|
-
},
|
|
828
|
-
coreml: {
|
|
829
|
-
url: hf("faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage"),
|
|
830
|
-
sizeMB: 1.7,
|
|
831
|
-
isDirectory: true,
|
|
832
|
-
files: [...MLPACKAGE_FILES],
|
|
833
|
-
runtimes: ["python"]
|
|
834
|
-
},
|
|
835
|
-
openvino: ovFormat(hf("faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml"), 1.8)
|
|
836
|
-
}
|
|
837
|
-
}, {
|
|
838
|
-
id: "scrypted-yolov9t-face",
|
|
839
|
-
name: "YOLOv9t Face ReLU",
|
|
840
|
-
description: "YOLOv9t face detection — YOLO-based, fast, 320x320 ReLU",
|
|
841
|
-
inputSize: {
|
|
842
|
-
width: 320,
|
|
843
|
-
height: 320
|
|
844
|
-
},
|
|
845
|
-
labels: [{
|
|
846
|
-
id: "face",
|
|
847
|
-
name: "Face"
|
|
848
|
-
}],
|
|
849
|
-
preprocessMode: "letterbox",
|
|
850
|
-
formats: {
|
|
851
|
-
onnx: {
|
|
852
|
-
url: hfScrypted("onnx/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.onnx"),
|
|
853
|
-
sizeMB: 8.1
|
|
854
|
-
},
|
|
855
|
-
coreml: {
|
|
856
|
-
url: hfScrypted("coreml/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.mlpackage"),
|
|
857
|
-
sizeMB: 4,
|
|
858
|
-
isDirectory: true,
|
|
859
|
-
files: [...MLPACKAGE_FILES],
|
|
860
|
-
runtimes: ["python"]
|
|
861
|
-
},
|
|
862
|
-
openvino: ovFormat(hf("faceDetection/scrypted-yolov9-face/openvino/scrypted_yolov9t_relu_face.xml"), 6)
|
|
863
|
-
}
|
|
864
|
-
}];
|
|
865
|
-
var FACE_EMBEDDING_MODELS = [{
|
|
866
|
-
id: "arcface-r100",
|
|
867
|
-
name: "ArcFace R100",
|
|
868
|
-
description: "ArcFace ResNet-100 — high-accuracy face recognition embeddings (512-d)",
|
|
869
|
-
inputSize: {
|
|
870
|
-
width: 112,
|
|
871
|
-
height: 112
|
|
872
|
-
},
|
|
873
|
-
inputLayout: "nhwc",
|
|
874
|
-
labels: [{
|
|
875
|
-
id: "embedding",
|
|
876
|
-
name: "Face Embedding"
|
|
877
|
-
}],
|
|
878
|
-
preprocessMode: "resize",
|
|
879
|
-
faceAlignment: true,
|
|
880
|
-
formats: {
|
|
881
|
-
onnx: {
|
|
882
|
-
url: hf("faceRecognition/arcface/onnx/camstack-arcface-arcface.onnx"),
|
|
883
|
-
sizeMB: 130
|
|
884
|
-
},
|
|
885
|
-
coreml: {
|
|
886
|
-
url: hf("faceRecognition/arcface/coreml/camstack-arcface-r100.mlpackage"),
|
|
887
|
-
sizeMB: 65,
|
|
888
|
-
isDirectory: true,
|
|
889
|
-
files: [...MLPACKAGE_FILES],
|
|
890
|
-
runtimes: ["python"]
|
|
891
|
-
},
|
|
892
|
-
openvino: ovFormat(hf("faceRecognition/arcface/openvino/camstack-arcface-r100.xml"), 65)
|
|
893
|
-
}
|
|
894
|
-
}, {
|
|
895
|
-
id: "inception-resnet-v1",
|
|
896
|
-
name: "Inception ResNet V1",
|
|
897
|
-
description: "FaceNet-style face recognition embeddings (512-d) — hosted on plugin-models HF repo",
|
|
898
|
-
inputSize: {
|
|
899
|
-
width: 160,
|
|
900
|
-
height: 160
|
|
901
|
-
},
|
|
902
|
-
labels: [{
|
|
903
|
-
id: "embedding",
|
|
904
|
-
name: "Face Embedding"
|
|
905
|
-
}],
|
|
906
|
-
preprocessMode: "resize",
|
|
907
|
-
formats: {
|
|
908
|
-
onnx: {
|
|
909
|
-
url: hfScrypted("onnx/inception_resnet_v1/inception_resnet_v1.onnx"),
|
|
910
|
-
sizeMB: 89.6
|
|
911
|
-
},
|
|
912
|
-
coreml: {
|
|
913
|
-
url: hfScrypted("coreml/inception_resnet_v1/inception_resnet_v1.mlpackage"),
|
|
914
|
-
sizeMB: 45,
|
|
915
|
-
isDirectory: true,
|
|
916
|
-
files: [...MLPACKAGE_FILES],
|
|
917
|
-
runtimes: ["python"]
|
|
918
|
-
},
|
|
919
|
-
openvino: ovFormat(hf("faceRecognition/inception-resnet-v1/openvino/camstack-inception-resnet-v1.xml"), 45)
|
|
920
|
-
}
|
|
921
|
-
}];
|
|
922
|
-
var PLATE_DETECTION_MODELS = [{
|
|
923
|
-
id: "yolov8n-plate",
|
|
924
|
-
name: "YOLOv8 Nano — License Plate",
|
|
925
|
-
description: "YOLOv8 Nano fine-tuned for license plate detection",
|
|
926
|
-
inputSize: {
|
|
927
|
-
width: 640,
|
|
928
|
-
height: 640
|
|
929
|
-
},
|
|
930
|
-
labels: [{
|
|
931
|
-
id: "plate",
|
|
932
|
-
name: "License Plate"
|
|
933
|
-
}],
|
|
934
|
-
preprocessMode: "letterbox",
|
|
935
|
-
formats: {
|
|
936
|
-
onnx: {
|
|
937
|
-
url: hf("plateDetection/yolov8-plate/onnx/camstack-yolov8n-plate.onnx"),
|
|
938
|
-
sizeMB: 12
|
|
939
|
-
},
|
|
940
|
-
coreml: {
|
|
941
|
-
url: hf("plateDetection/yolov8-plate/coreml/camstack-yolov8n-plate.mlpackage"),
|
|
942
|
-
sizeMB: 5.9,
|
|
943
|
-
isDirectory: true,
|
|
944
|
-
files: [...MLPACKAGE_FILES],
|
|
945
|
-
runtimes: ["python"]
|
|
946
|
-
},
|
|
947
|
-
openvino: ovFormat(hf("plateDetection/yolov8-plate/openvino/camstack-yolov8n-plate.xml"), 6.1)
|
|
948
|
-
}
|
|
949
|
-
}];
|
|
950
|
-
var PLATE_OCR_MODELS = [{
|
|
951
|
-
id: "vgg-english-g2",
|
|
952
|
-
name: "VGG English G2",
|
|
953
|
-
description: "EasyOCR VGG English G2 — text recognition for license plates and scene text",
|
|
954
|
-
inputSize: {
|
|
955
|
-
width: 384,
|
|
956
|
-
height: 64
|
|
957
|
-
},
|
|
958
|
-
labels: [{
|
|
959
|
-
id: "text",
|
|
960
|
-
name: "Plate Text"
|
|
961
|
-
}],
|
|
962
|
-
preprocessMode: "resize",
|
|
963
|
-
formats: {
|
|
964
|
-
onnx: {
|
|
965
|
-
url: hfScrypted("onnx/vgg_english_g2/vgg_english_g2.onnx"),
|
|
966
|
-
sizeMB: 14.4
|
|
967
|
-
},
|
|
968
|
-
coreml: {
|
|
969
|
-
url: hfScrypted("coreml/vgg_english_g2/vgg_english_g2.mlpackage"),
|
|
970
|
-
sizeMB: 11.2,
|
|
971
|
-
isDirectory: true,
|
|
972
|
-
files: [...MLPACKAGE_FILES],
|
|
973
|
-
runtimes: ["python"]
|
|
974
|
-
},
|
|
975
|
-
openvino: ovFormat(hf("plateRecognition/vgg_english_g2/openvino/vgg_english_g2.xml"), 7.2)
|
|
976
|
-
}
|
|
977
|
-
}];
|
|
978
|
-
var ANIMAL_CLASSIFIER_MODELS = [{
|
|
979
|
-
id: "animals-10",
|
|
980
|
-
name: "Animal Classifier (10)",
|
|
981
|
-
description: "ViT-based animal type classifier — cat, cow, dog, dolphin, eagle, panda, horse, monkey, sheep, spider",
|
|
982
|
-
inputSize: {
|
|
983
|
-
width: 224,
|
|
984
|
-
height: 224
|
|
985
|
-
},
|
|
986
|
-
inputNormalization: "imagenet",
|
|
987
|
-
labels: [{
|
|
988
|
-
id: "animal-type",
|
|
989
|
-
name: "Animal Type"
|
|
990
|
-
}],
|
|
991
|
-
preprocessMode: "resize",
|
|
992
|
-
formats: {
|
|
993
|
-
onnx: {
|
|
994
|
-
url: hf("animalClassification/animals-10/onnx/camstack-animals-10.onnx"),
|
|
995
|
-
sizeMB: 328
|
|
996
|
-
},
|
|
997
|
-
coreml: {
|
|
998
|
-
url: hf("animalClassification/animals-10/coreml/camstack-animals-10.mlpackage"),
|
|
999
|
-
sizeMB: 164,
|
|
1000
|
-
isDirectory: true,
|
|
1001
|
-
files: [...MLPACKAGE_FILES],
|
|
1002
|
-
runtimes: ["python"]
|
|
1003
|
-
},
|
|
1004
|
-
openvino: ovFormat(hf("animalClassification/animals-10/openvino/camstack-animals-10.xml"), 164)
|
|
1005
|
-
}
|
|
1006
|
-
}];
|
|
1007
|
-
var BIRD_CLASSIFIER_MODELS = [{
|
|
1008
|
-
id: "bird-nabirds-404",
|
|
1009
|
-
name: "NABirds (404 species)",
|
|
1010
|
-
description: "ResNet50 trained on NABirds — 404 North American species",
|
|
1011
|
-
inputSize: {
|
|
1012
|
-
width: 224,
|
|
1013
|
-
height: 224
|
|
1014
|
-
},
|
|
1015
|
-
inputNormalization: "imagenet",
|
|
1016
|
-
labels: [{
|
|
1017
|
-
id: "species",
|
|
1018
|
-
name: "Bird Species"
|
|
1019
|
-
}],
|
|
1020
|
-
preprocessMode: "resize",
|
|
1021
|
-
formats: {
|
|
1022
|
-
onnx: {
|
|
1023
|
-
url: hf("animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404.onnx"),
|
|
1024
|
-
sizeMB: 93
|
|
1025
|
-
},
|
|
1026
|
-
coreml: {
|
|
1027
|
-
url: hf("animalClassification/bird-nabirds/coreml/camstack-bird-nabirds-404.mlpackage"),
|
|
1028
|
-
sizeMB: 47,
|
|
1029
|
-
isDirectory: true,
|
|
1030
|
-
files: [...MLPACKAGE_FILES],
|
|
1031
|
-
runtimes: ["python"]
|
|
1032
|
-
},
|
|
1033
|
-
openvino: ovFormat(hf("animalClassification/bird-nabirds/openvino/camstack-bird-nabirds-404.xml"), 47)
|
|
1034
|
-
},
|
|
1035
|
-
extraFiles: [{
|
|
1036
|
-
url: hf("animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404-labels.json"),
|
|
1037
|
-
filename: "camstack-bird-nabirds-404-labels.json",
|
|
1038
|
-
sizeMB: .02
|
|
1039
|
-
}]
|
|
1040
|
-
}];
|
|
1041
|
-
var VEHICLE_CLASSIFIER_MODELS = [{
|
|
1042
|
-
id: "vehicle-type-efficientnet",
|
|
1043
|
-
name: "Vehicle Type (EfficientNet)",
|
|
1044
|
-
description: "EfficientNet-B4 vehicle make/model/year classifier — 8,949 classes from VMMRdb",
|
|
1045
|
-
inputSize: {
|
|
1046
|
-
width: 380,
|
|
1047
|
-
height: 380
|
|
1048
|
-
},
|
|
1049
|
-
inputNormalization: "imagenet",
|
|
1050
|
-
labels: [{
|
|
1051
|
-
id: "vehicle-type",
|
|
1052
|
-
name: "Vehicle Type"
|
|
1053
|
-
}],
|
|
1054
|
-
preprocessMode: "resize",
|
|
1055
|
-
formats: {
|
|
1056
|
-
onnx: {
|
|
1057
|
-
url: hf("vehicleClassification/efficientnet/onnx/camstack-vehicle-type-efficientnet.onnx"),
|
|
1058
|
-
sizeMB: 135
|
|
1059
|
-
},
|
|
1060
|
-
coreml: {
|
|
1061
|
-
url: hf("vehicleClassification/efficientnet/coreml/camstack-vehicle-type-efficientnet.mlpackage"),
|
|
1062
|
-
sizeMB: 10,
|
|
1063
|
-
isDirectory: true,
|
|
1064
|
-
files: [...MLPACKAGE_FILES],
|
|
1065
|
-
runtimes: ["python"]
|
|
1066
|
-
},
|
|
1067
|
-
openvino: ovFormat(hf("vehicleClassification/efficientnet/openvino/camstack-vehicle-type-efficientnet.xml"), 68)
|
|
1068
|
-
},
|
|
1069
|
-
extraFiles: [{
|
|
1070
|
-
url: hf("vehicleClassification/efficientnet/camstack-vehicle-type-labels.json"),
|
|
1071
|
-
filename: "camstack-vehicle-type-labels.json",
|
|
1072
|
-
sizeMB: .2
|
|
1073
|
-
}]
|
|
1074
|
-
}];
|
|
1075
|
-
var SEGMENTATION_REFINER_MODELS = [{
|
|
1076
|
-
id: "u2netp",
|
|
1077
|
-
name: "U2-Net Portable",
|
|
1078
|
-
description: "U2-Net-P — ultra-lightweight salient object segmentation (4.7 MB)",
|
|
1079
|
-
inputSize: {
|
|
1080
|
-
width: 320,
|
|
1081
|
-
height: 320
|
|
1082
|
-
},
|
|
1083
|
-
labels: [{
|
|
1084
|
-
id: "mask",
|
|
1085
|
-
name: "Segmentation Mask"
|
|
1086
|
-
}],
|
|
1087
|
-
preprocessMode: "resize",
|
|
1088
|
-
formats: {
|
|
1089
|
-
onnx: {
|
|
1090
|
-
url: hf("segmentationRefiner/u2netp/onnx/camstack-u2netp.onnx"),
|
|
1091
|
-
sizeMB: 5
|
|
1092
|
-
},
|
|
1093
|
-
coreml: {
|
|
1094
|
-
url: hf("segmentationRefiner/u2netp/coreml/camstack-u2netp.mlpackage"),
|
|
1095
|
-
sizeMB: 3,
|
|
1096
|
-
isDirectory: true,
|
|
1097
|
-
files: [...MLPACKAGE_FILES],
|
|
1098
|
-
runtimes: ["python"]
|
|
1099
|
-
},
|
|
1100
|
-
openvino: ovFormat(hf("segmentationRefiner/u2netp/openvino/camstack-u2netp.xml"), 2.5)
|
|
1101
|
-
}
|
|
1102
|
-
}];
|
|
1103
|
-
var INSTANCE_SEGMENTATION_MODELS = [
|
|
1104
|
-
{
|
|
1105
|
-
id: "yolo26n-seg",
|
|
1106
|
-
name: "YOLO26 Nano Seg",
|
|
1107
|
-
description: "YOLO26 Nano Segmentation — ultra-lightweight instance segmentation with masks",
|
|
1108
|
-
inputSize: {
|
|
1109
|
-
width: 640,
|
|
1110
|
-
height: 640
|
|
1111
|
-
},
|
|
1112
|
-
labels: [],
|
|
1113
|
-
preprocessMode: "letterbox",
|
|
1114
|
-
formats: {
|
|
1115
|
-
onnx: {
|
|
1116
|
-
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26n-seg.onnx"),
|
|
1117
|
-
sizeMB: 11
|
|
1118
|
-
},
|
|
1119
|
-
coreml: {
|
|
1120
|
-
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26n-seg.mlpackage"),
|
|
1121
|
-
sizeMB: 6,
|
|
1122
|
-
isDirectory: true,
|
|
1123
|
-
files: [...MLPACKAGE_FILES],
|
|
1124
|
-
runtimes: ["python"]
|
|
1125
|
-
},
|
|
1126
|
-
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26n-seg.xml"), 11)
|
|
1127
|
-
}
|
|
1128
|
-
},
|
|
1129
|
-
{
|
|
1130
|
-
id: "yolo26s-seg",
|
|
1131
|
-
name: "YOLO26 Small Seg",
|
|
1132
|
-
description: "YOLO26 Small Segmentation — balanced instance segmentation",
|
|
1133
|
-
inputSize: {
|
|
1134
|
-
width: 640,
|
|
1135
|
-
height: 640
|
|
1136
|
-
},
|
|
1137
|
-
labels: [],
|
|
1138
|
-
preprocessMode: "letterbox",
|
|
1139
|
-
formats: {
|
|
1140
|
-
onnx: {
|
|
1141
|
-
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26s-seg.onnx"),
|
|
1142
|
-
sizeMB: 40
|
|
1143
|
-
},
|
|
1144
|
-
coreml: {
|
|
1145
|
-
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26s-seg.mlpackage"),
|
|
1146
|
-
sizeMB: 20,
|
|
1147
|
-
isDirectory: true,
|
|
1148
|
-
files: [...MLPACKAGE_FILES],
|
|
1149
|
-
runtimes: ["python"]
|
|
1150
|
-
},
|
|
1151
|
-
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26s-seg.xml"), 40)
|
|
1152
|
-
}
|
|
1153
|
-
},
|
|
1154
|
-
{
|
|
1155
|
-
id: "yolo26m-seg",
|
|
1156
|
-
name: "YOLO26 Medium Seg",
|
|
1157
|
-
description: "YOLO26 Medium Segmentation — high-accuracy instance segmentation",
|
|
1158
|
-
inputSize: {
|
|
1159
|
-
width: 640,
|
|
1160
|
-
height: 640
|
|
1161
|
-
},
|
|
1162
|
-
labels: [],
|
|
1163
|
-
preprocessMode: "letterbox",
|
|
1164
|
-
formats: {
|
|
1165
|
-
onnx: {
|
|
1166
|
-
url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26m-seg.onnx"),
|
|
1167
|
-
sizeMB: 90
|
|
1168
|
-
},
|
|
1169
|
-
coreml: {
|
|
1170
|
-
url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26m-seg.mlpackage"),
|
|
1171
|
-
sizeMB: 45,
|
|
1172
|
-
isDirectory: true,
|
|
1173
|
-
files: [...MLPACKAGE_FILES],
|
|
1174
|
-
runtimes: ["python"]
|
|
1175
|
-
},
|
|
1176
|
-
openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26m-seg.xml"), 90)
|
|
1177
|
-
}
|
|
1178
|
-
}
|
|
1179
|
-
];
|
|
1180
|
-
var CLIP_EMBEDDING_MODELS = [
|
|
1181
|
-
{
|
|
1182
|
-
id: "mobileclip-s0",
|
|
1183
|
-
name: "MobileCLIP S0",
|
|
1184
|
-
description: "MobileCLIP S0 — Apple ultra-fast CLIP vision encoder, 512-dim, 256×256 (40 MB ONNX)",
|
|
1185
|
-
inputSize: {
|
|
1186
|
-
width: 256,
|
|
1187
|
-
height: 256
|
|
1188
|
-
},
|
|
1189
|
-
labels: [{
|
|
1190
|
-
id: "embedding",
|
|
1191
|
-
name: "CLIP Embedding"
|
|
1192
|
-
}],
|
|
1193
|
-
preprocessMode: "resize",
|
|
1194
|
-
inputNormalization: "none",
|
|
1195
|
-
formats: {
|
|
1196
|
-
onnx: {
|
|
1197
|
-
url: hf("clip/mobileclip-s0/onnx/camstack-mobileclip-s0-vision.onnx"),
|
|
1198
|
-
sizeMB: 40
|
|
1199
|
-
},
|
|
1200
|
-
openvino: ovFormat(hf("clip/mobileclip-s0/openvino/camstack-mobileclip-s0-vision.xml"), 25),
|
|
1201
|
-
coreml: {
|
|
1202
|
-
url: hf("clip/mobileclip-s0/coreml/camstack-mobileclip-s0-vision.mlpackage"),
|
|
1203
|
-
sizeMB: 30,
|
|
1204
|
-
isDirectory: true,
|
|
1205
|
-
files: [...MLPACKAGE_FILES],
|
|
1206
|
-
runtimes: ["python"]
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
},
|
|
1210
|
-
{
|
|
1211
|
-
id: "mobileclip-s1",
|
|
1212
|
-
name: "MobileCLIP S1",
|
|
1213
|
-
description: "MobileCLIP S1 — Apple balanced CLIP vision encoder, 512-dim, 256×256 (90 MB ONNX)",
|
|
1214
|
-
inputSize: {
|
|
1215
|
-
width: 256,
|
|
1216
|
-
height: 256
|
|
1217
|
-
},
|
|
1218
|
-
labels: [{
|
|
1219
|
-
id: "embedding",
|
|
1220
|
-
name: "CLIP Embedding"
|
|
1221
|
-
}],
|
|
1222
|
-
preprocessMode: "resize",
|
|
1223
|
-
inputNormalization: "none",
|
|
1224
|
-
formats: {
|
|
1225
|
-
onnx: {
|
|
1226
|
-
url: hf("clip/mobileclip-s1/onnx/camstack-mobileclip-s1-vision.onnx"),
|
|
1227
|
-
sizeMB: 90
|
|
1228
|
-
},
|
|
1229
|
-
openvino: ovFormat(hf("clip/mobileclip-s1/openvino/camstack-mobileclip-s1-vision.xml"), 55),
|
|
1230
|
-
coreml: {
|
|
1231
|
-
url: hf("clip/mobileclip-s1/coreml/camstack-mobileclip-s1-vision.mlpackage"),
|
|
1232
|
-
sizeMB: 65,
|
|
1233
|
-
isDirectory: true,
|
|
1234
|
-
files: [...MLPACKAGE_FILES],
|
|
1235
|
-
runtimes: ["python"]
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
},
|
|
1239
|
-
{
|
|
1240
|
-
id: "mobileclip-s2",
|
|
1241
|
-
name: "MobileCLIP S2",
|
|
1242
|
-
description: "MobileCLIP S2 — Apple high-accuracy CLIP vision encoder, 512-dim, 256×256 (150 MB ONNX)",
|
|
1243
|
-
inputSize: {
|
|
1244
|
-
width: 256,
|
|
1245
|
-
height: 256
|
|
1246
|
-
},
|
|
1247
|
-
labels: [{
|
|
1248
|
-
id: "embedding",
|
|
1249
|
-
name: "CLIP Embedding"
|
|
1250
|
-
}],
|
|
1251
|
-
preprocessMode: "resize",
|
|
1252
|
-
inputNormalization: "none",
|
|
1253
|
-
formats: {
|
|
1254
|
-
onnx: {
|
|
1255
|
-
url: hf("clip/mobileclip-s2/onnx/camstack-mobileclip-s2-vision.onnx"),
|
|
1256
|
-
sizeMB: 150
|
|
1257
|
-
},
|
|
1258
|
-
openvino: ovFormat(hf("clip/mobileclip-s2/openvino/camstack-mobileclip-s2-vision.xml"), 90),
|
|
1259
|
-
coreml: {
|
|
1260
|
-
url: hf("clip/mobileclip-s2/coreml/camstack-mobileclip-s2-vision.mlpackage"),
|
|
1261
|
-
sizeMB: 110,
|
|
1262
|
-
isDirectory: true,
|
|
1263
|
-
files: [...MLPACKAGE_FILES],
|
|
1264
|
-
runtimes: ["python"]
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
];
|
|
1269
|
-
var AUDIO_CLASSIFIER_MODELS = [{
|
|
1270
|
-
id: "yamnet-onnx",
|
|
1271
|
-
name: "YAMNet",
|
|
1272
|
-
description: "Google YAMNet — 521-class audio event classifier (3.2 MB ONNX, runs on any platform)",
|
|
1273
|
-
inputSize: {
|
|
1274
|
-
width: 1,
|
|
1275
|
-
height: 16e3
|
|
1276
|
-
},
|
|
1277
|
-
labels: [],
|
|
1278
|
-
preprocessMode: "resize",
|
|
1279
|
-
formats: {
|
|
1280
|
-
onnx: {
|
|
1281
|
-
url: hf("audioClassification/yamnet/onnx/camstack-yamnet.onnx"),
|
|
1282
|
-
sizeMB: 3.2
|
|
1283
|
-
},
|
|
1284
|
-
openvino: ovFormat(hf("audioClassification/yamnet/openvino/camstack-yamnet.xml"), 3.2),
|
|
1285
|
-
coreml: {
|
|
1286
|
-
url: hf("audioClassification/yamnet/onnx/camstack-yamnet.onnx"),
|
|
1287
|
-
sizeMB: 3.2,
|
|
1288
|
-
runtimes: ["python"]
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
}, {
|
|
1292
|
-
id: "apple-soundanalysis",
|
|
1293
|
-
name: "Apple SoundAnalysis",
|
|
1294
|
-
description: "macOS built-in — 303 sound categories, Neural Engine accelerated, zero download",
|
|
1295
|
-
inputSize: {
|
|
1296
|
-
width: 1,
|
|
1297
|
-
height: 16e3
|
|
1298
|
-
},
|
|
1299
|
-
labels: [],
|
|
1300
|
-
preprocessMode: "resize",
|
|
1301
|
-
formats: { coreml: {
|
|
1302
|
-
url: "",
|
|
1303
|
-
sizeMB: 0
|
|
1304
|
-
} }
|
|
1305
|
-
}];
|
|
1306
|
-
//#endregion
|
|
1307
|
-
//#region src/detection-pipeline/registry/step-definitions.ts
|
|
1308
|
-
var ANIMAL_10_LABELS = [
|
|
1309
|
-
"cat",
|
|
1310
|
-
"cow",
|
|
1311
|
-
"dog",
|
|
1312
|
-
"dolphin",
|
|
1313
|
-
"eagle",
|
|
1314
|
-
"giant panda",
|
|
1315
|
-
"horse",
|
|
1316
|
-
"monkey",
|
|
1317
|
-
"sheep",
|
|
1318
|
-
"spider"
|
|
1319
|
-
];
|
|
1320
|
-
var VGG_G2_CHARSET = ["", ..."0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("")];
|
|
1321
|
-
var PipelineStepBase = class {
|
|
1322
|
-
definition;
|
|
1323
|
-
constructor(definition) {
|
|
1324
|
-
this.definition = definition;
|
|
1325
|
-
}
|
|
1326
|
-
getConfigSchema() {
|
|
1327
|
-
return [];
|
|
1328
|
-
}
|
|
1329
|
-
};
|
|
1330
|
-
var ObjectDetectionStep = class {
|
|
1331
|
-
definition = {
|
|
1332
|
-
id: "object-detection",
|
|
1333
|
-
name: "Object Detection",
|
|
1334
|
-
slot: "detector",
|
|
1335
|
-
postprocessor: "yolo",
|
|
1336
|
-
extractMode: "full-frame",
|
|
1337
|
-
inputClasses: null,
|
|
1338
|
-
outputClasses: [
|
|
1339
|
-
"person",
|
|
1340
|
-
"vehicle",
|
|
1341
|
-
"animal"
|
|
1342
|
-
],
|
|
1343
|
-
models: [...OBJECT_DETECTION_MODELS],
|
|
1344
|
-
defaultModelId: "yolo26n",
|
|
1345
|
-
defaultConfidence: .5,
|
|
1346
|
-
labels: require_dist.COCO_80_LABELS.map((l) => l.id),
|
|
1347
|
-
classMap: require_dist.COCO_TO_MACRO
|
|
1348
|
-
};
|
|
1349
|
-
getConfigSchema() {
|
|
1350
|
-
return [
|
|
1351
|
-
{
|
|
1352
|
-
type: "multiselect",
|
|
1353
|
-
key: "enabledMacroClasses",
|
|
1354
|
-
label: "Enabled Classes",
|
|
1355
|
-
description: "Which macro classes to detect (empty = all three).",
|
|
1356
|
-
options: [
|
|
1357
|
-
{
|
|
1358
|
-
value: "person",
|
|
1359
|
-
label: "Person"
|
|
1360
|
-
},
|
|
1361
|
-
{
|
|
1362
|
-
value: "vehicle",
|
|
1363
|
-
label: "Vehicle"
|
|
1364
|
-
},
|
|
1365
|
-
{
|
|
1366
|
-
value: "animal",
|
|
1367
|
-
label: "Animal"
|
|
1368
|
-
}
|
|
1369
|
-
],
|
|
1370
|
-
default: [
|
|
1371
|
-
"person",
|
|
1372
|
-
"vehicle",
|
|
1373
|
-
"animal"
|
|
1374
|
-
]
|
|
1375
|
-
},
|
|
1376
|
-
{
|
|
1377
|
-
type: "slider",
|
|
1378
|
-
key: "minConfidencePerson",
|
|
1379
|
-
label: "Min Confidence — Person",
|
|
1380
|
-
description: "Drop person predictions below this score.",
|
|
1381
|
-
min: 0,
|
|
1382
|
-
max: 1,
|
|
1383
|
-
step: .05,
|
|
1384
|
-
default: .5,
|
|
1385
|
-
showValue: true
|
|
1386
|
-
},
|
|
1387
|
-
{
|
|
1388
|
-
type: "slider",
|
|
1389
|
-
key: "minConfidenceVehicle",
|
|
1390
|
-
label: "Min Confidence — Vehicle",
|
|
1391
|
-
description: "Drop vehicle predictions below this score.",
|
|
1392
|
-
min: 0,
|
|
1393
|
-
max: 1,
|
|
1394
|
-
step: .05,
|
|
1395
|
-
default: .5,
|
|
1396
|
-
showValue: true
|
|
1397
|
-
},
|
|
1398
|
-
{
|
|
1399
|
-
type: "slider",
|
|
1400
|
-
key: "minConfidenceAnimal",
|
|
1401
|
-
label: "Min Confidence — Animal",
|
|
1402
|
-
description: "Drop animal predictions below this score.",
|
|
1403
|
-
min: 0,
|
|
1404
|
-
max: 1,
|
|
1405
|
-
step: .05,
|
|
1406
|
-
default: .5,
|
|
1407
|
-
showValue: true
|
|
1408
|
-
}
|
|
1409
|
-
];
|
|
1410
|
-
}
|
|
1411
|
-
};
|
|
1412
|
-
var AudioClassifierStep = class {
|
|
1413
|
-
definition = {
|
|
1414
|
-
id: "audio-classifier",
|
|
1415
|
-
name: "Audio Classifier",
|
|
1416
|
-
slot: "audio-classifier",
|
|
1417
|
-
postprocessor: "yamnet",
|
|
1418
|
-
extractMode: "full-frame",
|
|
1419
|
-
inputClasses: null,
|
|
1420
|
-
outputClasses: ["audio"],
|
|
1421
|
-
models: [...AUDIO_CLASSIFIER_MODELS],
|
|
1422
|
-
defaultModelId: "yamnet-onnx",
|
|
1423
|
-
defaultModelIdByFormat: { coreml: "apple-soundanalysis" },
|
|
1424
|
-
enabledByDefault: true,
|
|
1425
|
-
defaultConfidence: .3
|
|
1426
|
-
};
|
|
1427
|
-
getConfigSchema() {
|
|
1428
|
-
return [{
|
|
1429
|
-
type: "multiselect",
|
|
1430
|
-
key: "enabledAudioClasses",
|
|
1431
|
-
label: "Audio Classes",
|
|
1432
|
-
description: "Which audio macro classes to surface (empty = all).",
|
|
1433
|
-
options: require_dist.AUDIO_MACRO_LABELS.map((l) => ({
|
|
1434
|
-
value: l.id,
|
|
1435
|
-
label: `${l.icon ?? ""} ${l.name}`.trim()
|
|
1436
|
-
})),
|
|
1437
|
-
default: [
|
|
1438
|
-
"scream",
|
|
1439
|
-
"crying",
|
|
1440
|
-
"dog",
|
|
1441
|
-
"alarm",
|
|
1442
|
-
"doorbell",
|
|
1443
|
-
"glass_breaking",
|
|
1444
|
-
"gunshot",
|
|
1445
|
-
"siren",
|
|
1446
|
-
"footsteps"
|
|
1447
|
-
]
|
|
1448
|
-
}, {
|
|
1449
|
-
type: "slider",
|
|
1450
|
-
key: "minConfidence",
|
|
1451
|
-
label: "Min Confidence",
|
|
1452
|
-
description: "Drop predictions whose score is below this threshold.",
|
|
1453
|
-
default: .3,
|
|
1454
|
-
min: 0,
|
|
1455
|
-
max: 1,
|
|
1456
|
-
step: .05,
|
|
1457
|
-
showValue: true
|
|
1458
|
-
}];
|
|
1459
|
-
}
|
|
1460
|
-
};
|
|
1461
|
-
var AnimalClassifierStep = class {
|
|
1462
|
-
definition = {
|
|
1463
|
-
id: "animal-classifier",
|
|
1464
|
-
name: "Animal Classifier",
|
|
1465
|
-
slot: "classifier",
|
|
1466
|
-
postprocessor: "softmax",
|
|
1467
|
-
extractMode: "crop-roi",
|
|
1468
|
-
inputClasses: ["animal"],
|
|
1469
|
-
outputClasses: ["animal-type"],
|
|
1470
|
-
models: [...ANIMAL_CLASSIFIER_MODELS],
|
|
1471
|
-
defaultModelId: "animals-10",
|
|
1472
|
-
enabledByDefault: false,
|
|
1473
|
-
defaultConfidence: .2,
|
|
1474
|
-
labels: [...ANIMAL_10_LABELS]
|
|
1475
|
-
};
|
|
1476
|
-
getConfigSchema() {
|
|
1477
|
-
return [{
|
|
1478
|
-
type: "multiselect",
|
|
1479
|
-
key: "enabledClasses",
|
|
1480
|
-
label: "Species",
|
|
1481
|
-
description: "Which animal species to keep (empty = all). The classifier still scores every label but only the selected classes are returned on the detection.",
|
|
1482
|
-
options: ANIMAL_10_LABELS.map((l) => ({
|
|
1483
|
-
value: l,
|
|
1484
|
-
label: l
|
|
1485
|
-
})),
|
|
1486
|
-
default: []
|
|
1487
|
-
}, {
|
|
1488
|
-
type: "slider",
|
|
1489
|
-
key: "minConfidence",
|
|
1490
|
-
label: "Min Confidence",
|
|
1491
|
-
description: "Drop classifications whose score is below this threshold.",
|
|
1492
|
-
default: this.definition.defaultConfidence,
|
|
1493
|
-
min: 0,
|
|
1494
|
-
max: 1,
|
|
1495
|
-
step: .05,
|
|
1496
|
-
showValue: true
|
|
1497
|
-
}];
|
|
1498
|
-
}
|
|
1499
|
-
};
|
|
1500
|
-
var ClassifierWithMinConfidence = class extends PipelineStepBase {
|
|
1501
|
-
getConfigSchema() {
|
|
1502
|
-
return [{
|
|
1503
|
-
type: "slider",
|
|
1504
|
-
key: "minConfidence",
|
|
1505
|
-
label: "Min Confidence",
|
|
1506
|
-
description: "Drop classifications whose score is below this threshold.",
|
|
1507
|
-
default: this.definition.defaultConfidence,
|
|
1508
|
-
min: 0,
|
|
1509
|
-
max: 1,
|
|
1510
|
-
step: .05,
|
|
1511
|
-
showValue: true
|
|
1512
|
-
}];
|
|
1513
|
-
}
|
|
1514
|
-
};
|
|
1515
|
-
var STEP_FACE_DETECTION = new PipelineStepBase({
|
|
1516
|
-
id: "face-detection",
|
|
1517
|
-
name: "Face Detection",
|
|
1518
|
-
slot: "cropper",
|
|
1519
|
-
postprocessor: "scrfd",
|
|
1520
|
-
extractMode: "crop-roi",
|
|
1521
|
-
inputClasses: ["person"],
|
|
1522
|
-
outputClasses: ["face"],
|
|
1523
|
-
models: [...FACE_DETECTION_MODELS],
|
|
1524
|
-
defaultModelId: "scrfd-2.5g",
|
|
1525
|
-
defaultConfidence: .5,
|
|
1526
|
-
defaultMinParentScore: .7
|
|
1527
|
-
});
|
|
1528
|
-
var STEP_FACE_EMBEDDING = new PipelineStepBase({
|
|
1529
|
-
id: "face-embedding",
|
|
1530
|
-
name: "Face Embedding",
|
|
1531
|
-
slot: "classifier",
|
|
1532
|
-
postprocessor: "arcface",
|
|
1533
|
-
extractMode: "crop-roi",
|
|
1534
|
-
inputClasses: ["face"],
|
|
1535
|
-
outputClasses: ["identity"],
|
|
1536
|
-
models: [...FACE_EMBEDDING_MODELS],
|
|
1537
|
-
defaultModelId: "arcface-r100",
|
|
1538
|
-
defaultConfidence: 0
|
|
1539
|
-
});
|
|
1540
|
-
var STEP_CLIP_EMBEDDING = new PipelineStepBase({
|
|
1541
|
-
id: "clip-embedding",
|
|
1542
|
-
name: "CLIP Embedding",
|
|
1543
|
-
slot: "classifier",
|
|
1544
|
-
postprocessor: "clip",
|
|
1545
|
-
extractMode: "crop-roi",
|
|
1546
|
-
inputClasses: [
|
|
1547
|
-
"person",
|
|
1548
|
-
"vehicle",
|
|
1549
|
-
"animal"
|
|
1550
|
-
],
|
|
1551
|
-
outputClasses: ["embedding"],
|
|
1552
|
-
models: [...CLIP_EMBEDDING_MODELS],
|
|
1553
|
-
defaultModelId: "mobileclip-s1",
|
|
1554
|
-
enabledByDefault: true,
|
|
1555
|
-
backfillIntoExistingOverrides: true,
|
|
1556
|
-
defaultConfidence: 0,
|
|
1557
|
-
defaultMinParentScore: .4,
|
|
1558
|
-
group: "CLIP"
|
|
1559
|
-
});
|
|
1560
|
-
var STEP_PLATE_DETECTION = new PipelineStepBase({
|
|
1561
|
-
id: "plate-detection",
|
|
1562
|
-
name: "Plate Detection",
|
|
1563
|
-
slot: "cropper",
|
|
1564
|
-
postprocessor: "yolo",
|
|
1565
|
-
extractMode: "crop-roi",
|
|
1566
|
-
inputClasses: ["vehicle"],
|
|
1567
|
-
outputClasses: ["plate"],
|
|
1568
|
-
models: [...PLATE_DETECTION_MODELS],
|
|
1569
|
-
defaultModelId: "yolov8n-plate",
|
|
1570
|
-
defaultConfidence: .5,
|
|
1571
|
-
defaultMinParentScore: .7,
|
|
1572
|
-
labels: ["plate"]
|
|
1573
|
-
});
|
|
1574
|
-
var STEP_PLATE_OCR = new PipelineStepBase({
|
|
1575
|
-
id: "plate-ocr",
|
|
1576
|
-
name: "Plate OCR",
|
|
1577
|
-
slot: "classifier",
|
|
1578
|
-
postprocessor: "ctc",
|
|
1579
|
-
extractMode: "crop-roi",
|
|
1580
|
-
inputClasses: ["plate"],
|
|
1581
|
-
outputClasses: ["plate-text"],
|
|
1582
|
-
models: [...PLATE_OCR_MODELS],
|
|
1583
|
-
defaultModelId: "vgg-english-g2",
|
|
1584
|
-
defaultConfidence: 0,
|
|
1585
|
-
charset: [...VGG_G2_CHARSET]
|
|
1586
|
-
});
|
|
1587
|
-
var STEP_BIRD_CLASSIFIER = new ClassifierWithMinConfidence({
|
|
1588
|
-
id: "bird-classifier",
|
|
1589
|
-
name: "Bird Classifier",
|
|
1590
|
-
slot: "classifier",
|
|
1591
|
-
postprocessor: "softmax",
|
|
1592
|
-
extractMode: "crop-roi",
|
|
1593
|
-
inputClasses: ["animal"],
|
|
1594
|
-
outputClasses: ["species"],
|
|
1595
|
-
models: [...BIRD_CLASSIFIER_MODELS],
|
|
1596
|
-
defaultModelId: "bird-nabirds-404",
|
|
1597
|
-
enabledByDefault: false,
|
|
1598
|
-
defaultConfidence: .2
|
|
1599
|
-
});
|
|
1600
|
-
var STEP_VEHICLE_CLASSIFIER = new ClassifierWithMinConfidence({
|
|
1601
|
-
id: "vehicle-classifier",
|
|
1602
|
-
name: "Vehicle Classifier",
|
|
1603
|
-
slot: "classifier",
|
|
1604
|
-
postprocessor: "softmax",
|
|
1605
|
-
extractMode: "crop-roi",
|
|
1606
|
-
inputClasses: ["vehicle"],
|
|
1607
|
-
outputClasses: ["vehicle-type"],
|
|
1608
|
-
models: [...VEHICLE_CLASSIFIER_MODELS],
|
|
1609
|
-
defaultModelId: "vehicle-type-efficientnet",
|
|
1610
|
-
enabledByDefault: false,
|
|
1611
|
-
defaultConfidence: .3
|
|
1612
|
-
});
|
|
1613
|
-
var STEP_SEGMENTATION = new PipelineStepBase({
|
|
1614
|
-
id: "segmentation",
|
|
1615
|
-
name: "Segmentation",
|
|
1616
|
-
slot: "refiner",
|
|
1617
|
-
postprocessor: "saliency",
|
|
1618
|
-
extractMode: "crop-roi",
|
|
1619
|
-
inputClasses: null,
|
|
1620
|
-
outputClasses: ["mask"],
|
|
1621
|
-
models: [...SEGMENTATION_REFINER_MODELS],
|
|
1622
|
-
defaultModelId: "u2netp",
|
|
1623
|
-
enabledByDefault: false,
|
|
1624
|
-
defaultConfidence: 0,
|
|
1625
|
-
group: "Segmentation"
|
|
1626
|
-
});
|
|
1627
|
-
new PipelineStepBase({
|
|
1628
|
-
id: "instance-segmentation",
|
|
1629
|
-
name: "Instance Segmentation",
|
|
1630
|
-
slot: "refiner",
|
|
1631
|
-
postprocessor: "yolo-seg",
|
|
1632
|
-
extractMode: "full-frame",
|
|
1633
|
-
inputClasses: null,
|
|
1634
|
-
outputClasses: ["mask"],
|
|
1635
|
-
models: [...INSTANCE_SEGMENTATION_MODELS],
|
|
1636
|
-
defaultModelId: "yolo26n-seg",
|
|
1637
|
-
enabledByDefault: false,
|
|
1638
|
-
defaultConfidence: .25,
|
|
1639
|
-
labels: require_dist.COCO_80_LABELS.map((l) => l.id),
|
|
1640
|
-
classMap: require_dist.COCO_TO_MACRO,
|
|
1641
|
-
group: "Segmentation"
|
|
1642
|
-
});
|
|
1643
|
-
var STEP_OBJECT_DETECTION_INSTANCE = new ObjectDetectionStep();
|
|
1644
|
-
var STEP_AUDIO_CLASSIFIER_INSTANCE = new AudioClassifierStep();
|
|
1645
|
-
var ALL_PIPELINE_STEPS = [
|
|
1646
|
-
STEP_OBJECT_DETECTION_INSTANCE,
|
|
1647
|
-
STEP_FACE_DETECTION,
|
|
1648
|
-
STEP_FACE_EMBEDDING,
|
|
1649
|
-
STEP_CLIP_EMBEDDING,
|
|
1650
|
-
STEP_PLATE_DETECTION,
|
|
1651
|
-
STEP_PLATE_OCR,
|
|
1652
|
-
new AnimalClassifierStep(),
|
|
1653
|
-
STEP_BIRD_CLASSIFIER,
|
|
1654
|
-
STEP_VEHICLE_CLASSIFIER,
|
|
1655
|
-
STEP_SEGMENTATION,
|
|
1656
|
-
STEP_AUDIO_CLASSIFIER_INSTANCE
|
|
1657
|
-
];
|
|
1658
|
-
/** Compat: flat array of StepDefinition for existing consumers */
|
|
1659
|
-
var ALL_STEPS = ALL_PIPELINE_STEPS.map((s) => s.definition);
|
|
1660
|
-
var STEP_MAP = new Map(ALL_PIPELINE_STEPS.map((s) => [s.definition.id, s]));
|
|
1661
|
-
/**
|
|
1662
|
-
* Look up a pipeline step by ID (class instance with getConfigSchema).
|
|
1663
|
-
* @throws if the step ID is not registered.
|
|
1664
|
-
*/
|
|
1665
|
-
function getStep(stepId) {
|
|
1666
|
-
const step = STEP_MAP.get(stepId);
|
|
1667
|
-
if (!step) throw new Error(`Unknown pipeline step: "${stepId}". Available: ${ALL_PIPELINE_STEPS.map((s) => s.definition.id).join(", ")}`);
|
|
1668
|
-
return step;
|
|
1669
|
-
}
|
|
1670
|
-
/**
|
|
1671
|
-
* Look up a step definition by ID (compat shortcut).
|
|
1672
|
-
* @throws if the step ID is not registered.
|
|
1673
|
-
*/
|
|
1674
|
-
function getStepDefinition(stepId) {
|
|
1675
|
-
return getStep(stepId).definition;
|
|
1676
|
-
}
|
|
1677
|
-
/**
|
|
1678
|
-
* Get the default model ID for a step given the current model format.
|
|
1679
|
-
*
|
|
1680
|
-
* Resolution order:
|
|
1681
|
-
* 1. `def.defaultModelIdByFormat?.[format]` — the step's declared
|
|
1682
|
-
* per-format preference — if that model exists in `def.models` AND
|
|
1683
|
-
* has a build for `format`.
|
|
1684
|
-
* 2. `def.defaultModelId` — the step's plain declared default — if it
|
|
1685
|
-
* exists in `def.models` AND has a build for `format`.
|
|
1686
|
-
* 3. The smallest-by-size model among those with a `format` build
|
|
1687
|
-
* (legacy fallback, preserved for steps/formats with no declared
|
|
1688
|
-
* preference reachable).
|
|
1689
|
-
* 4. `def.defaultModelId` unchanged, when ZERO models have a `format`
|
|
1690
|
-
* build — an unloadable case flagged elsewhere, not resolved here.
|
|
1691
|
-
*/
|
|
1692
|
-
function getDefaultModelForFormat(stepId, format) {
|
|
1693
|
-
const def = getStepDefinition(stepId);
|
|
1694
|
-
const hasFormatBuild = (modelId) => def.models.find((m) => m.id === modelId)?.formats[format] !== void 0;
|
|
1695
|
-
const declaredForFormat = def.defaultModelIdByFormat?.[format];
|
|
1696
|
-
if (declaredForFormat !== void 0 && hasFormatBuild(declaredForFormat)) return declaredForFormat;
|
|
1697
|
-
if (hasFormatBuild(def.defaultModelId)) return def.defaultModelId;
|
|
1698
|
-
const available = def.models.filter((m) => m.formats[format] && m.legacy !== true);
|
|
1699
|
-
if (available.length === 0) return def.defaultModelId;
|
|
1700
|
-
return [...available].toSorted((a, b) => {
|
|
1701
|
-
return (a.formats[format]?.sizeMB ?? Infinity) - (b.formats[format]?.sizeMB ?? Infinity);
|
|
1702
|
-
})[0].id;
|
|
1703
|
-
}
|
|
1704
|
-
/**
|
|
1705
|
-
* The single node-local authority for turning a CHOSEN model (or none) into a
|
|
1706
|
-
* concrete model that has a build for this node's engine `format`. Fuses the
|
|
1707
|
-
* two previously-duplicated decisions (orchestrator `pickDefaultModelId` +
|
|
1708
|
-
* provider `substituteIncompatibleModels`):
|
|
1709
|
-
*
|
|
1710
|
-
* - chosen === null → the addon's default model for `format`.
|
|
1711
|
-
* - chosen is a catalog model → keep it if it has a `format` build; else
|
|
1712
|
-
* the addon's default model for `format`
|
|
1713
|
-
* (a substitution — the caller surfaces it).
|
|
1714
|
-
* - chosen is NOT in the catalog (custom/unknown) → returned unchanged; the
|
|
1715
|
-
* operator owns a custom model's format compat.
|
|
1716
|
-
* - unknown stepId → chosen returned unchanged (never throws).
|
|
1717
|
-
*/
|
|
1718
|
-
function resolveModelForFormat(stepId, chosenModelId, format) {
|
|
1719
|
-
let def;
|
|
1720
|
-
try {
|
|
1721
|
-
def = getStepDefinition(stepId);
|
|
1722
|
-
} catch {
|
|
1723
|
-
return chosenModelId ?? "";
|
|
1724
|
-
}
|
|
1725
|
-
if (chosenModelId === null) return getDefaultModelForFormat(stepId, format);
|
|
1726
|
-
const entry = def.models.find((m) => m.id === chosenModelId);
|
|
1727
|
-
if (!entry) return chosenModelId;
|
|
1728
|
-
if (entry.formats[format]) return chosenModelId;
|
|
1729
|
-
return getDefaultModelForFormat(stepId, format);
|
|
1730
|
-
}
|
|
1731
|
-
//#endregion
|
|
1732
302
|
//#region src/detection-pipeline/default-detection-model.ts
|
|
1733
303
|
/** The object-detection step id — the only slot this resolver applies to. */
|
|
1734
304
|
var OBJECT_DETECTION_STEP_ID = "object-detection";
|
|
@@ -1788,7 +358,7 @@ function classifyAccelerator(backend, device) {
|
|
|
1788
358
|
* missing-build fallback branch is unit-testable without a live catalog —
|
|
1789
359
|
* mirrors `collectZeroBuildIssues`' injection seam.
|
|
1790
360
|
*/
|
|
1791
|
-
function resolveDefaultDetectionModel(backend, device, format, getStepDef = getStepDefinition) {
|
|
361
|
+
function resolveDefaultDetectionModel(backend, device, format, getStepDef = require_step_definitions.getStepDefinition) {
|
|
1792
362
|
let def;
|
|
1793
363
|
try {
|
|
1794
364
|
def = getStepDef(OBJECT_DETECTION_STEP_ID);
|
|
@@ -2819,7 +1389,7 @@ var EngineFactory = class {
|
|
|
2819
1389
|
await this.poolManager.applyConfig(steps);
|
|
2820
1390
|
}
|
|
2821
1391
|
buildPoolModelConfig(stepId, modelId, poolRuntime) {
|
|
2822
|
-
const def = getStepDefinition(stepId);
|
|
1392
|
+
const def = require_step_definitions.getStepDefinition(stepId);
|
|
2823
1393
|
const modelEntry = def.models.find((m) => m.id === modelId);
|
|
2824
1394
|
if (!modelEntry) throw new Error(`Model "${modelId}" not found in step "${stepId}" catalog`);
|
|
2825
1395
|
const format = RUNTIME_TO_FORMAT[poolRuntime];
|
|
@@ -3801,7 +2371,8 @@ async function buildAlignedFaceCrop(args) {
|
|
|
3801
2371
|
const native = await args.nativeCropProvider(roi, args.nativeMaxWidth);
|
|
3802
2372
|
if (native && native.width >= 2 && native.height >= 2 && native.bytes.length >= native.width * native.height * 3) return {
|
|
3803
2373
|
...await alignFaceCropFromRgb(native, region, args.landmarksImageSpace, { outSize: args.outSize }),
|
|
3804
|
-
source: "native"
|
|
2374
|
+
source: "native",
|
|
2375
|
+
nativeFaceShortSidePx: nativeFaceShortSide(args.faceBbox, region, native)
|
|
3805
2376
|
};
|
|
3806
2377
|
} catch {}
|
|
3807
2378
|
return {
|
|
@@ -3810,6 +2381,22 @@ async function buildAlignedFaceCrop(args) {
|
|
|
3810
2381
|
};
|
|
3811
2382
|
}
|
|
3812
2383
|
/**
|
|
2384
|
+
* Short side (px) of `faceBbox` (in detection space) re-measured in the NATIVE
|
|
2385
|
+
* crop's resolution. The native crop covers `region` (detection-space padded
|
|
2386
|
+
* region) rendered at `native.width × native.height` native pixels, so the
|
|
2387
|
+
* per-axis scale `native / region` maps the detection face size to its native
|
|
2388
|
+
* size. This is the size an embedder actually sees, so the gate uses it.
|
|
2389
|
+
*/
|
|
2390
|
+
function nativeFaceShortSide(faceBbox, region, native) {
|
|
2391
|
+
const regionW = Math.max(1, region.right - region.left);
|
|
2392
|
+
const regionH = Math.max(1, region.bottom - region.top);
|
|
2393
|
+
const scaleX = native.width / regionW;
|
|
2394
|
+
const scaleY = native.height / regionH;
|
|
2395
|
+
const faceW = (faceBbox[2] - faceBbox[0]) * scaleX;
|
|
2396
|
+
const faceH = (faceBbox[3] - faceBbox[1]) * scaleY;
|
|
2397
|
+
return Math.min(faceW, faceH);
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
3813
2400
|
* Produce an aligned 112x112 JPEG of a face from the full-frame JPEG and the
|
|
3814
2401
|
* face's 5 landmarks (in absolute image-space coordinates). Decodes a padded
|
|
3815
2402
|
* region around the face bbox to raw RGB, warps to the ArcFace template, and
|
|
@@ -4037,7 +2624,8 @@ function buildFrameResult(input) {
|
|
|
4037
2624
|
...embedding !== void 0 ? {
|
|
4038
2625
|
embedding,
|
|
4039
2626
|
...embeddingModelId !== void 0 ? { embeddingModelId } : {}
|
|
4040
|
-
} : {}
|
|
2627
|
+
} : {},
|
|
2628
|
+
...m.faceAlignedCrop !== void 0 ? { faceAlignedCrop: m.faceAlignedCrop } : {}
|
|
4041
2629
|
};
|
|
4042
2630
|
if (input.debug) {
|
|
4043
2631
|
const cleanDebug = pruneUndefined({
|
|
@@ -4118,7 +2706,8 @@ function toMutableRootDetection(det, rootStep, idGen, rootStepLatencyMs) {
|
|
|
4118
2706
|
mask: det.mask,
|
|
4119
2707
|
maskWidth: det.maskWidth,
|
|
4120
2708
|
maskHeight: det.maskHeight
|
|
4121
|
-
} : {}
|
|
2709
|
+
} : {},
|
|
2710
|
+
...det.landmarks !== void 0 ? { landmarks: det.landmarks } : {}
|
|
4122
2711
|
};
|
|
4123
2712
|
}
|
|
4124
2713
|
//#endregion
|
|
@@ -4237,6 +2826,14 @@ function formatTopResult(output) {
|
|
|
4237
2826
|
*/
|
|
4238
2827
|
var DEFAULT_MIN_FACE_SIZE_PX = 28;
|
|
4239
2828
|
/**
|
|
2829
|
+
* Cheap pre-native floor (px, detection space): below this a face is treated as
|
|
2830
|
+
* genuinely degenerate — SCRFD landmarks are unreliable and even a large native
|
|
2831
|
+
* upscale can't rescue it — so it is skipped WITHOUT paying a native-crop
|
|
2832
|
+
* round-trip. Above the floor, the real {@link DEFAULT_MIN_FACE_SIZE_PX} gate is
|
|
2833
|
+
* evaluated on the NATIVE face size (see the face branch of `executeChildren`).
|
|
2834
|
+
*/
|
|
2835
|
+
var MIN_FACE_DETECTION_FLOOR_PX = 6;
|
|
2836
|
+
/**
|
|
4240
2837
|
* Cap (px) on the width of the NATIVE face crop fetched for embedding (design
|
|
4241
2838
|
* B). The arcface input is a fixed 112² warp, so a wider native crop buys no
|
|
4242
2839
|
* embedding quality past a modest margin but does inflate the per-face transport
|
|
@@ -4244,6 +2841,17 @@ var DEFAULT_MIN_FACE_SIZE_PX = 28;
|
|
|
4244
2841
|
* above the downscaled detection resolution while bounding the crop payload.
|
|
4245
2842
|
*/
|
|
4246
2843
|
var NATIVE_FACE_CROP_MAX_WIDTH = 320;
|
|
2844
|
+
/**
|
|
2845
|
+
* StepOutput kinds that synthesize a full-frame detection when they run at
|
|
2846
|
+
* the tree ROOT (see `synthesizeRootDetection`) — classifier/embedding steps
|
|
2847
|
+
* promoted to root by `pipelineRunner.runDetailSubtree` (task 6b), e.g.
|
|
2848
|
+
* `clip-embedding`, `animal-classifier`. Detector (`'detections'`) roots take
|
|
2849
|
+
* the normal path; `'text'`/`'mask'` roots are out of scope and still
|
|
2850
|
+
* `continue` with no output, matching pre-existing behaviour.
|
|
2851
|
+
*/
|
|
2852
|
+
function isEnrichmentOutput(output) {
|
|
2853
|
+
return output.kind === "classifications" || output.kind === "embedding";
|
|
2854
|
+
}
|
|
4247
2855
|
var PipelineExecutor = class {
|
|
4248
2856
|
opts;
|
|
4249
2857
|
constructor(opts) {
|
|
@@ -4252,15 +2860,39 @@ var PipelineExecutor = class {
|
|
|
4252
2860
|
/** Per-key last-warn timestamps, so a persistently-failing/skipping child
|
|
4253
2861
|
* step surfaces a diagnostic without spamming the log every frame. */
|
|
4254
2862
|
warnThrottleAt = /* @__PURE__ */ new Map();
|
|
4255
|
-
throttledWarn(key, everyMs, message, meta) {
|
|
2863
|
+
throttledWarn(key, everyMs, message, meta, deviceId) {
|
|
4256
2864
|
const logger = this.opts.logger;
|
|
4257
2865
|
if (!logger) return;
|
|
4258
2866
|
const now = Date.now();
|
|
4259
2867
|
if (now - (this.warnThrottleAt.get(key) ?? 0) < everyMs) return;
|
|
4260
2868
|
this.warnThrottleAt.set(key, now);
|
|
2869
|
+
if (deviceId !== void 0) {
|
|
2870
|
+
logger.warn(message, {
|
|
2871
|
+
tags: { deviceId },
|
|
2872
|
+
meta
|
|
2873
|
+
});
|
|
2874
|
+
return;
|
|
2875
|
+
}
|
|
4261
2876
|
logger.warn(message, { meta });
|
|
4262
2877
|
}
|
|
4263
2878
|
/**
|
|
2879
|
+
* Surface WHY a face embedding was skipped — a detected face simply too small
|
|
2880
|
+
* (distance / night) is the common silent cause of "faces stopped collecting".
|
|
2881
|
+
* Reports the detection-space short side AND, when the skip was decided on the
|
|
2882
|
+
* native crop, the NATIVE face size so an operator sees the size that actually
|
|
2883
|
+
* gated. Throttled so it isn't per-frame spam.
|
|
2884
|
+
*/
|
|
2885
|
+
warnFaceTooSmall(child, detShortSidePx, minFaceSizePx, nativeFaceShortSidePx, deviceId) {
|
|
2886
|
+
this.throttledWarn(`face-small:${child.stepId}:${deviceId}`, 3e4, "face detected but too small to embed — skipping", {
|
|
2887
|
+
step: child.stepId,
|
|
2888
|
+
model: child.modelId,
|
|
2889
|
+
faceShortSidePx: Math.round(detShortSidePx),
|
|
2890
|
+
minFaceSizePx,
|
|
2891
|
+
gatedOn: nativeFaceShortSidePx === void 0 ? "detection" : "native",
|
|
2892
|
+
...nativeFaceShortSidePx === void 0 ? {} : { nativeFaceShortSidePx: Math.round(nativeFaceShortSidePx) }
|
|
2893
|
+
}, deviceId);
|
|
2894
|
+
}
|
|
2895
|
+
/**
|
|
4264
2896
|
* Execute the full pipeline tree against a frame.
|
|
4265
2897
|
*
|
|
4266
2898
|
* `rootInput` carries the frame in its source representation
|
|
@@ -4296,7 +2928,27 @@ var PipelineExecutor = class {
|
|
|
4296
2928
|
const rootStart = Date.now();
|
|
4297
2929
|
const rootOutput = await this.executeStep(rootStep, rootInput, imageWidth, imageHeight, "full-frame", void 0, void 0, traceBuilder, stepTimings, poolAgg);
|
|
4298
2930
|
const rootMs = Date.now() - rootStart;
|
|
4299
|
-
if (rootOutput.kind !== "detections")
|
|
2931
|
+
if (rootOutput.kind !== "detections") {
|
|
2932
|
+
if (isEnrichmentOutput(rootOutput)) {
|
|
2933
|
+
const mutable = this.synthesizeRootDetection(rootOutput, rootStep, idGen, rootMs, imageWidth, imageHeight);
|
|
2934
|
+
applyChildOutput(mutable, rootStep, rootOutput, rootMs, ctx);
|
|
2935
|
+
try {
|
|
2936
|
+
await this.executeChildren(rootStep.children, mutable, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg, runOpts?.plane, deviceId, nativeFaceCropProvider);
|
|
2937
|
+
} catch (err) {
|
|
2938
|
+
this.opts.logger?.warn("Pipeline child execution failed — keeping parent detection", {
|
|
2939
|
+
tags: { deviceId },
|
|
2940
|
+
meta: {
|
|
2941
|
+
rootStepId: rootStep.stepId,
|
|
2942
|
+
parentClass: mutable.macroClass,
|
|
2943
|
+
parentScore: mutable.score,
|
|
2944
|
+
error: require_dist.errMsg(err)
|
|
2945
|
+
}
|
|
2946
|
+
});
|
|
2947
|
+
}
|
|
2948
|
+
firstLevel.push(mutable);
|
|
2949
|
+
}
|
|
2950
|
+
continue;
|
|
2951
|
+
}
|
|
4300
2952
|
for (const det of rootOutput.detections) {
|
|
4301
2953
|
const mutable = toMutableRootDetection(det, rootStep, idGen, rootMs);
|
|
4302
2954
|
if (rootStep.definition.classMap) {
|
|
@@ -4311,7 +2963,7 @@ var PipelineExecutor = class {
|
|
|
4311
2963
|
continue;
|
|
4312
2964
|
}
|
|
4313
2965
|
try {
|
|
4314
|
-
await this.executeChildren(rootStep.children, mutable, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg, nativeFaceCropProvider);
|
|
2966
|
+
await this.executeChildren(rootStep.children, mutable, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg, runOpts?.plane, deviceId, nativeFaceCropProvider);
|
|
4315
2967
|
} catch (err) {
|
|
4316
2968
|
this.opts.logger?.warn("Pipeline child execution failed — keeping parent detection", {
|
|
4317
2969
|
tags: { deviceId },
|
|
@@ -4347,6 +2999,29 @@ var PipelineExecutor = class {
|
|
|
4347
2999
|
trace: traceBuilder.build(firstLevel.length + details.length)
|
|
4348
3000
|
};
|
|
4349
3001
|
}
|
|
3002
|
+
/**
|
|
3003
|
+
* Build a full-frame `MutableObjectDetection` for a ROOT step whose engine
|
|
3004
|
+
* output is a classification/embedding rather than detections — there is
|
|
3005
|
+
* no detector to bound a smaller box, so the synthesized detection covers
|
|
3006
|
+
* the entire input frame (`bbox = [0, 0, imageWidth, imageHeight]`).
|
|
3007
|
+
* `macroClass` is the step's own output semantic (`outputClasses[0]`,
|
|
3008
|
+
* falling back to `inputClasses[0]` when `outputClasses` is empty, then
|
|
3009
|
+
* the step id as a last resort so the field is never empty). `score` is
|
|
3010
|
+
* the output's own confidence when it has one (the classifier's top-1
|
|
3011
|
+
* score) — an embedding carries no confidence, so it defaults to 1.
|
|
3012
|
+
*/
|
|
3013
|
+
synthesizeRootDetection(output, rootStep, idGen, rootStepLatencyMs, imageWidth, imageHeight) {
|
|
3014
|
+
return toMutableRootDetection({
|
|
3015
|
+
class: rootStep.definition.outputClasses[0] ?? rootStep.definition.inputClasses?.[0] ?? rootStep.stepId,
|
|
3016
|
+
score: output.kind === "classifications" ? output.classifications[0]?.score ?? 1 : 1,
|
|
3017
|
+
bbox: [
|
|
3018
|
+
0,
|
|
3019
|
+
0,
|
|
3020
|
+
imageWidth,
|
|
3021
|
+
imageHeight
|
|
3022
|
+
]
|
|
3023
|
+
}, rootStep, idGen, rootStepLatencyMs);
|
|
3024
|
+
}
|
|
4350
3025
|
async executeStep(step, input, inputWidth, inputHeight, inputType, _parentBbox, parentClass, traceBuilder, stepTimings, poolAgg) {
|
|
4351
3026
|
const preprocessStart = Date.now();
|
|
4352
3027
|
const preprocessMs = Date.now() - preprocessStart;
|
|
@@ -4413,8 +3088,9 @@ var PipelineExecutor = class {
|
|
|
4413
3088
|
});
|
|
4414
3089
|
return output;
|
|
4415
3090
|
}
|
|
4416
|
-
async executeChildren(children, parentDetection, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg, nativeFaceCropProvider) {
|
|
3091
|
+
async executeChildren(children, parentDetection, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg, plane, deviceId, nativeFaceCropProvider) {
|
|
4417
3092
|
for (const child of children) {
|
|
3093
|
+
if (plane === "frame" && child.definition.inputClasses !== null) continue;
|
|
4418
3094
|
if (!this.matchesInputClasses(parentDetection.macroClass, child.inputClasses)) continue;
|
|
4419
3095
|
const minParentScore = child.settings?.minParentScore ?? child.definition?.defaultMinParentScore;
|
|
4420
3096
|
if (typeof minParentScore === "number" && parentDetection.score < minParentScore) continue;
|
|
@@ -4428,18 +3104,17 @@ var PipelineExecutor = class {
|
|
|
4428
3104
|
let cropH;
|
|
4429
3105
|
if (modelEntry?.faceAlignment) {
|
|
4430
3106
|
const minFaceSize = typeof child.settings?.["minFaceSize"] === "number" ? child.settings["minFaceSize"] : DEFAULT_MIN_FACE_SIZE_PX;
|
|
4431
|
-
const
|
|
4432
|
-
if (
|
|
4433
|
-
this.
|
|
4434
|
-
step: child.stepId,
|
|
4435
|
-
model: child.modelId,
|
|
4436
|
-
faceShortSidePx: Math.round(faceShortSide),
|
|
4437
|
-
minFaceSizePx: minFaceSize
|
|
4438
|
-
});
|
|
3107
|
+
const detShortSide = bboxShortSide(parentDetection.bbox);
|
|
3108
|
+
if (detShortSide < MIN_FACE_DETECTION_FLOOR_PX) {
|
|
3109
|
+
this.warnFaceTooSmall(child, detShortSide, minFaceSize, void 0, deviceId);
|
|
4439
3110
|
continue;
|
|
4440
3111
|
}
|
|
4441
3112
|
const lms = parentDetection.landmarks;
|
|
4442
3113
|
if (lms && lms.length >= 5) {
|
|
3114
|
+
if (!nativeFaceCropProvider && detShortSide < minFaceSize) {
|
|
3115
|
+
this.warnFaceTooSmall(child, detShortSide, minFaceSize, void 0, deviceId);
|
|
3116
|
+
continue;
|
|
3117
|
+
}
|
|
4443
3118
|
const aligned = await buildAlignedFaceCrop({
|
|
4444
3119
|
fullFrameJpeg,
|
|
4445
3120
|
faceBbox: parentDetection.bbox,
|
|
@@ -4452,10 +3127,20 @@ var PipelineExecutor = class {
|
|
|
4452
3127
|
nativeMaxWidth: NATIVE_FACE_CROP_MAX_WIDTH
|
|
4453
3128
|
} : {}
|
|
4454
3129
|
});
|
|
3130
|
+
const gateShortSide = aligned.nativeFaceShortSidePx ?? detShortSide;
|
|
3131
|
+
if (gateShortSide < minFaceSize) {
|
|
3132
|
+
this.warnFaceTooSmall(child, detShortSide, minFaceSize, aligned.source === "native" ? gateShortSide : void 0, deviceId);
|
|
3133
|
+
continue;
|
|
3134
|
+
}
|
|
4455
3135
|
cropJpegBuf = aligned.jpeg;
|
|
4456
3136
|
cropW = aligned.width;
|
|
4457
3137
|
cropH = aligned.height;
|
|
3138
|
+
parentDetection.faceAlignedCrop = cropJpegBuf.toString("base64");
|
|
4458
3139
|
} else {
|
|
3140
|
+
if (detShortSide < minFaceSize) {
|
|
3141
|
+
this.warnFaceTooSmall(child, detShortSide, minFaceSize, void 0, deviceId);
|
|
3142
|
+
continue;
|
|
3143
|
+
}
|
|
4459
3144
|
const crop = await cropJpeg(fullFrameJpeg, parentDetection.bbox, imageWidth, imageHeight);
|
|
4460
3145
|
cropJpegBuf = crop.jpeg;
|
|
4461
3146
|
cropW = crop.width;
|
|
@@ -4485,15 +3170,15 @@ var PipelineExecutor = class {
|
|
|
4485
3170
|
y: l.y + py1
|
|
4486
3171
|
}));
|
|
4487
3172
|
}
|
|
4488
|
-
await this.executeChildren(child.children, detail, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg, nativeFaceCropProvider);
|
|
3173
|
+
await this.executeChildren(child.children, detail, fullFrameJpegProvider, imageWidth, imageHeight, traceBuilder, stepTimings, ctx, poolAgg, plane, deviceId, nativeFaceCropProvider);
|
|
4489
3174
|
}
|
|
4490
3175
|
}
|
|
4491
3176
|
} catch (err) {
|
|
4492
|
-
this.throttledWarn(`child-fail:${child.stepId}`, 15e3, "pipeline child step failed", {
|
|
3177
|
+
this.throttledWarn(`child-fail:${child.stepId}:${deviceId}`, 15e3, "pipeline child step failed", {
|
|
4493
3178
|
step: child.stepId,
|
|
4494
3179
|
model: child.modelId,
|
|
4495
3180
|
error: require_dist.errMsg(err)
|
|
4496
|
-
});
|
|
3181
|
+
}, deviceId);
|
|
4497
3182
|
}
|
|
4498
3183
|
}
|
|
4499
3184
|
}
|
|
@@ -4538,7 +3223,7 @@ function buildExecutableTree(steps, getEngine) {
|
|
|
4538
3223
|
return { roots: steps.filter((s) => s.enabled).filter((s) => s.slot !== "audio-classifier").map((s) => buildNode(s, getEngine)) };
|
|
4539
3224
|
}
|
|
4540
3225
|
function buildNode(step, getEngine) {
|
|
4541
|
-
const definition = getStepDefinition(step.addonId);
|
|
3226
|
+
const definition = require_step_definitions.getStepDefinition(step.addonId);
|
|
4542
3227
|
const engine = getEngine(step.addonId);
|
|
4543
3228
|
const children = (step.children ?? []).filter((c) => c.enabled).map((c) => buildNode(c, getEngine));
|
|
4544
3229
|
const mergedSettings = {
|
|
@@ -4563,7 +3248,7 @@ function buildNode(step, getEngine) {
|
|
|
4563
3248
|
* entered recursively. Fields without a declared default are skipped.
|
|
4564
3249
|
*/
|
|
4565
3250
|
function collectSchemaDefaults(stepId) {
|
|
4566
|
-
const schema = getStep(stepId).getConfigSchema();
|
|
3251
|
+
const schema = require_step_definitions.getStep(stepId).getConfigSchema();
|
|
4567
3252
|
const out = {};
|
|
4568
3253
|
walkFieldsForDefaults(schema, out);
|
|
4569
3254
|
return out;
|
|
@@ -4628,7 +3313,7 @@ function collectSubstitutions(steps, format) {
|
|
|
4628
3313
|
for (const step of steps) {
|
|
4629
3314
|
const chosen = step.modelId;
|
|
4630
3315
|
if (chosen != null) {
|
|
4631
|
-
const running = resolveModelForFormat(step.addonId, chosen, format);
|
|
3316
|
+
const running = require_step_definitions.resolveModelForFormat(step.addonId, chosen, format);
|
|
4632
3317
|
if (running !== chosen) result.push({
|
|
4633
3318
|
addonId: step.addonId,
|
|
4634
3319
|
chosen,
|
|
@@ -4654,7 +3339,7 @@ function collectSubstitutions(steps, format) {
|
|
|
4654
3339
|
* black-box test. Unknown/custom addonIds (no registered `StepDefinition`)
|
|
4655
3340
|
* are skipped, never thrown.
|
|
4656
3341
|
*/
|
|
4657
|
-
function collectZeroBuildIssues(steps, format, getStepDef = getStepDefinition) {
|
|
3342
|
+
function collectZeroBuildIssues(steps, format, getStepDef = require_step_definitions.getStepDefinition) {
|
|
4658
3343
|
const result = [];
|
|
4659
3344
|
for (const step of steps) {
|
|
4660
3345
|
let def;
|
|
@@ -4680,7 +3365,7 @@ function collectZeroBuildIssues(steps, format, getStepDef = getStepDefinition) {
|
|
|
4680
3365
|
* tests can exercise the unknown-addon branch with a fabricated resolver
|
|
4681
3366
|
* without `vi.mock`.
|
|
4682
3367
|
*/
|
|
4683
|
-
function collectUnknownAddonIssues(steps, getStepDef = getStepDefinition) {
|
|
3368
|
+
function collectUnknownAddonIssues(steps, getStepDef = require_step_definitions.getStepDefinition) {
|
|
4684
3369
|
const result = [];
|
|
4685
3370
|
for (const step of steps) {
|
|
4686
3371
|
try {
|
|
@@ -4720,13 +3405,13 @@ function resolveInputSteps(steps, format, engine) {
|
|
|
4720
3405
|
for (const s of steps) {
|
|
4721
3406
|
let def;
|
|
4722
3407
|
try {
|
|
4723
|
-
def = getStepDefinition(s.addonId);
|
|
3408
|
+
def = require_step_definitions.getStepDefinition(s.addonId);
|
|
4724
3409
|
} catch {
|
|
4725
3410
|
unknownAddonIds.push(s.addonId);
|
|
4726
3411
|
continue;
|
|
4727
3412
|
}
|
|
4728
3413
|
const chosenModelId = s.modelId ?? null;
|
|
4729
|
-
const runningModelId = chosenModelId === null && engine !== void 0 && s.addonId === "object-detection" ? resolveDefaultDetectionModel(engine.backend, engine.device, format) : resolveModelForFormat(s.addonId, chosenModelId, format);
|
|
3414
|
+
const runningModelId = chosenModelId === null && engine !== void 0 && s.addonId === "object-detection" ? resolveDefaultDetectionModel(engine.backend, engine.device, format) : require_step_definitions.resolveModelForFormat(s.addonId, chosenModelId, format);
|
|
4730
3415
|
if (chosenModelId !== null && runningModelId !== chosenModelId) substitutions.push({
|
|
4731
3416
|
addonId: s.addonId,
|
|
4732
3417
|
chosen: chosenModelId,
|
|
@@ -5529,7 +4214,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
5529
4214
|
* first, then the custom registry. Returns undefined if neither has it.
|
|
5530
4215
|
*/
|
|
5531
4216
|
async resolveModelEntry(addonId, modelId) {
|
|
5532
|
-
const fromCatalog = getStepDefinition(addonId).models.find((m) => m.id === modelId);
|
|
4217
|
+
const fromCatalog = require_step_definitions.getStepDefinition(addonId).models.find((m) => m.id === modelId);
|
|
5533
4218
|
if (fromCatalog) return fromCatalog;
|
|
5534
4219
|
return (await this.getCustomModels()).get(addonId)?.find((m) => m.id === modelId);
|
|
5535
4220
|
}
|
|
@@ -5625,7 +4310,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
5625
4310
|
/** Pure recursive resolver — builds the resolved step tree without touching `modelSubstitutions`. */
|
|
5626
4311
|
resolveStepModelTree(steps, format) {
|
|
5627
4312
|
return steps.map((step) => {
|
|
5628
|
-
const resolved = resolveModelForFormat(step.addonId, step.modelId ?? null, format);
|
|
4313
|
+
const resolved = require_step_definitions.resolveModelForFormat(step.addonId, step.modelId ?? null, format);
|
|
5629
4314
|
const children = step.children?.length ? this.resolveStepModelTree([...step.children], format) : step.children;
|
|
5630
4315
|
return resolved === step.modelId && children === step.children ? step : {
|
|
5631
4316
|
...step,
|
|
@@ -5773,7 +4458,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
5773
4458
|
for (const step of nodes) {
|
|
5774
4459
|
if (!step.enabled) continue;
|
|
5775
4460
|
try {
|
|
5776
|
-
if (getStepDefinition(step.addonId).slot === "audio-classifier") continue;
|
|
4461
|
+
if (require_step_definitions.getStepDefinition(step.addonId).slot === "audio-classifier") continue;
|
|
5777
4462
|
} catch {
|
|
5778
4463
|
continue;
|
|
5779
4464
|
}
|
|
@@ -5793,7 +4478,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
5793
4478
|
async getCapabilities(_forceRefresh) {
|
|
5794
4479
|
const agentId = (this.addonCtx?.kernel?.cluster?.broker)?.nodeID ?? node_os.hostname();
|
|
5795
4480
|
const agentName = agentId;
|
|
5796
|
-
const addons = ALL_PIPELINE_STEPS.map((s) => ({
|
|
4481
|
+
const addons = require_step_definitions.ALL_PIPELINE_STEPS.map((s) => ({
|
|
5797
4482
|
id: s.definition.id,
|
|
5798
4483
|
name: s.definition.name,
|
|
5799
4484
|
models: s.definition.models.filter((m) => m.legacy !== true).map((m) => {
|
|
@@ -6266,7 +4951,10 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
6266
4951
|
const deviceOverrides = effectiveDeviceId > 0 ? await this.readDeviceStore(effectiveDeviceId) : {};
|
|
6267
4952
|
const effectiveTree = Object.keys(deviceOverrides).length > 0 ? applyDeviceOverridesToTree(tree, "object-detection", deviceOverrides) : tree;
|
|
6268
4953
|
const nativeFaceCropProvider = this.buildNativeFaceCropProvider(input.frameHandle);
|
|
6269
|
-
const { result, trace } = await executor.run(effectiveTree, rootInput, jpegProvider, imageWidth, imageHeight, effectiveDeviceId, {
|
|
4954
|
+
const { result, trace } = await executor.run(effectiveTree, rootInput, jpegProvider, imageWidth, imageHeight, effectiveDeviceId, {
|
|
4955
|
+
traceVerbosity: isRuntime ? this.eventBus ? "summary" : "off" : "full",
|
|
4956
|
+
plane: input.plane
|
|
4957
|
+
}, nativeFaceCropProvider);
|
|
6270
4958
|
if (isRuntime) {
|
|
6271
4959
|
if (trace && this.eventBus) this.eventBus.emit(require_dist.createEvent(require_dist.EventCategory.PipelineTrace, {
|
|
6272
4960
|
type: "device",
|
|
@@ -7324,7 +6012,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
7324
6012
|
};
|
|
7325
6013
|
function buildSchemaSlots(format, modelsDir, customByStep) {
|
|
7326
6014
|
const slotMap = /* @__PURE__ */ new Map();
|
|
7327
|
-
for (const pipelineStep of ALL_PIPELINE_STEPS) {
|
|
6015
|
+
for (const pipelineStep of require_step_definitions.ALL_PIPELINE_STEPS) {
|
|
7328
6016
|
const step = pipelineStep.definition;
|
|
7329
6017
|
const availableModels = mergeCustomModels(step.models, customByStep?.get(step.id) ?? []).filter((m) => m.formats[format] && m.legacy !== true);
|
|
7330
6018
|
if (availableModels.length === 0) continue;
|
|
@@ -7411,7 +6099,7 @@ function resolveChildSlots(slot) {
|
|
|
7411
6099
|
*/
|
|
7412
6100
|
function buildDefaultStepTree(format, objectDetectionModelId) {
|
|
7413
6101
|
const makeStep = (stepId, children, opts) => {
|
|
7414
|
-
const def = getStepDefinition(stepId);
|
|
6102
|
+
const def = require_step_definitions.getStepDefinition(stepId);
|
|
7415
6103
|
if (!def.models.some((m) => m.formats[format])) return null;
|
|
7416
6104
|
return {
|
|
7417
6105
|
addonId: def.id,
|
|
@@ -7420,7 +6108,7 @@ function buildDefaultStepTree(format, objectDetectionModelId) {
|
|
|
7420
6108
|
inputClasses: def.inputClasses ?? [],
|
|
7421
6109
|
outputClasses: def.outputClasses,
|
|
7422
6110
|
enabled: opts?.enabled ?? true,
|
|
7423
|
-
modelId: opts?.modelId ?? getDefaultModelForFormat(stepId, format),
|
|
6111
|
+
modelId: opts?.modelId ?? require_step_definitions.getDefaultModelForFormat(stepId, format),
|
|
7424
6112
|
children,
|
|
7425
6113
|
...def.group ? { group: def.group } : {}
|
|
7426
6114
|
};
|
|
@@ -8167,7 +6855,7 @@ var DetectionPipelineAddon = class DetectionPipelineAddon extends require_dist.B
|
|
|
8167
6855
|
}).catch(() => {});
|
|
8168
6856
|
}
|
|
8169
6857
|
getModelCatalog() {
|
|
8170
|
-
return ALL_STEPS.flatMap((s) => s.models.filter((m) => m.legacy !== true));
|
|
6858
|
+
return require_step_definitions.ALL_STEPS.flatMap((s) => s.models.filter((m) => m.legacy !== true));
|
|
8171
6859
|
}
|
|
8172
6860
|
/**
|
|
8173
6861
|
* Proactively install the OpenVINO Python package when Intel hardware
|
|
@@ -8275,10 +6963,10 @@ var DetectionPipelineAddon = class DetectionPipelineAddon extends require_dist.B
|
|
|
8275
6963
|
}
|
|
8276
6964
|
};
|
|
8277
6965
|
//#endregion
|
|
8278
|
-
exports.ALL_STEPS = ALL_STEPS;
|
|
6966
|
+
exports.ALL_STEPS = require_step_definitions.ALL_STEPS;
|
|
8279
6967
|
exports.DetectionPipelineProvider = DetectionPipelineProvider;
|
|
8280
6968
|
exports.backendToFormat = backendToFormat;
|
|
8281
6969
|
exports.default = DetectionPipelineAddon;
|
|
8282
|
-
exports.getDefaultModelForFormat = getDefaultModelForFormat;
|
|
8283
|
-
exports.getStepDefinition = getStepDefinition;
|
|
6970
|
+
exports.getDefaultModelForFormat = require_step_definitions.getDefaultModelForFormat;
|
|
6971
|
+
exports.getStepDefinition = require_step_definitions.getStepDefinition;
|
|
8284
6972
|
exports.shouldInstallOpenvino = shouldInstallOpenvino;
|