@camstack/addon-vision 0.1.1 → 0.1.3

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.
Files changed (111) hide show
  1. package/dist/addons/animal-classifier/index.js +999 -823
  2. package/dist/addons/animal-classifier/index.js.map +1 -1
  3. package/dist/addons/animal-classifier/index.mjs +242 -7
  4. package/dist/addons/animal-classifier/index.mjs.map +1 -1
  5. package/dist/addons/audio-classification/index.js +501 -379
  6. package/dist/addons/audio-classification/index.js.map +1 -1
  7. package/dist/addons/audio-classification/index.mjs +224 -4
  8. package/dist/addons/audio-classification/index.mjs.map +1 -1
  9. package/dist/addons/bird-global-classifier/index.js +1002 -826
  10. package/dist/addons/bird-global-classifier/index.js.map +1 -1
  11. package/dist/addons/bird-global-classifier/index.mjs +248 -7
  12. package/dist/addons/bird-global-classifier/index.mjs.map +1 -1
  13. package/dist/addons/bird-nabirds-classifier/index.js +1002 -826
  14. package/dist/addons/bird-nabirds-classifier/index.js.map +1 -1
  15. package/dist/addons/bird-nabirds-classifier/index.mjs +289 -7
  16. package/dist/addons/bird-nabirds-classifier/index.mjs.map +1 -1
  17. package/dist/addons/face-detection/index.js +1196 -935
  18. package/dist/addons/face-detection/index.js.map +1 -1
  19. package/dist/addons/face-detection/index.mjs +227 -7
  20. package/dist/addons/face-detection/index.mjs.map +1 -1
  21. package/dist/addons/face-recognition/index.js +1003 -808
  22. package/dist/addons/face-recognition/index.js.map +1 -1
  23. package/dist/addons/face-recognition/index.mjs +197 -6
  24. package/dist/addons/face-recognition/index.mjs.map +1 -1
  25. package/dist/addons/motion-detection/index.js +214 -111
  26. package/dist/addons/motion-detection/index.js.map +1 -1
  27. package/dist/addons/motion-detection/index.mjs +12 -9
  28. package/dist/addons/motion-detection/index.mjs.map +1 -1
  29. package/dist/addons/object-detection/index.js +1287 -1083
  30. package/dist/addons/object-detection/index.js.map +1 -1
  31. package/dist/addons/object-detection/index.mjs +373 -7
  32. package/dist/addons/object-detection/index.mjs.map +1 -1
  33. package/dist/addons/plate-detection/index.js +1075 -869
  34. package/dist/addons/plate-detection/index.js.map +1 -1
  35. package/dist/addons/plate-detection/index.mjs +230 -7
  36. package/dist/addons/plate-detection/index.mjs.map +1 -1
  37. package/dist/addons/plate-recognition/index.js +684 -506
  38. package/dist/addons/plate-recognition/index.js.map +1 -1
  39. package/dist/addons/plate-recognition/index.mjs +244 -5
  40. package/dist/addons/plate-recognition/index.mjs.map +1 -1
  41. package/dist/addons/segmentation-refiner/index.js +967 -791
  42. package/dist/addons/segmentation-refiner/index.js.map +1 -1
  43. package/dist/addons/segmentation-refiner/index.mjs +21 -17
  44. package/dist/addons/segmentation-refiner/index.mjs.map +1 -1
  45. package/dist/addons/vehicle-classifier/index.js +581 -411
  46. package/dist/addons/vehicle-classifier/index.js.map +1 -1
  47. package/dist/addons/vehicle-classifier/index.mjs +20 -16
  48. package/dist/addons/vehicle-classifier/index.mjs.map +1 -1
  49. package/dist/chunk-2YMA6QOV.mjs +193 -0
  50. package/dist/chunk-2YMA6QOV.mjs.map +1 -0
  51. package/dist/chunk-3IIFBJCD.mjs +45 -0
  52. package/dist/chunk-BS4DKYGN.mjs +48 -0
  53. package/dist/{chunk-7DYHXUPZ.mjs.map → chunk-BS4DKYGN.mjs.map} +1 -1
  54. package/dist/chunk-DE7I3VHO.mjs +106 -0
  55. package/dist/{chunk-KUO2BVFY.mjs.map → chunk-DE7I3VHO.mjs.map} +1 -1
  56. package/dist/chunk-F6D2OZ36.mjs +89 -0
  57. package/dist/chunk-F6D2OZ36.mjs.map +1 -0
  58. package/dist/chunk-GAOIFQDX.mjs +59 -0
  59. package/dist/chunk-GAOIFQDX.mjs.map +1 -0
  60. package/dist/chunk-HUIX2XVR.mjs +159 -0
  61. package/dist/chunk-HUIX2XVR.mjs.map +1 -0
  62. package/dist/chunk-K36R6HWY.mjs +51 -0
  63. package/dist/{chunk-XZ6ZMXXU.mjs.map → chunk-K36R6HWY.mjs.map} +1 -1
  64. package/dist/chunk-MBTAI3WE.mjs +78 -0
  65. package/dist/chunk-MBTAI3WE.mjs.map +1 -0
  66. package/dist/chunk-MGT6RUVX.mjs +423 -0
  67. package/dist/{chunk-BP7H4NFS.mjs.map → chunk-MGT6RUVX.mjs.map} +1 -1
  68. package/dist/chunk-PIFS7AIT.mjs +446 -0
  69. package/dist/chunk-PIFS7AIT.mjs.map +1 -0
  70. package/dist/chunk-WG66JYYW.mjs +116 -0
  71. package/dist/{chunk-22BHCDT5.mjs.map → chunk-WG66JYYW.mjs.map} +1 -1
  72. package/dist/chunk-XD7WGXHZ.mjs +82 -0
  73. package/dist/{chunk-DUN6XU3N.mjs.map → chunk-XD7WGXHZ.mjs.map} +1 -1
  74. package/dist/chunk-YYDM6V2F.mjs +113 -0
  75. package/dist/{chunk-BR2FPGOX.mjs.map → chunk-YYDM6V2F.mjs.map} +1 -1
  76. package/dist/chunk-ZK7P3TZN.mjs +286 -0
  77. package/dist/chunk-ZK7P3TZN.mjs.map +1 -0
  78. package/dist/index.js +4443 -3925
  79. package/dist/index.js.map +1 -1
  80. package/dist/index.mjs +2698 -250
  81. package/dist/index.mjs.map +1 -1
  82. package/package.json +2 -3
  83. package/dist/chunk-22BHCDT5.mjs +0 -101
  84. package/dist/chunk-6DJZZR64.mjs +0 -336
  85. package/dist/chunk-6DJZZR64.mjs.map +0 -1
  86. package/dist/chunk-7DYHXUPZ.mjs +0 -36
  87. package/dist/chunk-BJTO5JO5.mjs +0 -11
  88. package/dist/chunk-BP7H4NFS.mjs +0 -412
  89. package/dist/chunk-BR2FPGOX.mjs +0 -98
  90. package/dist/chunk-DNQNGDR4.mjs +0 -256
  91. package/dist/chunk-DNQNGDR4.mjs.map +0 -1
  92. package/dist/chunk-DUN6XU3N.mjs +0 -72
  93. package/dist/chunk-EPNWLSCG.mjs +0 -387
  94. package/dist/chunk-EPNWLSCG.mjs.map +0 -1
  95. package/dist/chunk-G32RCIUI.mjs +0 -645
  96. package/dist/chunk-G32RCIUI.mjs.map +0 -1
  97. package/dist/chunk-GR65KM6X.mjs +0 -289
  98. package/dist/chunk-GR65KM6X.mjs.map +0 -1
  99. package/dist/chunk-H7LMBTS5.mjs +0 -276
  100. package/dist/chunk-H7LMBTS5.mjs.map +0 -1
  101. package/dist/chunk-IK4XIQPC.mjs +0 -242
  102. package/dist/chunk-IK4XIQPC.mjs.map +0 -1
  103. package/dist/chunk-J6VNIIYX.mjs +0 -269
  104. package/dist/chunk-J6VNIIYX.mjs.map +0 -1
  105. package/dist/chunk-KUO2BVFY.mjs +0 -90
  106. package/dist/chunk-ML2JX43J.mjs +0 -248
  107. package/dist/chunk-ML2JX43J.mjs.map +0 -1
  108. package/dist/chunk-WUMV524J.mjs +0 -379
  109. package/dist/chunk-WUMV524J.mjs.map +0 -1
  110. package/dist/chunk-XZ6ZMXXU.mjs +0 -39
  111. /package/dist/{chunk-BJTO5JO5.mjs.map → chunk-3IIFBJCD.mjs.map} +0 -0
