@camstack/addon-vision 0.1.6 → 0.1.9
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.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/catalogs/general-ocr-models.ts","../src/catalogs/index.ts","../src/addons/object-detection/index.ts","../src/addons/face-detection/index.ts","../src/addons/face-recognition/index.ts","../src/addons/plate-detection/index.ts","../src/addons/plate-recognition/index.ts","../src/addons/audio-classification/index.ts","../src/addons/bird-global-classifier/index.ts","../src/addons/bird-nabirds-classifier/index.ts","../src/addons/animal-classifier/index.ts","../src/index.ts"],"sourcesContent":["import type { ModelCatalogEntry, LabelDefinition } from '@camstack/types'\nimport { hfModelUrl } from '@camstack/types'\n\nconst HF_REPO = 'camstack/camstack-models'\n\nconst OCR_TEXT_LABELS: readonly LabelDefinition[] = [\n { id: 'text', name: 'Scene Text' },\n] as const\n\n/**\n * General-purpose OCR models for scene text recognition in camera feeds.\n * These complement the plate-specific PaddleOCR models for broader text detection\n * (signs, labels, addresses, etc.).\n */\nexport const GENERAL_OCR_MODELS: readonly ModelCatalogEntry[] = [\n // ── OnnxTR / docTR — lightweight general scene text recognition ──\n {\n id: 'doctr-det-db-mobilenet',\n name: 'docTR Detection MobileNet',\n description: 'docTR DBNet MobileNet V3 — lightweight text region detection for scene text',\n inputSize: { width: 1024, height: 1024 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/onnx/camstack-doctr-det-db-mobilenet-v3.onnx'),\n sizeMB: 15,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/coreml/camstack-doctr-det-db-mobilenet-v3.mlpackage'),\n sizeMB: 8,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/openvino/camstack-doctr-det-db-mobilenet-v3.xml'),\n sizeMB: 8,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'doctr-rec-crnn-mobilenet',\n name: 'docTR Recognition CRNN MobileNet',\n description: 'docTR CRNN MobileNet V3 — lightweight text recognition for detected regions',\n inputSize: { width: 128, height: 32 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/onnx/camstack-doctr-rec-crnn-mobilenet-v3.onnx'),\n sizeMB: 5,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/coreml/camstack-doctr-rec-crnn-mobilenet-v3.mlpackage'),\n sizeMB: 3,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/openvino/camstack-doctr-rec-crnn-mobilenet-v3.xml'),\n sizeMB: 3,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'doctr-rec-parseq',\n name: 'docTR Recognition PARSeq',\n description: 'docTR PARSeq — high-accuracy scene text recognition (top ICDAR scores)',\n inputSize: { width: 128, height: 32 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/onnx/camstack-doctr-rec-parseq.onnx'),\n sizeMB: 25,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/coreml/camstack-doctr-rec-parseq.mlpackage'),\n sizeMB: 13,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/openvino/camstack-doctr-rec-parseq.xml'),\n sizeMB: 13,\n runtimes: ['python'],\n },\n },\n },\n\n // ── PaddleOCR PP-OCRv5 Mobile — general-purpose text detection + recognition ──\n {\n id: 'ppocr-v5-det-mobile',\n name: 'PP-OCRv5 Detection Mobile',\n description: 'PP-OCRv5 mobile text detection — optimized for edge, 100+ languages',\n inputSize: { width: 640, height: 640 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-det-mobile.onnx'),\n sizeMB: 6,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-det-mobile.mlpackage'),\n sizeMB: 3,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-det-mobile.xml'),\n sizeMB: 3,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'ppocr-v5-rec-mobile',\n name: 'PP-OCRv5 Recognition Mobile',\n description: 'PP-OCRv5 mobile text recognition — 100+ languages, CTC decoding',\n inputSize: { width: 320, height: 48 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-rec-mobile.onnx'),\n sizeMB: 8,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-rec-mobile.mlpackage'),\n sizeMB: 4,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-rec-mobile.xml'),\n sizeMB: 4,\n runtimes: ['python'],\n },\n },\n extraFiles: [\n {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/camstack-ppocr-v5-keys.txt'),\n filename: 'camstack-ppocr-v5-keys.txt',\n sizeMB: 0.1,\n },\n ],\n },\n] as const\n","export * from './object-detection-models.js'\nexport * from './face-detection-models.js'\nexport * from './face-recognition-models.js'\nexport * from './plate-detection-models.js'\nexport * from './plate-recognition-models.js'\nexport * from './general-ocr-models.js'\nexport * from './audio-classification-models.js'\nexport * from './segmentation-models.js'\nexport * from './animal-classification-models.js'\nexport * from './vehicle-classification-models.js'\nexport * from './segmentation-refiner-models.js'\n","import type {\n IDetectorProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n FrameInput,\n DetectorOutput,\n SpatialDetection,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { OBJECT_DETECTION_MODELS } from '../../catalogs/object-detection-models.js'\nimport { SEGMENTATION_MODELS } from '../../catalogs/segmentation-models.js'\nimport { COCO_TO_MACRO, MACRO_LABELS, COCO_80_LABELS } from '@camstack/types'\nimport { letterbox } from '../../shared/image-utils.js'\nimport { yoloPostprocess } from '../../shared/postprocess/yolo.js'\nimport { yoloSegPostprocess } from '../../shared/postprocess/yolo-seg.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\n/** Returns true when the model id identifies a YOLO segmentation model (e.g. yolov8n-seg, yolo11m-seg) */\nfunction isSegModel(modelId: string): boolean {\n return modelId.includes('-seg')\n}\n\n/** Combined catalog: regular detection models + segmentation models */\nconst ALL_DETECTION_MODELS: readonly ModelCatalogEntry[] = [\n ...OBJECT_DETECTION_MODELS,\n ...SEGMENTATION_MODELS,\n]\n\n/**\n * classMapMode controls how raw COCO labels are mapped after inference:\n *\n * - 'macro' (default): apply COCO_TO_MACRO — only person / vehicle / animal\n * survive, all other classes are dropped.\n * - 'all': keep every raw COCO label (80 classes). originalClass === class.\n */\ntype ClassMapMode = 'macro' | 'all'\n\n/** Map COCO-class detections to macro categories (person/vehicle/animal) */\nfunction applyClassMap(\n detections: SpatialDetection[],\n classMap: ClassMapDefinition,\n): SpatialDetection[] {\n return detections\n .filter((d) => classMap.mapping[d.class] !== undefined)\n .map((d) => ({\n ...d,\n originalClass: d.class,\n class: classMap.mapping[d.class]!,\n }))\n}\n\n/** RAM estimates per model (MB) */\nconst RAM_ESTIMATES: Record<string, number> = {\n 'yolov8n': 80, 'yolov8s': 150, 'yolov8s-relu': 150, 'yolov8m': 300, 'yolov8l': 500, 'yolov8x': 800,\n 'yolov9t': 60, 'yolov9s': 120, 'yolov9c': 300,\n 'yolo11n': 70, 'yolo11s': 130, 'yolo11m': 280, 'yolo11l': 450, 'yolo11x': 750,\n 'yolo11n-seg': 84, 'yolo11s-seg': 156, 'yolo11m-seg': 336,\n 'yolov8n-seg': 96, 'yolov8s-seg': 180, 'yolov8m-seg': 360,\n}\n\n/**\n * Accuracy scores per model (0-100).\n * YOLO11 scores are higher than YOLOv8 equivalents to reflect the\n * ~2 mAP improvement at same parameter count (e.g. YOLO11n 39.5 vs YOLOv8n 37.3).\n * This ensures the resolver prefers YOLO11 when both families are available.\n */\nconst ACCURACY_SCORES: Record<string, number> = {\n 'yolov8n': 55, 'yolov8s': 70, 'yolov8s-relu': 68, 'yolov8m': 82, 'yolov8l': 88, 'yolov8x': 92,\n 'yolov9t': 58, 'yolov9s': 73, 'yolov9c': 86,\n 'yolo11n': 62, 'yolo11s': 78, 'yolo11m': 88, 'yolo11l': 93, 'yolo11x': 97,\n 'yolo11n-seg': 62, 'yolo11s-seg': 78, 'yolo11m-seg': 88,\n 'yolov8n-seg': 55, 'yolov8s-seg': 70, 'yolov8m-seg': 82,\n}\n\nexport default class ObjectDetectionAddon implements IDetectorProvider, IDetectionAddon {\n readonly id = 'object-detection'\n readonly slot = 'detector' as const\n readonly inputClasses: readonly string[] | null = null\n readonly outputClasses = ['person', 'vehicle', 'animal'] as const\n readonly slotPriority = 0\n readonly manifest: AddonManifest = {\n id: 'object-detection',\n name: 'Object Detection',\n version: '0.1.0',\n\n description: 'YOLO-based object detection — detects persons, vehicles, and animals',\n\n slot: 'detector',\n inputClasses: undefined,\n outputClasses: ['person', 'vehicle', 'animal'],\n supportsCustomModels: true,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'yolo11n',\n runtime: 'node',\n backend: 'cpu',\n confidence: 0.5,\n iouThreshold: 0.45,\n classMapMode: 'macro',\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private confidence = 0.5\n private iouThreshold = 0.45\n private classMapMode: ClassMapMode = 'macro'\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return ALL_DETECTION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: RAM_ESTIMATES[m.id] ?? 100,\n accuracyScore: ACCURACY_SCORES[m.id] ?? 60,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'yolo11n'\n this.confidence = (cfg['confidence'] as number | undefined) ?? 0.5\n this.iouThreshold = (cfg['iouThreshold'] as number | undefined) ?? 0.45\n this.classMapMode = (cfg['classMapMode'] as ClassMapMode | undefined) ?? 'macro'\n\n const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`ObjectDetectionAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async detect(frame: FrameInput): Promise<DetectorOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n\n // Python engine path — send JPEG directly, Python handles preprocess + inference + postprocess\n if ('runJpeg' in this.engine! && typeof (this.engine as any).runJpeg === 'function') {\n const result = await (this.engine as any).runJpeg(frame.data) as Record<string, unknown>\n const rawDets = (result.detections ?? []) as Array<{ className: string; score: number; bbox: number[] }>\n const detections: SpatialDetection[] = rawDets.map((d) => ({\n class: this.classMapMode === 'all' ? d.className : (COCO_TO_MACRO.mapping[d.className] ?? d.className),\n originalClass: d.className,\n score: d.score,\n bbox: {\n x: d.bbox[0]! * frame.width,\n y: d.bbox[1]! * frame.height,\n w: (d.bbox[2]! - d.bbox[0]!) * frame.width,\n h: (d.bbox[3]! - d.bbox[1]!) * frame.height,\n },\n })).filter((d) => this.classMapMode === 'all' || COCO_TO_MACRO.mapping[d.originalClass!] !== undefined)\n\n return {\n detections,\n inferenceMs: (result.inferenceMs as number) ?? (Date.now() - start),\n modelId: this.modelEntry.id,\n }\n }\n\n // Node.js engine path — letterbox + run tensor + postprocess\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n const targetSize = Math.max(inputW, inputH)\n\n const lb = await letterbox(frame.data, targetSize)\n\n const numClasses = this.modelEntry.labels.length\n const labels = this.modelEntry.labels.map((l) => l.id)\n const postprocessOpts = {\n confidence: this.confidence,\n iouThreshold: this.iouThreshold,\n labels,\n scale: lb.scale,\n padX: lb.padX,\n padY: lb.padY,\n originalWidth: lb.originalWidth,\n originalHeight: lb.originalHeight,\n }\n\n let rawDetections: SpatialDetection[]\n\n if (isSegModel(this.modelEntry.id)) {\n // YOLO-seg models produce two outputs:\n // output0: [1, 4 + numClasses + 32, numBoxes] (detection + mask coefficients)\n // output1: [1, 32, 160, 160] (prototype masks)\n const outputs = await this.engine!.runMultiOutput(lb.data, [1, 3, targetSize, targetSize])\n const outputNames = Object.keys(outputs)\n\n if (outputNames.length < 2) {\n throw new Error(\n `ObjectDetectionAddon: seg model \"${this.modelEntry.id}\" returned ${outputNames.length} output(s); expected 2`,\n )\n }\n\n // ONNX output order is deterministic; first output is the detection tensor, second is protos\n const detectionOutput = outputs[outputNames[0]!]!\n const protoOutput = outputs[outputNames[1]!]!\n\n // Infer dims from tensor sizes\n const numMaskCoeffs = 32\n const numBoxes = detectionOutput.length / (4 + numClasses + numMaskCoeffs)\n const maskHeight = 160\n const maskWidth = 160\n\n rawDetections = yoloSegPostprocess(\n {\n detectionOutput,\n protoOutput,\n numClasses,\n numBoxes,\n numMaskCoeffs,\n maskHeight,\n maskWidth,\n },\n postprocessOpts,\n )\n } else {\n // Standard YOLO output: [1, 4+numClasses, numBoxes]\n const output = await this.engine!.run(lb.data, [1, 3, targetSize, targetSize])\n const numBoxes = output.length / (4 + numClasses)\n rawDetections = yoloPostprocess(output, numClasses, numBoxes, postprocessOpts)\n }\n\n const detections = this.classMapMode === 'all'\n ? rawDetections\n : applyClassMap(rawDetections, COCO_TO_MACRO)\n\n return {\n detections,\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = ALL_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n // Download model if needed\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n // Discover Python path for Python-based runtimes\n let pythonPath: string | undefined\n if (config?.runtime === 'python') {\n for (const cmd of ['python3', 'python']) {\n try {\n const { execSync } = await import('node:child_process')\n execSync(`${cmd} --version`, { timeout: 3000, stdio: 'ignore' })\n pythonPath = cmd\n break\n } catch { /* not found */ }\n }\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n pythonPath,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...ALL_DETECTION_MODELS],\n allowCustom: true,\n allowConversion: true,\n acceptFormats: ['onnx', 'coreml', 'openvino', 'tflite'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'yolo',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n { value: 'tensorrt', label: 'TensorRT (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Detection Thresholds',\n columns: 2,\n fields: [\n {\n key: 'confidence',\n label: 'Confidence Threshold',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.5,\n },\n {\n key: 'iouThreshold',\n label: 'IoU Threshold (NMS)',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.45,\n },\n ],\n },\n {\n id: 'classmap',\n title: 'Class Mapping',\n columns: 1,\n fields: [\n {\n key: 'classMapMode',\n label: 'Output classes',\n type: 'select',\n options: [\n { value: 'macro', label: 'Macro (person / vehicle / animal)' },\n { value: 'all', label: 'All COCO classes (80)' },\n ],\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return COCO_TO_MACRO\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...ALL_DETECTION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n // TODO: check downloaded models in modelsDir\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return this.classMapMode === 'all' ? COCO_80_LABELS : MACRO_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n ICropperProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n CropperOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { FACE_DETECTION_MODELS } from '../../catalogs/face-detection-models.js'\nimport { cropRegion, letterbox } from '../../shared/image-utils.js'\nimport { scrfdPostprocess } from '../../shared/postprocess/scrfd.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\nconst FACE_LABEL: LabelDefinition = { id: 'face', name: 'Face' }\nconst FACE_LABELS: readonly LabelDefinition[] = [FACE_LABEL]\nconst FACE_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\n/** RAM estimates per model (MB) */\nconst RAM_ESTIMATES: Record<string, number> = {\n 'scrfd-500m': 50,\n 'scrfd-2.5g': 80,\n 'scrfd-10g': 200,\n}\n\n/** Accuracy scores per model (0-100) */\nconst ACCURACY_SCORES: Record<string, number> = {\n 'scrfd-500m': 70,\n 'scrfd-2.5g': 82,\n 'scrfd-10g': 92,\n}\n\nexport default class FaceDetectionAddon implements ICropperProvider, IDetectionAddon {\n readonly id = 'face-detection'\n readonly slot = 'cropper' as const\n readonly inputClasses = ['person'] as const\n readonly outputClasses = ['face'] as const\n readonly slotPriority = 0\n readonly manifest: AddonManifest = {\n id: 'face-detection',\n name: 'Face Detection',\n version: '0.1.0',\n\n description: 'SCRFD-based face detector — crops face regions from person detections',\n\n slot: 'cropper',\n inputClasses: ['person'],\n outputClasses: ['face'],\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'scrfd-500m',\n runtime: 'node',\n backend: 'cpu',\n confidence: 0.5,\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private confidence = 0.5\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return FACE_DETECTION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: RAM_ESTIMATES[m.id] ?? 50,\n accuracyScore: ACCURACY_SCORES[m.id] ?? 70,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'scrfd-500m'\n this.confidence = (cfg['confidence'] as number | undefined) ?? 0.5\n\n const entry = FACE_DETECTION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`FaceDetectionAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async crop(input: CropInput): Promise<CropperOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n const targetSize = Math.max(inputW, inputH)\n\n // Crop the person region from the full frame\n const personCrop = await cropRegion(input.frame.data, input.roi)\n\n // Letterbox resize to model input size\n const lb = await letterbox(personCrop, targetSize)\n\n // SCRFD has multiple output tensors\n const engineWithMulti = this.engine as IInferenceEngine & {\n runMultiOutput?: (input: Float32Array, shape: readonly number[]) => Promise<Record<string, Float32Array>>\n }\n\n let outputs: Record<string, Float32Array>\n if (typeof engineWithMulti.runMultiOutput === 'function') {\n outputs = await engineWithMulti.runMultiOutput(lb.data, [1, 3, targetSize, targetSize])\n } else {\n // Fallback: wrap single output\n const single = await this.engine!.run(lb.data, [1, 3, targetSize, targetSize])\n outputs = { output0: single }\n }\n\n const crops = scrfdPostprocess(\n outputs,\n this.confidence,\n targetSize,\n lb.originalWidth,\n lb.originalHeight,\n )\n\n return {\n crops,\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = FACE_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...FACE_DETECTION_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'coreml', 'openvino'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'ssd',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Detection Thresholds',\n columns: 1,\n fields: [\n {\n key: 'confidence',\n label: 'Confidence Threshold',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.5,\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return FACE_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...FACE_DETECTION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return FACE_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n IClassifierProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n ClassifierOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n RequiredStep,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { FACE_RECOGNITION_MODELS } from '../../catalogs/face-recognition-models.js'\nimport { cropRegion, resizeAndNormalize } from '../../shared/image-utils.js'\nimport { l2Normalize } from '../../shared/postprocess/arcface.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\nconst IDENTITY_LABEL: LabelDefinition = { id: 'identity', name: 'Identity' }\nconst IDENTITY_LABELS: readonly LabelDefinition[] = [IDENTITY_LABEL]\nconst FACE_REC_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\nconst REQUIRED_STEPS: readonly RequiredStep[] = [\n { slot: 'cropper', outputClasses: ['face'], description: 'Requires a face detector' },\n]\n\nexport default class FaceRecognitionAddon implements IClassifierProvider, IDetectionAddon {\n readonly id = 'face-recognition'\n readonly slot = 'classifier' as const\n readonly inputClasses = ['face'] as const\n readonly outputClasses = ['identity:*'] as const\n readonly slotPriority = 0\n readonly requiredSteps = REQUIRED_STEPS\n readonly manifest: AddonManifest = {\n id: 'face-recognition',\n name: 'Face Recognition',\n version: '0.1.0',\n\n description: 'ArcFace-based face recognition — produces 512-d identity embeddings',\n\n slot: 'classifier',\n labelOutputType: 'face',\n inputClasses: ['face'],\n outputClasses: ['identity:*'],\n requiredSteps: REQUIRED_STEPS,\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'arcface-r100',\n runtime: 'node',\n backend: 'cpu',\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return FACE_RECOGNITION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: 400,\n accuracyScore: 90,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'arcface-r100'\n\n const entry = FACE_RECOGNITION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`FaceRecognitionAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async classify(input: CropInput): Promise<ClassifierOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n\n // Crop the face region\n const faceCrop = await cropRegion(input.frame.data, input.roi)\n\n // Resize to 112x112, NHWC layout (ArcFace expects NHWC)\n const layout = this.modelEntry.inputLayout ?? 'nhwc'\n const normalization = this.modelEntry.inputNormalization ?? 'zero-one'\n const normalized = await resizeAndNormalize(faceCrop, inputW, inputH, normalization, layout)\n\n // Run inference — output is 512-d embedding\n const rawEmbedding = await this.engine!.run(normalized, [1, inputH, inputW, 3])\n\n // L2 normalize the embedding\n const embedding = l2Normalize(rawEmbedding)\n\n return {\n classifications: [\n {\n class: 'identity',\n score: 1.0,\n embedding,\n },\n ],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = FACE_RECOGNITION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...FACE_RECOGNITION_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'coreml', 'openvino'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'embedding',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return FACE_REC_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...FACE_RECOGNITION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return IDENTITY_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n ICropperProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n CropperOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { PLATE_DETECTION_MODELS } from '../../catalogs/plate-detection-models.js'\nimport { cropRegion, letterbox } from '../../shared/image-utils.js'\nimport { yoloPostprocess } from '../../shared/postprocess/yolo.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\nconst PLATE_LABEL: LabelDefinition = { id: 'plate', name: 'License Plate' }\nconst PLATE_LABELS: readonly LabelDefinition[] = [PLATE_LABEL]\nconst PLATE_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\nexport default class PlateDetectionAddon implements ICropperProvider, IDetectionAddon {\n readonly id = 'plate-detection'\n readonly slot = 'cropper' as const\n readonly inputClasses = ['vehicle'] as const\n readonly outputClasses = ['plate'] as const\n readonly slotPriority = 0\n readonly manifest: AddonManifest = {\n id: 'plate-detection',\n name: 'License Plate Detection',\n version: '0.1.0',\n\n description: 'YOLO-based license plate detector — crops plate regions from vehicle detections',\n\n slot: 'cropper',\n inputClasses: ['vehicle'],\n outputClasses: ['plate'],\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'yolov8n-plate',\n runtime: 'node',\n backend: 'cpu',\n confidence: 0.5,\n iouThreshold: 0.45,\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private confidence = 0.5\n private iouThreshold = 0.45\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return PLATE_DETECTION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: 80,\n accuracyScore: 60,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'yolov8n-plate'\n this.confidence = (cfg['confidence'] as number | undefined) ?? 0.5\n this.iouThreshold = (cfg['iouThreshold'] as number | undefined) ?? 0.45\n\n const entry = PLATE_DETECTION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`PlateDetectionAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async crop(input: CropInput): Promise<CropperOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n const targetSize = Math.max(inputW, inputH)\n\n // Crop the vehicle region from the full frame\n const vehicleCrop = await cropRegion(input.frame.data, input.roi)\n\n const lb = await letterbox(vehicleCrop, targetSize)\n const output = await this.engine!.run(lb.data, [1, 3, targetSize, targetSize])\n\n const numClasses = this.modelEntry.labels.length\n const numBoxes = output.length / (4 + numClasses)\n const labels = this.modelEntry.labels.map((l) => l.id)\n\n const plates = yoloPostprocess(output, numClasses, numBoxes, {\n confidence: this.confidence,\n iouThreshold: this.iouThreshold,\n labels,\n scale: lb.scale,\n padX: lb.padX,\n padY: lb.padY,\n originalWidth: lb.originalWidth,\n originalHeight: lb.originalHeight,\n })\n\n // Override class to 'plate'\n const crops = plates.map((p) => ({ ...p, class: 'plate', originalClass: p.originalClass }))\n\n return {\n crops,\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = PLATE_DETECTION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...PLATE_DETECTION_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'coreml', 'openvino'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'yolo',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Detection Thresholds',\n columns: 2,\n fields: [\n {\n key: 'confidence',\n label: 'Confidence Threshold',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.5,\n },\n {\n key: 'iouThreshold',\n label: 'IoU Threshold (NMS)',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.45,\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return PLATE_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...PLATE_DETECTION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return PLATE_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n IClassifierProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n ClassifierOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n RequiredStep,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { PLATE_RECOGNITION_MODELS } from '../../catalogs/plate-recognition-models.js'\nimport { cropRegion, resizeAndNormalize } from '../../shared/image-utils.js'\nimport { ctcDecode } from '../../shared/postprocess/paddleocr.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\nconst PLATE_TEXT_LABEL: LabelDefinition = { id: 'plate-text', name: 'Plate Text' }\nconst PLATE_TEXT_LABELS: readonly LabelDefinition[] = [PLATE_TEXT_LABEL]\nconst PLATE_REC_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\n\n/** Load charset from dict.txt file — index 0 is the CTC blank token */\nfunction loadCharset(modelsDir: string, modelId: string): readonly string[] {\n // Try to find the dict file next to the model\n const dictNames = [\n `camstack-${modelId}-dict.txt`,\n `camstack-paddleocr-latin-dict.txt`,\n `camstack-paddleocr-en-dict.txt`,\n `camstack-crnn-mobilenet-charset.txt`,\n ]\n for (const name of dictNames) {\n const dictPath = path.join(modelsDir, name)\n if (fs.existsSync(dictPath)) {\n const lines = fs.readFileSync(dictPath, 'utf-8').split('\\n').filter((l) => l.length > 0)\n // PaddleOCR convention: blank token at index 0, then dict chars, then a space token at end\n return ['', ...lines, ' ']\n }\n }\n throw new Error(`PlateRecognitionAddon: dict.txt not found in ${modelsDir}`)\n}\n\nconst REQUIRED_STEPS: readonly RequiredStep[] = [\n { slot: 'cropper', outputClasses: ['plate'], description: 'Requires a plate detector' },\n]\n\nexport default class PlateRecognitionAddon implements IClassifierProvider, IDetectionAddon {\n readonly id = 'plate-recognition'\n readonly slot = 'classifier' as const\n readonly inputClasses = ['plate'] as const\n readonly outputClasses = ['plate-text:*'] as const\n readonly slotPriority = 0\n readonly requiredSteps = REQUIRED_STEPS\n readonly manifest: AddonManifest = {\n id: 'plate-recognition',\n name: 'License Plate Recognition (OCR)',\n version: '0.1.0',\n\n description: 'PaddleOCR-based license plate text recognition',\n\n slot: 'classifier',\n labelOutputType: 'plate',\n inputClasses: ['plate'],\n outputClasses: ['plate-text:*'],\n requiredSteps: REQUIRED_STEPS,\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'paddleocr-latin',\n runtime: 'node',\n backend: 'cpu',\n minConfidence: 0.5,\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private minConfidence = 0.5\n private charset: readonly string[] = []\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n const scores: Record<string, { ram: number; accuracy: number }> = {\n 'paddleocr-latin': { ram: 100, accuracy: 80 },\n 'paddleocr-en': { ram: 100, accuracy: 80 },\n }\n return PLATE_RECOGNITION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: scores[m.id]?.ram ?? 100,\n accuracyScore: scores[m.id]?.accuracy ?? 75,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'paddleocr-latin'\n this.minConfidence = (cfg['minConfidence'] as number | undefined) ?? 0.5\n\n const entry = PLATE_RECOGNITION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`PlateRecognitionAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async classify(input: CropInput): Promise<ClassifierOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n\n // Crop the plate region\n 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}`)\n const plateCrop = await cropRegion(input.frame.data, input.roi)\n console.log(`[plate-recognition] Crop size: ${plateCrop.length} bytes`)\n // DEBUG: save crop to /tmp for inspection\n try { require('fs').writeFileSync('/tmp/plate-recognition-crop.jpg', plateCrop) } catch {}\n\n // Resize to 320x48, normalize to [0,1], NCHW\n const normalized = await resizeAndNormalize(plateCrop, inputW, inputH, 'zero-one', 'nchw')\n\n const output = await this.engine!.run(normalized, [1, 3, inputH, inputW])\n\n // PaddleOCR CTC output shape: [1, seqLen, numChars]\n const numChars = this.charset.length\n const seqLen = output.length / numChars\n const { text, confidence } = ctcDecode(output, seqLen, numChars, this.charset)\n\n // Always return the result with confidence — let the pipeline/UI decide on thresholds\n return {\n classifications: [\n {\n class: 'plate-text',\n score: confidence,\n text: text.trim() || '(unreadable)',\n },\n ],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = PLATE_RECOGNITION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n // Ensure model + extra files (dict.txt) are downloaded via unified service\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n // Load charset from dict.txt (lazy — only on first use)\n this.charset = loadCharset(modelsDir, modelId)\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...PLATE_RECOGNITION_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'openvino'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'ocr',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Recognition Settings',\n columns: 1,\n fields: [\n {\n key: 'minConfidence',\n label: 'Minimum Confidence',\n type: 'slider',\n min: 0.1,\n max: 1.0,\n step: 0.05,\n default: 0.5,\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return PLATE_REC_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...PLATE_RECOGNITION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return PLATE_TEXT_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n IClassifierProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n ClassifierOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { AUDIO_CLASSIFICATION_MODELS } from '../../catalogs/audio-classification-models.js'\nimport { yamnetPostprocess } from '../../shared/postprocess/yamnet.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\n// YAMNet recognizes 521 audio classes from the AudioSet ontology.\n// This is the top-level subset used for filtering. Full class list lives in the model catalog.\nconst YAMNET_NUM_CLASSES = 521\n\nconst AUDIO_EVENT_LABEL: LabelDefinition = { id: 'audio-event', name: 'Audio Event' }\nconst AUDIO_LABELS: readonly LabelDefinition[] = [AUDIO_EVENT_LABEL]\nconst AUDIO_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\nexport default class AudioClassificationAddon implements IClassifierProvider, IDetectionAddon {\n readonly id = 'audio-classification'\n readonly slot = 'classifier' as const\n readonly inputClasses: readonly string[] | null = null\n readonly outputClasses = ['audio-event:*'] as const\n readonly slotPriority = 0\n readonly manifest: AddonManifest = {\n id: 'audio-classification',\n name: 'Audio Classification',\n version: '0.1.0',\n\n description: 'YAMNet-based audio event classification from audio waveform',\n\n slot: 'classifier',\n labelOutputType: 'classification',\n inputClasses: undefined,\n outputClasses: ['audio-event:*'],\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'yamnet',\n runtime: 'node',\n backend: 'cpu',\n minScore: 0.3,\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private minScore = 0.3\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return AUDIO_CLASSIFICATION_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: 100,\n accuracyScore: 80,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'yamnet'\n this.minScore = (cfg['minScore'] as number | undefined) ?? 0.3\n\n const entry = AUDIO_CLASSIFICATION_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`AudioClassificationAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n /**\n * classify() receives a CropInput but internally treats input.frame.data as raw audio context.\n * For audio, the actual audio chunk data should be stored in frame.data as a Float32Array\n * serialized into a Buffer (little-endian float32 samples at 16 kHz).\n *\n * The CropInput.roi is not used for audio — it is ignored.\n */\n async classify(input: CropInput): Promise<ClassifierOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n\n // Extract raw float32 audio samples from the buffer\n const buf = input.frame.data\n const numSamples = Math.floor(buf.length / 4)\n const audioData = new Float32Array(numSamples)\n for (let i = 0; i < numSamples; i++) {\n audioData[i] = buf.readFloatLE(i * 4)\n }\n\n // YAMNet expects 1D waveform at 16 kHz\n const output = await this.engine!.run(audioData, [numSamples])\n\n // YAMNet output shape: [numFrames, numClasses]\n const numFrames = output.length / YAMNET_NUM_CLASSES\n\n // Use model label ids as class names (or index strings if catalog is sparse)\n const classNames: string[] = this.modelEntry.labels.map((l) => l.id)\n // Pad to full 521 classes if the catalog only has a subset\n while (classNames.length < YAMNET_NUM_CLASSES) {\n classNames.push(`class_${classNames.length}`)\n }\n\n const results = yamnetPostprocess(\n output,\n Math.round(numFrames),\n YAMNET_NUM_CLASSES,\n classNames,\n this.minScore,\n )\n\n const classifications = results.map((r) => ({\n class: `audio-event:${r.className}`,\n score: r.score,\n }))\n\n return {\n classifications,\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = AUDIO_CLASSIFICATION_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...AUDIO_CLASSIFICATION_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'openvino'],\n requiredMetadata: ['inputSize', 'labels', 'outputFormat'],\n outputFormatHint: 'classification',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Classification Settings',\n columns: 1,\n fields: [\n {\n key: 'minScore',\n label: 'Minimum Score',\n type: 'slider',\n min: 0.05,\n max: 1.0,\n step: 0.05,\n default: 0.3,\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return AUDIO_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...AUDIO_CLASSIFICATION_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return AUDIO_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n IClassifierProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n ClassifierOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { BIRD_SPECIES_MODELS } from '../../catalogs/animal-classification-models.js'\nimport { cropRegion, resizeAndNormalize } from '../../shared/image-utils.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\n\nconst SPECIES_LABEL: LabelDefinition = { id: 'species', name: 'Bird Species' }\nconst SPECIES_LABELS: readonly LabelDefinition[] = [SPECIES_LABEL]\nconst BIRD_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\n/** Load bird species labels from JSON file in modelsDir */\nfunction loadLabels(modelsDir: string, modelId: string): readonly string[] {\n const labelNames = [\n `camstack-${modelId}-labels.json`,\n `camstack-bird-species-525-labels.json`,\n ]\n for (const name of labelNames) {\n const labelPath = path.join(modelsDir, name)\n if (fs.existsSync(labelPath)) {\n const raw = fs.readFileSync(labelPath, 'utf-8')\n return JSON.parse(raw) as string[]\n }\n }\n throw new Error(`BirdGlobalClassifierAddon: labels JSON not found in ${modelsDir}`)\n}\n\nfunction softmax(logits: Float32Array): Float32Array {\n const max = logits.reduce((a, b) => Math.max(a, b), -Infinity)\n const exps = logits.map((v) => Math.exp(v - max))\n const sum = exps.reduce((a, b) => a + b, 0)\n return exps.map((v) => v / sum) as unknown as Float32Array\n}\n\nexport default class BirdGlobalClassifierAddon implements IClassifierProvider, IDetectionAddon {\n readonly id = 'bird-global-classifier'\n readonly slot = 'classifier' as const\n readonly inputClasses = ['animal'] as const\n readonly outputClasses = ['species:*'] as const\n readonly slotPriority = 0\n readonly requiredSteps = [] as const\n readonly manifest: AddonManifest = {\n id: 'bird-global-classifier',\n name: 'Bird Classifier (Global, 525 species)',\n version: '0.1.0',\n\n description: 'EfficientNet — 525 worldwide bird species (MIT license, ONNX only)',\n\n slot: 'classifier',\n labelOutputType: 'classification',\n inputClasses: ['animal'],\n outputClasses: ['species:*'],\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'bird-species-525',\n runtime: 'node',\n backend: 'cpu',\n minConfidence: 0.3,\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private labels: readonly string[] = []\n private minConfidence = 0.3\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return BIRD_SPECIES_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: 120,\n accuracyScore: 80,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'bird-species-525'\n this.minConfidence = (cfg['minConfidence'] as number | undefined) ?? 0.3\n\n const entry = BIRD_SPECIES_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`BirdGlobalClassifierAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async classify(input: CropInput): Promise<ClassifierOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n\n // Crop the animal region\n const animalCrop = await cropRegion(input.frame.data, input.roi)\n\n // Resize to 224x224, ImageNet normalization, NCHW\n const normalized = await resizeAndNormalize(animalCrop, inputW, inputH, 'imagenet', 'nchw')\n\n // Run inference — output shape: [1, 525]\n const rawOutput = await this.engine!.run(normalized, [1, 3, inputH, inputW])\n\n // Softmax to get probabilities\n const probs = softmax(rawOutput)\n\n // Find argmax\n let maxIdx = 0\n let maxScore = probs[0] ?? 0\n for (let i = 1; i < probs.length; i++) {\n const score = probs[i] ?? 0\n if (score > maxScore) {\n maxScore = score\n maxIdx = i\n }\n }\n\n if (maxScore < this.minConfidence) {\n return {\n classifications: [],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n const label = this.labels[maxIdx] ?? `species_${maxIdx}`\n\n return {\n classifications: [\n {\n class: label,\n score: maxScore,\n },\n ],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = BIRD_SPECIES_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n // Ensure model + extra files (labels JSON) are downloaded via unified service\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n // Load labels from JSON file (lazy — only on first use)\n this.labels = loadLabels(modelsDir, modelId)\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...BIRD_SPECIES_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'coreml', 'openvino'],\n requiredMetadata: ['inputSize', 'labels'],\n outputFormatHint: 'classification',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Classification Settings',\n columns: 1,\n fields: [\n {\n key: 'minConfidence',\n label: 'Minimum Confidence',\n type: 'slider',\n min: 0.05,\n max: 1.0,\n step: 0.05,\n default: 0.3,\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return BIRD_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...BIRD_SPECIES_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return SPECIES_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n IClassifierProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n ClassifierOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { BIRD_NABIRDS_MODELS } from '../../catalogs/animal-classification-models.js'\nimport { cropRegion, resizeAndNormalize } from '../../shared/image-utils.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\n\nconst SPECIES_LABEL: LabelDefinition = { id: 'species', name: 'Bird Species' }\nconst SPECIES_LABELS: readonly LabelDefinition[] = [SPECIES_LABEL]\nconst BIRD_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\n/** Load NABirds labels from JSON file in modelsDir */\nfunction loadLabels(modelsDir: string, modelId: string): readonly string[] {\n const labelNames = [\n `camstack-${modelId}-labels.json`,\n `camstack-bird-nabirds-404-labels.json`,\n ]\n for (const name of labelNames) {\n const labelPath = path.join(modelsDir, name)\n if (fs.existsSync(labelPath)) {\n const raw = fs.readFileSync(labelPath, 'utf-8')\n return JSON.parse(raw) as string[]\n }\n }\n throw new Error(`BirdNABirdsClassifierAddon: labels JSON not found in ${modelsDir}`)\n}\n\nfunction softmax(logits: Float32Array): Float32Array {\n const max = logits.reduce((a, b) => Math.max(a, b), -Infinity)\n const exps = logits.map((v) => Math.exp(v - max))\n const sum = exps.reduce((a, b) => a + b, 0)\n return exps.map((v) => v / sum) as unknown as Float32Array\n}\n\nexport default class BirdNABirdsClassifierAddon implements IClassifierProvider, IDetectionAddon {\n readonly id = 'bird-nabirds-classifier'\n readonly slot = 'classifier' as const\n readonly inputClasses = ['animal'] as const\n readonly outputClasses = ['species:*'] as const\n readonly slotPriority = 0\n readonly requiredSteps = [] as const\n readonly manifest: AddonManifest = {\n id: 'bird-nabirds-classifier',\n name: 'Bird Classifier (NABirds, 404 species)',\n version: '0.1.0',\n\n description: 'ResNet50 — 404 North American bird species (NABirds dataset, ONNX + CoreML + OpenVINO)',\n\n slot: 'classifier',\n labelOutputType: 'classification',\n inputClasses: ['animal'],\n outputClasses: ['species:*'],\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'bird-nabirds-404',\n runtime: 'node',\n backend: 'cpu',\n minConfidence: 0.3,\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private labels: readonly string[] = []\n private minConfidence = 0.3\n private allowedSpecies: string[] | undefined\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return BIRD_NABIRDS_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: 300,\n accuracyScore: 80,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'bird-nabirds-404'\n this.minConfidence = (cfg['minConfidence'] as number | undefined) ?? 0.3\n this.allowedSpecies = (cfg['allowedSpecies'] as string[] | undefined)\n\n const entry = BIRD_NABIRDS_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`BirdNABirdsClassifierAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n private applyRegionFilter(scores: Float32Array, labels: string[]): void {\n if (!this.allowedSpecies || this.allowedSpecies.length === 0) return\n const allowedSet = new Set(this.allowedSpecies.map(s => s.toLowerCase()))\n for (let i = 0; i < scores.length; i++) {\n if (!allowedSet.has(labels[i]!.toLowerCase())) {\n scores[i] = 0\n }\n }\n }\n\n async classify(input: CropInput): Promise<ClassifierOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n\n // Crop the animal region\n const animalCrop = await cropRegion(input.frame.data, input.roi)\n\n // Resize to 224x224, ImageNet normalization, NCHW\n const normalized = await resizeAndNormalize(animalCrop, inputW, inputH, 'imagenet', 'nchw')\n\n // Run inference — output shape: [1, 404]\n const rawOutput = await this.engine!.run(normalized, [1, 3, inputH, inputW])\n\n // Softmax to get probabilities\n const probs = softmax(rawOutput)\n\n // Apply regional filter (zeroes out non-allowed species, then re-normalize)\n this.applyRegionFilter(probs, this.labels as string[])\n const filteredSum = probs.reduce((a, b) => a + b, 0)\n if (filteredSum > 0) {\n for (let i = 0; i < probs.length; i++) {\n probs[i] = (probs[i] ?? 0) / filteredSum\n }\n }\n\n // Find argmax\n let maxIdx = 0\n let maxScore = probs[0] ?? 0\n for (let i = 1; i < probs.length; i++) {\n const score = probs[i] ?? 0\n if (score > maxScore) {\n maxScore = score\n maxIdx = i\n }\n }\n\n if (maxScore < this.minConfidence) {\n return {\n classifications: [],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n const label = this.labels[maxIdx] ?? `species_${maxIdx}`\n\n return {\n classifications: [\n {\n class: label,\n score: maxScore,\n },\n ],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = BIRD_NABIRDS_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n // Ensure model + extra files (labels JSON) are downloaded via unified service\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n // Load labels from JSON file (lazy — only on first use)\n this.labels = loadLabels(modelsDir, modelId)\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...BIRD_NABIRDS_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'coreml', 'openvino'],\n requiredMetadata: ['inputSize', 'labels'],\n outputFormatHint: 'classification',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Classification Settings',\n columns: 1,\n fields: [\n {\n key: 'minConfidence',\n label: 'Minimum Confidence',\n type: 'slider',\n min: 0.05,\n max: 1.0,\n step: 0.05,\n default: 0.3,\n },\n ],\n },\n {\n id: 'region',\n title: 'Regional Filter',\n columns: 1,\n fields: [\n {\n key: 'regionFilter',\n label: 'Region Preset',\n type: 'select',\n options: [\n { value: '', label: 'None (all 404 species)' },\n { value: 'north-america-east', label: 'North America — Eastern' },\n { value: 'north-america-west', label: 'North America — Western' },\n { value: 'north-america-south', label: 'North America — Southern' },\n ],\n },\n {\n key: 'allowedSpecies',\n label: 'Custom Allowed Species (comma-separated)',\n type: 'text',\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return BIRD_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...BIRD_NABIRDS_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return SPECIES_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","import type {\n IClassifierProvider,\n IDetectionAddon,\n AddonManifest,\n AddonContext,\n CropInput,\n ClassifierOutput,\n ConfigUISchema,\n ClassMapDefinition,\n ProbeResult,\n ModelCatalogEntry,\n DetectionModel,\n LabelDefinition,\n IInferenceEngine,\n ModelRequirement,\n ResolvedInferenceConfig,\n} from '@camstack/types'\nimport { ANIMAL_TYPE_MODELS } from '../../catalogs/animal-classification-models.js'\nimport { cropRegion, resizeAndNormalize } from '../../shared/image-utils.js'\nimport { resolveEngine } from '../../shared/engine-resolver.js'\n\nconst ANIMAL_TYPE_LABEL: LabelDefinition = { id: 'animal-type', name: 'Animal Type' }\nconst ANIMAL_TYPE_LABELS: readonly LabelDefinition[] = [ANIMAL_TYPE_LABEL]\nconst ANIMAL_CLASS_MAP: ClassMapDefinition = { mapping: {}, preserveOriginal: true }\n\nconst ANIMAL_10_CLASSES = [\n 'cat',\n 'cow',\n 'dog',\n 'dolphin',\n 'eagle',\n 'giant panda',\n 'horse',\n 'monkey',\n 'sheep',\n 'spider',\n] as const\n\nfunction softmax(logits: Float32Array): Float32Array {\n const max = logits.reduce((a, b) => Math.max(a, b), -Infinity)\n const exps = logits.map((v) => Math.exp(v - max))\n const sum = exps.reduce((a, b) => a + b, 0)\n return exps.map((v) => v / sum) as unknown as Float32Array\n}\n\nexport default class AnimalClassifierAddon implements IClassifierProvider, IDetectionAddon {\n readonly id = 'animal-classifier'\n readonly slot = 'classifier' as const\n readonly inputClasses = ['animal'] as const\n readonly outputClasses = ['animal-type:*'] as const\n readonly slotPriority = 0\n readonly requiredSteps = [] as const\n readonly manifest: AddonManifest = {\n id: 'animal-classifier',\n name: 'Animal Classifier',\n version: '0.1.0',\n\n description: 'ViT-based animal type classifier — 10 common species',\n\n slot: 'classifier',\n labelOutputType: 'classification',\n inputClasses: ['animal'],\n outputClasses: ['animal-type:*'],\n supportsCustomModels: false,\n mayRequirePython: false,\n defaultConfig: {\n modelId: 'animals-10',\n runtime: 'node',\n backend: 'cpu',\n minConfidence: 0.3,\n },\n }\n\n private engine: IInferenceEngine | null = null\n private modelEntry!: ModelCatalogEntry\n private minConfidence = 0.3\n private resolvedConfig: ResolvedInferenceConfig | null = null\n private ctx: AddonContext | null = null\n\n getModelRequirements(): ModelRequirement[] {\n return ANIMAL_TYPE_MODELS.map((m) => ({\n modelId: m.id,\n name: m.name,\n minRAM_MB: 800,\n accuracyScore: 75,\n formats: Object.keys(m.formats) as readonly string[],\n }))\n }\n\n configure(config: ResolvedInferenceConfig): void {\n this.resolvedConfig = config\n }\n\n async initialize(ctx: AddonContext): Promise<void> {\n this.ctx = ctx\n const cfg = ctx.addonConfig\n const modelId = (cfg['modelId'] as string | undefined) ?? this.resolvedConfig?.modelId ?? 'animals-10'\n this.minConfidence = (cfg['minConfidence'] as number | undefined) ?? 0.3\n\n const entry = ANIMAL_TYPE_MODELS.find((m) => m.id === modelId)\n if (!entry) {\n throw new Error(`AnimalClassifierAddon: unknown modelId \"${modelId}\"`)\n }\n this.modelEntry = entry\n }\n\n async classify(input: CropInput): Promise<ClassifierOutput> {\n if (!this.engine) await this.ensureEngine()\n const start = Date.now()\n const { width: inputW, height: inputH } = this.modelEntry.inputSize\n\n // Crop the animal region\n const animalCrop = await cropRegion(input.frame.data, input.roi)\n\n // Resize to 224x224, ImageNet normalization, NCHW\n const normalized = await resizeAndNormalize(animalCrop, inputW, inputH, 'imagenet', 'nchw')\n\n // Run inference — output shape: [1, 10]\n const rawOutput = await this.engine!.run(normalized, [1, 3, inputH, inputW])\n\n // Softmax to get probabilities\n const probs = softmax(rawOutput)\n\n // Find argmax\n let maxIdx = 0\n let maxScore = probs[0] ?? 0\n for (let i = 1; i < probs.length; i++) {\n const score = probs[i] ?? 0\n if (score > maxScore) {\n maxScore = score\n maxIdx = i\n }\n }\n\n if (maxScore < this.minConfidence) {\n return {\n classifications: [],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n const label = ANIMAL_10_CLASSES[maxIdx] ?? `animal_${maxIdx}`\n\n return {\n classifications: [\n {\n class: label,\n score: maxScore,\n },\n ],\n inferenceMs: Date.now() - start,\n modelId: this.modelEntry.id,\n }\n }\n\n private async ensureEngine(): Promise<void> {\n const config = this.resolvedConfig\n const modelId = config?.modelId ?? this.modelEntry.id\n const runtime = config?.runtime === 'python' ? 'coreml' : (config?.runtime === 'node' ? 'onnx' : 'auto')\n const backend = config?.backend ?? 'cpu'\n const format = config?.format ?? 'onnx'\n\n const entry = ANIMAL_TYPE_MODELS.find((m) => m.id === modelId) ?? this.modelEntry\n this.modelEntry = entry\n\n const modelsDir = this.ctx!.models?.getModelsDir() ?? this.ctx!.locationPaths.models\n\n if (this.ctx!.models) {\n await this.ctx!.models.ensure(modelId, format as any)\n }\n\n const resolved = await resolveEngine({\n runtime: runtime as 'auto',\n backend,\n modelEntry: entry,\n modelsDir,\n models: this.ctx!.models,\n })\n this.engine = resolved.engine\n }\n\n async shutdown(): Promise<void> {\n await this.engine?.dispose()\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'model',\n title: 'Model',\n columns: 1,\n fields: [\n {\n key: 'modelId',\n label: 'Model',\n type: 'model-selector',\n catalog: [...ANIMAL_TYPE_MODELS],\n allowCustom: false,\n allowConversion: false,\n acceptFormats: ['onnx', 'coreml', 'openvino'],\n requiredMetadata: ['inputSize', 'labels'],\n outputFormatHint: 'classification',\n },\n ],\n },\n {\n id: 'runtime',\n title: 'Runtime',\n columns: 2,\n fields: [\n {\n key: 'runtime',\n label: 'Runtime',\n type: 'select',\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'onnx', label: 'ONNX Runtime' },\n { value: 'coreml', label: 'CoreML (Apple)' },\n { value: 'openvino', label: 'OpenVINO (Intel)' },\n ],\n },\n {\n key: 'backend',\n label: 'Backend',\n type: 'select',\n showWhen: { field: 'runtime', equals: 'onnx' },\n options: [\n { value: 'auto', label: 'Auto' },\n { value: 'cpu', label: 'CPU' },\n { value: 'coreml', label: 'CoreML' },\n { value: 'cuda', label: 'CUDA (NVIDIA)' },\n ],\n },\n ],\n },\n {\n id: 'thresholds',\n title: 'Classification Settings',\n columns: 1,\n fields: [\n {\n key: 'minConfidence',\n label: 'Minimum Confidence',\n type: 'slider',\n min: 0.05,\n max: 1.0,\n step: 0.05,\n default: 0.3,\n },\n ],\n },\n ],\n }\n }\n\n getClassMap(): ClassMapDefinition {\n return ANIMAL_CLASS_MAP\n }\n\n getModelCatalog(): ModelCatalogEntry[] {\n return [...ANIMAL_TYPE_MODELS]\n }\n\n getAvailableModels(): DetectionModel[] {\n return []\n }\n\n getActiveLabels(): readonly LabelDefinition[] {\n return ANIMAL_TYPE_LABELS\n }\n\n async probe(): Promise<ProbeResult> {\n return {\n available: true,\n runtime: this.engine?.runtime ?? 'onnx',\n device: this.engine?.device ?? 'cpu',\n capabilities: ['fp32'],\n }\n }\n}\n","// Shared image utilities\nexport { jpegToRgb, cropRegion, letterbox, resizeAndNormalize, rgbToGrayscale } from './shared/image-utils.js'\n\n// Postprocessing utilities\nexport { iou, nms, yoloPostprocess } from './shared/postprocess/yolo.js'\nexport { scrfdPostprocess } from './shared/postprocess/scrfd.js'\nexport { l2Normalize, cosineSimilarity } from './shared/postprocess/arcface.js'\nexport { ctcDecode } from './shared/postprocess/paddleocr.js'\nexport { yamnetPostprocess } from './shared/postprocess/yamnet.js'\n\n// Inference engines\nexport { NodeInferenceEngine } from './shared/node-engine.js'\nexport { PythonInferenceEngine } from './shared/python-engine.js'\n\n// Engine resolver\nexport { resolveEngine, probeOnnxBackends } from './shared/engine-resolver.js'\nexport type { EngineResolverOptions, ResolvedEngine } from './shared/engine-resolver.js'\n\n// Motion detection utilities\nexport { detectMotion } from './addons/motion-detection/frame-diff.js'\nexport type { MotionRegion } from './addons/motion-detection/frame-diff.js'\n\n// Model catalogs\nexport * from './catalogs/index.js'\n\n// Addon classes\nexport { default as ObjectDetectionAddon } from './addons/object-detection/index.js'\n// MotionDetectionAddon is NOT a pipeline addon — it is a camera capability\n// (frame-diff motion) injected into pipeline config as a camera-level setting.\nexport { default as FaceDetectionAddon } from './addons/face-detection/index.js'\nexport { default as FaceRecognitionAddon } from './addons/face-recognition/index.js'\nexport { default as PlateDetectionAddon } from './addons/plate-detection/index.js'\nexport { default as PlateRecognitionAddon } from './addons/plate-recognition/index.js'\nexport { default as AudioClassificationAddon } from './addons/audio-classification/index.js'\nexport { default as BirdGlobalClassifierAddon } from './addons/bird-global-classifier/index.js'\nexport { default as BirdNABirdsClassifierAddon } from './addons/bird-nabirds-classifier/index.js'\nexport { default as AnimalClassifierAddon } from './addons/animal-classifier/index.js'\n"],"mappings":"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","names":["detections"]}
|
|
1
|
+
{"version":3,"sources":["../src/catalogs/general-ocr-models.ts"],"sourcesContent":["import type { ModelCatalogEntry, LabelDefinition } from '@camstack/types'\nimport { hfModelUrl } from '@camstack/types'\n\nconst HF_REPO = 'camstack/camstack-models'\n\nconst OCR_TEXT_LABELS: readonly LabelDefinition[] = [\n { id: 'text', name: 'Scene Text' },\n] as const\n\n/**\n * General-purpose OCR models for scene text recognition in camera feeds.\n * These complement the plate-specific PaddleOCR models for broader text detection\n * (signs, labels, addresses, etc.).\n */\nexport const GENERAL_OCR_MODELS: readonly ModelCatalogEntry[] = [\n // ── OnnxTR / docTR — lightweight general scene text recognition ──\n {\n id: 'doctr-det-db-mobilenet',\n name: 'docTR Detection MobileNet',\n description: 'docTR DBNet MobileNet V3 — lightweight text region detection for scene text',\n inputSize: { width: 1024, height: 1024 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/onnx/camstack-doctr-det-db-mobilenet-v3.onnx'),\n sizeMB: 15,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/coreml/camstack-doctr-det-db-mobilenet-v3.mlpackage'),\n sizeMB: 8,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/openvino/camstack-doctr-det-db-mobilenet-v3.xml'),\n sizeMB: 8,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'doctr-rec-crnn-mobilenet',\n name: 'docTR Recognition CRNN MobileNet',\n description: 'docTR CRNN MobileNet V3 — lightweight text recognition for detected regions',\n inputSize: { width: 128, height: 32 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/onnx/camstack-doctr-rec-crnn-mobilenet-v3.onnx'),\n sizeMB: 5,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/coreml/camstack-doctr-rec-crnn-mobilenet-v3.mlpackage'),\n sizeMB: 3,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/openvino/camstack-doctr-rec-crnn-mobilenet-v3.xml'),\n sizeMB: 3,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'doctr-rec-parseq',\n name: 'docTR Recognition PARSeq',\n description: 'docTR PARSeq — high-accuracy scene text recognition (top ICDAR scores)',\n inputSize: { width: 128, height: 32 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/onnx/camstack-doctr-rec-parseq.onnx'),\n sizeMB: 25,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/coreml/camstack-doctr-rec-parseq.mlpackage'),\n sizeMB: 13,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/doctr/openvino/camstack-doctr-rec-parseq.xml'),\n sizeMB: 13,\n runtimes: ['python'],\n },\n },\n },\n\n // ── PaddleOCR PP-OCRv5 Mobile — general-purpose text detection + recognition ──\n {\n id: 'ppocr-v5-det-mobile',\n name: 'PP-OCRv5 Detection Mobile',\n description: 'PP-OCRv5 mobile text detection — optimized for edge, 100+ languages',\n inputSize: { width: 640, height: 640 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-det-mobile.onnx'),\n sizeMB: 6,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-det-mobile.mlpackage'),\n sizeMB: 3,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-det-mobile.xml'),\n sizeMB: 3,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'ppocr-v5-rec-mobile',\n name: 'PP-OCRv5 Recognition Mobile',\n description: 'PP-OCRv5 mobile text recognition — 100+ languages, CTC decoding',\n inputSize: { width: 320, height: 48 },\n labels: OCR_TEXT_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/onnx/camstack-ppocr-v5-rec-mobile.onnx'),\n sizeMB: 8,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/coreml/camstack-ppocr-v5-rec-mobile.mlpackage'),\n sizeMB: 4,\n isDirectory: true,\n files: [\n 'Manifest.json',\n 'Data/com.apple.CoreML/model.mlmodel',\n 'Data/com.apple.CoreML/weights/weight.bin',\n ],\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/openvino/camstack-ppocr-v5-rec-mobile.xml'),\n sizeMB: 4,\n runtimes: ['python'],\n },\n },\n extraFiles: [\n {\n url: hfModelUrl(HF_REPO, 'generalOcr/ppocr-v5/camstack-ppocr-v5-keys.txt'),\n filename: 'camstack-ppocr-v5-keys.txt',\n sizeMB: 0.1,\n },\n ],\n },\n] as const\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-vision",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Builtin detection addons for CamStack — object detection, face, plate, audio, motion",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
25
26
|
"import": "./dist/index.mjs",
|
|
26
|
-
"require": "./dist/index.js"
|
|
27
|
-
"types": "./dist/index.d.ts"
|
|
27
|
+
"require": "./dist/index.js"
|
|
28
28
|
},
|
|
29
29
|
"./addons/*": {
|
|
30
|
+
"types": "./dist/addons/*/index.d.ts",
|
|
30
31
|
"import": "./dist/addons/*/index.mjs",
|
|
31
|
-
"require": "./dist/addons/*/index.js"
|
|
32
|
-
"types": "./dist/addons/*/index.d.ts"
|
|
32
|
+
"require": "./dist/addons/*/index.js"
|
|
33
33
|
},
|
|
34
34
|
"./package.json": "./package.json"
|
|
35
35
|
},
|
package/dist/chunk-2YMA6QOV.mjs
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
require_yolo
|
|
3
|
-
} from "./chunk-DE7I3VHO.mjs";
|
|
4
|
-
import {
|
|
5
|
-
require_object_detection_models
|
|
6
|
-
} from "./chunk-MGT6RUVX.mjs";
|
|
7
|
-
import {
|
|
8
|
-
__commonJS,
|
|
9
|
-
__require
|
|
10
|
-
} from "./chunk-3IIFBJCD.mjs";
|
|
11
|
-
|
|
12
|
-
// src/shared/postprocess/scrfd.js
|
|
13
|
-
var require_scrfd = __commonJS({
|
|
14
|
-
"src/shared/postprocess/scrfd.js"(exports) {
|
|
15
|
-
"use strict";
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.scrfdPostprocess = scrfdPostprocess;
|
|
18
|
-
var yolo_js_1 = require_yolo();
|
|
19
|
-
var STRIDES = [8, 16, 32];
|
|
20
|
-
var NUM_ANCHORS_PER_STRIDE = 2;
|
|
21
|
-
function generateAnchors(stride, inputSize) {
|
|
22
|
-
const featureSize = Math.ceil(inputSize / stride);
|
|
23
|
-
const anchors = [];
|
|
24
|
-
for (let y = 0; y < featureSize; y++) {
|
|
25
|
-
for (let x = 0; x < featureSize; x++) {
|
|
26
|
-
for (let k = 0; k < NUM_ANCHORS_PER_STRIDE; k++) {
|
|
27
|
-
anchors.push({
|
|
28
|
-
cx: (x + 0.5) * stride,
|
|
29
|
-
cy: (y + 0.5) * stride
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return anchors;
|
|
35
|
-
}
|
|
36
|
-
function scrfdPostprocess(outputs, confidence, inputSize, originalWidth, originalHeight) {
|
|
37
|
-
const scaleX = originalWidth / inputSize;
|
|
38
|
-
const scaleY = originalHeight / inputSize;
|
|
39
|
-
const candidates = [];
|
|
40
|
-
for (const stride of STRIDES) {
|
|
41
|
-
const scoreKey = Object.keys(outputs).find((k) => k.includes(`score_${stride}`) || k.includes(`_${stride}_score`));
|
|
42
|
-
const bboxKey = Object.keys(outputs).find((k) => k.includes(`bbox_${stride}`) || k.includes(`_${stride}_bbox`));
|
|
43
|
-
const kpsKey = Object.keys(outputs).find((k) => k.includes(`kps_${stride}`) || k.includes(`_${stride}_kps`));
|
|
44
|
-
if (!scoreKey || !bboxKey)
|
|
45
|
-
continue;
|
|
46
|
-
const scores = outputs[scoreKey];
|
|
47
|
-
const bboxes = outputs[bboxKey];
|
|
48
|
-
const kps = kpsKey ? outputs[kpsKey] : void 0;
|
|
49
|
-
const anchors = generateAnchors(stride, inputSize);
|
|
50
|
-
const n = anchors.length;
|
|
51
|
-
for (let i = 0; i < n; i++) {
|
|
52
|
-
const score = scores[i];
|
|
53
|
-
if (score < confidence)
|
|
54
|
-
continue;
|
|
55
|
-
const anchor = anchors[i];
|
|
56
|
-
const x1 = anchor.cx - bboxes[i * 4] * stride;
|
|
57
|
-
const y1 = anchor.cy - bboxes[i * 4 + 1] * stride;
|
|
58
|
-
const x2 = anchor.cx + bboxes[i * 4 + 2] * stride;
|
|
59
|
-
const y2 = anchor.cy + bboxes[i * 4 + 3] * stride;
|
|
60
|
-
const bbox = {
|
|
61
|
-
x: x1 * scaleX,
|
|
62
|
-
y: y1 * scaleY,
|
|
63
|
-
w: (x2 - x1) * scaleX,
|
|
64
|
-
h: (y2 - y1) * scaleY
|
|
65
|
-
};
|
|
66
|
-
let landmarks;
|
|
67
|
-
if (kps) {
|
|
68
|
-
const pts = [];
|
|
69
|
-
for (let p = 0; p < 5; p++) {
|
|
70
|
-
pts.push({
|
|
71
|
-
x: (anchor.cx + kps[i * 10 + p * 2] * stride) * scaleX,
|
|
72
|
-
y: (anchor.cy + kps[i * 10 + p * 2 + 1] * stride) * scaleY
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
landmarks = pts;
|
|
76
|
-
}
|
|
77
|
-
candidates.push({ bbox, score, landmarks });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (candidates.length === 0)
|
|
81
|
-
return [];
|
|
82
|
-
const keptIndices = (0, yolo_js_1.nms)(candidates, 0.45);
|
|
83
|
-
return keptIndices.map((idx) => {
|
|
84
|
-
const { bbox, score, landmarks } = candidates[idx];
|
|
85
|
-
return {
|
|
86
|
-
class: "face",
|
|
87
|
-
originalClass: "face",
|
|
88
|
-
score,
|
|
89
|
-
bbox,
|
|
90
|
-
...landmarks ? { landmarks } : {}
|
|
91
|
-
};
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// src/catalogs/face-detection-models.js
|
|
98
|
-
var require_face_detection_models = __commonJS({
|
|
99
|
-
"src/catalogs/face-detection-models.js"(exports) {
|
|
100
|
-
"use strict";
|
|
101
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
102
|
-
exports.FACE_DETECTION_MODELS = void 0;
|
|
103
|
-
var types_1 = __require("@camstack/types");
|
|
104
|
-
var object_detection_models_js_1 = require_object_detection_models();
|
|
105
|
-
var HF_REPO = "camstack/camstack-models";
|
|
106
|
-
var FACE_LABELS = [
|
|
107
|
-
{ id: "face", name: "Face" }
|
|
108
|
-
];
|
|
109
|
-
exports.FACE_DETECTION_MODELS = [
|
|
110
|
-
{
|
|
111
|
-
id: "scrfd-500m",
|
|
112
|
-
name: "SCRFD 500M",
|
|
113
|
-
description: "SCRFD 500M \u2014 ultra-lightweight face detector",
|
|
114
|
-
inputSize: { width: 640, height: 640 },
|
|
115
|
-
labels: FACE_LABELS,
|
|
116
|
-
formats: {
|
|
117
|
-
onnx: {
|
|
118
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/onnx/camstack-scrfd-500m.onnx"),
|
|
119
|
-
sizeMB: 2.2
|
|
120
|
-
},
|
|
121
|
-
coreml: {
|
|
122
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/coreml/camstack-scrfd-500m.mlpackage"),
|
|
123
|
-
sizeMB: 1.2,
|
|
124
|
-
isDirectory: true,
|
|
125
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
126
|
-
runtimes: ["python"]
|
|
127
|
-
},
|
|
128
|
-
openvino: {
|
|
129
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/openvino/camstack-scrfd-500m.xml"),
|
|
130
|
-
sizeMB: 1.3,
|
|
131
|
-
runtimes: ["python"]
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
id: "scrfd-2.5g",
|
|
137
|
-
name: "SCRFD 2.5G",
|
|
138
|
-
description: "SCRFD 2.5G \u2014 balanced face detection model",
|
|
139
|
-
inputSize: { width: 640, height: 640 },
|
|
140
|
-
labels: FACE_LABELS,
|
|
141
|
-
formats: {
|
|
142
|
-
onnx: {
|
|
143
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx"),
|
|
144
|
-
sizeMB: 3.1
|
|
145
|
-
},
|
|
146
|
-
coreml: {
|
|
147
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage"),
|
|
148
|
-
sizeMB: 1.7,
|
|
149
|
-
isDirectory: true,
|
|
150
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
151
|
-
runtimes: ["python"]
|
|
152
|
-
},
|
|
153
|
-
openvino: {
|
|
154
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml"),
|
|
155
|
-
sizeMB: 1.8,
|
|
156
|
-
runtimes: ["python"]
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
id: "scrfd-10g",
|
|
162
|
-
name: "SCRFD 10G",
|
|
163
|
-
description: "SCRFD 10G \u2014 high-accuracy face detector",
|
|
164
|
-
inputSize: { width: 640, height: 640 },
|
|
165
|
-
labels: FACE_LABELS,
|
|
166
|
-
formats: {
|
|
167
|
-
onnx: {
|
|
168
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/onnx/camstack-scrfd-10g.onnx"),
|
|
169
|
-
sizeMB: 16
|
|
170
|
-
},
|
|
171
|
-
coreml: {
|
|
172
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/coreml/camstack-scrfd-10g.mlpackage"),
|
|
173
|
-
sizeMB: 8.2,
|
|
174
|
-
isDirectory: true,
|
|
175
|
-
files: object_detection_models_js_1.MLPACKAGE_FILES,
|
|
176
|
-
runtimes: ["python"]
|
|
177
|
-
},
|
|
178
|
-
openvino: {
|
|
179
|
-
url: (0, types_1.hfModelUrl)(HF_REPO, "faceDetection/scrfd/openvino/camstack-scrfd-10g.xml"),
|
|
180
|
-
sizeMB: 8.3,
|
|
181
|
-
runtimes: ["python"]
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
];
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
export {
|
|
190
|
-
require_scrfd,
|
|
191
|
-
require_face_detection_models
|
|
192
|
-
};
|
|
193
|
-
//# sourceMappingURL=chunk-2YMA6QOV.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/postprocess/scrfd.ts","../src/catalogs/face-detection-models.ts"],"sourcesContent":["import type { SpatialDetection, BoundingBox, Landmark } from '@camstack/types'\nimport { iou, nms } from './yolo.js'\n\nexport interface ScrfdRawOutputs {\n readonly [key: string]: Float32Array\n}\n\nconst STRIDES = [8, 16, 32] as const\nconst NUM_ANCHORS_PER_STRIDE = 2\n\n/** Generate anchor points for a given stride and input size */\nfunction generateAnchors(stride: number, inputSize: number): Array<{ cx: number; cy: number }> {\n const featureSize = Math.ceil(inputSize / stride)\n const anchors: Array<{ cx: number; cy: number }> = []\n for (let y = 0; y < featureSize; y++) {\n for (let x = 0; x < featureSize; x++) {\n for (let k = 0; k < NUM_ANCHORS_PER_STRIDE; k++) {\n anchors.push({\n cx: (x + 0.5) * stride,\n cy: (y + 0.5) * stride,\n })\n }\n }\n }\n return anchors\n}\n\nexport function scrfdPostprocess(\n outputs: ScrfdRawOutputs,\n confidence: number,\n inputSize: number,\n originalWidth: number,\n originalHeight: number,\n): SpatialDetection[] {\n // Scale factor from letterbox (assume square crop, so same scale both axes)\n const scaleX = originalWidth / inputSize\n const scaleY = originalHeight / inputSize\n\n interface Candidate {\n readonly bbox: BoundingBox\n readonly score: number\n readonly landmarks?: readonly Landmark[]\n }\n\n const candidates: Candidate[] = []\n\n for (const stride of STRIDES) {\n const scoreKey = Object.keys(outputs).find((k) => k.includes(`score_${stride}`) || k.includes(`_${stride}_score`))\n const bboxKey = Object.keys(outputs).find((k) => k.includes(`bbox_${stride}`) || k.includes(`_${stride}_bbox`))\n const kpsKey = Object.keys(outputs).find((k) => k.includes(`kps_${stride}`) || k.includes(`_${stride}_kps`))\n\n if (!scoreKey || !bboxKey) continue\n\n const scores = outputs[scoreKey]!\n const bboxes = outputs[bboxKey]!\n const kps = kpsKey ? outputs[kpsKey] : undefined\n const anchors = generateAnchors(stride, inputSize)\n\n const n = anchors.length\n\n for (let i = 0; i < n; i++) {\n const score = scores[i]!\n if (score < confidence) continue\n\n const anchor = anchors[i]!\n\n // Bboxes are relative to the anchor center in stride units, scaled by stride\n const x1 = anchor.cx - bboxes[i * 4]! * stride\n const y1 = anchor.cy - bboxes[i * 4 + 1]! * stride\n const x2 = anchor.cx + bboxes[i * 4 + 2]! * stride\n const y2 = anchor.cy + bboxes[i * 4 + 3]! * stride\n\n const bbox: BoundingBox = {\n x: x1 * scaleX,\n y: y1 * scaleY,\n w: (x2 - x1) * scaleX,\n h: (y2 - y1) * scaleY,\n }\n\n let landmarks: readonly Landmark[] | undefined\n if (kps) {\n const pts: Landmark[] = []\n for (let p = 0; p < 5; p++) {\n pts.push({\n x: (anchor.cx + kps[i * 10 + p * 2]! * stride) * scaleX,\n y: (anchor.cy + kps[i * 10 + p * 2 + 1]! * stride) * scaleY,\n })\n }\n landmarks = pts\n }\n\n candidates.push({ bbox, score, landmarks })\n }\n }\n\n if (candidates.length === 0) return []\n\n const keptIndices = nms(candidates, 0.45)\n\n return keptIndices.map((idx) => {\n const { bbox, score, landmarks } = candidates[idx]!\n return {\n class: 'face',\n originalClass: 'face',\n score,\n bbox,\n ...(landmarks ? { landmarks } : {}),\n } satisfies SpatialDetection\n })\n}\n","import type { ModelCatalogEntry, LabelDefinition } from '@camstack/types'\nimport { hfModelUrl } from '@camstack/types'\nimport { MLPACKAGE_FILES } from './object-detection-models.js'\n\nconst HF_REPO = 'camstack/camstack-models'\n\nconst FACE_LABELS: readonly LabelDefinition[] = [\n { id: 'face', name: 'Face' },\n] as const\n\nexport const FACE_DETECTION_MODELS: readonly ModelCatalogEntry[] = [\n {\n id: 'scrfd-500m',\n name: 'SCRFD 500M',\n description: 'SCRFD 500M — ultra-lightweight face detector',\n inputSize: { width: 640, height: 640 },\n labels: FACE_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/onnx/camstack-scrfd-500m.onnx'),\n sizeMB: 2.2,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/coreml/camstack-scrfd-500m.mlpackage'),\n sizeMB: 1.2,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/openvino/camstack-scrfd-500m.xml'),\n sizeMB: 1.3,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'scrfd-2.5g',\n name: 'SCRFD 2.5G',\n description: 'SCRFD 2.5G — balanced face detection model',\n inputSize: { width: 640, height: 640 },\n labels: FACE_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx'),\n sizeMB: 3.1,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage'),\n sizeMB: 1.7,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml'),\n sizeMB: 1.8,\n runtimes: ['python'],\n },\n },\n },\n {\n id: 'scrfd-10g',\n name: 'SCRFD 10G',\n description: 'SCRFD 10G — high-accuracy face detector',\n inputSize: { width: 640, height: 640 },\n labels: FACE_LABELS,\n formats: {\n onnx: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/onnx/camstack-scrfd-10g.onnx'),\n sizeMB: 16,\n },\n coreml: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/coreml/camstack-scrfd-10g.mlpackage'),\n sizeMB: 8.2,\n isDirectory: true,\n files: MLPACKAGE_FILES,\n runtimes: ['python'],\n },\n openvino: {\n url: hfModelUrl(HF_REPO, 'faceDetection/scrfd/openvino/camstack-scrfd-10g.xml'),\n sizeMB: 8.3,\n runtimes: ['python'],\n },\n },\n },\n] as const\n"],"mappings":"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","names":[]}
|