supervision 0.2.6 → 0.2.8

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 (60) hide show
  1. package/dist/editing.d.ts +1 -1
  2. package/dist/editing.d.ts.map +1 -1
  3. package/dist/index.js +527 -68
  4. package/dist/index.js.map +1 -1
  5. package/dist/mask-preparation.worker.js +130 -4
  6. package/dist/mask-preparation.worker.js.map +1 -1
  7. package/dist/render-preparation/mask-frame-artifact.d.ts +10 -0
  8. package/dist/render-preparation/mask-frame-artifact.d.ts.map +1 -1
  9. package/dist/render-preparation/mask-frame-compositor.d.ts +2 -1
  10. package/dist/render-preparation/mask-frame-compositor.d.ts.map +1 -1
  11. package/dist/render-preparation/mask-frame-preparer.d.ts.map +1 -1
  12. package/dist/render-preparation/mask-outline-paths.d.ts +3 -0
  13. package/dist/render-preparation/mask-outline-paths.d.ts.map +1 -0
  14. package/dist/render-preparation/mask-preparation-worker-protocol.d.ts +2 -1
  15. package/dist/render-preparation/mask-preparation-worker-protocol.d.ts.map +1 -1
  16. package/dist/render-preparation/prepared-render-window.d.ts.map +1 -1
  17. package/dist/renderers/detection-render-order.d.ts +4 -0
  18. package/dist/renderers/detection-render-order.d.ts.map +1 -0
  19. package/dist/renderers/media-renderer-core.d.ts.map +1 -1
  20. package/dist/renderers/media-renderer-scene.d.ts +8 -1
  21. package/dist/renderers/media-renderer-scene.d.ts.map +1 -1
  22. package/dist/renderers/pixi-box-layer.d.ts +1 -0
  23. package/dist/renderers/pixi-box-layer.d.ts.map +1 -1
  24. package/dist/renderers/pixi-interaction-layer.d.ts.map +1 -1
  25. package/dist/renderers/pixi-interaction-presentation-layer.d.ts.map +1 -1
  26. package/dist/renderers/pixi-mask-brush-preview.d.ts.map +1 -1
  27. package/dist/renderers/pixi-mask-layer.d.ts +4 -2
  28. package/dist/renderers/pixi-mask-layer.d.ts.map +1 -1
  29. package/dist/renderers/pixi-mask-screen-stroke.d.ts +17 -0
  30. package/dist/renderers/pixi-mask-screen-stroke.d.ts.map +1 -0
  31. package/dist/renderers/pixi-media-scene.d.ts +5 -0
  32. package/dist/renderers/pixi-media-scene.d.ts.map +1 -1
  33. package/dist/renderers/pixi-region-layer.d.ts +2 -0
  34. package/dist/renderers/pixi-region-layer.d.ts.map +1 -1
  35. package/dist/renderers/pixi-vector-layer.d.ts +1 -0
  36. package/dist/renderers/pixi-vector-layer.d.ts.map +1 -1
  37. package/dist/tracking.worker.js.map +1 -1
  38. package/dist/types/media-renderer.d.ts +21 -6
  39. package/dist/types/media-renderer.d.ts.map +1 -1
  40. package/dist/types/media-session.d.ts +2 -0
  41. package/dist/types/media-session.d.ts.map +1 -1
  42. package/node_modules/supervision-js-core/dist/index.d.ts +1 -1
  43. package/node_modules/supervision-js-core/dist/index.d.ts.map +1 -1
  44. package/node_modules/supervision-js-core/dist/index.js +44 -11
  45. package/node_modules/supervision-js-core/dist/index.js.map +1 -1
  46. package/node_modules/supervision-js-core/dist/interactions/annotation-editing-engine.d.ts +2 -2
  47. package/node_modules/supervision-js-core/dist/interactions/annotation-editing-engine.d.ts.map +1 -1
  48. package/node_modules/supervision-js-core/dist/interactions/detection-picker.d.ts.map +1 -1
  49. package/node_modules/supervision-js-core/dist/interactions/viewport-controller.d.ts.map +1 -1
  50. package/node_modules/supervision-js-core/dist/types/detections.d.ts +2 -1
  51. package/node_modules/supervision-js-core/dist/types/detections.d.ts.map +1 -1
  52. package/node_modules/supervision-js-core/dist/types/editing.d.ts +7 -0
  53. package/node_modules/supervision-js-core/dist/types/editing.d.ts.map +1 -1
  54. package/node_modules/supervision-js-core/dist/types/interaction.d.ts +11 -0
  55. package/node_modules/supervision-js-core/dist/types/interaction.d.ts.map +1 -1
  56. package/node_modules/supervision-js-core/dist/types/mask-style.d.ts +3 -0
  57. package/node_modules/supervision-js-core/dist/types/mask-style.d.ts.map +1 -1
  58. package/node_modules/supervision-js-core/dist/types/viewport.d.ts +3 -0
  59. package/node_modules/supervision-js-core/dist/types/viewport.d.ts.map +1 -1
  60. 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 && bounds) {
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
- }, [imageBitmap, ...idMaskTransfers, ...coverageTransfers]);
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
- }, [imageData.data.buffer, ...idMaskTransfers, ...coverageTransfers]);
1968
+ }, [
1969
+ imageData.data.buffer,
1970
+ ...idMaskTransfers,
1971
+ ...strokeTransfers,
1972
+ ...coverageTransfers,
1973
+ ]);
1848
1974
  }
1849
1975
  catch (error) {
1850
1976
  workerScope.postMessage({