supervision 0.2.6 → 0.2.7
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/editing.d.ts +1 -1
- package/dist/editing.d.ts.map +1 -1
- package/dist/index.js +325 -24
- package/dist/index.js.map +1 -1
- package/dist/mask-preparation.worker.js +130 -4
- package/dist/mask-preparation.worker.js.map +1 -1
- package/dist/render-preparation/mask-frame-artifact.d.ts +10 -0
- package/dist/render-preparation/mask-frame-artifact.d.ts.map +1 -1
- package/dist/render-preparation/mask-frame-compositor.d.ts +2 -1
- package/dist/render-preparation/mask-frame-compositor.d.ts.map +1 -1
- package/dist/render-preparation/mask-frame-preparer.d.ts.map +1 -1
- package/dist/render-preparation/mask-outline-paths.d.ts +3 -0
- package/dist/render-preparation/mask-outline-paths.d.ts.map +1 -0
- package/dist/render-preparation/mask-preparation-worker-protocol.d.ts +2 -1
- package/dist/render-preparation/mask-preparation-worker-protocol.d.ts.map +1 -1
- package/dist/render-preparation/prepared-render-window.d.ts.map +1 -1
- package/dist/renderers/detection-render-order.d.ts +4 -0
- package/dist/renderers/detection-render-order.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-box-layer.d.ts +1 -0
- package/dist/renderers/pixi-box-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-interaction-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-interaction-presentation-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-mask-brush-preview.d.ts.map +1 -1
- package/dist/renderers/pixi-mask-layer.d.ts +4 -2
- package/dist/renderers/pixi-mask-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-mask-screen-stroke.d.ts +17 -0
- package/dist/renderers/pixi-mask-screen-stroke.d.ts.map +1 -0
- package/dist/renderers/pixi-media-scene.d.ts.map +1 -1
- package/dist/renderers/pixi-vector-layer.d.ts +1 -0
- package/dist/renderers/pixi-vector-layer.d.ts.map +1 -1
- package/dist/tracking.worker.js.map +1 -1
- package/dist/types/media-renderer.d.ts +14 -0
- package/dist/types/media-renderer.d.ts.map +1 -1
- package/dist/types/media-session.d.ts +2 -0
- package/dist/types/media-session.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.d.ts +1 -1
- package/node_modules/supervision-js-core/dist/index.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.js +44 -11
- package/node_modules/supervision-js-core/dist/index.js.map +1 -1
- package/node_modules/supervision-js-core/dist/interactions/annotation-editing-engine.d.ts +2 -2
- package/node_modules/supervision-js-core/dist/interactions/annotation-editing-engine.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/interactions/detection-picker.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/interactions/viewport-controller.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/detections.d.ts +2 -1
- package/node_modules/supervision-js-core/dist/types/detections.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/editing.d.ts +7 -0
- package/node_modules/supervision-js-core/dist/types/editing.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/interaction.d.ts +4 -0
- package/node_modules/supervision-js-core/dist/types/interaction.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/mask-style.d.ts +3 -0
- package/node_modules/supervision-js-core/dist/types/mask-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/viewport.d.ts +3 -0
- package/node_modules/supervision-js-core/dist/types/viewport.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,74 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
/** Trace closed pixel boundaries, retaining holes and disconnected components. */
|
|
5
|
+
function traceMaskOutlinePaths(raster, width, height, ids) {
|
|
6
|
+
const edgesById = new Map();
|
|
7
|
+
const stride = width + 1;
|
|
8
|
+
const steps = [1, stride, -1, -stride];
|
|
9
|
+
const add = (id, vertex, direction) => {
|
|
10
|
+
let edges = edgesById.get(id);
|
|
11
|
+
if (!edges)
|
|
12
|
+
edgesById.set(id, (edges = new Map()));
|
|
13
|
+
const outgoing = edges.get(vertex);
|
|
14
|
+
if (outgoing)
|
|
15
|
+
outgoing.push(direction);
|
|
16
|
+
else
|
|
17
|
+
edges.set(vertex, [direction]);
|
|
18
|
+
};
|
|
19
|
+
for (let y = 0; y < height; y += 1) {
|
|
20
|
+
for (let x = 0; x < width; x += 1) {
|
|
21
|
+
const offset = y * width + x;
|
|
22
|
+
const id = raster[offset];
|
|
23
|
+
if (!ids.has(id))
|
|
24
|
+
continue;
|
|
25
|
+
const vertex = y * stride + x;
|
|
26
|
+
if (y === 0 || raster[offset - width] !== id)
|
|
27
|
+
add(id, vertex, 0);
|
|
28
|
+
if (x === width - 1 || raster[offset + 1] !== id)
|
|
29
|
+
add(id, vertex + 1, 1);
|
|
30
|
+
if (y === height - 1 || raster[offset + width] !== id)
|
|
31
|
+
add(id, vertex + stride + 1, 2);
|
|
32
|
+
if (x === 0 || raster[offset - 1] !== id)
|
|
33
|
+
add(id, vertex + stride, 3);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const result = new Map();
|
|
37
|
+
for (const [id, edges] of edgesById) {
|
|
38
|
+
const paths = [];
|
|
39
|
+
while (edges.size > 0) {
|
|
40
|
+
const start = edges.keys().next().value;
|
|
41
|
+
let vertex = start;
|
|
42
|
+
let previousDirection = -1;
|
|
43
|
+
let firstDirection = -1;
|
|
44
|
+
const points = [];
|
|
45
|
+
do {
|
|
46
|
+
const outgoing = edges.get(vertex);
|
|
47
|
+
// Turn right at diagonal contacts so separate islands stay separate.
|
|
48
|
+
const direction = previousDirection < 0
|
|
49
|
+
? outgoing[0]
|
|
50
|
+
: [1, 0, 3, 2]
|
|
51
|
+
.map((turn) => (previousDirection + turn) % 4)
|
|
52
|
+
.find((candidate) => outgoing.includes(candidate));
|
|
53
|
+
if (firstDirection < 0)
|
|
54
|
+
firstDirection = direction;
|
|
55
|
+
if (direction !== previousDirection)
|
|
56
|
+
points.push(vertex % stride, Math.floor(vertex / stride));
|
|
57
|
+
outgoing.splice(outgoing.indexOf(direction), 1);
|
|
58
|
+
if (outgoing.length === 0)
|
|
59
|
+
edges.delete(vertex);
|
|
60
|
+
vertex += steps[direction];
|
|
61
|
+
previousDirection = direction;
|
|
62
|
+
} while (vertex !== start);
|
|
63
|
+
if (previousDirection === firstDirection)
|
|
64
|
+
points.splice(0, 2);
|
|
65
|
+
paths.push(new Float32Array(points));
|
|
66
|
+
}
|
|
67
|
+
result.set(id, paths);
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
|
|
4
72
|
/** COCO-compatible keypoint visibility values. */
|
|
5
73
|
var KeypointVisibility;
|
|
6
74
|
(function (KeypointVisibility) {
|
|
@@ -895,7 +963,9 @@
|
|
|
895
963
|
}
|
|
896
964
|
function createIdMaskRasterFrame(instructions, maxRasterWidth) {
|
|
897
965
|
try {
|
|
898
|
-
return createIdMaskFrame(materializeMaskInstructions(instructions)
|
|
966
|
+
return createIdMaskFrame(materializeMaskInstructions(instructions).map((instruction) => instruction.stroke?.widthUnit === "screen"
|
|
967
|
+
? { ...instruction, stroke: undefined }
|
|
968
|
+
: instruction), {
|
|
899
969
|
maxWidth: maxRasterWidth,
|
|
900
970
|
});
|
|
901
971
|
}
|
|
@@ -930,10 +1000,47 @@
|
|
|
930
1000
|
function compositeInstruction(rgba, canvasWidth, instruction) {
|
|
931
1001
|
const fill = resolveRgbaColor(instruction.color, instruction.alpha);
|
|
932
1002
|
const bounds = compositeMaskFill(rgba, canvasWidth, instruction.mask, fill);
|
|
933
|
-
if (instruction.stroke &&
|
|
1003
|
+
if (instruction.stroke &&
|
|
1004
|
+
instruction.stroke.widthUnit !== "screen" &&
|
|
1005
|
+
bounds) {
|
|
934
1006
|
compositeMaskStroke(rgba, canvasWidth, decodeCompressedRleMask(instruction.mask), bounds, instruction.stroke);
|
|
935
1007
|
}
|
|
936
1008
|
}
|
|
1009
|
+
function createMaskScreenStrokes(instructions, width, height, preparedRaster) {
|
|
1010
|
+
const outlined = instructions.filter(({ visible, stroke }) => visible !== false &&
|
|
1011
|
+
stroke?.widthUnit === "screen" &&
|
|
1012
|
+
stroke.width > 0 &&
|
|
1013
|
+
stroke.alpha > 0);
|
|
1014
|
+
if (outlined.length === 0)
|
|
1015
|
+
return undefined;
|
|
1016
|
+
const masks = materializeMaskInstructions(instructions);
|
|
1017
|
+
const raster = preparedRaster ?? new Uint32Array(width * height);
|
|
1018
|
+
if (!preparedRaster) {
|
|
1019
|
+
for (const { detectionIndex, mask } of masks) {
|
|
1020
|
+
const counts = decodeCompressedRleCounts(mask.counts);
|
|
1021
|
+
let offset = 0;
|
|
1022
|
+
for (let index = 0; index < counts.length; index += 1) {
|
|
1023
|
+
const length = counts[index];
|
|
1024
|
+
if (index % 2 === 1) {
|
|
1025
|
+
for (let pixel = offset; pixel < offset + length; pixel += 1) {
|
|
1026
|
+
const x = Math.floor(pixel / mask.height);
|
|
1027
|
+
const y = pixel % mask.height;
|
|
1028
|
+
raster[y * width + x] = detectionIndex + 1;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
offset += length;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
const paths = traceMaskOutlinePaths(raster, width, height, new Set(outlined.map(({ detectionIndex }) => detectionIndex + 1)));
|
|
1036
|
+
return outlined.map(({ detectionIndex, stroke }) => ({
|
|
1037
|
+
detectionIndex,
|
|
1038
|
+
alpha: stroke.alpha,
|
|
1039
|
+
color: stroke.color,
|
|
1040
|
+
width: stroke.width,
|
|
1041
|
+
paths: paths.get(detectionIndex + 1) ?? [],
|
|
1042
|
+
}));
|
|
1043
|
+
}
|
|
937
1044
|
function materializeMaskInstructions(instructions) {
|
|
938
1045
|
return instructions
|
|
939
1046
|
.filter((instruction) => instruction.visible !== false)
|
|
@@ -1788,6 +1895,8 @@
|
|
|
1788
1895
|
const coverageTransfers = getRegionMaskCoverageTransfers(regionMaskCoverage);
|
|
1789
1896
|
const idMaskFrame = createIdMaskRasterFrame(message.job.instructions, message.job.maxRasterWidth);
|
|
1790
1897
|
if (idMaskFrame) {
|
|
1898
|
+
const screenStrokes = createMaskScreenStrokes(message.job.instructions, idMaskFrame.width, idMaskFrame.height, idMaskFrame.data);
|
|
1899
|
+
const strokeTransfers = screenStrokes?.flatMap(({ paths }) => paths.map((path) => path.buffer)) ?? [];
|
|
1791
1900
|
workerScope.postMessage({
|
|
1792
1901
|
artifactKind: PreparedMaskFrameKind.IdMask,
|
|
1793
1902
|
fillPalette: idMaskFrame.fillPalette,
|
|
@@ -1796,6 +1905,7 @@
|
|
|
1796
1905
|
key: message.job.key,
|
|
1797
1906
|
maxStrokeWidth: idMaskFrame.maxStrokeWidth,
|
|
1798
1907
|
raster: idMaskFrame.data,
|
|
1908
|
+
screenStrokes,
|
|
1799
1909
|
regionMaskCoverage,
|
|
1800
1910
|
requestId: message.requestId,
|
|
1801
1911
|
sourceWidth: idMaskFrame.sourceWidth,
|
|
@@ -1808,6 +1918,7 @@
|
|
|
1808
1918
|
idMaskFrame.fillPalette.buffer,
|
|
1809
1919
|
idMaskFrame.strokePalette.buffer,
|
|
1810
1920
|
idMaskFrame.strokeWidths.buffer,
|
|
1921
|
+
...strokeTransfers,
|
|
1811
1922
|
...coverageTransfers,
|
|
1812
1923
|
]);
|
|
1813
1924
|
return;
|
|
@@ -1826,25 +1937,40 @@
|
|
|
1826
1937
|
const imageBitmap = createImageBitmapFromImageData(imageData);
|
|
1827
1938
|
const idMaskPlane = createIdMaskPlane(message.job.instructions, message.job.maxRasterWidth);
|
|
1828
1939
|
const idMaskTransfers = idMaskPlane ? [idMaskPlane.data.buffer] : [];
|
|
1940
|
+
const screenStrokes = createMaskScreenStrokes(message.job.instructions, preparedPixels.width, preparedPixels.height);
|
|
1941
|
+
const strokeTransfers = screenStrokes?.flatMap(({ paths }) => paths.map((path) => path.buffer)) ??
|
|
1942
|
+
[];
|
|
1829
1943
|
if (imageBitmap) {
|
|
1830
1944
|
workerScope.postMessage({
|
|
1831
1945
|
idMaskPlane,
|
|
1832
1946
|
imageBitmap,
|
|
1947
|
+
screenStrokes,
|
|
1833
1948
|
key: message.job.key,
|
|
1834
1949
|
regionMaskCoverage,
|
|
1835
1950
|
requestId: message.requestId,
|
|
1836
1951
|
type: MaskPreparationWorkerMessageType.Complete,
|
|
1837
|
-
}, [
|
|
1952
|
+
}, [
|
|
1953
|
+
imageBitmap,
|
|
1954
|
+
...idMaskTransfers,
|
|
1955
|
+
...strokeTransfers,
|
|
1956
|
+
...coverageTransfers,
|
|
1957
|
+
]);
|
|
1838
1958
|
return;
|
|
1839
1959
|
}
|
|
1840
1960
|
workerScope.postMessage({
|
|
1841
1961
|
idMaskPlane,
|
|
1842
1962
|
imageData,
|
|
1963
|
+
screenStrokes,
|
|
1843
1964
|
key: message.job.key,
|
|
1844
1965
|
regionMaskCoverage,
|
|
1845
1966
|
requestId: message.requestId,
|
|
1846
1967
|
type: MaskPreparationWorkerMessageType.Complete,
|
|
1847
|
-
}, [
|
|
1968
|
+
}, [
|
|
1969
|
+
imageData.data.buffer,
|
|
1970
|
+
...idMaskTransfers,
|
|
1971
|
+
...strokeTransfers,
|
|
1972
|
+
...coverageTransfers,
|
|
1973
|
+
]);
|
|
1848
1974
|
}
|
|
1849
1975
|
catch (error) {
|
|
1850
1976
|
workerScope.postMessage({
|