supervision 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +672 -9
- package/dist/index.js.map +1 -1
- package/dist/mask-preparation.worker.js +129 -0
- package/dist/mask-preparation.worker.js.map +1 -1
- package/dist/render-preparation/heatmap-frame-preparer.d.ts +13 -0
- package/dist/render-preparation/heatmap-frame-preparer.d.ts.map +1 -0
- package/dist/render-preparation/heatmap-preparation-worker-protocol.d.ts +24 -0
- package/dist/render-preparation/heatmap-preparation-worker-protocol.d.ts.map +1 -0
- package/dist/renderers/heatmap-color.d.ts +7 -0
- package/dist/renderers/heatmap-color.d.ts.map +1 -0
- package/dist/renderers/media-renderer-core.d.ts.map +1 -1
- package/dist/renderers/media-renderer-scene.d.ts +2 -1
- package/dist/renderers/media-renderer-scene.d.ts.map +1 -1
- package/dist/renderers/pixi-frame-present.d.ts +1 -0
- package/dist/renderers/pixi-frame-present.d.ts.map +1 -1
- package/dist/renderers/pixi-heatmap-layer.d.ts +42 -0
- package/dist/renderers/pixi-heatmap-layer.d.ts.map +1 -0
- package/dist/renderers/pixi-media-scene.d.ts.map +1 -1
- package/dist/renderers/pixi-scene-layer-slot.d.ts +1 -0
- package/dist/renderers/pixi-scene-layer-slot.d.ts.map +1 -1
- package/dist/tracking.worker.js.map +1 -1
- package/dist/workers/worker-rpc-client.d.ts +1 -1
- package/dist/workers/worker-rpc-client.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.d.ts +2 -2
- package/node_modules/supervision-js-core/dist/index.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.js +109 -1
- package/node_modules/supervision-js-core/dist/index.js.map +1 -1
- package/node_modules/supervision-js-core/dist/interactions/annotation-handles.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/annotation-renderer-presentation.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/annotation-renderer-registry.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts +24 -3
- package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/detections.d.ts +18 -0
- package/node_modules/supervision-js-core/dist/types/detections.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/utils/detection-frames.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1000,6 +1000,104 @@
|
|
|
1000
1000
|
IdMaskTextureFormat["Rgba8"] = "rgba8unorm";
|
|
1001
1001
|
})(IdMaskTextureFormat || (IdMaskTextureFormat = {}));
|
|
1002
1002
|
|
|
1003
|
+
const DEFAULT_STOPS = [
|
|
1004
|
+
{ position: 0, color: 0xffd600 },
|
|
1005
|
+
{ position: 0.35, color: 0xffd600 },
|
|
1006
|
+
{ position: 0.7, color: 0xff7a00 },
|
|
1007
|
+
{ position: 1, color: 0xdc1e1e },
|
|
1008
|
+
];
|
|
1009
|
+
const MAX_HEATMAP_PIXELS = 16_777_216;
|
|
1010
|
+
const MAX_HEATMAP_SIDE = 8_192;
|
|
1011
|
+
/** Turns semantic scores into an RGBA raster; no palette enters cold data. */
|
|
1012
|
+
function colorizeHeatmap(map, renderer) {
|
|
1013
|
+
const { bounds, width, height, values } = map;
|
|
1014
|
+
if (!Number.isFinite(bounds?.x) ||
|
|
1015
|
+
!Number.isFinite(bounds?.y) ||
|
|
1016
|
+
!Number.isFinite(bounds?.width) ||
|
|
1017
|
+
!Number.isFinite(bounds?.height) ||
|
|
1018
|
+
bounds.width <= 0 ||
|
|
1019
|
+
bounds.height <= 0 ||
|
|
1020
|
+
!Number.isInteger(width) ||
|
|
1021
|
+
!Number.isInteger(height) ||
|
|
1022
|
+
width <= 0 ||
|
|
1023
|
+
height <= 0 ||
|
|
1024
|
+
width > MAX_HEATMAP_SIDE ||
|
|
1025
|
+
height > MAX_HEATMAP_SIDE ||
|
|
1026
|
+
width * height > MAX_HEATMAP_PIXELS ||
|
|
1027
|
+
!(Array.isArray(values) ||
|
|
1028
|
+
values instanceof Float32Array ||
|
|
1029
|
+
values instanceof Float64Array ||
|
|
1030
|
+
values instanceof Uint16Array) ||
|
|
1031
|
+
values.length !== width * height) {
|
|
1032
|
+
throw new RangeError("Heatmap bounds and dimensions must be valid, match row-major values, and fit the raster limit.");
|
|
1033
|
+
}
|
|
1034
|
+
const scale = map.valueScale ?? 1;
|
|
1035
|
+
const threshold = (map.threshold ?? 0) * (renderer.thresholdScale ?? 1);
|
|
1036
|
+
const maximumScore = renderer.maximumScore ?? 1;
|
|
1037
|
+
const opacity = clamp01(renderer.opacity ?? 1);
|
|
1038
|
+
const minimumAlpha = clamp01(renderer.minimumAlpha ?? 0);
|
|
1039
|
+
const stops = renderer.colorStops ?? DEFAULT_STOPS;
|
|
1040
|
+
if (!Number.isFinite(scale) ||
|
|
1041
|
+
scale <= 0 ||
|
|
1042
|
+
!Number.isFinite(threshold) ||
|
|
1043
|
+
!Number.isFinite(maximumScore) ||
|
|
1044
|
+
maximumScore <= 0 ||
|
|
1045
|
+
!Number.isFinite(renderer.thresholdScale ?? 1) ||
|
|
1046
|
+
(renderer.thresholdScale ?? 1) < 0 ||
|
|
1047
|
+
!Number.isFinite(renderer.opacity ?? 1) ||
|
|
1048
|
+
!Number.isFinite(renderer.minimumAlpha ?? 0) ||
|
|
1049
|
+
stops.length === 0 ||
|
|
1050
|
+
stops.some((stop, index) => !Number.isFinite(stop.position) ||
|
|
1051
|
+
stop.position < 0 ||
|
|
1052
|
+
stop.position > 1 ||
|
|
1053
|
+
!Number.isInteger(stop.color) ||
|
|
1054
|
+
stop.color < 0 ||
|
|
1055
|
+
stop.color > 0xffffff ||
|
|
1056
|
+
(index > 0 && stop.position < stops[index - 1].position))) {
|
|
1057
|
+
throw new RangeError("Invalid heatmap scale, threshold, or color stops.");
|
|
1058
|
+
}
|
|
1059
|
+
const rgba = new Uint8ClampedArray(new ArrayBuffer(values.length * 4));
|
|
1060
|
+
if (maximumScore <= threshold || opacity === 0)
|
|
1061
|
+
return rgba;
|
|
1062
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
1063
|
+
const score = values[index] * scale;
|
|
1064
|
+
if (!Number.isFinite(score) || score <= threshold)
|
|
1065
|
+
continue;
|
|
1066
|
+
const color = interpolateColor(stops, clamp01(score / maximumScore));
|
|
1067
|
+
const alphaIntensity = clamp01((score - threshold) / (maximumScore - threshold));
|
|
1068
|
+
const offset = index * 4;
|
|
1069
|
+
rgba[offset] = color >> 16;
|
|
1070
|
+
rgba[offset + 1] = (color >> 8) & 0xff;
|
|
1071
|
+
rgba[offset + 2] = color & 0xff;
|
|
1072
|
+
rgba[offset + 3] = Math.round(255 * opacity * (minimumAlpha + (1 - minimumAlpha) * alphaIntensity));
|
|
1073
|
+
}
|
|
1074
|
+
return rgba;
|
|
1075
|
+
}
|
|
1076
|
+
function interpolateColor(stops, value) {
|
|
1077
|
+
const upperIndex = stops.findIndex((stop) => stop.position >= value);
|
|
1078
|
+
if (upperIndex === -1)
|
|
1079
|
+
return stops[stops.length - 1].color;
|
|
1080
|
+
if (upperIndex === 0)
|
|
1081
|
+
return stops[0].color;
|
|
1082
|
+
const left = stops[upperIndex - 1];
|
|
1083
|
+
const right = stops[upperIndex];
|
|
1084
|
+
const span = right.position - left.position;
|
|
1085
|
+
const ratio = span === 0 ? 1 : (value - left.position) / span;
|
|
1086
|
+
const channel = (shift) => Math.round(((left.color >> shift) & 0xff) * (1 - ratio) +
|
|
1087
|
+
((right.color >> shift) & 0xff) * ratio);
|
|
1088
|
+
return (channel(16) << 16) | (channel(8) << 8) | channel(0);
|
|
1089
|
+
}
|
|
1090
|
+
function clamp01(value) {
|
|
1091
|
+
return Math.max(0, Math.min(1, value));
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
var HeatmapPreparationWorkerMessageType;
|
|
1095
|
+
(function (HeatmapPreparationWorkerMessageType) {
|
|
1096
|
+
HeatmapPreparationWorkerMessageType["Prepare"] = "heatmap-prepare";
|
|
1097
|
+
HeatmapPreparationWorkerMessageType["Complete"] = "heatmap-complete";
|
|
1098
|
+
HeatmapPreparationWorkerMessageType["Error"] = "heatmap-error";
|
|
1099
|
+
})(HeatmapPreparationWorkerMessageType || (HeatmapPreparationWorkerMessageType = {}));
|
|
1100
|
+
|
|
1003
1101
|
var MaskPreparationWorkerMessageType;
|
|
1004
1102
|
(function (MaskPreparationWorkerMessageType) {
|
|
1005
1103
|
MaskPreparationWorkerMessageType["Complete"] = "complete";
|
|
@@ -1011,11 +1109,42 @@
|
|
|
1011
1109
|
const workerScope = globalThis;
|
|
1012
1110
|
workerScope.addEventListener("message", (event) => {
|
|
1013
1111
|
const message = event.data;
|
|
1112
|
+
if (message.type === HeatmapPreparationWorkerMessageType.Prepare) {
|
|
1113
|
+
prepareHeatmap(message);
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1014
1116
|
if (message.type !== MaskPreparationWorkerMessageType.Prepare) {
|
|
1015
1117
|
return;
|
|
1016
1118
|
}
|
|
1017
1119
|
prepareMaskFrame(message);
|
|
1018
1120
|
});
|
|
1121
|
+
function prepareHeatmap(message) {
|
|
1122
|
+
try {
|
|
1123
|
+
const data = colorizeHeatmap(message.map, message.renderer);
|
|
1124
|
+
const imageData = new ImageData(data, message.map.width, message.map.height);
|
|
1125
|
+
const imageBitmap = createImageBitmapFromImageData(imageData);
|
|
1126
|
+
if (imageBitmap) {
|
|
1127
|
+
workerScope.postMessage({
|
|
1128
|
+
imageBitmap,
|
|
1129
|
+
requestId: message.requestId,
|
|
1130
|
+
type: HeatmapPreparationWorkerMessageType.Complete,
|
|
1131
|
+
}, [imageBitmap]);
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
workerScope.postMessage({
|
|
1135
|
+
imageData,
|
|
1136
|
+
requestId: message.requestId,
|
|
1137
|
+
type: HeatmapPreparationWorkerMessageType.Complete,
|
|
1138
|
+
}, [imageData.data.buffer]);
|
|
1139
|
+
}
|
|
1140
|
+
catch (error) {
|
|
1141
|
+
workerScope.postMessage({
|
|
1142
|
+
error: error instanceof Error ? error.message : "Unable to prepare heatmap.",
|
|
1143
|
+
requestId: message.requestId,
|
|
1144
|
+
type: HeatmapPreparationWorkerMessageType.Error,
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1019
1148
|
function prepareMaskFrame(message) {
|
|
1020
1149
|
try {
|
|
1021
1150
|
const regionMaskCoverage = createRegionMaskCoverageFrame(message.job.instructions);
|