@eyepop.ai/eyepop-render-2d 0.16.3 → 0.18.0

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/README.md CHANGED
@@ -126,6 +126,18 @@ Render2d.renderFace(target = '$..objects[?(@.classLabel=="face")]')
126
126
  // or
127
127
  Render2d.renderFace()
128
128
  ```
129
+ #### Render Segmentation Masks
130
+ ```typescript
131
+ Render2d.renderMask(target = '$..objects[?(@.mask)]')
132
+ // or
133
+ Render2d.renderMask()
134
+ ```
135
+ #### Render Segmentation Contours
136
+ ```typescript
137
+ Render2d.renderContour(target = '$..objects[?(@.contours)]')
138
+ // or
139
+ Render2d.renderContour()
140
+ ```
129
141
  #### Blur an Object (TODO does black-put instead of blur)
130
142
  ```typescript
131
143
  Render2d.renderBlur(target = '$..objects[?(@.classLabel=="face")]')
@@ -1,61 +1,5 @@
1
+ import { StreamTime, Prediction } from '@eyepop.ai/eyepop';
1
2
  import { CanvasRenderingContext2D } from 'canvas';
2
- import { StreamTime as StreamTime$1 } from '@eyepop.ai/eyepop';
3
-
4
- interface StreamTime {
5
- timestamp: number;
6
- seconds: number;
7
- offset: number;
8
- }
9
- interface Prediction extends StreamTime {
10
- source_width: number;
11
- source_height: number;
12
- source_id: string;
13
- objects: Array<PredictedObject>;
14
- classes: Array<PredictedClass>;
15
- labels: Array<string>;
16
- meshs: Array<PredictedMesh>;
17
- keyPoints: Array<PredictedKeyPoints>;
18
- }
19
- interface PredictedClass {
20
- id: number;
21
- confidence: number;
22
- classLabel: string;
23
- category: string;
24
- }
25
- interface PredictedObject extends PredictedClass {
26
- traceId: number | undefined;
27
- x: number;
28
- y: number;
29
- width: number;
30
- height: number;
31
- orientation: number;
32
- outline: Array<Point2d>;
33
- objects: Array<PredictedObject>;
34
- classes: Array<PredictedClass>;
35
- labels: Array<string>;
36
- meshs: Array<PredictedMesh>;
37
- keyPoints: Array<PredictedKeyPoints>;
38
- }
39
- interface Point2d {
40
- x: number;
41
- y: number;
42
- }
43
- interface PredictedMesh {
44
- category: string;
45
- id: number;
46
- confidence: number;
47
- points: Array<Point3d>;
48
- }
49
- interface Point3d extends Point2d {
50
- z: number | undefined;
51
- }
52
- interface PredictedKeyPoints {
53
- category: string;
54
- type: string;
55
- points: Array<PredictedKeyPoint>;
56
- }
57
- interface PredictedKeyPoint extends Point3d, PredictedClass {
58
- }
59
3
 