@@ -0,0 +1,116 @@
1
+ import {
2
+ __commonJS,
3
+ __require
4
+ } from "./chunk-3IIFBJCD.mjs";
5
+
6
+ // src/shared/image-utils.js
7
+ var require_image_utils = __commonJS({
8
+ "src/shared/image-utils.js"(exports) {
9
+ "use strict";
10
+ var __importDefault = exports && exports.__importDefault || function(mod) {
11
+ return mod && mod.__esModule ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.jpegToRgb = jpegToRgb;
15
+ exports.cropRegion = cropRegion;
16
+ exports.letterbox = letterbox;
17
+ exports.resizeAndNormalize = resizeAndNormalize;
18
+ exports.rgbToGrayscale = rgbToGrayscale;
19
+ var sharp_1 = __importDefault(__require("sharp"));
20
+ async function jpegToRgb(jpeg) {
21
+ const { data, info } = await (0, sharp_1.default)(jpeg).removeAlpha().raw().toBuffer({ resolveWithObject: true });
22
+ return { data, width: info.width, height: info.height };
23
+ }
24
+ async function cropRegion(jpeg, roi) {
25
+ return (0, sharp_1.default)(jpeg).extract({
26
+ left: Math.round(roi.x),
27
+ top: Math.round(roi.y),
28
+ width: Math.round(roi.w),
29
+ height: Math.round(roi.h)
30
+ }).jpeg().toBuffer();
31
+ }
32
+ async function letterbox(jpeg, targetSize) {
33
+ const meta = await (0, sharp_1.default)(jpeg).metadata();
34
+ const originalWidth = meta.width ?? 0;
35
+ const originalHeight = meta.height ?? 0;
36
+ const scale = Math.min(targetSize / originalWidth, targetSize / originalHeight);
37
+ const scaledWidth = Math.round(originalWidth * scale);
38
+ const scaledHeight = Math.round(originalHeight * scale);
39
+ const padX = Math.floor((targetSize - scaledWidth) / 2);
40
+ const padY = Math.floor((targetSize - scaledHeight) / 2);
41
+ const { data } = await (0, sharp_1.default)(jpeg).resize(scaledWidth, scaledHeight).extend({
42
+ top: padY,
43
+ bottom: targetSize - scaledHeight - padY,
44
+ left: padX,
45
+ right: targetSize - scaledWidth - padX,
46
+ background: { r: 114, g: 114, b: 114 }
47
+ }).removeAlpha().raw().toBuffer({ resolveWithObject: true });
48
+ const numPixels = targetSize * targetSize;
49
+ const float32 = new Float32Array(3 * numPixels);
50
+ for (let i = 0; i < numPixels; i++) {
51
+ const srcBase = i * 3;
52
+ float32[0 * numPixels + i] = data[srcBase] / 255;
53
+ float32[1 * numPixels + i] = data[srcBase + 1] / 255;
54
+ float32[2 * numPixels + i] = data[srcBase + 2] / 255;
55
+ }
56
+ return { data: float32, scale, padX, padY, originalWidth, originalHeight };
57
+ }
58
+ async function resizeAndNormalize(jpeg, targetWidth, targetHeight, normalization, layout) {
59
+ const { data } = await (0, sharp_1.default)(jpeg).resize(targetWidth, targetHeight, { fit: "fill" }).removeAlpha().raw().toBuffer({ resolveWithObject: true });
60
+ const numPixels = targetWidth * targetHeight;
61
+ const float32 = new Float32Array(3 * numPixels);
62
+ const mean = [0.485, 0.456, 0.406];
63
+ const std = [0.229, 0.224, 0.225];
64
+ if (layout === "nchw") {
65
+ for (let i = 0; i < numPixels; i++) {
66
+ const srcBase = i * 3;
67
+ for (let c = 0; c < 3; c++) {
68
+ const raw = data[srcBase + c] / 255;
69
+ let val;
70
+ if (normalization === "zero-one") {
71
+ val = raw;
72
+ } else if (normalization === "imagenet") {
73
+ val = (raw - mean[c]) / std[c];
74
+ } else {
75
+ val = data[srcBase + c];
76
+ }
77
+ float32[c * numPixels + i] = val;
78
+ }
79
+ }
80
+ } else {
81
+ for (let i = 0; i < numPixels; i++) {
82
+ const srcBase = i * 3;
83
+ for (let c = 0; c < 3; c++) {
84
+ const raw = data[srcBase + c] / 255;
85
+ let val;
86
+ if (normalization === "zero-one") {
87
+ val = raw;
88
+ } else if (normalization === "imagenet") {
89
+ val = (raw - mean[c]) / std[c];
90
+ } else {
91
+ val = data[srcBase + c];
92
+ }
93
+ float32[i * 3 + c] = val;
94
+ }
95
+ }
96
+ }
97
+ return float32;
98
+ }
99
+ function rgbToGrayscale(rgb, width, height) {
100
+ const numPixels = width * height;
101
+ const gray = new Uint8Array(numPixels);
102
+ for (let i = 0; i < numPixels; i++) {
103
+ const r = rgb[i * 3];
104
+ const g = rgb[i * 3 + 1];
105
+ const b = rgb[i * 3 + 2];
106
+ gray[i] = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
107
+ }
108
+ return gray;
109
+ }
110
+ }
111
+ });
112
+
113
+ export {
114
+ require_image_utils
115
+ };
116
+ //# sourceMappingURL=chunk-WG66JYYW.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/image-utils.ts"],"sourcesContent":["import sharp from 'sharp'\nimport type { BoundingBox } from '@camstack/types'\n\n/** Decode JPEG to raw RGB pixels */\nexport async function jpegToRgb(\n jpeg: Buffer,\n): Promise<{ data: Buffer; width: number; height: number }> {\n const { data, info } = await sharp(jpeg)\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n return { data, width: info.width, height: info.height }\n}\n\n/** Crop a region from a JPEG buffer */\nexport async function cropRegion(jpeg: Buffer, roi: BoundingBox): Promise<Buffer> {\n return sharp(jpeg)\n .extract({\n left: Math.round(roi.x),\n top: Math.round(roi.y),\n width: Math.round(roi.w),\n height: Math.round(roi.h),\n })\n .jpeg()\n .toBuffer()\n}\n\n/** Letterbox resize for YOLO: resize preserving aspect ratio, pad to square */\nexport async function letterbox(\n jpeg: Buffer,\n targetSize: number,\n): Promise<{\n data: Float32Array\n scale: number\n padX: number\n padY: number\n originalWidth: number\n originalHeight: number\n}> {\n const meta = await sharp(jpeg).metadata()\n const originalWidth = meta.width ?? 0\n const originalHeight = meta.height ?? 0\n\n const scale = Math.min(targetSize / originalWidth, targetSize / originalHeight)\n const scaledWidth = Math.round(originalWidth * scale)\n const scaledHeight = Math.round(originalHeight * scale)\n\n const padX = Math.floor((targetSize - scaledWidth) / 2)\n const padY = Math.floor((targetSize - scaledHeight) / 2)\n\n const { data } = await sharp(jpeg)\n .resize(scaledWidth, scaledHeight)\n .extend({\n top: padY,\n bottom: targetSize - scaledHeight - padY,\n left: padX,\n right: targetSize - scaledWidth - padX,\n background: { r: 114, g: 114, b: 114 },\n })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n // Convert HWC uint8 to CHW float [0,1]\n const numPixels = targetSize * targetSize\n const float32 = new Float32Array(3 * numPixels)\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n float32[0 * numPixels + i] = (data[srcBase]! / 255)\n float32[1 * numPixels + i] = (data[srcBase + 1]! / 255)\n float32[2 * numPixels + i] = (data[srcBase + 2]! / 255)\n }\n\n return { data: float32, scale, padX, padY, originalWidth, originalHeight }\n}\n\n/** Resize and normalize to Float32Array */\nexport async function resizeAndNormalize(\n jpeg: Buffer,\n targetWidth: number,\n targetHeight: number,\n normalization: 'zero-one' | 'imagenet' | 'none',\n layout: 'nchw' | 'nhwc',\n): Promise<Float32Array> {\n const { data } = await sharp(jpeg)\n .resize(targetWidth, targetHeight, { fit: 'fill' })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n const numPixels = targetWidth * targetHeight\n const float32 = new Float32Array(3 * numPixels)\n\n // ImageNet mean and std per channel\n const mean = [0.485, 0.456, 0.406]\n const std = [0.229, 0.224, 0.225]\n\n if (layout === 'nchw') {\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[c * numPixels + i] = val\n }\n }\n } else {\n // nhwc\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[i * 3 + c] = val\n }\n }\n }\n\n return float32\n}\n\n/** Convert raw RGB to grayscale Uint8Array */\nexport function rgbToGrayscale(rgb: Buffer, width: number, height: number): Uint8Array {\n const numPixels = width * height\n const gray = new Uint8Array(numPixels)\n for (let i = 0; i < numPixels; i++) {\n const r = rgb[i * 3]!\n const g = rgb[i * 3 + 1]!\n const b = rgb[i * 3 + 2]!\n // BT.601 luma\n gray[i] = Math.round(0.299 * r + 0.587 * g + 0.114 * b)\n }\n return gray\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/shared/image-utils.ts"],"sourcesContent":["import sharp from 'sharp'\nimport type { BoundingBox } from '@camstack/types'\n\n/** Decode JPEG to raw RGB pixels */\nexport async function jpegToRgb(\n jpeg: Buffer,\n): Promise<{ data: Buffer; width: number; height: number }> {\n const { data, info } = await sharp(jpeg)\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n return { data, width: info.width, height: info.height }\n}\n\n/** Crop a region from a JPEG buffer */\nexport async function cropRegion(jpeg: Buffer, roi: BoundingBox): Promise<Buffer> {\n return sharp(jpeg)\n .extract({\n left: Math.round(roi.x),\n top: Math.round(roi.y),\n width: Math.round(roi.w),\n height: Math.round(roi.h),\n })\n .jpeg()\n .toBuffer()\n}\n\n/** Letterbox resize for YOLO: resize preserving aspect ratio, pad to square */\nexport async function letterbox(\n jpeg: Buffer,\n targetSize: number,\n): Promise<{\n data: Float32Array\n scale: number\n padX: number\n padY: number\n originalWidth: number\n originalHeight: number\n}> {\n const meta = await sharp(jpeg).metadata()\n const originalWidth = meta.width ?? 0\n const originalHeight = meta.height ?? 0\n\n const scale = Math.min(targetSize / originalWidth, targetSize / originalHeight)\n const scaledWidth = Math.round(originalWidth * scale)\n const scaledHeight = Math.round(originalHeight * scale)\n\n const padX = Math.floor((targetSize - scaledWidth) / 2)\n const padY = Math.floor((targetSize - scaledHeight) / 2)\n\n const { data } = await sharp(jpeg)\n .resize(scaledWidth, scaledHeight)\n .extend({\n top: padY,\n bottom: targetSize - scaledHeight - padY,\n left: padX,\n right: targetSize - scaledWidth - padX,\n background: { r: 114, g: 114, b: 114 },\n })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n // Convert HWC uint8 to CHW float [0,1]\n const numPixels = targetSize * targetSize\n const float32 = new Float32Array(3 * numPixels)\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n float32[0 * numPixels + i] = (data[srcBase]! / 255)\n float32[1 * numPixels + i] = (data[srcBase + 1]! / 255)\n float32[2 * numPixels + i] = (data[srcBase + 2]! / 255)\n }\n\n return { data: float32, scale, padX, padY, originalWidth, originalHeight }\n}\n\n/** Resize and normalize to Float32Array */\nexport async function resizeAndNormalize(\n jpeg: Buffer,\n targetWidth: number,\n targetHeight: number,\n normalization: 'zero-one' | 'imagenet' | 'none',\n layout: 'nchw' | 'nhwc',\n): Promise<Float32Array> {\n const { data } = await sharp(jpeg)\n .resize(targetWidth, targetHeight, { fit: 'fill' })\n .removeAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true })\n\n const numPixels = targetWidth * targetHeight\n const float32 = new Float32Array(3 * numPixels)\n\n // ImageNet mean and std per channel\n const mean = [0.485, 0.456, 0.406]\n const std = [0.229, 0.224, 0.225]\n\n if (layout === 'nchw') {\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[c * numPixels + i] = val\n }\n }\n } else {\n // nhwc\n for (let i = 0; i < numPixels; i++) {\n const srcBase = i * 3\n for (let c = 0; c < 3; c++) {\n const raw = data[srcBase + c]! / 255\n let val: number\n if (normalization === 'zero-one') {\n val = raw\n } else if (normalization === 'imagenet') {\n val = (raw - mean[c]!) / std[c]!\n } else {\n val = data[srcBase + c]!\n }\n float32[i * 3 + c] = val\n }\n }\n }\n\n return float32\n}\n\n/** Convert raw RGB to grayscale Uint8Array */\nexport function rgbToGrayscale(rgb: Buffer, width: number, height: number): Uint8Array {\n const numPixels = width * height\n const gray = new Uint8Array(numPixels)\n for (let i = 0; i < numPixels; i++) {\n const r = rgb[i * 3]!\n const g = rgb[i * 3 + 1]!\n const b = rgb[i * 3 + 2]!\n // BT.601 luma\n gray[i] = Math.round(0.299 * r + 0.587 * g + 0.114 * b)\n }\n return gray\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,82 @@
1
+ import {
2
+ require_object_detection_models
3
+ } from "./chunk-MGT6RUVX.mjs";
4
+ import {
5
+ __commonJS,
6
+ __require
7
+ } from "./chunk-3IIFBJCD.mjs";
8
+
9
+ // src/catalogs/animal-classification-models.js
10
+ var require_animal_classification_models = __commonJS({
11
+ "src/catalogs/animal-classification-models.js"(exports) {
12
+ "use strict";
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.ANIMAL_TYPE_MODELS = exports.BIRD_NABIRDS_MODELS = exports.BIRD_SPECIES_MODELS = void 0;
15
+ var types_1 = __require("@camstack/types");
16
+ var object_detection_models_js_1 = require_object_detection_models();
17
+ var HF_REPO = "camstack/camstack-models";
18
+ var hf = (path) => (0, types_1.hfModelUrl)(HF_REPO, path);
19
+ var BIRD_LABEL = { id: "species", name: "Bird Species" };
20
+ var ANIMAL_TYPE_LABEL = { id: "animal-type", name: "Animal Type" };
21
+ exports.BIRD_SPECIES_MODELS = [
22
+ {
23
+ id: "bird-species-525",
24
+ name: "Bird Species (525)",
25
+ description: "EfficientNet bird species classifier \u2014 525 species, MIT license",
26
+ inputSize: { width: 224, height: 224 },
27
+ inputNormalization: "imagenet",
28
+ labels: [BIRD_LABEL],
29
+ formats: {
30
+ onnx: { url: hf("animalClassification/bird-species/onnx/camstack-bird-species-525.onnx"), sizeMB: 32 }
31
+ },
32
+ extraFiles: [
33
+ {
34
+ url: hf("animalClassification/bird-species/onnx/camstack-bird-species-525-labels.json"),
35
+ filename: "camstack-bird-species-525-labels.json",
36
+ sizeMB: 0.02
37
+ }
38
+ ]
39
+ }
40
+ ];
41
+ exports.BIRD_NABIRDS_MODELS = [
42
+ {
43
+ id: "bird-nabirds-404",
44
+ name: "NABirds (404 species)",
45
+ description: "ResNet50 trained on NABirds \u2014 404 North American species with ONNX, CoreML, OpenVINO",
46
+ inputSize: { width: 224, height: 224 },
47
+ inputNormalization: "imagenet",
48
+ labels: [{ id: "species", name: "Bird Species" }],
49
+ formats: {
50
+ onnx: { url: hf("animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404.onnx"), sizeMB: 93 },
51
+ coreml: { url: hf("animalClassification/bird-nabirds/coreml/camstack-bird-nabirds-404.mlpackage"), sizeMB: 47, isDirectory: true, files: object_detection_models_js_1.MLPACKAGE_FILES, runtimes: ["python"] },
52
+ openvino: { url: hf("animalClassification/bird-nabirds/openvino/camstack-bird-nabirds-404.xml"), sizeMB: 47, runtimes: ["python"] }
53
+ },
54
+ extraFiles: [
55
+ {
56
+ url: hf("animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404-labels.json"),
57
+ filename: "camstack-bird-nabirds-404-labels.json",
58
+ sizeMB: 0.02
59
+ }
60
+ ]
61
+ }
62
+ ];
63
+ exports.ANIMAL_TYPE_MODELS = [
64
+ {
65
+ id: "animals-10",
66
+ name: "Animal Classifier (10)",
67
+ description: "ViT-based animal type classifier \u2014 cat, cow, dog, dolphin, eagle, panda, horse, monkey, sheep, spider",
68
+ inputSize: { width: 224, height: 224 },
69
+ inputNormalization: "imagenet",
70
+ labels: [ANIMAL_TYPE_LABEL],
71
+ formats: {
72
+ onnx: { url: hf("animalClassification/animals-10/onnx/camstack-animals-10.onnx"), sizeMB: 328 }
73
+ }
74
+ }
75
+ ];
76
+ }
77
+ });
78
+
79
+ export {
80
+ require_animal_classification_models
81
+ };
82
+ //# sourceMappingURL=chunk-XD7WGXHZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/catalogs/animal-classification-models.ts"],"sourcesContent":["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 hf = (path: string) => hfModelUrl(HF_REPO, path)\n\nconst BIRD_LABEL: LabelDefinition = { id: 'species', name: 'Bird Species' }\nconst ANIMAL_TYPE_LABEL: LabelDefinition = { id: 'animal-type', name: 'Animal Type' }\n\nexport const BIRD_SPECIES_MODELS: readonly ModelCatalogEntry[] = [\n {\n id: 'bird-species-525',\n name: 'Bird Species (525)',\n description: 'EfficientNet bird species classifier — 525 species, MIT license',\n inputSize: { width: 224, height: 224 },\n inputNormalization: 'imagenet',\n labels: [BIRD_LABEL],\n formats: {\n onnx: { url: hf('animalClassification/bird-species/onnx/camstack-bird-species-525.onnx'), sizeMB: 32 },\n },\n extraFiles: [\n {\n url: hf('animalClassification/bird-species/onnx/camstack-bird-species-525-labels.json'),\n filename: 'camstack-bird-species-525-labels.json',\n sizeMB: 0.02,\n },\n ],\n },\n] as const\n\nexport const BIRD_NABIRDS_MODELS: readonly ModelCatalogEntry[] = [\n {\n id: 'bird-nabirds-404',\n name: 'NABirds (404 species)',\n description: 'ResNet50 trained on NABirds — 404 North American species with ONNX, CoreML, OpenVINO',\n inputSize: { width: 224, height: 224 },\n inputNormalization: 'imagenet',\n labels: [{ id: 'species', name: 'Bird Species' }],\n formats: {\n onnx: { url: hf('animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404.onnx'), sizeMB: 93 },\n coreml: { url: hf('animalClassification/bird-nabirds/coreml/camstack-bird-nabirds-404.mlpackage'), sizeMB: 47, isDirectory: true, files: MLPACKAGE_FILES, runtimes: ['python'] },\n openvino: { url: hf('animalClassification/bird-nabirds/openvino/camstack-bird-nabirds-404.xml'), sizeMB: 47, runtimes: ['python'] },\n },\n extraFiles: [\n {\n url: hf('animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404-labels.json'),\n filename: 'camstack-bird-nabirds-404-labels.json',\n sizeMB: 0.02,\n },\n ],\n },\n] as const\n\nexport const ANIMAL_TYPE_MODELS: readonly ModelCatalogEntry[] = [\n {\n id: 'animals-10',\n name: 'Animal Classifier (10)',\n description: 'ViT-based animal type classifier — cat, cow, dog, dolphin, eagle, panda, horse, monkey, sheep, spider',\n inputSize: { width: 224, height: 224 },\n inputNormalization: 'imagenet',\n labels: [ANIMAL_TYPE_LABEL],\n formats: {\n onnx: { url: hf('animalClassification/animals-10/onnx/camstack-animals-10.onnx'), sizeMB: 328 },\n },\n },\n] as const\n"],"mappings":";;;;;AACA,SAAS,kBAAkB;AAG3B,IAAM,UAAU;AAEhB,IAAM,KAAK,CAAC,SAAiB,WAAW,SAAS,IAAI;AAErD,IAAM,aAA8B,EAAE,IAAI,WAAW,MAAM,eAAe;AAC1E,IAAM,oBAAqC,EAAE,IAAI,eAAe,MAAM,cAAc;AAE7E,IAAM,sBAAoD;AAAA,EAC/D;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IACrC,oBAAoB;AAAA,IACpB,QAAQ,CAAC,UAAU;AAAA,IACnB,SAAS;AAAA,MACP,MAAM,EAAE,KAAK,GAAG,uEAAuE,GAAG,QAAQ,GAAG;AAAA,IACvG;AAAA,IACA,YAAY;AAAA,MACV;AAAA,QACE,KAAK,GAAG,8EAA8E;AAAA,QACtF,UAAU;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,sBAAoD;AAAA,EAC/D;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IACrC,oBAAoB;AAAA,IACpB,QAAQ,CAAC,EAAE,IAAI,WAAW,MAAM,eAAe,CAAC;AAAA,IAChD,SAAS;AAAA,MACP,MAAM,EAAE,KAAK,GAAG,uEAAuE,GAAG,QAAQ,GAAG;AAAA,MACrG,QAAQ,EAAE,KAAK,GAAG,8EAA8E,GAAG,QAAQ,IAAI,aAAa,MAAM,OAAO,iBAAiB,UAAU,CAAC,QAAQ,EAAE;AAAA,MAC/K,UAAU,EAAE,KAAK,GAAG,0EAA0E,GAAG,QAAQ,IAAI,UAAU,CAAC,QAAQ,EAAE;AAAA,IACpI;AAAA,IACA,YAAY;AAAA,MACV;AAAA,QACE,KAAK,GAAG,8EAA8E;AAAA,QACtF,UAAU;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,qBAAmD;AAAA,EAC9D;AAAA,IACE,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,IACrC,oBAAoB;AAAA,IACpB,QAAQ,CAAC,iBAAiB;AAAA,IAC1B,SAAS;AAAA,MACP,MAAM,EAAE,KAAK,GAAG,+DAA+D,GAAG,QAAQ,IAAI;AAAA,IAChG;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/catalogs/animal-classification-models.ts"],"sourcesContent":["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 hf = (path: string) => hfModelUrl(HF_REPO, path)\n\nconst BIRD_LABEL: LabelDefinition = { id: 'species', name: 'Bird Species' }\nconst ANIMAL_TYPE_LABEL: LabelDefinition = { id: 'animal-type', name: 'Animal Type' }\n\nexport const BIRD_SPECIES_MODELS: readonly ModelCatalogEntry[] = [\n {\n id: 'bird-species-525',\n name: 'Bird Species (525)',\n description: 'EfficientNet bird species classifier — 525 species, MIT license',\n inputSize: { width: 224, height: 224 },\n inputNormalization: 'imagenet',\n labels: [BIRD_LABEL],\n formats: {\n onnx: { url: hf('animalClassification/bird-species/onnx/camstack-bird-species-525.onnx'), sizeMB: 32 },\n },\n extraFiles: [\n {\n url: hf('animalClassification/bird-species/onnx/camstack-bird-species-525-labels.json'),\n filename: 'camstack-bird-species-525-labels.json',\n sizeMB: 0.02,\n },\n ],\n },\n] as const\n\nexport const BIRD_NABIRDS_MODELS: readonly ModelCatalogEntry[] = [\n {\n id: 'bird-nabirds-404',\n name: 'NABirds (404 species)',\n description: 'ResNet50 trained on NABirds — 404 North American species with ONNX, CoreML, OpenVINO',\n inputSize: { width: 224, height: 224 },\n inputNormalization: 'imagenet',\n labels: [{ id: 'species', name: 'Bird Species' }],\n formats: {\n onnx: { url: hf('animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404.onnx'), sizeMB: 93 },\n coreml: { url: hf('animalClassification/bird-nabirds/coreml/camstack-bird-nabirds-404.mlpackage'), sizeMB: 47, isDirectory: true, files: MLPACKAGE_FILES, runtimes: ['python'] },\n openvino: { url: hf('animalClassification/bird-nabirds/openvino/camstack-bird-nabirds-404.xml'), sizeMB: 47, runtimes: ['python'] },\n },\n extraFiles: [\n {\n url: hf('animalClassification/bird-nabirds/onnx/camstack-bird-nabirds-404-labels.json'),\n filename: 'camstack-bird-nabirds-404-labels.json',\n sizeMB: 0.02,\n },\n ],\n },\n] as const\n\nexport const ANIMAL_TYPE_MODELS: readonly ModelCatalogEntry[] = [\n {\n id: 'animals-10',\n name: 'Animal Classifier (10)',\n description: 'ViT-based animal type classifier — cat, cow, dog, dolphin, eagle, panda, horse, monkey, sheep, spider',\n inputSize: { width: 224, height: 224 },\n inputNormalization: 'imagenet',\n labels: [ANIMAL_TYPE_LABEL],\n formats: {\n onnx: { url: hf('animalClassification/animals-10/onnx/camstack-animals-10.onnx'), sizeMB: 328 },\n },\n },\n] as const\n"],"mappings":";;;;;;;;;;;;;;AACA,QAAA,UAAA,UAAA,iBAAA;AACA,QAAA,+BAAA;AAEA,QAAM,UAAU;AAEhB,QAAM,KAAK,CAAC,UAAiB,GAAA,QAAA,YAAW,SAAS,IAAI;AAErD,QAAM,aAA8B,EAAE,IAAI,WAAW,MAAM,eAAc;AACzE,QAAM,oBAAqC,EAAE,IAAI,eAAe,MAAM,cAAa;AAEtE,YAAA,sBAAoD;MAC/D;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,oBAAoB;QACpB,QAAQ,CAAC,UAAU;QACnB,SAAS;UACP,MAAM,EAAE,KAAK,GAAG,uEAAuE,GAAG,QAAQ,GAAE;;QAEtG,YAAY;UACV;YACE,KAAK,GAAG,8EAA8E;YACtF,UAAU;YACV,QAAQ;;;;;AAMH,YAAA,sBAAoD;MAC/D;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,oBAAoB;QACpB,QAAQ,CAAC,EAAE,IAAI,WAAW,MAAM,eAAc,CAAE;QAChD,SAAS;UACP,MAAM,EAAE,KAAK,GAAG,uEAAuE,GAAG,QAAQ,GAAE;UACpG,QAAQ,EAAE,KAAK,GAAG,8EAA8E,GAAG,QAAQ,IAAI,aAAa,MAAM,OAAO,6BAAA,iBAAiB,UAAU,CAAC,QAAQ,EAAC;UAC9K,UAAU,EAAE,KAAK,GAAG,0EAA0E,GAAG,QAAQ,IAAI,UAAU,CAAC,QAAQ,EAAC;;QAEnI,YAAY;UACV;YACE,KAAK,GAAG,8EAA8E;YACtF,UAAU;YACV,QAAQ;;;;;AAMH,YAAA,qBAAmD;MAC9D;QACE,IAAI;QACJ,MAAM;QACN,aAAa;QACb,WAAW,EAAE,OAAO,KAAK,QAAQ,IAAG;QACpC,oBAAoB;QACpB,QAAQ,CAAC,iBAAiB;QAC1B,SAAS;UACP,MAAM,EAAE,KAAK,GAAG,+DAA+D,GAAG,QAAQ,IAAG;;;;;;","names":[]}
@@ -0,0 +1,113 @@
1
+ import {
2
+ __commonJS
3
+ } from "./chunk-3IIFBJCD.mjs";
4
+
5
+ // src/addons/motion-detection/frame-diff.js
6
+ var require_frame_diff = __commonJS({
7
+ "src/addons/motion-detection/frame-diff.js"(exports) {
8
+ "use strict";
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.detectMotion = detectMotion;
11
+ function detectMotion(current, previous, width, height, threshold, minArea) {
12
+ const numPixels = width * height;
13
+ const mask = new Uint8Array(numPixels);
14
+ for (let i = 0; i < numPixels; i++) {
15
+ mask[i] = Math.abs((current[i] ?? 0) - (previous[i] ?? 0)) > threshold ? 1 : 0;
16
+ }
17
+ const labels = new Int32Array(numPixels).fill(0);
18
+ const parent = new Int32Array(numPixels + 1).fill(0);
19
+ let nextLabel = 1;
20
+ function findRoot(x) {
21
+ while (parent[x] !== x) {
22
+ parent[x] = parent[parent[x]];
23
+ x = parent[x];
24
+ }
25
+ return x;
26
+ }
27
+ function union(a, b) {
28
+ const ra = findRoot(a);
29
+ const rb = findRoot(b);
30
+ if (ra !== rb)
31
+ parent[rb] = ra;
32
+ return ra;
33
+ }
34
+ for (let i = 0; i <= numPixels; i++) {
35
+ parent[i] = i;
36
+ }
37
+ for (let y = 0; y < height; y++) {
38
+ for (let x = 0; x < width; x++) {
39
+ const idx = y * width + x;
40
+ if (!mask[idx])
41
+ continue;
42
+ const above = y > 0 ? labels[(y - 1) * width + x] ?? 0 : 0;
43
+ const left = x > 0 ? labels[y * width + (x - 1)] ?? 0 : 0;
44
+ if (above === 0 && left === 0) {
45
+ labels[idx] = nextLabel;
46
+ parent[nextLabel] = nextLabel;
47
+ nextLabel++;
48
+ } else if (above !== 0 && left === 0) {
49
+ labels[idx] = above;
50
+ } else if (above === 0 && left !== 0) {
51
+ labels[idx] = left;
52
+ } else {
53
+ labels[idx] = union(above, left);
54
+ }
55
+ }
56
+ }
57
+ for (let i = 0; i < numPixels; i++) {
58
+ if (labels[i]) {
59
+ labels[i] = findRoot(labels[i]);
60
+ }
61
+ }
62
+ const bboxMap = /* @__PURE__ */ new Map();
63
+ for (let y = 0; y < height; y++) {
64
+ for (let x = 0; x < width; x++) {
65
+ const idx = y * width + x;
66
+ const label = labels[idx];
67
+ if (!label)
68
+ continue;
69
+ const diff = Math.abs((current[idx] ?? 0) - (previous[idx] ?? 0));
70
+ const existing = bboxMap.get(label);
71
+ if (existing) {
72
+ existing.minX = Math.min(existing.minX, x);
73
+ existing.minY = Math.min(existing.minY, y);
74
+ existing.maxX = Math.max(existing.maxX, x);
75
+ existing.maxY = Math.max(existing.maxY, y);
76
+ existing.count++;
77
+ existing.intensitySum += diff;
78
+ } else {
79
+ bboxMap.set(label, {
80
+ minX: x,
81
+ minY: y,
82
+ maxX: x,
83
+ maxY: y,
84
+ count: 1,
85
+ intensitySum: diff
86
+ });
87
+ }
88
+ }
89
+ }
90
+ const regions = [];
91
+ for (const [, info] of bboxMap) {
92
+ if (info.count < minArea)
93
+ continue;
94
+ regions.push({
95
+ bbox: {
96
+ x: info.minX,
97
+ y: info.minY,
98
+ w: info.maxX - info.minX + 1,
99
+ h: info.maxY - info.minY + 1
100
+ },
101
+ pixelCount: info.count,
102
+ intensity: info.intensitySum / info.count
103
+ });
104
+ }
105
+ return regions;
106
+ }
107
+ }
108
+ });
109
+
110
+ export {
111
+ require_frame_diff
112
+ };
113
+ //# sourceMappingURL=chunk-YYDM6V2F.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/addons/motion-detection/frame-diff.ts"],"sourcesContent":["import type { BoundingBox } from '@camstack/types'\n\nexport interface MotionRegion {\n readonly bbox: BoundingBox\n readonly pixelCount: number\n readonly intensity: number\n}\n\n/**\n * Detect motion by frame differencing.\n *\n * @param current - Grayscale pixel array for the current frame (Uint8Array, length = width * height)\n * @param previous - Grayscale pixel array for the previous frame\n * @param width - Frame width in pixels\n * @param height - Frame height in pixels\n * @param threshold - Pixel diff threshold 0-255; differences below this are ignored\n * @param minArea - Minimum number of changed pixels for a region to be reported\n */\nexport function detectMotion(\n current: Uint8Array,\n previous: Uint8Array,\n width: number,\n height: number,\n threshold: number,\n minArea: number,\n): MotionRegion[] {\n const numPixels = width * height\n\n // Step 1: Compute binary mask — 1 where abs(current - previous) > threshold\n const mask = new Uint8Array(numPixels)\n for (let i = 0; i < numPixels; i++) {\n mask[i] = Math.abs((current[i] ?? 0) - (previous[i] ?? 0)) > threshold ? 1 : 0\n }\n\n // Step 2: Two-pass connected component labeling\n const labels = new Int32Array(numPixels).fill(0)\n const parent = new Int32Array(numPixels + 1).fill(0)\n let nextLabel = 1\n\n // Union-Find helpers\n function findRoot(x: number): number {\n while (parent[x] !== x) {\n parent[x] = parent[parent[x]!]! // path compression\n x = parent[x]!\n }\n return x\n }\n\n function union(a: number, b: number): number {\n const ra = findRoot(a)\n const rb = findRoot(b)\n if (ra !== rb) parent[rb] = ra\n return ra\n }\n\n // Initialize parent array as identity\n for (let i = 0; i <= numPixels; i++) {\n parent[i] = i\n }\n\n // First pass: assign provisional labels\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x\n if (!mask[idx]) continue\n\n const above = y > 0 ? labels[(y - 1) * width + x] ?? 0 : 0\n const left = x > 0 ? labels[y * width + (x - 1)] ?? 0 : 0\n\n if (above === 0 && left === 0) {\n labels[idx] = nextLabel\n parent[nextLabel] = nextLabel\n nextLabel++\n } else if (above !== 0 && left === 0) {\n labels[idx] = above\n } else if (above === 0 && left !== 0) {\n labels[idx] = left\n } else {\n // Both neighbors — merge\n labels[idx] = union(above, left)\n }\n }\n }\n\n // Second pass: resolve all labels to roots\n for (let i = 0; i < numPixels; i++) {\n if (labels[i]) {\n labels[i] = findRoot(labels[i]!)\n }\n }\n\n // Step 3: Collect bounding boxes and pixel counts per root label\n const bboxMap = new Map<\n number,\n { minX: number; minY: number; maxX: number; maxY: number; count: number; intensitySum: number }\n >()\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x\n const label = labels[idx]\n if (!label) continue\n\n const diff = Math.abs((current[idx] ?? 0) - (previous[idx] ?? 0))\n const existing = bboxMap.get(label)\n if (existing) {\n existing.minX = Math.min(existing.minX, x)\n existing.minY = Math.min(existing.minY, y)\n existing.maxX = Math.max(existing.maxX, x)\n existing.maxY = Math.max(existing.maxY, y)\n existing.count++\n existing.intensitySum += diff\n } else {\n bboxMap.set(label, {\n minX: x,\n minY: y,\n maxX: x,\n maxY: y,\n count: 1,\n intensitySum: diff,\n })\n }\n }\n }\n\n // Step 4: Filter by minimum area and build result\n const regions: MotionRegion[] = []\n for (const [, info] of bboxMap) {\n if (info.count < minArea) continue\n regions.push({\n bbox: {\n x: info.minX,\n y: info.minY,\n w: info.maxX - info.minX + 1,\n h: info.maxY - info.minY + 1,\n },\n pixelCount: info.count,\n intensity: info.intensitySum / info.count,\n })\n }\n\n return regions\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/addons/motion-detection/frame-diff.ts"],"sourcesContent":["import type { BoundingBox } from '@camstack/types'\n\nexport interface MotionRegion {\n readonly bbox: BoundingBox\n readonly pixelCount: number\n readonly intensity: number\n}\n\n/**\n * Detect motion by frame differencing.\n *\n * @param current - Grayscale pixel array for the current frame (Uint8Array, length = width * height)\n * @param previous - Grayscale pixel array for the previous frame\n * @param width - Frame width in pixels\n * @param height - Frame height in pixels\n * @param threshold - Pixel diff threshold 0-255; differences below this are ignored\n * @param minArea - Minimum number of changed pixels for a region to be reported\n */\nexport function detectMotion(\n current: Uint8Array,\n previous: Uint8Array,\n width: number,\n height: number,\n threshold: number,\n minArea: number,\n): MotionRegion[] {\n const numPixels = width * height\n\n // Step 1: Compute binary mask — 1 where abs(current - previous) > threshold\n const mask = new Uint8Array(numPixels)\n for (let i = 0; i < numPixels; i++) {\n mask[i] = Math.abs((current[i] ?? 0) - (previous[i] ?? 0)) > threshold ? 1 : 0\n }\n\n // Step 2: Two-pass connected component labeling\n const labels = new Int32Array(numPixels).fill(0)\n const parent = new Int32Array(numPixels + 1).fill(0)\n let nextLabel = 1\n\n // Union-Find helpers\n function findRoot(x: number): number {\n while (parent[x] !== x) {\n parent[x] = parent[parent[x]!]! // path compression\n x = parent[x]!\n }\n return x\n }\n\n function union(a: number, b: number): number {\n const ra = findRoot(a)\n const rb = findRoot(b)\n if (ra !== rb) parent[rb] = ra\n return ra\n }\n\n // Initialize parent array as identity\n for (let i = 0; i <= numPixels; i++) {\n parent[i] = i\n }\n\n // First pass: assign provisional labels\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x\n if (!mask[idx]) continue\n\n const above = y > 0 ? labels[(y - 1) * width + x] ?? 0 : 0\n const left = x > 0 ? labels[y * width + (x - 1)] ?? 0 : 0\n\n if (above === 0 && left === 0) {\n labels[idx] = nextLabel\n parent[nextLabel] = nextLabel\n nextLabel++\n } else if (above !== 0 && left === 0) {\n labels[idx] = above\n } else if (above === 0 && left !== 0) {\n labels[idx] = left\n } else {\n // Both neighbors — merge\n labels[idx] = union(above, left)\n }\n }\n }\n\n // Second pass: resolve all labels to roots\n for (let i = 0; i < numPixels; i++) {\n if (labels[i]) {\n labels[i] = findRoot(labels[i]!)\n }\n }\n\n // Step 3: Collect bounding boxes and pixel counts per root label\n const bboxMap = new Map<\n number,\n { minX: number; minY: number; maxX: number; maxY: number; count: number; intensitySum: number }\n >()\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x\n const label = labels[idx]\n if (!label) continue\n\n const diff = Math.abs((current[idx] ?? 0) - (previous[idx] ?? 0))\n const existing = bboxMap.get(label)\n if (existing) {\n existing.minX = Math.min(existing.minX, x)\n existing.minY = Math.min(existing.minY, y)\n existing.maxX = Math.max(existing.maxX, x)\n existing.maxY = Math.max(existing.maxY, y)\n existing.count++\n existing.intensitySum += diff\n } else {\n bboxMap.set(label, {\n minX: x,\n minY: y,\n maxX: x,\n maxY: y,\n count: 1,\n intensitySum: diff,\n })\n }\n }\n }\n\n // Step 4: Filter by minimum area and build result\n const regions: MotionRegion[] = []\n for (const [, info] of bboxMap) {\n if (info.count < minArea) continue\n regions.push({\n bbox: {\n x: info.minX,\n y: info.minY,\n w: info.maxX - info.minX + 1,\n h: info.maxY - info.minY + 1,\n },\n pixelCount: info.count,\n intensity: info.intensitySum / info.count,\n })\n }\n\n return regions\n}\n"],"mappings":"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","names":[]}