60
4
  interface Colors {
61
5
  primary_color: string;
@@ -77,7 +21,7 @@ declare class Style {
77
21
 
78
22
  interface Render {
79
23
  start(context: CanvasRenderingContext2D, style: Style): void;
80
- draw(element: any, xOffset: number, yOffset: number, xScale: number, yScale: number, streamTime: StreamTime$1): void;
24
+ draw(element: any, xOffset: number, yOffset: number, xScale: number, yScale: number, streamTime: StreamTime): void;
81
25
  }
82
26
 
83
27
  interface RenderRule {
@@ -92,6 +36,8 @@ declare namespace Render2d {
92
36
  function renderer(context: CanvasRenderingContext2D, rules?: RenderRule[] | undefined): Renderer;
93
37
  function renderBlur(target: string): RenderRule;
94
38
  function renderBox(includeSecondaryLabels?: boolean, target?: string): RenderRule;
39
+ function renderMask(target?: string): RenderRule;
40
+ function renderContour(target?: string): RenderRule;
95
41
  function renderFace(target?: string): RenderRule;
96
42
  function renderHand(target?: string): RenderRule;
97
43
  function renderPose(target?: string): RenderRule;
@@ -1,61 +1,5 @@
1
+ import { StreamTime, Prediction } from '@eyepop.ai/eyepop';
1
2
  import { CanvasRenderingContext2D } from 'canvas';
2
- import { StreamTime as StreamTime$1 } from '@eyepop.ai/eyepop';
3
-
4
- interface StreamTime {
5
- timestamp: number;
6
- seconds: number;
7
- offset: number;
8
- }
9
- interface Prediction extends StreamTime {
10
- source_width: number;
11
- source_height: number;
12
- source_id: string;
13
- objects: Array<PredictedObject>;
14
- classes: Array<PredictedClass>;
15
- labels: Array<string>;
16
- meshs: Array<PredictedMesh>;
17
- keyPoints: Array<PredictedKeyPoints>;
18
- }
19
- interface PredictedClass {
20
- id: number;
21
- confidence: number;
22
- classLabel: string;
23
- category: string;
24
- }
25
- interface PredictedObject extends PredictedClass {
26
- traceId: number | undefined;
27
- x: number;
28
- y: number;
29
- width: number;
30
- height: number;
31
- orientation: number;
32
- outline: Array<Point2d>;
33
- objects: Array<PredictedObject>;
34
- classes: Array<PredictedClass>;
35
- labels: Array<string>;
36
- meshs: Array<PredictedMesh>;
37
- keyPoints: Array<PredictedKeyPoints>;
38
- }
39
- interface Point2d {
40
- x: number;
41
- y: number;
42
- }
43
- interface PredictedMesh {
44
- category: string;
45
- id: number;
46
- confidence: number;
47
- points: Array<Point3d>;
48
- }
49
- interface Point3d extends Point2d {
50
- z: number | undefined;
51
- }
52
- interface PredictedKeyPoints {
53
- category: string;
54
- type: string;
55
- points: Array<PredictedKeyPoint>;
56
- }
57
- interface PredictedKeyPoint extends Point3d, PredictedClass {
58
- }
59
3
 
60
4
  interface Colors {
61
5
  primary_color: string;
@@ -77,7 +21,7 @@ declare class Style {
77
21
 
78
22
  interface Render {
79
23
  start(context: CanvasRenderingContext2D, style: Style): void;
80
- draw(element: any, xOffset: number, yOffset: number, xScale: number, yScale: number, streamTime: StreamTime$1): void;
24
+ draw(element: any, xOffset: number, yOffset: number, xScale: number, yScale: number, streamTime: StreamTime): void;
81
25
  }
82
26
 
83
27
  interface RenderRule {
@@ -92,6 +36,8 @@ declare namespace Render2d {
92
36
  function renderer(context: CanvasRenderingContext2D, rules?: RenderRule[] | undefined): Renderer;
93
37
  function renderBlur(target: string): RenderRule;
94
38
  function renderBox(includeSecondaryLabels?: boolean, target?: string): RenderRule;
39
+ function renderMask(target?: string): RenderRule;
40
+ function renderContour(target?: string): RenderRule;
95
41
  function renderFace(target?: string): RenderRule;
96
42
  function renderHand(target?: string): RenderRule;
97
43
  function renderPose(target?: string): RenderRule;
@@ -728,6 +728,117 @@ var RenderTrail = class {
728
728
  }
729
729
  };
730
730
 
731
+ // render-mask.ts
732
+ var RenderMask = class {
733
+ start(context, style) {
734
+ this.context = context;
735
+ this.style = style;
736
+ }
737
+ draw(element, xOffset, yOffset, xScale, yScale, streamTime) {
738
+ if (!element.mask) {
739
+ return;
740
+ }
741
+ const context = this.context;
742
+ const style = this.style;
743
+ if (!context || !style) {
744
+ throw new Error("render() called before start()");
745
+ }
746
+ const buffer = Buffer.from(element.mask.bitmap, "base64");
747
+ const offscreenCanvas = new OffscreenCanvas(element.mask.width, element.mask.height);
748
+ const offscreenContext = offscreenCanvas.getContext("2d");
749
+ if (!offscreenContext) {
750
+ throw new Error("cannot render a mask without offscreen context");
751
+ }
752
+ const aPixel = offscreenContext.createImageData(1, 1);
753
+ const d = aPixel.data;
754
+ d[0] = 80;
755
+ d[1] = 80;
756
+ d[2] = 80;
757
+ d[3] = 128;
758
+ for (let y = 0; y < element.mask.height; y++) {
759
+ const line = y * element.mask.stride;
760
+ for (let s = 0; s < element.mask.stride; s++) {
761
+ const byte = buffer[line + s];
762
+ for (let p = 0; p < 8; p++) {
763
+ const x = s * 8 + p;
764
+ if (x >= element.mask.width) {
765
+ break;
766
+ }
767
+ const bit = byte >> 7 - p % 8 & 1;
768
+ if (bit) {
769
+ offscreenContext.putImageData(aPixel, x, y);
770
+ }
771
+ }
772
+ }
773
+ }
774
+ const bitmap = offscreenCanvas.transferToImageBitmap();
775
+ context.drawImage(
776
+ // @ts-ignore - wouldn't work for node, but then we errored out above already
777
+ bitmap,
778
+ element.x + xOffset,
779
+ element.y + yOffset,
780
+ element.width * xScale,
781
+ element.height * yScale
782
+ );
783
+ }
784
+ };
785
+
786
+ // render-contour.ts
787
+ var RenderContour = class {
788
+ start(context, style) {
789
+ this.context = context;
790
+ this.style = style;
791
+ }
792
+ draw(element, xOffset, yOffset, xScale, yScale, streamTime) {
793
+ if (!element.contours || !element.contours.length) {
794
+ return;
795
+ }
796
+ const context = this.context;
797
+ const style = this.style;
798
+ if (!context || !style) {
799
+ throw new Error("render() called before start()");
800
+ }
801
+ const lineWidth = Math.max(1, Math.max(context.canvas.width, context.canvas.height) / 360);
802
+ console.log("line width:", lineWidth, context.canvas.width, context.canvas.height);
803
+ for (let j = 0; j < element.contours.length; j++) {
804
+ const contour = element.contours[j];
805
+ if (contour.points.length < 2) {
806
+ continue;
807
+ }
808
+ context.beginPath();
809
+ context.lineWidth = lineWidth;
810
+ context.strokeStyle = style.colors.primary_color;
811
+ context.fillStyle = style.colors.opacity_color;
812
+ let p = contour.points[0];
813
+ context.moveTo(p.x * xScale + xOffset, p.y * yScale + yOffset);
814
+ for (let i = contour.points.length - 1; i > 0; i--) {
815
+ p = contour.points[i];
816
+ context.lineTo(p.x * xScale + xOffset, p.y * yScale + yOffset);
817
+ }
818
+ context.closePath();
819
+ context.stroke();
820
+ if (contour.cutouts && contour.cutouts.length) {
821
+ for (let k = 0; k < contour.cutouts.length; k++) {
822
+ const points = contour.cutouts[k];
823
+ if (points.length < 2) {
824
+ continue;
825
+ }
826
+ context.beginPath();
827
+ p = points[0];
828
+ context.moveTo(p.x * xScale + xOffset, p.y * yScale + yOffset);
829
+ for (let i = points.length - 1; i > 0; i--) {
830
+ p = points[i];
831
+ context.lineTo(p.x * xScale + xOffset, p.y * yScale + yOffset);
832
+ }
833
+ context.closePath();
834
+ context.stroke();
835
+ }
836
+ }
837
+ context.fill();
838
+ }
839
+ }
840
+ };
841
+
731
842
  // index.ts
732
843
  var Render2d;
733
844
  ((Render2d2) => {
@@ -743,6 +854,14 @@ var Render2d;
743
854
  return { render: new RenderBox(includeSecondaryLabels), target };
744
855
  }
745
856
  Render2d2.renderBox = renderBox;
857
+ function renderMask(target = "$..objects[?(@.mask)]") {
858
+ return { render: new RenderMask(), target };
859
+ }
860
+ Render2d2.renderMask = renderMask;
861
+ function renderContour(target = "$..objects[?(@.contours)]") {
862
+ return { render: new RenderContour(), target };
863
+ }
864
+ Render2d2.renderContour = renderContour;
746
865
  function renderFace(target = '$..objects[?(@.classLabel=="face")]') {
747
866
  return { render: new RenderFace(), target };
748
867
  }